cdrecord.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:61k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)cdrecord.c 1.94 00/01/28 Copyright 1995-2000 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)cdrecord.c 1.94 00/01/28 Copyright 1995-2000 J. Schilling";
  5. #endif
  6. /*
  7.  * Record data on a CD/CVD-Recorder
  8.  *
  9.  * Copyright (c) 1995-2000 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26. #include <mconfig.h>
  27. #include <stdio.h>
  28. #include <standard.h>
  29. #include <stdxlib.h>
  30. #include <fctldefs.h>
  31. #include <errno.h>
  32. #include <sys/types.h>
  33. #include <sys/time.h>
  34. #ifdef HAVE_SYS_RESOURCE_H
  35. #include <sys/resource.h> /* for rlimit */
  36. #endif
  37. #include <sys/stat.h>
  38. #include <statdefs.h>
  39. #include <unixstd.h>
  40. #ifdef HAVE_SYS_MMAN_H
  41. #include <sys/mman.h>
  42. #endif
  43. #include <strdefs.h>
  44. #include <utypes.h>
  45. #include <intcvt.h>
  46. #include <signal.h>
  47. #include <scg/scsireg.h> /* XXX wegen SC_NOT_READY */
  48. #include <scg/scsitransp.h>
  49. #include <scg/scgcmd.h> /* XXX fuer read_buffer */
  50. #include "scsi_scan.h"
  51. #include "auheader.h"
  52. #include "cdrecord.h"
  53. char cdr_version[] = "1.8";
  54. /*
  55.  * Map toc/track types into names.
  56.  */
  57. char *toc2name[] = {
  58. "CD-DA",
  59. "CD-ROM",
  60. "CD-ROM XA mode 1",
  61. "CD-ROM XA mode 2",
  62. "CD-I",
  63. "Illegal toc type 5",
  64. "Illegal toc type 6",
  65. "Illegal toc type 7",
  66. };
  67. /*
  68.  * Map sector types into names.
  69.  */
  70. char *st2name[] = {
  71. "Illegal sector type 0",
  72. "CD-ROM mode 1",
  73. "CD-ROM mode 2",
  74. "Illegal sector type 3",
  75. "CD-DA without preemphasis",
  76. "CD-DA with preemphasis",
  77. "Illegal sector type 6",
  78. "Illegal sector type 7",
  79. };
  80. /*
  81.  * Map data block types into names.
  82.  */
  83. char *db2name[] = {
  84. "Raw (audio)",
  85. "Raw (audio) with P/Q sub channel",
  86. "Raw (audio) with P/W sub channel",
  87. "Raw (audio) with P/W raw sub channel",
  88. "Reserved mode 4",
  89. "Reserved mode 5",
  90. "Reserved mode 6",
  91. "Vendor unique mode 7",
  92. "CD-ROM mode 1",
  93. "CD-ROM mode 2",
  94. "CD-ROM XA mode 1",
  95. "CD-ROM XA mode 2 form 1",
  96. "CD-ROM XA mode 2 form 2",
  97. "CD-ROM XA mode 2 form 1/2/mix",
  98. "Reserved mode 14",
  99. "Vendor unique mode 15",
  100. };
  101. int debug; /* print debug messages */
  102. LOCAL int scsi_verbose; /* SCSI verbose flag */
  103. int lverbose; /* local verbose flag */
  104. /*
  105.  * NOTICE: You should not make BUF_SIZE more than
  106.  * the buffer size of the CD-Recorder.
  107.  *
  108.  * Do not set BUF_SIZE to be more than 126 KBytes
  109.  * if you are running cdrecord on a sun4c machine.
  110.  *
  111.  * WARNING: Philips CDD 521 dies if BUF_SIZE is to big.
  112.  */
  113. /*#define BUF_SIZE (126*1024)*/
  114. /*#define BUF_SIZE (100*1024)*/
  115. #define BUF_SIZE (63*1024)
  116. /*#define BUF_SIZE (56*1024)*/
  117. char *buf; /* The transfer buffer */
  118. long bufsize; /* The size of the transfer buffer */
  119. int data_secs_per_tr; /* # of data secs per transfer */
  120. int audio_secs_per_tr; /* # of audio secs per transfer */
  121. BOOL isgui;
  122. int didintr;
  123. struct timeval starttime;
  124. struct timeval stoptime;
  125. struct timeval fixtime;
  126. static long fs = -1L; /* fifo (ring buffer) size */
  127. EXPORT int  main __PR((int ac, char **av));
  128. LOCAL void usage __PR((int));
  129. LOCAL void blusage __PR((int));
  130. LOCAL void intr __PR((int sig));
  131. LOCAL void intfifo __PR((int sig));
  132. LOCAL void exscsi __PR((int excode, void *arg));
  133. LOCAL void excdr __PR((int excode, void *arg));
  134. EXPORT int read_buf __PR((int f, char *bp, int size));
  135. EXPORT int get_buf __PR((int f, char **bpp, int size));
  136. LOCAL int write_track_data __PR((SCSI *scgp, cdr_t *, int , track_t *));
  137. EXPORT int pad_track __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp,
  138.      long startsec, long amt,
  139.      BOOL dolast, long *bytesp));
  140. EXPORT int write_buf __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp,
  141.      char *bp, long startsec, long amt, int secsize,
  142.      BOOL dolast, long *bytesp));
  143. LOCAL void printdata __PR((int, track_t *));
  144. LOCAL void printaudio __PR((int, track_t *));
  145. LOCAL void checkfile __PR((int, track_t *));
  146. LOCAL int checkfiles __PR((int, track_t *));
  147. LOCAL void setpregaps __PR((int, track_t *));
  148. LOCAL long checktsize __PR((int, track_t *));
  149. LOCAL void checksize __PR((track_t *));
  150. LOCAL BOOL checkdsize __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp, long tsize));
  151. LOCAL void raise_fdlim __PR((void));
  152. LOCAL void gargs __PR((int, char **, int *, track_t *, char **,
  153. int *, cdr_t **,
  154. int *, long *, int *, int *));
  155. LOCAL void set_trsizes __PR((cdr_t *, int, track_t *));
  156. EXPORT void load_media __PR((SCSI *scgp, cdr_t *, BOOL));
  157. EXPORT void unload_media __PR((SCSI *scgp, cdr_t *, int));
  158. EXPORT void set_secsize __PR((SCSI *scgp, int secsize));
  159. LOCAL void check_recovery __PR((SCSI *scgp, cdr_t *, int));
  160. void audioread __PR((SCSI *scgp, cdr_t *, int));
  161. LOCAL void print_msinfo __PR((SCSI *scgp, cdr_t *));
  162. LOCAL void print_toc __PR((SCSI *scgp, cdr_t *));
  163. LOCAL void print_track __PR((int, long, struct msf *, int, int, int));
  164. LOCAL void prtimediff __PR((const char *fmt,
  165. struct timeval *start,
  166. struct timeval *stop));
  167. #if !defined(HAVE_SYS_PRIOCNTL_H)
  168. LOCAL int rt_raisepri __PR((int));
  169. #endif
  170. EXPORT void raisepri __PR((int));
  171. LOCAL void checkgui __PR((void));
  172. LOCAL char * astoll __PR((const char *s, Llong *ll));
  173. LOCAL Llong number __PR((char* arg, int* retp));
  174. EXPORT int getnum __PR((char* arg, long* valp));
  175. EXPORT int getllnum __PR((char *arg, Llong* lvalp));
  176. LOCAL int getbltype __PR((char* optstr, long *typep));
  177. struct exargs {
  178. SCSI *scgp;
  179. cdr_t *dp;
  180. int old_secsize;
  181. int flags;
  182. int exflags;
  183. } exargs;
  184. EXPORT int 
  185. main(ac, av)
  186. int ac;
  187. char *av[];
  188. {
  189. char *dev = NULL;
  190. int timeout = 40; /* Set default timeout to 40s CW-7502 is slow*/
  191. int speed = 1;
  192. long flags = 0L;
  193. int toctype = -1;
  194. int blanktype = 0;
  195. int i;
  196. int tracks = 0;
  197. int trackno;
  198. long tsize;
  199. track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */
  200. cdr_t *dp = (cdr_t *)0;
  201. dstat_t ds;
  202. long startsec = 0L;
  203. int errs = 0;
  204. SCSI *scgp;
  205. char errstr[80];
  206. #ifdef __EMX__ 
  207. /* This gives wildcard expansion with Non-Posix shells with EMX */ 
  208. _wildcard(&ac, &av); 
  209. #endif 
  210. save_args(ac, av);
  211. fillbytes(track, sizeof(track), '');
  212. raise_fdlim();
  213. gargs(ac, av, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
  214. &toctype, &blanktype);
  215. if (toctype < 0)
  216. comerrno(EX_BAD, "Internal error: Bad TOC type.n");
  217. /*
  218.  * Warning: you are not allowed to modify or to remove this
  219.  * version printing code!
  220.  */
  221. #ifdef DRV_DVD
  222. i = set_cdrcmds("mmc_dvd", (cdr_t **)NULL);
  223. #endif
  224. if ((flags & F_MSINFO) == 0 || lverbose || flags & F_VERSION)
  225. printf("Cdrecord%s %s (%s-%s-%s) Copyright (C) 1995-2000 J鰎g Schillingn",
  226. #ifdef DRV_DVD
  227. i?"-ProDVD":"",
  228. #else
  229. "",
  230. #endif
  231. cdr_version,
  232. HOST_CPU, HOST_VENDOR, HOST_OS);
  233. if (flags & F_VERSION)
  234. exit(0);
  235. checkgui();
  236. if (debug || lverbose) {
  237. printf("TOC Type: %d = %sn",
  238. toctype, toc2name[toctype & TOC_MASK]);
  239. }
  240. if ((flags & (F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_INQUIRY|F_SCANBUS|F_RESET)) == 0) {
  241. /*
  242.  * Try to lock us im memory (will only work for root)
  243.  * but you need access to root anyway to use /dev/scg?
  244.  */
  245. #if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK)
  246. if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
  247. errmsg("WARNING: Cannot do mlockall(2).n");
  248. errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.n");
  249. }
  250. #endif
  251. raisepri(0); /* max priority */
  252. init_fifo(fs);
  253. }
  254. if ((scgp = open_scsi(dev, errstr, sizeof(errstr),
  255. debug, (flags & F_MSINFO) == 0 || lverbose)) == (SCSI *)0) {
  256. errmsg("%s%sCannot open SCSI driver.n", errstr, errstr[0]?". ":"");
  257. comerrno(EX_BAD, "For possible targets try 'cdrecord -scanbus'. Make sure you are root.n");
  258. }
  259. scsi_settimeout(scgp, timeout);
  260. scgp->verbose = scsi_verbose;
  261. scgp->debug = debug;
  262. scgp->cap->c_bsize = 2048;
  263. if ((flags & F_MSINFO) == 0 || lverbose) {
  264. char *vers;
  265. char *auth;
  266. /*
  267.  * Warning: you are not allowed to modify or to remove this 
  268.  * version checking code!
  269.  */
  270. vers = scg_version(0, SCG_VERSION);
  271. auth = scg_version(0, SCG_AUTHOR);
  272. printf("Using libscg version '%s-%s'n", auth, vers);
  273. if (auth == 0 || strcmp("schily", auth) != 0) {
  274. errmsgno(EX_BAD,
  275. "Warning: using inofficial version of libscg (%s-%s '%s').n",
  276. auth, vers, scg_version(0, SCG_SCCS_ID));
  277. }
  278. vers = scg_version(scgp, SCG_VERSION);
  279. auth = scg_version(scgp, SCG_AUTHOR);
  280. if (lverbose > 1)
  281. error("Using libscg transport code version '%s-%s'n", auth, vers);
  282. if (auth == 0 || strcmp("schily", auth) != 0) {
  283. errmsgno(EX_BAD,
  284. "Warning: using inofficial libscg transport code version (%s-%s '%s').n",
  285. auth, vers, scg_version(scgp, SCG_SCCS_ID));
  286. }
  287. }
  288. bufsize = scsi_bufsize(scgp, BUF_SIZE);
  289. if ((buf = scsi_getbuf(scgp, bufsize)) == NULL)
  290. comerr("Cannot get SCSI I/O buffer.n");
  291. if ((flags & F_SCANBUS) != 0) {
  292. select_target(scgp);
  293. exit(0);
  294. }
  295. if ((flags & F_RESET) != 0) {
  296. scsireset(scgp);
  297. exit(0);
  298. }
  299. /*
  300.  * First try to check which type of SCSI device we
  301.  * have.
  302.  */
  303. if (debug || lverbose)
  304. printf("atapi: %dn", scsi_isatapi(scgp));
  305. scgp->silent++;
  306. test_unit_ready(scgp); /* eat up unit attention */
  307. scgp->silent--;
  308. if (!do_inquiry(scgp, (flags & F_MSINFO) == 0 || lverbose)) {
  309. errmsgno(EX_BAD, "Cannot do inquiry for CD/DVD-Recorder.n");
  310. if (unit_ready(scgp))
  311. errmsgno(EX_BAD, "The unit seems to be hung and needs power cycling.n");
  312. exit(EX_BAD);
  313. }
  314. if ((flags & F_PRCAP) != 0) {
  315. print_capabilities(scgp);
  316. exit(0);
  317. }
  318. if ((flags & F_INQUIRY) != 0)
  319. exit(0);
  320. if (dp == (cdr_t *)NULL) { /* No driver= option specified */
  321. dp = get_cdrcmds(scgp);
  322. } else if (!is_unknown_dev(scgp) && dp != get_cdrcmds(scgp)) {
  323. errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.n");
  324. }
  325. if (!is_cddrive(scgp))
  326. comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.n");
  327. if (dp == (cdr_t *)0)
  328. comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.n");
  329. if (((flags & (F_MSINFO|F_TOC|F_LOAD|F_EJECT)) == 0 || tracks > 0) &&
  330. (dp->cdr_flags & CDR_ISREADER) != 0) {
  331. comerrno(EX_BAD,
  332. "Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.n");
  333. }
  334. if ((*dp->cdr_attach)(scgp, dp) != 0)
  335. comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.n");
  336. exargs.scgp    = scgp;
  337. exargs.dp    = dp;
  338. exargs.old_secsize = -1;
  339. exargs.flags    = flags;
  340. if ((flags & F_MSINFO) == 0 || lverbose) {
  341. printf("Using %s (%s).n", dp->cdr_drtext, dp->cdr_drname);
  342. printf("Driver flags   : ");
  343. if ((dp->cdr_flags & CDR_SWABAUDIO) != 0)
  344. printf("SWABAUDIO");
  345. printf("n");
  346. }
  347. scgp->silent++;
  348. if ((debug || lverbose)) {
  349. tsize = -1;
  350. if ((*dp->cdr_buffer_cap)(scgp, &tsize, (long *)0) < 0 || tsize <= 0) {
  351. if (read_buffer(scgp, buf, 4, 0) >= 0)
  352. tsize = a_to_u_4_byte(buf);
  353. }
  354. if (tsize > 0) {
  355. printf("Drive buf size : %lu = %lu KBn",
  356. tsize, tsize >> 10);
  357. }
  358. }
  359. scgp->silent--;
  360. if (tracks > 0 && (debug || lverbose))
  361. printf("FIFO size      : %lu = %lu KBn", fs, fs >> 10);
  362. if ((flags & F_CHECKDRIVE) != 0)
  363. exit(0);
  364. if (tracks == 0 && (flags & (F_FIX|F_BLANK)) == 0 && (flags & F_EJECT) != 0) {
  365. /*
  366.  * Do not check if the unit is ready here to allow to open
  367.  * an empty unit too.
  368.  */
  369. unload_media(scgp, dp, flags);
  370. exit(0);
  371. }
  372. flush();
  373. if (tracks > 1)
  374. sleep(2); /* Let the user watch the inquiry messages */
  375. set_trsizes(dp, tracks, track);
  376. setpregaps(tracks, track);
  377. checkfiles(tracks, track);
  378. tsize = checktsize(tracks, track);
  379. do_cue(tracks, track, 0);
  380. /*
  381.  * Is this the right place to do this ?
  382.  */
  383. check_recovery(scgp, dp, flags);
  384. if ((flags & F_FORCE) == 0)
  385. load_media(scgp, dp, TRUE);
  386. if ((flags & F_LOAD) != 0) {
  387. scgp->silent++; /* silently      */
  388. scsi_prevent_removal(scgp, 0); /* allow manual open */
  389. scgp->silent--; /* if load failed... */
  390. exit(0);
  391. }
  392. exargs.old_secsize = sense_secsize(scgp, 1);
  393. if (exargs.old_secsize < 0)
  394. exargs.old_secsize = sense_secsize(scgp, 0);
  395. on_comerr(exscsi, &exargs);
  396. if (lverbose)
  397. printf("Current Secsize: %dn", exargs.old_secsize);
  398. if (exargs.old_secsize > 0 && exargs.old_secsize != 2048) {
  399. /*
  400.  * Some drives (e.g. Plextor) don't like to write correctly
  401.  * in DAO mode if the sector size is set to 512 bytes.
  402.  * In addition, cdrecord -msinfo will not work properly
  403.  * if the sector size is not 2048 bytes.
  404.  */
  405. set_secsize(scgp, 2048);
  406. }
  407. /*audioread(dp, flags);*/
  408. /*unload_media(scgp, dp, flags);*/
  409. /*return 0;*/
  410. fillbytes(&ds, sizeof(ds), '');
  411. if (flags & F_WRITE)
  412. ds.ds_cdrflags = RF_WRITE;
  413. if (flags & F_PRATIP) {
  414. lverbose++; /* XXX Hack */
  415. }
  416. if ((*dp->cdr_getdisktype)(scgp, dp, &ds) < 0) {
  417. errmsgno(EX_BAD, "Cannot get disk type.n");
  418. exscsi(EX_BAD, &exargs);
  419. if ((flags & F_FORCE) == 0)
  420. exit(EX_BAD);
  421. }
  422. if (flags & F_PRATIP) {
  423. lverbose--; /* XXX Hack */
  424. exscsi(0, &exargs);
  425. exit(0);
  426. }
  427. /*
  428.  * The next actions should depend on the disk type.
  429.  */
  430. /*
  431.  * Dirty hack!
  432.  * At least MMC drives will not return the next writable
  433.  * address we expect when the drive's write mode is set
  434.  * tp DAO/SAO. We need this address for mkisofs and thus
  435.  * it must be the first user accessible sector and not the
  436.  * first sector of the pregap. Set_speed_dummy() witha a
  437.  * 'speedp' f 0 sets the write mode to TAO on MMC drives.
  438.  *
  439.  * We set TAO unconditionally to make checkdsize() work
  440.  * currectly in DAO mode too.
  441.  */
  442. scgp->silent++;
  443. (*dp->cdr_set_speed_dummy)(scgp, 0, TRUE);
  444. scgp->silent--;
  445. if (flags & F_MSINFO) {
  446. print_msinfo(scgp, dp);
  447. exscsi(0, &exargs);
  448. exit(0);
  449. }
  450. if (flags & F_TOC) {
  451. print_toc(scgp, dp);
  452. exscsi(0, &exargs);
  453. exit(0);
  454. }
  455. #ifdef XXX
  456. if ((*dp->cdr_check_session)() < 0) {
  457. exscsi(EX_BAD, &exargs);
  458. exit(EX_BAD);
  459. }
  460. #endif
  461. if (tsize == 0) {
  462. if (tracks > 0) {
  463. errmsgno(EX_BAD,
  464. "WARNING: Track size unknown. Data may not fit on disk.n");
  465. }
  466. } else if (!checkdsize(scgp, dp, &ds, tsize) && (flags & (F_IGNSIZE|F_FORCE)) == 0) {
  467. exscsi(EX_BAD, &exargs);
  468. exit(EX_BAD);
  469. }
  470. if (tracks > 0 && fs > 0l) {
  471. /*
  472.  * Start the extra process needed for improved buffering.
  473.  */
  474. if (!init_faio(tracks, track, bufsize))
  475. fs = 0L;
  476. else
  477. on_comerr(excdr, &exargs);
  478. }
  479. if ((*dp->cdr_set_speed_dummy)(scgp, &speed, flags & F_DUMMY) < 0) {
  480. errmsgno(EX_BAD, "Cannot set speed/dummy.n");
  481. excdr(EX_BAD, &exargs);
  482. exit(EX_BAD);
  483. }
  484. if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) {
  485. wait_unit_ready(scgp, 120);
  486. scsi_blank(scgp, 0L, blanktype);
  487. excdr(0, &exargs);
  488. exit(0);
  489. }
  490. /*
  491.  * Last chance to quit!
  492.  */
  493. printf("Starting to write CD/DVD at speed %d in %s mode for %s session.n",
  494. speed,
  495. (flags & F_DUMMY) ? "dummy" : "write",
  496. (flags & F_MULTI) ? "multi" : "single");
  497. printf("Last chance to quit, starting %s write in 9 seconds.",
  498. (flags & F_DUMMY)?"dummy":"real");
  499. flush();
  500. signal(SIGINT, intr);
  501. for (i=9; --i > 0;) {
  502. sleep(1);
  503. if (didintr) {
  504. printf("n");
  505. goto restore_it;
  506. }
  507. printf("bbbbbbbbbb%d seconds.", i);
  508. flush();
  509. }
  510. signal(SIGINT, SIG_DFL);
  511. signal(SIGINT, intfifo);
  512. signal(SIGTERM, intfifo);
  513. printf("n");
  514. if (tracks > 0 && fs > 0l) {
  515. /*
  516.  * Wait for the read-buffer to become full.
  517.  * This should be take no extra time if the input is a file.
  518.  * If the input is a pipe (e.g. mkisofs) this can take a
  519.  * while. If mkisofs dumps core before it starts writing,
  520.  * we abort before the writing process started.
  521.  */
  522. if (!await_faio()) {
  523. errmsgno(EX_BAD, "Input buffer error, aborting.n");
  524. excdr(EX_BAD, &exargs);
  525. exit(EX_BAD);
  526. }
  527. }
  528. if (gettimeofday(&starttime, (struct timezone *)0) < 0)
  529. errmsg("Cannot get start timen");
  530. /*
  531.  * Blank the media if we were requested to do so
  532.  */
  533. if (flags & F_BLANK) {
  534. if ((*dp->cdr_blank)(scgp, 0L, blanktype) < 0) {
  535. errmsgno(EX_BAD, "Cannot blank disk, aborting.n");
  536. excdr(EX_BAD, &exargs);
  537. exit(EX_BAD);
  538. }
  539. if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
  540. errmsg("Cannot get blank timen");
  541. if (lverbose)
  542. prtimediff("Blanking time: ", &starttime, &fixtime);
  543. if (!wait_unit_ready(scgp, 60) || tracks == 0) {
  544. excdr(0, &exargs);
  545. exit(0);
  546. }
  547. /*
  548.  * Reset start time so we will not see blanking time and
  549.  * writing time counted together.
  550.  */
  551. if (gettimeofday(&starttime, (struct timezone *)0) < 0)
  552. errmsg("Cannot get start timen");
  553. }
  554. /*
  555.  * Get the number of the next recordable track.
  556.  */
  557. scgp->silent++;
  558. if (read_tochdr(scgp, dp, NULL, &trackno) < 0) {
  559. trackno = 0;
  560. }
  561. scgp->silent--;
  562. for (i = 1; i <= tracks; i++) {
  563. track[i].trackno = i + trackno;
  564. }
  565. trackno++;
  566. track[0].trackno = trackno; /* XXX Hack for TEAC fixate */
  567. /*
  568.  * Now we actually start writing to the CD/DVD.
  569.  * XXX Check total size of the tracks and remaining size of disk.
  570.  */
  571. if ((*dp->cdr_open_session)(scgp, tracks, track, toctype, flags & F_MULTI) < 0) {
  572. errmsgno(EX_BAD, "Cannot open new session.n");
  573. excdr(EX_BAD, &exargs);
  574. exit(EX_BAD);
  575. }
  576. /*
  577.  * As long as open_session() will do nothing but
  578.  * set up parameters, we may leave fix_it here.
  579.  * I case we have to add an open_session() for a drive
  580.  * that wants to do something that modifies the disk
  581.  * We have to think about a new solution.
  582.  */
  583. if (flags & F_FIX)
  584. goto fix_it;
  585. if (flags & F_SAO) {
  586. if (debug || lverbose) {
  587. printf("Sending CUE sheet...n");
  588. flush();
  589. }
  590. if ((*dp->cdr_send_cue)(scgp, tracks, track) < 0) {
  591. errmsgno(EX_BAD, "Cannot send CUE sheet.n");
  592. excdr(EX_BAD, &exargs);
  593. exit(EX_BAD);
  594. }
  595. }
  596. if ((flags & F_SAO)) {
  597. (*dp->cdr_next_wr_address)(scgp, 0, &track[0], &startsec);
  598. if (startsec <= 0 && startsec != -150) {
  599. errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%d) using -150n",
  600. startsec);
  601. startsec = -150;
  602. }
  603. if (debug)
  604. printf("SAO startsec: %ldn", startsec);
  605. for (i = 1; i <= tracks; i++) {
  606. track[i].trackstart += startsec +150;
  607. }
  608. #ifdef XXX
  609. if (debug || lverbose)
  610. printf("Writing lead-in...n");
  611. pad_track(scgp, dp, 1, &track[1], -150, 0,
  612. FALSE, 0);
  613. #endif
  614. }
  615. /*
  616.  * Need to set trackno to the real value from
  617.  * the current disk status.
  618.  */
  619. for (i = 1; i <= tracks; i++, trackno++) {
  620. startsec = 0L;
  621. /*
  622.  * trackno is the "real" track number while 'i' is a counter
  623.  * going from 1 to tracks.
  624.  */
  625. if ((*dp->cdr_open_track)(scgp, dp, trackno, &track[i]) < 0) {
  626. errs++;
  627. break;
  628. }
  629. if ((flags & F_SAO) == 0) {
  630. if ((*dp->cdr_next_wr_address)(scgp, trackno, &track[i], &startsec) < 0) {
  631. errs++;
  632. break;
  633. }
  634. track[i].trackstart = startsec;
  635. }
  636. if (debug || lverbose) {
  637. printf("Starting new track at sector: %ldn",
  638. track[i].trackstart);
  639. flush();
  640. }
  641. if (write_track_data(scgp, dp, trackno, &track[i]) < 0) {
  642. errs++;
  643. sleep(5);
  644. request_sense(scgp);
  645. (*dp->cdr_close_track)(scgp, trackno, &track[i]);
  646. break;
  647. }
  648. if ((*dp->cdr_close_track)(scgp, trackno, &track[i]) < 0) {
  649. /*
  650.  * Check for "Dummy blocks added" message first.
  651.  */
  652. if (scsi_sense_key(scgp) != SC_ILLEGAL_REQUEST ||
  653. scsi_sense_code(scgp) != 0xB5) {
  654. errs++;
  655. break;
  656. }
  657. }
  658. }
  659. fix_it:
  660. if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
  661. errmsg("Cannot get stop timen");
  662. if (lverbose)
  663. prtimediff("Writing  time: ", &starttime, &stoptime);
  664. if ((flags & F_NOFIX) == 0) {
  665. if (lverbose) {
  666. printf("Fixating...n");
  667. flush();
  668. }
  669. if ((*dp->cdr_fixate)(scgp, flags & F_MULTI, flags & F_DUMMY,
  670. toctype, tracks, track) < 0)
  671. errs++;
  672. if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
  673. errmsg("Cannot get fix timen");
  674. if (lverbose)
  675. prtimediff("Fixating time: ", &stoptime, &fixtime);
  676. }
  677. restore_it:
  678. /*
  679.  * Try to restore the old sector size and stop FIFO.
  680.  */
  681. excdr(errs?-2:0, &exargs);
  682. exit(errs?-2:0);
  683. return (0);
  684. }
  685. LOCAL void 
  686. usage(excode)
  687. int excode;
  688. {
  689. errmsgno(EX_BAD, "Usage: %s [options] track1...tracknn",
  690. get_progname());
  691. error("Options:n");
  692. error("t-version print version information and exitn");
  693. error("t-v increment general verbose level by onen");
  694. error("t-V increment SCSI command transport verbose level by onen");
  695. error("t-debug print additional debug messagesn");
  696. error("tdev=target SCSI target to use as CD/DVD-Recordern");
  697. error("ttimeout=# set the default SCSI command timeout to #.n");
  698. error("tdriver=name user supplied driver name, use with extreme caren");
  699. error("t-checkdrive check if a driver for the drive is presentn");
  700. error("t-prcap print drive capabilities for MMC compliant drivesn");
  701. error("t-inq do an inquiry for the drive end exitn");
  702. error("t-scanbus scan the SCSI bus end exitn");
  703. error("t-reset reset the SCSI bus with the cdrecorder (if possible)n");
  704. error("t-ignsize ignore the known size of a medium (may cause problems)n");
  705. error("t-useinfo use *.inf files to overwrite audio options.n");
  706. error("tspeed=# set speed of driven");
  707. error("tblank=type blank a CD-RW disc (see blank=help)n");
  708. #ifdef FIFO
  709. error("tfs=# Set fifo size to # (0 to disable, default is %ld MB)n",
  710. DEFAULT_FIFOSIZE/(1024*1024));
  711. #endif
  712. error("t-load load the disk and exit (works only with tray loader)n");
  713. error("t-eject eject the disk after doing the workn");
  714. error("t-dummy do everything with laser turned offn");
  715. error("t-msinfo retrieve multi-session info for mkisofs >= 1.10n");
  716. error("t-toc retrieve and print TOC/PMA datan");
  717. error("t-atip retrieve and print ATIP datan");
  718. error("t-multi generate a TOC that allows multi sessionn");
  719. error("t In this case default track type is CD-ROM XA2n");
  720. error("t-fix fixate a corrupt or unfixated disk (generate a TOC)n");
  721. error("t-nofix do not fixate disk after writing tracksn");
  722. error("t-force force to continue on some errors to allow blanking bad disksn");
  723. error("t-dao Write disk in DAO mode. This option will go away in the future.n");
  724. error("ttsize=# Length of valid data in next trackn");
  725. error("tpadsize=# Amount of padding for next trackn");
  726. error("tpregap=# Amount of pre-gap sectors before next trackn");
  727. error("tdefpregap=# Amount of pre-gap sectors for all but track #1n");
  728. error("tmcn=text Set the media catalog number for this CD to 'text'n");
  729. error("tisrc=text Set the ISRC number for the next track to 'text'n");
  730. error("tindex=list Set the index list for the next track to 'list'n");
  731. error("t-audio Subsequent tracks are CD-DA audio tracksn");
  732. error("t-data Subsequent tracks are CD-ROM data mode 1 (default)n");
  733. error("t-mode2 Subsequent tracks are CD-ROM data mode 2n");
  734. error("t-xa1 Subsequent tracks are CD-ROM XA mode 1n");
  735. error("t-xa2 Subsequent tracks are CD-ROM XA mode 2n");
  736. error("t-cdi Subsequent tracks are CDI tracksn");
  737. error("t-isosize Use iso9660 file system size for next data trackn");
  738. error("t-preemp Audio tracks are mastered with 50/15 祍 preemphasisn");
  739. error("t-nopreemp Audio tracks are mastered with no preemphasis (default)n");
  740. error("t-pad Pad data tracks with %d zeroed sectorsn", PAD_SECS);
  741. error("t Pad audio tracks to a multiple of %d bytesn", AUDIO_SEC_SIZE);
  742. error("t-nopad Do not pad data tracks (default)n");
  743. error("t-swab Audio data source is byte-swapped (little-endian/Intel)n");
  744. error("The type of the first track is used for the toc type.n");
  745. error("Currently only form 1 tracks are supported.n");
  746. exit(excode);
  747. }
  748. LOCAL void
  749. blusage(ret)
  750. int ret;
  751. {
  752. error("Blanking options:n");
  753. error("tallttblank the entire diskn");
  754. error("tdiscttblank the entire diskn");
  755. error("tdiskttblank the entire diskn");
  756. error("tfastttminimally blank the entire disk (PMA, TOC, pregap)n");
  757. error("tminimalttminimally blank the entire disk (PMA, TOC, pregap)n");
  758. error("ttrackttblank a trackn");
  759. error("tunreservetunreserve a trackn");
  760. error("ttrtailttblank a track tailn");
  761. error("tunclosettunclose last sessionn");
  762. error("tsessionttblank last sessionn");
  763. exit(ret);
  764. /* NOTREACHED */
  765. }
  766. LOCAL void
  767. intr(sig)
  768. int sig;
  769. {
  770. sig = 0; /* Fake usage */
  771. signal(SIGINT, intr);
  772. didintr++;
  773. }
  774. LOCAL void
  775. intfifo(sig)
  776. int sig;
  777. {
  778. excdr(sig, NULL);
  779. exit(sig);
  780. }
  781. LOCAL void
  782. exscsi(excode, arg)
  783. int excode;
  784. void *arg;
  785. {
  786. struct exargs *exp = (struct exargs *)arg;
  787. /*
  788.  * Try to restore the old sector size.
  789.  */
  790. if (exp != NULL && exp->exflags == 0) {
  791. set_secsize(exp->scgp, exp->old_secsize);
  792. unload_media(exp->scgp, exp->dp, exp->flags);
  793. exp->exflags++; /* Make sure that it only get called once */
  794. }
  795. }
  796. LOCAL void
  797. excdr(excode, arg)
  798. int excode;
  799. void *arg;
  800. {
  801. exscsi(excode, arg);
  802. #ifdef FIFO
  803. kill_faio();
  804. wait_faio();
  805. if (debug || lverbose)
  806. fifo_stats();
  807. #endif
  808. }
  809. EXPORT int
  810. read_buf(f, bp, size)
  811. int f;
  812. char *bp;
  813. int size;
  814. {
  815. char *p = bp;
  816. int amount = 0;
  817. int n;
  818. do {
  819. do {
  820. n = read(f, p, size-amount);
  821. } while (n < 0 && (errno == EAGAIN || errno == EINTR));
  822. if (n < 0)
  823. return (n);
  824. amount += n;
  825. p += n;
  826. } while (amount < size && n > 0);
  827. return (amount);
  828. }
  829. EXPORT int
  830. get_buf(f, bpp, size)
  831. int f;
  832. char **bpp;
  833. int size;
  834. {
  835. if (fs > 0) {
  836. /* return (faio_read_buf(f, *bpp, size));*/
  837. return (faio_get_buf(f, bpp, size));
  838. } else {
  839. return (read_buf(f, *bpp, size));
  840. }
  841. }
  842. LOCAL int
  843. write_track_data(scgp, dp, track, trackp)
  844. SCSI *scgp;
  845. cdr_t *dp;
  846. int track;
  847. track_t *trackp;
  848. {
  849. int f;
  850. int isaudio;
  851. long startsec;
  852. long bytes_read = 0;
  853. long bytes = 0;
  854. long savbytes = 0;
  855. int count;
  856. long tracksize;
  857. int secsize;
  858. int secspt;
  859. int bytespt;
  860. int bytes_to_read;
  861. long amount;
  862. int pad;
  863. int bswab;
  864. BOOL neednl = FALSE;
  865. BOOL islast = FALSE;
  866. char *bp = buf;
  867. long bsize;
  868. long bfree;
  869. #ifdef BCAP
  870. int per;
  871. int oper = -1;
  872. #endif
  873. scgp->silent++;
  874. if (read_buff_cap(scgp, &bsize, &bfree) < 0)
  875. bsize = -1;
  876. scgp->silent--;
  877. if (is_packet(trackp)) /* XXX Ugly hack for now */
  878. return (write_packet_data(scgp, dp, track, trackp));
  879. f = trackp->f;
  880. isaudio = is_audio(trackp);
  881. tracksize = trackp->tracksize;
  882. startsec = trackp->trackstart;
  883. secsize = trackp->secsize;
  884. secspt = trackp->secspt;
  885. bytespt = secsize * secspt;
  886. pad = !isaudio && is_pad(trackp); /* Pad only data tracks */
  887. bswab = isaudio && is_swab(trackp); /* Swab only audio tracks */
  888. if (debug) {
  889. printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%dn",
  890. secsize, secspt, bytespt, isaudio, pad);
  891. }
  892. if (lverbose) {
  893. if (tracksize > 0)
  894. printf("rTrack %02d:   0 of %3ld MB written.",
  895.        track, tracksize >> 20);
  896. else
  897. printf("rTrack %02d:   0 MB written.", track);
  898. flush();
  899. neednl = TRUE;
  900. }
  901. do {
  902. bytes_to_read = bytespt;
  903. if (tracksize > 0) {
  904. bytes_to_read = tracksize - bytes_read;
  905. if (bytes_to_read > bytespt)
  906. bytes_to_read = bytespt;
  907. }
  908. count = get_buf(f, &bp, bytes_to_read);
  909. if (count < 0)
  910. comerr("read error on input filen");
  911. if (count == 0)
  912. break;
  913. bytes_read += count;
  914. if (tracksize >= 0 && bytes_read >= tracksize) {
  915. count -= bytes_read - tracksize;
  916. if (trackp->padsize == 0 && (bytes_read/secsize) >= 300)
  917. islast = TRUE;
  918. }
  919. if (bswab)
  920. swabbytes(bp, count);
  921. if (count < bytespt) {
  922. if (debug) {
  923. printf("nNOTICE: reducing block size for last record.n");
  924. neednl = FALSE;
  925. }
  926. if ((amount = count % secsize) != 0) {
  927. amount = secsize - amount;
  928. fillbytes(&bp[count], amount, '');
  929. count += amount;
  930. printf("nWARNING: padding up to secsize.n");
  931. neednl = FALSE;
  932. }
  933. bytespt = count;
  934. secspt = count / secsize;
  935. if (trackp->padsize == 0 && (bytes_read/secsize) >= 300)
  936. islast = TRUE;
  937. }
  938. amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
  939. if (amount < 0) {
  940. printf("%swrite track data: error after %ld bytesn",
  941. neednl?"n":"", bytes);
  942. return (-1);
  943. }
  944. bytes += amount;
  945. startsec += amount / secsize;
  946. if (lverbose && (bytes >= (savbytes + 0x100000))) {
  947. int fper;
  948. printf("rTrack %02d: %3ld", track, bytes >> 20);
  949. if (tracksize > 0)
  950. printf(" of %3ld MB", tracksize >> 20);
  951. else
  952. printf(" MB");
  953. printf(" written");
  954. fper = fifo_percent(TRUE);
  955. if (fper >= 0)
  956. printf(" (fifo %3d%%)", fper);
  957. printf(".");
  958. savbytes = (bytes >> 20) << 20;
  959. flush();
  960. neednl = TRUE;
  961. }
  962. #ifdef BCAP
  963. if (bsize >= 0) {
  964. read_buff_cap(scgp, 0, &bfree);
  965. per = 100*(bsize - bfree) / bsize;
  966. if (per != oper)
  967. printf("[%3d] %3d %3dbbbbbbbbbbbbbb",
  968. per, bsize >> 10, bfree >> 10);
  969. oper = per;
  970. flush();
  971. }
  972. #endif
  973. } while (tracksize < 0 || bytes_read < tracksize);
  974. if ((bytes / secsize) < 300) {
  975. amount = roundup(trackp->padsize, secsize);
  976. if (((bytes+amount) / secsize) < 300)
  977. trackp->padsize = 300 * secsize - bytes;
  978. }
  979. if (trackp->padsize) {
  980. if (neednl) {
  981. printf("n");
  982. neednl = FALSE;
  983. }
  984. if ((trackp->padsize >> 20) > 0) {
  985. neednl = TRUE;
  986. } else if (lverbose) {
  987. printf("Track %02d: writing %3ld KB of pad data.n",
  988. track, trackp->padsize >> 10);
  989. neednl = FALSE;
  990. }
  991. pad_track(scgp, dp, track, trackp, startsec, trackp->padsize,
  992. TRUE, &amount);
  993. bytes += amount;
  994. startsec += amount / secsize;
  995. }
  996. printf("%sTrack %02d: Total bytes read/written: %ld/%ld (%ld sectors).n",
  997.        neednl?"n":"", track, bytes_read, bytes, bytes/secsize);
  998. flush();
  999. return 0;
  1000. }
  1001. EXPORT int
  1002. pad_track(scgp, dp, track, trackp, startsec, amt, dolast, bytesp)
  1003. SCSI *scgp;
  1004. cdr_t *dp;
  1005. int track;
  1006. track_t *trackp;
  1007. long startsec;
  1008. long amt;
  1009. BOOL dolast;
  1010. long *bytesp;
  1011. {
  1012. long bytes = 0;
  1013. long savbytes = 0;
  1014. int secsize;
  1015. int secspt;
  1016. int bytespt;
  1017. int amount;
  1018. BOOL neednl = FALSE;
  1019. BOOL islast = FALSE;
  1020. secsize = trackp->secsize;
  1021. secspt = trackp->secspt;
  1022. bytespt = secsize * secspt;
  1023. fillbytes(buf, bytespt, '');
  1024. if ((amt >> 20) > 0) {
  1025. printf("rTrack %02d:   0 of %3ld MB pad written.",
  1026. track, amt >> 20);
  1027. flush();
  1028. }
  1029. do {
  1030. if (amt < bytespt) {
  1031. bytespt = roundup(amt, secsize);
  1032. secspt = bytespt / secsize;
  1033. }
  1034. if (dolast && (amt - bytespt) <= 0)
  1035. islast = TRUE;
  1036. amount = (*dp->cdr_write_trackdata)(scgp, buf, startsec, bytespt, secspt, islast);
  1037. if (amount < 0) {
  1038. printf("%swrite track data: error after %ld bytesn",
  1039. neednl?"n":"", bytes);
  1040. if (bytesp)
  1041. *bytesp = bytes;
  1042. read_buff_cap(scgp, 0, 0);
  1043. return (-1);
  1044. }
  1045. amt -= amount;
  1046. bytes += amount;
  1047. startsec += amount / secsize;
  1048. if (lverbose && (bytes >= (savbytes + 0x100000))) {
  1049. printf("rTrack %02d: %3ld", track, bytes >> 20);
  1050. savbytes = (bytes >> 20) << 20;
  1051. flush();
  1052. neednl = TRUE;
  1053. }
  1054. } while (amt > 0);
  1055. if (bytesp)
  1056. *bytesp = bytes;
  1057. return (bytes);
  1058. }
  1059. #ifdef USE_WRITE_BUF
  1060. EXPORT int
  1061. write_buf(scgp, dp, track, trackp, bp, startsec, amt, secsize, dolast, bytesp)
  1062. SCSI *scgp;
  1063. cdr_t *dp;
  1064. int track;
  1065. track_t *trackp;
  1066. char *bp;
  1067. long startsec;
  1068. long amt;
  1069. int secsize;
  1070. BOOL dolast;
  1071. long *bytesp;
  1072. {
  1073. long bytes = 0;
  1074. long savbytes = 0;
  1075. /* int secsize;*/
  1076. int secspt;
  1077. int bytespt;
  1078. int amount;
  1079. BOOL neednl = FALSE;
  1080. BOOL islast = FALSE;
  1081. /* secsize = trackp->secsize;*/
  1082. /* secspt = trackp->secspt;*/
  1083. secspt = bufsize/secsize;
  1084. secspt = min(255, secspt);
  1085. bytespt = secsize * secspt;
  1086. /* fillbytes(buf, bytespt, '');*/
  1087. if ((amt >> 20) > 0) {
  1088. printf("rTrack %02d:   0 of %3ld MB pad written.",
  1089. track, amt >> 20);
  1090. flush();
  1091. }
  1092. do {
  1093. if (amt < bytespt) {
  1094. bytespt = roundup(amt, secsize);
  1095. secspt = bytespt / secsize;
  1096. }
  1097. if (dolast && (amt - bytespt) <= 0)
  1098. islast = TRUE;
  1099. amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
  1100. if (amount < 0) {
  1101. printf("%swrite track data: error after %ld bytesn",
  1102. neednl?"n":"", bytes);
  1103. if (bytesp)
  1104. *bytesp = bytes;
  1105. read_buff_cap(scgp, 0, 0);
  1106. return (-1);
  1107. }
  1108. amt -= amount;
  1109. bytes += amount;
  1110. startsec += amount / secsize;
  1111. if (lverbose && (bytes >= (savbytes + 0x100000))) {
  1112. printf("rTrack %02d: %3ld", track, bytes >> 20);
  1113. savbytes = (bytes >> 20) << 20;
  1114. flush();
  1115. neednl = TRUE;
  1116. }
  1117. } while (amt > 0);
  1118. if (bytesp)
  1119. *bytesp = bytes;
  1120. return (bytes);
  1121. }
  1122. #endif /* USE_WRITE_BUF */
  1123. LOCAL void
  1124. printdata(track, trackp)
  1125. int track;
  1126. track_t *trackp;
  1127. {
  1128. if (trackp->tracksize >= 0) {
  1129. printf("Track %02d: data  %3ld MB        ",
  1130. track, trackp->tracksize >> 20);
  1131. } else {
  1132. printf("Track %02d: data  unknown length",
  1133. track);
  1134. }
  1135. if (trackp->padsize > 0) {
  1136. if ((trackp->padsize >> 20) > 0)
  1137. printf(" padsize: %3ld MB", trackp->padsize >> 20);
  1138. else
  1139. printf(" padsize: %3ld KB", trackp->padsize >> 10);
  1140. }
  1141. if (trackp->pregapsize != 150) {
  1142. printf(" pregapsize: %3ld", trackp->pregapsize);
  1143. }
  1144. printf("n");
  1145. }
  1146. LOCAL void
  1147. printaudio(track, trackp)
  1148. int track;
  1149. track_t *trackp;
  1150. {
  1151. if (trackp->tracksize >= 0) {
  1152. printf("Track %02d: audio %3ld MB (%02d:%02d.%02d) %spreemp%s%s",
  1153. track, trackp->tracksize >> 20,
  1154. minutes(trackp->tracksize),
  1155. seconds(trackp->tracksize),
  1156. hseconds(trackp->tracksize),
  1157. is_preemp(trackp) ? "" : "no ",
  1158. is_swab(trackp) ? " swab":"",
  1159. ((trackp->tracksize < 300L*trackp->secsize) ||
  1160. (trackp->tracksize % trackp->secsize)) &&
  1161. is_pad(trackp) ? " pad" : "");
  1162. } else {
  1163. printf("Track %02d: audio unknown length    %spreemp%s%s",
  1164. track, is_preemp(trackp) ? "" : "no ",
  1165. is_swab(trackp) ? " swab":"",
  1166. (trackp->tracksize % trackp->secsize) && is_pad(trackp) ? " pad" : "");
  1167. }
  1168. if (trackp->padsize > 0) {
  1169. if ((trackp->padsize >> 20) > 0)
  1170. printf(" padsize: %3ld MB", trackp->padsize >> 20);
  1171. else
  1172. printf(" padsize: %3ld KB", trackp->padsize >> 10);
  1173. printf(" (%02d:%02d.%02d)",
  1174. minutes(trackp->padsize),
  1175. seconds(trackp->padsize),
  1176. hseconds(trackp->padsize));
  1177. }
  1178. if (trackp->pregapsize != 150) {
  1179. printf(" pregapsize: %3ld", trackp->pregapsize);
  1180. }
  1181. printf("n");
  1182. }
  1183. LOCAL void
  1184. checkfile(track, trackp)
  1185. int track;
  1186. track_t *trackp;
  1187. {
  1188. if (trackp->tracksize > 0 &&
  1189. is_audio(trackp) &&
  1190. ((trackp->tracksize < 300L*trackp->secsize) ||
  1191. (trackp->tracksize % trackp->secsize)) &&
  1192. !is_pad(trackp)) {
  1193. errmsgno(EX_BAD, "Bad audio track size %ld for track %02d.n",
  1194. trackp->tracksize, track);
  1195. errmsgno(EX_BAD, "Audio tracks must be at least %ld bytes and a multiple of %d.n",
  1196. 300L*trackp->secsize, trackp->secsize);
  1197. comerrno(EX_BAD, "See -pad option.n");
  1198. }
  1199. if (!lverbose)
  1200. return;
  1201. if (is_audio(trackp))
  1202. printaudio(track, trackp);
  1203. else
  1204. printdata(track, trackp);
  1205. }
  1206. LOCAL int
  1207. checkfiles(tracks, trackp)
  1208. int tracks;
  1209. track_t *trackp;
  1210. {
  1211. int i;
  1212. int isaudio = 1;
  1213. for (i = 1; i <= tracks; i++) {
  1214. if (!is_audio(&trackp[i]))
  1215. isaudio = 0;
  1216. checkfile(i, &trackp[i]);
  1217. }
  1218. return (isaudio);
  1219. }
  1220. LOCAL void
  1221. setpregaps(tracks, trackp)
  1222. int tracks;
  1223. track_t *trackp;
  1224. {
  1225. int i;
  1226. int sectype;
  1227. track_t *tp;
  1228. /*
  1229.  * Set some values for track 0 (the lead-in)
  1230.  * XXX There should be a better place to do this.
  1231.  */
  1232. sectype = trackp[1].sectype;
  1233. trackp[0].sectype = sectype;
  1234. trackp[0].dbtype = trackp[1].dbtype;
  1235. for (i = 1; i <= tracks; i++) {
  1236. tp = &trackp[i];
  1237. if (tp->pregapsize == -1L) {
  1238. tp->pregapsize = 150; /* Default Pre GAP */
  1239. if (sectype != tp->sectype) {
  1240. tp->pregapsize = 255; /* Pre GAP is 255 */
  1241. tp->flags &= ~TI_PREGAP;
  1242. }
  1243. }
  1244. sectype = tp->sectype; /* Save old sectype */
  1245. }
  1246. /*
  1247.  * Set some values for track 0xAA (the lead-out)
  1248.  * XXX There should be a better place to do this.
  1249.  */
  1250. trackp[tracks+1].sectype = sectype;
  1251. trackp[tracks+1].dbtype = trackp[tracks].dbtype;
  1252. }
  1253. LOCAL long
  1254. checktsize(tracks, trackp)
  1255. int tracks;
  1256. track_t *trackp;
  1257. {
  1258. int i;
  1259. long curr;
  1260. long total = -150;
  1261. Ullong btotal;
  1262. track_t *tp;
  1263. for (i = 1; i <= tracks; i++) {
  1264. tp = &trackp[i];
  1265. if (!is_pregap(tp))
  1266. total += tp->pregapsize;
  1267. if (lverbose > 1) {
  1268. printf("track: %d start: %ld pregap: %ldn",
  1269. i, total, tp->pregapsize);
  1270. }
  1271. tp->trackstart = total;
  1272. if (tp->tracksize >= 0) {
  1273. curr = (tp->tracksize + (tp->secsize-1)) / tp->secsize;
  1274. curr += (tp->padsize + (tp->secsize-1)) / tp->secsize;
  1275. if (curr < 300) /* Minimum track size is 4s */
  1276. curr = 300;
  1277. if (is_tao(tp) && !is_audio(tp)) {
  1278. curr += 2;
  1279. }
  1280. total += curr;
  1281. }
  1282. }
  1283. tp = &trackp[i];
  1284. tp->trackstart = total;
  1285. if (!lverbose)
  1286. return (total);
  1287. btotal = (Ullong)total * 2352;
  1288. /* XXX Sector Size ??? */
  1289. if (tracks > 0) {
  1290. printf("Total size:     %3lu MB (%02d:%02d.%02d) = %ld sectorsn",
  1291. (Ulong)(btotal >> 20),
  1292. minutes(btotal),
  1293. seconds(btotal),
  1294. hseconds(btotal), total);
  1295. btotal += 150 * 2352;
  1296. printf("Lout start:     %3lu MB (%02d:%02d/%02d) = %ld sectorsn",
  1297. (Ulong)(btotal >> 20),
  1298. minutes(btotal),
  1299. seconds(btotal),
  1300. frames(btotal), total);
  1301. }
  1302. return (total);
  1303. }
  1304. LOCAL void
  1305. checksize(trackp)
  1306. track_t *trackp;
  1307. {
  1308. struct stat st;
  1309. /*
  1310.  * If the current input file is a regular file and
  1311.  * 'padsize=' has not been specified,
  1312.  * use fstat() or file parser to get the size of the file.
  1313.  */
  1314. if (trackp->tracksize < 0 && (trackp->flags & TI_ISOSIZE) != 0) {
  1315. trackp->tracksize = isosize(trackp->f);
  1316. }
  1317. if (trackp->tracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
  1318. trackp->tracksize = ausize(trackp->f);
  1319. }
  1320. if (trackp->tracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
  1321. trackp->tracksize = wavsize(trackp->f);
  1322. if (trackp->tracksize > 0) /* Force little endian input */
  1323. trackp->flags |= TI_SWAB;
  1324. }
  1325. if (trackp->tracksize == AU_BAD_CODING) {
  1326. comerrno(EX_BAD, "Inappropriate audio coding in '%s'.n",
  1327. trackp->filename);
  1328. }
  1329. if (trackp->tracksize < 0 &&
  1330. fstat(trackp->f, &st) >= 0 && S_ISREG(st.st_mode)) {
  1331. trackp->tracksize = st.st_size;
  1332. }
  1333. }
  1334. LOCAL BOOL
  1335. checkdsize(scgp, dp, dsp, tsize)
  1336. SCSI *scgp;
  1337. cdr_t *dp;
  1338. dstat_t *dsp;
  1339. long tsize;
  1340. {
  1341. long startsec = 0L;
  1342. long endsec = 0L;
  1343. scgp->silent++;
  1344. (*dp->cdr_next_wr_address)(scgp, /*i*/ 0, (track_t *)0, &startsec);
  1345. scgp->silent--;
  1346. /*
  1347.  * This only should happen when the drive is currently in DAO mode.
  1348.  * We rely on the drive being in TAO mode, a negative value for
  1349.  * startsec is not correct here it may be caused by bad firmware or
  1350.  * by a drive in DAO mode. In DAO mode the drive will report the
  1351.  * pre-gap as part of the writable area.
  1352.  */
  1353. if (startsec < 0)
  1354. startsec = 0;
  1355. endsec = startsec + tsize;
  1356. if (dsp->ds_maxblocks > 0) {
  1357. if (lverbose)
  1358. printf("Blocks total: %ld Blocks current: %ld Blocks remaining: %ldn",
  1359. dsp->ds_maxblocks,
  1360. dsp->ds_maxblocks - startsec,
  1361. dsp->ds_maxblocks - endsec);
  1362. if (endsec > dsp->ds_maxblocks) {
  1363. errmsgno(EX_BAD,
  1364. "WARNING: Data may not fit on current disk.n");
  1365. /* XXX Check for flags & CDR_NO_LOLIMIT */
  1366. /* return (FALSE);*/
  1367. }
  1368. if (lverbose && dsp->ds_maxrblocks > 0)
  1369. printf("RBlocks total: %ld RBlocks current: %ld RBlocks remaining: %ldn",
  1370. dsp->ds_maxrblocks,
  1371. dsp->ds_maxrblocks - startsec,
  1372. dsp->ds_maxrblocks - endsec);
  1373. if (dsp->ds_maxrblocks > 0 && endsec > dsp->ds_maxrblocks) {
  1374. errmsgno(EX_BAD,
  1375. "Data does not fit on current disk.n");
  1376. return (FALSE);
  1377. }
  1378. } else {
  1379. if (endsec >= (405000-301)) { /*<90 min disk*/
  1380. errmsgno(EX_BAD,
  1381. "Data will not fit on any disk.n");
  1382. return (FALSE);
  1383. } else if (endsec >= (333000-150)) { /* 74 min disk*/
  1384. errmsgno(EX_BAD,
  1385. "WARNING: Data may not fit on standard 74min disk.n");
  1386. }
  1387. }
  1388. return (TRUE);
  1389. }
  1390. LOCAL void
  1391. raise_fdlim()
  1392. {
  1393. #ifdef RLIMIT_NOFILE
  1394. struct rlimit rlim;
  1395. /*
  1396.  * Set max # of file descriptors to be able to hold all files open
  1397.  */
  1398. getrlimit(RLIMIT_NOFILE, &rlim);
  1399. rlim.rlim_cur = MAX_TRACK + 10;
  1400. if (rlim.rlim_cur > rlim.rlim_max)
  1401. errmsgno(EX_BAD,
  1402. "warning: low file descriptor limit (%ld)n",
  1403. rlim.rlim_max);
  1404. setrlimit(RLIMIT_NOFILE, &rlim);
  1405. #endif /* RLIMIT_NOFILE */
  1406. }
  1407. char *opts =
  1408. "help,version,checkdrive,prcap,inq,scanbus,reset,ignsize,useinfo,dev*,timeout#,driver*,tsize&,padsize&,pregap&,defpregap&,speed#,load,eject,dummy,msinfo,toc,atip,multi,fix,nofix,debug,v+,V+,audio,data,mode2,xa1,xa2,cdi,isosize,nopreemp,preemp,nopad,pad,swab,fs&,blank&,pktsize#,packet,noclose,force,dao,scms,isrc*,mcn*,index*";
  1409. LOCAL void
  1410. gargs(ac, av, tracksp, trackp, devp, timeoutp, dpp, speedp, flagsp, toctypep, blankp)
  1411. int ac;
  1412. char **av;
  1413. int *tracksp;
  1414. track_t *trackp;
  1415. cdr_t **dpp;
  1416. char **devp;
  1417. int *timeoutp;
  1418. int *speedp;
  1419. long *flagsp;
  1420. int *toctypep;
  1421. int *blankp;
  1422. {
  1423. int cac;
  1424. char * const*cav;
  1425. char *driver = NULL;
  1426. char *dev = NULL;
  1427. char *isrc = NULL;
  1428. char *mcn = NULL;
  1429. char *tindex = NULL;
  1430. long bltype = -1;
  1431. Llong tracksize;
  1432. Llong padsize;
  1433. long pregapsize;
  1434. long defpregap = -1L;
  1435. long secsize;
  1436. int pktsize;
  1437. int speed = -1;
  1438. int help = 0;
  1439. int version = 0;
  1440. int checkdrive = 0;
  1441. int prcap = 0;
  1442. int inq = 0;
  1443. int scanbus = 0;
  1444. int reset = 0;
  1445. int ignsize = 0;
  1446. int useinfo = 0;
  1447. int load = 0;
  1448. int eject = 0;
  1449. int dummy = 0;
  1450. int msinfo = 0;
  1451. int toc = 0;
  1452. int atip = 0;
  1453. int multi = 0;
  1454. int fix = 0;
  1455. int nofix = 0;
  1456. int audio;
  1457. int autoaudio = 0;
  1458. int data;
  1459. int mode2;
  1460. int xa1;
  1461. int xa2;
  1462. int cdi;
  1463. int isize;
  1464. int ispacket = 0;
  1465. int noclose = 0;
  1466. int force = 0;
  1467. int dao = 0;
  1468. int scms = 0;
  1469. int preemp = 0;
  1470. int nopreemp;
  1471. int pad = 0;
  1472. int bswab = 0;
  1473. int nopad;
  1474. int flags;
  1475. int tracks = *tracksp;
  1476. int tracktype = TOC_ROM;
  1477. int sectype = ST_ROM_MODE1;
  1478. int dbtype = DB_ROM_MODE1;
  1479. int got_track;
  1480. trackp[0].flags |= TI_TAO;
  1481. trackp[1].pregapsize = -1;
  1482. *flagsp |= F_WRITE;
  1483. cac = --ac;
  1484. cav = ++av;
  1485. for (;; cac--, cav++) {
  1486. tracksize = (Llong)-1L;
  1487. padsize = (Llong)0L;
  1488. pregapsize = defpregap;
  1489. audio = data = mode2 = xa1 = xa2 = cdi = 0;
  1490. isize = nopreemp = nopad = 0;
  1491. pktsize = 0;
  1492. isrc = NULL;
  1493. tindex = NULL;
  1494. if (getargs(&cac, &cav, opts,
  1495. &help, &version, &checkdrive, &prcap,
  1496. &inq, &scanbus, &reset, &ignsize,
  1497. &useinfo,
  1498. devp, timeoutp, &driver,
  1499. getllnum, &tracksize,
  1500. getllnum, &padsize,
  1501. getnum, &pregapsize,
  1502. getnum, &defpregap,
  1503. &speed,
  1504. &load, &eject, &dummy, &msinfo, &toc, &atip,
  1505. &multi, &fix, &nofix,
  1506. &debug, &lverbose, &scsi_verbose,
  1507. &audio, &data, &mode2,
  1508. &xa1, &xa2, &cdi,
  1509. &isize,
  1510. &nopreemp, &preemp,
  1511. &nopad, &pad, &bswab, getnum, &fs,
  1512. getbltype, &bltype, &pktsize,
  1513. &ispacket, &noclose, &force,
  1514. &dao, &scms,
  1515. &isrc, &mcn, &tindex) < 0) {
  1516. errmsgno(EX_BAD, "Bad Option: %s.n", cav[0]);
  1517. usage(EX_BAD);
  1518. }
  1519. if (help)
  1520. usage(0);
  1521. if (tracks == 0) {
  1522. if (driver)
  1523. set_cdrcmds(driver, dpp);
  1524. if (version)
  1525. *flagsp |= F_VERSION;
  1526. if (checkdrive)
  1527. *flagsp |= F_CHECKDRIVE;
  1528. if (prcap)
  1529. *flagsp |= F_PRCAP;
  1530. if (inq)
  1531. *flagsp |= F_INQUIRY;
  1532. if (scanbus)
  1533. *flagsp |= F_SCANBUS;
  1534. if (reset)
  1535. *flagsp |= F_RESET;
  1536. if (ignsize)
  1537. *flagsp |= F_IGNSIZE;
  1538. if (load)
  1539. *flagsp |= F_LOAD;
  1540. if (eject)
  1541. *flagsp |= F_EJECT;
  1542. if (dummy)
  1543. *flagsp |= F_DUMMY;
  1544. if (msinfo)
  1545. *flagsp |= F_MSINFO;
  1546. if (toc) {
  1547. *flagsp |= F_TOC;
  1548. *flagsp &= ~F_WRITE;
  1549. }
  1550. if (atip) {
  1551. *flagsp |= F_PRATIP;
  1552. *flagsp &= ~F_WRITE;
  1553. }
  1554. if (multi) {
  1555. *flagsp |= F_MULTI;
  1556. tracktype = TOC_XA2;
  1557. sectype = ST_ROM_MODE2;
  1558. dbtype = DB_XA_MODE2; /* XXX -multi nimmt DB_XA_MODE2_F1 !!! */
  1559. }
  1560. if (fix)
  1561. *flagsp |= F_FIX;
  1562. if (nofix)
  1563. *flagsp |= F_NOFIX;
  1564. if (force) 
  1565. *flagsp |= F_FORCE;
  1566. if (bltype >= 0) {
  1567. *flagsp |= F_BLANK;
  1568. *blankp = bltype;
  1569. }
  1570. if (dao) {
  1571. *flagsp |= F_SAO;
  1572. trackp[0].flags &= ~TI_TAO;
  1573. }
  1574. if (mcn) {
  1575. #ifdef AUINFO
  1576. setmcn(mcn, &trackp[0]);
  1577. #else
  1578. trackp[0].isrc = malloc(16);
  1579. fillbytes(trackp[0].isrc, 16, '');
  1580. strncpy(trackp[0].isrc, mcn, 13);
  1581. #endif
  1582. mcn = NULL;
  1583. }
  1584. version = checkdrive = prcap = inq = scanbus = reset = ignsize =
  1585. load = eject = dummy = msinfo = toc = atip = multi = fix = nofix = force = dao = 0;
  1586. } else if ((version + checkdrive + prcap + inq + scanbus + reset + ignsize +
  1587.     load + eject + dummy + msinfo + toc + atip + multi + fix + nofix + force + dao) > 0 ||
  1588. mcn != NULL)
  1589. comerrno(EX_BAD, "Badly placed option. Global options must be before any track.n");
  1590. if (nopreemp)
  1591. preemp = 0;
  1592. if (nopad)
  1593. pad = 0;
  1594. if ((audio + data + mode2 + xa1 + xa2 + cdi) > 1) {
  1595. errmsgno(EX_BAD, "Too many types for track %d.n", tracks+1);
  1596. comerrno(EX_BAD, "Only one of -audio, -data, -mode2, -xa1, -xa2, -cdi allowed.n");
  1597. }
  1598. if (ispacket && audio) {
  1599. comerrno(EX_BAD, "Audio data cannot be written in packet mode.n");
  1600. }
  1601. got_track = getfiles(&cac, &cav, opts);
  1602. if (autoaudio) {
  1603. autoaudio = 0;
  1604. tracktype = TOC_ROM;
  1605. sectype = ST_ROM_MODE1;
  1606. dbtype = DB_ROM_MODE1;
  1607. }
  1608. if (got_track != 0 && (is_auname(cav[0]) || is_wavname(cav[0]))) {
  1609. autoaudio++;
  1610. audio++;
  1611. }
  1612. if (data) {
  1613. tracktype = TOC_ROM;
  1614. sectype = ST_ROM_MODE1;
  1615. dbtype = DB_ROM_MODE1;
  1616. }
  1617. if (mode2) {
  1618. tracktype = TOC_ROM;
  1619. sectype = ST_ROM_MODE2;
  1620. dbtype = DB_ROM_MODE2;
  1621. }
  1622. if (audio) {
  1623. tracktype = TOC_DA;
  1624. sectype = preemp ? ST_AUDIO_PRE : ST_AUDIO_NOPRE;
  1625. dbtype = DB_RAW;
  1626. }
  1627. if (xa1) {
  1628. tracktype = TOC_XA1;
  1629. sectype = ST_ROM_MODE1;
  1630. dbtype = DB_XA_MODE1;
  1631. }
  1632. if (xa2) {
  1633. tracktype = TOC_XA2;
  1634. sectype = ST_ROM_MODE2;
  1635. dbtype = DB_XA_MODE2_F1; /* XXX Das unterscheidet sich von -multi !!! */
  1636. }
  1637. if (cdi) {
  1638. tracktype = TOC_CDI;
  1639. sectype = ST_ROM_MODE2;
  1640. dbtype = DB_XA_MODE2_F1;
  1641. }
  1642. if (tracks == 0)
  1643. *toctypep = tracktype;
  1644. flags = 0;
  1645. if ((sectype & ST_AUDIOMASK) != 0)
  1646. flags |= TI_AUDIO;
  1647. if (isize) {
  1648. flags |= TI_ISOSIZE;
  1649. if ((*flagsp & F_MULTI) != 0)
  1650. comerrno(EX_BAD, "Cannot get isosize for multi session disks.n");
  1651. }
  1652. if (preemp)
  1653. flags |= TI_PREEMP;
  1654. if (scms)
  1655. flags |= TI_SCMS;
  1656. if ((flags & TI_AUDIO) == 0 && padsize > (Llong)0L)
  1657. pad = TRUE;
  1658. if (pad) {
  1659. flags |= TI_PAD;
  1660. if ((flags & TI_AUDIO) == 0 && padsize == (Llong)0L)
  1661. padsize = (Llong)PAD_SIZE;
  1662. }
  1663. if (bswab)
  1664. flags |= TI_SWAB;
  1665. if (ispacket) 
  1666. flags |= TI_PACKET;
  1667. if (noclose) 
  1668. flags |= TI_NOCLOSE;
  1669. if ((*flagsp & F_SAO) == 0)
  1670. flags |= TI_TAO;
  1671. if (got_track == 0)
  1672. break;
  1673. tracks++;
  1674. if (tracks > MAX_TRACK)
  1675. comerrno(EX_BAD, "Track limit (%d) exceededn",
  1676. MAX_TRACK);
  1677. if (strcmp("-", cav[0]) == 0) {
  1678. trackp[tracks].f = STDIN_FILENO;
  1679. #if defined(__CYGWIN32__) || defined(__EMX__)
  1680. setmode(STDIN_FILENO, O_BINARY);
  1681. #endif
  1682. } else {
  1683. if (access(cav[0], R_OK) < 0)
  1684. comerr("No read access for '%s'.n", cav[0]);
  1685. if ((trackp[tracks].f = open(cav[0], O_RDONLY|O_BINARY)) < 0)
  1686. comerr("Cannot open '%s'.n", cav[0]);
  1687. }
  1688. if (!is_auname(cav[0]) && !is_wavname(cav[0]))
  1689. flags |= TI_NOAUHDR;
  1690. if ((*flagsp & F_SAO) != 0 && (flags & TI_AUDIO) != 0)
  1691. flags |= TI_PREGAP; /* Hack for now */
  1692. if (tracks == 1)
  1693. flags &= ~TI_PREGAP;
  1694. if (tracks == 1 && (pregapsize != -1L && pregapsize != 150))
  1695. pregapsize = -1L;
  1696. secsize = tracktype == TOC_DA ? AUDIO_SEC_SIZE : DATA_SEC_SIZE;
  1697. trackp[tracks].filename = cav[0];;
  1698. trackp[tracks].trackstart = 0L;
  1699. trackp[tracks].tracksize = tracksize;
  1700. if (trackp[tracks].pregapsize < 0)
  1701. trackp[tracks].pregapsize = pregapsize;
  1702. trackp[tracks+1].pregapsize = -1;
  1703. trackp[tracks].padsize = padsize;
  1704. trackp[tracks].secsize = secsize;
  1705. trackp[tracks].secspt = 0; /* transfer size is set up in set_trsizes() */
  1706. trackp[tracks].pktsize = pktsize;
  1707. trackp[tracks].trackno = tracks;
  1708. trackp[tracks].sectype = sectype;
  1709. trackp[tracks].tracktype = tracktype;
  1710. trackp[tracks].dbtype = dbtype;
  1711. trackp[tracks].flags = flags;
  1712. trackp[tracks].nindex = 1;
  1713. trackp[tracks].tindex = 0;
  1714. checksize(&trackp[tracks]);
  1715. tracksize = trackp[tracks].tracksize;
  1716. if (tracksize > 0 && (tracksize / secsize) < 300) {
  1717. tracksize = roundup(tracksize, secsize);
  1718. padsize = tracksize + roundup(padsize, secsize);
  1719. if ((padsize / secsize) < 300) {
  1720. trackp[tracks].padsize =
  1721. 300 * secsize - tracksize;
  1722. }
  1723. }
  1724. #ifdef AUINFO
  1725. if (useinfo) {
  1726. auinfo(cav[0], tracks, trackp);
  1727. if (tracks == 1)
  1728. printf("pregap1: %ldn", trackp[1].pregapsize);
  1729. }
  1730. #endif
  1731. if (isrc) {
  1732. #ifdef AUINFO
  1733. setisrc(isrc, &trackp[tracks]);
  1734. #else
  1735. trackp[tracks].isrc = malloc(16);
  1736. fillbytes(trackp[tracks].isrc, 16, '');
  1737. strncpy(trackp[tracks].isrc, isrc, 12);
  1738. #endif
  1739. }
  1740. if (tindex) {
  1741. #ifdef AUINFO
  1742. setindex(tindex, &trackp[tracks]);
  1743. #endif
  1744. }
  1745. if (debug) {
  1746. printf("File: '%s' tracksize: %ld secsize: %d tracktype: %d = %s sectype: %X = %s dbtype: %s flags %Xn",
  1747. cav[0], trackp[tracks].tracksize, 
  1748. trackp[tracks].secsize, 
  1749. tracktype, toc2name[tracktype & TOC_MASK],
  1750. sectype, st2name[sectype & ST_MASK], db2name[dbtype], flags);
  1751. }
  1752. }
  1753. if (speed < 0 && speed != -1)
  1754. comerrno(EX_BAD, "Bad speed option.n");
  1755. if (fs < 0L && fs != -1L)
  1756. comerrno(EX_BAD, "Bad fifo size option.n");
  1757. dev = *devp;
  1758. cdr_defaults(&dev, &speed, &fs);
  1759. if (debug)
  1760. printf("dev: %s speed: %d fs: %ldn", dev, speed, fs);
  1761. if (speed >= 0)
  1762. *speedp = speed;
  1763. if (fs < 0L)
  1764. fs = DEFAULT_FIFOSIZE;
  1765. if (dev != *devp && (*flagsp & F_SCANBUS) == 0)
  1766. *devp = dev;
  1767. if (!*devp && (*flagsp & (F_VERSION|F_SCANBUS)) == 0) {
  1768. errmsgno(EX_BAD, "No CD/DVD-Recorder device specified.n");
  1769. usage(EX_BAD);
  1770. }
  1771. if (*flagsp & (F_LOAD|F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_PRCAP|F_INQUIRY|F_SCANBUS|F_RESET)) {
  1772. if (tracks != 0) {
  1773. errmsgno(EX_BAD, "No tracks allowed with this optionn");
  1774. usage(EX_BAD);
  1775. }
  1776. return;
  1777. }
  1778. if (tracks == 0 && (*flagsp & (F_LOAD|F_EJECT|F_BLANK)) == 0) {
  1779. errmsgno(EX_BAD, "No tracks specified. Need at least one.n");
  1780. usage(EX_BAD);
  1781. }
  1782. *tracksp = tracks;
  1783. if (*flagsp & F_SAO) {
  1784. /*
  1785.  * Make sure that you change WRITER_MAXWAIT & READER_MAXWAIT
  1786.  * too if you change this timeout.
  1787.  */
  1788. if (*timeoutp < 200) /* Lead in size is 2:30 */
  1789. *timeoutp = 200; /* 200s is 150s *1.33 */
  1790. }
  1791. }
  1792. LOCAL void
  1793. set_trsizes(dp, tracks, trackp)
  1794. cdr_t *dp;
  1795. int tracks;
  1796. track_t *trackp;
  1797. {
  1798. int i;
  1799. /*
  1800.  * We are using SCSI Group 0 write
  1801.  * and cannot write more than 255 secs at once.
  1802.  */
  1803. data_secs_per_tr = bufsize/DATA_SEC_SIZE;
  1804. audio_secs_per_tr = bufsize/AUDIO_SEC_SIZE;
  1805. data_secs_per_tr = min(255, data_secs_per_tr);
  1806. audio_secs_per_tr = min(255, audio_secs_per_tr);
  1807. trackp[1].flags |= TI_FIRST;
  1808. trackp[tracks].flags |= TI_LAST;
  1809. for (i = 1; i <= tracks; i++) {
  1810. trackp[i].secspt =
  1811. is_audio(&trackp[i]) ?
  1812. audio_secs_per_tr :
  1813. data_secs_per_tr;
  1814. if (is_packet(&trackp[i]) && trackp[i].pktsize > 0) {
  1815. if (trackp[i].secspt >= trackp[i].pktsize) {
  1816. trackp[i].secspt = trackp[i].pktsize;
  1817. } else {
  1818. comerrno(EX_BAD,
  1819. "Track %d packet size %d exceeds buffer limit of %d sectors",
  1820. i, trackp[i].pktsize, trackp[i].secspt);
  1821. }
  1822. }
  1823. if ((dp->cdr_flags & CDR_SWABAUDIO) != 0 &&
  1824. is_audio(&trackp[i])) {
  1825. trackp[i].flags ^= TI_SWAB;
  1826. }
  1827. }
  1828. }
  1829. EXPORT void
  1830. load_media(scgp, dp, doexit)
  1831. SCSI *scgp;
  1832. cdr_t *dp;
  1833. BOOL doexit;
  1834. {
  1835. int code;
  1836. int key;
  1837. /*
  1838.  * Do some preparation before...
  1839.  */
  1840. scgp->silent++; /* Be quiet if this fails */
  1841. test_unit_ready(scgp); /* First eat up unit attention */
  1842. (*dp->cdr_load)(scgp); /* now try to load media and */
  1843. scsi_start_stop_unit(scgp, 1, 0);/* start unit in silent mode */
  1844. scgp->silent--;
  1845. if (!wait_unit_ready(scgp, 60)) {
  1846. code = scsi_sense_code(scgp);
  1847. key = scsi_sense_key(scgp);
  1848. scgp->silent++;
  1849. scsi_prevent_removal(scgp, 0);/* In case someone locked it */
  1850. scgp->silent--;
  1851. if (!doexit)
  1852. return;
  1853. if (key == SC_NOT_READY && (code == 0x3A || code == 0x30))
  1854. comerrno(EX_BAD, "No disk / Wrong disk!n");
  1855. comerrno(EX_BAD, "CD/DVD-Recorder not ready.n");
  1856. }
  1857. scsi_prevent_removal(scgp, 1);
  1858. scsi_start_stop_unit(scgp, 1, 0);
  1859. wait_unit_ready(scgp, 120);
  1860. scgp->silent++;
  1861. rezero_unit(scgp); /* Is this needed? Not supported by some drvives */
  1862. scgp->silent--;
  1863. test_unit_ready(scgp);
  1864. scsi_start_stop_unit(scgp, 1, 0);
  1865. wait_unit_ready(scgp, 120);
  1866. }
  1867. EXPORT void
  1868. unload_media(scgp, dp, flags)
  1869. SCSI *scgp;
  1870. cdr_t *dp;
  1871. int flags;
  1872. {
  1873. scsi_prevent_removal(scgp, 0);
  1874. if ((flags & F_EJECT) != 0)
  1875. (*dp->cdr_unload)(scgp);
  1876. }
  1877. EXPORT void
  1878. set_secsize(scgp, secsize)
  1879. SCSI *scgp;
  1880. int secsize;
  1881. {
  1882. if (secsize > 0) {
  1883. /*
  1884.  * Try to restore the old sector size.
  1885.  */
  1886. scgp->silent++;
  1887. select_secsize(scgp, secsize);
  1888. scgp->silent--;
  1889. }
  1890. }
  1891. LOCAL void
  1892. check_recovery(scgp, dp, flags)
  1893. SCSI *scgp;
  1894. cdr_t *dp;
  1895. int flags;
  1896. {
  1897. if ((*dp->cdr_check_recovery)(scgp)) {
  1898. errmsgno(EX_BAD, "Recovery needed.n");
  1899. unload_media(scgp, dp, flags);
  1900. excdr(EX_BAD, NULL); /* XXX &exargs ??? */
  1901. exit(EX_BAD);
  1902. }
  1903. }
  1904. #define DEBUG
  1905. void audioread(scgp, dp, flags)
  1906. SCSI *scgp;
  1907. cdr_t *dp;
  1908. int flags;
  1909. {
  1910. #ifdef DEBUG
  1911. int speed = 1;
  1912. int dummy = 0;
  1913. if ((*dp->cdr_set_speed_dummy)(scgp, &speed, dummy) < 0)
  1914. exit(-1);
  1915. if ((*dp->cdr_set_secsize)(scgp, 2352) < 0)
  1916. exit(-1);
  1917. scgp->cap->c_bsize = 2352;
  1918. read_scsi(scgp, buf, 1000, 1);
  1919. printf("XXX:n");
  1920. write(1, buf, 512);
  1921. unload_media(scgp, dp, flags);
  1922. excdr(0, NULL); /* XXX &exargs ??? */
  1923. exit(0);
  1924. #endif
  1925. }
  1926. LOCAL void
  1927. print_msinfo(scgp, dp)
  1928. SCSI *scgp;
  1929. cdr_t *dp;
  1930. {
  1931. long off;
  1932. long fa;
  1933. if ((*dp->cdr_session_offset)(scgp, &off) < 0) {
  1934. errmsgno(EX_BAD, "Cannot read session offsetn");
  1935. return;
  1936. }
  1937. if (lverbose)
  1938. printf("session offset: %ldn", off);
  1939. if (dp->cdr_next_wr_address(scgp, 0, (track_t *)0, &fa) < 0) {
  1940. errmsgno(EX_BAD, "Cannot read first writable addressn");
  1941. return;
  1942. }
  1943. printf("%ld,%ldn", off, fa);
  1944. }
  1945. LOCAL void
  1946. print_toc(scgp, dp)
  1947. SCSI *scgp;
  1948. cdr_t *dp;
  1949. {
  1950. int first;
  1951. int last;
  1952. long lba;
  1953. long xlba;
  1954. struct msf msf;
  1955. int adr;
  1956. int control;
  1957. int mode;
  1958. int i;
  1959. scgp->silent++;
  1960. if (read_capacity(scgp) < 0) {
  1961. scgp->silent--;
  1962. errmsgno(EX_BAD, "Cannot read capacityn");
  1963. return;
  1964. }
  1965. scgp->silent--;
  1966. if (read_tochdr(scgp, dp, &first, &last) < 0) {
  1967. errmsgno(EX_BAD, "Cannot read TOC/PMAn");
  1968. return;
  1969. }
  1970. printf("first: %d last %dn", first, last);
  1971. for (i = first; i <= last; i++) {
  1972. read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
  1973. xlba = -150 +
  1974. msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
  1975. if (xlba == lba/4)
  1976. lba = xlba;
  1977. print_track(i, lba, &msf, adr, control, mode);
  1978. }
  1979. i = 0xAA;
  1980. read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
  1981. xlba = -150 +
  1982. msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
  1983. if (xlba == lba/4)
  1984. lba = xlba;
  1985. print_track(i, lba, &msf, adr, control, mode);
  1986. if (lverbose > 1) {
  1987. scgp->silent++;
  1988. if (read_cdtext(scgp) < 0)
  1989. errmsgno(EX_BAD, "No CD-Text or CD-Text unaware drive.n");
  1990. scgp->silent++;
  1991. }
  1992. }
  1993. LOCAL void
  1994. print_track(track, lba, msp, adr, control, mode)
  1995. int track;
  1996. long lba;
  1997. struct msf *msp;
  1998. int adr;
  1999. int control;
  2000. int mode;
  2001. {
  2002. long lba_512 = lba*4;
  2003. if (track == 0xAA)
  2004. printf("track:lout ");
  2005. else
  2006. printf("track: %3d ", track);
  2007. printf("lba: %9ld (%9ld) %02d:%02d:%02d adr: %X control: %X mode: %dn",
  2008. lba, lba_512,
  2009. msp->msf_min,
  2010. msp->msf_sec,
  2011. msp->msf_frame,
  2012. adr, control, mode);
  2013. }
  2014. LOCAL void
  2015. prtimediff(fmt, start, stop)
  2016. const char *fmt;
  2017. struct timeval *start;
  2018. struct timeval *stop;
  2019. {
  2020. struct timeval tv;
  2021. tv.tv_sec = stop->tv_sec - start->tv_sec;
  2022. tv.tv_usec = stop->tv_usec - start->tv_usec;
  2023. while (tv.tv_usec > 1000000) {
  2024. tv.tv_usec -= 1000000;
  2025. tv.tv_sec += 1;
  2026. }
  2027. while (tv.tv_usec < 0) {
  2028. tv.tv_usec += 1000000;
  2029. tv.tv_sec -= 1;
  2030. }
  2031. /*
  2032.  * We need to cast timeval->* to long because
  2033.  * of the broken sys/time.h in Linux.
  2034.  */
  2035. printf("%s%4ld.%03ldsn", fmt, (long)tv.tv_sec, (long)tv.tv_usec/1000);
  2036. flush();
  2037. }
  2038. #ifdef HAVE_SYS_PRIOCNTL_H
  2039. #include <sys/procset.h> /* Needed for SCO Openserver */
  2040. #include <sys/priocntl.h>
  2041. #include <sys/rtpriocntl.h>
  2042. EXPORT void
  2043. raisepri(pri)
  2044. int pri;
  2045. {
  2046. int pid;
  2047. int classes;
  2048. int ret;
  2049. pcinfo_t info;
  2050. pcparms_t param;
  2051. rtinfo_t rtinfo;
  2052. rtparms_t rtparam;
  2053. pid = getpid();
  2054. /* get info */
  2055. strcpy(info.pc_clname, "RT");
  2056. classes = priocntl(P_PID, pid, PC_GETCID, (void *)&info);
  2057. if (classes == -1)
  2058. comerr("Cannot get priority class id priocntl(PC_GETCID)n");
  2059. movebytes(info.pc_clinfo, &rtinfo, sizeof(rtinfo_t));
  2060.  
  2061. /* set priority to max */
  2062. rtparam.rt_pri = rtinfo.rt_maxpri - pri;
  2063. rtparam.rt_tqsecs = 0;
  2064. rtparam.rt_tqnsecs = RT_TQDEF;
  2065. param.pc_cid = info.pc_cid;
  2066. movebytes(&rtparam, param.pc_clparms, sizeof(rtparms_t));
  2067. ret = priocntl(P_PID, pid, PC_SETPARMS, (void *)&param);
  2068. if (ret == -1) {
  2069. errmsg("WARNING: Cannot set priority class parameters priocntl(PC_SETPARMS)n");
  2070. errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.n");
  2071. }
  2072. }
  2073. #else /* HAVE_SYS_PRIOCNTL_H */
  2074. #if defined(_POSIX_PRIORITY_SCHEDULING)
  2075. /*
  2076.  * XXX Ugly but needed because of a typo in /usr/iclude/sched.h on Linux.
  2077.  * XXX This should be removed as soon as we are sure that Linux-2.0.29 is gone.
  2078.  */
  2079. #ifdef __linux
  2080. #define _P __P
  2081. #endif
  2082. #include <sched.h>
  2083. #ifdef __linux
  2084. #undef _P
  2085. #endif
  2086. LOCAL int
  2087. rt_raisepri(pri)
  2088. int pri;
  2089. {
  2090. struct sched_param scp;
  2091. /*
  2092.  * Verify that scheduling is available
  2093.  */
  2094. #ifdef _SC_PRIORITY_SCHEDULING
  2095. if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) {
  2096. errmsg("WARNING: RR-scheduler not available, disabling.n");
  2097. return(-1);
  2098. }
  2099. #endif
  2100. fillbytes(&scp, sizeof(scp), '');
  2101. scp.sched_priority = sched_get_priority_max(SCHED_RR) - pri;
  2102. if (sched_setscheduler(0, SCHED_RR, &scp) < 0) {
  2103. errmsg("WARNING: Cannot set RR-schedulern");
  2104. return (-1);
  2105. }
  2106. return (0);
  2107. }
  2108. #else /* _POSIX_PRIORITY_SCHEDULING */
  2109. #ifdef __CYGWIN32__
  2110. /*
  2111.  * NOTE: Base.h has a second typedef for BOOL.
  2112.  *  We define BOOL to make all local code use BOOL
  2113.  *  from Windows.h and use the hidden __SBOOL for
  2114.  *  our global interfaces.
  2115.  */
  2116. #define BOOL WBOOL /* This is the Win BOOL */
  2117. #define format __format
  2118. #include <vadefs.h>
  2119. #include <Windows32/Base.h>
  2120. #include <Windows32/Defines.h>
  2121. #include <Windows32/Structures.h>
  2122. #include <Windows32/Functions.h>
  2123. #undef format
  2124. LOCAL int
  2125. rt_raisepri(pri)
  2126. int pri;
  2127. {
  2128. /* set priority class */
  2129. if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) {
  2130. errmsgno(EX_BAD, "No realtime priority class possible.n");
  2131. return (-1);
  2132. }
  2133. /* set thread priority */
  2134. if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL-pri) == FALSE) {
  2135. errmsgno(EX_BAD, "Could not set realtime priority.n");
  2136. return (-1);
  2137. }
  2138. return (0);
  2139. }
  2140. #else
  2141. LOCAL int
  2142. rt_raisepri(pri)
  2143. int pri;
  2144. {
  2145. return (-1);
  2146. }
  2147. #endif /* __CYGWIN32__ */
  2148. #endif /* _POSIX_PRIORITY_SCHEDULING */
  2149. EXPORT void
  2150. raisepri(pri)
  2151. int pri;
  2152. {
  2153. if (rt_raisepri(pri) >= 0)
  2154. return;
  2155. #if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
  2156. if (setpriority(PRIO_PROCESS, getpid(), -20 + pri) < 0) {
  2157. errmsg("WARNING: Cannot set priority using setpriority().n");
  2158. errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.n");
  2159. }
  2160. #else
  2161. #ifdef HAVE_DOSSETPRIORITY /* RT priority on OS/2 */
  2162. /*
  2163.  * Set priority to timecritical 31 - pri (arg)
  2164.  */
  2165. DosSetPriority(0, 3, 31, 0);
  2166. DosSetPriority(0, 3, -pri, 0);
  2167. #else
  2168. #ifdef HAVE_NICE
  2169. if (nice(-20 + pri) == -1) {
  2170. errmsg("WARNING: Cannot set priority using nice().n");
  2171. errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.n");
  2172. }
  2173. #else
  2174. errmsgno(EX_BAD, "WARNING: Cannot set priority on this OS.n");
  2175. errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.n");
  2176. #endif
  2177. #endif
  2178. #endif
  2179. }
  2180. #endif /* HAVE_SYS_PRIOCNTL_H */
  2181. LOCAL void
  2182. checkgui()
  2183. {
  2184. struct stat st;
  2185. if (fstat(STDERR_FILENO, &st) >= 0 && !S_ISCHR(st.st_mode)) {
  2186. isgui = TRUE;
  2187. if (lverbose > 1)
  2188. printf("Using remote (pipe) mode for interactive i/o.n");
  2189. }
  2190. }
  2191. LOCAL char *
  2192. astoll(s, ll)
  2193. register const char *s;
  2194.         Llong *ll;
  2195. {
  2196. char *p;
  2197. long l = 0;
  2198. p = astol(s, &l);
  2199. *ll = (Llong)l;
  2200. return (p);
  2201. }
  2202. LOCAL Llong
  2203. number(arg, retp)
  2204. register char *arg;
  2205. int *retp;
  2206. {
  2207. Llong val = 0;
  2208. if (*retp != 1)
  2209. return (val);
  2210. if (*arg == '') {
  2211. *retp = -1;
  2212. } else if (*(arg = astoll(arg, &val))) {
  2213. if (*arg == 'p' || *arg == 'P') {
  2214. val *= (1024*1024);
  2215. val *= (1024*1024*1024);
  2216. arg++;
  2217. }
  2218. if (*arg == 't' || *arg == 'T') {
  2219. val *= (1024*1024);
  2220. val *= (1024*1024);
  2221. arg++;
  2222. }
  2223. if (*arg == 'g' || *arg == 'G') {
  2224. val *= (1024*1024*1024);
  2225. arg++;
  2226. }
  2227. if (*arg == 'm' || *arg == 'M') {
  2228. val *= (1024*1024);
  2229. arg++;
  2230. }
  2231. else if (*arg == 'f' || *arg == 'F') {
  2232. val *= 2352;
  2233. arg++;
  2234. }
  2235. else if (*arg == 's' || *arg == 'S') {
  2236. val *= 2048;
  2237. arg++;
  2238. }
  2239. else if (*arg == 'k' || *arg == 'K') {
  2240. val *= 1024;
  2241. arg++;
  2242. }
  2243. else if (*arg == 'b' || *arg == 'B') {
  2244. val *= 512;
  2245. arg++;
  2246. }
  2247. else if (*arg == 'w' || *arg == 'W') {
  2248. val *= 2;
  2249. arg++;
  2250. }
  2251. if (*arg == '*' || *arg == 'x')
  2252. val *= number(++arg, retp);
  2253. else if (*arg != '')
  2254. *retp = -1;
  2255. }
  2256. return (val);
  2257. }
  2258. EXPORT int
  2259. getnum(arg, valp)
  2260. char *arg;
  2261. long *valp;
  2262. {
  2263. int ret = 1;
  2264. *valp = (long)number(arg, &ret);
  2265. return (ret);
  2266. }
  2267. EXPORT int
  2268. getllnum(arg, lvalp)
  2269. char *arg;
  2270. Llong *lvalp;
  2271. {
  2272. int ret = 1;
  2273. *lvalp = number(arg, &ret);
  2274. return (ret);
  2275. }
  2276. LOCAL int
  2277. getbltype(optstr, typep)
  2278. char *optstr;
  2279. long *typep;
  2280. {
  2281. if (streql(optstr, "all")) {
  2282. *typep = BLANK_DISC;
  2283. } else if (streql(optstr, "disc")) {
  2284. *typep = BLANK_DISC;
  2285. } else if (streql(optstr, "disk")) {
  2286. *typep = BLANK_DISC;
  2287. } else if (streql(optstr, "fast")) {
  2288. *typep = BLANK_MINIMAL;
  2289. } else if (streql(optstr, "minimal")) {
  2290. *typep = BLANK_MINIMAL;
  2291. } else if (streql(optstr, "track")) {
  2292. *typep = BLANK_TRACK;
  2293. } else if (streql(optstr, "unreserve")) {
  2294. *typep = BLANK_UNRESERVE;
  2295. } else if (streql(optstr, "trtail")) {
  2296. *typep = BLANK_TAIL;
  2297. } else if (streql(optstr, "unclose")) {
  2298. *typep = BLANK_UNCLOSE;
  2299. } else if (streql(optstr, "session")) {
  2300. *typep = BLANK_SESSION;
  2301. } else if (streql(optstr, "help")) {
  2302. blusage(0);
  2303. } else {
  2304. error("Illegal blanking type '%s'.n", optstr);
  2305. blusage(EX_BAD);
  2306. return (-1);
  2307. }
  2308. return (TRUE);
  2309. }