1
/* @(#)cdrecord.c 1.119 01/04/19 Copyright 1995-2001 J. Schilling */
4
"@(#)cdrecord.c 1.119 01/04/19 Copyright 1995-2001 J. Schilling";
7
* Record data on a CD/CVD-Recorder
9
* Copyright (c) 1995-2001 J. Schilling
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)
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.
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.
33
#include <sys/types.h>
35
#ifdef HAVE_SYS_RESOURCE_H
36
#include <sys/resource.h> /* for rlimit */
41
#ifdef HAVE_SYS_MMAN_H
50
#include <scg/scsireg.h> /* XXX wegen SC_NOT_READY */
51
#include <scg/scsitransp.h>
52
#include <scg/scgcmd.h> /* XXX fuer read_buffer */
53
#include "scsi_scan.h"
58
char cdr_version[] = "1.10";
61
* Map toc/track types into names.
75
* Map sector types into names.
78
"Illegal sector type 0",
81
"Illegal sector type 3",
82
"CD-DA without preemphasis",
83
"CD-DA with preemphasis",
84
"Illegal sector type 6",
85
"Illegal sector type 7",
89
* Map data block types into names.
93
"Raw (audio) with P/Q sub channel",
94
"Raw (audio) with P/W sub channel",
95
"Raw (audio) with P/W raw sub channel",
99
"Vendor unique mode 7",
103
"CD-ROM XA mode 2 form 1",
104
"CD-ROM XA mode 2 form 2",
105
"CD-ROM XA mode 2 form 1/2/mix",
107
"Vendor unique mode 15",
110
int debug; /* print debug messages */
111
LOCAL int kdebug; /* print kernel debug messages */
112
LOCAL int scsi_verbose; /* SCSI verbose flag */
113
LOCAL int silent; /* SCSI silent flag */
114
int lverbose; /* local verbose flag */
117
* NOTICE: You should not make BUF_SIZE more than
118
* the buffer size of the CD-Recorder.
120
* Do not set BUF_SIZE to be more than 126 KBytes
121
* if you are running cdrecord on a sun4c machine.
123
* WARNING: Philips CDD 521 dies if BUF_SIZE is to big.
125
/*#define BUF_SIZE (126*1024)*/
126
/*#define BUF_SIZE (100*1024)*/
127
#define BUF_SIZE (63*1024)
128
/*#define BUF_SIZE (56*1024)*/
130
char *buf; /* The transfer buffer */
131
long bufsize; /* The size of the transfer buffer */
132
int data_secs_per_tr; /* # of data secs per transfer */
133
int audio_secs_per_tr; /* # of audio secs per transfer */
139
struct timeval starttime;
140
struct timeval stoptime;
141
struct timeval fixtime;
143
static long fs = -1L; /* fifo (ring buffer) size */
145
EXPORT int main __PR((int ac, char **av));
146
LOCAL void usage __PR((int));
147
LOCAL void blusage __PR((int));
148
LOCAL void intr __PR((int sig));
149
LOCAL void intfifo __PR((int sig));
150
LOCAL void exscsi __PR((int excode, void *arg));
151
LOCAL void excdr __PR((int excode, void *arg));
152
EXPORT int read_buf __PR((int f, char *bp, int size));
153
EXPORT int get_buf __PR((int f, char **bpp, int size));
154
LOCAL int write_track_data __PR((SCSI *scgp, cdr_t *, int , track_t *));
155
EXPORT int pad_track __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp,
156
long startsec, Llong amt,
157
BOOL dolast, Llong *bytesp));
158
EXPORT int write_buf __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp,
159
char *bp, long startsec, long amt, int secsize,
160
BOOL dolast, long *bytesp));
161
LOCAL void printdata __PR((int, track_t *));
162
LOCAL void printaudio __PR((int, track_t *));
163
LOCAL void checkfile __PR((int, track_t *));
164
LOCAL int checkfiles __PR((int, track_t *));
165
LOCAL void setpregaps __PR((int, track_t *));
166
LOCAL long checktsize __PR((int, track_t *));
167
LOCAL void checksize __PR((track_t *));
168
LOCAL BOOL checkdsize __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp, long tsize, int flags));
169
LOCAL void raise_fdlim __PR((void));
170
LOCAL void gargs __PR((int, char **, int *, track_t *, char **,
172
int *, long *, int *, int *));
173
LOCAL void set_trsizes __PR((cdr_t *, int, track_t *));
174
EXPORT void load_media __PR((SCSI *scgp, cdr_t *, BOOL));
175
EXPORT void unload_media __PR((SCSI *scgp, cdr_t *, int));
176
EXPORT void set_secsize __PR((SCSI *scgp, int secsize));
177
LOCAL void check_recovery __PR((SCSI *scgp, cdr_t *, int));
178
void audioread __PR((SCSI *scgp, cdr_t *, int));
179
LOCAL void print_msinfo __PR((SCSI *scgp, cdr_t *));
180
LOCAL void print_toc __PR((SCSI *scgp, cdr_t *));
181
LOCAL void print_track __PR((int, long, struct msf *, int, int, int));
182
LOCAL void prtimediff __PR((const char *fmt,
183
struct timeval *start,
184
struct timeval *stop));
185
#if !defined(HAVE_SYS_PRIOCNTL_H)
186
LOCAL int rt_raisepri __PR((int));
188
EXPORT void raisepri __PR((int));
189
LOCAL void wait_input __PR((void));
190
LOCAL void checkgui __PR((void));
191
LOCAL Llong number __PR((char* arg, int* retp));
192
EXPORT int getnum __PR((char* arg, long* valp));
193
EXPORT int getllnum __PR((char *arg, Llong* lvalp));
194
LOCAL int getbltype __PR((char* optstr, long *typep));
210
int timeout = 40; /* Set default timeout to 40s CW-7502 is slow*/
219
track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */
220
cdr_t *dp = (cdr_t *)0;
228
/* This gives wildcard expansion with Non-Posix shells with EMX */
233
fillbytes(track, sizeof(track), '\0');
235
gargs(ac, av, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
236
&toctype, &blanktype);
238
comerrno(EX_BAD, "Internal error: Bad TOC type.\n");
241
* Warning: you are not allowed to modify or to remove this
242
* version printing code!
245
i = set_cdrcmds("mmc_dvd", (cdr_t **)NULL);
247
if ((flags & F_MSINFO) == 0 || lverbose || flags & F_VERSION)
248
printf("Cdrecord%s %s (%s-%s-%s) Copyright (C) 1995-2001 Jļæ½rg Schilling\n",
255
HOST_CPU, HOST_VENDOR, HOST_OS);
256
if (flags & F_VERSION)
261
if (debug || lverbose) {
262
printf("TOC Type: %d = %s\n",
263
toctype, toc2name[toctype & TOC_MASK]);
266
if ((flags & (F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_INQUIRY|F_SCANBUS|F_RESET)) == 0) {
268
* Try to lock us im memory (will only work for root)
269
* but you need access to root anyway to use /dev/scg?
271
#if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK)
272
if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
273
errmsg("WARNING: Cannot do mlockall(2).\n");
274
errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
278
raisepri(0); /* max priority */
282
if ((flags & F_WAITI) != 0) {
284
printf("Waiting for data on stdin...\n");
289
* Call scg_remote() to force loading the remote SCSI transport library
290
* code that is located in librscg instead of the dummy remote routines
291
* that are located inside libscg.
294
if ((scgp = scg_open(dev, errstr, sizeof(errstr),
295
debug, (flags & F_MSINFO) == 0 || lverbose)) == (SCSI *)0) {
296
errmsg("%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":"");
297
comerrno(EX_BAD, "For possible targets try 'cdrecord -scanbus'. Make sure you are root.\n");
299
scg_settimeout(scgp, timeout);
300
scgp->verbose = scsi_verbose;
301
scgp->silent = silent;
303
scgp->kdebug = kdebug;
304
scgp->cap->c_bsize = 2048;
307
if ((flags & F_MSINFO) == 0 || lverbose) {
312
* Warning: you are not allowed to modify or to remove this
313
* version checking code!
315
vers = scg_version(0, SCG_VERSION);
316
auth = scg_version(0, SCG_AUTHOR);
317
printf("Using libscg version '%s-%s'\n", auth, vers);
318
if (auth == 0 || strcmp("schily", auth) != 0) {
320
"Warning: using inofficial version of libscg (%s-%s '%s').\n",
321
auth, vers, scg_version(0, SCG_SCCS_ID));
324
vers = scg_version(scgp, SCG_VERSION);
325
auth = scg_version(scgp, SCG_AUTHOR);
327
error("Using libscg transport code version '%s-%s'\n", auth, vers);
328
if (auth == 0 || strcmp("schily", auth) != 0) {
330
"Warning: using inofficial libscg transport code version (%s-%s '%s').\n",
331
auth, vers, scg_version(scgp, SCG_SCCS_ID));
334
vers = scg_version(scgp, SCG_RVERSION);
335
auth = scg_version(scgp, SCG_RAUTHOR);
336
if (lverbose > 1 && vers && auth)
337
error("Using remote transport code version '%s-%s'\n", auth, vers);
338
if (auth != 0 && strcmp("schily", auth) != 0) {
340
"Warning: using inofficial remote transport code version (%s-%s '%s').\n",
341
auth, vers, scg_version(scgp, SCG_RSCCS_ID));
344
if (lverbose && driveropts)
345
printf("Driveropts: '%s'\n", driveropts);
347
bufsize = scg_bufsize(scgp, BUF_SIZE);
349
error("SCSI buffer size: %ld\n", bufsize);
350
if ((buf = scg_getbuf(scgp, bufsize)) == NULL)
351
comerr("Cannot get SCSI I/O buffer.\n");
353
if ((flags & F_SCANBUS) != 0) {
354
select_target(scgp, stdout);
357
if ((flags & F_RESET) != 0) {
358
if (scg_reset(scgp, SCG_RESET_NOP) < 0)
359
comerr("Cannot reset (OS does not implement reset).\n");
360
if (scg_reset(scgp, SCG_RESET_TGT) >= 0)
362
if (scg_reset(scgp, SCG_RESET_BUS) < 0)
363
comerr("Cannot reset target.\n");
367
* First try to check which type of SCSI device we
370
if (debug || lverbose)
371
printf("atapi: %d\n", scg_isatapi(scgp));
373
test_unit_ready(scgp); /* eat up unit attention */
375
if (!do_inquiry(scgp, (flags & F_MSINFO) == 0 || lverbose)) {
376
errmsgno(EX_BAD, "Cannot do inquiry for CD/DVD-Recorder.\n");
377
if (unit_ready(scgp))
378
errmsgno(EX_BAD, "The unit seems to be hung and needs power cycling.\n");
382
if ((flags & F_PRCAP) != 0) {
383
print_capabilities(scgp);
386
if ((flags & F_INQUIRY) != 0)
389
if (dp == (cdr_t *)NULL) { /* No driver= option specified */
390
dp = get_cdrcmds(scgp);
391
} else if (!is_unknown_dev(scgp) && dp != get_cdrcmds(scgp)) {
392
errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n");
395
if (!is_cddrive(scgp))
396
comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n");
397
if (dp == (cdr_t *)0)
398
comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.\n");
400
if (((flags & (F_MSINFO|F_TOC|F_LOAD|F_EJECT)) == 0 || tracks > 0) &&
401
(dp->cdr_flags & CDR_ISREADER) != 0) {
402
BOOL is_dvdr = FALSE;
405
"Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.\n");
407
is_mmc(scgp, &is_dvdr);
408
if (is_dvdr && !set_cdrcmds("mmc_dvd", (cdr_t **)NULL)) {
410
"This version of cdrecord does not include DVD-R support code.\n");
412
"If you need DVD-R support, ask the Author for cdrecord-ProDVD.\n");
417
if ((*dp->cdr_attach)(scgp, dp) != 0)
418
comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.\n");
422
exargs.old_secsize = -1;
423
exargs.flags = flags;
425
if ((flags & F_MSINFO) == 0 || lverbose) {
426
printf("Using %s (%s).\n", dp->cdr_drtext, dp->cdr_drname);
427
printf("Driver flags : ");
428
if ((dp->cdr_flags & CDR_SWABAUDIO) != 0)
433
if ((debug || lverbose)) {
435
if ((*dp->cdr_buffer_cap)(scgp, &tsize, (long *)0) < 0 || tsize <= 0) {
436
if (read_buffer(scgp, buf, 4, 0) >= 0)
437
tsize = a_to_u_4_byte(buf);
440
printf("Drive buf size : %lu = %lu KB\n",
446
if (tracks > 0 && (debug || lverbose))
447
printf("FIFO size : %lu = %lu KB\n", fs, fs >> 10);
449
if ((flags & F_CHECKDRIVE) != 0)
452
if (tracks == 0 && (flags & (F_FIX|F_BLANK)) == 0 && (flags & F_EJECT) != 0) {
454
* Do not check if the unit is ready here to allow to open
457
unload_media(scgp, dp, flags);
463
sleep(2); /* Let the user watch the inquiry messages */
465
set_trsizes(dp, tracks, track);
466
setpregaps(tracks, track);
467
checkfiles(tracks, track);
468
tsize = checktsize(tracks, track);
469
do_cue(tracks, track, 0);
472
* Is this the right place to do this ?
474
check_recovery(scgp, dp, flags);
476
if ((flags & F_FORCE) == 0)
477
load_media(scgp, dp, TRUE);
479
if ((flags & F_LOAD) != 0) {
480
scgp->silent++; /* silently */
481
scsi_prevent_removal(scgp, 0); /* allow manual open */
482
scgp->silent--; /* if load failed... */
485
exargs.old_secsize = sense_secsize(scgp, 1);
486
if (exargs.old_secsize < 0)
487
exargs.old_secsize = sense_secsize(scgp, 0);
489
printf("Current Secsize: %d\n", exargs.old_secsize);
493
if (exargs.old_secsize < 0)
494
exargs.old_secsize = scgp->cap->c_bsize;
495
if (exargs.old_secsize != scgp->cap->c_bsize)
496
errmsgno(EX_BAD, "Warning: blockdesc secsize %d differs from cap secsize %d\n",
497
exargs.old_secsize, scgp->cap->c_bsize);
499
on_comerr(exscsi, &exargs);
502
printf("Current Secsize: %d\n", exargs.old_secsize);
504
if (exargs.old_secsize > 0 && exargs.old_secsize != 2048) {
506
* Some drives (e.g. Plextor) don't like to write correctly
507
* in DAO mode if the sector size is set to 512 bytes.
508
* In addition, cdrecord -msinfo will not work properly
509
* if the sector size is not 2048 bytes.
511
set_secsize(scgp, 2048);
514
/*audioread(dp, flags);*/
515
/*unload_media(scgp, dp, flags);*/
517
fillbytes(&ds, sizeof(ds), '\0');
519
ds.ds_cdrflags = RF_WRITE;
520
if (flags & F_PRATIP) {
521
lverbose++; /* XXX Hack */
523
if ((*dp->cdr_getdisktype)(scgp, dp, &ds) < 0) {
524
errmsgno(EX_BAD, "Cannot get disk type.\n");
525
exscsi(EX_BAD, &exargs);
526
if ((flags & F_FORCE) == 0)
529
if (flags & F_PRATIP) {
530
lverbose--; /* XXX Hack */
535
* The next actions should depend on the disk type.
540
* At least MMC drives will not return the next writable
541
* address we expect when the drive's write mode is set
542
* to DAO/SAO. We need this address for mkisofs and thus
543
* it must be the first user accessible sector and not the
544
* first sector of the pregap. Set_speed_dummy() witha a
545
* 'speedp' f 0 sets the write mode to TAO on MMC drives.
547
* We set TAO unconditionally to make checkdsize() work
548
* currectly in DAO mode too.
550
* XXX The ACER drive:
551
* XXX Vendor_info : 'ATAPI '
552
* XXX Identifikation : 'CD-R/RW 8X4X32 '
553
* XXX Revision : '5.EW'
554
* XXX Will not return from -dummy to non-dummy without
555
* XXX opening the tray.
558
(*dp->cdr_set_speed_dummy)(scgp, 0, flags & F_DUMMY);
561
if (flags & F_MSINFO) {
562
print_msinfo(scgp, dp);
573
if ((*dp->cdr_check_session)() < 0) {
574
exscsi(EX_BAD, &exargs);
581
"WARNING: Track size unknown. Data may not fit on disk.\n");
583
} else if (!checkdsize(scgp, dp, &ds, tsize, flags)) {
584
exscsi(EX_BAD, &exargs);
587
if (tracks > 0 && fs > 0l) {
589
* Start the extra process needed for improved buffering.
591
if (!init_faio(tracks, track, bufsize))
594
on_comerr(excdr, &exargs);
596
if ((*dp->cdr_set_speed_dummy)(scgp, &speed, flags & F_DUMMY) < 0) {
597
errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
598
excdr(EX_BAD, &exargs);
601
if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) {
602
wait_unit_ready(scgp, 120);
603
scsi_blank(scgp, 0L, blanktype, FALSE);
608
* Last chance to quit!
610
printf("Starting to write CD/DVD at speed %d in %s mode for %s session.\n",
612
(flags & F_DUMMY) ? "dummy" : "write",
613
(flags & F_MULTI) ? "multi" : "single");
614
printf("Last chance to quit, starting %s write in 9 seconds.",
615
(flags & F_DUMMY)?"dummy":"real");
617
signal(SIGINT, intr);
618
for (i=9; --i >= 0;) {
624
printf("\b\b\b\b\b\b\b\b\b\b%d seconds.", i);
627
printf(" Operation starts.");
629
signal(SIGINT, SIG_DFL);
630
signal(SIGINT, intfifo);
631
signal(SIGTERM, intfifo);
633
if (tracks > 0 && fs > 0l) {
635
* Wait for the read-buffer to become full.
636
* This should be take no extra time if the input is a file.
637
* If the input is a pipe (e.g. mkisofs) this can take a
638
* while. If mkisofs dumps core before it starts writing,
639
* we abort before the writing process started.
642
errmsgno(EX_BAD, "Input buffer error, aborting.\n");
643
excdr(EX_BAD, &exargs);
647
if (gettimeofday(&starttime, (struct timezone *)0) < 0)
648
errmsg("Cannot get start time\n");
651
* Blank the media if we were requested to do so
653
if (flags & F_BLANK) {
654
if ((*dp->cdr_blank)(scgp, 0L, blanktype) < 0) {
655
errmsgno(EX_BAD, "Cannot blank disk, aborting.\n");
656
excdr(EX_BAD, &exargs);
659
if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
660
errmsg("Cannot get blank time\n");
662
prtimediff("Blanking time: ", &starttime, &fixtime);
664
if (!wait_unit_ready(scgp, 240) || tracks == 0) {
669
* Reset start time so we will not see blanking time and
670
* writing time counted together.
672
if (gettimeofday(&starttime, (struct timezone *)0) < 0)
673
errmsg("Cannot get start time\n");
676
* Get the number of the next recordable track.
679
if (read_tochdr(scgp, dp, NULL, &trackno) < 0) {
683
for (i = 1; i <= tracks; i++) {
684
track[i].trackno = i + trackno;
687
track[0].trackno = trackno; /* XXX Hack for TEAC fixate */
690
* Now we actually start writing to the CD/DVD.
691
* XXX Check total size of the tracks and remaining size of disk.
693
if ((*dp->cdr_open_session)(scgp, dp, tracks, track, toctype, flags & F_MULTI) < 0) {
694
errmsgno(EX_BAD, "Cannot open new session.\n");
695
excdr(EX_BAD, &exargs);
698
if ((flags & F_DUMMY) == 0 && dp->cdr_opc) {
699
if (debug || lverbose) {
700
printf("Performing OPC...\n");
703
if (dp->cdr_opc(scgp, NULL, 0, TRUE) < 0)
704
comerr("OPC failed.\n");
708
* As long as open_session() will do nothing but
709
* set up parameters, we may leave fix_it here.
710
* I case we have to add an open_session() for a drive
711
* that wants to do something that modifies the disk
712
* We have to think about a new solution.
718
if (debug || lverbose) {
719
printf("Sending CUE sheet...\n");
722
if ((*dp->cdr_send_cue)(scgp, tracks, track) < 0) {
723
errmsgno(EX_BAD, "Cannot send CUE sheet.\n");
724
excdr(EX_BAD, &exargs);
728
if ((flags & F_SAO)) {
729
(*dp->cdr_next_wr_address)(scgp, 0, &track[0], &startsec);
730
if (startsec <= 0 && startsec != -150) {
731
errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%ld) using -150\n",
737
printf("SAO startsec: %ld\n", startsec);
739
for (i = 1; i <= tracks; i++) {
740
track[i].trackstart += startsec +150;
743
if (debug || lverbose)
744
printf("Writing lead-in...\n");
746
pad_track(scgp, dp, 1, &track[1], -150, (Llong)0,
751
* Need to set trackno to the real value from
752
* the current disk status.
754
for (i = 1; i <= tracks; i++, trackno++) {
758
* trackno is the "real" track number while 'i' is a counter
759
* going from 1 to tracks.
761
if ((*dp->cdr_open_track)(scgp, dp, trackno, &track[i]) < 0) {
766
if ((flags & F_SAO) == 0) {
767
if ((*dp->cdr_next_wr_address)(scgp, trackno, &track[i], &startsec) < 0) {
771
track[i].trackstart = startsec;
773
if (debug || lverbose) {
774
printf("Starting new track at sector: %ld\n",
775
track[i].trackstart);
778
if (write_track_data(scgp, dp, trackno, &track[i]) < 0) {
782
(*dp->cdr_close_track)(scgp, trackno, &track[i]);
785
if ((*dp->cdr_close_track)(scgp, trackno, &track[i]) < 0) {
787
* Check for "Dummy blocks added" message first.
789
if (scg_sense_key(scgp) != SC_ILLEGAL_REQUEST ||
790
scg_sense_code(scgp) != 0xB5) {
797
if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
798
errmsg("Cannot get stop time\n");
800
prtimediff("Writing time: ", &starttime, &stoptime);
802
if ((flags & F_NOFIX) == 0) {
804
printf("Fixating...\n");
807
if ((*dp->cdr_fixate)(scgp, flags & F_MULTI, flags & F_DUMMY,
808
toctype, tracks, track) < 0) {
810
* Ignore fixating errors in dummy mode.
812
if ((flags & F_DUMMY) == 0)
815
if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
816
errmsg("Cannot get fix time\n");
818
prtimediff("Fixating time: ", &stoptime, &fixtime);
823
* Try to restore the old sector size and stop FIFO.
825
excdr(errs?-2:0, &exargs);
834
errmsgno(EX_BAD, "Usage: %s [options] track1...trackn\n",
838
error("\t-version print version information and exit\n");
839
error("\tdev=target SCSI target to use as CD/DVD-Recorder\n");
840
error("\ttimeout=# set the default SCSI command timeout to #.\n");
841
error("\tdebug=#,-d Set to # or increment misc debug level\n");
842
error("\tkdebug=#,kd=# do Kernel debugging\n");
843
error("\t-verbose,-v increment general verbose level by one\n");
844
error("\t-Verbose,-V increment SCSI command transport verbose level by one\n");
845
error("\t-silent,-s do not print status of failed SCSI commands\n");
846
error("\tdriver=name user supplied driver name, use with extreme care\n");
847
error("\tdriveropts=opt a comma separated list of driver specific options\n");
848
error("\t-checkdrive check if a driver for the drive is present\n");
849
error("\t-prcap print drive capabilities for MMC compliant drives\n");
850
error("\t-inq do an inquiry for the drive and exit\n");
851
error("\t-scanbus scan the SCSI bus and exit\n");
852
error("\t-reset reset the SCSI bus with the cdrecorder (if possible)\n");
853
error("\t-ignsize ignore the known size of a medium (may cause problems)\n");
854
error("\t-useinfo use *.inf files to overwrite audio options.\n");
855
error("\tspeed=# set speed of drive\n");
856
error("\tblank=type blank a CD-RW disc (see blank=help)\n");
858
error("\tfs=# Set fifo size to # (0 to disable, default is %ld MB)\n",
859
DEFAULT_FIFOSIZE/(1024L*1024L));
861
error("\t-load load the disk and exit (works only with tray loader)\n");
862
error("\t-eject eject the disk after doing the work\n");
863
error("\t-dummy do everything with laser turned off\n");
864
error("\t-msinfo retrieve multi-session info for mkisofs >= 1.10\n");
865
error("\t-toc retrieve and print TOC/PMA data\n");
866
error("\t-atip retrieve and print ATIP data\n");
867
error("\t-multi generate a TOC that allows multi session\n");
868
error("\t In this case default track type is CD-ROM XA2\n");
869
error("\t-fix fixate a corrupt or unfixated disk (generate a TOC)\n");
870
error("\t-nofix do not fixate disk after writing tracks\n");
871
error("\t-waiti wait until input is available before opening SCSI\n");
872
error("\t-force force to continue on some errors to allow blanking bad disks\n");
873
error("\t-dao Write disk in DAO mode. This option will be replaced in the future.\n");
874
error("\ttsize=# Length of valid data in next track\n");
875
error("\tpadsize=# Amount of padding for next track\n");
876
error("\tpregap=# Amount of pre-gap sectors before next track\n");
877
error("\tdefpregap=# Amount of pre-gap sectors for all but track #1\n");
878
error("\tmcn=text Set the media catalog number for this CD to 'text'\n");
879
error("\tisrc=text Set the ISRC number for the next track to 'text'\n");
880
error("\tindex=list Set the index list for the next track to 'list'\n");
882
error("\t-audio Subsequent tracks are CD-DA audio tracks\n");
883
error("\t-data Subsequent tracks are CD-ROM data mode 1 (default)\n");
884
error("\t-mode2 Subsequent tracks are CD-ROM data mode 2\n");
885
error("\t-xa1 Subsequent tracks are CD-ROM XA mode 1\n");
886
error("\t-xa2 Subsequent tracks are CD-ROM XA mode 2\n");
887
error("\t-cdi Subsequent tracks are CDI tracks\n");
888
error("\t-isosize Use iso9660 file system size for next data track\n");
889
error("\t-preemp Audio tracks are mastered with 50/15 ļæ½s preemphasis\n");
890
error("\t-nopreemp Audio tracks are mastered with no preemphasis (default)\n");
891
error("\t-pad Pad data tracks with %d zeroed sectors\n", PAD_SECS);
892
error("\t Pad audio tracks to a multiple of %d bytes\n", AUDIO_SEC_SIZE);
893
error("\t-nopad Do not pad data tracks (default)\n");
894
error("\t-shorttrack Subsequent tracks may be non Red Book < 4 seconds if in DAO mode\n");
895
error("\t-noshorttrack Subsequent tracks must be >= 4 seconds\n");
896
error("\t-swab Audio data source is byte-swapped (little-endian/Intel)\n");
897
error("The type of the first track is used for the toc type.\n");
898
error("Currently only form 1 tracks are supported.\n");
906
error("Blanking options:\n");
907
error("\tall\t\tblank the entire disk\n");
908
error("\tdisc\t\tblank the entire disk\n");
909
error("\tdisk\t\tblank the entire disk\n");
910
error("\tfast\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
911
error("\tminimal\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
912
error("\ttrack\t\tblank a track\n");
913
error("\tunreserve\tunreserve a track\n");
914
error("\ttrtail\t\tblank a track tail\n");
915
error("\tunclose\t\tunclose last session\n");
916
error("\tsession\t\tblank last session\n");
927
sig = 0; /* Fake usage for gcc */
929
signal(SIGINT, intr);
948
struct exargs *exp = (struct exargs *)arg;
951
* Try to restore the old sector size.
953
if (exp != NULL && exp->exflags == 0) {
955
set_secsize(exp->scgp, exp->old_secsize);
956
unload_media(exp->scgp, exp->dp, exp->flags);
958
exp->exflags++; /* Make sure that it only get called once */
972
if (debug || lverbose)
978
read_buf(f, bp, size)
989
n = read(f, p, size-amount);
990
} while (n < 0 && (errno == EAGAIN || errno == EINTR));
996
} while (amount < size && n > 0);
1001
get_buf(f, bpp, size)
1007
/* return (faio_read_buf(f, *bpp, size));*/
1008
return (faio_get_buf(f, bpp, size));
1010
return (read_buf(f, *bpp, size));
1015
write_track_data(scgp, dp, track, trackp)
1024
Llong bytes_read = 0;
1036
BOOL neednl = FALSE;
1037
BOOL islast = FALSE;
1048
if (read_buff_cap(scgp, &bsize, &bfree) < 0)
1053
if (is_packet(trackp)) /* XXX Ugly hack for now */
1054
return (write_packet_data(scgp, dp, track, trackp));
1057
isaudio = is_audio(trackp);
1058
tracksize = trackp->tracksize;
1059
startsec = trackp->trackstart;
1061
secsize = trackp->secsize;
1062
secspt = trackp->secspt;
1063
bytespt = secsize * secspt;
1065
pad = !isaudio && is_pad(trackp); /* Pad only data tracks */
1066
bswab = isaudio && is_swab(trackp); /* Swab only audio tracks */
1069
printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n",
1070
secsize, secspt, bytespt, isaudio, pad);
1075
printf("\rTrack %02d: 0 of %3lld MB written.",
1076
track, tracksize >> 20);
1078
printf("\rTrack %02d: 0 MB written.", track);
1084
bytes_to_read = bytespt;
1085
if (tracksize > 0) {
1086
if ((tracksize - bytes_read) > bytespt)
1087
bytes_to_read = bytespt;
1089
bytes_to_read = tracksize - bytes_read;
1091
count = get_buf(f, &bp, bytes_to_read);
1094
comerr("read error on input file\n");
1097
bytes_read += count;
1098
if (tracksize >= 0 && bytes_read >= tracksize) {
1099
count -= bytes_read - tracksize;
1101
* Paranoia: tracksize is known (trackp->tracksize >= 0)
1102
* At this point, trackp->padsize should alway be set
1103
* if the tracksize is less than 300 sectors.
1105
if (trackp->padsize == 0 &&
1106
(is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
1111
swabbytes(bp, count);
1113
if (count < bytespt) {
1115
printf("\nNOTICE: reducing block size for last record.\n");
1119
if ((amount = count % secsize) != 0) {
1120
amount = secsize - amount;
1121
fillbytes(&bp[count], amount, '\0');
1123
printf("\nWARNING: padding up to secsize.\n");
1127
secspt = count / secsize;
1129
* If tracksize is not known (trackp->tracksize < 0)
1130
* we may need to set trackp->padsize
1131
* if the tracksize is less than 300 sectors.
1133
if (trackp->padsize == 0 &&
1134
(is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
1140
amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
1143
if (scsi_in_progress(scgp)) {
1148
printf("%swrite track data: error after %lld bytes\n",
1149
neednl?"\n":"", bytes);
1153
startsec += amount / secsize;
1155
if (lverbose && (bytes >= (savbytes + 0x100000))) {
1158
printf("\rTrack %02d: %3lld", track, bytes >> 20);
1160
printf(" of %3lld MB", tracksize >> 20);
1164
fper = fifo_percent(TRUE);
1166
printf(" (fifo %3d%%)", fper);
1168
savbytes = (bytes >> 20) << 20;
1174
read_buff_cap(scgp, 0, &bfree);
1175
per = 100*(bsize - bfree) / bsize;
1177
printf("[buf %3d%%] %3ld %3ld\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",
1178
per, bsize >> 10, bfree >> 10);
1183
} while (tracksize < 0 || bytes_read < tracksize);
1185
if (!is_shorttrk(trackp) && (bytes / secsize) < 300) {
1187
* If tracksize is not known (trackp->tracksize < 0) or
1188
* for some strange reason we did not set padsize properly
1189
* we may need to modify trackp->padsize if
1190
* tracksize+padsize is less than 300 sectors.
1192
savbytes = roundup(trackp->padsize, secsize);
1193
if (((bytes+savbytes) / secsize) < 300)
1194
trackp->padsize = 300 * secsize - bytes;
1196
if (trackp->padsize) {
1201
if ((trackp->padsize >> 20) > 0) {
1203
} else if (lverbose) {
1204
printf("Track %02d: writing %3lld KB of pad data.\n",
1205
track, (Llong)(trackp->padsize >> 10));
1208
pad_track(scgp, dp, track, trackp, startsec, trackp->padsize,
1211
startsec += savbytes / secsize;
1213
printf("%sTrack %02d: Total bytes read/written: %lld/%lld (%lld sectors).\n",
1214
neednl?"\n":"", track, bytes_read, bytes, bytes/secsize);
1220
pad_track(scgp, dp, track, trackp, startsec, amt, dolast, bytesp)
1236
BOOL neednl = FALSE;
1237
BOOL islast = FALSE;
1239
secsize = trackp->secsize;
1240
secspt = trackp->secspt;
1241
bytespt = secsize * secspt;
1243
fillbytes(buf, bytespt, '\0');
1245
if ((amt >> 20) > 0) {
1246
printf("\rTrack %02d: 0 of %3lld MB pad written.",
1251
if (amt < bytespt) {
1252
bytespt = roundup(amt, secsize);
1253
secspt = bytespt / secsize;
1255
if (dolast && (amt - bytespt) <= 0)
1260
amount = (*dp->cdr_write_trackdata)(scgp, buf, startsec, bytespt, secspt, islast);
1263
if (scsi_in_progress(scgp)) {
1268
printf("%swrite track pad data: error after %lld bytes\n",
1269
neednl?"\n":"", bytes);
1272
read_buff_cap(scgp, 0, 0);
1277
startsec += amount / secsize;
1279
if (lverbose && (bytes >= (savbytes + 0x100000))) {
1280
printf("\rTrack %02d: %3lld", track, bytes >> 20);
1281
savbytes = (bytes >> 20) << 20;
1291
return (bytes > 0 ? 1:-1);
1294
#ifdef USE_WRITE_BUF
1296
write_buf(scgp, dp, track, trackp, bp, startsec, amt, secsize, dolast, bytesp)
1314
BOOL neednl = FALSE;
1315
BOOL islast = FALSE;
1317
/* secsize = trackp->secsize;*/
1318
/* secspt = trackp->secspt;*/
1320
secspt = bufsize/secsize;
1321
secspt = min(255, secspt);
1322
bytespt = secsize * secspt;
1324
/* fillbytes(buf, bytespt, '\0');*/
1326
if ((amt >> 20) > 0) {
1327
printf("\rTrack %02d: 0 of %3ld MB pad written.",
1332
if (amt < bytespt) {
1333
bytespt = roundup(amt, secsize);
1334
secspt = bytespt / secsize;
1336
if (dolast && (amt - bytespt) <= 0)
1339
amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
1341
printf("%swrite track data: error after %ld bytes\n",
1342
neednl?"\n":"", bytes);
1345
read_buff_cap(scgp, 0, 0);
1350
startsec += amount / secsize;
1352
if (lverbose && (bytes >= (savbytes + 0x100000))) {
1353
printf("\rTrack %02d: %3ld", track, bytes >> 20);
1354
savbytes = (bytes >> 20) << 20;
1364
#endif /* USE_WRITE_BUF */
1367
printdata(track, trackp)
1371
if (trackp->tracksize >= 0) {
1372
printf("Track %02d: data %3lld MB ",
1373
track, (Llong)(trackp->tracksize >> 20));
1375
printf("Track %02d: data unknown length",
1378
if (trackp->padsize > 0) {
1379
if ((trackp->padsize >> 20) > 0)
1380
printf(" padsize: %3lld MB", (Llong)(trackp->padsize >> 20));
1382
printf(" padsize: %3lld KB", (Llong)(trackp->padsize >> 10));
1384
if (trackp->pregapsize != 150) {
1385
printf(" pregapsize: %3ld", trackp->pregapsize);
1391
printaudio(track, trackp)
1395
if (trackp->tracksize >= 0) {
1396
printf("Track %02d: audio %3lld MB (%02d:%02d.%02d) %spreemp%s%s",
1397
track, (Llong)(trackp->tracksize >> 20),
1398
minutes(trackp->tracksize),
1399
seconds(trackp->tracksize),
1400
hseconds(trackp->tracksize),
1401
is_preemp(trackp) ? "" : "no ",
1402
is_swab(trackp) ? " swab":"",
1403
((trackp->tracksize < 300L*trackp->secsize) ||
1404
(trackp->tracksize % trackp->secsize)) &&
1405
is_pad(trackp) ? " pad" : "");
1407
printf("Track %02d: audio unknown length %spreemp%s%s",
1408
track, is_preemp(trackp) ? "" : "no ",
1409
is_swab(trackp) ? " swab":"",
1410
(trackp->tracksize % trackp->secsize) && is_pad(trackp) ? " pad" : "");
1412
if (trackp->padsize > 0) {
1413
if ((trackp->padsize >> 20) > 0)
1414
printf(" padsize: %3lld MB", (Llong)(trackp->padsize >> 20));
1416
printf(" padsize: %3lld KB", (Llong)(trackp->padsize >> 10));
1417
printf(" (%02d:%02d.%02d)",
1418
minutes(trackp->padsize),
1419
seconds(trackp->padsize),
1420
hseconds(trackp->padsize));
1422
if (trackp->pregapsize != 150) {
1423
printf(" pregapsize: %3ld", trackp->pregapsize);
1429
checkfile(track, trackp)
1433
if (trackp->tracksize > 0 &&
1435
( (!is_shorttrk(trackp) &&
1436
(trackp->tracksize < 300L*trackp->secsize)) ||
1437
(trackp->tracksize % trackp->secsize)) &&
1439
errmsgno(EX_BAD, "Bad audio track size %lld for track %02d.\n",
1440
(Llong)trackp->tracksize, track);
1441
errmsgno(EX_BAD, "Audio tracks must be at least %ld bytes and a multiple of %d.\n",
1442
300L*trackp->secsize, trackp->secsize);
1443
comerrno(EX_BAD, "See -pad option.\n");
1449
if (is_audio(trackp))
1450
printaudio(track, trackp);
1452
printdata(track, trackp);
1456
checkfiles(tracks, trackp)
1463
for (i = 1; i <= tracks; i++) {
1464
if (!is_audio(&trackp[i]))
1466
checkfile(i, &trackp[i]);
1472
setpregaps(tracks, trackp)
1481
* Set some values for track 0 (the lead-in)
1482
* XXX There should be a better place to do this.
1484
sectype = trackp[1].sectype;
1485
trackp[0].sectype = sectype;
1486
trackp[0].dbtype = trackp[1].dbtype;
1488
for (i = 1; i <= tracks; i++) {
1490
if (tp->pregapsize == -1L) {
1491
tp->pregapsize = 150; /* Default Pre GAP */
1492
if (sectype != tp->sectype) {
1493
tp->pregapsize = 255; /* Pre GAP is 255 */
1494
tp->flags &= ~TI_PREGAP;
1497
sectype = tp->sectype; /* Save old sectype */
1500
* Set some values for track 0xAA (the lead-out)
1501
* XXX There should be a better place to do this.
1503
trackp[tracks+1].sectype = sectype;
1504
trackp[tracks+1].dbtype = trackp[tracks].dbtype;
1508
checktsize(tracks, trackp)
1518
for (i = 1; i <= tracks; i++) {
1521
total += tp->pregapsize;
1524
printf("track: %d start: %lld pregap: %ld\n",
1525
i, total, tp->pregapsize);
1527
tp->trackstart = total;
1528
if (tp->tracksize >= 0) {
1529
curr = (tp->tracksize + (tp->secsize-1)) / tp->secsize;
1530
curr += (tp->padsize + (tp->secsize-1)) / tp->secsize;
1532
* Minimum track size is 4s
1534
if (!is_shorttrk(tp) && curr < 300)
1536
if (is_tao(tp) && !is_audio(tp)) {
1543
tp->trackstart = total;
1547
btotal = (Ullong)total * 2352;
1548
/* XXX Sector Size ??? */
1550
printf("Total size: %3llu MB (%02d:%02d.%02d) = %lld sectors\n",
1554
hseconds(btotal), total);
1555
btotal += 150 * 2352;
1556
printf("Lout start: %3llu MB (%02d:%02d/%02d) = %lld sectors\n",
1560
frames(btotal), total);
1573
* If the current input file is a regular file and
1574
* 'padsize=' has not been specified,
1575
* use fstat() or file parser to get the size of the file.
1577
if (trackp->tracksize < 0 && (trackp->flags & TI_ISOSIZE) != 0) {
1578
lsize = isosize(trackp->f);
1579
trackp->tracksize = lsize;
1580
if (trackp->tracksize != lsize)
1581
comerrno(EX_BAD, "This OS cannot handle large ISO-9660 images.\n");
1583
if (trackp->tracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
1584
lsize = ausize(trackp->f);
1585
trackp->tracksize = lsize;
1586
if (trackp->tracksize != lsize)
1587
comerrno(EX_BAD, "This OS cannot handle large audio images.\n");
1589
if (trackp->tracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
1590
lsize = wavsize(trackp->f);
1591
trackp->tracksize = lsize;
1592
if (trackp->tracksize != lsize)
1593
comerrno(EX_BAD, "This OS cannot handle large WAV images.\n");
1594
if (trackp->tracksize > 0) /* Force little endian input */
1595
trackp->flags |= TI_SWAB;
1597
if (trackp->tracksize == AU_BAD_CODING) {
1598
comerrno(EX_BAD, "Inappropriate audio coding in '%s'.\n",
1601
if (trackp->tracksize < 0 &&
1602
fstat(trackp->f, &st) >= 0 && S_ISREG(st.st_mode)) {
1603
trackp->tracksize = st.st_size;
1608
checkdsize(scgp, dp, dsp, tsize, flags)
1619
(*dp->cdr_next_wr_address)(scgp, /*i*/ 0, (track_t *)0, &startsec);
1623
* This only should happen when the drive is currently in DAO mode.
1624
* We rely on the drive being in TAO mode, a negative value for
1625
* startsec is not correct here it may be caused by bad firmware or
1626
* by a drive in DAO mode. In DAO mode the drive will report the
1627
* pre-gap as part of the writable area.
1633
* Size limitations for CD's:
1635
* 404850 == 90 min Red book calls this the
1636
* first negative time
1637
* allows lead out start up to
1640
* 449850 == 100 min This is the first time that
1641
* is no more representable
1642
* in a two digit BCD number.
1643
* allows lead out start up to
1647
endsec = startsec + tsize;
1649
if (dsp->ds_maxblocks > 0) {
1651
printf("Blocks total: %ld Blocks current: %ld Blocks remaining: %ld\n",
1653
dsp->ds_maxblocks - startsec,
1654
dsp->ds_maxblocks - endsec);
1656
if (endsec > dsp->ds_maxblocks) {
1658
"WARNING: Data may not fit on current disk.\n");
1660
/* XXX Check for flags & CDR_NO_LOLIMIT */
1663
if (lverbose && dsp->ds_maxrblocks > 0)
1664
printf("RBlocks total: %ld RBlocks current: %ld RBlocks remaining: %ld\n",
1666
dsp->ds_maxrblocks - startsec,
1667
dsp->ds_maxrblocks - endsec);
1668
if (dsp->ds_maxrblocks > 0 && endsec > dsp->ds_maxrblocks) {
1670
"Data does not fit on current disk.\n");
1673
if ((endsec > 404700) ||
1674
(dsp->ds_maxrblocks > 404700 && 449850 > dsp->ds_maxrblocks)) {
1676
* Assume that this must be a CD and not a DVD.
1677
* So this is a non Red Book compliant CD with a
1678
* capacity between 90 and 99 minutes.
1680
if (dsp->ds_maxrblocks > 404700)
1681
printf("RedBook total: %ld RedBook current: %ld RedBook remaining: %ld\n",
1685
if (endsec > 404700) {
1686
if ((flags & (F_IGNSIZE|F_FORCE)) == 0)
1688
"Notice: Most recorders cannot write CD's >= 90 minutes.\n");
1690
"Notice: Use -ignsize option to allow >= 90 minutes.\n");
1695
if (endsec >= (405000-300)) { /*<90 min disk*/
1697
"Data will not fit on any disk.\n");
1699
} else if (endsec >= (333000-150)) { /* 74 min disk*/
1701
"WARNING: Data may not fit on standard 74min disk.\n");
1706
if (dsp->ds_maxblocks < 449850) {
1708
* Assume that this must be a CD and not a DVD.
1710
if (endsec > 449700) {
1711
errmsgno(EX_BAD, "Cannot write CD's >= 100 minutes.\n");
1715
if ((flags & (F_IGNSIZE|F_FORCE)) != 0)
1723
#ifdef RLIMIT_NOFILE
1728
* Set max # of file descriptors to be able to hold all files open
1730
getrlimit(RLIMIT_NOFILE, &rlim);
1731
rlim.rlim_cur = MAX_TRACK + 10;
1732
if (rlim.rlim_cur > rlim.rlim_max)
1734
"warning: low file descriptor limit (%lld)\n",
1735
(Llong)rlim.rlim_max);
1736
setrlimit(RLIMIT_NOFILE, &rlim);
1738
#endif /* RLIMIT_NOFILE */
1742
"help,version,checkdrive,prcap,inq,scanbus,reset,ignsize,useinfo,dev*,timeout#,driver*,driveropts*,tsize&,padsize&,pregap&,defpregap&,speed#,load,eject,dummy,msinfo,toc,atip,multi,fix,nofix,waiti,debug#,d+,kdebug#,kd#,verbose+,v+,Verbose+,V+,silent,s,audio,data,mode2,xa1,xa2,cdi,isosize,nopreemp,preemp,nopad,pad,swab,fs&,blank&,pktsize#,packet,noclose,force,dao,scms,isrc*,mcn*,index*,shorttrack,noshorttrack";
1745
gargs(ac, av, tracksp, trackp, devp, timeoutp, dpp, speedp, flagsp, toctypep, blankp)
1760
char *driver = NULL;
1764
char *tindex = NULL;
1769
long defpregap = -1L;
1813
int tracks = *tracksp;
1814
int tracktype = TOC_ROM;
1815
int sectype = ST_ROM_MODE1;
1816
int dbtype = DB_ROM_MODE1;
1819
trackp[0].flags |= TI_TAO;
1820
trackp[1].pregapsize = -1;
1825
for (;; cac--, cav++) {
1826
tracksize = (Llong)-1L;
1827
padsize = (Llong)0L;
1828
pregapsize = defpregap;
1829
audio = data = mode2 = xa1 = xa2 = cdi = 0;
1830
isize = nopreemp = nopad = noshorttrack = 0;
1834
if (getargs(&cac, &cav, opts,
1835
&help, &version, &checkdrive, &prcap,
1836
&inq, &scanbus, &reset, &ignsize,
1838
devp, timeoutp, &driver, &driveropts,
1839
getllnum, &tracksize,
1841
getnum, &pregapsize,
1844
&load, &eject, &dummy, &msinfo, &toc, &atip,
1845
&multi, &fix, &nofix, &waiti,
1848
&lverbose, &lverbose,
1849
&scsi_verbose, &scsi_verbose,
1851
&audio, &data, &mode2,
1855
&nopad, &pad, &bswab, getnum, &fs,
1856
getbltype, &bltype, &pktsize,
1857
&ispacket, &noclose, &force,
1859
&isrc, &mcn, &tindex,
1860
&shorttrack, &noshorttrack) < 0) {
1861
errmsgno(EX_BAD, "Bad Option: %s.\n", cav[0]);
1868
set_cdrcmds(driver, dpp);
1870
*flagsp |= F_VERSION;
1872
*flagsp |= F_CHECKDRIVE;
1876
*flagsp |= F_INQUIRY;
1878
*flagsp |= F_SCANBUS;
1882
*flagsp |= F_IGNSIZE;
1890
*flagsp |= F_MSINFO;
1893
*flagsp &= ~F_WRITE;
1896
*flagsp |= F_PRATIP;
1897
*flagsp &= ~F_WRITE;
1901
tracktype = TOC_XA2;
1902
sectype = ST_ROM_MODE2;
1903
dbtype = DB_XA_MODE2; /* XXX -multi nimmt DB_XA_MODE2_F1 !!! */
1920
trackp[0].flags &= ~TI_TAO;
1924
setmcn(mcn, &trackp[0]);
1926
trackp[0].isrc = malloc(16);
1927
fillbytes(trackp[0].isrc, 16, '\0');
1928
strncpy(trackp[0].isrc, mcn, 13);
1932
version = checkdrive = prcap = inq = scanbus = reset = ignsize =
1933
load = eject = dummy = msinfo = toc = atip = multi = fix = nofix =
1934
waiti = force = dao = 0;
1935
} else if ((version + checkdrive + prcap + inq + scanbus + reset + ignsize +
1936
load + eject + dummy + msinfo + toc + atip + multi + fix + nofix +
1937
waiti + force + dao) > 0 ||
1939
comerrno(EX_BAD, "Badly placed option. Global options must be before any track.\n");
1948
if ((audio + data + mode2 + xa1 + xa2 + cdi) > 1) {
1949
errmsgno(EX_BAD, "Too many types for track %d.\n", tracks+1);
1950
comerrno(EX_BAD, "Only one of -audio, -data, -mode2, -xa1, -xa2, -cdi allowed.\n");
1952
if (ispacket && audio) {
1953
comerrno(EX_BAD, "Audio data cannot be written in packet mode.\n");
1955
got_track = getfiles(&cac, &cav, opts);
1958
tracktype = TOC_ROM;
1959
sectype = ST_ROM_MODE1;
1960
dbtype = DB_ROM_MODE1;
1962
if (got_track != 0 && (is_auname(cav[0]) || is_wavname(cav[0]))) {
1967
tracktype = TOC_ROM;
1968
sectype = ST_ROM_MODE1;
1969
dbtype = DB_ROM_MODE1;
1972
tracktype = TOC_ROM;
1973
sectype = ST_ROM_MODE2;
1974
dbtype = DB_ROM_MODE2;
1978
sectype = preemp ? ST_AUDIO_PRE : ST_AUDIO_NOPRE;
1982
tracktype = TOC_XA1;
1983
sectype = ST_ROM_MODE1;
1984
dbtype = DB_XA_MODE1;
1987
tracktype = TOC_XA2;
1988
sectype = ST_ROM_MODE2;
1989
dbtype = DB_XA_MODE2_F1; /* XXX Das unterscheidet sich von -multi !!! */
1992
tracktype = TOC_CDI;
1993
sectype = ST_ROM_MODE2;
1994
dbtype = DB_XA_MODE2_F1;
1997
*toctypep = tracktype;
2000
if ((sectype & ST_AUDIOMASK) != 0)
2003
flags |= TI_ISOSIZE;
2004
if ((*flagsp & F_MULTI) != 0)
2005
comerrno(EX_BAD, "Cannot get isosize for multi session disks.\n");
2012
if ((flags & TI_AUDIO) == 0 && padsize > (Llong)0L)
2016
if ((flags & TI_AUDIO) == 0 && padsize == (Llong)0L)
2017
padsize = (Llong)PAD_SIZE;
2019
if (shorttrack && (*flagsp & F_SAO) != 0)
2020
flags |= TI_SHORT_TRACK;
2022
flags &= ~TI_SHORT_TRACK;
2028
flags |= TI_NOCLOSE;
2030
if ((*flagsp & F_SAO) == 0)
2037
if (tracks > MAX_TRACK)
2038
comerrno(EX_BAD, "Track limit (%d) exceeded\n",
2041
if (strcmp("-", cav[0]) == 0) {
2042
trackp[tracks].f = STDIN_FILENO;
2044
#if defined(__CYGWIN32__) || defined(__EMX__)
2045
setmode(STDIN_FILENO, O_BINARY);
2048
if (access(cav[0], R_OK) < 0)
2049
comerr("No read access for '%s'.\n", cav[0]);
2051
if ((trackp[tracks].f = open(cav[0], O_RDONLY|O_BINARY)) < 0)
2052
comerr("Cannot open '%s'.\n", cav[0]);
2054
if (!is_auname(cav[0]) && !is_wavname(cav[0]))
2055
flags |= TI_NOAUHDR;
2057
if ((*flagsp & F_SAO) != 0 && (flags & TI_AUDIO) != 0)
2058
flags |= TI_PREGAP; /* Hack for now */
2060
flags &= ~TI_PREGAP;
2062
if (tracks == 1 && (pregapsize != -1L && pregapsize != 150))
2064
secsize = tracktype == TOC_DA ? AUDIO_SEC_SIZE : DATA_SEC_SIZE;
2065
trackp[tracks].filename = cav[0];;
2066
trackp[tracks].trackstart = 0L;
2067
trackp[tracks].tracksize = tracksize;
2068
if (trackp[tracks].pregapsize < 0)
2069
trackp[tracks].pregapsize = pregapsize;
2070
trackp[tracks+1].pregapsize = -1;
2071
trackp[tracks].padsize = padsize;
2072
trackp[tracks].secsize = secsize;
2073
trackp[tracks].secspt = 0; /* transfer size is set up in set_trsizes() */
2074
trackp[tracks].pktsize = pktsize;
2075
trackp[tracks].trackno = tracks;
2076
trackp[tracks].sectype = sectype;
2077
trackp[tracks].tracktype = tracktype;
2078
trackp[tracks].dbtype = dbtype;
2079
trackp[tracks].flags = flags;
2080
trackp[tracks].nindex = 1;
2081
trackp[tracks].tindex = 0;
2082
checksize(&trackp[tracks]);
2083
tracksize = trackp[tracks].tracksize;
2084
if (!is_shorttrk(&trackp[tracks]) &&
2085
tracksize > 0 && (tracksize / secsize) < 300) {
2086
tracksize = roundup(tracksize, secsize);
2087
padsize = tracksize + roundup(padsize, secsize);
2088
if ((padsize / secsize) < 300) {
2089
trackp[tracks].padsize =
2090
300 * secsize - tracksize;
2095
auinfo(cav[0], tracks, trackp);
2097
printf("pregap1: %ld\n", trackp[1].pregapsize);
2102
setisrc(isrc, &trackp[tracks]);
2104
trackp[tracks].isrc = malloc(16);
2105
fillbytes(trackp[tracks].isrc, 16, '\0');
2106
strncpy(trackp[tracks].isrc, isrc, 12);
2111
setindex(tindex, &trackp[tracks]);
2116
printf("File: '%s' tracksize: %lld secsize: %d tracktype: %d = %s sectype: %X = %s dbtype: %s flags %X\n",
2117
cav[0], (Llong)trackp[tracks].tracksize,
2118
trackp[tracks].secsize,
2119
tracktype, toc2name[tracktype & TOC_MASK],
2120
sectype, st2name[sectype & ST_MASK], db2name[dbtype], flags);
2124
if (speed < 0 && speed != -1)
2125
comerrno(EX_BAD, "Bad speed option.\n");
2127
if (fs < 0L && fs != -1L)
2128
comerrno(EX_BAD, "Bad fifo size option.\n");
2131
cdr_defaults(&dev, &speed, &fs);
2133
printf("dev: %s speed: %d fs: %ld\n", dev, speed, fs);
2139
fs = DEFAULT_FIFOSIZE;
2141
if (dev != *devp && (*flagsp & F_SCANBUS) == 0)
2144
if (!*devp && (*flagsp & (F_VERSION|F_SCANBUS)) == 0) {
2145
errmsgno(EX_BAD, "No CD/DVD-Recorder device specified.\n");
2148
if (*flagsp & (F_LOAD|F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_PRCAP|F_INQUIRY|F_SCANBUS|F_RESET)) {
2150
errmsgno(EX_BAD, "No tracks allowed with this option\n");
2155
if (tracks == 0 && (*flagsp & (F_LOAD|F_EJECT|F_BLANK)) == 0) {
2156
errmsgno(EX_BAD, "No tracks specified. Need at least one.\n");
2160
if (*flagsp & F_SAO) {
2162
* Make sure that you change WRITER_MAXWAIT & READER_MAXWAIT
2163
* too if you change this timeout.
2165
if (*timeoutp < 200) /* Lead in size is 2:30 */
2166
*timeoutp = 200; /* 200s is 150s *1.33 */
2171
set_trsizes(dp, tracks, trackp)
2179
* We are using SCSI Group 0 write
2180
* and cannot write more than 255 secs at once.
2182
data_secs_per_tr = bufsize/DATA_SEC_SIZE;
2183
audio_secs_per_tr = bufsize/AUDIO_SEC_SIZE;
2184
data_secs_per_tr = min(255, data_secs_per_tr);
2185
audio_secs_per_tr = min(255, audio_secs_per_tr);
2187
trackp[1].flags |= TI_FIRST;
2188
trackp[tracks].flags |= TI_LAST;
2190
for (i = 1; i <= tracks; i++) {
2192
is_audio(&trackp[i]) ?
2195
if (is_packet(&trackp[i]) && trackp[i].pktsize > 0) {
2196
if (trackp[i].secspt >= trackp[i].pktsize) {
2197
trackp[i].secspt = trackp[i].pktsize;
2200
"Track %d packet size %d exceeds buffer limit of %d sectors",
2201
i, trackp[i].pktsize, trackp[i].secspt);
2204
if ((dp->cdr_flags & CDR_SWABAUDIO) != 0 &&
2205
is_audio(&trackp[i])) {
2206
trackp[i].flags ^= TI_SWAB;
2212
load_media(scgp, dp, doexit)
2221
* Do some preparation before...
2223
scgp->silent++; /* Be quiet if this fails */
2224
test_unit_ready(scgp); /* First eat up unit attention */
2225
(*dp->cdr_load)(scgp); /* now try to load media and */
2226
scsi_start_stop_unit(scgp, 1, 0);/* start unit in silent mode */
2229
if (!wait_unit_ready(scgp, 60)) {
2230
code = scg_sense_code(scgp);
2231
key = scg_sense_key(scgp);
2233
scsi_prevent_removal(scgp, 0);/* In case someone locked it */
2238
if (key == SC_NOT_READY && (code == 0x3A || code == 0x30))
2239
comerrno(EX_BAD, "No disk / Wrong disk!\n");
2240
comerrno(EX_BAD, "CD/DVD-Recorder not ready.\n");
2243
scsi_prevent_removal(scgp, 1);
2244
scsi_start_stop_unit(scgp, 1, 0);
2245
wait_unit_ready(scgp, 120);
2247
rezero_unit(scgp); /* Is this needed? Not supported by some drvives */
2249
test_unit_ready(scgp);
2250
scsi_start_stop_unit(scgp, 1, 0);
2251
wait_unit_ready(scgp, 120);
2255
unload_media(scgp, dp, flags)
2260
scsi_prevent_removal(scgp, 0);
2261
if ((flags & F_EJECT) != 0)
2262
(*dp->cdr_unload)(scgp);
2266
set_secsize(scgp, secsize)
2272
* Try to restore the old sector size.
2275
select_secsize(scgp, secsize);
2281
check_recovery(scgp, dp, flags)
2286
if ((*dp->cdr_check_recovery)(scgp)) {
2287
errmsgno(EX_BAD, "Recovery needed.\n");
2288
unload_media(scgp, dp, flags);
2289
excdr(EX_BAD, NULL); /* XXX &exargs ??? */
2295
void audioread(scgp, dp, flags)
2304
if ((*dp->cdr_set_speed_dummy)(scgp, &speed, dummy) < 0)
2306
if ((*dp->cdr_set_secsize)(scgp, 2352) < 0)
2308
scgp->cap->c_bsize = 2352;
2310
read_scsi(scgp, buf, 1000, 1);
2313
unload_media(scgp, dp, flags);
2314
excdr(0, NULL); /* XXX &exargs ??? */
2320
print_msinfo(scgp, dp)
2327
if ((*dp->cdr_session_offset)(scgp, &off) < 0) {
2328
errmsgno(EX_BAD, "Cannot read session offset\n");
2332
printf("session offset: %ld\n", off);
2334
if (dp->cdr_next_wr_address(scgp, 0, (track_t *)0, &fa) < 0) {
2335
errmsgno(EX_BAD, "Cannot read first writable address\n");
2338
printf("%ld,%ld\n", off, fa);
2357
if (read_capacity(scgp) < 0) {
2359
errmsgno(EX_BAD, "Cannot read capacity\n");
2363
if (read_tochdr(scgp, dp, &first, &last) < 0) {
2364
errmsgno(EX_BAD, "Cannot read TOC/PMA\n");
2367
printf("first: %d last %d\n", first, last);
2368
for (i = first; i <= last; i++) {
2369
read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
2371
msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
2374
print_track(i, lba, &msf, adr, control, mode);
2377
read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
2379
msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
2382
print_track(i, lba, &msf, adr, control, mode);
2385
if (read_cdtext(scgp) < 0)
2386
errmsgno(EX_BAD, "No CD-Text or CD-Text unaware drive.\n");
2392
print_track(track, lba, msp, adr, control, mode)
2400
long lba_512 = lba*4;
2403
printf("track:lout ");
2405
printf("track: %3d ", track);
2407
printf("lba: %9ld (%9ld) %02d:%02d:%02d adr: %X control: %X mode: %d\n",
2412
adr, control, mode);
2416
prtimediff(fmt, start, stop)
2418
struct timeval *start;
2419
struct timeval *stop;
2423
tv.tv_sec = stop->tv_sec - start->tv_sec;
2424
tv.tv_usec = stop->tv_usec - start->tv_usec;
2425
while (tv.tv_usec > 1000000) {
2426
tv.tv_usec -= 1000000;
2429
while (tv.tv_usec < 0) {
2430
tv.tv_usec += 1000000;
2434
* We need to cast timeval->* to long because
2435
* of the broken sys/time.h in Linux.
2437
printf("%s%4ld.%03lds\n", fmt, (long)tv.tv_sec, (long)tv.tv_usec/1000);
2441
#ifdef HAVE_SYS_PRIOCNTL_H
2443
#include <sys/procset.h> /* Needed for SCO Openserver */
2444
#include <sys/priocntl.h>
2445
#include <sys/rtpriocntl.h>
2462
strcpy(info.pc_clname, "RT");
2463
classes = priocntl(P_PID, pid, PC_GETCID, (void *)&info);
2465
comerr("Cannot get priority class id priocntl(PC_GETCID)\n");
2467
movebytes(info.pc_clinfo, &rtinfo, sizeof(rtinfo_t));
2469
/* set priority to max */
2470
rtparam.rt_pri = rtinfo.rt_maxpri - pri;
2471
rtparam.rt_tqsecs = 0;
2472
rtparam.rt_tqnsecs = RT_TQDEF;
2473
param.pc_cid = info.pc_cid;
2474
movebytes(&rtparam, param.pc_clparms, sizeof(rtparms_t));
2475
ret = priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m);
2477
errmsg("WARNING: Cannot set priority class parameters priocntl(PC_SETPARMS)\n");
2478
errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
2482
#else /* HAVE_SYS_PRIOCNTL_H */
2484
#if defined(_POSIX_PRIORITY_SCHEDULING)
2486
* XXX Ugly but needed because of a typo in /usr/iclude/sched.h on Linux.
2487
* XXX This should be removed as soon as we are sure that Linux-2.0.29 is gone.
2503
struct sched_param scp;
2506
* Verify that scheduling is available
2508
#ifdef _SC_PRIORITY_SCHEDULING
2509
if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) {
2510
errmsg("WARNING: RR-scheduler not available, disabling.\n");
2514
fillbytes(&scp, sizeof(scp), '\0');
2515
scp.sched_priority = sched_get_priority_max(SCHED_RR) - pri;
2516
if (sched_setscheduler(0, SCHED_RR, &scp) < 0) {
2517
errmsg("WARNING: Cannot set RR-scheduler\n");
2523
#else /* _POSIX_PRIORITY_SCHEDULING */
2528
* NOTE: Base.h from Cygwin-B20 has a second typedef for BOOL.
2529
* We define BOOL to make all local code use BOOL
2530
* from Windows.h and use the hidden __SBOOL for
2531
* our global interfaces.
2533
* NOTE: windows.h from Cygwin-1.x includes a structure field named sample,
2534
* so me may not define our own 'sample' or need to #undef it now.
2535
* With a few nasty exceptions, Microsoft assumes that any global
2536
* defines or identifiers will begin with an Uppercase letter, so
2537
* there may be more of these problems in the future.
2539
* NOTE: windows.h defines interface as an alias for struct, this
2540
* is used by COM/OLE2, I guess it is class on C++
2541
* We man need to #undef 'interface'
2543
#define BOOL WBOOL /* This is the Win BOOL */
2544
#define format __format /* Avoid format parameter hides global ... */
2545
#include <windows.h>
2553
/* set priority class */
2554
if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) {
2555
errmsgno(EX_BAD, "No realtime priority class possible.\n");
2559
/* set thread priority */
2560
if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL-pri) == FALSE) {
2561
errmsgno(EX_BAD, "Could not set realtime priority.\n");
2576
#endif /* __CYGWIN32__ */
2578
#endif /* _POSIX_PRIORITY_SCHEDULING */
2584
if (rt_raisepri(pri) >= 0)
2586
#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
2588
if (setpriority(PRIO_PROCESS, getpid(), -20 + pri) < 0) {
2589
errmsg("WARNING: Cannot set priority using setpriority().\n");
2590
errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
2593
#ifdef HAVE_DOSSETPRIORITY /* RT priority on OS/2 */
2595
* Set priority to timecritical 31 - pri (arg)
2597
DosSetPriority(0, 3, 31, 0);
2598
DosSetPriority(0, 3, -pri, 0);
2601
if (nice(-20 + pri) == -1) {
2602
errmsg("WARNING: Cannot set priority using nice().\n");
2603
errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
2606
errmsgno(EX_BAD, "WARNING: Cannot set priority on this OS.\n");
2607
errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
2613
#endif /* HAVE_SYS_PRIOCNTL_H */
2617
* sys/types.h and sys/time.h are already included.
2620
# include <stropts.h>
2628
#if defined(HAVE_SELECT) && defined(NEED_SYS_SELECT_H)
2629
#include <sys/select.h>
2639
FD_SET(STDIN_FILENO, &in);
2640
select(1, &in, NULL, NULL, 0);
2644
pfd.fd = STDIN_FILENO;
2645
pfd.events = POLLIN;
2647
poll(&pfd, (unsigned long)1, INFTIM);
2656
if (fstat(STDERR_FILENO, &st) >= 0 && !S_ISCHR(st.st_mode)) {
2659
printf("Using remote (pipe) mode for interactive i/o.\n");
2674
} else if (*(arg = astoll(arg, &val))) {
2675
if (*arg == 'p' || *arg == 'P') {
2677
val *= (1024*1024*1024);
2680
if (*arg == 't' || *arg == 'T') {
2685
if (*arg == 'g' || *arg == 'G') {
2686
val *= (1024*1024*1024);
2689
if (*arg == 'm' || *arg == 'M') {
2693
else if (*arg == 'f' || *arg == 'F') {
2697
else if (*arg == 's' || *arg == 'S') {
2701
else if (*arg == 'k' || *arg == 'K') {
2705
else if (*arg == 'b' || *arg == 'B') {
2709
else if (*arg == 'w' || *arg == 'W') {
2713
if (*arg == '*' || *arg == 'x')
2714
val *= number(++arg, retp);
2715
else if (*arg != '\0')
2728
*valp = (long)number(arg, &ret);
2733
getllnum(arg, lvalp)
2739
*lvalp = number(arg, &ret);
2744
getbltype(optstr, typep)
2748
if (streql(optstr, "all")) {
2749
*typep = BLANK_DISC;
2750
} else if (streql(optstr, "disc")) {
2751
*typep = BLANK_DISC;
2752
} else if (streql(optstr, "disk")) {
2753
*typep = BLANK_DISC;
2754
} else if (streql(optstr, "fast")) {
2755
*typep = BLANK_MINIMAL;
2756
} else if (streql(optstr, "minimal")) {
2757
*typep = BLANK_MINIMAL;
2758
} else if (streql(optstr, "track")) {
2759
*typep = BLANK_TRACK;
2760
} else if (streql(optstr, "unreserve")) {
2761
*typep = BLANK_UNRESERVE;
2762
} else if (streql(optstr, "trtail")) {
2763
*typep = BLANK_TAIL;
2764
} else if (streql(optstr, "unclose")) {
2765
*typep = BLANK_UNCLOSE;
2766
} else if (streql(optstr, "session")) {
2767
*typep = BLANK_SESSION;
2768
} else if (streql(optstr, "help")) {
2771
error("Illegal blanking type '%s'.\n", optstr);