1 /* @(#)interface.c 1.84 20/07/16 Copyright 1998-2002,2015 Heiko Eissfeldt, Copyright 2006-2016 J. Schilling */
2 #include "config.h"
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)interface.c 1.84 20/07/16 Copyright 1998-2002,2015 Heiko Eissfeldt, Copyright 2006-2016 J. Schilling";
6
7 #endif
8 /*
9 * Copyright (C) 1998-2002,2015 Heiko Eissfeldt heiko@colossus.escape.de
10 * Copyright (c) 2006-2016 J. Schilling
11 *
12 * Interface module for cdrom drive access
13 *
14 * Two interfaces are possible.
15 *
16 * 1. using 'cooked' ioctls() (Linux only)
17 * : available for atapi, sbpcd and cdu31a drives only.
18 *
19 * 2. using the generic scsi device (for details see SCSI Prog. HOWTO).
20 * NOTE: a bug/misfeature in the kernel requires blocking signal
21 * SIGINT during SCSI command handling. Once this flaw has
22 * been removed, the sigprocmask SIG_BLOCK and SIG_UNBLOCK calls
23 * should removed, thus saving context switches.
24 *
25 * For testing purposes I have added a third simulation interface.
26 *
27 * Version 0.8: used experiences of Jochen Karrer.
28 * SparcLinux port fixes
29 * AlphaLinux port fixes
30 *
31 */
32 /*
33 * The contents of this file are subject to the terms of the
34 * Common Development and Distribution License, Version 1.0 only
35 * (the "License"). You may not use this file except in compliance
36 * with the License.
37 *
38 * See the file CDDL.Schily.txt in this distribution for details.
39 * A copy of the CDDL is also available via the Internet at
40 * http://www.opensource.org/licenses/cddl1.txt
41 *
42 * When distributing Covered Code, include this CDDL HEADER in each
43 * file and include the License file CDDL.Schily.txt from this distribution.
44 */
45 #if 0
46 #define SIM_CD
47 #endif
48
49 #include "config.h"
50 #include <schily/stdio.h>
51 #include <schily/standard.h>
52 #include <schily/stdlib.h>
53 #include <schily/unistd.h>
54 #include <schily/string.h>
55 #include <schily/errno.h>
56 #include <schily/signal.h>
57 #include <schily/fcntl.h>
58 #include <schily/assert.h>
59 #include <schily/nlsdefs.h>
60 #include <schily/device.h>
61 #include <schily/ioctl.h>
62 #include <schily/stat.h>
63 #include <schily/time.h>
64 #include <schily/poll.h>
65 #include <schily/schily.h>
66
67
68 #include "mycdrom.h"
69 #include "lowlevel.h"
70 /* some include file locations have changed with newer kernels */
71 #if defined(__linux__)
72 # if LINUX_VERSION_CODE > 0x10300 + 97
73 # if LINUX_VERSION_CODE < 0x200ff
74 # include <linux/sbpcd.h>
75 # include <linux/ucdrom.h>
76 # endif
77 # if !defined(CDROM_SELECT_SPEED)
78 # include <linux/ucdrom.h>
79 # endif
80 # endif
81 #endif
82
83 #include <scg/scsireg.h>
84 #include <scg/scsitransp.h>
85
86 #include "mytype.h"
87 #include "byteorder.h"
88 #include "interface.h"
89 #include "cdda2wav.h"
90 #include "semshm.h"
91 #include "setuid.h"
92 #include "ringbuff.h"
93 #include "toc.h"
94 #include "global.h"
95 #include "ioctl.h"
96 #include "exitcodes.h"
97 #include "scsi_cmds.h"
98
99 #include <schily/utypes.h>
100 #include <cdrecord.h>
101 #include "scsi_scan.h"
102
103 unsigned interface;
104
105 int trackindex_disp = 0;
106
107 void (*EnableCdda) __PR((SCSI *, int Switch, unsigned uSectorsize));
108 unsigned (*doReadToc) __PR((SCSI *scgp));
109 void (*ReadTocText) __PR((SCSI *scgp));
110 unsigned (*ReadLastAudio) __PR((SCSI *scgp));
111 int (*ReadCdRom) __PR((SCSI *scgp, UINT4 *p, unsigned lSector,
112 unsigned SectorBurstVal));
113 int (*ReadCdRom_C2) __PR((SCSI *scgp, UINT4 *p, unsigned lSector,
114 unsigned SectorBurstVal));
115 int (*ReadCdRomData) __PR((SCSI *scgp, unsigned char *p, unsigned lSector,
116 unsigned SectorBurstVal));
117 int (*ReadCdRomSub) __PR((SCSI *scgp, UINT4 *p, unsigned lSector,
118 unsigned SectorBurstVal));
119 subq_chnl *(*ReadSubChannels) __PR((SCSI *scgp, unsigned lSector));
120 subq_chnl *(*ReadSubQ) __PR((SCSI *scgp, unsigned char sq_format,
121 unsigned char track));
122 void (*SelectSpeed) __PR((SCSI *scgp, unsigned speed));
123 int (*Play_at) __PR((SCSI *scgp, unsigned int from_sector,
124 unsigned int sectors));
125 int (*StopPlay) __PR((SCSI *scgp));
126 void (*trash_cache) __PR((UINT4 *p, unsigned lSector,
127 unsigned SectorBurstVal));
128
129 #if defined USE_PARANOIA
130 long cdda_read __PR((void *d, void * buffer, long beginsector,
131 long sectors));
132 long cdda_read_c2 __PR((void *d, void * buffer, long beginsector,
133 long sectors));
134
135 long
cdda_read(d,buffer,beginsector,sectors)136 cdda_read(d, buffer, beginsector, sectors)
137 void *d;
138 void *buffer;
139 long beginsector;
140 long sectors;
141 {
142 long ret = ReadCdRom(d, buffer, beginsector, sectors);
143 return (ret);
144 }
145
146 long
cdda_read_c2(d,buffer,beginsector,sectors)147 cdda_read_c2(d, buffer, beginsector, sectors)
148 void *d;
149 void *buffer;
150 long beginsector;
151 long sectors;
152 {
153 long ret = ReadCdRom_C2(d, buffer, beginsector, sectors);
154 return (ret);
155 }
156 #endif
157
158 typedef struct string_len {
159 char *str;
160 unsigned int sl;
161 } mystring;
162
163 static mystring drv_is_not_mmc[] = {
164 { "DEC RRD47 (C) DEC ", 24},
165 /* { "SONY CD-ROM CDU625 1.0", 28}, */
166 { NULL, 0} /* must be last entry */
167 };
168
169 static mystring drv_has_mmc_cdda[] = {
170 { "HITACHI CDR-7930", 16 },
171 /* { "TOSHIBA CD-ROM XM-5402TA3605", 28}, */
172 { NULL, 0} /* must be last entry */
173 };
174
175 static int Is_a_Toshiba3401;
176
177 int Toshiba3401 __PR((void));
178
179 int
Toshiba3401()180 Toshiba3401() {
181 return (Is_a_Toshiba3401);
182 }
183
184 /* hook */
185 static void Dummy __PR((void));
186 static void
Dummy()187 Dummy()
188 {
189 }
190
191 static SCSI *_scgp;
192
193 SCSI *get_scsi_p __PR((void));
194
195 SCSI *
get_scsi_p()196 get_scsi_p()
197 {
198 return (_scgp);
199 }
200
201 #if !defined(SIM_CD)
202
203 static void trash_cache_SCSI __PR((UINT4 *p, unsigned lSector,
204 unsigned SectorBurstVal));
205
206 static void
trash_cache_SCSI(p,lSector,SectorBurstVal)207 trash_cache_SCSI(p, lSector, SectorBurstVal)
208 UINT4 *p;
209 unsigned lSector;
210 unsigned SectorBurstVal;
211 {
212 /*
213 * trash the cache
214 */
215 ReadCdRom(get_scsi_p(), p,
216 find_an_off_sector(lSector, SectorBurstVal),
217 min(global.nsectors, 6));
218 }
219
220
221
222 static void Check_interface_for_device __PR((struct stat *statstruct,
223 char *pdev_name));
224 LOCAL int OpenCdRom __PR((char *pdev_name));
225 LOCAL void scg_openerr __PR((char *errstr));
226 LOCAL int find_drive __PR((SCSI *scgp, char *dev));
227
228 static void SetupSCSI __PR((SCSI *scgp));
229
230 static void
SetupSCSI(scgp)231 SetupSCSI(scgp)
232 SCSI *scgp;
233 {
234 unsigned char *p;
235 int err;
236
237 if (interface != GENERIC_SCSI) {
238 /*
239 * unfortunately we have the wrong interface and are
240 * not able to change on the fly
241 */
242 errmsgno(EX_BAD,
243 _("The generic SCSI interface and devices are required\n"));
244 exit(SYNTAX_ERROR);
245 }
246
247 /*
248 * do a test unit ready to 'init' the device.
249 */
250 seterrno(0);
251 TestForMedium(scgp);
252 err = geterrno();
253 if (err == EPERM || err == EACCES) {
254 scg_openerr("");
255 /* NOTREACHED */
256 }
257
258 /*
259 * check for the correct type of unit.
260 */
261 p = ScsiInquiry(scgp);
262
263 #undef TYPE_ROM
264 #define TYPE_ROM 5
265 #undef TYPE_WORM
266 #define TYPE_WORM 4
267 if (p == NULL) {
268 errmsgno(EX_BAD, _("Inquiry command failed. Aborting...\n"));
269 exit(DEVICE_ERROR);
270 }
271
272 if ((*p != TYPE_ROM && *p != TYPE_WORM)) {
273 errmsgno(EX_BAD,
274 _("This is neither a scsi cdrom nor a worm device.\n"));
275 exit(SYNTAX_ERROR);
276 }
277
278 if (global.quiet == 0) {
279 fprintf(outfp,
280 _("Type: %s, Vendor '%8.8s' Model '%16.16s' Revision '%4.4s' "),
281 *p == TYPE_ROM ? "ROM" : "WORM",
282 p+8,
283 p+16,
284 p+32);
285 }
286 /*
287 * generic Sony type defaults
288 */
289 density = 0x0;
290 accepts_fua_bit = -1;
291 EnableCdda = (void (*) __PR((SCSI *, int, unsigned)))Dummy;
292 ReadCdRom = ReadCdda12;
293 ReadCdRomSub = ReadCddaSubSony;
294 ReadCdRom_C2 = ReadCddaNoFallback_C2;
295 ReadCdRomData = (int (*) __PR((SCSI *,
296 unsigned char *,
297 unsigned, unsigned))) ReadStandardData;
298 ReadLastAudio = ReadFirstSessionTOCSony;
299 SelectSpeed = SpeedSelectSCSISony;
300 Play_at = Play_atSCSI;
301 StopPlay = StopPlaySCSI;
302 trash_cache = trash_cache_SCSI;
303 ReadTocText = ReadTocTextSCSIMMC;
304 doReadToc = ReadTocSCSI;
305 ReadSubQ = ReadSubQSCSI;
306 ReadSubChannels = (subq_chnl * (*) __PR((SCSI *, unsigned)))NULL;
307
308 /*
309 * check for brands and adjust special peculiaritites
310 */
311
312 /*
313 * If your drive is not treated correctly, you can adjust some things
314 * here:
315 * global.in_lendian: should be to 1, if the CDROM drive or CD-Writer
316 * delivers the samples in the native byteorder of the audio cd
317 * (LSB first).
318 * HP CD-Writers need it set to 0.
319 * NOTE: If you get correct wav files when using sox with the '-x'
320 * option, the endianess is wrong. You can use the -C option to
321 * specify the value of global.in_lendian.
322 */
323
324 {
325 int mmc_code;
326
327 scgp->silent++;
328 allow_atapi(scgp, 1);
329 if (*p == TYPE_ROM) {
330 mmc_code = heiko_mmc(scgp);
331 } else {
332 mmc_code = 0;
333 }
334 scgp->silent--;
335
336 /*
337 * Exceptions for drives that report incorrect MMC capability
338 */
339 if (mmc_code != 0) {
340 /*
341 * these drives are NOT capable of MMC commands
342 */
343 mystring *pp = drv_is_not_mmc;
344 while (pp->str != NULL) {
345 if (strncmp(pp->str, (char *)p+8, pp->sl) == 0) {
346 mmc_code = 0;
347 break;
348 }
349 pp++;
350 }
351 }
352 {
353 /*
354 * these drives flag themselves as non-MMC, but offer
355 * CDDA reading only with a MMC method.
356 */
357 mystring *pp = drv_has_mmc_cdda;
358 while (pp->str != NULL) {
359 if (strncmp(pp->str, (char *)p+8, pp->sl) == 0) {
360 mmc_code = 1;
361 break;
362 }
363 pp++;
364 }
365 }
366
367 switch (mmc_code) {
368 case 2: /* SCSI-3 cdrom drive with accurate audio stream */
369 /* FALLTHROUGH */
370 case 1: /* SCSI-3 cdrom drive with no accurate audio stream */
371 /* FALLTHROUGH */
372 lost_toshibas:
373 global.in_lendian = 1;
374 if (mmc_code == 2)
375 global.overlap = 0;
376 else
377 global.overlap = 1;
378 ReadCdRom = ReadCddaFallbackMMC;
379 ReadCdRom_C2 = ReadCddaFallbackMMC_C2;
380 ReadCdRomSub = ReadCddaSubSony;
381 ReadLastAudio = ReadFirstSessionTOCMMC;
382 SelectSpeed = SpeedSelectSCSIMMC;
383 ReadTocText = ReadTocTextSCSIMMC;
384 doReadToc = ReadTocMMC;
385 ReadSubChannels = ReadSubChannelsFallbackMMC;
386 if (!memcmp(p+8, "SONY CD-RW CRX100E 1.0", 27))
387 ReadTocText = (void (*) __PR((SCSI *)))NULL;
388 if (!global.quiet)
389 fprintf(outfp, "MMC+CDDA\n");
390 break;
391 case -1: /* "MMC drive does not support cdda reading, sorry\n." */
392 doReadToc = ReadTocMMC;
393 if (!global.quiet)
394 fprintf(outfp, "MMC-CDDA\n");
395 /* FALLTHROUGH */
396 case 0: /* non SCSI-3 cdrom drive */
397 if (!global.quiet) fprintf(outfp, _("no MMC\n"));
398 ReadLastAudio = (unsigned (*) __PR((SCSI *)))NULL;
399 if (!memcmp(p+8, "TOSHIBA", 7) ||
400 !memcmp(p+8, "IBM", 3) ||
401 !memcmp(p+8, "DEC", 3)) {
402 /*
403 * Older Toshiba ATAPI drives don't identify
404 * themselves as MMC.
405 * The last digit of the model number is
406 * '2' for ATAPI drives.
407 * These are treated as MMC.
408 */
409 if (!memcmp(p+15, " CD-ROM XM-", 11) &&
410 p[29] == '2') {
411 goto lost_toshibas;
412 }
413 density = 0x82;
414 EnableCdda = EnableCddaModeSelect;
415 ReadSubChannels = ReadStandardSub;
416 ReadCdRom = ReadStandard;
417 SelectSpeed = SpeedSelectSCSIToshiba;
418 if (!memcmp(p+15, " CD-ROM XM-3401", 15)) {
419 Is_a_Toshiba3401 = 1;
420 }
421 global.in_lendian = 1;
422 } else if (!memcmp(p+8, "IMS", 3) ||
423 !memcmp(p+8, "KODAK", 5) ||
424 !memcmp(p+8, "RICOH", 5) ||
425 !memcmp(p+8, "HP", 2) ||
426 !memcmp(p+8, "PHILIPS", 7) ||
427 !memcmp(p+8, "PLASMON", 7) ||
428 !memcmp(p+8, "GRUNDIG CDR100IPW", 17) ||
429 !memcmp(p+8, "MITSUMI CD-R ", 13)) {
430 EnableCdda = EnableCddaModeSelect;
431 ReadCdRom = ReadStandard;
432 SelectSpeed = SpeedSelectSCSIPhilipsCDD2600;
433
434 /*
435 * treat all of these as bigendian
436 */
437 global.in_lendian = 0;
438
439 /*
440 * no overlap reading for cd-writers
441 */
442 global.overlap = 0;
443 } else if (!memcmp(p+8, "NRC", 3)) {
444 SelectSpeed = (void (*) __PR((SCSI *, unsigned)))NULL;
445 } else if (!memcmp(p+8, "YAMAHA", 6)) {
446 EnableCdda = EnableCddaModeSelect;
447 SelectSpeed = SpeedSelectSCSIYamaha;
448
449 /*
450 * no overlap reading for cd-writers
451 */
452 global.overlap = 0;
453 global.in_lendian = 1;
454 } else if (!memcmp(p+8, "PLEXTOR", 7)) {
455 global.in_lendian = 1;
456 global.overlap = 0;
457 ReadLastAudio = ReadFirstSessionTOCSony;
458 ReadTocText = ReadTocTextSCSIMMC;
459 doReadToc = ReadTocSony;
460 ReadSubChannels = ReadSubChannelsSony;
461 } else if (!memcmp(p+8, "SONY", 4)) {
462 global.in_lendian = 1;
463 if (!memcmp(p+16, "CD-ROM CDU55E", 13)) {
464 ReadCdRom = ReadCddaMMC12;
465 }
466 ReadLastAudio = ReadFirstSessionTOCSony;
467 ReadTocText = ReadTocTextSCSIMMC;
468 doReadToc = ReadTocSony;
469 ReadSubChannels = ReadSubChannelsSony;
470 } else if (!memcmp(p+8, "NEC", 3)) {
471 ReadCdRom = ReadCdda10;
472 ReadTocText = (void (*) __PR((SCSI *)))NULL;
473 SelectSpeed = SpeedSelectSCSINEC;
474 global.in_lendian = 1;
475 /*
476 * I assume all versions of the 502 require
477 * this?
478 * no overlap reading for NEC CD-ROM 502!
479 */
480 if (!memcmp(p+29, "5022.0r", 3))
481 global.overlap = 0;
482 } else if (!memcmp(p+8, "MATSHITA", 8)) {
483 ReadCdRom = ReadCdda12Matsushita;
484 global.in_lendian = 1;
485 }
486 } /* switch (get_mmc) */
487 }
488
489 /*
490 * look if caddy is loaded
491 */
492 if (interface == GENERIC_SCSI) {
493 scgp->silent++;
494 while (!wait_unit_ready(scgp, 60)) {
495 int c;
496
497 fprintf(outfp,
498 _("load cdrom please and press enter"));
499 fflush(outfp);
500 while ((c = getchar()) != '\n') {
501 if (c == EOF)
502 break;
503 }
504 if (c == EOF)
505 exit(DEVICE_ERROR);
506 }
507 scgp->silent--;
508 }
509 }
510
511 /********************** General setup *******************************/
512
513 /*
514 * As the name implies, interfaces and devices are checked. We also
515 * adjust nsectors, overlap, and interface for the first time here.
516 * Any unnecessary privileges (setuid, setgid) are also dropped here.
517 */
518 static void
Check_interface_for_device(statstruct,pdev_name)519 Check_interface_for_device(statstruct, pdev_name)
520 struct stat *statstruct;
521 char *pdev_name;
522 {
523 #if !(defined(__FreeBSD__) || \
524 defined(__FreeBSD_kernel__) || \
525 defined(__DragonFly__)) || \
526 __FreeBSD_version < 600000
527
528 #if !defined(STAT_MACROS_BROKEN) || (STAT_MACROS_BROKEN != 1)
529 if (!S_ISCHR(statstruct->st_mode) &&
530 !S_ISBLK(statstruct->st_mode)) {
531 errmsgno(EX_BAD, _("%s is not a device.\n"),
532 pdev_name);
533 exit(SYNTAX_ERROR);
534 }
535 #endif
536
537 #if defined(HAVE_ST_RDEV) && (HAVE_ST_RDEV == 1)
538 switch (major(statstruct->st_rdev)) {
539 #if defined(__linux__)
540 case SCSI_GENERIC_MAJOR: /* generic */
541 #else
542 default: /* ??? what is the proper value here */
543 #endif
544 #if !defined(STAT_MACROS_BROKEN) || (STAT_MACROS_BROKEN != 1)
545 #if defined(__linux__)
546 if (!S_ISCHR(statstruct->st_mode)) {
547 errmsgno(EX_BAD, _("%s is not a char device.\n"),
548 pdev_name);
549 exit(SYNTAX_ERROR);
550 }
551
552 if (interface != GENERIC_SCSI) {
553 fprintf(outfp,
554 _("wrong interface (cooked_ioctl) for this device (%s)\nset to generic_scsi\n"),
555 pdev_name);
556 interface = GENERIC_SCSI;
557 }
558 #endif
559 #else
560 default: /* ??? what is the proper value here */
561 #endif
562 break;
563
564 #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
565 #if defined(__linux__)
566 case SCSI_CDROM_MAJOR: /* scsi cd */
567 default: /* for example ATAPI cds */
568 #else
569 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
570 #if __FreeBSD_version >= 600021
571 case 0: /* majors abandoned */
572 /* FALLTHROUGH */
573 #endif
574 #if __FreeBSD_version >= 501113
575 case 4: /* GEOM */
576 /* FALLTHROUGH */
577 #endif
578 case 117: /* pre-GEOM atapi cd */
579 if (!S_ISCHR(statstruct->st_mode)) {
580 errmsgno(EX_BAD, _("%s is not a char device.\n"),
581 pdev_name);
582 exit(SYNTAX_ERROR);
583 }
584 if (interface != COOKED_IOCTL) {
585 fprintf(outfp,
586 _("cdrom device (%s) is not of type generic SCSI. \
587 Setting interface to cooked_ioctl.\n"), pdev_name);
588 interface = COOKED_IOCTL;
589 }
590 break;
591 case 19: /* first atapi cd */
592 #endif
593 #endif
594 if (!S_ISBLK(statstruct->st_mode)) {
595 errmsgno(EX_BAD, _("%s is not a block device.\n"),
596 pdev_name);
597 exit(SYNTAX_ERROR);
598 }
599 #if defined(__linux__)
600 #if LINUX_VERSION_CODE >= 0x20600
601 /*
602 * In Linux kernel 2.6 it is better to use the SCSI interface
603 * with the device.
604 */
605 break;
606 #endif
607 #endif
608 if (interface != COOKED_IOCTL) {
609 fprintf(outfp,
610 _("cdrom device (%s) is not of type generic SCSI. \
611 Setting interface to cooked_ioctl.\n"), pdev_name);
612 interface = COOKED_IOCTL;
613 }
614
615 if (interface == COOKED_IOCTL) {
616 fprintf(outfp,
617 _("\nW: The cooked_ioctl interface is functionally very limited!!\n"));
618 #if defined(__linux__)
619 fprintf(outfp,
620 _("\nW: For good sampling quality simply use the generic SCSI interface!\n"
621 "For example dev=1,0,0\n"));
622 #endif
623 }
624
625 break;
626 #endif
627 }
628 #endif
629 #endif
630 if (global.overlap >= global.nsectors)
631 global.overlap = global.nsectors-1;
632 }
633
634 /*
635 * open the cdrom device
636 */
637 static int
OpenCdRom(pdev_name)638 OpenCdRom(pdev_name)
639 char *pdev_name;
640 {
641 int retval = 0;
642 struct stat fstatstruct;
643 #ifdef HAVE_IOCTL_INTERFACE
644 struct stat statstruct;
645 int have_named_device = 0;
646 #endif
647
648 interface = GENERIC_SCSI;
649
650 /*
651 * The device (given by pdevname) can be:
652 * a. an SCSI device specified with a /dev/xxx name,
653 * b. an SCSI device specified with bus,target,lun numbers,
654 * c. a non-SCSI device such as ATAPI or proprietary CDROM devices.
655 */
656 #ifdef HAVE_IOCTL_INTERFACE
657 have_named_device = FALSE;
658 if (pdev_name) {
659 have_named_device = strchr(pdev_name, ':') == NULL &&
660 memcmp(pdev_name, "/dev/", 5) == 0;
661 } else {
662 interface = GENERIC_SCSI; /* Paranoia for "coverity" */
663 }
664
665 if (have_named_device) {
666 if (stat(pdev_name, &statstruct)) {
667 errmsg(_("Cannot stat device %s.\n"), pdev_name);
668 exit(STAT_ERROR);
669 } else {
670 Check_interface_for_device(&statstruct, pdev_name);
671 }
672 }
673 #endif
674
675 if (interface == GENERIC_SCSI) {
676 SCSI *scgp;
677 char errstr[80];
678
679 needroot(0);
680 needgroup(0);
681 if (global.issetuid || global.uid != 0)
682 priv_on();
683 /*
684 * Call scg_remote() to force loading the remote SCSI transport
685 * library code that is located in librscg instead of the dummy
686 * remote routines that are located inside libscg.
687 */
688 scg_remote();
689 if (pdev_name != NULL &&
690 ((strncmp(pdev_name, "HELP", 4) == 0) ||
691 (strncmp(pdev_name, "help", 4) == 0))) {
692 scg_help(stderr);
693 exit(NO_ERROR);
694 }
695
696 /*
697 * device name, debug, verboseopen
698 */
699 _scgp = scg_open(pdev_name, errstr, sizeof (errstr), 0, 0);
700
701 if (_scgp == NULL) {
702 scg_openerr(errstr);
703 /* NOTREACHED */
704 }
705 scgp = _scgp;
706 scg_settimeout(scgp, 300);
707 scg_settimeout(scgp, 60);
708 if (global.dev_opts) {
709 int i = scg_opts(scgp, global.dev_opts);
710 if (i <= 0)
711 exit(i < 0 ? EX_BAD : 0);
712 }
713 scgp->silent = global.scsi_silent;
714 scgp->verbose = global.scsi_verbose;
715 scgp->debug = global.scsi_debug;
716 scgp->kdebug = global.scsi_kdebug;
717
718 global.bufsize = scg_bufsize(scgp, global.bufsize);
719 if (global.nsectors >
720 (unsigned)global.bufsize/CD_FRAMESIZE_RAW) {
721 global.nsectors = global.bufsize/CD_FRAMESIZE_RAW;
722 }
723 #ifdef USE_PARANOIA
724 if (global.paranoia_parms.enable_c2_check && global.nsectors >
725 (unsigned)global.bufsize/CD_FRAMESIZE_RAWER) {
726 global.nsectors = global.bufsize/CD_FRAMESIZE_RAWER;
727 }
728 #endif
729 if (global.overlap >= global.nsectors)
730 global.overlap = global.nsectors-1;
731
732 /*
733 * Newer versions of Linux seem to introduce an incompatible
734 * change and require root privileges or limit RLIMIT_MEMLOCK
735 * infinity in order to get a SCSI buffer in case we did call
736 * mlockall(MCL_FUTURE).
737 */
738 init_scsibuf(scgp, global.bufsize);
739 if (global.issetuid || global.uid != 0)
740 priv_off();
741 dontneedgroup();
742 dontneedroot();
743
744 if (global.scanbus) {
745 int i = select_target(scgp, outfp);
746
747 if (i < 0) {
748 scg_openerr("");
749 /* NOTREACHED */
750 }
751 exit(0);
752 }
753 if (scg_scsibus(scgp) < 0 &&
754 scg_target(scgp) < 0 && scg_lun(scgp) < 0) {
755 int i = find_drive(scgp, pdev_name);
756
757 if (i < 0) {
758 scg_openerr("");
759 /* NOTREACHED */
760 }
761 }
762 } else {
763 needgroup(0);
764 retval = open(pdev_name,
765 #ifdef linux
766 O_NONBLOCK |
767 #endif
768 O_RDONLY);
769 dontneedgroup();
770
771 if (retval < 0) {
772 errmsg(_("Cannot open '%s'.\n"), pdev_name);
773 exit(DEVICEOPEN_ERROR);
774 }
775
776 /*
777 * Do final security checks here
778 */
779 if (fstat(retval, &fstatstruct)) {
780 errmsg(_("Could not fstat %s (fd %d).\n"),
781 pdev_name, retval);
782 exit(STAT_ERROR);
783 }
784 Check_interface_for_device(&fstatstruct, pdev_name);
785
786 #if defined HAVE_IOCTL_INTERFACE
787 /* Watch for race conditions */
788 if (have_named_device &&
789 (fstatstruct.st_dev != statstruct.st_dev ||
790 fstatstruct.st_ino != statstruct.st_ino)) {
791 errmsgno(EX_BAD,
792 _("Race condition attempted in OpenCdRom. Exiting now.\n"));
793 exit(RACE_ERROR);
794 }
795 #endif
796 /*
797 * The program structure looks like a desaster :-(
798 * We do this more than once as it is impossible to understand
799 * where the right place would be to do this....
800 */
801 if (_scgp != NULL) {
802 _scgp->verbose = global.scsi_verbose;
803 }
804 }
805 return (retval);
806 }
807
808 LOCAL void
scg_openerr(errstr)809 scg_openerr(errstr)
810 char *errstr;
811 {
812 int err = geterrno();
813
814 errmsgno(err, _("%s%sCannot open or use SCSI driver.\n"),
815 errstr, errstr[0]?". ":"");
816 errmsgno(EX_BAD,
817 _("For possible targets try 'cdda2wav -scanbus'.%s\n"),
818 geteuid() ?
819 _(" Make sure you are root."):"");
820
821 if (global.issetuid || global.uid != 0)
822 priv_off();
823 dontneedgroup();
824 dontneedroot();
825 #if defined(sun) || defined(__sun)
826 fprintf(stderr,
827 _("On SunOS/Solaris make sure you have Joerg Schillings scg SCSI driver installed.\n"));
828 #endif
829 #if defined(__linux__)
830 fprintf(stderr,
831 _("Use the script scan_scsi.linux to find out more.\n"));
832 #endif
833 fprintf(stderr,
834 _("Probably you did not define your SCSI device.\n"));
835 fprintf(stderr,
836 _("Set the CDDA_DEVICE environment variable or use the -D option.\n"));
837 fprintf(stderr,
838 _("You can also define the default device in the Makefile.\n"));
839 fprintf(stderr,
840 _("For possible transport specifiers try 'cdda2wav dev=help'.\n"));
841 exit(SYNTAX_ERROR);
842 }
843
844 LOCAL int
find_drive(scgp,dev)845 find_drive(scgp, dev)
846 SCSI *scgp;
847 char *dev;
848 {
849 int ntarget;
850
851 fprintf(outfp, _("No target specified, trying to find one...\n"));
852 ntarget = find_target(scgp, INQ_ROMD, -1);
853 if (ntarget < 0)
854 return (ntarget);
855 if (ntarget == 1) {
856 /*
857 * Simple case, exactly one CD-ROM found.
858 */
859 find_target(scgp, INQ_ROMD, 1);
860 } else if (ntarget <= 0 &&
861 (ntarget = find_target(scgp, INQ_WORM, -1)) == 1) {
862 /*
863 * Exactly one CD-ROM acting as WORM found.
864 */
865 find_target(scgp, INQ_WORM, 1);
866 } else if (ntarget <= 0) {
867 /*
868 * No single CD-ROM or WORM found.
869 */
870 errmsgno(EX_BAD, _("No CD/DVD/BD-Recorder target found.\n"));
871 errmsgno(EX_BAD,
872 _("Your platform may not allow to scan for SCSI devices.\n"));
873 comerrno(EX_BAD,
874 _("Call 'cdda2wav dev=help' or ask your sysadmin for possible targets.\n"));
875 } else {
876 errmsgno(EX_BAD, _("Too many CD/DVD/BD-Recorder targets found.\n"));
877 select_target(scgp, outfp);
878 comerrno(EX_BAD,
879 _("Select a target from the list above and use 'cdda2wav dev=%s%sb,t,l'.\n"),
880 dev?dev:"", dev?(dev[strlen(dev)-1] == ':'?"":":"):"");
881 }
882 fprintf(outfp, _("Using dev=%s%s%d,%d,%d.\n"),
883 dev?dev:"", dev?(dev[strlen(dev)-1] == ':'?"":":"):"",
884 scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp));
885 return (ntarget);
886 }
887
888
889 #endif /* SIM_CD */
890
891 /******************* Simulation interface *****************/
892 #if defined SIM_CD
893 #include "toc.h"
894 static unsigned long sim_pos = 0;
895
896 /*
897 * read 'SectorBurst' adjacent sectors of audio sectors
898 * to Buffer '*p' beginning at sector 'lSector'
899 */
900 static int ReadCdRom_sim __PR((SCSI *x, UINT4 *p, unsigned lSector,
901 unsigned SectorBurstVal));
902 static int
ReadCdRom_sim(x,p,lSector,SectorBurstVal)903 ReadCdRom_sim(x, p, lSector, SectorBurstVal)
904 SCSI *x;
905 UINT4 *p;
906 unsigned lSector;
907 unsigned SectorBurstVal;
908 {
909 unsigned int loop = 0;
910 Int16_t *q = (Int16_t *) p;
911 int joffset = 0;
912
913 if (lSector > g_toc[cdtracks].dwStartSector ||
914 lSector + SectorBurstVal > g_toc[cdtracks].dwStartSector + 1) {
915 fprintf(stderr,
916 _("Read request out of bounds: %u - %u (%d - %d allowed)\n"),
917 lSector, lSector + SectorBurstVal,
918 0, g_toc[cdtracks].dwStartSector);
919 }
920 #if 0
921 /*
922 * jitter with a probability of jprob
923 */
924 if (random() <= jprob) {
925 /*
926 * jitter up to jmax samples
927 */
928 joffset = random();
929 }
930 #endif
931
932 #ifdef DEBUG_SHM
933 fprintf(stderr, ", last_b = %p\n", *last_buffer);
934 #endif
935 for (loop = lSector*CD_FRAMESAMPLES + joffset;
936 loop < (lSector+SectorBurstVal)*CD_FRAMESAMPLES + joffset;
937 loop++) {
938 *q++ = loop;
939 *q++ = ~loop;
940 }
941 #ifdef DEBUG_SHM
942 fprintf(stderr,
943 "sim wrote from %p upto %p - 4 (%d), last_b = %p\n",
944 p, q, SectorBurstVal*CD_FRAMESAMPLES, *last_buffer);
945 #endif
946 sim_pos = (lSector+SectorBurstVal)*CD_FRAMESAMPLES + joffset;
947 return (SectorBurstVal);
948 }
949
950 static int Play_at_sim __PR((SCSI *x, unsigned int from_sector,
951 unsigned int sectors));
952 static int
Play_at_sim(x,from_sector,sectors)953 Play_at_sim(x, from_sector, sectors)
954 SCSI *x;
955 unsigned int from_sector;
956 unsigned int sectors;
957 {
958 sim_pos = from_sector*CD_FRAMESAMPLES;
959 return (0);
960 }
961
962 static unsigned sim_indices;
963
964
965 /*
966 * read the table of contents (toc) via the ioctl interface
967 */
968 static unsigned ReadToc_sim __PR((SCSI *x, TOC *toc));
969 static unsigned
ReadToc_sim(x,toc)970 ReadToc_sim(x, toc)
971 SCSI *x;
972 TOC *toc;
973 {
974 unsigned int scenario;
975 int scen[12][3] = {
976 { 1, 1, 500 },
977 { 1, 2, 500 },
978 { 1, 99, 150*99 },
979 { 2, 1, 500 },
980 { 2, 2, 500 },
981 { 2, 99, 150*99 },
982 { 2, 1, 500 },
983 { 5, 2, 500 },
984 { 5, 99, 150*99 },
985 { 99, 1, 1000 },
986 { 99, 2, 1000 },
987 { 99, 99, 150*99 },
988 };
989 unsigned int i;
990 unsigned trcks;
991 #if 0
992 fprintf(stderr, "select one of the following TOCs\n"
993 "0 : 1 track with 1 index\n"
994 "1 : 1 track with 2 indices\n"
995 "2 : 1 track with 99 indices\n"
996 "3 : 2 tracks with 1 index each\n"
997 "4 : 2 tracks with 2 indices each\n"
998 "5 : 2 tracks with 99 indices each\n"
999 "6 : 2 tracks (data and audio) with 1 index each\n"
1000 "7 : 5 tracks with 2 indices each\n"
1001 "8 : 5 tracks with 99 indices each\n"
1002 "9 : 99 tracks with 1 index each\n"
1003 "10: 99 tracks with 2 indices each\n"
1004 "11: 99 tracks with 99 indices each\n");
1005
1006 do {
1007 scanf("%u", &scenario);
1008 } while (scenario > sizeof (scen)/2/sizeof (int));
1009 #else
1010 scenario = 6;
1011 #endif
1012 /*
1013 * build table of contents
1014 */
1015 #if 0
1016 trcks = scen[scenario][0] + 1;
1017 sim_indices = scen[scenario][1];
1018
1019 for (i = 0; i < trcks; i++) {
1020 toc[i].bFlags = (scenario == 6 && i == 0) ? 0x40 : 0xb1;
1021 toc[i].bTrack = i + 1;
1022 toc[i].dwStartSector = i * scen[scenario][2];
1023 toc[i].mins = (toc[i].dwStartSector+150) / (60*75);
1024 toc[i].secs = (toc[i].dwStartSector+150 / 75) % (60);
1025 toc[i].frms = (toc[i].dwStartSector+150) % (75);
1026 }
1027 toc[i].bTrack = 0xaa;
1028 toc[i].dwStartSector = i * scen[scenario][2];
1029 toc[i].mins = (toc[i].dwStartSector+150) / (60*75);
1030 toc[i].secs = (toc[i].dwStartSector+150 / 75) % (60);
1031 toc[i].frms = (toc[i].dwStartSector+150) % (75);
1032 #else
1033 {
1034 int starts[15] = { 23625, 30115, 39050, 51777, 67507,
1035 88612, 112962, 116840, 143387, 162662,
1036 173990, 186427, 188077, 209757, 257120};
1037
1038 trcks = 14 + 1;
1039 sim_indices = 1;
1040
1041 for (i = 0; i < trcks; i++) {
1042 toc[i].bFlags = 0x0;
1043 toc[i].bTrack = i + 1;
1044 toc[i].dwStartSector = starts[i];
1045 toc[i].mins = (starts[i]+150) / (60*75);
1046 toc[i].secs = (starts[i]+150 / 75) % (60);
1047 toc[i].frms = (starts[i]+150) % (75);
1048 }
1049 toc[i].bTrack = 0xaa;
1050 toc[i].dwStartSector = starts[i];
1051 toc[i].mins = (starts[i]) / (60*75);
1052 toc[i].secs = (starts[i] / 75) % (60);
1053 toc[i].frms = (starts[i]) % (75);
1054 }
1055 #endif
1056 return (--trcks); /* without lead-out */
1057 }
1058
1059
1060 static subq_chnl *ReadSubQ_sim __PR((SCSI *scgp,
1061 unsigned char sq_format,
1062 unsigned char track));
1063 /*
1064 * request sub-q-channel information. This function may cause confusion
1065 * for a drive, when called in the sampling process.
1066 */
1067 static subq_chnl *
ReadSubQ_sim(scgp,sq_format,track)1068 ReadSubQ_sim(scgp, sq_format, track)
1069 SCSI *scgp;
1070 unsigned char sq_format;
1071 unsigned char track;
1072 {
1073 subq_chnl *SQp = (subq_chnl *) (SubQbuffer);
1074 subq_position *SQPp = (subq_position *) &SQp->data;
1075 unsigned long sim_pos1;
1076 unsigned long sim_pos2;
1077
1078 if (sq_format != GET_POSITIONDATA)
1079 return (NULL); /* not supported by sim */
1080
1081 /*
1082 * simulate CDROMSUBCHNL ioctl
1083 *
1084 * copy to SubQbuffer
1085 */
1086 SQp->audio_status = 0;
1087 SQp->format = 0xff;
1088 SQp->control_adr = 0xff;
1089 sim_pos1 = sim_pos/CD_FRAMESAMPLES;
1090 sim_pos2 = sim_pos1 % 150;
1091 SQp->track = (sim_pos1 / 5000) + 1;
1092 SQp->index = ((sim_pos1 / 150) % sim_indices) + 1;
1093 sim_pos1 += 150;
1094 SQPp->abs_min = sim_pos1 / (75*60);
1095 SQPp->abs_sec = (sim_pos1 / 75) % 60;
1096 SQPp->abs_frame = sim_pos1 % 75;
1097 SQPp->trel_min = sim_pos2 / (75*60);
1098 SQPp->trel_sec = (sim_pos2 / 75) % 60;
1099 SQPp->trel_frameb = sim_pos2 % 75;
1100
1101 return ((subq_chnl *)(SubQbuffer));
1102 }
1103
1104 static void SelectSpeed_sim __PR((SCSI *x, unsigned sp));
1105 /* ARGSUSED */
1106 static void
SelectSpeed_sim(x,sp)1107 SelectSpeed_sim(x, sp)
1108 SCSI *x;
1109 unsigned sp;
1110 {
1111 }
1112
1113 static void trash_cache_sim __PR((UINT4 *p, unsigned lSector,
1114 unsigned SectorBurstVal));
1115
1116 /* ARGSUSED */
1117 static void
trash_cache_sim(p,lSector,SectorBurstVal)1118 trash_cache_sim(p, lSector, SectorBurstVal)
1119 UINT4 *p;
1120 unsigned lSector;
1121 unsigned SectorBurstVal;
1122 {
1123 }
1124
1125 static void SetupSimCd __PR((void));
1126
1127 static void
SetupSimCd()1128 SetupSimCd()
1129 {
1130 EnableCdda = (void (*) __PR((SCSI *, int, unsigned)))Dummy;
1131 ReadCdRom = ReadCdRom_sim;
1132 ReadCdRomData = (int (*) __PR((SCSI *,
1133 unsigned char *,
1134 unsigned, unsigned)))ReadCdRom_sim;
1135 doReadToc = ReadToc_sim;
1136 ReadTocText = (void (*) __PR((SCSI *)))NULL;
1137 ReadSubQ = ReadSubQ_sim;
1138 ReadSubChannels = (subq_chnl * (*) __PR((SCSI *, unsigned)))NULL;
1139 ReadLastAudio = (unsigned (*) __PR((SCSI *)))NULL;
1140 SelectSpeed = SelectSpeed_sim;
1141 Play_at = Play_at_sim;
1142 StopPlay = (int (*) __PR((SCSI *)))Dummy;
1143 trash_cache = trash_cache_sim;
1144 }
1145
1146 #endif /* def SIM_CD */
1147
1148 /* perform initialization depending on the interface used. */
1149 void
SetupInterface()1150 SetupInterface()
1151 {
1152 #if defined SIM_CD
1153 fprintf(stderr, "SIMULATION MODE !!!!!!!!!!!\n");
1154 #else
1155 /*
1156 * ensure interface is setup correctly
1157 */
1158 global.cooked_fd = OpenCdRom(global.dev_name);
1159 #endif
1160
1161 #ifdef _SC_PAGESIZE
1162 global.pagesize = sysconf(_SC_PAGESIZE);
1163 #else
1164 global.pagesize = getpagesize();
1165 #endif
1166
1167 /*
1168 * request one sector for table of contents
1169 */
1170 bufTOCsize = CD_FRAMESIZE_RAW + 96; /* Sufficient space for 222 TOC entries */
1171 bufferTOC = malloc(bufTOCsize); /* assumes sufficient aligned addresses */
1172 /*
1173 * SubQchannel buffer
1174 */
1175 SubQbuffer = malloc(48); /* assumes sufficient aligned addresses */
1176 if (!bufferTOC || !SubQbuffer) {
1177 errmsg(_("Too low on memory. Giving up.\n"));
1178 exit(NOMEM_ERROR);
1179 }
1180
1181 #if defined SIM_CD
1182 scgp = malloc(sizeof (* scgp));
1183 if (scgp == NULL) {
1184 FatalError(geterrno(), _("No memory for SCSI structure.\n"));
1185 }
1186 scgp->silent = 0;
1187 SetupSimCd();
1188 #else
1189 /*
1190 * if drive is of type scsi, get vendor name
1191 */
1192 if (interface == GENERIC_SCSI) {
1193 unsigned sector_size;
1194 SCSI *scgp = _scgp;
1195
1196 SetupSCSI(scgp);
1197 sector_size = get_orig_sectorsize(scgp, &orgmode4, &orgmode10,
1198 &orgmode11);
1199 if (!SCSI_emulated_ATAPI_on(scgp)) {
1200 if (sector_size != 2048 &&
1201 set_sectorsize(scgp, 2048)) {
1202 fprintf(stderr,
1203 _("Could not change sector size from %u to 2048\n"),
1204 sector_size);
1205 }
1206 }
1207
1208 /*
1209 * get cache setting
1210 *
1211 * set cache to zero
1212 */
1213 } else {
1214 #if defined(HAVE_IOCTL_INTERFACE)
1215 _scgp = malloc(sizeof (* _scgp));
1216 if (_scgp == NULL) {
1217 FatalError(geterrno(),
1218 _("No memory for SCSI structure.\n"));
1219 }
1220 _scgp->silent = 0;
1221 SetupCookedIoctl(global.dev_name);
1222 #else
1223 FatalError(EX_BAD,
1224 _("Sorry, there is no known method to access the device.\n"));
1225 #endif
1226 }
1227 #endif /* if def SIM_CD */
1228 /*
1229 * The structure looks like a desaster :-(
1230 * We do this more than once as it is impossible to understand where
1231 * the right place would be to do this....
1232 */
1233 if (_scgp != NULL) {
1234 _scgp->verbose = global.scsi_verbose;
1235 }
1236 }
1237
1238 EXPORT int
poll_in()1239 poll_in()
1240 {
1241 #ifdef HAVE_POLL
1242 struct pollfd pfd[1];
1243
1244 pfd[0].fd = fileno(stdin);
1245 pfd[0].events = POLLIN;
1246 pfd[0].revents = 0;
1247 return (poll(pfd, 1, 0));
1248 #else
1249 #ifdef HAVE_SELECT
1250 struct timeval tv;
1251 fd_set rd;
1252
1253 FD_ZERO(&rd);
1254 FD_SET(fileno(stdin), &rd);
1255
1256 tv.tv_sec = 0;
1257 tv.tv_usec = 0;
1258 return (select(1, &rd, NULL, NULL, &tv));
1259 #else
1260 comerrno(EX_BAD, _("Poll/Select not available.\n"));
1261 #endif
1262 #endif
1263 }
1264