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