1/*
2 * cdrom_id - determines the capabilities of cdrom drives
3 *
4 * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
5 *
6 *	This program is free software; you can redistribute it and/or modify it
7 *	under the terms of the GNU General Public License as published by the
8 *	Free Software Foundation version 2 of the License.
9 *
10 */
11
12#ifndef _GNU_SOURCE
13#define _GNU_SOURCE 1
14#endif
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <unistd.h>
19#include <fcntl.h>
20#include <ctype.h>
21#include <string.h>
22#include <errno.h>
23#include <sys/ioctl.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <linux/types.h>
27
28#include "../../udev.h"
29
30/*
31 * Taken from the cdrom.h kernel include file.
32 * Included here as some distros don't have an updated version
33 * with all of the DVD flags.  So we just include our own, aren't
34 * we so nice...
35 */
36#define CDROM_GET_CAPABILITY	0x5331	/* get capabilities */
37
38/* capability flags used with the uniform CD-ROM driver */
39#define CDC_CLOSE_TRAY		0x1	/* caddy systems _can't_ close */
40#define CDC_OPEN_TRAY		0x2	/* but _can_ eject.  */
41#define CDC_LOCK		0x4	/* disable manual eject */
42#define CDC_SELECT_SPEED 	0x8	/* programmable speed */
43#define CDC_SELECT_DISC		0x10	/* select disc from juke-box */
44#define CDC_MULTI_SESSION 	0x20	/* read sessions>1 */
45#define CDC_MCN			0x40	/* Medium Catalog Number */
46#define CDC_MEDIA_CHANGED 	0x80	/* media changed */
47#define CDC_PLAY_AUDIO		0x100	/* audio functions */
48#define CDC_RESET		0x200	/* hard reset device */
49#define CDC_IOCTLS		0x400	/* driver has non-standard ioctls */
50#define CDC_DRIVE_STATUS	0x800	/* driver implements drive status */
51#define CDC_GENERIC_PACKET	0x1000	/* driver implements generic packets */
52#define CDC_CD_R		0x2000	/* drive is a CD-R */
53#define CDC_CD_RW		0x4000	/* drive is a CD-RW */
54#define CDC_DVD			0x8000	/* drive is a DVD */
55#define CDC_DVD_R		0x10000	/* drive can write DVD-R */
56#define CDC_DVD_RAM		0x20000	/* drive can write DVD-RAM */
57#define CDC_MO_DRIVE		0x40000	/* drive is an MO device */
58#define CDC_MRW			0x80000	/* drive can read MRW */
59#define CDC_MRW_W		0x100000 /* drive can write MRW */
60#define CDC_RAM			0x200000 /* ok to open for WRITE */
61
62#ifdef USE_LOG
63void log_message(int priority, const char *format, ...)
64{
65	va_list args;
66	static int udev_log = -1;
67
68	if (udev_log == -1) {
69		const char *value;
70
71		value = getenv("UDEV_LOG");
72		if (value)
73			udev_log = log_priority(value);
74		else
75			udev_log = LOG_ERR;
76	}
77
78	if (priority > udev_log)
79		return;
80
81	va_start(args, format);
82	vsyslog(priority, format, args);
83	va_end(args);
84}
85#endif
86
87int main(int argc, char *argv[])
88{
89	const char *node = NULL;
90	int i;
91	int export = 0;
92	int fd;
93	int rc = 0;
94	int result;
95
96	logging_init("cdrom_id");
97
98	for (i = 1 ; i < argc; i++) {
99		char *arg = argv[i];
100
101		if (strcmp(arg, "--export") == 0) {
102			export = 1;
103		} else
104			node = arg;
105	}
106	if (!node) {
107		info("no node specified");
108		rc = 1;
109		goto exit;
110	}
111
112	fd = open(node, O_RDONLY|O_NONBLOCK);
113	if (fd < 0) {
114		info("unable to open '%s'", node);
115		rc = 1;
116		goto exit;
117	}
118
119	result = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
120	if (result < 0) {
121		info("CDROM_GET_CAPABILITY failed for '%s'", node);
122		rc = 3;
123		goto close;
124	}
125
126	printf("ID_CDROM=1\n");
127
128	if (result & CDC_CD_R)
129		printf("ID_CDROM_CD_R=1\n");
130	if (result & CDC_CD_RW)
131		printf("ID_CDROM_CD_RW=1\n");
132
133	if (result & CDC_DVD)
134		printf("ID_CDROM_DVD=1\n");
135	if (result & CDC_DVD_R)
136		printf("ID_CDROM_DVD_R=1\n");
137	if (result & CDC_DVD_RAM)
138		printf("ID_CDROM_DVD_RAM=1\n");
139
140	if (result & CDC_MRW)
141		printf("ID_CDROM_MRW=1\n");
142	if (result & CDC_MRW_W)
143		printf("ID_CDROM_MRW_W=1\n");
144
145	if (result & CDC_RAM)
146		printf("ID_CDROM_RAM=1\n");
147close:
148	close(fd);
149exit:
150	logging_close();
151	return rc;
152}
153