2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
15 * Modified by Eduard Bloch in 08/2006 and later
18 /* @(#)cdrecord.c 1.310 06/02/09 Copyright 1995-2006 J. Schilling */
20 * Record data on a CD/CVD-Recorder
22 * Copyright (c) 1995-2006 J. Schilling
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License version 2
27 * as published by the Free Software Foundation.
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * You should have received a copy of the GNU General Public License along with
35 * this program; see the file COPYING. If not, write to the Free Software
36 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
46 #ifdef HAVE_SYS_RESOURCE_H
47 #include <sys/resource.h> /* for rlimit */
51 #ifdef HAVE_SYS_MMAN_H
67 #include <usal/scsireg.h> /* XXX wegen SC_NOT_READY */
68 #include <usal/scsitransp.h>
69 #include <usal/usalcmd.h> /* XXX fuer read_buffer */
70 #include "scsi_scan.h"
78 #include <sys/capability.h> /* for rawio capability */
81 #if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0
82 #ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */
84 #define USE_POSIX_PRIORITY_SCHEDULING
89 * Map toc/track types into names.
103 * Map sector types into names.
106 "Illegal sector type 0",
109 "Illegal sector type 3",
110 "CD-DA without preemphasis",
111 "CD-DA with preemphasis",
112 "Illegal sector type 6",
113 "Illegal sector type 7",
117 * Map data block types into names.
121 "Raw (audio) with P/Q sub channel",
122 "Raw (audio) with P/W packed sub channel",
123 "Raw (audio) with P/W raw sub channel",
127 "Vendor unique mode 7",
130 "CD-ROM XA mode 2 form 1",
131 "CD-ROM XA mode 2 form 1 (with subheader)",
132 "CD-ROM XA mode 2 form 2",
133 "CD-ROM XA mode 2 form 1/2/mix",
135 "Vendor unique mode 15",
139 * Map write modes into names.
141 static char wm_none[] = "unknown";
142 static char wm_ill[] = "illegal";
158 "SAO/RAW16", /* Most liklely not needed */
167 int debug; /* print debug messages */
168 static int kdebug; /* print kernel debug messages */
169 static int scsi_verbose; /* SCSI verbose flag */
170 static int silent; /* SCSI silent flag */
171 int lverbose; /* static verbose flag */
172 int xdebug; /* extended debug flag */
174 char *buf; /* The transfer buffer */
175 long bufsize = -1; /* The size of the transfer buffer */
177 static int gracetime = GRACE_TIME;
178 static int raw_speed = -1;
179 static int dma_speed = -1;
180 static int dminbuf = -1; /* XXX Hack for now drive min buf fill */
184 static char *cuefilename = NULL;
185 static uid_t oeuid = (uid_t)-1;
187 struct timeval starttime;
188 struct timeval wstarttime;
189 struct timeval stoptime;
190 struct timeval fixtime;
192 static long fs = -1; /* fifo (ring buffer) size */
193 static Llong warn_minisize = -1L;
195 static int gracewait(cdr_t *dp, BOOL *didgracep);
196 static void cdrstats(cdr_t *dp);
197 static void susage(int);
198 static void usage(int);
199 static void blusage(int);
200 static void formattypeusage(int);
201 static void intr(int sig);
202 static void catchsig(int sig);
203 static int scsi_cb(void *arg);
204 static void intfifo(int sig);
205 static void exscsi(int excode, void *arg);
206 static void excdr(int excode, void *arg);
207 int read_buf(int f, char *bp, int size);
208 int fill_buf(int f, track_t *trackp, long secno, char *bp, int size);
209 int get_buf(int f, track_t *trackp, long secno, char **bpp, int size);
210 int write_secs(SCSI *usalp, cdr_t *dp, char *bp, long startsec, int bytespt,
211 int secspt, BOOL islast);
212 static int write_track_data(SCSI *usalp, cdr_t *, track_t *);
213 int pad_track(SCSI *usalp, cdr_t *dp, track_t *trackp, long startsec,
214 Llong amt, BOOL dolast, Llong *bytesp);
215 int write_buf(SCSI *usalp, cdr_t *dp, track_t *trackp, char *bp,
216 long startsec, Llong amt, int secsize, BOOL dolast,
218 static void printdata(int, track_t *);
219 static void printaudio(int, track_t *);
220 static void checkfile(int, track_t *);
221 static int checkfiles(int, track_t *);
222 static void setleadinout(int, track_t *);
223 static void setpregaps(int, track_t *);
224 static long checktsize(int, track_t *);
225 static void opentracks(track_t *);
226 static void checksize(track_t *);
227 static BOOL checkdsize(SCSI *usalp, cdr_t *dp, long tsize, int flags);
228 static void raise_fdlim(void);
229 static void raise_memlock(void);
230 static int gargs(int, char **, int *, track_t *, char **, int *, cdr_t **,
231 int *, long *, int *, int *);
232 static void set_trsizes(cdr_t *, int, track_t *);
233 void load_media(SCSI *usalp, cdr_t *, BOOL);
234 void unload_media(SCSI *usalp, cdr_t *, int);
235 void reload_media(SCSI *usalp, cdr_t *);
236 void set_secsize(SCSI *usalp, int secsize);
237 static int get_dmaspeed(SCSI *usalp, cdr_t *);
238 static BOOL do_opc(SCSI *usalp, cdr_t *, int);
239 static void check_recovery(SCSI *usalp, cdr_t *, int);
240 void audioread(SCSI *usalp, cdr_t *, int);
241 static void print_msinfo(SCSI *usalp, cdr_t *);
242 static void print_toc(SCSI *usalp, cdr_t *);
243 static void print_track(int, long, struct msf *, int, int, int);
244 #if !defined(HAVE_SYS_PRIOCNTL_H)
245 static int rt_raisepri(int);
248 static void wait_input(void);
249 static void checkgui(void);
250 static int getbltype(char *optstr, long *typep);
251 static int getformattype(char *optstr, long *typep);
252 static void print_drflags(cdr_t *dp);
253 static void print_wrmodes(cdr_t *dp);
254 static BOOL check_wrmode(cdr_t *dp, int wmode, int tflags);
255 static void set_wrmode(cdr_t *dp, int wmode, int tflags);
256 static void linuxcheck(void);
259 static int get_cap(cap_value_t cap_array);
270 void fifo_cleanup(void) {
274 /* shared variables */
276 char *msifile = NULL;
278 int main(int argc, char *argv[])
281 int timeout = 40; /* Set default timeout to 40s CW-7502 is slow*/
290 track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */
291 cdr_t *dp = (cdr_t *)0;
296 BOOL gracedone = FALSE;
298 BOOL is_cdwr = FALSE;
299 BOOL is_dvdwr = FALSE;
301 buf=strstr(argv[0], "cdrecord");
302 if(buf && '\0' == buf[8]) /* lame cheater detected */
306 /* This gives wildcard expansion with Non-Posix shells with EMX */
307 _wildcard(&argc, &argv);
309 save_args(argc, argv);
310 oeuid = geteuid(); /* Remember saved set uid */
312 fillbytes(track, sizeof (track), '\0');
313 for (i = 0; i < MAX_TRACK+2; i++)
314 track[i].track = track[i].trackno = i;
315 track[0].tracktype = TOC_MASK;
317 ispacket = gargs(argc, argv, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
318 &blanktype, &formattype);
319 if ((track[0].tracktype & TOC_MASK) == TOC_MASK)
320 comerrno(EX_BAD, "Internal error: Bad TOC type.\n");
322 if (flags & F_VERSION) {
324 "Cdrecord-yelling-line-to-tell-frontends-to-use-it-like-version 2.01.01a03-dvd \n"
325 "Wodim " CDRKIT_VERSION "\n"
326 "Copyright (C) 2006 Cdrkit suite contributors\n"
327 "Based on works from Joerg Schilling, Copyright (C) 1995-2006, J. Schilling\n"
334 if (debug || lverbose) {
335 printf("TOC Type: %d = %s\n",
336 track[0].tracktype & TOC_MASK,
337 toc2name[track[0].tracktype & TOC_MASK]);
340 if ((flags & (F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_INQUIRY|F_SCANBUS|F_RESET)) == 0) {
342 * Try to lock us im memory (will only work for root)
343 * but you need access to root anyway to send SCSI commands.
344 * We need to be root to open /dev/usal? or similar devices
345 * on other OS variants and we need to be root to be able
346 * to send SCSI commands at least on AIX and
347 * Solaris (USCSI only) regardless of the permissions for
350 * XXX The following test used to be
351 * XXX #if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK)
352 * XXX but the definition for _POSIX_MEMLOCK did change during
353 * XXX the last 8 years and the autoconf test is better for
354 * XXX the static case. sysconf() only makes sense if we like
355 * XXX to check dynamically.
358 #if defined(HAVE_MLOCKALL)
360 * XXX mlockall() needs root privilleges.
362 if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
365 "W: Cannot do mlockall(2). Possibly increased risk for buffer underruns.\n");
370 * XXX raisepri() needs root privilleges.
372 raisepri(0); /* max priority */
374 * XXX shmctl(id, SHM_LOCK, 0) needs root privilleges.
375 * XXX So if we use SysV shared memory, wee need to be root.
377 * Note that not being able to set up a FIFO bombs us
378 * back to the DOS ages. Trying to run cdrecord without
379 * root privillegs is extremely silly, it breaks most
380 * of the advanced features. We need to be at least installed
381 * suid root or called by RBACs pfexec.
383 init_fifo(fs); /* Attach shared memory (still one process) */
386 if ((flags & F_WAITI) != 0) {
388 printf("Waiting for data on stdin...\n");
393 * Call usal_remote() to force loading the remote SCSI transport library
394 * code that is located in librusal instead of the dummy remote routines
395 * that are located inside libusal.
399 ((strncmp(dev, "HELP", 4) == 0) ||
400 (strncmp(dev, "help", 4) == 0))) {
405 if( (!dev || *dev=='\0'|| 0==strcmp(dev, "-1")) && (flags & F_SCANBUS)==0 ) {
406 int64_t need_size=0L;
410 fprintf(stderr, "Device was not specified. Trying to find an appropriate drive...\n");
412 /* estimate how much data user wants to write */
413 for(t=1;t<=tracks;t++) {
414 if(track[t].tracksize>=0)
415 need_size+=track[t].tracksize;
416 else if(0==stat(track[t].filename, &statbuf))
417 need_size+=statbuf.st_size;
419 usalp=open_auto(need_size, debug, lverbose);
423 usalp = usal_open(dev, errstr, sizeof(errstr), debug, lverbose);
427 errmsg("\nCannot open SCSI driver!\n"
428 "For possible targets try 'wodim --devices' or 'wodim -scanbus'.\n"
429 "For possible transport specifiers try 'wodim dev=help'.\n"
430 "For IDE/ATAPI devices configuration, see the file README.ATAPI.setup from\n"
431 "the wodim documentation.\n");
437 fprintf(stderr, "file_dac_read: %d\n", priv_ineffect(PRIV_FILE_DAC_READ));
440 * Give up privs we do not need anymore.
442 * file_dac_read,proc_lock_memory,proc_priocntl,net_privaddr
446 priv_set(PRIV_OFF, PRIV_EFFECTIVE,
447 PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
448 PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL);
449 priv_set(PRIV_OFF, PRIV_PERMITTED,
450 PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
451 PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL);
452 priv_set(PRIV_OFF, PRIV_INHERITABLE,
453 PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
454 PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL);
457 * This is only for OS that do not support fine grained privs.
459 * XXX Below this point we do not need root privilleges anymore.
461 if (geteuid() != getuid()) { /* AIX does not like to do this */
462 /* If we are not root */
464 if (setreuid(-1, getuid()) < 0)
467 if (seteuid(getuid()) < 0)
469 if (setuid(getuid()) < 0)
472 comerr("Panic cannot set back effective uid.\n");
476 /* get the rawio capability */
477 if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose>2))
479 perror("Warning: Cannot gain SYS_RAWIO capability");
480 fprintf(stderr, "Possible reason: wodim not installed SUID root.\n");
485 * WARNING: We now are no more able to do any privilleged operation
486 * unless we have been called by root.
488 * XXX It may be that we later get problems in init_faio() because
489 * XXX this function calls raisepri() to lower the priority slightly.
491 usal_settimeout(usalp, timeout);
492 usalp->verbose = scsi_verbose;
493 usalp->silent = silent;
494 usalp->debug = debug;
495 usalp->kdebug = kdebug;
496 usalp->cap->c_bsize = DATA_SEC_SIZE;
498 if ((flags & F_MSINFO) == 0 || lverbose) {
504 fprintf(stderr, "Wodim version: " CDRKIT_VERSION "\n");
506 vers = usal_version(0, SCG_VERSION);
507 auth = usal_version(0, SCG_AUTHOR);
508 if(lverbose >1 && auth && vers)
509 fprintf(stderr, "Using libusal version '%s-%s'.\n", auth, vers);
512 vers = usal_version(usalp, SCG_RVERSION);
513 auth = usal_version(usalp, SCG_RAUTHOR);
514 if (lverbose > 1 && vers && auth)
515 fprintf(stderr, "Using remote transport code version '%s-%s'\n", auth, vers);
518 if (lverbose && driveropts)
519 printf("Driveropts: '%s'\n", driveropts);
521 /* bufsize = usal_bufsize(usalp, CDR_BUF_SIZE);*/
522 bufsize = usal_bufsize(usalp, bufsize);
523 if (lverbose || debug)
524 fprintf(stderr, "SCSI buffer size: %ld\n", bufsize);
525 if ((buf = usal_getbuf(usalp, bufsize)) == NULL)
526 comerr("Cannot get SCSI I/O buffer.\n");
529 return (list_devices(usalp, stdout, 0));
531 if ((flags & F_SCANBUS) != 0) {
532 select_target(usalp, stdout);
535 if ((flags & F_RESET) != 0) {
536 if (usal_reset(usalp, SCG_RESET_NOP) < 0)
537 comerr("Cannot reset (OS does not implement reset).\n");
538 if (usal_reset(usalp, SCG_RESET_TGT) >= 0)
540 if (usal_reset(usalp, SCG_RESET_BUS) < 0)
541 comerr("Cannot reset target.\n");
546 * First try to check which type of SCSI device we
548 if (debug || lverbose)
549 printf("atapi: %d\n", usal_isatapi(usalp));
552 test_unit_ready(usalp); /* eat up unit attention */
554 if (!do_inquiry(usalp, (flags & F_MSINFO) == 0 || lverbose)) {
555 errmsgno(EX_BAD, "Cannot do inquiry for CD/DVD-Recorder.\n");
556 if (unit_ready(usalp))
557 errmsgno(EX_BAD, "The unit seems to be hung and needs power cycling.\n");
565 extern void gconf(SCSI *);
572 if ((flags & F_PRCAP) != 0) {
573 print_capabilities(usalp);
574 print_capabilities_mmc4(usalp);
577 if ((flags & F_INQUIRY) != 0)
580 if (dp == (cdr_t *)NULL) { /* No driver= option specified */
581 dp = get_cdrcmds(usalp); /* Calls dp->cdr_identify() */
583 else if (!is_unknown_dev(usalp) && dp != get_cdrcmds(usalp)) {
584 errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n");
586 is_mmc(usalp, &is_cdwr, &is_dvdwr);
589 track[0].flags |= TI_PACKET;
590 /*XXX put here to only affect DVD writing, should be in gargs.
591 * however if set in args for all mode, packet writing is then
592 * broken for all disc as cdrecord assume that PACKET imply TAO which
593 * is not true at all???? */
594 track[0].flags &= ~TI_TAO;
598 if (dp == (cdr_t *)0)
599 comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.\n");
601 /* DVD does not support TAO */
604 fprintf(stderr, "Using Session At Once (SAO) for DVD mode.\n");
605 dp->cdr_flags |= F_SAO;
606 for (i = 0; i <= MAX_TRACK; i++) {
607 track[i].flags &= ~TI_TAO;
608 track[i].flags |= TI_SAO;
612 if (!is_cddrive(usalp))
613 comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n");
615 * The driver is known, set up data structures...
621 ndp = malloc(sizeof (cdr_t));
622 dsp = malloc(sizeof (dstat_t));
623 if (ndp == NULL || dsp == NULL)
624 comerr("Cannot allocate memory for driver structure.\n");
625 movebytes(dp, ndp, sizeof (cdr_t));
627 dp->cdr_flags |= CDR_ALLOC;
628 dp->cdr_cmdflags = flags;
630 fillbytes(dsp, sizeof (*dsp), '\0');
631 dsp->ds_minbuf = 0xFFFF;
635 if ((flags & (F_MSINFO|F_TOC|F_LOAD|F_DLCK|F_EJECT)) == 0 ||
639 if ((dp->cdr_flags & CDR_ISREADER) != 0) {
641 "Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.\n");
644 if (!is_mmc(usalp, &is_cdwr, &is_dvdwr))
645 is_cdwr = TRUE; /* If it is not MMC, it must be a CD writer */
647 if (is_dvdwr && !set_cdrcmds("mmc_mdvd", (cdr_t **)NULL)) {
649 "Internal error, DVD driver failure. Please report to debburn-devel@lists.alioth.debian.org.\n");
652 * Only exit if this is not the ProDVD test binary.
659 * Set up data structures for current drive state.
661 if ((*dp->cdr_attach)(usalp, dp) != 0)
662 comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.\n");
665 printf("Drive current speed: %d\n", dp->cdr_dstat->ds_dr_cur_wspeed);
666 printf("Drive default speed: %d\n", dp->cdr_speeddef);
667 printf("Drive max speed : %d\n", dp->cdr_speedmax);
669 if (speed > (int)dp->cdr_speedmax && (flags & F_FORCE) == 0)
670 speed = dp->cdr_speedmax;
672 speed = dp->cdr_speeddef;
675 printf("Selected speed : %d\n", speed);
677 dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
679 exargs.usalp = usalp;
681 exargs.old_secsize = -1;
682 exargs.flags = flags;
684 if ((flags & F_MSINFO) == 0 || lverbose) {
685 printf("Using %s (%s).\n", dp->cdr_drtext, dp->cdr_drname);
690 if ((debug || lverbose)) {
692 if ((*dp->cdr_buffer_cap)(usalp, &tsize, (long *)0) < 0 || tsize < 0) {
693 if (read_buffer(usalp, buf, 4, 0) >= 0)
694 tsize = a_to_u_4_byte(buf);
697 printf("Drive buf size : %lu = %lu KB\n",
703 dma_speed = get_dmaspeed(usalp, dp);
705 if ((debug || lverbose) && dma_speed > 0) {
707 * We do not yet know what medium type is in...
709 printf("Drive DMA Speed: %d kB/s %dx CD %dx DVD\n",
710 dma_speed, dma_speed/176, dma_speed/1385);
712 if ((tracks > 0 || cuefilename != NULL) && (debug || lverbose))
713 printf("FIFO size : %lu = %lu KB\n", fs, fs >> 10);
715 #ifdef HAVE_LIB_EDC_ECC
716 if ((flags & F_RAW) != 0 && (dp->cdr_dstat->ds_flags & DSF_DVD) == 0)
717 raw_speed = encspeed(debug || lverbose);
720 if ((flags & F_CHECKDRIVE) != 0)
723 if ((flags & F_ABORT) != 0) {
725 * flush cache is not supported by CD-ROMs avoid prob with -toc
728 scsi_flush_cache(usalp, FALSE);
729 (*dp->cdr_abort_session)(usalp, dp);
734 if (tracks == 0 && cuefilename == NULL &&
735 (flags & (F_FIX|F_BLANK)) == 0 && (flags & F_EJECT) != 0) {
737 * Do not check if the unit is ready here to allow to open
740 unload_media(usalp, dp, flags);
746 parsecue(cuefilename, track);
747 tracks = track[0].tracks;
753 sleep(2); /* Let the user watch the inquiry messages */
755 if (tracks > 0 && !check_wrmode(dp, flags, track[1].flags))
756 comerrno(EX_BAD, "Illegal write mode for this drive.\n");
758 if ((track[0].flags & TI_TEXT) == 0 && /* CD-Text not yet processed */
759 (track[MAX_TRACK+1].flags & TI_TEXT) != 0) {
761 * CD-Text from textfile= or from CUE CDTEXTFILE will win
762 * over CD-Text from *.inf files and over CD-Text from
763 * CUE SONGWRITER, ...
765 packtext(tracks, track);
766 track[0].flags |= TI_TEXT;
769 if (flags & F_CLONE) {
771 clone_tracktype(track);
774 setleadinout(tracks, track);
775 set_trsizes(dp, tracks, track);
776 setpregaps(tracks, track);
777 checkfiles(tracks, track);
778 tsize = checktsize(tracks, track);
781 * Make wm2name[wrmode] work.
782 * This must be done after the track flags have been set up
783 * by the functions above.
785 if (tracks == 0 && (flags & F_BLANK) != 0)
786 dp->cdr_dstat->ds_wrmode = WM_BLANK;
787 else if (tracks == 0 && (flags & F_FORMAT) != 0)
788 dp->cdr_dstat->ds_wrmode = WM_FORMAT;
790 set_wrmode(dp, flags, track[1].flags);
798 (*dp->cdr_gen_cue)(track, &cp, FALSE);
804 * Create Lead-in data. Only needed in RAW mode.
810 * Install exit handler before we change the drive status.
812 on_comerr(exscsi, &exargs);
814 if ((flags & F_FORCE) == 0)
815 load_media(usalp, dp, TRUE);
817 if ((flags & (F_LOAD|F_DLCK)) != 0) {
818 if ((flags & F_DLCK) == 0) {
819 usalp->silent++; /* silently */
820 scsi_prevent_removal(
821 usalp, 0); /* allow manual open */
822 usalp->silent--; /* if load failed... */
824 exit(0); /* we did not change status */
826 exargs.old_secsize = sense_secsize(usalp, 1);
827 if (exargs.old_secsize < 0)
828 exargs.old_secsize = sense_secsize(usalp, 0);
830 printf("Current Secsize: %d\n", exargs.old_secsize);
832 if (read_capacity(usalp) < 0) {
833 if (exargs.old_secsize > 0)
834 usalp->cap->c_bsize = exargs.old_secsize;
837 if (exargs.old_secsize < 0)
838 exargs.old_secsize = usalp->cap->c_bsize;
839 if (exargs.old_secsize != usalp->cap->c_bsize)
840 errmsgno(EX_BAD, "Warning: blockdesc secsize %d differs from cap secsize %d\n",
841 exargs.old_secsize, usalp->cap->c_bsize);
844 printf("Current Secsize: %d\n", exargs.old_secsize);
846 if (exargs.old_secsize > 0 && exargs.old_secsize != DATA_SEC_SIZE) {
848 * Some drives (e.g. Plextor) don't like to write correctly
849 * in SAO mode if the sector size is set to 512 bytes.
850 * In addition, wodim -msinfo will not work properly
851 * if the sector size is not 2048 bytes.
853 set_secsize(usalp, DATA_SEC_SIZE);
857 * Is this the right place to do this ?
859 check_recovery(usalp, dp, flags);
861 /*audioread(dp, flags);*/
862 /*unload_media(usalp, dp, flags);*/
865 dp->cdr_dstat->ds_cdrflags |= RF_WRITE;
867 dp->cdr_dstat->ds_cdrflags |= RF_BLANK;
868 if (flags & F_PRATIP || lverbose > 0) {
869 dp->cdr_dstat->ds_cdrflags |= RF_PRATIP;
871 if (flags & F_IMMED || dminbuf > 0) {
874 if (lverbose <= 0) /* XXX Hack needed for now */
876 dp->cdr_dstat->ds_cdrflags |= RF_WR_WAIT;
878 if ((*dp->cdr_getdisktype)(usalp, dp) < 0) {
879 errmsgno(EX_BAD, "Cannot get disk type.\n");
880 if ((flags & F_FORCE) == 0)
883 if (flags & F_PRATIP) {
887 * The next actions should depend on the disk type.
890 if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0)
897 * Init drive to default modes:
899 * We set TAO unconditionally to make checkdsize() work
900 * currectly in SAO mode too.
902 * At least MMC drives will not return the next writable
903 * address we expect when the drive's write mode is set
904 * to SAO. We need this address for mkisofs and thus
905 * it must be the first user accessible sector and not the
906 * first sector of the pregap.
908 * XXX The ACER drive:
909 * XXX Vendor_info : 'ATAPI '
910 * XXX Identifikation : 'CD-R/RW 8X4X32 '
911 * XXX Revision : '5.EW'
912 * XXX Will not return from -dummy to non-dummy without
913 * XXX opening the tray.
916 if ((*dp->cdr_init)(usalp, dp) < 0)
917 comerrno(EX_BAD, "Cannot init drive.\n");
920 if (flags & F_SETDROPTS) {
922 * Note that the set speed function also contains
923 * drive option processing for speed related drive options.
925 if ((*dp->cdr_opt1)(usalp, dp) < 0) {
926 errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n");
928 if ((*dp->cdr_set_speed_dummy)(usalp, dp, &speed) < 0) {
929 errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
931 dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
932 if ((*dp->cdr_opt2)(usalp, dp) < 0) {
933 errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n");
938 * XXX If dp->cdr_opt1() ever affects the result for
939 * XXX the multi session info we would need to move it here.
941 if (flags & F_MSINFO) {
942 print_msinfo(usalp, dp);
946 print_toc(usalp, dp);
950 if ((*dp->cdr_check_session)() < 0) {
955 Int32_t omb = dp->cdr_dstat->ds_maxblocks;
957 if ((*dp->cdr_opt1)(usalp, dp) < 0) {
958 errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n");
960 if (tsize > 0 && omb != dp->cdr_dstat->ds_maxblocks) {
961 printf("Disk size changed by user options.\n");
962 printf("Checking disk capacity according to new values.\n");
968 "WARNING: Total disk size unknown. Data may not fit on disk.\n");
970 } else if (tracks > 0) {
972 * XXX How do we let the user check the remaining
973 * XXX disk size witout starting the write process?
975 if (!checkdsize(usalp, dp, tsize, flags))
978 if (tracks > 0 && fs > 0l) {
979 #if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID)
981 * Hack to work around the POSIX design bug in real time
982 * priority handling: we need to be root even to lower
984 * Note that we need to find a more general way that works
985 * even on OS that do not support getreuid() which is *BSD
988 if (oeuid != getuid()) {
989 if (setreuid(-1, oeuid) < 0)
990 errmsg("Could set back effective uid.\n");
995 * fork() here to start the extra process needed for
996 * improved buffering.
998 if (!init_faio(track, bufsize))
1001 on_comerr(excdr, &exargs);
1003 atexit(fifo_cleanup);
1005 #if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID)
1007 * XXX Below this point we never need root privilleges anymore.
1009 if (geteuid() != getuid()) { /* AIX does not like to do this */
1010 /* If we are not root */
1011 if (setreuid(-1, getuid()) < 0)
1012 comerr("Panic cannot set back effective uid.\n");
1015 if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose>2))
1016 perror("Error: Cannot gain SYS_RAWIO capability, is wodim installed SUID root? Reason");
1022 if ((*dp->cdr_set_speed_dummy)(usalp, dp, &speed) < 0) {
1023 errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
1024 if ((flags & F_FORCE) == 0)
1027 dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
1028 if ((flags & F_WRITE) != 0 && raw_speed >= 0) {
1029 int max_raw = (flags & F_FORCE) != 0 ? raw_speed:raw_speed/2;
1031 if (getenv("CDR_FORCERAWSPEED"))
1032 max_raw = raw_speed;
1034 for (i = 1; i <= MAX_TRACK; i++) {
1036 * Check for Clone tracks
1038 if ((track[i].sectype & ST_MODE_RAW) != 0)
1041 * Check for non-data tracks
1043 if ((track[i].sectype & ST_MODE_MASK) == ST_MODE_AUDIO)
1046 if (speed > max_raw) {
1048 "Processor too slow. Cannot write RAW data at speed %d.\n",
1050 comerrno(EX_BAD, "Max RAW data speed on this processor is %d.\n",
1056 if (tracks > 0 && (flags & F_WRITE) != 0 && dma_speed > 0) {
1057 int max_dma = (dma_speed+1)*4/5; /* use an empirical formula to estimate available bandwith */
1059 if((flags & F_FORCE) != 0 || getenv("CDR_FORCESPEED"))
1060 max_dma = dma_speed;
1062 if (speed > max_dma) {
1064 "DMA speed too slow (OK for %dx). Cannot write at speed %dx.\n",
1066 if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
1067 errmsgno(EX_BAD, "Max DMA data speed is %d.\n", max_dma);
1068 comerrno(EX_BAD, "Try to use 'driveropts=burnfree'.\n");
1072 if ((flags & (F_WRITE|F_BLANK)) != 0 &&
1073 (dp->cdr_dstat->ds_flags & DSF_ERA) != 0) {
1075 printf("Current speed %d, medium low speed: %d medium high speed: %d\n",
1077 dp->cdr_dstat->ds_at_min_speed,
1078 dp->cdr_dstat->ds_at_max_speed);
1080 if (dp->cdr_dstat->ds_at_max_speed > 0 &&
1082 speed > (int)dp->cdr_dstat->ds_at_max_speed) {
1084 * Be careful here: 10x media may be written faster.
1085 * The current code will work as long as there is no
1086 * writer that can only write faster than 8x
1088 if ((flags & F_FORCE) == 0) {
1090 "Write speed %d of medium not sufficient for this writer.\n",
1091 dp->cdr_dstat->ds_at_max_speed);
1093 "You may have used an ultra low speed medium on a high speed writer.\n");
1097 if ((dp->cdr_dstat->ds_flags & DSF_ULTRASPP_ERA) != 0 &&
1098 (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0)) {
1099 if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0) {
1101 "Trying to use ultra high speed+ medium on a writer which is not\ncompatible with ultra high speed+ media.\n");
1102 } else if ((flags & F_FORCE) == 0) {
1104 "Probably trying to use ultra high speed+ medium on improper writer.\n");
1106 } else if ((dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA) != 0 &&
1107 (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0)) {
1108 if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0) {
1110 "Trying to use ultra high speed medium on a writer which is not\ncompatible with ultra high speed media.\n");
1111 } else if ((flags & F_FORCE) == 0) {
1113 "Probably trying to use ultra high speed medium on improper writer.\n");
1116 if (dp->cdr_dstat->ds_at_min_speed >= 4 &&
1117 dp->cdr_dstat->ds_at_max_speed > 4 &&
1118 dp->cdr_dstat->ds_dr_max_wspeed <= 4) {
1119 if ((flags & F_FORCE) == 0) {
1121 "Trying to use high speed medium on low speed writer.\n");
1124 if ((int)dp->cdr_dstat->ds_at_min_speed > speed) {
1125 if ((flags & F_FORCE) == 0) {
1127 "Write speed %d of writer not sufficient for this medium.\n",
1130 "You did use a %s speed medium on an improper writer or\n",
1131 dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA ?
1132 "ultra high": "high");
1134 "you used a speed=# option with a speed too low for this medium.\n");
1138 if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) {
1139 printf("Waiting for drive to calm down.\n");
1140 wait_unit_ready(usalp, 120);
1141 if (gracewait(dp, &gracedone) < 0) {
1143 * In case kill() did not work ;-)
1148 scsi_blank(usalp, 0L, blanktype, FALSE);
1152 * Last chance to quit!
1154 if (gracewait(dp, &gracedone) < 0) {
1156 * In case kill() did not work ;-)
1162 if (dp->profile == 0x2B && flags & F_SAO && tsize > 0) {
1163 printf("Preparing middle zone location for this DVD+R dual layer disc\n");
1164 if (!dp->cdr_layer_split(usalp, dp, tsize)) {
1165 errmsgno(EX_BAD, "Cannot send structure for middle zone location.\n");
1170 if (tracks > 0 && fs > 0l) {
1172 * Wait for the read-buffer to become full.
1173 * This should be take no extra time if the input is a file.
1174 * If the input is a pipe (e.g. mkisofs) this can take a
1175 * while. If mkisofs dumps core before it starts writing,
1176 * we abort before the writing process started.
1178 if (!await_faio()) {
1179 comerrno(EX_BAD, "Input buffer error, aborting.\n");
1182 wait_unit_ready(usalp, 120);
1184 starttime.tv_sec = 0;
1185 wstarttime.tv_sec = 0;
1186 stoptime.tv_sec = 0;
1188 if (gettimeofday(&starttime, (struct timezone *)0) < 0)
1189 errmsg("Cannot get start time\n");
1192 * Blank the media if we were requested to do so
1194 if (flags & F_BLANK) {
1196 * Do not abort if OPC failes. Just give it a chance
1197 * for better laser power calibration than without OPC.
1199 * Ricoh drives return with a vendor unique sense code.
1200 * This is most likely because they refuse to do OPC
1201 * on a non blank media.
1204 do_opc(usalp, dp, flags);
1206 wait_unit_ready(usalp, 120);
1207 if (gettimeofday(&starttime, (struct timezone *)0) < 0)
1208 errmsg("Cannot get start time\n");
1210 if ((*dp->cdr_blank)(usalp, dp, 0L, blanktype) < 0) {
1211 errmsgno(EX_BAD, "Cannot blank disk, aborting.\n");
1212 if (blanktype != BLANK_DISC) {
1213 errmsgno(EX_BAD, "Some drives do not support all blank types.\n");
1214 errmsgno(EX_BAD, "Try again with wodim blank=all.\n");
1218 if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
1219 errmsg("Cannot get blank time\n");
1221 prtimediff("Blanking time: ", &starttime, &fixtime);
1224 * XXX Erst blank und dann format?
1225 * XXX Wenn ja, dann hier (flags & F_FORMAT) testen
1227 * EB: nee, besser nicht
1229 if (!wait_unit_ready(usalp, 240) || tracks == 0) {
1233 if (flags & F_FORMAT) {
1234 printf("wodim: media format asked\n");
1236 * Do not abort if OPC failes. Just give it a chance
1237 * for better laser power calibration than without OPC.
1239 * Ricoh drives return with a vendor unique sense code.
1240 * This is most likely because they refuse to do OPC
1241 * on a non blank media.
1244 do_opc(usalp, dp, flags);
1246 wait_unit_ready(usalp, 120);
1247 if (gettimeofday(&starttime, (struct timezone *)0) < 0)
1248 errmsg("Cannot get start time\n");
1250 if ((*dp->cdr_format)(usalp, dp, formattype) < 0) {
1251 errmsgno(EX_BAD, "Cannot format disk, aborting.\n");
1254 if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
1255 errmsg("Cannot get format time\n");
1257 prtimediff("Formatting time: ", &starttime, &fixtime);
1259 if (!wait_unit_ready(usalp, 240) || tracks == 0) {
1262 if (gettimeofday(&starttime, (struct timezone *)0) < 0)
1263 errmsg("Cannot get start time\n");
1266 * Reset start time so we will not see blanking time and
1267 * writing time counted together.
1269 if (gettimeofday(&starttime, (struct timezone *)0) < 0)
1270 errmsg("Cannot get start time\n");
1271 if (tracks == 0 && (flags & F_FIX) == 0)
1272 comerrno(EX_BAD, "No tracks found.\n");
1274 * Get the number of the next recordable track by reading the TOC and
1275 * use the number the last current track number.
1278 if (read_tochdr(usalp, dp, NULL, &trackno) < 0) {
1283 /* If it is DVD, the information in TOC is fabricated :)
1284 The real information is from read disk info command*/
1285 if((dp->cdr_dstat->ds_disktype&DT_DVD) && (dp->cdr_dstat->ds_trlast>0)){
1286 trackno=dp->cdr_dstat->ds_trlast-1;
1288 printf("trackno=%d\n",trackno);
1291 if ((tracks + trackno) > MAX_TRACK) {
1293 * XXX How many tracks are allowed on a DVD?
1295 comerrno(EX_BAD, "Too many tracks for this disk, last track number is %d.\n",
1299 for (i = 0; i <= tracks+1; i++) { /* Lead-in ... Lead-out */
1300 track[i].trackno = i + trackno; /* Set up real track # */
1303 if ((*dp->cdr_opt2)(usalp, dp) < 0) {
1304 errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n");
1308 * Now we actually start writing to the CD/DVD.
1309 * XXX Check total size of the tracks and remaining size of disk.
1311 if ((*dp->cdr_open_session)(usalp, dp, track) < 0) {
1312 comerrno(EX_BAD, "Cannot open new session.\n");
1314 if (!do_opc(usalp, dp, flags))
1318 * As long as open_session() will do nothing but
1319 * set up parameters, we may leave fix_it here.
1320 * I case we have to add an open_session() for a drive
1321 * that wants to do something that modifies the disk
1322 * We have to think about a new solution.
1328 * This call may modify trackp[i].trackstart for all tracks.
1330 if ((*dp->cdr_write_leadin)(usalp, dp, track) < 0)
1331 comerrno(EX_BAD, "Could not write Lead-in.\n");
1333 if (lverbose && (dp->cdr_dstat->ds_cdrflags & RF_LEADIN) != 0) {
1335 if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
1336 errmsg("Cannot get lead-in write time\n");
1337 prtimediff("Lead-in write time: ", &starttime, &fixtime);
1340 if (gettimeofday(&wstarttime, (struct timezone *)0) < 0)
1341 errmsg("Cannot get start time\n");
1342 for (i = 1; i <= tracks; i++) {
1345 if ((*dp->cdr_open_track)(usalp, dp, &track[i]) < 0) {
1346 errmsgno(EX_BAD, "Cannot open next track.\n");
1351 if ((flags & (F_SAO|F_RAW)) == 0) {
1352 if ((*dp->cdr_next_wr_address)(usalp, &track[i], &startsec) < 0) {
1353 errmsgno(EX_BAD, "Cannot get next writable address.\n");
1357 track[i].trackstart = startsec;
1359 if (debug || lverbose) {
1360 printf("Starting new track at sector: %ld\n",
1361 track[i].trackstart);
1364 if (write_track_data(usalp, dp, &track[i]) < 0) {
1365 if (cdr_underrun(usalp)) {
1367 "The current problem looks like a buffer underrun.\n");
1368 if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
1369 errmsgno(EX_BAD, "Try to use 'driveropts=burnfree'.\n");
1371 errmsgno(EX_BAD, "It looks like 'driveropts=burnfree' does not work for this drive.\n");
1372 errmsgno(EX_BAD, "Please report.\n");
1376 "Make sure that you are root, enable DMA and check your HW/OS set up.\n");
1378 errmsgno(EX_BAD, "A write error occured.\n");
1379 errmsgno(EX_BAD, "Please properly read the error message above.\n");
1384 (*dp->cdr_close_track)(usalp, dp, &track[i]);
1387 if ((*dp->cdr_close_track)(usalp, dp, &track[i]) < 0) {
1389 * Check for "Dummy blocks added" message first.
1391 if (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST ||
1392 usal_sense_code(usalp) != 0xB5) {
1393 errmsgno(EX_BAD, "Cannot close track.\n");
1400 if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
1401 errmsg("Cannot get stop time\n");
1404 if (flags & F_RAW) {
1406 printf("Writing Leadout...\n");
1409 write_leadout(usalp, dp, track);
1411 if ((flags & F_NOFIX) == 0) {
1413 printf("Fixating...\n");
1416 if ((*dp->cdr_fixate)(usalp, dp, track) < 0) {
1418 * Ignore fixating errors in dummy mode.
1420 if ((flags & F_DUMMY) == 0) {
1421 errmsgno(EX_BAD, "Cannot fixate disk.\n");
1425 if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
1426 errmsg("Cannot get fix time\n");
1428 prtimediff("Fixating time: ", &stoptime, &fixtime);
1430 if ((dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) {
1431 dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT;
1432 (*dp->cdr_stats)(usalp, dp);
1434 if ((flags & (F_RAW|F_EJECT)) == F_RAW) {
1436 * Most drives seem to forget to reread the TOC from disk
1437 * if they are in RAW mode.
1440 if (read_tochdr(usalp, dp, NULL, NULL) < 0) {
1442 if ((flags & F_DUMMY) == 0)
1443 reload_media(usalp, dp);
1451 * Try to restore the old sector size and stop FIFO.
1459 gracewait(cdr_t *dp, BOOL *didgracep)
1462 BOOL didgrace = FALSE;
1465 didgrace = *didgracep;
1467 if(warn_minisize>=0) {
1468 fprintf(stderr, "\nWARNING: found a microscopic small track size (%lld bytes).\n"
1469 " Do you really want to write this image? Press Ctrl-C to abort...\n\n",
1473 if (gracetime < MIN_GRACE_TIME)
1474 gracetime = MIN_GRACE_TIME;
1475 if (gracetime > 999)
1478 printf("Starting to write CD/DVD at speed %5.1f in %s%s %s mode for %s session.\n",
1479 (float)dp->cdr_dstat->ds_wspeed,
1480 (dp->cdr_cmdflags & F_DUMMY) ? "dummy" : "real",
1481 (dp->cdr_cmdflags & F_FORCE) ? " force" : "",
1482 wm2name[dp->cdr_dstat->ds_wrmode],
1483 (dp->cdr_cmdflags & F_MULTI) ? "multi" : "single");
1485 printf("No chance to quit anymore.");
1488 printf("Last chance to quit, starting %s write in %4d seconds.",
1489 (dp->cdr_cmdflags & F_DUMMY)?"dummy":"real", gracetime);
1491 signal(SIGINT, intr);
1492 signal(SIGHUP, intr);
1493 signal(SIGTERM, intr);
1495 for (i = gracetime; --i >= 0; ) {
1499 excdr(SIGINT, &exargs);
1500 signal(SIGINT, SIG_DFL);
1501 kill(getpid(), SIGINT);
1503 * In case kill() did not work ;-)
1509 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b%4d seconds.", i);
1513 printf(" Operation starts.");
1515 signal(SIGINT, SIG_DFL);
1516 signal(SIGHUP, SIG_DFL);
1517 signal(SIGTERM, SIG_DFL);
1518 signal(SIGINT, intfifo);
1519 signal(SIGHUP, intfifo);
1520 signal(SIGTERM, intfifo);
1531 float secsps = 75.0;
1534 struct timeval tcur;
1535 struct timeval tlast;
1536 BOOL nostop = FALSE;
1538 if (starttime.tv_sec == 0)
1541 if (stoptime.tv_sec == 0) {
1542 gettimeofday(&stoptime, (struct timezone *)0);
1546 if ((dp->cdr_dstat->ds_cdrflags & RF_DID_STAT) != 0)
1548 dp->cdr_dstat->ds_cdrflags |= RF_DID_STAT;
1553 if (dp->cdr_cmdflags & F_FIX)
1556 if ((dp->cdr_cmdflags & (F_WRITE|F_BLANK)) == F_BLANK)
1562 prtimediff("Writing time: ", &starttime, &stoptime);
1564 nsecs = dp->cdr_dstat->ds_endsec - dp->cdr_dstat->ds_startsec;
1566 if (dp->cdr_dstat->ds_flags & DSF_DVD)
1569 tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
1570 tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
1571 while (tlast.tv_usec < 0) {
1572 tlast.tv_usec += 1000000;
1575 if (!nostop && nsecs != 0 && dp->cdr_dstat->ds_endsec > 0) {
1577 * May not be known (e.g. cdrecord -)
1579 * XXX if we later allow this code to know how much has
1580 * XXX actually been written, then we may remove the
1581 * XXX dependance from nostop & nsecs != 0
1583 fspeed = (nsecs / secsps) /
1584 (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
1587 if (dp->is_dvd) fspeed /= 9;
1588 printf("Average write speed %5.1fx.\n", fspeed);
1591 if (dp->cdr_dstat->ds_minbuf <= 100) {
1592 printf("Min drive buffer fill was %u%%\n",
1593 (unsigned int)dp->cdr_dstat->ds_minbuf);
1595 if (dp->cdr_dstat->ds_buflow > 0) {
1596 printf("Total of %ld possible drive buffer underruns predicted.\n",
1597 (long)dp->cdr_dstat->ds_buflow);
1607 fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname());
1608 fprintf(stderr, "\nUse\t%s -help\n", get_progname());
1609 fprintf(stderr, "to get a list of valid options.\n");
1610 fprintf(stderr, "\nUse\t%s blank=help\n", get_progname());
1611 fprintf(stderr, "to get a list of valid blanking options.\n");
1612 fprintf(stderr, "\nUse\t%s dev=b,t,l driveropts=help -checkdrive\n", get_progname());
1613 fprintf(stderr, "to get a list of drive specific options.\n");
1614 fprintf(stderr, "\nUse\t%s dev=help\n", get_progname());
1615 fprintf(stderr, "to get a list of possible SCSI transport specifiers.\n");
1623 fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname());
1624 fprintf(stderr, "Options:\n");
1625 fprintf(stderr, "\t-version print version information and exit\n");
1626 fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n");
1627 fprintf(stderr, "\tgracetime=# set the grace time before starting to write to #.\n");
1628 fprintf(stderr, "\ttimeout=# set the default SCSI command timeout to #.\n");
1629 fprintf(stderr, "\tdebug=#,-d Set to # or increment misc debug level\n");
1630 fprintf(stderr, "\tkdebug=#,kd=# do Kernel debugging\n");
1631 fprintf(stderr, "\t-verbose,-v increment general verbose level by one\n");
1632 fprintf(stderr, "\t-Verbose,-V increment SCSI command transport verbose level by one\n");
1633 fprintf(stderr, "\t-silent,-s do not print status of failed SCSI commands\n");
1634 fprintf(stderr, "\tdriver=name user supplied driver name, use with extreme care\n");
1635 fprintf(stderr, "\tdriveropts=opt a comma separated list of driver specific options\n");
1636 fprintf(stderr, "\t-setdropts set driver specific options and exit\n");
1637 fprintf(stderr, "\t-checkdrive check if a driver for the drive is present\n");
1638 fprintf(stderr, "\t-prcap print drive capabilities for MMC compliant drives\n");
1639 fprintf(stderr, "\t-inq do an inquiry for the drive and exit\n");
1640 fprintf(stderr, "\t-scanbus scan the SCSI and IDE buses and exit\n");
1641 fprintf(stderr, "\t-reset reset the SCSI bus with the cdrecorder (if possible)\n");
1642 fprintf(stderr, "\t-abort send an abort sequence to the drive (may help if hung)\n");
1643 fprintf(stderr, "\t-overburn allow to write more than the official size of a medium\n");
1644 fprintf(stderr, "\t-ignsize ignore the known size of a medium (may cause problems)\n");
1645 fprintf(stderr, "\t-useinfo use *.inf files to overwrite audio options.\n");
1646 fprintf(stderr, "\tspeed=# set speed of drive\n");
1647 fprintf(stderr, "\tblank=type blank a CD-RW disc (see blank=help)\n");
1648 fprintf(stderr, "\t-format format a CD-RW/DVD-RW/DVD+RW disc\n");
1649 fprintf(stderr, "\tformattype=# select the format method for DVD+RW disc\n");
1651 fprintf(stderr, "\tfs=# Set fifo size to # (0 to disable, default is %ld MB)\n",
1652 DEFAULT_FIFOSIZE/(1024L*1024L));
1654 fprintf(stderr, "\tts=# set maximum transfer size for a single SCSI command\n");
1655 fprintf(stderr, "\t-load load the disk and exit (works only with tray loader)\n");
1656 fprintf(stderr, "\t-lock load and lock the disk and exit (works only with tray loader)\n");
1657 fprintf(stderr, "\t-eject eject the disk after doing the work\n");
1658 fprintf(stderr, "\t-dummy do everything with laser turned off\n");
1659 fprintf(stderr, "\t-msinfo retrieve multi-session info for genisoimage\n");
1660 fprintf(stderr, "\t-msifile=path run -msinfo and copy output to file\n");
1661 fprintf(stderr, "\t-toc retrieve and print TOC/PMA data\n");
1662 fprintf(stderr, "\t-atip retrieve and print ATIP data\n");
1663 fprintf(stderr, "\t-multi generate a TOC that allows multi session\n");
1664 fprintf(stderr, "\t In this case default track type is CD-ROM XA mode 2 form 1 - 2048 bytes\n");
1665 fprintf(stderr, "\t-fix fixate a corrupt or unfixated disk (generate a TOC)\n");
1666 fprintf(stderr, "\t-nofix do not fixate disk after writing tracks\n");
1667 fprintf(stderr, "\t-waiti wait until input is available before opening SCSI\n");
1668 fprintf(stderr, "\t-immed Try to use the SCSI IMMED flag with certain long lasting commands\n");
1669 fprintf(stderr, "\t-force force to continue on some errors to allow blanking bad disks\n");
1670 fprintf(stderr, "\t-tao Write disk in TAO mode.\n");
1671 fprintf(stderr, "\t-dao Write disk in SAO mode.\n");
1672 fprintf(stderr, "\t-sao Write disk in SAO mode.\n");
1673 fprintf(stderr, "\t-raw Write disk in RAW mode.\n");
1674 fprintf(stderr, "\t-raw96r Write disk in RAW/RAW96R mode.\n");
1675 fprintf(stderr, "\t-raw96p Write disk in RAW/RAW96P mode.\n");
1676 fprintf(stderr, "\t-raw16 Write disk in RAW/RAW16 mode.\n");
1678 fprintf(stderr, "\t-clone Write disk in clone write mode.\n");
1680 fprintf(stderr, "\ttsize=# Length of valid data in next track\n");
1681 fprintf(stderr, "\tpadsize=# Amount of padding for next track\n");
1682 fprintf(stderr, "\tpregap=# Amount of pre-gap sectors before next track\n");
1683 fprintf(stderr, "\tdefpregap=# Amount of pre-gap sectors for all but track #1\n");
1684 fprintf(stderr, "\tmcn=text Set the media catalog number for this CD to 'text'\n");
1685 fprintf(stderr, "\tisrc=text Set the ISRC number for the next track to 'text'\n");
1686 fprintf(stderr, "\tindex=list Set the index list for the next track to 'list'\n");
1687 fprintf(stderr, "\t-text Write CD-Text from information from *.inf or *.cue files\n");
1688 fprintf(stderr, "\ttextfile=name Set the file with CD-Text data to 'name'\n");
1689 fprintf(stderr, "\tcuefile=name Set the file with CDRWIN CUE data to 'name'\n");
1691 fprintf(stderr, "\t-audio Subsequent tracks are CD-DA audio tracks\n");
1692 fprintf(stderr, "\t-data Subsequent tracks are CD-ROM data mode 1 - 2048 bytes (default)\n");
1693 fprintf(stderr, "\t-mode2 Subsequent tracks are CD-ROM data mode 2 - 2336 bytes\n");
1694 fprintf(stderr, "\t-xa Subsequent tracks are CD-ROM XA mode 2 form 1 - 2048 bytes\n");
1695 fprintf(stderr, "\t-xa1 Subsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n");
1696 fprintf(stderr, "\t-xa2 Subsequent tracks are CD-ROM XA mode 2 form 2 - 2324 bytes\n");
1697 fprintf(stderr, "\t-xamix Subsequent tracks are CD-ROM XA mode 2 form 1/2 - 2332 bytes\n");
1698 fprintf(stderr, "\t-cdi Subsequent tracks are CDI tracks\n");
1699 fprintf(stderr, "\t-isosize Use iso9660 file system size for next data track\n");
1700 fprintf(stderr, "\t-preemp Audio tracks are mastered with 50/15 microseconds preemphasis\n");
1701 fprintf(stderr, "\t-nopreemp Audio tracks are mastered with no preemphasis (default)\n");
1702 fprintf(stderr, "\t-copy Audio tracks have unlimited copy permission\n");
1703 fprintf(stderr, "\t-nocopy Audio tracks may only be copied once for personal use (default)\n");
1704 fprintf(stderr, "\t-scms Audio tracks will not have any copy permission at all\n");
1705 fprintf(stderr, "\t-pad Pad data tracks with %d zeroed sectors\n", PAD_SECS);
1706 fprintf(stderr, "\t Pad audio tracks to a multiple of %d bytes\n", AUDIO_SEC_SIZE);
1707 fprintf(stderr, "\t-nopad Do not pad data tracks (default)\n");
1708 fprintf(stderr, "\t-shorttrack Subsequent tracks may be non Red Book < 4 seconds if in SAO or RAW mode\n");
1709 fprintf(stderr, "\t-noshorttrack Subsequent tracks must be >= 4 seconds\n");
1710 fprintf(stderr, "\t-swab Audio data source is byte-swapped (little-endian/Intel)\n");
1711 fprintf(stderr, "The type of the first track is used for the toc type.\n");
1712 fprintf(stderr, "Currently only form 1 tracks are supported.\n");
1719 fprintf(stderr, "Blanking options:\n");
1720 fprintf(stderr, "\tall\t\tblank the entire disk\n");
1721 fprintf(stderr, "\tdisc\t\tblank the entire disk\n");
1722 fprintf(stderr, "\tdisk\t\tblank the entire disk\n");
1723 fprintf(stderr, "\tfast\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
1724 fprintf(stderr, "\tminimal\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
1725 fprintf(stderr, "\ttrack\t\tblank a track\n");
1726 fprintf(stderr, "\tunreserve\tunreserve a track\n");
1727 fprintf(stderr, "\ttrtail\t\tblank a track tail\n");
1728 fprintf(stderr, "\tunclose\t\tunclose last session\n");
1729 fprintf(stderr, "\tsession\t\tblank last session\n");
1736 formattypeusage(int ret)
1738 fprintf(stderr, "Formating options:\n");
1739 fprintf(stderr, "\tfull\t\tstandard formating\n");
1740 fprintf(stderr, "\tbackground\t\tbackground formating\n");
1741 fprintf(stderr, "\tforce\t\tforce reformat\n");
1751 sig = 0; /* Fake usage for gcc */
1753 signal(SIGINT, intr);
1761 signal(sig, catchsig);
1769 return (0); /* Keep lint happy */
1775 errmsgno(EX_BAD, "Caught interrupt.\n");
1777 SCSI *usalp = exargs.usalp;
1779 if (usalp->running) {
1780 if (usalp->cb_fun != NULL) {
1781 comerrno(EX_BAD, "Second interrupt. Doing hard abort.\n");
1784 usalp->cb_fun = scsi_cb;
1785 usalp->cb_arg = &exargs;
1794 exscsi(int excode, void *arg)
1796 struct exargs *exp = (struct exargs *)arg;
1799 * Try to restore the old sector size.
1801 if (exp != NULL && exp->exflags == 0) {
1802 if (exp->usalp->running) {
1806 * flush cache is not supported by CD-ROMs avoid prob with -toc
1808 exp->usalp->silent++;
1809 scsi_flush_cache(exp->usalp, FALSE);
1810 (*exp->dp->cdr_abort_session)(exp->usalp, exp->dp);
1811 exp->usalp->silent--;
1812 set_secsize(exp->usalp, exp->old_secsize);
1813 unload_media(exp->usalp, exp->dp, exp->flags);
1815 exp->exflags++; /* Make sure that it only get called once */
1820 excdr(int excode, void *arg)
1822 struct exargs *exp = (struct exargs *)arg;
1824 exscsi(excode, arg);
1827 if ((exp->dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) {
1828 exp->dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT;
1829 (*exp->dp->cdr_stats)(exp->usalp, exp->dp);
1835 if (debug || lverbose)
1841 read_buf(int f, char *bp, int size)
1849 n = read(f, p, size-amount);
1850 } while (n < 0 && (geterrno() == EAGAIN || geterrno() == EINTR));
1856 } while (amount < size && n > 0);
1861 fill_buf(int f, track_t *trackp, long secno, char *bp, int size)
1869 nsecs = size / trackp->secsize;
1870 if (nsecs < trackp->secspt) {
1872 * Clear buffer to prepare for last transfer.
1873 * Make sure that a partial sector ends with NULs
1875 fillbytes(bp, trackp->secspt * trackp->secsize, '\0');
1878 if (!is_raw(trackp)) {
1879 amount = read_buf(f, bp, size);
1880 if (amount != size) {
1884 * We got less than expected, clear rest of buf.
1886 fillbytes(&bp[amount], size-amount, '\0');
1888 if (is_swab(trackp))
1889 swabbytes(bp, amount);
1893 rsize = nsecs * trackp->isecsize;
1894 rmod = size % trackp->secsize;
1900 readoffset = trackp->dataoff;
1901 amount = read_buf(f, bp + readoffset, rsize);
1902 if (is_swab(trackp))
1903 swabbytes(bp + readoffset, amount);
1905 if (trackp->isecsize == 2448 && trackp->secsize == 2368)
1906 subrecodesecs(trackp, (Uchar *)bp, secno, nsecs);
1908 scatter_secs(trackp, bp + readoffset, nsecs);
1910 if (amount != rsize) {
1914 * We got less than expected, clear rest of buf.
1916 fillbytes(&bp[amount], rsize-amount, '\0');
1917 nsecs = amount / trackp->isecsize;
1918 rmod = amount % trackp->isecsize;
1919 amount = nsecs * trackp->secsize;
1927 if ((trackp->sectype & ST_MODE_RAW) == 0) {
1928 encsectors(trackp, (Uchar *)bp, secno, nsecs);
1929 fillsubch(trackp, (Uchar *)bp, secno, nsecs);
1931 scrsectors(trackp, (Uchar *)bp, secno, nsecs);
1937 get_buf(int f, track_t *trackp, long secno, char **bpp, int size)
1940 /* return (faio_read_buf(f, *bpp, size));*/
1941 return (faio_get_buf(f, bpp, size));
1943 return (fill_buf(f, trackp, secno, *bpp, size));
1948 write_secs(SCSI *usalp, cdr_t *dp, char *bp, long startsec, int bytespt,
1949 int secspt, BOOL islast)
1955 amount = (*dp->cdr_write_trackdata)(usalp, bp, startsec, bytespt, secspt, islast);
1958 if (scsi_in_progress(usalp)) {
1960 * If we sleep too long, the drive buffer is empty
1961 * before we start filling it again. The max. CD speed
1962 * is ~ 10 MB/s (52x RAW writing). The max. DVD speed
1963 * is ~ 25 MB/s (18x DVD 1385 kB/s).
1964 * With 10 MB/s, a 1 MB buffer empties within 100ms.
1965 * With 25 MB/s, a 1 MB buffer empties within 40ms.
1967 if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0) {
1973 if (sysconf(_SC_CLK_TCK) < 100)
1988 write_track_data(SCSI *usalp, cdr_t *dp, track_t *trackp)
1990 int track = trackp->trackno;
1994 Llong bytes_read = 0;
2005 BOOL neednl = FALSE;
2006 BOOL islast = FALSE;
2008 struct timeval tlast;
2009 struct timeval tcur;
2010 float secsps = 75.0;
2021 if (dp->cdr_dstat->ds_flags & DSF_DVD)
2025 if ((*dp->cdr_buffer_cap)(usalp, &bsize, &bfree) < 0)
2027 if (bsize == 0) /* If we have no (known) buffer, we cannot */
2028 bsize = -1L; /* retrieve the buffer fill ratio */
2032 if (is_packet(trackp)) /* XXX Ugly hack for now */
2033 return (write_packet_data(usalp, dp, trackp));
2035 if (trackp->xfp != NULL)
2036 f = xfileno(trackp->xfp);
2038 isaudio = is_audio(trackp);
2039 tracksize = trackp->tracksize;
2040 startsec = trackp->trackstart;
2042 secsize = trackp->secsize;
2043 secspt = trackp->secspt;
2044 bytespt = secsize * secspt;
2046 pad = !isaudio && is_pad(trackp); /* Pad only data tracks */
2049 printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n",
2050 secsize, secspt, bytespt, isaudio, pad);
2055 printf("\rTrack %02d: 0 of %4lld MB written.",
2056 track, tracksize >> 20);
2058 printf("\rTrack %02d: 0 MB written.", track);
2063 gettimeofday(&tlast, (struct timezone *)0);
2065 bytes_to_read = bytespt;
2066 if (tracksize > 0) {
2067 if ((tracksize - bytes_read) > bytespt)
2068 bytes_to_read = bytespt;
2070 bytes_to_read = tracksize - bytes_read;
2072 count = get_buf(f, trackp, startsec, &bp, bytes_to_read);
2075 comerr("read error on input file\n");
2078 bytes_read += count;
2079 if (tracksize >= 0 && bytes_read >= tracksize) {
2080 count -= bytes_read - tracksize;
2082 * Paranoia: tracksize is known (trackp->tracksize >= 0)
2083 * At this point, trackp->padsize should alway be set
2084 * if the tracksize is less than 300 sectors.
2086 if (trackp->padsecs == 0 &&
2087 (is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
2091 if (count < bytespt) {
2093 printf("\nNOTICE: reducing block size for last record.\n");
2097 if ((amount = count % secsize) != 0) {
2098 amount = secsize - amount;
2100 printf("\nWARNING: padding up to secsize.\n");
2104 secspt = count / secsize;
2106 * If tracksize is not known (trackp->tracksize < 0)
2107 * we may need to set trackp->padsize
2108 * if the tracksize is less than 300 sectors.
2110 if (trackp->padsecs == 0 &&
2111 (is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
2115 amount = write_secs(usalp, dp, bp, startsec, bytespt, secspt, islast);
2117 printf("%swrite track data: error after %lld bytes\n",
2118 neednl?"\n":"", bytes);
2122 startsec += amount / secsize;
2124 if (lverbose && (bytes >= (savbytes + 0x100000))) {
2126 int nsecs = (bytes - savbytes) / secsize;
2129 gettimeofday(&tcur, (struct timezone *)0);
2130 printf("\rTrack %02d: %4lld", track, bytes >> 20);
2132 printf(" of %4lld MB", tracksize >> 20);
2136 fper = fifo_percent(TRUE);
2138 printf(" (fifo %3d%%)", fper);
2140 if (bsize > 0) { /* buffer size known */
2142 per = (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree);
2145 per = 100*(bsize - bfree) / bsize;
2146 if ((bsize - bfree) <= amount || per <= 5)
2147 dp->cdr_dstat->ds_buflow++;
2148 if (per < (int)dp->cdr_dstat->ds_minbuf &&
2149 (startsec*secsize) > bsize) {
2150 dp->cdr_dstat->ds_minbuf = per;
2152 printf(" [buf %3d%%]", per);
2154 printf(" %3ld %3ld", bsize >> 10, bfree >> 10);
2160 tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
2161 tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
2162 while (tlast.tv_usec < 0) {
2163 tlast.tv_usec += 1000000;
2166 fspeed = (nsecs / secsps) /
2167 (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
2171 if (bsize > 0 && per > dminbuf &&
2172 dp->cdr_dstat->ds_cdrflags & RF_WR_WAIT) {
2173 int wsecs = (per-dminbuf)*(bsize/secsize)/100;
2174 int msecs = 0x100000/secsize;
2177 int s = dp->cdr_dstat->ds_dr_cur_wspeed;
2181 if (dp->cdr_dstat->ds_flags & DSF_DVD)
2186 if (wsecs > msecs) /* Less that 1 MB */
2188 wt = wsecs * 1000 / secsps / fspeed;
2189 mt = (per-dminbuf)*(bsize/secsize)/100 * 1000 / secsps/s;
2193 if (wt > 1000) /* Max 1 second */
2195 if (wt < 20) /* Min 20 ms */
2199 printf(" |%3d %4dms %5dms|", wsecs, wt, mt);
2201 printf(" |%3d %4dms|", wsecs, wt);
2206 if (dp->is_dvd) fspeed /= 9;
2207 printf(" %5.1fx", fspeed);
2209 savbytes = (bytes >> 20) << 20;
2215 if (bsize > 0) { /* buffer size known */
2216 (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree);
2217 per = 100*(bsize - bfree) / bsize;
2219 printf("[buf %3d%%] %3ld %3ld\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",
2220 per, bsize >> 10, bfree >> 10);
2227 } while (tracksize < 0 || bytes_read < tracksize);
2229 if (!is_shorttrk(trackp) && (bytes / secsize) < 300) {
2231 * If tracksize is not known (trackp->tracksize < 0) or
2232 * for some strange reason we did not set padsecs properly
2233 * we may need to modify trackp->padsecs if
2234 * tracksize+padsecs is less than 300 sectors.
2236 if ((trackp->padsecs + (bytes / secsize)) < 300)
2237 trackp->padsecs = 300 - (bytes / secsize);
2239 if (trackp->padsecs > 0) {
2243 * pad_track() is based on secsize. Compute the amount of bytes
2244 * assumed by pad_track().
2246 padbytes = (Llong)trackp->padsecs * secsize;
2252 if ((padbytes >> 20) > 0) {
2254 } else if (lverbose) {
2255 printf("Track %02d: writing %3lld KB of pad data.\n",
2256 track, (Llong)(padbytes >> 10));
2259 pad_track(usalp, dp, trackp, startsec, padbytes,
2262 startsec += savbytes / secsize;
2264 printf("%sTrack %02d: Total bytes read/written: %lld/%lld (%lld sectors).\n",
2265 neednl?"\n":"", track, bytes_read, bytes, bytes/secsize);
2271 pad_track(SCSI *usalp, cdr_t *dp, track_t *trackp, long startsec, Llong amt,
2272 BOOL dolast, Llong *bytesp)
2274 int track = trackp->trackno;
2277 Llong padsize = amt;
2282 BOOL neednl = FALSE;
2283 BOOL islast = FALSE;
2284 struct timeval tlast;
2285 struct timeval tcur;
2286 float secsps = 75.0;
2297 if (dp->cdr_dstat->ds_flags & DSF_DVD)
2301 if ((*dp->cdr_buffer_cap)(usalp, &bsize, &bfree) < 0)
2303 if (bsize == 0) /* If we have no (known) buffer, we cannot */
2304 bsize = -1L; /* retrieve the buffer fill ratio */
2307 secsize = trackp->secsize;
2308 secspt = trackp->secspt;
2309 bytespt = secsize * secspt;
2311 fillbytes(buf, bytespt, '\0');
2313 if ((amt >> 20) > 0) {
2314 printf("\rTrack %02d: 0 of %4lld MB pad written.",
2318 gettimeofday(&tlast, (struct timezone *)0);
2320 if (amt < bytespt) {
2321 bytespt = roundup(amt, secsize);
2322 secspt = bytespt / secsize;
2324 if (dolast && (amt - bytespt) <= 0)
2327 if (is_raw(trackp)) {
2328 encsectors(trackp, (Uchar *)buf, startsec, secspt);
2329 fillsubch(trackp, (Uchar *)buf, startsec, secspt);
2332 amount = write_secs(usalp, dp, buf, startsec, bytespt, secspt, islast);
2334 printf("%swrite track pad data: error after %lld bytes\n",
2335 neednl?"\n":"", bytes);
2338 (*dp->cdr_buffer_cap)(usalp, (long *)0, (long *)0);
2343 startsec += amount / secsize;
2345 if (lverbose && (bytes >= (savbytes + 0x100000))) {
2346 int nsecs = (bytes - savbytes) / secsize;
2349 gettimeofday(&tcur, (struct timezone *)0);
2350 printf("\rTrack %02d: %4lld", track, bytes >> 20);
2352 printf(" of %4lld MB", padsize >> 20);
2355 printf(" pad written");
2356 savbytes = (bytes >> 20) << 20;
2359 if (bsize > 0) { /* buffer size known */
2361 per = (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree);
2364 per = 100*(bsize - bfree) / bsize;
2365 if ((bsize - bfree) <= amount || per <= 5)
2366 dp->cdr_dstat->ds_buflow++;
2367 if (per < (int)dp->cdr_dstat->ds_minbuf &&
2368 (startsec*secsize) > bsize) {
2369 dp->cdr_dstat->ds_minbuf = per;
2371 printf(" [buf %3d%%]", per);
2373 printf(" %3ld %3ld", bsize >> 10, bfree >> 10);
2378 tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
2379 tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
2380 while (tlast.tv_usec < 0) {
2381 tlast.tv_usec += 1000000;
2384 fspeed = (nsecs / secsps) /
2385 (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
2388 printf(" %5.1fx", fspeed);
2400 return (bytes > 0 ? 1:-1);
2403 #ifdef USE_WRITE_BUF
2405 write_buf(SCSI *usalp, cdr_t *dp, track_t *trackp, char *bp, long startsec,
2406 Llong amt, int secsize, BOOL dolast, Llong *bytesp)
2408 int track = trackp->trackno;
2415 BOOL neednl = FALSE;
2416 BOOL islast = FALSE;
2418 /* secsize = trackp->secsize;*/
2419 /* secspt = trackp->secspt;*/
2421 secspt = bufsize/secsize;
2422 secspt = min(255, secspt);
2423 bytespt = secsize * secspt;
2425 /* fillbytes(buf, bytespt, '\0');*/
2427 if ((amt >> 20) > 0) {
2428 printf("\rTrack %02d: 0 of %4ld MB pad written.",
2433 if (amt < bytespt) {
2434 bytespt = roundup(amt, secsize);
2435 secspt = bytespt / secsize;
2437 if (dolast && (amt - bytespt) <= 0)
2440 amount = write_secs(usalp, dp, bp, startsec, bytespt, secspt, islast);
2442 printf("%swrite track data: error after %ld bytes\n",
2443 neednl?"\n":"", bytes);
2446 (*dp->cdr_buffer_cap)(usalp, (long *)0, (long *)0);
2451 startsec += amount / secsize;
2453 if (lverbose && (bytes >= (savbytes + 0x100000))) {
2454 printf("\rTrack %02d: %3ld", track, bytes >> 20);
2455 savbytes = (bytes >> 20) << 20;
2465 #endif /* USE_WRITE_BUF */
2468 printdata(int track, track_t *trackp)
2470 if (trackp->itracksize >= 0) {
2471 printf("Track %02d: data %4lld MB ",
2472 track, (Llong)(trackp->itracksize >> 20));
2474 printf("Track %02d: data unknown length",
2477 if (trackp->padsecs > 0) {
2478 Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize;
2480 if ((padbytes >> 20) > 0)
2481 printf(" padsize: %4lld MB", (Llong)(padbytes >> 20));
2483 printf(" padsize: %4lld KB", (Llong)(padbytes >> 10));
2485 if (trackp->pregapsize != (trackp->flags & TI_DVD)? 0 : 150) {
2486 printf(" pregapsize: %3ld", trackp->pregapsize);
2489 printf(" START: %ld SECTORS: %ld INDEX0 %ld",
2490 trackp->trackstart, trackp->tracksecs, trackp->index0start);
2495 printaudio(int track, track_t *trackp)
2497 if (trackp->itracksize >= 0) {
2498 printf("Track %02d: audio %4lld MB (%02d:%02d.%02d) %spreemp%s%s",
2499 track, (Llong)(trackp->itracksize >> 20),
2500 minutes(trackp->itracksize),
2501 seconds(trackp->itracksize),
2502 hseconds(trackp->itracksize),
2503 is_preemp(trackp) ? "" : "no ",
2504 is_swab(trackp) ? " swab":"",
2505 ((trackp->itracksize < 300L*trackp->isecsize) ||
2506 (trackp->itracksize % trackp->isecsize)) &&
2507 is_pad(trackp) ? " pad" : "");
2509 printf("Track %02d: audio unknown length %spreemp%s%s",
2510 track, is_preemp(trackp) ? "" : "no ",
2511 is_swab(trackp) ? " swab":"",
2512 (trackp->itracksize % trackp->isecsize) && is_pad(trackp) ? " pad" : "");
2514 if (is_scms(trackp))
2516 else if (is_copy(trackp))
2521 if (trackp->padsecs > 0) {
2522 Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize;
2524 if ((padbytes >> 20) > 0)
2525 printf(" padsize: %4lld MB", (Llong)(padbytes >> 20));
2527 printf(" padsize: %4lld KB", (Llong)(padbytes >> 10));
2528 printf(" (%02d:%02d.%02d)",
2529 Sminutes(trackp->padsecs),
2530 Sseconds(trackp->padsecs),
2531 Shseconds(trackp->padsecs));
2533 if (trackp->pregapsize != ((trackp->flags & TI_DVD)? 0 : 150) || xdebug > 0) {
2534 printf(" pregapsize: %3ld", trackp->pregapsize);
2537 printf(" START: %ld SECTORS: %ld INDEX0 %ld",
2538 trackp->trackstart, trackp->tracksecs, trackp->index0start);
2543 checkfile(int track, track_t *trackp)
2545 if (trackp->itracksize > 0 &&
2547 ((!is_shorttrk(trackp) &&
2548 (trackp->itracksize < 300L*trackp->isecsize)) ||
2549 (trackp->itracksize % trackp->isecsize)) &&
2551 errmsgno(EX_BAD, "Bad audio track size %lld for track %02d.\n",
2552 (Llong)trackp->itracksize, track);
2553 errmsgno(EX_BAD, "Audio tracks must be at least %ld bytes and a multiple of %d.\n",
2554 300L*trackp->isecsize, trackp->isecsize);
2556 if (!is_shorttrk(trackp) && (trackp->itracksize < 300L*trackp->isecsize))
2557 comerrno(EX_BAD, "See -shorttrack option.\n");
2558 if (!is_pad(trackp) && (trackp->itracksize % trackp->isecsize))
2559 comerrno(EX_BAD, "See -pad option.\n");
2562 if (lverbose == 0 && xdebug == 0)
2565 if (is_audio(trackp))
2566 printaudio(track, trackp);
2568 printdata(track, trackp);
2572 checkfiles(int tracks, track_t *trackp)
2577 int endtrack = tracks;
2581 * Include Lead-in & Lead-out.
2586 for (i = starttrack; i <= endtrack; i++) {
2587 if (!is_audio(&trackp[i]))
2590 printf("SECTYPE %X ", trackp[i].sectype);
2591 checkfile(i, &trackp[i]);
2597 setleadinout(int tracks, track_t *trackp)
2600 * Set some values for track 0 (the lead-in)
2602 if (!is_clone(&trackp[0])) {
2603 trackp[0].sectype = trackp[1].sectype;
2604 trackp[0].dbtype = trackp[1].dbtype;
2605 trackp[0].dataoff = trackp[1].dataoff;
2608 * XXX Which other flags should be copied to Track 0 ?
2610 if (is_audio(&trackp[1]))
2611 trackp[0].flags |= TI_AUDIO;
2615 * Set some values for track 0xAA (the lead-out)
2617 trackp[tracks+1].pregapsize = 0;
2618 trackp[tracks+1].isecsize = trackp[tracks].isecsize;
2619 trackp[tracks+1].secsize = trackp[tracks].secsize;
2621 if (!is_clone(&trackp[0])) {
2622 trackp[tracks+1].tracktype = trackp[tracks].tracktype;
2623 trackp[tracks+1].sectype = trackp[tracks].sectype;
2624 trackp[tracks+1].dbtype = trackp[tracks].dbtype;
2625 trackp[tracks+1].dataoff = trackp[tracks].dataoff;
2628 trackp[tracks+1].flags = trackp[tracks].flags;
2632 setpregaps(int tracks, track_t *trackp)
2639 sectype = trackp[1].sectype;
2642 for (i = 1; i <= tracks; i++) {
2644 if (tp->pregapsize == -1L) {
2645 tp->pregapsize = 150; /* Default CD Pre GAP*/
2646 if (trackp->flags & TI_DVD) {
2648 } else if (sectype != (tp->sectype & ST_MASK)) {
2649 tp->pregapsize = 255; /* Pre GAP is 255 */
2650 tp->flags &= ~TI_PREGAP;
2653 sectype = tp->sectype & ST_MASK; /* Save old sectype */
2655 trackp[tracks+1].pregapsize = 0;
2656 trackp[tracks+1].index0start = 0;
2658 for (i = 1; i <= tracks; i++) {
2660 * index0start is set below tracksecks if this track contains
2661 * the pregap (index 0) of the next track.
2663 trackp[i].index0start = trackp[i].tracksecs;
2665 pregapsize = trackp[i+1].pregapsize;
2666 if (is_pregap(&trackp[i+1]) && pregapsize > 0)
2667 trackp[i].index0start -= pregapsize;
2672 * Check total size of the medium
2675 checktsize(int tracks, track_t *trackp)
2679 Llong total = -150; /* CD track #1 pregap compensation */
2683 if (trackp->flags & TI_DVD)
2685 for (i = 1; i <= tracks; i++) {
2688 total += tp->pregapsize;
2691 printf("track: %d start: %lld pregap: %ld\n",
2692 i, total, tp->pregapsize);
2694 tp->trackstart = total;
2695 if (tp->itracksize >= 0) {
2696 curr = (tp->itracksize + (tp->isecsize-1)) / tp->isecsize;
2697 curr += tp->padsecs;
2699 * Minimum track size is 4s
2701 if (!is_shorttrk(tp) && curr < 300)
2703 if ((trackp->flags & TI_DVD) == 0) {
2705 * XXX Was passiert hier bei is_packet() ???
2707 if (is_tao(tp) && !is_audio(tp)) {
2712 } else if (is_sao(tp) || is_raw(tp)) {
2713 errmsgno(EX_BAD, "Track %d has unknown length.\n", i);
2715 "Use tsize= option in %s mode to specify track size.\n",
2716 is_sao(tp) ? "SAO" : "RAW");
2720 tp->trackstart = total;
2721 tp->tracksecs = 6750; /* Size of first session Lead-Out */
2725 if (trackp->flags & TI_DVD)
2726 btotal = (Ullong)total * 2048;
2728 btotal = (Ullong)total * 2352;
2729 /* XXX CD Sector Size ??? */
2731 if (trackp->flags & TI_DVD) {
2732 printf("Total size: %4llu MB = %lld sectors\n",
2733 btotal >> 20, total);
2735 printf("Total size: %4llu MB (%02d:%02d.%02d) = %lld sectors\n",
2739 hseconds(btotal), total);
2740 btotal += 150 * 2352;
2741 printf("Lout start: %4llu MB (%02d:%02d/%02d) = %lld sectors\n",
2745 frames(btotal), total);
2752 opentracks(track_t *trackp)
2756 int tracks = trackp[0].tracks;
2761 for (i = 1; i <= tracks; i++) {
2764 if (auinfosize(tp->filename, tp)) {
2768 tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0);
2769 } else if (strcmp("-", tp->filename) == 0) {
2773 tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0);
2775 if ((tp->xfp = xopen(tp->filename,
2776 O_RDONLY|O_BINARY, 0)) == NULL) {
2777 comerr("Cannot open '%s'.\n", tp->filename);
2782 tracksize = tp->itracksize;
2783 secsize = tp->isecsize;
2784 if (!is_shorttrk(tp) &&
2785 tracksize > 0 && (tracksize / secsize) < 300) {
2787 tracksize = roundup(tracksize, secsize);
2789 (tracksize / secsize)) < 300) {
2791 300 - tracksize / secsize;
2794 printf("TRACK %d SECTORS: %ld",
2796 printf(" pasdize %lld (%ld sectors)\n",
2797 (Llong)tp->padsecs * secsize,
2802 if (tp->flags & TI_USEINFO) {
2803 auinfo(tp->filename, i, trackp);
2804 if (lverbose > 0 && i == 1)
2805 printf("pregap1: %ld\n", trackp[1].pregapsize);
2809 * tracksecks is total numbers of sectors in track (starting from
2812 if (tp->padsecs > 0)
2813 tp->tracksecs += tp->padsecs;
2816 printf("File: '%s' itracksize: %lld isecsize: %d tracktype: %d = %s sectype: %X = %s dbtype: %s flags %X\n",
2817 tp->filename, (Llong)tp->itracksize,
2819 tp->tracktype & TOC_MASK, toc2name[tp->tracktype & TOC_MASK],
2820 tp->sectype, st2name[tp->sectype & ST_MASK], db2name[tp->dbtype], tp->flags);
2826 checksize(track_t *trackp)
2832 if (trackp->xfp != NULL)
2833 f = xfileno(trackp->xfp);
2836 * If the current input file is a regular file and
2837 * 'padsize=' has not been specified,
2838 * use fstat() or file parser to get the size of the file.
2840 if (trackp->itracksize < 0 && (trackp->flags & TI_ISOSIZE) != 0) {
2842 trackp->itracksize = lsize;
2843 if (trackp->itracksize != lsize)
2844 comerrno(EX_BAD, "This OS cannot handle large ISO-9660 images.\n");
2846 if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
2848 trackp->itracksize = lsize;
2849 if (trackp->itracksize != lsize)
2850 comerrno(EX_BAD, "This OS cannot handle large audio images.\n");
2852 if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
2854 trackp->itracksize = lsize;
2855 if (trackp->itracksize != lsize)
2856 comerrno(EX_BAD, "This OS cannot handle large WAV images.\n");
2857 if (trackp->itracksize > 0) /* Force little endian input */
2858 trackp->flags |= TI_SWAB;
2860 if (trackp->itracksize == AU_BAD_CODING) {
2861 comerrno(EX_BAD, "Inappropriate audio coding in '%s'.\n",
2864 if (trackp->itracksize < 0 &&
2865 fstat(f, &st) >= 0 && S_ISREG(st.st_mode)) {
2866 trackp->itracksize = st.st_size;
2868 if (trackp->itracksize >= 0) {
2870 * We do not allow cdrecord to start if itracksize is not
2871 * a multiple of isecsize or we are allowed to pad to secsize via -pad.
2872 * For this reason, we may safely always assume padding.
2874 trackp->tracksecs = (trackp->itracksize + trackp->isecsize -1) / trackp->isecsize;
2875 trackp->tracksize = (trackp->itracksize / trackp->isecsize) * trackp->secsize
2876 + trackp->itracksize % trackp->isecsize;
2878 trackp->tracksecs = -1L;
2883 checkdsize(SCSI *usalp, cdr_t *dp, long tsize, int flags)
2887 dstat_t *dsp = dp->cdr_dstat;
2891 (*dp->cdr_next_wr_address)(usalp, (track_t *)0, &startsec);
2895 * This only should happen when the drive is currently in SAO mode.
2896 * We rely on the drive being in TAO mode, a negative value for
2897 * startsec is not correct here it may be caused by bad firmware or
2898 * by a drive in SAO mode. In SAO mode the drive will report the
2899 * pre-gap as part of the writable area.
2905 * Size limitations (sectors) for CD's:
2907 * 404850 == 90 min Red book calls this the
2908 * first negative time
2909 * allows lead out start up to
2912 * 449850 == 100 min This is the first time that
2913 * is no more representable
2914 * in a two digit BCD number.
2915 * allows lead out start up to
2918 * ~540000 == 120 min The largest CD ever made.
2920 * ~650000 == 1.3 GB a Double Density (DD) CD.
2923 endsec = startsec + tsize;
2924 dsp->ds_startsec = startsec;
2925 dsp->ds_endsec = endsec;
2928 if (dsp->ds_maxblocks > 0) {
2930 * dsp->ds_maxblocks > 0 (disk capacity is known).
2933 printf("Blocks total: %ld Blocks current: %ld Blocks remaining: %ld\n",
2934 (long)dsp->ds_maxblocks,
2935 (long)dsp->ds_maxblocks - startsec,
2936 (long)dsp->ds_maxblocks - endsec);
2938 if (endsec > dsp->ds_maxblocks) {
2939 if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */
2941 * There is no overburning on DVD...
2944 "Data does not fit on current disk.\n");
2948 "WARNING: Data may not fit on current disk.\n");
2950 /* XXX Check for flags & CDR_NO_LOLIMIT */
2953 if (lverbose && dsp->ds_maxrblocks > 0)
2954 printf("RBlocks total: %ld RBlocks current: %ld RBlocks remaining: %ld\n",
2955 (long)dsp->ds_maxrblocks,
2956 (long)dsp->ds_maxrblocks - startsec,
2957 (long)dsp->ds_maxrblocks - endsec);
2958 if (dsp->ds_maxrblocks > 0 && endsec > dsp->ds_maxrblocks) {
2960 "Data does not fit on current disk.\n");
2963 if ((endsec > dsp->ds_maxblocks && endsec > 404700) ||
2964 (dsp->ds_maxrblocks > 404700 && 449850 > dsp->ds_maxrblocks)) {
2966 * Assume that this must be a CD and not a DVD.
2967 * So this is a non Red Book compliant CD with a
2968 * capacity between 90 and 99 minutes.
2970 if (dsp->ds_maxrblocks > 404700)
2971 printf("RedBook total: %ld RedBook current: %ld RedBook remaining: %ld\n",
2975 if (endsec > dsp->ds_maxblocks && endsec > 404700) {
2976 if ((flags & (F_IGNSIZE|F_FORCE)) == 0) {
2978 "Notice: Most recorders cannot write CD's >= 90 minutes.\n");
2980 "Notice: Use -ignsize option to allow >= 90 minutes.\n");
2987 * dsp->ds_maxblocks == 0 (disk capacity is unknown).
2989 profile = dp->profile;
2990 if (endsec >= (4200000)) {
2992 "ERROR: Could not manage to find medium size, and more than 8.0 GB of data.\n");
2994 } else if (profile != 0x2B) {
2995 if (endsec >= (2300000)) {
2997 "ERROR: Could not manage to find medium size, and more than 4.3 GB of data for a non dual layer disc.\n");
2999 } else if (endsec >= (405000-300)) { /*<90 min disk or DVD*/
3001 "WARNING: Could not manage to find medium size, and more than 90 mins of data.\n");
3002 } else if (endsec >= (333000-150)) { /* 74 min disk*/
3004 "WARNING: Data may not fit on standard 74min disk.\n");
3008 if (dsp->ds_maxblocks <= 0 || endsec <= dsp->ds_maxblocks)
3012 if (dsp->ds_maxblocks > 0 && endsec > dsp->ds_maxblocks) {
3013 if ((flags & (F_OVERBURN|F_IGNSIZE|F_FORCE)) != 0) {
3014 if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */
3016 "Notice: -overburn is not expected to work with DVD media.\n");
3019 "Notice: Overburning active. Trying to write more than the official disk capacity.\n");
3022 if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */
3024 "Notice: Use -overburn option to write more than the official disk capacity.\n");
3026 "Notice: Most CD-writers do overburning only on SAO or RAW mode.\n");
3031 if (dsp->ds_maxblocks < 449850) {
3032 if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */
3033 if (endsec <= dsp->ds_maxblocks)
3035 errmsgno(EX_BAD, "Cannot write more than remaining DVD capacity.\n");
3039 * Assume that this must be a CD and not a DVD.
3041 if (endsec > 449700) {
3042 errmsgno(EX_BAD, "Cannot write CD's >= 100 minutes.\n");
3046 if ((flags & (F_IGNSIZE|F_FORCE)) != 0)
3054 #ifdef RLIMIT_NOFILE
3059 * Set max # of file descriptors to be able to hold all files open
3061 getrlimit(RLIMIT_NOFILE, &rlim);
3062 if (rlim.rlim_cur >= (MAX_TRACK + 10))
3065 rlim.rlim_cur = MAX_TRACK + 10;
3066 if (rlim.rlim_cur > rlim.rlim_max)
3068 "Warning: low file descriptor limit (%lld)\n",
3069 (Llong)rlim.rlim_max);
3070 setrlimit(RLIMIT_NOFILE, &rlim);
3072 #endif /* RLIMIT_NOFILE */
3078 #ifdef RLIMIT_MEMLOCK
3081 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
3083 if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0)
3084 errmsg("Warning: Cannot raise RLIMIT_MEMLOCK limits.\n");
3085 #endif /* RLIMIT_MEMLOCK */
3089 "help,version,checkdrive,prcap,inq,devices,scanbus,reset,abort,overburn,ignsize,useinfo,dev*,timeout#,driver*,driveropts*,setdropts,tsize&,padsize&,pregap&,defpregap&,speed#,load,lock,eject,dummy,msinfo,toc,atip,multi,fix,nofix,waiti,immed,debug#,d+,kdebug#,kd#,verbose+,v+,Verbose+,V+,x+,xd#,silent,s,audio,data,mode2,xa,xa1,xa2,xamix,cdi,isosize,nopreemp,preemp,nocopy,copy,nopad,pad,swab,fs&,ts&,blank&,format,formattype&,pktsize#,packet,noclose,force,tao,dao,sao,raw,raw96r,raw96p,raw16,clone,scms,isrc*,mcn*,index*,cuefile*,textfile*,text,shorttrack,noshorttrack,gracetime#,minbuf#,msifile*";
3092 * Defines used to find whether a write mode has been specified.
3094 #define M_TAO 1 /* Track at Once mode */
3095 #define M_SAO 2 /* Session at Once mode (also known as DAO) */
3096 #define M_RAW 4 /* Raw mode */
3097 #define M_PACKET 8 /* Packed mode */
3099 gargs(int ac, char **av, int *tracksp, track_t *trackp, char **devp,
3100 int *timeoutp, cdr_t **dpp, int *speedp, long *flagsp, int *blankp,
3105 char *driver = NULL;
3109 char *tindex = NULL;
3110 char *cuefile = NULL;
3111 char *textfile = NULL;
3114 int formattype = -1;
3118 long defpregap = -1L;
3177 int tracks = *tracksp;
3178 int tracktype = TOC_ROM;
3179 /* int sectype = ST_ROM_MODE1 | ST_MODE_1;*/
3180 int sectype = SECT_ROM;
3181 int dbtype = DB_ROM_MODE1;
3182 int secsize = DATA_SEC_SIZE;
3187 trackp[0].flags |= TI_TAO;
3188 trackp[1].pregapsize = -1;
3193 for (; ; cac--, cav++) {
3194 tracksize = (Llong)-1L;
3195 padsize = (Llong)0L;
3196 pregapsize = defpregap;
3197 audio = data = mode2 = xa = xa1 = xa2 = xamix = cdi = 0;
3198 isize = nopreemp = nocopy = nopad = noshorttrack = 0;
3203 * Get options up to next file type arg.
3205 if ((ga_ret = getargs(&cac, &cav, opts,
3206 &help, &version, &checkdrive, &prcap,
3207 &inq, &scandevs, &scanbus, &reset, &doabort, &overburn, &ignsize,
3209 devp, timeoutp, &driver, &driveropts, &setdropts,
3210 getllnum, &tracksize,
3212 getnum, &pregapsize,
3216 &eject, &dummy, &msinfo, &toc, &atip,
3217 &multi, &fix, &nofix, &waiti, &immed,
3220 &lverbose, &lverbose,
3221 &scsi_verbose, &scsi_verbose,
3224 &audio, &data, &mode2,
3225 &xa, &xa1, &xa2, &xamix, &cdi,
3229 &nopad, &pad, &bswab, getnum, &fs, getnum, &bufsize,
3230 getbltype, &bltype, &doformat, getformattype, &formattype, &pktsize,
3231 &ispacket, &noclose, &force,
3232 &tao, &dao, &dao, &raw, &raw96r, &raw96p, &raw16,
3234 &scms, &isrc, &mcn, &tindex,
3235 &cuefile, &textfile, &usetext,
3236 &shorttrack, &noshorttrack,
3237 &gracetime, &dminbuf, &msifile)) < 0) {
3238 errmsgno(EX_BAD, "Bad Option: %s.\n", cav[0]);
3245 set_cdrcmds(driver, dpp);
3247 *flagsp |= F_VERSION;
3249 *flagsp |= F_CHECKDRIVE;
3253 *flagsp |= F_INQUIRY;
3254 if (scanbus || scandevs) /* scandevs behaves similarly WRT in the legacy code, just the scan operation is different */
3255 *flagsp |= F_SCANBUS;
3261 *flagsp |= F_OVERBURN;
3263 *flagsp |= F_IGNSIZE;
3273 *flagsp |= F_SETDROPTS;
3277 *flagsp |= F_MSINFO;
3280 *flagsp &= ~F_WRITE;
3283 *flagsp |= F_PRATIP;
3284 *flagsp &= ~F_WRITE;
3288 * 2048 Bytes user data
3291 tracktype = TOC_XA2;
3292 sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
3293 sectype = SECT_MODE_2_F1;
3294 dbtype = DB_XA_MODE2; /* XXX -multi nimmt DB_XA_MODE2_F1 !!! */
3295 secsize = DATA_SEC_SIZE; /* 2048 */
3314 *flagsp |= F_FORMAT;
3315 *formatp |= FULL_FORMAT;
3317 if (formattype >= 0) {
3318 *flagsp |= F_FORMAT;
3319 *formatp |= formattype;
3327 trackp[0].flags &= ~TI_TAO;
3328 trackp[0].flags |= TI_SAO;
3331 } else if ((raw == 0) && (raw96r + raw96p + raw16) > 0)
3333 if ((raw != 0) && (raw96r + raw96p + raw16) == 0)
3338 trackp[0].flags &= ~TI_TAO;
3339 trackp[0].flags |= TI_RAW;
3340 trackp[0].flags |= TI_RAW96R;
3346 trackp[0].flags &= ~TI_TAO;
3347 trackp[0].flags |= TI_RAW;
3353 trackp[0].flags &= ~TI_TAO;
3354 trackp[0].flags |= TI_RAW;
3355 trackp[0].flags |= TI_RAW16;
3360 setmcn(mcn, &trackp[0]);
3362 trackp[0].isrc = malloc(16);
3363 fillbytes(trackp[0].isrc, 16, '\0');
3364 strncpy(trackp[0].isrc, mcn, 13);
3368 if ((raw96r + raw96p + raw16) > 1) {
3369 errmsgno(EX_BAD, "Too many raw modes.\n");
3370 comerrno(EX_BAD, "Only one of -raw16, -raw96p, -raw96r allowed.\n");
3372 if ((tao + ispacket + dao + raw) > 1) {
3373 errmsgno(EX_BAD, "Too many write modes.\n");
3374 comerrno(EX_BAD, "Only one of -packet, -dao, -raw allowed.\n");
3376 if (dao && (raw96r + raw96p + raw16) > 0) {
3378 comerrno(EX_BAD, "SAO RAW writing does not allow -raw16.\n");
3380 comerrno(EX_BAD, "SAO RAW writing only makes sense in clone mode.\n");
3382 comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n");
3384 comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n");
3388 trackp[0].flags |= TI_CLONE;
3390 comerrno(EX_BAD, "Clone writing not compiled in.\n");
3394 if (!checktextfile(textfile)) {
3395 if ((*flagsp & F_WRITE) != 0) {
3397 "Cannot use '%s' as CD-Text file.\n",
3401 if ((*flagsp & F_WRITE) != 0) {
3402 if ((dao + raw96r + raw96p) == 0)
3404 "CD-Text needs -dao, -raw96r or -raw96p.\n");
3406 trackp[0].flags |= TI_TEXT;
3408 version = checkdrive = prcap = inq = scanbus = reset = doabort =
3409 overburn = ignsize =
3410 load = lock = eject = dummy = msinfo = toc = atip = multi = fix = nofix =
3411 waiti = immed = force = dao = setdropts = 0;
3412 raw96r = raw96p = raw16 = clone = 0;
3413 } else if ((version + checkdrive + prcap + inq + scanbus +
3414 reset + doabort + overburn + ignsize +
3415 load + lock + eject + dummy + msinfo + toc + atip + multi + fix + nofix +
3416 waiti + immed + force + dao + setdropts +
3417 raw96r + raw96p + raw16 + clone) > 0 ||
3419 comerrno(EX_BAD, "Badly placed option. Global options must be before any track.\n");
3430 if ((audio + data + mode2 + xa + xa1 + xa2 + xamix) > 1) {
3431 errmsgno(EX_BAD, "Too many types for track %d.\n", tracks+1);
3432 comerrno(EX_BAD, "Only one of -audio, -data, -mode2, -xa, -xa1, -xa2, -xamix allowed.\n");
3434 if (ispacket && audio) {
3435 comerrno(EX_BAD, "Audio data cannot be written in packet mode.\n");
3438 * Check whether the next argument is a file type arg.
3439 * If this is true, then we got a track file name.
3440 * If getargs() did previously return NOTAFLAG, we may have hit
3441 * an argument that has been escaped via "--", so we may not
3442 * call getfiles() again in this case. If we would call
3443 * getfiles() and the current arg has been escaped and looks
3444 * like an option, a call to getfiles() would skip it.
3446 if (ga_ret != NOTAFLAG)
3447 ga_ret = getfiles(&cac, &cav, opts);
3450 tracktype = TOC_ROM;
3451 sectype = ST_ROM_MODE1 | ST_MODE_1;
3453 dbtype = DB_ROM_MODE1;
3454 secsize = DATA_SEC_SIZE; /* 2048 */
3457 if (ga_ret == NOTAFLAG && (is_auname(cav[0]) || is_wavname(cav[0]))) {
3459 * We got a track and autodetection decided that it
3460 * is an audio track.
3467 * 2048 Bytes user data
3469 tracktype = TOC_ROM;
3470 sectype = ST_ROM_MODE1 | ST_MODE_1;
3472 dbtype = DB_ROM_MODE1;
3473 secsize = DATA_SEC_SIZE; /* 2048 */
3478 * 2336 Bytes user data
3480 tracktype = TOC_ROM;
3481 sectype = ST_ROM_MODE2 | ST_MODE_2;
3482 sectype = SECT_MODE_2;
3483 dbtype = DB_ROM_MODE2;
3484 secsize = MODE2_SEC_SIZE; /* 2336 */
3489 * 2352 Bytes user data
3492 sectype = preemp ? ST_AUDIO_PRE : ST_AUDIO_NOPRE;
3493 sectype |= ST_MODE_AUDIO;
3494 sectype = SECT_AUDIO;
3496 sectype |= ST_PREEMPMASK;
3498 secsize = AUDIO_SEC_SIZE; /* 2352 */
3503 * 2048 Bytes user data
3505 if (tracktype != TOC_CDI)
3506 tracktype = TOC_XA2;
3507 sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
3508 sectype = SECT_MODE_2_F1;
3509 dbtype = DB_XA_MODE2;
3510 secsize = DATA_SEC_SIZE; /* 2048 */
3515 * 8 Bytes subheader + 2048 Bytes user data
3517 if (tracktype != TOC_CDI)
3518 tracktype = TOC_XA2;
3519 sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
3520 sectype = SECT_MODE_2_F1;
3521 dbtype = DB_XA_MODE2_F1;
3527 * 2324 Bytes user data
3529 if (tracktype != TOC_CDI)
3530 tracktype = TOC_XA2;
3531 sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_2;
3532 sectype = SECT_MODE_2_F2;
3533 dbtype = DB_XA_MODE2_F2;
3539 * 8 Bytes subheader + 2324 Bytes user data
3541 if (tracktype != TOC_CDI)
3542 tracktype = TOC_XA2;
3543 sectype = ST_ROM_MODE2 | ST_MODE_2_MIXED;
3544 sectype = SECT_MODE_2_MIX;
3545 dbtype = DB_XA_MODE2_MIX;
3550 tracktype = TOC_CDI;
3553 trackp[0].tracktype = tracktype;
3554 trackp[0].dbtype = dbtype;
3555 trackp[0].isecsize = secsize;
3556 trackp[0].secsize = secsize;
3557 if ((*flagsp & F_RAW) != 0) {
3558 trackp[0].secsize = is_raw16(&trackp[0]) ?
3559 RAW16_SEC_SIZE:RAW96_SEC_SIZE;
3561 if ((*flagsp & F_DUMMY) != 0)
3562 trackp[0].tracktype |= TOCF_DUMMY;
3563 if ((*flagsp & F_MULTI) != 0)
3564 trackp[0].tracktype |= TOCF_MULTI;
3567 flags = trackp[0].flags;
3569 if ((sectype & ST_AUDIOMASK) != 0)
3572 flags |= TI_ISOSIZE;
3573 if ((*flagsp & F_MULTI) != 0)
3574 comerrno(EX_BAD, "Cannot get isosize for multi session disks.\n");
3576 * As we do not get the padding from the ISO-9660
3577 * formatting utility, we need to force padding here.
3580 if (padsize == (Llong)0L)
3581 padsize = (Llong)PAD_SIZE;
3584 if ((flags & TI_AUDIO) != 0) {
3592 if (pad || ((flags & TI_AUDIO) == 0 && padsize > (Llong)0L)) {
3594 if ((flags & TI_AUDIO) == 0 && padsize == (Llong)0L)
3595 padsize = (Llong)PAD_SIZE;
3597 if (shorttrack && (*flagsp & (F_SAO|F_RAW)) != 0)
3598 flags |= TI_SHORT_TRACK;
3600 flags &= ~TI_SHORT_TRACK;
3605 trackp[0].flags &= ~TI_TAO;
3608 flags |= TI_NOCLOSE;
3610 flags |= TI_USEINFO;
3612 if (ga_ret == NOARGS) {
3614 * All options have already been parsed and no more
3615 * file type arguments are present.
3619 if (tracks == 0 && (wm == 0)) {
3620 errmsgno(EX_BAD, "No write mode specified.\n");
3621 errmsgno(EX_BAD, "Assuming -tao mode.\n");
3622 errmsgno(EX_BAD, "Future versions of wodim may have different drive dependent defaults.\n");
3627 if (tracks > MAX_TRACK)
3628 comerrno(EX_BAD, "Track limit (%d) exceeded\n",
3631 * Make 'tracks' immediately usable in track structure.
3634 for (i = 0; i < MAX_TRACK+2; i++)
3635 trackp[i].tracks = tracks;
3638 if (strcmp("-", cav[0]) == 0)
3641 if (!is_auname(cav[0]) && !is_wavname(cav[0]))
3642 flags |= TI_NOAUHDR;
3644 if ((*flagsp & (F_SAO|F_RAW)) != 0 && (flags & TI_AUDIO) != 0)
3645 flags |= TI_PREGAP; /* Hack for now */
3647 flags &= ~TI_PREGAP;
3649 if (tracks == 1 && (pregapsize != -1L && pregapsize != 150))
3651 trackp[tracks].filename = cav[0];
3652 trackp[tracks].trackstart = 0L;
3653 trackp[tracks].itracksize = tracksize;
3654 trackp[tracks].tracksize = tracksize;
3655 trackp[tracks].tracksecs = -1L;
3656 if (tracksize >= 0) {
3657 trackp[tracks].tracksecs = (tracksize+secsize-1)/secsize;
3658 if(tracksize<616448)
3659 warn_minisize=tracksize;
3661 if (trackp[tracks].pregapsize < 0)
3662 trackp[tracks].pregapsize = pregapsize;
3663 trackp[tracks+1].pregapsize = -1;
3664 trackp[tracks].padsecs = (padsize+2047)/2048;
3665 trackp[tracks].isecsize = secsize;
3666 trackp[tracks].secsize = secsize;
3667 trackp[tracks].flags = flags;
3669 * XXX Dies ist falsch: auch bei SAO/RAW kann
3670 * XXX secsize != isecsize sein.
3672 if ((*flagsp & F_RAW) != 0) {
3673 if (is_raw16(&trackp[tracks]))
3674 trackp[tracks].secsize = RAW16_SEC_SIZE;
3676 trackp[tracks].secsize = RAW96_SEC_SIZE;
3677 #ifndef HAVE_LIB_EDC_ECC
3678 if ((sectype & ST_MODE_MASK) != ST_MODE_AUDIO) {
3680 "EDC/ECC library not compiled in.\n");
3682 "Data sectors are not supported in RAW mode.\n");
3686 trackp[tracks].secspt = 0; /* transfer size is set up in set_trsizes() */
3687 trackp[tracks].pktsize = pktsize;
3688 trackp[tracks].trackno = tracks;
3689 trackp[tracks].sectype = sectype;
3691 if ((*flagsp & F_CLONE) != 0) {
3692 trackp[tracks].isecsize = 2448;
3693 trackp[tracks].sectype |= ST_MODE_RAW;
3697 trackp[tracks].dataoff = dataoff;
3698 trackp[tracks].tracktype = tracktype;
3699 trackp[tracks].dbtype = dbtype;
3700 trackp[tracks].flags = flags;
3701 trackp[tracks].nindex = 1;
3702 trackp[tracks].tindex = 0;
3705 setisrc(isrc, &trackp[tracks]);
3707 trackp[tracks].isrc = malloc(16);
3708 fillbytes(trackp[tracks].isrc, 16, '\0');
3709 strncpy(trackp[tracks].isrc, isrc, 12);
3714 setindex(tindex, &trackp[tracks]);
3720 if (dminbuf < 25 || dminbuf > 95)
3722 "Bad minbuf=%d option (must be between 25 and 95)\n",
3726 if (speed < 0 && speed != -1)
3727 comerrno(EX_BAD, "Bad speed option.\n");
3729 if (fs < 0L && fs != -1L)
3730 comerrno(EX_BAD, "Bad fifo size option.\n");
3732 if (bufsize < 0L && bufsize != -1L)
3733 comerrno(EX_BAD, "Bad transfer size option.\n");
3735 bufsize = CDR_BUF_SIZE;
3736 if (bufsize > CDR_MAX_BUF_SIZE)
3737 bufsize = CDR_MAX_BUF_SIZE;
3740 cdr_defaults(&dev, &speed, &fs, &driveropts);
3742 printf("dev: '%s' speed: %d fs: %ld driveropts '%s'\n",
3743 dev, speed, fs, driveropts);
3749 fs = DEFAULT_FIFOSIZE;
3750 if (fs < 2*bufsize) {
3751 errmsgno(EX_BAD, "Fifo size %ld too small, turning fifo off.\n", fs);
3755 if (dev != *devp && (*flagsp & F_SCANBUS) == 0)
3759 ((strncmp(*devp, "HELP", 4) == 0) ||
3760 (strncmp(*devp, "help", 4) == 0))) {
3761 *flagsp |= F_CHECKDRIVE; /* Set this for not calling mlockall() */
3764 if (*flagsp & (F_LOAD|F_DLCK|F_SETDROPTS|F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_PRCAP|F_INQUIRY|F_SCANBUS|F_RESET|F_ABORT)) {
3767 "No tracks allowed with -load, -lock, -setdropts, -msinfo, -toc, -atip, -fix,\n"
3768 "-version, -checkdrive, -prcap, -inq, -scanbus, --devices, -reset and -abort options.\n" );
3774 if (*flagsp & F_SAO) {
3776 * Make sure that you change WRITER_MAXWAIT & READER_MAXWAIT
3777 * too if you change this timeout.
3779 if (*timeoutp < 200) /* Lead in size is 2:30 */
3780 *timeoutp = 200; /* 200s is 150s *1.33 */
3783 trackp[MAX_TRACK+1].flags |= TI_TEXT;
3787 if ((*flagsp & F_SAO) == 0 &&
3788 (*flagsp & F_RAW) == 0) {
3790 if ((*flagsp & F_SAO) == 0) {
3792 errmsgno(EX_BAD, "The cuefile= option only works with -dao.\n");
3796 errmsgno(EX_BAD, "No tracks allowed with the cuefile= option\n");
3799 cuefilename = cuefile;
3802 if (tracks == 0 && (*flagsp & (F_LOAD|F_DLCK|F_EJECT|F_BLANK|F_FORMAT)) == 0) {
3803 errmsgno(EX_BAD, "No tracks specified. Need at least one.\n");
3810 set_trsizes(cdr_t *dp, int tracks, track_t *trackp)
3816 trackp[1].flags |= TI_FIRST;
3817 trackp[tracks].flags |= TI_LAST;
3820 printf("Set Transfersizes start\n");
3821 for (i = 0; i <= tracks+1; i++) {
3822 if ((dp->cdr_flags & CDR_SWABAUDIO) != 0 &&
3823 is_audio(&trackp[i])) {
3824 trackp[i].flags ^= TI_SWAB;
3826 if (!is_audio(&trackp[i]))
3827 trackp[i].flags &= ~TI_SWAB; /* Only swab audio */
3830 * Use the biggest sector size to compute how many
3831 * sectors may fit into one single DMA buffer.
3833 secsize = trackp[i].secsize;
3834 if (trackp[i].isecsize > secsize)
3835 secsize = trackp[i].isecsize;
3838 * We are using SCSI Group 0 write
3839 * and cannot write more than 255 secs at once.
3841 secspt = bufsize/secsize;
3842 secspt = min(255, secspt);
3843 trackp[i].secspt = secspt;
3845 if (is_packet(&trackp[i]) && trackp[i].pktsize > 0) {
3846 if (trackp[i].secspt >= trackp[i].pktsize) {
3847 trackp[i].secspt = trackp[i].pktsize;
3850 "Track %d packet size %d exceeds buffer limit of %d sectors",
3851 i, trackp[i].pktsize, trackp[i].secspt);
3855 printf("Track %d flags %X secspt %d secsize: %d isecsize: %d\n",
3856 i, trackp[i].flags, trackp[i].secspt,
3857 trackp[i].secsize, trackp[i].isecsize);
3861 printf("Set Transfersizes end\n");
3865 load_media(SCSI *usalp, cdr_t *dp, BOOL doexit)
3869 BOOL immed = (dp->cdr_cmdflags&F_IMMED) != 0;
3872 * Do some preparation before...
3874 usalp->silent++; /* Be quiet if this fails */
3875 test_unit_ready(usalp); /* First eat up unit attention */
3876 if ((*dp->cdr_load)(usalp, dp) < 0) { /* now try to load media and */
3879 comerrno(EX_BAD, "Cannot load media.\n");
3881 scsi_start_stop_unit(usalp, 1, 0, immed); /* start unit in silent mode */
3884 if (!wait_unit_ready(usalp, 60)) {
3885 code = usal_sense_code(usalp);
3886 key = usal_sense_key(usalp);
3888 scsi_prevent_removal(usalp, 0); /* In case someone locked it */
3893 if (key == SC_NOT_READY && (code == 0x3A || code == 0x30))
3894 comerrno(EX_BAD, "No disk / Wrong disk!\n");
3895 comerrno(EX_BAD, "CD/DVD-Recorder not ready.\n");
3898 scsi_prevent_removal(usalp, 1);
3899 scsi_start_stop_unit(usalp, 1, 0, immed);
3900 wait_unit_ready(usalp, 120);
3902 if(geteuid() == 0) /* EB: needed? Not allowed for non-root, that is sure. */
3903 rezero_unit(usalp); /* Is this needed? Not supported by some drvives */
3905 test_unit_ready(usalp);
3906 scsi_start_stop_unit(usalp, 1, 0, immed);
3907 wait_unit_ready(usalp, 120);
3911 unload_media(SCSI *usalp, cdr_t *dp, int flags)
3913 scsi_prevent_removal(usalp, 0);
3914 if ((flags & F_EJECT) != 0) {
3915 if ((*dp->cdr_unload)(usalp, dp) < 0)
3916 errmsgno(EX_BAD, "Cannot eject media.\n");
3921 reload_media(SCSI *usalp, cdr_t *dp)
3928 errmsgno(EX_BAD, "Drive needs to reload the media to return to proper status.\n");
3929 unload_media(usalp, dp, F_EJECT);
3932 * Note that even Notebook drives identify as CDR_TRAYLOAD
3934 if ((dp->cdr_flags & CDR_TRAYLOAD) != 0) {
3936 load_media(usalp, dp, FALSE);
3941 if (((dp->cdr_flags & CDR_TRAYLOAD) == 0) ||
3942 !wait_unit_ready(usalp, 5)) {
3943 static FILE *tty = NULL;
3945 printf("Re-load disk and hit <CR>");
3952 if ((dp->cdr_cmdflags & F_STDIN) != 0)
3953 tty = fileluopen(STDERR_FILENO, "rw");
3957 f = fcntl(fileno(tty), F_GETFL, 0);
3958 if (f < 0 || (f & O_ACCMODE) == O_WRONLY) {
3960 signal(SIGUSR1, catchsig);
3961 printf("Controlling file not open for reading, send SIGUSR1 to continue.\n");
3967 if (rols_fgetline(tty, ans, 1) < 0)
3968 comerrno(EX_BAD, "Aborted by EOF on input.\n");
3972 load_media(usalp, dp, TRUE);
3976 set_secsize(SCSI *usalp, int secsize)
3980 * Try to restore the old sector size.
3983 select_secsize(usalp, secsize);
3989 get_dmaspeed(SCSI *usalp, cdr_t *dp)
3996 if(getenv("CDR_NODMATEST"))
3999 if (debug || lverbose)
4001 "Beginning DMA speed test. Set CDR_NODMATEST environment variable if device\n"
4002 "communication breaks or freezes immediately after that.\n" );
4004 fillbytes((caddr_t)buf, 4, '\0');
4007 i = read_buffer(usalp, buf, 4, 0);
4011 tsize = a_to_u_4_byte(buf);
4015 if (gettimeofday(&starttime, (struct timezone *)0) < 0)
4021 for (i = 0; i < 100; i++) {
4022 if (read_buffer(usalp, buf, bs, 0) < 0)
4025 if (gettimeofday(&fixtime, (struct timezone *)0) < 0) {
4026 errmsg("Cannot get DMA stop time\n");
4029 timevaldiff(&starttime, &fixtime);
4031 t = fixtime.tv_sec * 1000 + fixtime.tv_usec / 1000;
4035 fprintf(stderr, "Read Speed: %lu %ld %ld kB/s %ldx CD %ldx DVD\n",
4036 tsize, t, tsize/t, tsize/t/176, tsize/t/1385);
4044 do_opc(SCSI *usalp, cdr_t *dp, int flags)
4046 if ((flags & F_DUMMY) == 0 && dp->cdr_opc) {
4047 if (debug || lverbose) {
4048 printf("Performing OPC...\n");
4051 if (dp->cdr_opc(usalp, NULL, 0, TRUE) < 0) {
4052 errmsgno(EX_BAD, "OPC failed.\n");
4053 if ((flags & F_FORCE) == 0)
4061 check_recovery(SCSI *usalp, cdr_t *dp, int flags)
4063 if ((*dp->cdr_check_recovery)(usalp, dp)) {
4064 errmsgno(EX_BAD, "Recovery needed.\n");
4065 unload_media(usalp, dp, flags);
4074 audioread(SCSI *usalp, cdr_t *dp, int flags)
4078 int oflags = dp->cdr_cmdflags;
4080 dp->cdr_cmdflags &= ~F_DUMMY;
4081 if ((*dp->cdr_set_speed_dummy)(usalp, dp, &speed) < 0)
4083 dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
4084 dp->cdr_cmdflags = oflags;
4086 if ((*dp->cdr_set_secsize)(usalp, 2352) < 0)
4088 usalp->cap->c_bsize = 2352;
4090 read_scsi(usalp, buf, 1000, 1);
4092 write(1, buf, 512); /* FIXME: handle return value */
4093 unload_media(usalp, dp, flags);
4099 print_msinfo(SCSI *usalp, cdr_t *dp)
4104 if ((*dp->cdr_session_offset)(usalp, &off) < 0) {
4105 errmsgno(EX_BAD, "Cannot read session offset\n");
4109 printf("session offset: %ld\n", off);
4111 if (dp->cdr_next_wr_address(usalp, (track_t *)0, &fa) < 0) {
4112 errmsgno(EX_BAD, "Cannot read first writable address\n");
4115 printf("%ld,%ld\n", off, fa);
4117 FILE *f = fopen(msifile, "w");
4119 fprintf(f, "%ld,%ld", off, fa);
4123 perror("Unable to write multi session info file");
4130 print_toc(SCSI *usalp, cdr_t *dp)
4143 if (read_capacity(usalp) < 0) {
4145 errmsgno(EX_BAD, "Cannot read capacity\n");
4149 if (read_tochdr(usalp, dp, &first, &last) < 0) {
4150 errmsgno(EX_BAD, "Cannot read TOC/PMA\n");
4153 printf("first: %d last %d\n", first, last);
4154 for (i = first; i <= last; i++) {
4155 read_trackinfo(usalp, i, &lba, &msf, &adr, &control, &mode);
4157 msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
4160 print_track(i, lba, &msf, adr, control, mode);
4163 read_trackinfo(usalp, i, &lba, &msf, &adr, &control, &mode);
4165 msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
4168 print_track(i, lba, &msf, adr, control, mode);
4171 if (read_cdtext(usalp) < 0)
4172 errmsgno(EX_BAD, "No CD-Text or CD-Text unaware drive.\n");
4178 print_track(int track, long lba, struct msf *msp, int adr,
4179 int control, int mode)
4181 long lba_512 = lba*4;
4184 printf("track:lout ");
4186 printf("track: %3d ", track);
4188 printf("lba: %9ld (%9ld) %02d:%02d:%02d adr: %X control: %X mode: %d\n",
4193 adr, control, mode);
4196 #ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */
4198 #include <sys/procset.h> /* Needed for SCO Openserver */
4199 #include <sys/priocntl.h>
4200 #include <sys/rtpriocntl.h>
4216 strcpy(info.pc_clname, "RT");
4217 classes = priocntl(P_PID, pid, PC_GETCID, (void *)&info);
4219 comerr("Cannot get priority class id priocntl(PC_GETCID)\n");
4221 movebytes(info.pc_clinfo, &rtinfo, sizeof (rtinfo_t));
4223 /* set priority to max */
4224 rtparam.rt_pri = rtinfo.rt_maxpri - pri;
4225 rtparam.rt_tqsecs = 0;
4226 rtparam.rt_tqnsecs = RT_TQDEF;
4227 param.pc_cid = info.pc_cid;
4228 movebytes(&rtparam, param.pc_clparms, sizeof (rtparms_t));
4229 ret = priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m);
4231 errmsg("WARNING: Cannot set priority class parameters priocntl(PC_SETPARMS)\n");
4232 errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
4236 #else /* HAVE_SYS_PRIOCNTL_H */
4238 #if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0
4240 * The second best choice: POSIX real time scheduling.
4243 * XXX Ugly but needed because of a typo in /usr/iclude/sched.h on Linux.
4244 * XXX This should be removed as soon as we are sure that Linux-2.0.29 is gone.
4257 rt_raisepri(int pri)
4259 struct sched_param scp;
4262 * Verify that scheduling is available
4264 #ifdef _SC_PRIORITY_SCHEDULING
4265 if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) {
4266 errmsg("WARNING: RR-scheduler not available, disabling.\n");
4270 fillbytes(&scp, sizeof (scp), '\0');
4271 scp.sched_priority = sched_get_priority_max(SCHED_RR) - pri;
4272 if (sched_setscheduler(0, SCHED_RR, &scp) < 0) {
4274 errmsg("WARNING: Cannot set RR-scheduler\n");
4280 #else /* _POSIX_PRIORITY_SCHEDULING */
4284 * Win32 specific priority settings.
4287 * NOTE: Base.h from Cygwin-B20 has a second typedef for BOOL.
4288 * We define BOOL to make all static code use BOOL
4289 * from Windows.h and use the hidden __SBOOL for
4290 * our global interfaces.
4292 * NOTE: windows.h from Cygwin-1.x includes a structure field named sample,
4293 * so me may not define our own 'sample' or need to #undef it now.
4294 * With a few nasty exceptions, Microsoft assumes that any global
4295 * defines or identifiers will begin with an Uppercase letter, so
4296 * there may be more of these problems in the future.
4298 * NOTE: windows.h defines interface as an alias for struct, this
4299 * is used by COM/OLE2, I guess it is class on C++
4300 * We man need to #undef 'interface'
4302 #define BOOL WBOOL /* This is the Win BOOL */
4303 #define format __format /* Avoid format parameter hides global ... */
4304 #include <windows.h>
4309 rt_raisepri(int pri)
4311 int prios[] = {THREAD_PRIORITY_TIME_CRITICAL, THREAD_PRIORITY_HIGHEST};
4313 /* set priority class */
4314 if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) {
4315 if(debug || lverbose>2)
4316 errmsgno(EX_BAD, "No realtime priority class possible.\n");
4320 /* set thread priority */
4321 if (pri >= 0 && pri <= 1 && SetThreadPriority(GetCurrentThread(), prios[pri]) == FALSE) {
4322 errmsgno(EX_BAD, "Could not set realtime priority.\n");
4330 * This OS does not support real time scheduling.
4333 rt_raisepri(int pri)
4338 #endif /* __CYGWIN32__ */
4340 #endif /* _POSIX_PRIORITY_SCHEDULING */
4345 if (rt_raisepri(pri) >= 0)
4347 #if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
4349 if (setpriority(PRIO_PROCESS, getpid(), -20 + pri) < 0) {
4350 if(debug || lverbose>2)
4352 "WARNING: Cannot set priority using setpriority(),"
4353 "increased risk for buffer underruns.\n");
4356 #ifdef HAVE_DOSSETPRIORITY /* RT priority on OS/2 */
4358 * Set priority to timecritical 31 - pri (arg)
4360 DosSetPriority(0, 3, 31, 0);
4361 DosSetPriority(0, 3, -pri, 0);
4363 #if defined(HAVE_NICE) && !defined(__DJGPP__) /* DOS has nice but no multitasking */
4364 if (nice(-20 + pri) == -1) {
4365 errmsg("WARNING: Cannot set priority using nice().\n");
4366 errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
4369 errmsgno(EX_BAD, "WARNING: Cannot set priority on this OS.\n");
4370 errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
4376 #endif /* HAVE_SYS_PRIOCNTL_H */
4380 * sys/types.h and sys/time.h are already included.
4383 # include <stropts.h>
4391 #if defined(HAVE_SELECT) && defined(NEED_SYS_SELECT_H)
4392 #include <sys/select.h>
4394 #if defined(HAVE_SELECT) && defined(NEED_SYS_SOCKET_H)
4395 #include <sys/socket.h>
4405 FD_SET(STDIN_FILENO, &in);
4406 select(1, &in, NULL, NULL, 0);
4410 pfd.fd = STDIN_FILENO;
4411 pfd.events = POLLIN;
4413 poll(&pfd, (unsigned long)1, INFTIM);
4422 if (fstat(STDERR_FILENO, &st) >= 0 && !S_ISCHR(st.st_mode)) {
4425 printf("Using remote (pipe) mode for interactive i/o.\n");
4430 getbltype(char *optstr, long *typep)
4432 if (streql(optstr, "all")) {
4433 *typep = BLANK_DISC;
4434 } else if (streql(optstr, "disc")) {
4435 *typep = BLANK_DISC;
4436 } else if (streql(optstr, "disk")) {
4437 *typep = BLANK_DISC;
4438 } else if (streql(optstr, "fast")) {
4439 *typep = BLANK_MINIMAL;
4440 } else if (streql(optstr, "minimal")) {
4441 *typep = BLANK_MINIMAL;
4442 } else if (streql(optstr, "track")) {
4443 *typep = BLANK_TRACK;
4444 } else if (streql(optstr, "unreserve")) {
4445 *typep = BLANK_UNRESERVE;
4446 } else if (streql(optstr, "trtail")) {
4447 *typep = BLANK_TAIL;
4448 } else if (streql(optstr, "unclose")) {
4449 *typep = BLANK_UNCLOSE;
4450 } else if (streql(optstr, "session")) {
4451 *typep = BLANK_SESSION;
4452 } else if (streql(optstr, "help")) {
4455 fprintf(stderr, "Illegal blanking type '%s'.\n", optstr);
4463 getformattype(char *optstr, long *typep)
4465 if (streql(optstr, "full")) {
4466 *typep = FULL_FORMAT;
4467 } else if (streql(optstr, "background")) {
4468 *typep = BACKGROUND_FORMAT;
4469 } else if (streql(optstr, "force")) {
4470 *typep = FORCE_FORMAT;
4471 } else if (streql(optstr, "help")) {
4474 fprintf(stderr, "Illegal blanking type '%s'.\n", optstr);
4475 formattypeusage(EX_BAD);
4481 print_drflags(cdr_t *dp)
4483 printf("Driver flags : ");
4485 if ((dp->cdr_flags & CDR_DVD) != 0)
4488 if ((dp->cdr_flags & CDR_MMC3) != 0)
4490 else if ((dp->cdr_flags & CDR_MMC2) != 0)
4492 else if ((dp->cdr_flags & CDR_MMC) != 0)
4495 if ((dp->cdr_flags & CDR_SWABAUDIO) != 0)
4496 printf("SWABAUDIO ");
4497 if ((dp->cdr_flags & CDR_BURNFREE) != 0)
4498 printf("BURNFREE ");
4499 if ((dp->cdr_flags & CDR_VARIREC) != 0)
4501 if ((dp->cdr_flags & CDR_GIGAREC) != 0)
4503 if ((dp->cdr_flags & CDR_AUDIOMASTER) != 0)
4504 printf("AUDIOMASTER ");
4505 if ((dp->cdr_flags & CDR_FORCESPEED) != 0)
4506 printf("FORCESPEED ");
4507 if ((dp->cdr_flags & CDR_SPEEDREAD) != 0)
4508 printf("SPEEDREAD ");
4509 if ((dp->cdr_flags & CDR_DISKTATTOO) != 0)
4510 printf("DISKTATTOO ");
4511 if ((dp->cdr_flags & CDR_SINGLESESS) != 0)
4512 printf("SINGLESESSION ");
4513 if ((dp->cdr_flags & CDR_HIDE_CDR) != 0)
4519 print_wrmodes(cdr_t *dp)
4521 BOOL needblank = FALSE;
4523 printf("Supported modes: ");
4524 if ((dp->cdr_flags & CDR_TAO) != 0) {
4528 if ((dp->cdr_flags & CDR_PACKET) != 0) {
4529 printf("%sPACKET", needblank?" ":"");
4532 if ((dp->cdr_flags & CDR_SAO) != 0) {
4533 printf("%sSAO", needblank?" ":"");
4537 if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW16)) == (CDR_SAO|CDR_SRAW16)) {
4538 printf("%sSAO/R16", needblank?" ":"");
4542 if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96P)) == (CDR_SAO|CDR_SRAW96P)) {
4543 printf("%sSAO/R96P", needblank?" ":"");
4546 if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96R)) == (CDR_SAO|CDR_SRAW96R)) {
4547 printf("%sSAO/R96R", needblank?" ":"");
4550 if ((dp->cdr_flags & (CDR_RAW|CDR_RAW16)) == (CDR_RAW|CDR_RAW16)) {
4551 printf("%sRAW/R16", needblank?" ":"");
4554 if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96P)) == (CDR_RAW|CDR_RAW96P)) {
4555 printf("%sRAW/R96P", needblank?" ":"");
4558 if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96R)) == (CDR_RAW|CDR_RAW96R)) {
4559 printf("%sRAW/R96R", needblank?" ":"");
4566 check_wrmode(cdr_t *dp, int wmode, int tflags)
4568 int cdflags = dp->cdr_flags;
4570 if ((tflags & TI_PACKET) != 0 && (cdflags & CDR_PACKET) == 0) {
4571 errmsgno(EX_BAD, "Drive does not support PACKET recording.\n");
4574 if ((tflags & TI_TAO) != 0 && (cdflags & CDR_TAO) == 0) {
4575 errmsgno(EX_BAD, "Drive does not support TAO recording.\n");
4578 if ((wmode & F_SAO) != 0) {
4579 if ((cdflags & CDR_SAO) == 0) {
4580 errmsgno(EX_BAD, "Drive does not support SAO recording.\n");
4581 if ((cdflags & CDR_RAW) != 0)
4582 errmsgno(EX_BAD, "Try -raw option.\n");
4586 if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_SRAW16) == 0) {
4587 errmsgno(EX_BAD, "Drive does not support SAO/RAW16.\n");
4591 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_SRAW96P) == 0) {
4592 errmsgno(EX_BAD, "Drive does not support SAO/RAW96P.\n");
4595 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_SRAW96R) == 0) {
4596 errmsgno(EX_BAD, "Drive does not support SAO/RAW96R.\n");
4600 if ((wmode & F_RAW) != 0) {
4601 if ((cdflags & CDR_RAW) == 0) {
4602 errmsgno(EX_BAD, "Drive does not support RAW recording.\n");
4605 if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_RAW16) == 0) {
4606 errmsgno(EX_BAD, "Drive does not support RAW/RAW16.\n");
4609 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_RAW96P) == 0) {
4610 errmsgno(EX_BAD, "Drive does not support RAW/RAW96P.\n");
4613 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_RAW96R) == 0) {
4614 errmsgno(EX_BAD, "Drive does not support RAW/RAW96R.\n");
4621 if ((wmode & F_SAO) != 0)
4622 cdflags &= ~(CDR_RAW16|CDR_RAW96P|CDR_RAW96R);
4623 if ((wmode & F_RAW) != 0)
4624 cdflags &= ~(CDR_SRAW96P|CDR_SRAW96R);
4626 if ((cdflags & (CDR_SRAW96R|CDR_RAW96R)) != 0)
4627 errmsgno(EX_BAD, "Try -raw96r option.\n");
4628 else if ((cdflags & (CDR_SRAW96P|CDR_RAW96P)) != 0)
4629 errmsgno(EX_BAD, "Try -raw96p option.\n");
4630 else if ((cdflags & CDR_RAW16) != 0)
4631 errmsgno(EX_BAD, "Try -raw16 option.\n");
4636 set_wrmode(cdr_t *dp, int wmode, int tflags)
4638 dstat_t *dsp = dp->cdr_dstat;
4640 if ((tflags & TI_PACKET) != 0) {
4641 dsp->ds_wrmode = WM_PACKET;
4644 if ((tflags & TI_TAO) != 0) {
4645 dsp->ds_wrmode = WM_TAO;
4648 if ((wmode & F_SAO) != 0) {
4649 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == 0) {
4650 dsp->ds_wrmode = WM_SAO;
4653 if ((tflags & TI_RAW16) != 0) { /* Is this needed? */
4654 dsp->ds_wrmode = WM_SAO_RAW16;
4657 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) {
4658 dsp->ds_wrmode = WM_SAO_RAW96P;
4661 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) {
4662 dsp->ds_wrmode = WM_SAO_RAW96R;
4666 if ((wmode & F_RAW) != 0) {
4667 if ((tflags & TI_RAW16) != 0) {
4668 dsp->ds_wrmode = WM_RAW_RAW16;
4671 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) {
4672 dsp->ds_wrmode = WM_RAW_RAW96P;
4675 if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) {
4676 dsp->ds_wrmode = WM_RAW_RAW96R;
4680 dsp->ds_wrmode = WM_NONE;
4683 #if defined(linux) || defined(__linux) || defined(__linux__)
4685 #include <sys/utsname.h>
4691 get_cap(cap_value_t cap_array)
4695 capa = cap_get_proc();
4696 cap_set_flag(capa, CAP_EFFECTIVE, 1, &cap_array, CAP_SET);
4697 ret = cap_set_proc(capa);