File: | build-scan/../src/udev/cdrom_id/cdrom_id.c |
Warning: | line 807, column 39 The left operand of '&' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | |||
2 | /* | |||
3 | * cdrom_id - optical drive and media information prober | |||
4 | * | |||
5 | * | |||
6 | */ | |||
7 | ||||
8 | #include <errno(*__errno_location ()).h> | |||
9 | #include <fcntl.h> | |||
10 | #include <getopt.h> | |||
11 | #include <limits.h> | |||
12 | #include <linux1/cdrom.h> | |||
13 | #include <scsi/sg.h> | |||
14 | #include <stddef.h> | |||
15 | #include <stdio.h> | |||
16 | #include <stdlib.h> | |||
17 | #include <string.h> | |||
18 | #include <sys/ioctl.h> | |||
19 | #include <sys/stat.h> | |||
20 | #include <sys/time.h> | |||
21 | #include <sys/types.h> | |||
22 | #include <time.h> | |||
23 | #include <unistd.h> | |||
24 | ||||
25 | #include "libudev.h" | |||
26 | ||||
27 | #include "libudev-private.h" | |||
28 | #include "random-util.h" | |||
29 | #include "udev-util.h" | |||
30 | ||||
31 | /* device info */ | |||
32 | static unsigned int cd_cd_rom; | |||
33 | static unsigned int cd_cd_r; | |||
34 | static unsigned int cd_cd_rw; | |||
35 | static unsigned int cd_dvd_rom; | |||
36 | static unsigned int cd_dvd_r; | |||
37 | static unsigned int cd_dvd_rw; | |||
38 | static unsigned int cd_dvd_ram; | |||
39 | static unsigned int cd_dvd_plus_r; | |||
40 | static unsigned int cd_dvd_plus_rw; | |||
41 | static unsigned int cd_dvd_plus_r_dl; | |||
42 | static unsigned int cd_dvd_plus_rw_dl; | |||
43 | static unsigned int cd_bd; | |||
44 | static unsigned int cd_bd_r; | |||
45 | static unsigned int cd_bd_re; | |||
46 | static unsigned int cd_hddvd; | |||
47 | static unsigned int cd_hddvd_r; | |||
48 | static unsigned int cd_hddvd_rw; | |||
49 | static unsigned int cd_mo; | |||
50 | static unsigned int cd_mrw; | |||
51 | static unsigned int cd_mrw_w; | |||
52 | ||||
53 | /* media info */ | |||
54 | static unsigned int cd_media; | |||
55 | static unsigned int cd_media_cd_rom; | |||
56 | static unsigned int cd_media_cd_r; | |||
57 | static unsigned int cd_media_cd_rw; | |||
58 | static unsigned int cd_media_dvd_rom; | |||
59 | static unsigned int cd_media_dvd_r; | |||
60 | static unsigned int cd_media_dvd_rw; | |||
61 | static unsigned int cd_media_dvd_rw_ro; /* restricted overwrite mode */ | |||
62 | static unsigned int cd_media_dvd_rw_seq; /* sequential mode */ | |||
63 | static unsigned int cd_media_dvd_ram; | |||
64 | static unsigned int cd_media_dvd_plus_r; | |||
65 | static unsigned int cd_media_dvd_plus_rw; | |||
66 | static unsigned int cd_media_dvd_plus_r_dl; | |||
67 | static unsigned int cd_media_dvd_plus_rw_dl; | |||
68 | static unsigned int cd_media_bd; | |||
69 | static unsigned int cd_media_bd_r; | |||
70 | static unsigned int cd_media_bd_re; | |||
71 | static unsigned int cd_media_hddvd; | |||
72 | static unsigned int cd_media_hddvd_r; | |||
73 | static unsigned int cd_media_hddvd_rw; | |||
74 | static unsigned int cd_media_mo; | |||
75 | static unsigned int cd_media_mrw; | |||
76 | static unsigned int cd_media_mrw_w; | |||
77 | ||||
78 | static const char *cd_media_state = NULL((void*)0); | |||
79 | static unsigned int cd_media_session_next; | |||
80 | static unsigned int cd_media_session_count; | |||
81 | static unsigned int cd_media_track_count; | |||
82 | static unsigned int cd_media_track_count_data; | |||
83 | static unsigned int cd_media_track_count_audio; | |||
84 | static unsigned long long int cd_media_session_last_offset; | |||
85 | ||||
86 | #define ERRCODE(s)((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ( (s)[13])) ((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ((s)[13])) | |||
87 | #define SK(errcode)(((errcode) >> 16) & 0xF) (((errcode) >> 16) & 0xF) | |||
88 | #define ASC(errcode)(((errcode) >> 8) & 0xFF) (((errcode) >> 8) & 0xFF) | |||
89 | #define ASCQ(errcode)((errcode) & 0xFF) ((errcode) & 0xFF) | |||
90 | ||||
91 | static bool_Bool is_mounted(const char *device) | |||
92 | { | |||
93 | struct stat statbuf; | |||
94 | FILE *fp; | |||
95 | int maj, min; | |||
96 | bool_Bool mounted = false0; | |||
97 | ||||
98 | if (stat(device, &statbuf) < 0) | |||
99 | return false0; | |||
100 | ||||
101 | fp = fopen("/proc/self/mountinfo", "re"); | |||
102 | if (fp == NULL((void*)0)) | |||
103 | return false0; | |||
104 | while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) { | |||
105 | if (makedev(maj, min)gnu_dev_makedev (maj, min) == statbuf.st_rdev) { | |||
106 | mounted = true1; | |||
107 | break; | |||
108 | } | |||
109 | } | |||
110 | fclose(fp); | |||
111 | return mounted; | |||
112 | } | |||
113 | ||||
114 | static void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err) | |||
115 | { | |||
116 | if (err == -1) { | |||
117 | log_debug("%s failed", cmd)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 117, __func__, "%s failed" , cmd) : -abs(_e); }); | |||
118 | return; | |||
119 | } | |||
120 | log_debug("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh", cmd, SK(err), ASC(err), ASCQ(err))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 120, __func__, "%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh" , cmd, (((err) >> 16) & 0xF), (((err) >> 8) & 0xFF), ((err) & 0xFF)) : -abs(_e); }); | |||
121 | } | |||
122 | ||||
123 | struct scsi_cmd { | |||
124 | struct cdrom_generic_command cgc; | |||
125 | union { | |||
126 | struct request_sense s; | |||
127 | unsigned char u[18]; | |||
128 | } _sense; | |||
129 | struct sg_io_hdr sg_io; | |||
130 | }; | |||
131 | ||||
132 | static void scsi_cmd_init(struct udev *udev, struct scsi_cmd *cmd) | |||
133 | { | |||
134 | memzero(cmd, sizeof(struct scsi_cmd))({ size_t _l_ = (sizeof(struct scsi_cmd)); void *_x_ = (cmd); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); }); | |||
135 | cmd->cgc.quiet = 1; | |||
136 | cmd->cgc.sense = &cmd->_sense.s; | |||
137 | cmd->sg_io.interface_id = 'S'; | |||
138 | cmd->sg_io.mx_sb_len = sizeof(cmd->_sense); | |||
139 | cmd->sg_io.cmdp = cmd->cgc.cmd; | |||
140 | cmd->sg_io.sbp = cmd->_sense.u; | |||
141 | cmd->sg_io.flags = SG_FLAG_LUN_INHIBIT2 | SG_FLAG_DIRECT_IO1; | |||
142 | } | |||
143 | ||||
144 | static void scsi_cmd_set(struct udev *udev, struct scsi_cmd *cmd, size_t i, unsigned char arg) | |||
145 | { | |||
146 | cmd->sg_io.cmd_len = i + 1; | |||
147 | cmd->cgc.cmd[i] = arg; | |||
148 | } | |||
149 | ||||
150 | #define CHECK_CONDITION0x01 0x01 | |||
151 | ||||
152 | static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize) | |||
153 | { | |||
154 | int ret = 0; | |||
155 | ||||
156 | if (bufsize > 0) { | |||
157 | cmd->sg_io.dxferp = buf; | |||
158 | cmd->sg_io.dxfer_len = bufsize; | |||
159 | cmd->sg_io.dxfer_direction = SG_DXFER_FROM_DEV-3; | |||
160 | } else { | |||
161 | cmd->sg_io.dxfer_direction = SG_DXFER_NONE-1; | |||
162 | } | |||
163 | if (ioctl(fd, SG_IO0x2285, &cmd->sg_io)) | |||
164 | return -1; | |||
165 | ||||
166 | if ((cmd->sg_io.info & SG_INFO_OK_MASK0x1) != SG_INFO_OK0x0) { | |||
167 | errno(*__errno_location ()) = EIO5; | |||
168 | ret = -1; | |||
169 | if (cmd->sg_io.masked_status & CHECK_CONDITION0x01) { | |||
170 | ret = ERRCODE(cmd->_sense.u)((((cmd->_sense.u)[2] & 0x0F) << 16) | ((cmd-> _sense.u)[12] << 8) | ((cmd->_sense.u)[13])); | |||
171 | if (ret == 0) | |||
172 | ret = -1; | |||
173 | } | |||
174 | } | |||
175 | return ret; | |||
176 | } | |||
177 | ||||
178 | static int media_lock(struct udev *udev, int fd, bool_Bool lock) | |||
179 | { | |||
180 | int err; | |||
181 | ||||
182 | /* disable the kernel's lock logic */ | |||
183 | err = ioctl(fd, CDROM_CLEAR_OPTIONS0x5321, CDO_LOCK0x8); | |||
184 | if (err < 0) | |||
185 | log_debug("CDROM_CLEAR_OPTIONS, CDO_LOCK failed")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 185, __func__, "CDROM_CLEAR_OPTIONS, CDO_LOCK failed" ) : -abs(_e); }); | |||
186 | ||||
187 | err = ioctl(fd, CDROM_LOCKDOOR0x5329, lock ? 1 : 0); | |||
188 | if (err < 0) | |||
189 | log_debug("CDROM_LOCKDOOR failed")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 189, __func__, "CDROM_LOCKDOOR failed" ) : -abs(_e); }); | |||
190 | ||||
191 | return err; | |||
192 | } | |||
193 | ||||
194 | static int media_eject(struct udev *udev, int fd) | |||
195 | { | |||
196 | struct scsi_cmd sc; | |||
197 | int err; | |||
198 | ||||
199 | scsi_cmd_init(udev, &sc); | |||
200 | scsi_cmd_set(udev, &sc, 0, 0x1b); | |||
201 | scsi_cmd_set(udev, &sc, 4, 0x02); | |||
202 | scsi_cmd_set(udev, &sc, 5, 0); | |||
203 | err = scsi_cmd_run(udev, &sc, fd, NULL((void*)0), 0); | |||
204 | if ((err != 0)) { | |||
205 | info_scsi_cmd_err(udev, "START_STOP_UNIT", err); | |||
206 | return -1; | |||
207 | } | |||
208 | return 0; | |||
209 | } | |||
210 | ||||
211 | static int cd_capability_compat(struct udev *udev, int fd) | |||
212 | { | |||
213 | int capability; | |||
214 | ||||
215 | capability = ioctl(fd, CDROM_GET_CAPABILITY0x5331, NULL((void*)0)); | |||
216 | if (capability < 0) { | |||
217 | log_debug("CDROM_GET_CAPABILITY failed")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 217, __func__, "CDROM_GET_CAPABILITY failed" ) : -abs(_e); }); | |||
218 | return -1; | |||
219 | } | |||
220 | ||||
221 | if (capability & CDC_CD_R0x2000) | |||
222 | cd_cd_r = 1; | |||
223 | if (capability & CDC_CD_RW0x4000) | |||
224 | cd_cd_rw = 1; | |||
225 | if (capability & CDC_DVD0x8000) | |||
226 | cd_dvd_rom = 1; | |||
227 | if (capability & CDC_DVD_R0x10000) | |||
228 | cd_dvd_r = 1; | |||
229 | if (capability & CDC_DVD_RAM0x20000) | |||
230 | cd_dvd_ram = 1; | |||
231 | if (capability & CDC_MRW0x80000) | |||
232 | cd_mrw = 1; | |||
233 | if (capability & CDC_MRW_W0x100000) | |||
234 | cd_mrw_w = 1; | |||
235 | return 0; | |||
236 | } | |||
237 | ||||
238 | static int cd_media_compat(struct udev *udev, int fd) | |||
239 | { | |||
240 | if (ioctl(fd, CDROM_DRIVE_STATUS0x5326, CDSL_CURRENT2147483647) != CDS_DISC_OK4) { | |||
241 | log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 241, __func__, "CDROM_DRIVE_STATUS != CDS_DISC_OK" ) : -abs(_e); }); | |||
242 | return -1; | |||
243 | } | |||
244 | cd_media = 1; | |||
245 | return 0; | |||
246 | } | |||
247 | ||||
248 | static int cd_inquiry(struct udev *udev, int fd) | |||
249 | { | |||
250 | struct scsi_cmd sc; | |||
251 | unsigned char inq[128]; | |||
252 | int err; | |||
253 | ||||
254 | scsi_cmd_init(udev, &sc); | |||
255 | scsi_cmd_set(udev, &sc, 0, 0x12); | |||
256 | scsi_cmd_set(udev, &sc, 4, 36); | |||
257 | scsi_cmd_set(udev, &sc, 5, 0); | |||
258 | err = scsi_cmd_run(udev, &sc, fd, inq, 36); | |||
259 | if ((err != 0)) { | |||
260 | info_scsi_cmd_err(udev, "INQUIRY", err); | |||
261 | return -1; | |||
262 | } | |||
263 | ||||
264 | if ((inq[0] & 0x1F) != 5) { | |||
265 | log_debug("not an MMC unit")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 265, __func__, "not an MMC unit" ) : -abs(_e); }); | |||
266 | return -1; | |||
267 | } | |||
268 | ||||
269 | log_debug("INQUIRY: [%.8s][%.16s][%.4s]", inq + 8, inq + 16, inq + 32)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 269, __func__, "INQUIRY: [%.8s][%.16s][%.4s]" , inq + 8, inq + 16, inq + 32) : -abs(_e); }); | |||
270 | return 0; | |||
271 | } | |||
272 | ||||
273 | static void feature_profile_media(struct udev *udev, int cur_profile) | |||
274 | { | |||
275 | switch (cur_profile) { | |||
276 | case 0x03: | |||
277 | case 0x04: | |||
278 | case 0x05: | |||
279 | log_debug("profile 0x%02x ", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 279, __func__, "profile 0x%02x " , cur_profile) : -abs(_e); }); | |||
280 | cd_media = 1; | |||
281 | cd_media_mo = 1; | |||
282 | break; | |||
283 | case 0x08: | |||
284 | log_debug("profile 0x%02x media_cd_rom", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 284, __func__, "profile 0x%02x media_cd_rom" , cur_profile) : -abs(_e); }); | |||
285 | cd_media = 1; | |||
286 | cd_media_cd_rom = 1; | |||
287 | break; | |||
288 | case 0x09: | |||
289 | log_debug("profile 0x%02x media_cd_r", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 289, __func__, "profile 0x%02x media_cd_r" , cur_profile) : -abs(_e); }); | |||
290 | cd_media = 1; | |||
291 | cd_media_cd_r = 1; | |||
292 | break; | |||
293 | case 0x0a: | |||
294 | log_debug("profile 0x%02x media_cd_rw", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 294, __func__, "profile 0x%02x media_cd_rw" , cur_profile) : -abs(_e); }); | |||
295 | cd_media = 1; | |||
296 | cd_media_cd_rw = 1; | |||
297 | break; | |||
298 | case 0x10: | |||
299 | log_debug("profile 0x%02x media_dvd_ro", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 299, __func__, "profile 0x%02x media_dvd_ro" , cur_profile) : -abs(_e); }); | |||
300 | cd_media = 1; | |||
301 | cd_media_dvd_rom = 1; | |||
302 | break; | |||
303 | case 0x11: | |||
304 | log_debug("profile 0x%02x media_dvd_r", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 304, __func__, "profile 0x%02x media_dvd_r" , cur_profile) : -abs(_e); }); | |||
305 | cd_media = 1; | |||
306 | cd_media_dvd_r = 1; | |||
307 | break; | |||
308 | case 0x12: | |||
309 | log_debug("profile 0x%02x media_dvd_ram", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 309, __func__, "profile 0x%02x media_dvd_ram" , cur_profile) : -abs(_e); }); | |||
310 | cd_media = 1; | |||
311 | cd_media_dvd_ram = 1; | |||
312 | break; | |||
313 | case 0x13: | |||
314 | log_debug("profile 0x%02x media_dvd_rw_ro", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 314, __func__, "profile 0x%02x media_dvd_rw_ro" , cur_profile) : -abs(_e); }); | |||
315 | cd_media = 1; | |||
316 | cd_media_dvd_rw = 1; | |||
317 | cd_media_dvd_rw_ro = 1; | |||
318 | break; | |||
319 | case 0x14: | |||
320 | log_debug("profile 0x%02x media_dvd_rw_seq", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 320, __func__, "profile 0x%02x media_dvd_rw_seq" , cur_profile) : -abs(_e); }); | |||
321 | cd_media = 1; | |||
322 | cd_media_dvd_rw = 1; | |||
323 | cd_media_dvd_rw_seq = 1; | |||
324 | break; | |||
325 | case 0x1B: | |||
326 | log_debug("profile 0x%02x media_dvd_plus_r", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 326, __func__, "profile 0x%02x media_dvd_plus_r" , cur_profile) : -abs(_e); }); | |||
327 | cd_media = 1; | |||
328 | cd_media_dvd_plus_r = 1; | |||
329 | break; | |||
330 | case 0x1A: | |||
331 | log_debug("profile 0x%02x media_dvd_plus_rw", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 331, __func__, "profile 0x%02x media_dvd_plus_rw" , cur_profile) : -abs(_e); }); | |||
332 | cd_media = 1; | |||
333 | cd_media_dvd_plus_rw = 1; | |||
334 | break; | |||
335 | case 0x2A: | |||
336 | log_debug("profile 0x%02x media_dvd_plus_rw_dl", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 336, __func__, "profile 0x%02x media_dvd_plus_rw_dl" , cur_profile) : -abs(_e); }); | |||
337 | cd_media = 1; | |||
338 | cd_media_dvd_plus_rw_dl = 1; | |||
339 | break; | |||
340 | case 0x2B: | |||
341 | log_debug("profile 0x%02x media_dvd_plus_r_dl", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 341, __func__, "profile 0x%02x media_dvd_plus_r_dl" , cur_profile) : -abs(_e); }); | |||
342 | cd_media = 1; | |||
343 | cd_media_dvd_plus_r_dl = 1; | |||
344 | break; | |||
345 | case 0x40: | |||
346 | log_debug("profile 0x%02x media_bd", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 346, __func__, "profile 0x%02x media_bd" , cur_profile) : -abs(_e); }); | |||
347 | cd_media = 1; | |||
348 | cd_media_bd = 1; | |||
349 | break; | |||
350 | case 0x41: | |||
351 | case 0x42: | |||
352 | log_debug("profile 0x%02x media_bd_r", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 352, __func__, "profile 0x%02x media_bd_r" , cur_profile) : -abs(_e); }); | |||
353 | cd_media = 1; | |||
354 | cd_media_bd_r = 1; | |||
355 | break; | |||
356 | case 0x43: | |||
357 | log_debug("profile 0x%02x media_bd_re", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 357, __func__, "profile 0x%02x media_bd_re" , cur_profile) : -abs(_e); }); | |||
358 | cd_media = 1; | |||
359 | cd_media_bd_re = 1; | |||
360 | break; | |||
361 | case 0x50: | |||
362 | log_debug("profile 0x%02x media_hddvd", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 362, __func__, "profile 0x%02x media_hddvd" , cur_profile) : -abs(_e); }); | |||
363 | cd_media = 1; | |||
364 | cd_media_hddvd = 1; | |||
365 | break; | |||
366 | case 0x51: | |||
367 | log_debug("profile 0x%02x media_hddvd_r", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 367, __func__, "profile 0x%02x media_hddvd_r" , cur_profile) : -abs(_e); }); | |||
368 | cd_media = 1; | |||
369 | cd_media_hddvd_r = 1; | |||
370 | break; | |||
371 | case 0x52: | |||
372 | log_debug("profile 0x%02x media_hddvd_rw", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 372, __func__, "profile 0x%02x media_hddvd_rw" , cur_profile) : -abs(_e); }); | |||
373 | cd_media = 1; | |||
374 | cd_media_hddvd_rw = 1; | |||
375 | break; | |||
376 | default: | |||
377 | log_debug("profile 0x%02x <ignored>", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 377, __func__, "profile 0x%02x <ignored>" , cur_profile) : -abs(_e); }); | |||
378 | break; | |||
379 | } | |||
380 | } | |||
381 | ||||
382 | static int feature_profiles(struct udev *udev, const unsigned char *profiles, size_t size) | |||
383 | { | |||
384 | unsigned int i; | |||
385 | ||||
386 | for (i = 0; i+4 <= size; i += 4) { | |||
387 | int profile; | |||
388 | ||||
389 | profile = profiles[i] << 8 | profiles[i+1]; | |||
390 | switch (profile) { | |||
391 | case 0x03: | |||
392 | case 0x04: | |||
393 | case 0x05: | |||
394 | log_debug("profile 0x%02x mo", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 394, __func__, "profile 0x%02x mo" , profile) : -abs(_e); }); | |||
395 | cd_mo = 1; | |||
396 | break; | |||
397 | case 0x08: | |||
398 | log_debug("profile 0x%02x cd_rom", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 398, __func__, "profile 0x%02x cd_rom" , profile) : -abs(_e); }); | |||
399 | cd_cd_rom = 1; | |||
400 | break; | |||
401 | case 0x09: | |||
402 | log_debug("profile 0x%02x cd_r", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 402, __func__, "profile 0x%02x cd_r" , profile) : -abs(_e); }); | |||
403 | cd_cd_r = 1; | |||
404 | break; | |||
405 | case 0x0A: | |||
406 | log_debug("profile 0x%02x cd_rw", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 406, __func__, "profile 0x%02x cd_rw" , profile) : -abs(_e); }); | |||
407 | cd_cd_rw = 1; | |||
408 | break; | |||
409 | case 0x10: | |||
410 | log_debug("profile 0x%02x dvd_rom", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 410, __func__, "profile 0x%02x dvd_rom" , profile) : -abs(_e); }); | |||
411 | cd_dvd_rom = 1; | |||
412 | break; | |||
413 | case 0x12: | |||
414 | log_debug("profile 0x%02x dvd_ram", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 414, __func__, "profile 0x%02x dvd_ram" , profile) : -abs(_e); }); | |||
415 | cd_dvd_ram = 1; | |||
416 | break; | |||
417 | case 0x13: | |||
418 | case 0x14: | |||
419 | log_debug("profile 0x%02x dvd_rw", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 419, __func__, "profile 0x%02x dvd_rw" , profile) : -abs(_e); }); | |||
420 | cd_dvd_rw = 1; | |||
421 | break; | |||
422 | case 0x1B: | |||
423 | log_debug("profile 0x%02x dvd_plus_r", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 423, __func__, "profile 0x%02x dvd_plus_r" , profile) : -abs(_e); }); | |||
424 | cd_dvd_plus_r = 1; | |||
425 | break; | |||
426 | case 0x1A: | |||
427 | log_debug("profile 0x%02x dvd_plus_rw", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 427, __func__, "profile 0x%02x dvd_plus_rw" , profile) : -abs(_e); }); | |||
428 | cd_dvd_plus_rw = 1; | |||
429 | break; | |||
430 | case 0x2A: | |||
431 | log_debug("profile 0x%02x dvd_plus_rw_dl", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 431, __func__, "profile 0x%02x dvd_plus_rw_dl" , profile) : -abs(_e); }); | |||
432 | cd_dvd_plus_rw_dl = 1; | |||
433 | break; | |||
434 | case 0x2B: | |||
435 | log_debug("profile 0x%02x dvd_plus_r_dl", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 435, __func__, "profile 0x%02x dvd_plus_r_dl" , profile) : -abs(_e); }); | |||
436 | cd_dvd_plus_r_dl = 1; | |||
437 | break; | |||
438 | case 0x40: | |||
439 | cd_bd = 1; | |||
440 | log_debug("profile 0x%02x bd", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 440, __func__, "profile 0x%02x bd" , profile) : -abs(_e); }); | |||
441 | break; | |||
442 | case 0x41: | |||
443 | case 0x42: | |||
444 | cd_bd_r = 1; | |||
445 | log_debug("profile 0x%02x bd_r", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 445, __func__, "profile 0x%02x bd_r" , profile) : -abs(_e); }); | |||
446 | break; | |||
447 | case 0x43: | |||
448 | cd_bd_re = 1; | |||
449 | log_debug("profile 0x%02x bd_re", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 449, __func__, "profile 0x%02x bd_re" , profile) : -abs(_e); }); | |||
450 | break; | |||
451 | case 0x50: | |||
452 | cd_hddvd = 1; | |||
453 | log_debug("profile 0x%02x hddvd", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 453, __func__, "profile 0x%02x hddvd" , profile) : -abs(_e); }); | |||
454 | break; | |||
455 | case 0x51: | |||
456 | cd_hddvd_r = 1; | |||
457 | log_debug("profile 0x%02x hddvd_r", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 457, __func__, "profile 0x%02x hddvd_r" , profile) : -abs(_e); }); | |||
458 | break; | |||
459 | case 0x52: | |||
460 | cd_hddvd_rw = 1; | |||
461 | log_debug("profile 0x%02x hddvd_rw", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 461, __func__, "profile 0x%02x hddvd_rw" , profile) : -abs(_e); }); | |||
462 | break; | |||
463 | default: | |||
464 | log_debug("profile 0x%02x <ignored>", profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 464, __func__, "profile 0x%02x <ignored>" , profile) : -abs(_e); }); | |||
465 | break; | |||
466 | } | |||
467 | } | |||
468 | return 0; | |||
469 | } | |||
470 | ||||
471 | /* returns 0 if media was detected */ | |||
472 | static int cd_profiles_old_mmc(struct udev *udev, int fd) | |||
473 | { | |||
474 | struct scsi_cmd sc; | |||
475 | int err; | |||
476 | ||||
477 | unsigned char header[32]; | |||
478 | ||||
479 | scsi_cmd_init(udev, &sc); | |||
480 | scsi_cmd_set(udev, &sc, 0, 0x51); | |||
481 | scsi_cmd_set(udev, &sc, 8, sizeof(header)); | |||
482 | scsi_cmd_set(udev, &sc, 9, 0); | |||
483 | err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); | |||
484 | if ((err != 0)) { | |||
485 | info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); | |||
486 | if (cd_media == 1) { | |||
487 | log_debug("no current profile, but disc is present; assuming CD-ROM")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 487, __func__, "no current profile, but disc is present; assuming CD-ROM" ) : -abs(_e); }); | |||
488 | cd_media_cd_rom = 1; | |||
489 | cd_media_track_count = 1; | |||
490 | cd_media_track_count_data = 1; | |||
491 | return 0; | |||
492 | } else { | |||
493 | log_debug("no current profile, assuming no media")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 493, __func__, "no current profile, assuming no media" ) : -abs(_e); }); | |||
494 | return -1; | |||
495 | } | |||
496 | }; | |||
497 | ||||
498 | cd_media = 1; | |||
499 | ||||
500 | if (header[2] & 16) { | |||
501 | cd_media_cd_rw = 1; | |||
502 | log_debug("profile 0x0a media_cd_rw")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 502, __func__, "profile 0x0a media_cd_rw" ) : -abs(_e); }); | |||
503 | } else if ((header[2] & 3) < 2 && cd_cd_r) { | |||
504 | cd_media_cd_r = 1; | |||
505 | log_debug("profile 0x09 media_cd_r")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 505, __func__, "profile 0x09 media_cd_r" ) : -abs(_e); }); | |||
506 | } else { | |||
507 | cd_media_cd_rom = 1; | |||
508 | log_debug("profile 0x08 media_cd_rom")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 508, __func__, "profile 0x08 media_cd_rom" ) : -abs(_e); }); | |||
509 | } | |||
510 | return 0; | |||
511 | } | |||
512 | ||||
513 | /* returns 0 if media was detected */ | |||
514 | static int cd_profiles(struct udev *udev, int fd) | |||
515 | { | |||
516 | struct scsi_cmd sc; | |||
517 | unsigned char features[65530]; | |||
518 | unsigned int cur_profile = 0; | |||
519 | unsigned int len; | |||
520 | unsigned int i; | |||
521 | int err; | |||
522 | int ret; | |||
523 | ||||
524 | ret = -1; | |||
525 | ||||
526 | /* First query the current profile */ | |||
527 | scsi_cmd_init(udev, &sc); | |||
528 | scsi_cmd_set(udev, &sc, 0, 0x46); | |||
529 | scsi_cmd_set(udev, &sc, 8, 8); | |||
530 | scsi_cmd_set(udev, &sc, 9, 0); | |||
531 | err = scsi_cmd_run(udev, &sc, fd, features, 8); | |||
532 | if ((err != 0)) { | |||
533 | info_scsi_cmd_err(udev, "GET CONFIGURATION", err); | |||
534 | /* handle pre-MMC2 drives which do not support GET CONFIGURATION */ | |||
535 | if (SK(err)(((err) >> 16) & 0xF) == 0x5 && IN_SET(ASC(err), 0x20, 0x24)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){0x20, 0x24})/sizeof(int)]; switch((((err ) >> 8) & 0xFF)) { case 0x20: case 0x24: _found = 1 ; break; default: break; } _found; })) { | |||
536 | log_debug("drive is pre-MMC2 and does not support 46h get configuration command")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 536, __func__, "drive is pre-MMC2 and does not support 46h get configuration command" ) : -abs(_e); }); | |||
537 | log_debug("trying to work around the problem")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 537, __func__, "trying to work around the problem" ) : -abs(_e); }); | |||
538 | ret = cd_profiles_old_mmc(udev, fd); | |||
539 | } | |||
540 | goto out; | |||
541 | } | |||
542 | ||||
543 | cur_profile = features[6] << 8 | features[7]; | |||
544 | if (cur_profile > 0) { | |||
545 | log_debug("current profile 0x%02x", cur_profile)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 545, __func__, "current profile 0x%02x" , cur_profile) : -abs(_e); }); | |||
546 | feature_profile_media (udev, cur_profile); | |||
547 | ret = 0; /* we have media */ | |||
548 | } else { | |||
549 | log_debug("no current profile, assuming no media")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 549, __func__, "no current profile, assuming no media" ) : -abs(_e); }); | |||
550 | } | |||
551 | ||||
552 | len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; | |||
553 | log_debug("GET CONFIGURATION: size of features buffer 0x%04x", len)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 553, __func__, "GET CONFIGURATION: size of features buffer 0x%04x" , len) : -abs(_e); }); | |||
554 | ||||
555 | if (len > sizeof(features)) { | |||
556 | log_debug("cannot get features in a single query, truncating")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 556, __func__, "cannot get features in a single query, truncating" ) : -abs(_e); }); | |||
557 | len = sizeof(features); | |||
558 | } else if (len <= 8) | |||
559 | len = sizeof(features); | |||
560 | ||||
561 | /* Now get the full feature buffer */ | |||
562 | scsi_cmd_init(udev, &sc); | |||
563 | scsi_cmd_set(udev, &sc, 0, 0x46); | |||
564 | scsi_cmd_set(udev, &sc, 7, ( len >> 8 ) & 0xff); | |||
565 | scsi_cmd_set(udev, &sc, 8, len & 0xff); | |||
566 | scsi_cmd_set(udev, &sc, 9, 0); | |||
567 | err = scsi_cmd_run(udev, &sc, fd, features, len); | |||
568 | if ((err != 0)) { | |||
569 | info_scsi_cmd_err(udev, "GET CONFIGURATION", err); | |||
570 | return -1; | |||
571 | } | |||
572 | ||||
573 | /* parse the length once more, in case the drive decided to have other features suddenly :) */ | |||
574 | len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; | |||
575 | log_debug("GET CONFIGURATION: size of features buffer 0x%04x", len)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 575, __func__, "GET CONFIGURATION: size of features buffer 0x%04x" , len) : -abs(_e); }); | |||
576 | ||||
577 | if (len > sizeof(features)) { | |||
578 | log_debug("cannot get features in a single query, truncating")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 578, __func__, "cannot get features in a single query, truncating" ) : -abs(_e); }); | |||
579 | len = sizeof(features); | |||
580 | } | |||
581 | ||||
582 | /* device features */ | |||
583 | for (i = 8; i+4 < len; i += (4 + features[i+3])) { | |||
584 | unsigned int feature; | |||
585 | ||||
586 | feature = features[i] << 8 | features[i+1]; | |||
587 | ||||
588 | switch (feature) { | |||
589 | case 0x00: | |||
590 | log_debug("GET CONFIGURATION: feature 'profiles', with %i entries", features[i+3] / 4)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 590, __func__, "GET CONFIGURATION: feature 'profiles', with %i entries" , features[i+3] / 4) : -abs(_e); }); | |||
591 | feature_profiles(udev, &features[i]+4, MIN(features[i+3], len - i - 4)__extension__ ({ const typeof((features[i+3])) __unique_prefix_A2 = ((features[i+3])); const typeof((len - i - 4)) __unique_prefix_B3 = ((len - i - 4)); __unique_prefix_A2 < __unique_prefix_B3 ? __unique_prefix_A2 : __unique_prefix_B3; })); | |||
592 | break; | |||
593 | default: | |||
594 | log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes", feature, features[i+3])({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 594, __func__, "GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes" , feature, features[i+3]) : -abs(_e); }); | |||
595 | break; | |||
596 | } | |||
597 | } | |||
598 | out: | |||
599 | return ret; | |||
600 | } | |||
601 | ||||
602 | static int cd_media_info(struct udev *udev, int fd) | |||
603 | { | |||
604 | struct scsi_cmd sc; | |||
605 | unsigned char header[32]; | |||
606 | static const char *media_status[] = { | |||
607 | "blank", | |||
608 | "appendable", | |||
609 | "complete", | |||
610 | "other" | |||
611 | }; | |||
612 | int err; | |||
613 | ||||
614 | scsi_cmd_init(udev, &sc); | |||
615 | scsi_cmd_set(udev, &sc, 0, 0x51); | |||
616 | scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff); | |||
617 | scsi_cmd_set(udev, &sc, 9, 0); | |||
618 | err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); | |||
619 | if ((err != 0)) { | |||
620 | info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); | |||
621 | return -1; | |||
622 | }; | |||
623 | ||||
624 | cd_media = 1; | |||
625 | log_debug("disk type %02x", header[8])({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 625, __func__, "disk type %02x" , header[8]) : -abs(_e); }); | |||
626 | log_debug("hardware reported media status: %s", media_status[header[2] & 3])({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 626, __func__, "hardware reported media status: %s" , media_status[header[2] & 3]) : -abs(_e); }); | |||
627 | ||||
628 | /* exclude plain CDROM, some fake cdroms return 0 for "blank" media here */ | |||
629 | if (!cd_media_cd_rom) | |||
630 | cd_media_state = media_status[header[2] & 3]; | |||
631 | ||||
632 | /* fresh DVD-RW in restricted overwite mode reports itself as | |||
633 | * "appendable"; change it to "blank" to make it consistent with what | |||
634 | * gets reported after blanking, and what userspace expects */ | |||
635 | if (cd_media_dvd_rw_ro && (header[2] & 3) == 1) | |||
636 | cd_media_state = media_status[0]; | |||
637 | ||||
638 | /* DVD+RW discs (and DVD-RW in restricted mode) once formatted are | |||
639 | * always "complete", DVD-RAM are "other" or "complete" if the disc is | |||
640 | * write protected; we need to check the contents if it is blank */ | |||
641 | if ((cd_media_dvd_rw_ro || cd_media_dvd_plus_rw || cd_media_dvd_plus_rw_dl || cd_media_dvd_ram) && (header[2] & 3) > 1) { | |||
642 | unsigned char buffer[32 * 2048]; | |||
643 | unsigned char len; | |||
644 | int offset; | |||
645 | ||||
646 | if (cd_media_dvd_ram) { | |||
647 | /* a write protected dvd-ram may report "complete" status */ | |||
648 | ||||
649 | unsigned char dvdstruct[8]; | |||
650 | unsigned char format[12]; | |||
651 | ||||
652 | scsi_cmd_init(udev, &sc); | |||
653 | scsi_cmd_set(udev, &sc, 0, 0xAD); | |||
654 | scsi_cmd_set(udev, &sc, 7, 0xC0); | |||
655 | scsi_cmd_set(udev, &sc, 9, sizeof(dvdstruct)); | |||
656 | scsi_cmd_set(udev, &sc, 11, 0); | |||
657 | err = scsi_cmd_run(udev, &sc, fd, dvdstruct, sizeof(dvdstruct)); | |||
658 | if ((err != 0)) { | |||
659 | info_scsi_cmd_err(udev, "READ DVD STRUCTURE", err); | |||
660 | return -1; | |||
661 | } | |||
662 | if (dvdstruct[4] & 0x02) { | |||
663 | cd_media_state = media_status[2]; | |||
664 | log_debug("write-protected DVD-RAM media inserted")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 664, __func__, "write-protected DVD-RAM media inserted" ) : -abs(_e); }); | |||
665 | goto determined; | |||
666 | } | |||
667 | ||||
668 | /* let's make sure we don't try to read unformatted media */ | |||
669 | scsi_cmd_init(udev, &sc); | |||
670 | scsi_cmd_set(udev, &sc, 0, 0x23); | |||
671 | scsi_cmd_set(udev, &sc, 8, sizeof(format)); | |||
672 | scsi_cmd_set(udev, &sc, 9, 0); | |||
673 | err = scsi_cmd_run(udev, &sc, fd, format, sizeof(format)); | |||
674 | if ((err != 0)) { | |||
675 | info_scsi_cmd_err(udev, "READ DVD FORMAT CAPACITIES", err); | |||
676 | return -1; | |||
677 | } | |||
678 | ||||
679 | len = format[3]; | |||
680 | if (len & 7 || len < 16) { | |||
681 | log_debug("invalid format capacities length")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 681, __func__, "invalid format capacities length" ) : -abs(_e); }); | |||
682 | return -1; | |||
683 | } | |||
684 | ||||
685 | switch(format[8] & 3) { | |||
686 | case 1: | |||
687 | log_debug("unformatted DVD-RAM media inserted")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 687, __func__, "unformatted DVD-RAM media inserted" ) : -abs(_e); }); | |||
688 | /* This means that last format was interrupted | |||
689 | * or failed, blank dvd-ram discs are factory | |||
690 | * formatted. Take no action here as it takes | |||
691 | * quite a while to reformat a dvd-ram and it's | |||
692 | * not automatically started */ | |||
693 | goto determined; | |||
694 | ||||
695 | case 2: | |||
696 | log_debug("formatted DVD-RAM media inserted")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 696, __func__, "formatted DVD-RAM media inserted" ) : -abs(_e); }); | |||
697 | break; | |||
698 | ||||
699 | case 3: | |||
700 | cd_media = 0; //return no media | |||
701 | log_debug("format capacities returned no media")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 701, __func__, "format capacities returned no media" ) : -abs(_e); }); | |||
702 | return -1; | |||
703 | } | |||
704 | } | |||
705 | ||||
706 | /* Take a closer look at formatted media (unformatted DVD+RW | |||
707 | * has "blank" status", DVD-RAM was examined earlier) and check | |||
708 | * for ISO and UDF PVDs or a fs superblock presence and do it | |||
709 | * in one ioctl (we need just sectors 0 and 16) */ | |||
710 | scsi_cmd_init(udev, &sc); | |||
711 | scsi_cmd_set(udev, &sc, 0, 0x28); | |||
712 | scsi_cmd_set(udev, &sc, 5, 0); | |||
713 | scsi_cmd_set(udev, &sc, 8, 32); | |||
714 | scsi_cmd_set(udev, &sc, 9, 0); | |||
715 | err = scsi_cmd_run(udev, &sc, fd, buffer, sizeof(buffer)); | |||
716 | if ((err != 0)) { | |||
717 | cd_media = 0; | |||
718 | info_scsi_cmd_err(udev, "READ FIRST 32 BLOCKS", err); | |||
719 | return -1; | |||
720 | } | |||
721 | ||||
722 | /* if any non-zero data is found in sector 16 (iso and udf) or | |||
723 | * eventually 0 (fat32 boot sector, ext2 superblock, etc), disc | |||
724 | * is assumed non-blank */ | |||
725 | ||||
726 | for (offset = 32768; offset < (32768 + 2048); offset++) { | |||
727 | if (buffer [offset]) { | |||
728 | log_debug("data in block 16, assuming complete")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 728, __func__, "data in block 16, assuming complete" ) : -abs(_e); }); | |||
729 | goto determined; | |||
730 | } | |||
731 | } | |||
732 | ||||
733 | for (offset = 0; offset < 2048; offset++) { | |||
734 | if (buffer [offset]) { | |||
735 | log_debug("data in block 0, assuming complete")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 735, __func__, "data in block 0, assuming complete" ) : -abs(_e); }); | |||
736 | goto determined; | |||
737 | } | |||
738 | } | |||
739 | ||||
740 | cd_media_state = media_status[0]; | |||
741 | log_debug("no data in blocks 0 or 16, assuming blank")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 741, __func__, "no data in blocks 0 or 16, assuming blank" ) : -abs(_e); }); | |||
742 | } | |||
743 | ||||
744 | determined: | |||
745 | /* "other" is e. g. DVD-RAM, can't append sessions there; DVDs in | |||
746 | * restricted overwrite mode can never append, only in sequential mode */ | |||
747 | if ((header[2] & 3) < 2 && !cd_media_dvd_rw_ro) | |||
748 | cd_media_session_next = header[10] << 8 | header[5]; | |||
749 | cd_media_session_count = header[9] << 8 | header[4]; | |||
750 | cd_media_track_count = header[11] << 8 | header[6]; | |||
751 | ||||
752 | return 0; | |||
753 | } | |||
754 | ||||
755 | static int cd_media_toc(struct udev *udev, int fd) | |||
756 | { | |||
757 | struct scsi_cmd sc; | |||
758 | unsigned char header[12]; | |||
759 | unsigned char toc[65536]; | |||
760 | unsigned int len, i, num_tracks; | |||
761 | unsigned char *p; | |||
762 | int err; | |||
763 | ||||
764 | scsi_cmd_init(udev, &sc); | |||
765 | scsi_cmd_set(udev, &sc, 0, 0x43); | |||
766 | scsi_cmd_set(udev, &sc, 6, 1); | |||
767 | scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff); | |||
768 | scsi_cmd_set(udev, &sc, 9, 0); | |||
769 | err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); | |||
770 | if ((err
| |||
771 | info_scsi_cmd_err(udev, "READ TOC", err); | |||
772 | return -1; | |||
773 | } | |||
774 | ||||
775 | len = (header[0] << 8 | header[1]) + 2; | |||
776 | log_debug("READ TOC: len: %d, start track: %d, end track: %d", len, header[2], header[3])({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 776, __func__, "READ TOC: len: %d, start track: %d, end track: %d" , len, header[2], header[3]) : -abs(_e); }); | |||
777 | if (len > sizeof(toc)) | |||
778 | return -1; | |||
779 | if (len < 2) | |||
780 | return -1; | |||
781 | /* 2: first track, 3: last track */ | |||
782 | num_tracks = header[3] - header[2] + 1; | |||
783 | ||||
784 | /* empty media has no tracks */ | |||
785 | if (len < 8) | |||
786 | return 0; | |||
787 | ||||
788 | scsi_cmd_init(udev, &sc); | |||
789 | scsi_cmd_set(udev, &sc, 0, 0x43); | |||
790 | scsi_cmd_set(udev, &sc, 6, header[2]); /* First Track/Session Number */ | |||
791 | scsi_cmd_set(udev, &sc, 7, (len >> 8) & 0xff); | |||
792 | scsi_cmd_set(udev, &sc, 8, len & 0xff); | |||
793 | scsi_cmd_set(udev, &sc, 9, 0); | |||
794 | err = scsi_cmd_run(udev, &sc, fd, toc, len); | |||
795 | if ((err
| |||
796 | info_scsi_cmd_err(udev, "READ TOC (tracks)", err); | |||
797 | return -1; | |||
798 | } | |||
799 | ||||
800 | /* Take care to not iterate beyond the last valid track as specified in | |||
801 | * the TOC, but also avoid going beyond the TOC length, just in case | |||
802 | * the last track number is invalidly large */ | |||
803 | for (p = toc+4, i = 4; i < len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) { | |||
804 | unsigned int block; | |||
805 | unsigned int is_data_track; | |||
806 | ||||
807 | is_data_track = (p[1] & 0x04) != 0; | |||
| ||||
808 | ||||
809 | block = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; | |||
810 | log_debug("track=%u info=0x%x(%s) start_block=%u",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 811, __func__, "track=%u info=0x%x(%s) start_block=%u" , p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block ) : -abs(_e); }) | |||
811 | p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 811, __func__, "track=%u info=0x%x(%s) start_block=%u" , p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block ) : -abs(_e); }); | |||
812 | ||||
813 | if (is_data_track) | |||
814 | cd_media_track_count_data++; | |||
815 | else | |||
816 | cd_media_track_count_audio++; | |||
817 | } | |||
818 | ||||
819 | scsi_cmd_init(udev, &sc); | |||
820 | scsi_cmd_set(udev, &sc, 0, 0x43); | |||
821 | scsi_cmd_set(udev, &sc, 2, 1); /* Session Info */ | |||
822 | scsi_cmd_set(udev, &sc, 8, sizeof(header)); | |||
823 | scsi_cmd_set(udev, &sc, 9, 0); | |||
824 | err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); | |||
825 | if ((err != 0)) { | |||
826 | info_scsi_cmd_err(udev, "READ TOC (multi session)", err); | |||
827 | return -1; | |||
828 | } | |||
829 | len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7]; | |||
830 | log_debug("last track %u starts at block %u", header[4+2], len)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 830, __func__, "last track %u starts at block %u" , header[4+2], len) : -abs(_e); }); | |||
831 | cd_media_session_last_offset = (unsigned long long int)len * 2048; | |||
832 | return 0; | |||
833 | } | |||
834 | ||||
835 | int main(int argc, char *argv[]) { | |||
836 | struct udev *udev; | |||
837 | static const struct option options[] = { | |||
838 | { "lock-media", no_argument0, NULL((void*)0), 'l' }, | |||
839 | { "unlock-media", no_argument0, NULL((void*)0), 'u' }, | |||
840 | { "eject-media", no_argument0, NULL((void*)0), 'e' }, | |||
841 | { "debug", no_argument0, NULL((void*)0), 'd' }, | |||
842 | { "help", no_argument0, NULL((void*)0), 'h' }, | |||
843 | {} | |||
844 | }; | |||
845 | bool_Bool eject = false0; | |||
846 | bool_Bool lock = false0; | |||
847 | bool_Bool unlock = false0; | |||
848 | const char *node = NULL((void*)0); | |||
849 | int fd = -1; | |||
850 | int cnt; | |||
851 | int rc = 0; | |||
852 | ||||
853 | log_set_target(LOG_TARGET_AUTO); | |||
854 | udev_parse_config(); | |||
855 | log_parse_environment()log_parse_environment_realm(LOG_REALM_UDEV); | |||
856 | log_open(); | |||
857 | ||||
858 | udev = udev_new(); | |||
859 | if (udev == NULL((void*)0)) | |||
| ||||
860 | goto exit; | |||
861 | ||||
862 | for (;;) { | |||
863 | int option; | |||
864 | ||||
865 | option = getopt_long(argc, argv, "deluh", options, NULL((void*)0)); | |||
866 | if (option == -1) | |||
867 | break; | |||
868 | ||||
869 | switch (option) { | |||
870 | case 'l': | |||
871 | lock = true1; | |||
872 | break; | |||
873 | case 'u': | |||
874 | unlock = true1; | |||
875 | break; | |||
876 | case 'e': | |||
877 | eject = true1; | |||
878 | break; | |||
879 | case 'd': | |||
880 | log_set_target(LOG_TARGET_CONSOLE); | |||
881 | log_set_max_level(LOG_DEBUG)log_set_max_level_realm(LOG_REALM_UDEV, (7)); | |||
882 | log_open(); | |||
883 | break; | |||
884 | case 'h': | |||
885 | printf("Usage: cdrom_id [options] <device>\n" | |||
886 | " -l,--lock-media lock the media (to enable eject request events)\n" | |||
887 | " -u,--unlock-media unlock the media\n" | |||
888 | " -e,--eject-media eject the media\n" | |||
889 | " -d,--debug debug to stderr\n" | |||
890 | " -h,--help print this help text\n\n"); | |||
891 | goto exit; | |||
892 | default: | |||
893 | rc = 1; | |||
894 | goto exit; | |||
895 | } | |||
896 | } | |||
897 | ||||
898 | node = argv[optind]; | |||
899 | if (!node) { | |||
900 | log_error("no device")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 900, __func__, "no device" ) : -abs(_e); }); | |||
901 | fprintf(stderrstderr, "no device\n"); | |||
902 | rc = 1; | |||
903 | goto exit; | |||
904 | } | |||
905 | ||||
906 | initialize_srand(); | |||
907 | for (cnt = 20; cnt > 0; cnt--) { | |||
908 | struct timespec duration; | |||
909 | ||||
910 | fd = open(node, O_RDONLY00|O_NONBLOCK04000|O_CLOEXEC02000000|(is_mounted(node) ? 0 : O_EXCL0200)); | |||
911 | if (fd >= 0 || errno(*__errno_location ()) != EBUSY16) | |||
912 | break; | |||
913 | duration.tv_sec = 0; | |||
914 | duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); | |||
915 | nanosleep(&duration, NULL((void*)0)); | |||
916 | } | |||
917 | if (fd
| |||
918 | log_debug("unable to open '%s'", node)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 918, __func__, "unable to open '%s'" , node) : -abs(_e); }); | |||
919 | fprintf(stderrstderr, "unable to open '%s'\n", node); | |||
920 | rc = 1; | |||
921 | goto exit; | |||
922 | } | |||
923 | log_debug("probing: '%s'", node)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 923, __func__, "probing: '%s'" , node) : -abs(_e); }); | |||
924 | ||||
925 | /* same data as original cdrom_id */ | |||
926 | if (cd_capability_compat(udev, fd) < 0) { | |||
927 | rc = 1; | |||
928 | goto exit; | |||
929 | } | |||
930 | ||||
931 | /* check for media - don't bail if there's no media as we still need to | |||
932 | * to read profiles */ | |||
933 | cd_media_compat(udev, fd); | |||
934 | ||||
935 | /* check if drive talks MMC */ | |||
936 | if (cd_inquiry(udev, fd) < 0) | |||
937 | goto work; | |||
938 | ||||
939 | /* read drive and possibly current profile */ | |||
940 | if (cd_profiles(udev, fd) != 0) | |||
941 | goto work; | |||
942 | ||||
943 | /* at this point we are guaranteed to have media in the drive - find out more about it */ | |||
944 | ||||
945 | /* get session/track info */ | |||
946 | cd_media_toc(udev, fd); | |||
947 | ||||
948 | /* get writable media state */ | |||
949 | cd_media_info(udev, fd); | |||
950 | ||||
951 | work: | |||
952 | /* lock the media, so we enable eject button events */ | |||
953 | if (lock && cd_media) { | |||
954 | log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 954, __func__, "PREVENT_ALLOW_MEDIUM_REMOVAL (lock)" ) : -abs(_e); }); | |||
955 | media_lock(udev, fd, true1); | |||
956 | } | |||
957 | ||||
958 | if (unlock && cd_media) { | |||
959 | log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 959, __func__, "PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)" ) : -abs(_e); }); | |||
960 | media_lock(udev, fd, false0); | |||
961 | } | |||
962 | ||||
963 | if (eject) { | |||
964 | log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 964, __func__, "PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)" ) : -abs(_e); }); | |||
965 | media_lock(udev, fd, false0); | |||
966 | log_debug("START_STOP_UNIT (eject)")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/udev/cdrom_id/cdrom_id.c", 966, __func__, "START_STOP_UNIT (eject)" ) : -abs(_e); }); | |||
967 | media_eject(udev, fd); | |||
968 | } | |||
969 | ||||
970 | printf("ID_CDROM=1\n"); | |||
971 | if (cd_cd_rom) | |||
972 | printf("ID_CDROM_CD=1\n"); | |||
973 | if (cd_cd_r) | |||
974 | printf("ID_CDROM_CD_R=1\n"); | |||
975 | if (cd_cd_rw) | |||
976 | printf("ID_CDROM_CD_RW=1\n"); | |||
977 | if (cd_dvd_rom) | |||
978 | printf("ID_CDROM_DVD=1\n"); | |||
979 | if (cd_dvd_r) | |||
980 | printf("ID_CDROM_DVD_R=1\n"); | |||
981 | if (cd_dvd_rw) | |||
982 | printf("ID_CDROM_DVD_RW=1\n"); | |||
983 | if (cd_dvd_ram) | |||
984 | printf("ID_CDROM_DVD_RAM=1\n"); | |||
985 | if (cd_dvd_plus_r) | |||
986 | printf("ID_CDROM_DVD_PLUS_R=1\n"); | |||
987 | if (cd_dvd_plus_rw) | |||
988 | printf("ID_CDROM_DVD_PLUS_RW=1\n"); | |||
989 | if (cd_dvd_plus_r_dl) | |||
990 | printf("ID_CDROM_DVD_PLUS_R_DL=1\n"); | |||
991 | if (cd_dvd_plus_rw_dl) | |||
992 | printf("ID_CDROM_DVD_PLUS_RW_DL=1\n"); | |||
993 | if (cd_bd) | |||
994 | printf("ID_CDROM_BD=1\n"); | |||
995 | if (cd_bd_r) | |||
996 | printf("ID_CDROM_BD_R=1\n"); | |||
997 | if (cd_bd_re) | |||
998 | printf("ID_CDROM_BD_RE=1\n"); | |||
999 | if (cd_hddvd) | |||
1000 | printf("ID_CDROM_HDDVD=1\n"); | |||
1001 | if (cd_hddvd_r) | |||
1002 | printf("ID_CDROM_HDDVD_R=1\n"); | |||
1003 | if (cd_hddvd_rw) | |||
1004 | printf("ID_CDROM_HDDVD_RW=1\n"); | |||
1005 | if (cd_mo) | |||
1006 | printf("ID_CDROM_MO=1\n"); | |||
1007 | if (cd_mrw) | |||
1008 | printf("ID_CDROM_MRW=1\n"); | |||
1009 | if (cd_mrw_w) | |||
1010 | printf("ID_CDROM_MRW_W=1\n"); | |||
1011 | ||||
1012 | if (cd_media) | |||
1013 | printf("ID_CDROM_MEDIA=1\n"); | |||
1014 | if (cd_media_mo) | |||
1015 | printf("ID_CDROM_MEDIA_MO=1\n"); | |||
1016 | if (cd_media_mrw) | |||
1017 | printf("ID_CDROM_MEDIA_MRW=1\n"); | |||
1018 | if (cd_media_mrw_w) | |||
1019 | printf("ID_CDROM_MEDIA_MRW_W=1\n"); | |||
1020 | if (cd_media_cd_rom) | |||
1021 | printf("ID_CDROM_MEDIA_CD=1\n"); | |||
1022 | if (cd_media_cd_r) | |||
1023 | printf("ID_CDROM_MEDIA_CD_R=1\n"); | |||
1024 | if (cd_media_cd_rw) | |||
1025 | printf("ID_CDROM_MEDIA_CD_RW=1\n"); | |||
1026 | if (cd_media_dvd_rom) | |||
1027 | printf("ID_CDROM_MEDIA_DVD=1\n"); | |||
1028 | if (cd_media_dvd_r) | |||
1029 | printf("ID_CDROM_MEDIA_DVD_R=1\n"); | |||
1030 | if (cd_media_dvd_ram) | |||
1031 | printf("ID_CDROM_MEDIA_DVD_RAM=1\n"); | |||
1032 | if (cd_media_dvd_rw) | |||
1033 | printf("ID_CDROM_MEDIA_DVD_RW=1\n"); | |||
1034 | if (cd_media_dvd_plus_r) | |||
1035 | printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n"); | |||
1036 | if (cd_media_dvd_plus_rw) | |||
1037 | printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n"); | |||
1038 | if (cd_media_dvd_plus_rw_dl) | |||
1039 | printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n"); | |||
1040 | if (cd_media_dvd_plus_r_dl) | |||
1041 | printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n"); | |||
1042 | if (cd_media_bd) | |||
1043 | printf("ID_CDROM_MEDIA_BD=1\n"); | |||
1044 | if (cd_media_bd_r) | |||
1045 | printf("ID_CDROM_MEDIA_BD_R=1\n"); | |||
1046 | if (cd_media_bd_re) | |||
1047 | printf("ID_CDROM_MEDIA_BD_RE=1\n"); | |||
1048 | if (cd_media_hddvd) | |||
1049 | printf("ID_CDROM_MEDIA_HDDVD=1\n"); | |||
1050 | if (cd_media_hddvd_r) | |||
1051 | printf("ID_CDROM_MEDIA_HDDVD_R=1\n"); | |||
1052 | if (cd_media_hddvd_rw) | |||
1053 | printf("ID_CDROM_MEDIA_HDDVD_RW=1\n"); | |||
1054 | ||||
1055 | if (cd_media_state != NULL((void*)0)) | |||
1056 | printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state); | |||
1057 | if (cd_media_session_next > 0) | |||
1058 | printf("ID_CDROM_MEDIA_SESSION_NEXT=%u\n", cd_media_session_next); | |||
1059 | if (cd_media_session_count > 0) | |||
1060 | printf("ID_CDROM_MEDIA_SESSION_COUNT=%u\n", cd_media_session_count); | |||
1061 | if (cd_media_session_count > 1 && cd_media_session_last_offset > 0) | |||
1062 | printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset); | |||
1063 | if (cd_media_track_count > 0) | |||
1064 | printf("ID_CDROM_MEDIA_TRACK_COUNT=%u\n", cd_media_track_count); | |||
1065 | if (cd_media_track_count_audio > 0) | |||
1066 | printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%u\n", cd_media_track_count_audio); | |||
1067 | if (cd_media_track_count_data > 0) | |||
1068 | printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%u\n", cd_media_track_count_data); | |||
1069 | exit: | |||
1070 | if (fd >= 0) | |||
1071 | close(fd); | |||
1072 | udev_unref(udev); | |||
1073 | log_close(); | |||
1074 | return rc; | |||
1075 | } |