[Debburn-changes] r415 - in cdrkit/trunk: . cdda2wav cdrecord
debian mkisofs readcd scgcheck scgskeleton
Eduard Bloch
blade at alioth.debian.org
Tue Nov 21 19:34:30 CET 2006
Author: blade
Date: 2006-11-21 19:34:28 +0100 (Tue, 21 Nov 2006)
New Revision: 415
Added:
cdrkit/trunk/cdrecord/wodim.c
cdrkit/trunk/cdrecord/wodim.h
Removed:
cdrkit/trunk/cdrecord/cdrecord.c
cdrkit/trunk/cdrecord/cdrecord.h
Modified:
cdrkit/trunk/CMakeLists.txt
cdrkit/trunk/cdda2wav/interface.c
cdrkit/trunk/cdda2wav/ioctl.c
cdrkit/trunk/cdda2wav/scsi_cmds.c
cdrkit/trunk/cdrecord/auinfo.c
cdrkit/trunk/cdrecord/cd_misc.c
cdrkit/trunk/cdrecord/cdr_drv.c
cdrkit/trunk/cdrecord/cdtext.c
cdrkit/trunk/cdrecord/clone.c
cdrkit/trunk/cdrecord/cue.c
cdrkit/trunk/cdrecord/diskid.c
cdrkit/trunk/cdrecord/drv_7501.c
cdrkit/trunk/cdrecord/drv_jvc.c
cdrkit/trunk/cdrecord/drv_mmc.c
cdrkit/trunk/cdrecord/drv_philips.c
cdrkit/trunk/cdrecord/drv_simul.c
cdrkit/trunk/cdrecord/drv_sony.c
cdrkit/trunk/cdrecord/fifo.c
cdrkit/trunk/cdrecord/isosize.c
cdrkit/trunk/cdrecord/modes.c
cdrkit/trunk/cdrecord/movesect.c
cdrkit/trunk/cdrecord/scsi_cdr.c
cdrkit/trunk/cdrecord/scsi_cdr_mmc4.c
cdrkit/trunk/cdrecord/scsi_mmc.c
cdrkit/trunk/cdrecord/scsi_mmc4.c
cdrkit/trunk/cdrecord/scsi_scan.c
cdrkit/trunk/cdrecord/sector.c
cdrkit/trunk/cdrecord/subchan.c
cdrkit/trunk/cdrecord/wm_packet.c
cdrkit/trunk/cdrecord/wm_session.c
cdrkit/trunk/cdrecord/wm_track.c
cdrkit/trunk/debian/changelog
cdrkit/trunk/mkisofs/scsi.c
cdrkit/trunk/readcd/readcd.c
cdrkit/trunk/scgcheck/dmaresid.c
cdrkit/trunk/scgcheck/scgcheck.c
cdrkit/trunk/scgcheck/sense.c
cdrkit/trunk/scgskeleton/skel.c
Log:
Renaming cdrecord.{c,h} to wodim.{c,h}
Modified: cdrkit/trunk/CMakeLists.txt
===================================================================
--- cdrkit/trunk/CMakeLists.txt 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/CMakeLists.txt 2006-11-21 18:34:28 UTC (rev 415)
@@ -1,5 +1,5 @@
PROJECT (cdrkit)
-SUBDIRS(cdda2wav cdrecord libdeflt libedc libhfs_iso libparanoia libscg libschily libunls mkisofs readcd rscsi 3rd-party/dirsplit include)
+SUBDIRS(cdda2wav wodim libdeflt libedc libhfs_iso libparanoia libscg libschily libunls mkisofs readcd rscsi 3rd-party/dirsplit include)
#ADD_DEFINITIONS(-DSHUT_UP)
Modified: cdrkit/trunk/cdda2wav/interface.c
===================================================================
--- cdrkit/trunk/cdda2wav/interface.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdda2wav/interface.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -92,7 +92,7 @@
#include "scsi_cmds.h"
#include <utypes.h>
-#include <cdrecord.h>
+#include <wodim.h>
#include "scsi_scan.h"
unsigned interface;
Modified: cdrkit/trunk/cdda2wav/ioctl.c
===================================================================
--- cdrkit/trunk/cdda2wav/ioctl.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdda2wav/ioctl.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -68,7 +68,7 @@
#include "exitcodes.h"
#include <utypes.h>
-#include <cdrecord.h>
+#include <wodim.h>
#if defined (HAVE_IOCTL_INTERFACE)
#if !defined(sun) && !defined(__sun) && !(defined(__FreeBSD__) && (__FreeBSD_version >= 501112))
Modified: cdrkit/trunk/cdda2wav/scsi_cmds.c
===================================================================
--- cdrkit/trunk/cdda2wav/scsi_cmds.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdda2wav/scsi_cmds.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -48,7 +48,7 @@
#include "interface.h"
#include "byteorder.h"
#include "global.h"
-#include "cdrecord.h"
+#include "wodim.h"
#include "toc.h"
#include "scsi_cmds.h"
#include "exitcodes.h"
Modified: cdrkit/trunk/cdrecord/auinfo.c
===================================================================
--- cdrkit/trunk/cdrecord/auinfo.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/auinfo.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -45,7 +45,7 @@
#include <schily.h>
#include "cdtext.h"
-#include "cdrecord.h"
+#include "wodim.h"
extern int debug;
extern int xdebug;
Modified: cdrkit/trunk/cdrecord/cd_misc.c
===================================================================
--- cdrkit/trunk/cdrecord/cd_misc.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/cd_misc.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -41,7 +41,7 @@
#include <stdio.h>
#include <schily.h>
-#include "cdrecord.h"
+#include "wodim.h"
int from_bcd(int b);
int to_bcd(int i);
Modified: cdrkit/trunk/cdrecord/cdr_drv.c
===================================================================
--- cdrkit/trunk/cdrecord/cdr_drv.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/cdr_drv.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -46,7 +46,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
extern int xdebug;
Deleted: cdrkit/trunk/cdrecord/cdrecord.c
===================================================================
--- cdrkit/trunk/cdrecord/cdrecord.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/cdrecord.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -1,4659 +0,0 @@
-/*
- * This file has been modified for the cdrkit suite.
- *
- * The behaviour and appearence of the program code below can differ to a major
- * extent from the version distributed by the original author(s).
- *
- * For details, see Changelog file distributed with the cdrkit package. If you
- * received this file from another source then ask the distributing person for
- * a log of modifications.
- *
- */
-
-/*
- *
- * Modified by Eduard Bloch in 08/2006
- */
-
-/* @(#)cdrecord.c 1.310 06/02/09 Copyright 1995-2006 J. Schilling */
-#ifndef lint
-static char sccsid[] =
- "@(#)cdrecord.c 1.310 06/02/09 Copyright 1995-2006 J. Schilling";
-#endif
-/*
- * Record data on a CD/CVD-Recorder
- *
- * Copyright (c) 1995-2006 J. Schilling
- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; see the file COPYING. If not, write to the Free Software
- * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <mconfig.h>
-#include <stdio.h>
-#include <standard.h>
-#include <stdxlib.h>
-#include <fctldefs.h>
-#include <errno.h>
-#include <timedefs.h>
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h> /* for rlimit */
-#endif
-#include <statdefs.h>
-#include <unixstd.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <strdefs.h>
-#include <utypes.h>
-#include <intcvt.h>
-#include <signal.h>
-#include <schily.h>
-#include <getargs.h>
-#ifdef HAVE_PRIV_H
-#include <priv.h>
-#endif
-
-#include "xio.h"
-
-#include <scg/scsireg.h> /* XXX wegen SC_NOT_READY */
-#include <scg/scsitransp.h>
-#include <scg/scgcmd.h> /* XXX fuer read_buffer */
-#include "scsi_scan.h"
-
-#include "auheader.h"
-#include "cdrecord.h"
-#include "defaults.h"
-#include "movesect.h"
-
-#ifdef __linux__
-#include <sys/capability.h> /* for rawio capability */
-#endif
-
-#define cdr_version "1.0"
-
-#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0
-#ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */
-#else
-#define USE_POSIX_PRIORITY_SCHEDULING
-#endif
-#endif
-
-/*
- * Map toc/track types into names.
- */
-char *toc2name[] = {
- "CD-DA",
- "CD-ROM",
- "CD-ROM XA mode 1",
- "CD-ROM XA mode 2",
- "CD-I",
- "Illegal toc type 5",
- "Illegal toc type 6",
- "Illegal toc type 7",
-};
-
-/*
- * Map sector types into names.
- */
-char *st2name[] = {
- "Illegal sector type 0",
- "CD-ROM mode 1",
- "CD-ROM mode 2",
- "Illegal sector type 3",
- "CD-DA without preemphasis",
- "CD-DA with preemphasis",
- "Illegal sector type 6",
- "Illegal sector type 7",
-};
-
-/*
- * Map data block types into names.
- */
-char *db2name[] = {
- "Raw (audio)",
- "Raw (audio) with P/Q sub channel",
- "Raw (audio) with P/W packed sub channel",
- "Raw (audio) with P/W raw sub channel",
- "Reserved mode 4",
- "Reserved mode 5",
- "Reserved mode 6",
- "Vendor unique mode 7",
- "CD-ROM mode 1",
- "CD-ROM mode 2",
- "CD-ROM XA mode 2 form 1",
- "CD-ROM XA mode 2 form 1 (with subheader)",
- "CD-ROM XA mode 2 form 2",
- "CD-ROM XA mode 2 form 1/2/mix",
- "Reserved mode 14",
- "Vendor unique mode 15",
-};
-
-/*
- * Map write modes into names.
- */
-static char wm_none[] = "unknown";
-static char wm_ill[] = "illegal";
-
-char *wm2name[] = {
- wm_none,
- "BLANK",
- "FORMAT",
- wm_ill,
- "PACKET",
- wm_ill,
- wm_ill,
- wm_ill,
- "TAO",
- wm_ill,
- wm_ill,
- wm_ill,
- "SAO",
- "SAO/RAW16", /* Most liklely not needed */
- "SAO/RAW96P",
- "SAO/RAW96R",
- "RAW",
- "RAW/RAW16",
- "RAW/RAW96P",
- "RAW/RAW96R",
-};
-
-int debug; /* print debug messages */
-static int kdebug; /* print kernel debug messages */
-static int scsi_verbose; /* SCSI verbose flag */
-static int silent; /* SCSI silent flag */
-int lverbose; /* static verbose flag */
-int xdebug; /* extended debug flag */
-
-char *buf; /* The transfer buffer */
-long bufsize = -1; /* The size of the transfer buffer */
-
-static int gracetime = GRACE_TIME;
-static int raw_speed = -1;
-static int dma_speed = -1;
-static int dminbuf = -1; /* XXX Hack for now drive min buf fill */
-BOOL isgui;
-static int didintr;
-char *driveropts;
-static char *cuefilename;
-static uid_t oeuid = (uid_t)-1;
-
-struct timeval starttime;
-struct timeval wstarttime;
-struct timeval stoptime;
-struct timeval fixtime;
-
-static long fs = -1L; /* fifo (ring buffer) size */
-
-static int gracewait(cdr_t *dp, BOOL *didgracep);
-static void cdrstats(cdr_t *dp);
-static void susage(int);
-static void usage(int);
-static void blusage(int);
-static void formattypeusage(int);
-static void intr(int sig);
-static void catchsig(int sig);
-static int scsi_cb(void *arg);
-static void intfifo(int sig);
-static void exscsi(int excode, void *arg);
-static void excdr(int excode, void *arg);
-int read_buf(int f, char *bp, int size);
-int fill_buf(int f, track_t *trackp, long secno, char *bp, int size);
-int get_buf(int f, track_t *trackp, long secno, char **bpp, int size);
-int write_secs(SCSI *scgp, cdr_t *dp, char *bp, long startsec, int bytespt,
- int secspt, BOOL islast);
-static int write_track_data(SCSI *scgp, cdr_t *, track_t *);
-int pad_track(SCSI *scgp, cdr_t *dp, track_t *trackp, long startsec,
- Llong amt, BOOL dolast, Llong *bytesp);
-int write_buf(SCSI *scgp, cdr_t *dp, track_t *trackp, char *bp,
- long startsec, Llong amt, int secsize, BOOL dolast,
- Llong *bytesp);
-static void printdata(int, track_t *);
-static void printaudio(int, track_t *);
-static void checkfile(int, track_t *);
-static int checkfiles(int, track_t *);
-static void setleadinout(int, track_t *);
-static void setpregaps(int, track_t *);
-static long checktsize(int, track_t *);
-static void opentracks(track_t *);
-static void checksize(track_t *);
-static BOOL checkdsize(SCSI *scgp, cdr_t *dp, long tsize, int flags);
-static void raise_fdlim(void);
-static void raise_memlock(void);
-static int gargs(int, char **, int *, track_t *, char **, int *, cdr_t **,
- int *, long *, int *, int *);
-static void set_trsizes(cdr_t *, int, track_t *);
-void load_media(SCSI *scgp, cdr_t *, BOOL);
-void unload_media(SCSI *scgp, cdr_t *, int);
-void reload_media(SCSI *scgp, cdr_t *);
-void set_secsize(SCSI *scgp, int secsize);
-static int get_dmaspeed(SCSI *scgp, cdr_t *);
-static BOOL do_opc(SCSI *scgp, cdr_t *, int);
-static void check_recovery(SCSI *scgp, cdr_t *, int);
-void audioread(SCSI *scgp, cdr_t *, int);
-static void print_msinfo(SCSI *scgp, cdr_t *);
-static void print_toc(SCSI *scgp, cdr_t *);
-static void print_track(int, long, struct msf *, int, int, int);
-#if !defined(HAVE_SYS_PRIOCNTL_H)
-static int rt_raisepri(int);
-#endif
-void raisepri(int);
-static void wait_input(void);
-static void checkgui(void);
-static int getbltype(char *optstr, long *typep);
-static int getformattype(char *optstr, long *typep);
-static void print_drflags(cdr_t *dp);
-static void print_wrmodes(cdr_t *dp);
-static BOOL check_wrmode(cdr_t *dp, int wmode, int tflags);
-static void set_wrmode(cdr_t *dp, int wmode, int tflags);
-static void linuxcheck(void);
-
-#ifdef __linux__
-static int get_cap(cap_value_t cap_array);
-#endif
-
-struct exargs {
- SCSI *scgp;
- cdr_t *dp;
- int old_secsize;
- int flags;
- int exflags;
-} exargs;
-
-void fifo_cleanup(void) {
- kill_faio();
-}
-
-int main(int argc, char *argv[])
-{
- char *dev = NULL;
- int timeout = 40; /* Set default timeout to 40s CW-7502 is slow*/
- int speed = -1;
- long flags = 0L;
- int blanktype = 0;
- int formattype = 0;
- int i;
- int tracks = 0;
- int trackno;
- long tsize;
- track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */
- cdr_t *dp = (cdr_t *)0;
- long startsec = 0L;
- int errs = 0;
- SCSI *scgp = NULL;
- char errstr[80];
- BOOL gracedone = FALSE;
- int ispacket;
- BOOL is_cdwr = FALSE;
- BOOL is_dvdwr = FALSE;
-
-
-#ifdef __EMX__
- /* This gives wildcard expansion with Non-Posix shells with EMX */
- _wildcard(&argc, &argv);
-#endif
- save_args(argc, argv);
- oeuid = geteuid(); /* Remember saved set uid */
-
- fillbytes(track, sizeof (track), '\0');
- for (i = 0; i < MAX_TRACK+2; i++)
- track[i].track = track[i].trackno = i;
- track[0].tracktype = TOC_MASK;
- raise_fdlim();
- ispacket = gargs(argc, argv, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
- &blanktype, &formattype);
- if ((track[0].tracktype & TOC_MASK) == TOC_MASK)
- comerrno(EX_BAD, "Internal error: Bad TOC type.\n");
-
- if (flags & F_VERSION) {
- fprintf(stderr,
- "Cdrecord-yelling-line-to-tell-frontends-to-use-it-like-version 2.01.01a03-dvd \n"
- "Wodim " cdr_version "\n"
- "Copyright (C) 2006 Cdrkit suite contributors\n"
- "Based on works from Joerg Schilling, Copyright (C) 1995-2006, J. Schilling\n"
- );
- exit(0);
- }
-
- checkgui();
-
- if (debug || lverbose) {
- printf("TOC Type: %d = %s\n",
- track[0].tracktype & TOC_MASK,
- toc2name[track[0].tracktype & TOC_MASK]);
- }
-
- if ((flags & (F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_INQUIRY|F_SCANBUS|F_RESET)) == 0) {
- /*
- * Try to lock us im memory (will only work for root)
- * but you need access to root anyway to send SCSI commands.
- * We need to be root to open /dev/scg? or similar devices
- * on other OS variants and we need to be root to be able
- * to send SCSI commands at least on AIX and
- * Solaris (USCSI only) regardless of the permissions for
- * opening files
- *
- * XXX The folowing test used to be
- * XXX #if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK)
- * XXX but the definition for _POSIX_MEMLOCK did change during
- * XXX the last 8 years and the autoconf test is better for
- * XXX the static case. sysconf() only makes sense if we like
- * XXX to check dynamically.
- */
- raise_memlock();
-#if defined(HAVE_MLOCKALL)
- /*
- * XXX mlockall() needs root privilleges.
- */
- if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
- errmsg("WARNING: Cannot do mlockall(2).\n");
- errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
- }
-#endif
-
- /*
- * XXX raisepri() needs root privilleges.
- */
- raisepri(0); /* max priority */
- /*
- * XXX shmctl(id, SHM_LOCK, 0) needs root privilleges.
- * XXX So if we use SysV shared memory, wee need to be root.
- *
- * Note that not being able to set up a FIFO bombs us
- * back to the DOS ages. Trying to run cdrecord without
- * root privillegs is extremely silly, it breaks most
- * of the advanced features. We need to be at least installed
- * suid root or called by RBACs pfexec.
- */
- init_fifo(fs); /* Attach shared memory (still one process) */
- }
-
- if ((flags & F_WAITI) != 0) {
- if (lverbose)
- printf("Waiting for data on stdin...\n");
- wait_input();
- }
-
- /*
- * Call scg_remote() to force loading the remote SCSI transport library
- * code that is located in librscg instead of the dummy remote routines
- * that are located inside libscg.
- */
- scg_remote();
- if (dev != NULL &&
- ((strncmp(dev, "HELP", 4) == 0) ||
- (strncmp(dev, "help", 4) == 0))) {
- scg_help(stderr);
- exit(0);
- }
-
- scgp = scg_open(dev, errstr, sizeof (errstr),
- debug, lverbose);
- if(!scgp && dev) {
- char *dalt;
- int len=5+strlen(dev);
- dalt=calloc(len, sizeof(char));
- strcat(dalt, "ATA:");
- strcat(dalt+4, dev);
- scgp = scg_open(dalt, errstr, sizeof (errstr),
- debug, lverbose);
- }
- if(!scgp)
- {
- errmsg("\nCannot open SCSI driver!\n"
- "For possible targets try 'wodim -scanbus'.\n"
- "For possible transport specifiers try 'wodim dev=help'.\n"
- "For IDE/ATAPI devices configuration, see the file README.ATAPI.setup from\n"
- "the wodim documentation.\n");
- exit(EX_BAD);
- }
-#ifdef HAVE_PRIV_SET
-#ifdef PRIV_DEBUG
- fprintf(stderr, "file_dac_read: %d\n", priv_ineffect(PRIV_FILE_DAC_READ));
-#endif
- /*
- * Give up privs we do not need anymore.
- * We no longer need:
- * file_dac_read,proc_lock_memory,proc_priocntl,net_privaddr
- * We still need:
- * sys_devices
- */
- priv_set(PRIV_OFF, PRIV_EFFECTIVE,
- PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
- PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL);
- priv_set(PRIV_OFF, PRIV_PERMITTED,
- PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
- PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL);
- priv_set(PRIV_OFF, PRIV_INHERITABLE,
- PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
- PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL);
-#endif
- /*
- * This is only for OS that do not support fine grained privs.
- *
- * XXX Below this point we do not need root privilleges anymore.
- */
- if (geteuid() != getuid()) { /* AIX does not like to do this */
- /* If we are not root */
-#ifdef HAVE_SETREUID
- if (setreuid(-1, getuid()) < 0)
-#else
-#ifdef HAVE_SETEUID
- if (seteuid(getuid()) < 0)
-#else
- if (setuid(getuid()) < 0)
-#endif
-#endif
- comerr("Panic cannot set back effective uid.\n");
- }
-
-#ifdef __linux__
- /* get the rawio capability */
- if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose))
- {
- perror("Warning: Cannot gain SYS_RAWIO capability");
- fprintf(stderr, "Possible reason: wodim not installed SUID root.\n");
- }
-#endif
-
- /*
- * WARNING: We now are no more able to do any privilleged operation
- * unless we have been called by root.
- *
- * XXX It may be that we later get problems in init_faio() because
- * XXX this function calls raisepri() to lower the priority slightly.
- */
- scg_settimeout(scgp, timeout);
- scgp->verbose = scsi_verbose;
- scgp->silent = silent;
- scgp->debug = debug;
- scgp->kdebug = kdebug;
- scgp->cap->c_bsize = DATA_SEC_SIZE;
-
- if ((flags & F_MSINFO) == 0 || lverbose) {
- char *vers;
- char *auth;
-
- vers = scg_version(0, SCG_VERSION);
- auth = scg_version(0, SCG_AUTHOR);
- if(lverbose >1 && auth && vers)
- fprintf(stderr, "Using libscg version '%s-%s'.\n", auth, vers);
-
-
- vers = scg_version(scgp, SCG_RVERSION);
- auth = scg_version(scgp, SCG_RAUTHOR);
- if (lverbose > 1 && vers && auth)
- fprintf(stderr, "Using remote transport code version '%s-%s'\n", auth, vers);
- }
-
- if (lverbose && driveropts)
- printf("Driveropts: '%s'\n", driveropts);
-
-/* bufsize = scg_bufsize(scgp, CDR_BUF_SIZE);*/
- bufsize = scg_bufsize(scgp, bufsize);
- if (lverbose || debug)
- fprintf(stderr, "SCSI buffer size: %ld\n", bufsize);
- if ((buf = scg_getbuf(scgp, bufsize)) == NULL)
- comerr("Cannot get SCSI I/O buffer.\n");
-
- if ((flags & F_SCANBUS) != 0) {
- select_target(scgp, stdout);
- exit(0);
- }
- if ((flags & F_RESET) != 0) {
- if (scg_reset(scgp, SCG_RESET_NOP) < 0)
- comerr("Cannot reset (OS does not implement reset).\n");
- if (scg_reset(scgp, SCG_RESET_TGT) >= 0)
- exit(0);
- if (scg_reset(scgp, SCG_RESET_BUS) < 0)
- comerr("Cannot reset target.\n");
- exit(0);
- }
-
- /*
- * First try to check which type of SCSI device we
- * have.
- */
- if (debug || lverbose)
- printf("atapi: %d\n", scg_isatapi(scgp));
- scgp->silent++;
- test_unit_ready(scgp); /* eat up unit attention */
- scgp->silent--;
- if (!do_inquiry(scgp, (flags & F_MSINFO) == 0 || lverbose)) {
- errmsgno(EX_BAD, "Cannot do inquiry for CD/DVD-Recorder.\n");
- if (unit_ready(scgp))
- errmsgno(EX_BAD, "The unit seems to be hung and needs power cycling.\n");
- exit(EX_BAD);
- }
-#ifdef GCONF
-/*
- * Debug only
- */
-{
-extern void gconf(SCSI *);
-
-if (lverbose > 2)
- gconf(scgp);
-}
-#endif
-
- if ((flags & F_PRCAP) != 0) {
- print_capabilities(scgp);
- print_capabilities_mmc4(scgp);
- exit(0);
- }
- if ((flags & F_INQUIRY) != 0)
- exit(0);
-
- if (dp == (cdr_t *)NULL) { /* No driver= option specified */
- dp = get_cdrcmds(scgp); /* Calls dp->cdr_identify() */
- } else if (!is_unknown_dev(scgp) && dp != get_cdrcmds(scgp)) {
- errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n");
- }
- is_mmc(scgp, &is_cdwr, &is_dvdwr);
- if (ispacket) {
- if (is_dvdwr) {
- track[0].flags |= TI_PACKET;
- /*XXX put here to only affect DVD writing, should be in gargs.
- * however if set in args for all mode, packet writing is then
- * broken for all disc as cdrecord assume that PACKET imply TAO which
- * is not true at all???? */
- track[0].flags &= ~TI_TAO;
- }
- }
-
- if (dp == (cdr_t *)0)
- comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.\n");
-
- /* DVD does not support TAO */
- if (dp->is_dvd) {
- if(lverbose>1)
- fprintf(stderr, "Using Session At Once (SAO) for DVD mode.\n");
- dp->cdr_flags |= F_SAO;
- for (i = 0; i <= MAX_TRACK; i++) {
- track[i].flags &= ~TI_TAO;
- track[i].flags |= TI_SAO;
- }
- }
-
- if (!is_cddrive(scgp))
- comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n");
- /*
- * The driver is known, set up data structures...
- */
- {
- cdr_t *ndp;
- dstat_t *dsp;
-
- ndp = malloc(sizeof (cdr_t));
- dsp = malloc(sizeof (dstat_t));
- if (ndp == NULL || dsp == NULL)
- comerr("Cannot allocate memory for driver structure.\n");
- movebytes(dp, ndp, sizeof (cdr_t));
- dp = ndp;
- dp->cdr_flags |= CDR_ALLOC;
- dp->cdr_cmdflags = flags;
-
- fillbytes(dsp, sizeof (*dsp), '\0');
- dsp->ds_minbuf = 0xFFFF;
- dp->cdr_dstat = dsp;
- }
-
- if ((flags & (F_MSINFO|F_TOC|F_LOAD|F_DLCK|F_EJECT)) == 0 ||
- tracks > 0 ||
- cuefilename != NULL) {
-
-
- if ((dp->cdr_flags & CDR_ISREADER) != 0) {
- errmsgno(EX_BAD,
- "Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.\n");
- }
-
- if (!is_mmc(scgp, &is_cdwr, &is_dvdwr))
- is_cdwr = TRUE; /* If it is not MMC, it must be a CD writer */
-
- if (is_dvdwr && !set_cdrcmds("mmc_mdvd", (cdr_t **)NULL)) {
- errmsgno(EX_BAD,
- "Internal error, DVD driver failure. Please report to debburn-devel at lists.alioth.debian.org.\n");
- /*
- errmsgno(EX_BAD,
- "This version of cdrecord does not include DVD-R/DVD-RW support code.\n");
- errmsgno(EX_BAD,
- "See /usr/share/doc/cdrecord/README.DVD.Debian for details on DVD support.\n");
- */
- }
- /*
- * Only exit if this is not the ProDVD test binary.
- */
- if (!is_cdwr)
- exit(EX_BAD);
- }
-
- /*
- * Set up data structures for current drive state.
- */
- if ((*dp->cdr_attach)(scgp, dp) != 0)
- comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.\n");
-
- if (lverbose > 1) {
- printf("Drive current speed: %d\n", dp->cdr_dstat->ds_dr_cur_wspeed);
- printf("Drive default speed: %d\n", dp->cdr_speeddef);
- printf("Drive max speed : %d\n", dp->cdr_speedmax);
- }
- if (speed > (int)dp->cdr_speedmax && (flags & F_FORCE) == 0)
- speed = dp->cdr_speedmax;
- if (speed < 0)
- speed = dp->cdr_speeddef;
-
- if (lverbose > 1) {
- printf("Selected speed : %d\n", speed);
- }
- dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
-
- exargs.scgp = scgp;
- exargs.dp = dp;
- exargs.old_secsize = -1;
- exargs.flags = flags;
-
- if ((flags & F_MSINFO) == 0 || lverbose) {
- printf("Using %s (%s).\n", dp->cdr_drtext, dp->cdr_drname);
- print_drflags(dp);
- print_wrmodes(dp);
- }
- scgp->silent++;
- if ((debug || lverbose)) {
- tsize = -1;
- if ((*dp->cdr_buffer_cap)(scgp, &tsize, (long *)0) < 0 || tsize < 0) {
- if (read_buffer(scgp, buf, 4, 0) >= 0)
- tsize = a_to_u_4_byte(buf);
- }
- if (tsize > 0) {
- printf("Drive buf size : %lu = %lu KB\n",
- tsize, tsize >> 10);
- }
- }
- scgp->silent--;
-
- dma_speed = get_dmaspeed(scgp, dp);
- if ((debug || lverbose) && dma_speed > 0) {
- /*
- * We do not yet know what medium type is in...
- */
- printf("Drive DMA Speed: %d kB/s %dx CD %dx DVD\n",
- dma_speed, dma_speed/176, dma_speed/1385);
- }
- if ((tracks > 0 || cuefilename != NULL) && (debug || lverbose))
- printf("FIFO size : %lu = %lu KB\n", fs, fs >> 10);
-
-#ifdef HAVE_LIB_EDC_ECC
- if ((flags & F_RAW) != 0 && (dp->cdr_dstat->ds_flags & DSF_DVD) == 0)
- raw_speed = encspeed(debug || lverbose);
-#endif
-
- if ((flags & F_CHECKDRIVE) != 0)
- exit(0);
-
- if ((flags & F_ABORT) != 0) {
- /*
- * flush cache is not supported by CD-ROMs avoid prob with -toc
- */
- scgp->silent++;
- scsi_flush_cache(scgp, FALSE);
- (*dp->cdr_abort_session)(scgp, dp);
- scgp->silent--;
- exit(0);
- }
-
- if (tracks == 0 && cuefilename == NULL &&
- (flags & (F_FIX|F_BLANK)) == 0 && (flags & F_EJECT) != 0) {
- /*
- * Do not check if the unit is ready here to allow to open
- * an empty unit too.
- */
- unload_media(scgp, dp, flags);
- exit(0);
- }
- flush();
-
- if (cuefilename) {
- parsecue(cuefilename, track);
- tracks = track[0].tracks;
- } else {
- opentracks(track);
- }
-
- if (tracks > 1)
- sleep(2); /* Let the user watch the inquiry messages */
-
- if (tracks > 0 && !check_wrmode(dp, flags, track[1].flags))
- comerrno(EX_BAD, "Illegal write mode for this drive.\n");
-
- if ((track[0].flags & TI_TEXT) == 0 && /* CD-Text not yet processed */
- (track[MAX_TRACK+1].flags & TI_TEXT) != 0) {
- /*
- * CD-Text from textfile= or from CUE CDTEXTFILE will win
- * over CD-Text from *.inf files and over CD-Text from
- * CUE SONGWRITER, ...
- */
- packtext(tracks, track);
- track[0].flags |= TI_TEXT;
- }
-#ifdef CLONE_WRITE
- if (flags & F_CLONE) {
- clone_toc(track);
- clone_tracktype(track);
- }
-#endif
- setleadinout(tracks, track);
- set_trsizes(dp, tracks, track);
- setpregaps(tracks, track);
- checkfiles(tracks, track);
- tsize = checktsize(tracks, track);
-
- /*
- * Make wm2name[wrmode] work.
- * This must be done after the track flags have been set up
- * by the functions above.
- */
- if (tracks == 0 && (flags & F_BLANK) != 0)
- dp->cdr_dstat->ds_wrmode = WM_BLANK;
- else if (tracks == 0 && (flags & F_FORMAT) != 0)
- dp->cdr_dstat->ds_wrmode = WM_FORMAT;
- else
- set_wrmode(dp, flags, track[1].flags);
-
- /*
- * Debug only
- */
- {
- void *cp = NULL;
-
- (*dp->cdr_gen_cue)(track, &cp, FALSE);
- if (cp)
- free(cp);
- }
-
- /*
- * Create Lead-in data. Only needed in RAW mode.
- */
- do_leadin(track);
-
-
- /*
- * Install exit handler before we change the drive status.
- */
- on_comerr(exscsi, &exargs);
-
- if ((flags & F_FORCE) == 0)
- load_media(scgp, dp, TRUE);
-
- if ((flags & (F_LOAD|F_DLCK)) != 0) {
- if ((flags & F_DLCK) == 0) {
- scgp->silent++; /* silently */
- scsi_prevent_removal(
- scgp, 0); /* allow manual open */
- scgp->silent--; /* if load failed... */
- }
- exit(0); /* we did not change status */
- }
- exargs.old_secsize = sense_secsize(scgp, 1);
- if (exargs.old_secsize < 0)
- exargs.old_secsize = sense_secsize(scgp, 0);
- if (debug)
- printf("Current Secsize: %d\n", exargs.old_secsize);
- scgp->silent++;
- if (read_capacity(scgp) < 0) {
- if (exargs.old_secsize > 0)
- scgp->cap->c_bsize = exargs.old_secsize;
- }
- scgp->silent--;
- if (exargs.old_secsize < 0)
- exargs.old_secsize = scgp->cap->c_bsize;
- if (exargs.old_secsize != scgp->cap->c_bsize)
- errmsgno(EX_BAD, "Warning: blockdesc secsize %d differs from cap secsize %d\n",
- exargs.old_secsize, scgp->cap->c_bsize);
-
- if (lverbose)
- printf("Current Secsize: %d\n", exargs.old_secsize);
-
- if (exargs.old_secsize > 0 && exargs.old_secsize != DATA_SEC_SIZE) {
- /*
- * Some drives (e.g. Plextor) don't like to write correctly
- * in SAO mode if the sector size is set to 512 bytes.
- * In addition, cdrecord -msinfo will not work properly
- * if the sector size is not 2048 bytes.
- */
- set_secsize(scgp, DATA_SEC_SIZE);
- }
-
- /*
- * Is this the right place to do this ?
- */
- check_recovery(scgp, dp, flags);
-
-/*audioread(dp, flags);*/
-/*unload_media(scgp, dp, flags);*/
-/*return 0;*/
- if (flags & F_WRITE)
- dp->cdr_dstat->ds_cdrflags |= RF_WRITE;
- if (flags & F_BLANK)
- dp->cdr_dstat->ds_cdrflags |= RF_BLANK;
- if (flags & F_PRATIP || lverbose > 0) {
- dp->cdr_dstat->ds_cdrflags |= RF_PRATIP;
- }
- if (flags & F_IMMED || dminbuf > 0) {
- if (dminbuf <= 0)
- dminbuf = 50;
- if (lverbose <= 0) /* XXX Hack needed for now */
- lverbose++;
- dp->cdr_dstat->ds_cdrflags |= RF_WR_WAIT;
- }
- if ((*dp->cdr_getdisktype)(scgp, dp) < 0) {
- errmsgno(EX_BAD, "Cannot get disk type.\n");
- if ((flags & F_FORCE) == 0)
- comexit(EX_BAD);
- }
- if (flags & F_PRATIP) {
- comexit(0);
- }
- /*
- * The next actions should depend on the disk type.
- */
- if (dma_speed > 0) {
- if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0)
- dma_speed /= 176;
- else
- dma_speed /= 1385;
- }
-
- /*
- * Init drive to default modes:
- *
- * We set TAO unconditionally to make checkdsize() work
- * currectly in SAO mode too.
- *
- * At least MMC drives will not return the next writable
- * address we expect when the drive's write mode is set
- * to SAO. We need this address for mkisofs and thus
- * it must be the first user accessible sector and not the
- * first sector of the pregap.
- *
- * XXX The ACER drive:
- * XXX Vendor_info : 'ATAPI '
- * XXX Identifikation : 'CD-R/RW 8X4X32 '
- * XXX Revision : '5.EW'
- * XXX Will not return from -dummy to non-dummy without
- * XXX opening the tray.
- */
- scgp->silent++;
- if ((*dp->cdr_init)(scgp, dp) < 0)
- comerrno(EX_BAD, "Cannot init drive.\n");
- scgp->silent--;
-
- if (flags & F_SETDROPTS) {
- /*
- * Note that the set speed function also contains
- * drive option processing for speed related drive options.
- */
- if ((*dp->cdr_opt1)(scgp, dp) < 0) {
- errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n");
- }
- if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0) {
- errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
- }
- dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
- if ((*dp->cdr_opt2)(scgp, dp) < 0) {
- errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n");
- }
- comexit(0);
- }
- /*
- * XXX If dp->cdr_opt1() ever affects the result for
- * XXX the multi session info we would need to move it here.
- */
- if (flags & F_MSINFO) {
- print_msinfo(scgp, dp);
- comexit(0);
- }
- if (flags & F_TOC) {
- print_toc(scgp, dp);
- comexit(0);
- }
-#ifdef XXX
- if ((*dp->cdr_check_session)() < 0) {
- comexit(EX_BAD);
- }
-#endif
- {
- Int32_t omb = dp->cdr_dstat->ds_maxblocks;
-
- if ((*dp->cdr_opt1)(scgp, dp) < 0) {
- errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n");
- }
- if (tsize > 0 && omb != dp->cdr_dstat->ds_maxblocks) {
- printf("Disk size changed by user options.\n");
- printf("Checking disk capacity according to new values.\n");
- }
- }
- if (tsize == 0) {
- if (tracks > 0) {
- errmsgno(EX_BAD,
- "WARNING: Total disk size unknown. Data may not fit on disk.\n");
- }
- } else if (tracks > 0) {
- /*
- * XXX How do we let the user check the remaining
- * XXX disk size witout starting the write process?
- */
- if (!checkdsize(scgp, dp, tsize, flags))
- comexit(EX_BAD);
- }
- if (tracks > 0 && fs > 0l) {
-#if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID)
- /*
- * Hack to work around the POSIX design bug in real time
- * priority handling: we need to be root even to lower
- * our priority.
- * Note that we need to find a more general way that works
- * even on OS that do not support getreuid() which is *BSD
- * and SUSv3 only.
- */
- if (oeuid != getuid()) {
- if (setreuid(-1, oeuid) < 0)
- errmsg("Could set back effective uid.\n");
- }
-
-#endif
- /*
- * fork() here to start the extra process needed for
- * improved buffering.
- */
- if (!init_faio(track, bufsize))
- fs = 0L;
- else
- on_comerr(excdr, &exargs);
-
- atexit(fifo_cleanup);
-
-#if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID)
- /*
- * XXX Below this point we never need root privilleges anymore.
- */
- if (geteuid() != getuid()) { /* AIX does not like to do this */
- /* If we are not root */
- if (setreuid(-1, getuid()) < 0)
- comerr("Panic cannot set back effective uid.\n");
- }
-#ifdef __linux__
- if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose))
- perror("Error: Cannot gain SYS_RAWIO capability, is wodim installed SUID root? Reason");
-#endif
-
-#endif
- }
- if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0) {
- errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
- if ((flags & F_FORCE) == 0)
- comexit(EX_BAD);
- }
- dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
- if ((flags & F_WRITE) != 0 && raw_speed >= 0) {
- int max_raw = (flags & F_FORCE) != 0 ? raw_speed:raw_speed/2;
-
- if (getenv("CDR_FORCERAWSPEED"))
- max_raw = raw_speed;
-
- for (i = 1; i <= MAX_TRACK; i++) {
- /*
- * Check for Clone tracks
- */
- if ((track[i].sectype & ST_MODE_RAW) != 0)
- continue;
- /*
- * Check for non-data tracks
- */
- if ((track[i].sectype & ST_MODE_MASK) == ST_MODE_AUDIO)
- continue;
-
- if (speed > max_raw) {
- errmsgno(EX_BAD,
- "Processor too slow. Cannot write RAW data at speed %d.\n",
- speed);
- comerrno(EX_BAD, "Max RAW data speed on this processor is %d.\n",
- max_raw);
- }
- break;
- }
- }
- if (tracks > 0 && (flags & F_WRITE) != 0 && dma_speed > 0) {
- int max_dma = (flags & F_FORCE) != 0 ? dma_speed:(dma_speed+1)*4/5;
-
- if (getenv("CDR_FORCESPEED"))
- max_dma = dma_speed;
-
- if (speed > max_dma) {
- errmsgno(EX_BAD,
- "DMA speed too slow (OK for %dx). Cannot write at speed %dx.\n",
- max_dma, speed);
- if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
- errmsgno(EX_BAD, "Max DMA data speed is %d.\n", max_dma);
- comerrno(EX_BAD, "Try to use 'driveropts=burnfree'.\n");
- }
- }
- }
- if ((flags & (F_WRITE|F_BLANK)) != 0 &&
- (dp->cdr_dstat->ds_flags & DSF_ERA) != 0) {
- if (xdebug) {
- printf("Current speed %d, medium low speed: %d medium high speed: %d\n",
- speed,
- dp->cdr_dstat->ds_at_min_speed,
- dp->cdr_dstat->ds_at_max_speed);
- }
- if (dp->cdr_dstat->ds_at_max_speed > 0 &&
- speed <= 8 &&
- speed > (int)dp->cdr_dstat->ds_at_max_speed) {
- /*
- * Be careful here: 10x media may be written faster.
- * The current code will work as long as there is no
- * writer that can only write faster than 8x
- */
- if ((flags & F_FORCE) == 0) {
- errmsgno(EX_BAD,
- "Write speed %d of medium not sufficient for this writer.\n",
- dp->cdr_dstat->ds_at_max_speed);
- comerrno(EX_BAD,
- "You may have used an ultra low speed medium on a high speed writer.\n");
- }
- }
-
- if ((dp->cdr_dstat->ds_flags & DSF_ULTRASPP_ERA) != 0 &&
- (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0)) {
- if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0) {
- comerrno(EX_BAD,
- "Trying to use ultra high speed+ medium on a writer which is not\ncompatible with ultra high speed+ media.\n");
- } else if ((flags & F_FORCE) == 0) {
- comerrno(EX_BAD,
- "Probably trying to use ultra high speed+ medium on improper writer.\n");
- }
- } else if ((dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA) != 0 &&
- (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0)) {
- if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0) {
- comerrno(EX_BAD,
- "Trying to use ultra high speed medium on a writer which is not\ncompatible with ultra high speed media.\n");
- } else if ((flags & F_FORCE) == 0) {
- comerrno(EX_BAD,
- "Probably trying to use ultra high speed medium on improper writer.\n");
- }
- }
- if (dp->cdr_dstat->ds_at_min_speed >= 4 &&
- dp->cdr_dstat->ds_at_max_speed > 4 &&
- dp->cdr_dstat->ds_dr_max_wspeed <= 4) {
- if ((flags & F_FORCE) == 0) {
- comerrno(EX_BAD,
- "Trying to use high speed medium on low speed writer.\n");
- }
- }
- if ((int)dp->cdr_dstat->ds_at_min_speed > speed) {
- if ((flags & F_FORCE) == 0) {
- errmsgno(EX_BAD,
- "Write speed %d of writer not sufficient for this medium.\n",
- speed);
- errmsgno(EX_BAD,
- "You did use a %s speed medium on an improper writer or\n",
- dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA ?
- "ultra high": "high");
- comerrno(EX_BAD,
- "you used a speed=# option with a speed too low for this medium.\n");
- }
- }
- }
- if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) {
- printf("Waiting for drive to calm down.\n");
- wait_unit_ready(scgp, 120);
- if (gracewait(dp, &gracedone) < 0) {
- /*
- * In case kill() did not work ;-)
- */
- errs++;
- goto restore_it;
- }
- scsi_blank(scgp, 0L, blanktype, FALSE);
- }
-
- /*
- * Last chance to quit!
- */
- if (gracewait(dp, &gracedone) < 0) {
- /*
- * In case kill() did not work ;-)
- */
- errs++;
- goto restore_it;
- }
-
- if (dp->profile == 0x2B && flags & F_SAO && tsize > 0) {
- printf("Preparing middle zone location for this DVD+R dual layer disc\n");
- if (!dp->cdr_layer_split(scgp, dp, tsize)) {
- errmsgno(EX_BAD, "Cannot send structure for middle zone location.\n");
- comexit(EX_BAD);
- }
- }
-
- if (tracks > 0 && fs > 0l) {
- /*
- * Wait for the read-buffer to become full.
- * This should be take no extra time if the input is a file.
- * If the input is a pipe (e.g. mkisofs) this can take a
- * while. If mkisofs dumps core before it starts writing,
- * we abort before the writing process started.
- */
- if (!await_faio()) {
- comerrno(EX_BAD, "Input buffer error, aborting.\n");
- }
- }
- wait_unit_ready(scgp, 120);
-
- starttime.tv_sec = 0;
- wstarttime.tv_sec = 0;
- stoptime.tv_sec = 0;
- fixtime.tv_sec = 0;
- if (gettimeofday(&starttime, (struct timezone *)0) < 0)
- errmsg("Cannot get start time\n");
-
- /*
- * Blank the media if we were requested to do so
- */
- if (flags & F_BLANK) {
- /*
- * Do not abort if OPC failes. Just give it a chance
- * for better laser power calibration than without OPC.
- *
- * Ricoh drives return with a vendor unique sense code.
- * This is most likely because they refuse to do OPC
- * on a non blank media.
- */
- scgp->silent++;
- do_opc(scgp, dp, flags);
- scgp->silent--;
- wait_unit_ready(scgp, 120);
- if (gettimeofday(&starttime, (struct timezone *)0) < 0)
- errmsg("Cannot get start time\n");
-
- if ((*dp->cdr_blank)(scgp, dp, 0L, blanktype) < 0) {
- errmsgno(EX_BAD, "Cannot blank disk, aborting.\n");
- if (blanktype != BLANK_DISC) {
- errmsgno(EX_BAD, "Some drives do not support all blank types.\n");
- errmsgno(EX_BAD, "Try again with wodim blank=all.\n");
- }
- comexit(EX_BAD);
- }
- if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
- errmsg("Cannot get blank time\n");
- if (lverbose)
- prtimediff("Blanking time: ", &starttime, &fixtime);
-
- /*
- * XXX Erst blank und dann format?
- * XXX Wenn ja, dann hier (flags & F_FORMAT) testen
- */
- if (!wait_unit_ready(scgp, 240) || tracks == 0) {
- comexit(0);
- }
- if (flags & F_FORMAT) {
- printf("wodim: media format asked\n");
- /*
- * Do not abort if OPC failes. Just give it a chance
- * for better laser power calibration than without OPC.
- *
- * Ricoh drives return with a vendor unique sense code.
- * This is most likely because they refuse to do OPC
- * on a non blank media.
- */
- scgp->silent++;
- do_opc(scgp, dp, flags);
- scgp->silent--;
- wait_unit_ready(scgp, 120);
- if (gettimeofday(&starttime, (struct timezone *)0) < 0)
- errmsg("Cannot get start time\n");
-
- if ((*dp->cdr_format)(scgp, dp, formattype) < 0) {
- errmsgno(EX_BAD, "Cannot format disk, aborting.\n");
- comexit(EX_BAD);
- }
- if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
- errmsg("Cannot get format time\n");
- if (lverbose)
- prtimediff("Formatting time: ", &starttime, &fixtime);
-
- if (!wait_unit_ready(scgp, 240) || tracks == 0) {
- comexit(0);
- }
- if (gettimeofday(&starttime, (struct timezone *)0) < 0)
- errmsg("Cannot get start time\n");
- }
- /*
- * Reset start time so we will not see blanking time and
- * writing time counted together.
- */
- if (gettimeofday(&starttime, (struct timezone *)0) < 0)
- errmsg("Cannot get start time\n");
- }
- if (tracks == 0 && (flags & F_FIX) == 0)
- comerrno(EX_BAD, "No tracks found.\n");
- /*
- * Get the number of the next recordable track by reading the TOC and
- * use the number the last current track number.
- */
- scgp->silent++;
- if (read_tochdr(scgp, dp, NULL, &trackno) < 0) {
- trackno = 0;
- }
- scgp->silent--;
-
- /* If it is DVD, the information in TOC is fabricated :)
- The real information is from read disk info command*/
- if((dp->cdr_dstat->ds_disktype&DT_DVD) && (dp->cdr_dstat->ds_trlast>0)){
- trackno=dp->cdr_dstat->ds_trlast-1;
- if (lverbose > 2)
- printf("trackno=%d\n",trackno);
- }
-
- if ((tracks + trackno) > MAX_TRACK) {
- /*
- * XXX How many tracks are allowed on a DVD?
- */
- comerrno(EX_BAD, "Too many tracks for this disk, last track number is %d.\n",
- tracks + trackno);
- }
-
- for (i = 0; i <= tracks+1; i++) { /* Lead-in ... Lead-out */
- track[i].trackno = i + trackno; /* Set up real track # */
- }
-
- if ((*dp->cdr_opt2)(scgp, dp) < 0) {
- errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n");
- }
-
- /*
- * Now we actually start writing to the CD/DVD.
- * XXX Check total size of the tracks and remaining size of disk.
- */
- if ((*dp->cdr_open_session)(scgp, dp, track) < 0) {
- comerrno(EX_BAD, "Cannot open new session.\n");
- }
- if (!do_opc(scgp, dp, flags))
- comexit(EX_BAD);
-
- /*
- * As long as open_session() will do nothing but
- * set up parameters, we may leave fix_it here.
- * I case we have to add an open_session() for a drive
- * that wants to do something that modifies the disk
- * We have to think about a new solution.
- */
- if (flags & F_FIX)
- goto fix_it;
-
- /*
- * This call may modify trackp[i].trackstart for all tracks.
- */
- if ((*dp->cdr_write_leadin)(scgp, dp, track) < 0)
- comerrno(EX_BAD, "Could not write Lead-in.\n");
-
- if (lverbose && (dp->cdr_dstat->ds_cdrflags & RF_LEADIN) != 0) {
-
- if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
- errmsg("Cannot get lead-in write time\n");
- prtimediff("Lead-in write time: ", &starttime, &fixtime);
- }
-
- if (gettimeofday(&wstarttime, (struct timezone *)0) < 0)
- errmsg("Cannot get start time\n");
- for (i = 1; i <= tracks; i++) {
- startsec = 0L;
-
- if ((*dp->cdr_open_track)(scgp, dp, &track[i]) < 0) {
- errmsgno(EX_BAD, "Cannot open next track.\n");
- errs++;
- break;
- }
-
- if ((flags & (F_SAO|F_RAW)) == 0) {
- if ((*dp->cdr_next_wr_address)(scgp, &track[i], &startsec) < 0) {
- errmsgno(EX_BAD, "Cannot get next writable address.\n");
- errs++;
- break;
- }
- track[i].trackstart = startsec;
- }
- if (debug || lverbose) {
- printf("Starting new track at sector: %ld\n",
- track[i].trackstart);
- flush();
- }
- if (write_track_data(scgp, dp, &track[i]) < 0) {
- if (cdr_underrun(scgp)) {
- errmsgno(EX_BAD,
- "The current problem looks like a buffer underrun.\n");
- if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
- errmsgno(EX_BAD,
- "Try to use 'driveropts=burnfree'.\n");
- else {
- errmsgno(EX_BAD,
- "It looks like 'driveropts=burnfree' does not work for this drive.\n");
- errmsgno(EX_BAD, "Please report.\n");
- }
-
- errmsgno(EX_BAD,
- "Make sure that you are root, enable DMA and check your HW/OS set up.\n");
- } else {
- errmsgno(EX_BAD, "A write error occured.\n");
- errmsgno(EX_BAD, "Please properly read the error message above.\n");
- }
- errs++;
- sleep(5);
- unit_ready(scgp);
- (*dp->cdr_close_track)(scgp, dp, &track[i]);
- break;
- }
- if ((*dp->cdr_close_track)(scgp, dp, &track[i]) < 0) {
- /*
- * Check for "Dummy blocks added" message first.
- */
- if (scg_sense_key(scgp) != SC_ILLEGAL_REQUEST ||
- scg_sense_code(scgp) != 0xB5) {
- errmsgno(EX_BAD, "Cannot close track.\n");
- errs++;
- break;
- }
- }
- }
-fix_it:
- if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
- errmsg("Cannot get stop time\n");
- cdrstats(dp);
-
- if (flags & F_RAW) {
- if (lverbose) {
- printf("Writing Leadout...\n");
- flush();
- }
- write_leadout(scgp, dp, track);
- }
- if ((flags & F_NOFIX) == 0) {
- if (lverbose) {
- printf("Fixating...\n");
- flush();
- }
- if ((*dp->cdr_fixate)(scgp, dp, track) < 0) {
- /*
- * Ignore fixating errors in dummy mode.
- */
- if ((flags & F_DUMMY) == 0) {
- errmsgno(EX_BAD, "Cannot fixate disk.\n");
- errs++;
- }
- }
- if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
- errmsg("Cannot get fix time\n");
- if (lverbose)
- prtimediff("Fixating time: ", &stoptime, &fixtime);
- }
- if ((dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) {
- dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT;
- (*dp->cdr_stats)(scgp, dp);
- }
- if ((flags & (F_RAW|F_EJECT)) == F_RAW) {
- /*
- * Most drives seem to forget to reread the TOC from disk
- * if they are in RAW mode.
- */
- scgp->silent++;
- if (read_tochdr(scgp, dp, NULL, NULL) < 0) {
- scgp->silent--;
- if ((flags & F_DUMMY) == 0)
- reload_media(scgp, dp);
- } else {
- scgp->silent--;
- }
- }
-
-restore_it:
- /*
- * Try to restore the old sector size and stop FIFO.
- */
- kill_faio();
- comexit(errs?-2:0);
- return (0);
-}
-
-static int
-gracewait(cdr_t *dp, BOOL *didgracep)
-{
- int i;
- BOOL didgrace = FALSE;
-
- if (didgracep)
- didgrace = *didgracep;
-
- if (gracetime < MIN_GRACE_TIME)
- gracetime = MIN_GRACE_TIME;
- if (gracetime > 999)
- gracetime = 999;
-
- printf("Starting to write CD/DVD at speed %5.1f in %s%s %s mode for %s session.\n",
- (float)dp->cdr_dstat->ds_wspeed,
- (dp->cdr_cmdflags & F_DUMMY) ? "dummy" : "real",
- (dp->cdr_cmdflags & F_FORCE) ? " force" : "",
- wm2name[dp->cdr_dstat->ds_wrmode],
- (dp->cdr_cmdflags & F_MULTI) ? "multi" : "single");
- if (didgrace) {
- printf("No chance to quit anymore.");
- goto grace_done;
- }
- printf("Last chance to quit, starting %s write in %d seconds.",
- (dp->cdr_cmdflags & F_DUMMY)?"dummy":"real", gracetime);
- flush();
- signal(SIGINT, intr);
- signal(SIGHUP, intr);
- signal(SIGTERM, intr);
-
- for (i = gracetime; --i >= 0; ) {
- sleep(1);
- if (didintr) {
- printf("\n");
- excdr(SIGINT, &exargs);
- signal(SIGINT, SIG_DFL);
- kill(getpid(), SIGINT);
- /*
- * In case kill() did not work ;-)
- */
- if (didgracep)
- *didgracep = FALSE;
- return (-1);
- }
- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b%4d seconds.", i);
- flush();
- }
-grace_done:
- printf(" Operation starts.");
- flush();
- signal(SIGINT, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGINT, intfifo);
- signal(SIGHUP, intfifo);
- signal(SIGTERM, intfifo);
- printf("\n");
-
- if (didgracep)
- *didgracep = TRUE;
- return (0);
-}
-
-static void
-cdrstats(cdr_t *dp)
-{
- float secsps = 75.0;
- int nsecs;
- float fspeed;
- struct timeval tcur;
- struct timeval tlast;
- BOOL nostop = FALSE;
-
- if (starttime.tv_sec == 0)
- return;
-
- if (stoptime.tv_sec == 0) {
- gettimeofday(&stoptime, (struct timezone *)0);
- nostop = TRUE;
- }
-
- if ((dp->cdr_dstat->ds_cdrflags & RF_DID_STAT) != 0)
- return;
- dp->cdr_dstat->ds_cdrflags |= RF_DID_STAT;
-
- if (lverbose == 0)
- return;
-
- if (dp->cdr_cmdflags & F_FIX)
- return;
-
- if ((dp->cdr_cmdflags & (F_WRITE|F_BLANK)) == F_BLANK)
- return;
-
- tlast = wstarttime;
- tcur = stoptime;
-
- prtimediff("Writing time: ", &starttime, &stoptime);
-
- nsecs = dp->cdr_dstat->ds_endsec - dp->cdr_dstat->ds_startsec;
-
- if (dp->cdr_dstat->ds_flags & DSF_DVD)
- secsps = 676.27;
-
- tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
- tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
- while (tlast.tv_usec < 0) {
- tlast.tv_usec += 1000000;
- tlast.tv_sec -= 1;
- }
- if (!nostop && nsecs != 0 && dp->cdr_dstat->ds_endsec > 0) {
- /*
- * May not be known (e.g. cdrecord -)
- *
- * XXX if we later allow this code to know how much has
- * XXX actually been written, then we may remove the
- * XXX dependance from nostop & nsecs != 0
- */
- fspeed = (nsecs / secsps) /
- (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
- if (fspeed > 999.0)
- fspeed = 999.0;
- if (dp->is_dvd) fspeed /= 9;
- printf("Average write speed %5.1fx.\n", fspeed);
- }
-
- if (dp->cdr_dstat->ds_minbuf <= 100) {
- printf("Min drive buffer fill was %u%%\n",
- (unsigned int)dp->cdr_dstat->ds_minbuf);
- }
- if (dp->cdr_dstat->ds_buflow > 0) {
- printf("Total of %ld possible drive buffer underruns predicted.\n",
- (long)dp->cdr_dstat->ds_buflow);
- }
-}
-
-/*
- * Short usage
- */
-static void
-susage(int ret)
-{
- fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname());
- fprintf(stderr, "\nUse\t%s -help\n", get_progname());
- fprintf(stderr, "to get a list of valid options.\n");
- fprintf(stderr, "\nUse\t%s blank=help\n", get_progname());
- fprintf(stderr, "to get a list of valid blanking options.\n");
- fprintf(stderr, "\nUse\t%s dev=b,t,l driveropts=help -checkdrive\n", get_progname());
- fprintf(stderr, "to get a list of drive specific options.\n");
- fprintf(stderr, "\nUse\t%s dev=help\n", get_progname());
- fprintf(stderr, "to get a list of possible SCSI transport specifiers.\n");
- exit(ret);
- /* NOTREACHED */
-}
-
-static void
-usage(int excode)
-{
- fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname());
- fprintf(stderr, "Options:\n");
- fprintf(stderr, "\t-version print version information and exit\n");
- fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n");
- fprintf(stderr, "\tgracetime=# set the grace time before starting to write to #.\n");
- fprintf(stderr, "\ttimeout=# set the default SCSI command timeout to #.\n");
- fprintf(stderr, "\tdebug=#,-d Set to # or increment misc debug level\n");
- fprintf(stderr, "\tkdebug=#,kd=# do Kernel debugging\n");
- fprintf(stderr, "\t-verbose,-v increment general verbose level by one\n");
- fprintf(stderr, "\t-Verbose,-V increment SCSI command transport verbose level by one\n");
- fprintf(stderr, "\t-silent,-s do not print status of failed SCSI commands\n");
- fprintf(stderr, "\tdriver=name user supplied driver name, use with extreme care\n");
- fprintf(stderr, "\tdriveropts=opt a comma separated list of driver specific options\n");
- fprintf(stderr, "\t-setdropts set driver specific options and exit\n");
- fprintf(stderr, "\t-checkdrive check if a driver for the drive is present\n");
- fprintf(stderr, "\t-prcap print drive capabilities for MMC compliant drives\n");
- fprintf(stderr, "\t-inq do an inquiry for the drive and exit\n");
- fprintf(stderr, "\t-scanbus scan the SCSI and IDE buses and exit\n");
- fprintf(stderr, "\t-reset reset the SCSI bus with the cdrecorder (if possible)\n");
- fprintf(stderr, "\t-abort send an abort sequence to the drive (may help if hung)\n");
- fprintf(stderr, "\t-overburn allow to write more than the official size of a medium\n");
- fprintf(stderr, "\t-ignsize ignore the known size of a medium (may cause problems)\n");
- fprintf(stderr, "\t-useinfo use *.inf files to overwrite audio options.\n");
- fprintf(stderr, "\tspeed=# set speed of drive\n");
- fprintf(stderr, "\tblank=type blank a CD-RW disc (see blank=help)\n");
- fprintf(stderr, "\t-format format a CD-RW/DVD-RW/DVD+RW disc\n");
- fprintf(stderr, "\tformattype=# select the format method for DVD+RW disc\n");
-#ifdef FIFO
- fprintf(stderr, "\tfs=# Set fifo size to # (0 to disable, default is %ld MB)\n",
- DEFAULT_FIFOSIZE/(1024L*1024L));
-#endif
- fprintf(stderr, "\tts=# set maximum transfer size for a single SCSI command\n");
- fprintf(stderr, "\t-load load the disk and exit (works only with tray loader)\n");
- fprintf(stderr, "\t-lock load and lock the disk and exit (works only with tray loader)\n");
- fprintf(stderr, "\t-eject eject the disk after doing the work\n");
- fprintf(stderr, "\t-dummy do everything with laser turned off\n");
- fprintf(stderr, "\t-msinfo retrieve multi-session info for mkisofs >= 1.10\n");
- fprintf(stderr, "\t-toc retrieve and print TOC/PMA data\n");
- fprintf(stderr, "\t-atip retrieve and print ATIP data\n");
- fprintf(stderr, "\t-multi generate a TOC that allows multi session\n");
- fprintf(stderr, "\t In this case default track type is CD-ROM XA mode 2 form 1 - 2048 bytes\n");
- fprintf(stderr, "\t-fix fixate a corrupt or unfixated disk (generate a TOC)\n");
- fprintf(stderr, "\t-nofix do not fixate disk after writing tracks\n");
- fprintf(stderr, "\t-waiti wait until input is available before opening SCSI\n");
- fprintf(stderr, "\t-immed Try to use the SCSI IMMED flag with certain long lasting commands\n");
- fprintf(stderr, "\t-force force to continue on some errors to allow blanking bad disks\n");
- fprintf(stderr, "\t-tao Write disk in TAO mode. This option will be replaced in the future.\n");
- fprintf(stderr, "\t-dao Write disk in SAO mode. This option will be replaced in the future.\n");
- fprintf(stderr, "\t-sao Write disk in SAO mode. This option will be replaced in the future.\n");
- fprintf(stderr, "\t-raw Write disk in RAW mode. This option will be replaced in the future.\n");
- fprintf(stderr, "\t-raw96r Write disk in RAW/RAW96R mode. This option will be replaced in the future.\n");
- fprintf(stderr, "\t-raw96p Write disk in RAW/RAW96P mode. This option will be replaced in the future.\n");
- fprintf(stderr, "\t-raw16 Write disk in RAW/RAW16 mode. This option will be replaced in the future.\n");
-#ifdef CLONE_WRITE
- fprintf(stderr, "\t-clone Write disk in clone write mode.\n");
-#endif
- fprintf(stderr, "\ttsize=# Length of valid data in next track\n");
- fprintf(stderr, "\tpadsize=# Amount of padding for next track\n");
- fprintf(stderr, "\tpregap=# Amount of pre-gap sectors before next track\n");
- fprintf(stderr, "\tdefpregap=# Amount of pre-gap sectors for all but track #1\n");
- fprintf(stderr, "\tmcn=text Set the media catalog number for this CD to 'text'\n");
- fprintf(stderr, "\tisrc=text Set the ISRC number for the next track to 'text'\n");
- fprintf(stderr, "\tindex=list Set the index list for the next track to 'list'\n");
- fprintf(stderr, "\t-text Write CD-Text from information from *.inf or *.cue files\n");
- fprintf(stderr, "\ttextfile=name Set the file with CD-Text data to 'name'\n");
- fprintf(stderr, "\tcuefile=name Set the file with CDRWIN CUE data to 'name'\n");
-
- fprintf(stderr, "\t-audio Subsequent tracks are CD-DA audio tracks\n");
- fprintf(stderr, "\t-data Subsequent tracks are CD-ROM data mode 1 - 2048 bytes (default)\n");
- fprintf(stderr, "\t-mode2 Subsequent tracks are CD-ROM data mode 2 - 2336 bytes\n");
- fprintf(stderr, "\t-xa Subsequent tracks are CD-ROM XA mode 2 form 1 - 2048 bytes\n");
- fprintf(stderr, "\t-xa1 Subsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n");
- fprintf(stderr, "\t-xa2 Subsequent tracks are CD-ROM XA mode 2 form 2 - 2324 bytes\n");
- fprintf(stderr, "\t-xamix Subsequent tracks are CD-ROM XA mode 2 form 1/2 - 2332 bytes\n");
- fprintf(stderr, "\t-cdi Subsequent tracks are CDI tracks\n");
- fprintf(stderr, "\t-isosize Use iso9660 file system size for next data track\n");
- fprintf(stderr, "\t-preemp Audio tracks are mastered with 50/15 µs preemphasis\n");
- fprintf(stderr, "\t-nopreemp Audio tracks are mastered with no preemphasis (default)\n");
- fprintf(stderr, "\t-copy Audio tracks have unlimited copy permission\n");
- fprintf(stderr, "\t-nocopy Audio tracks may only be copied once for personal use (default)\n");
- fprintf(stderr, "\t-scms Audio tracks will not have any copy permission at all\n");
- fprintf(stderr, "\t-pad Pad data tracks with %d zeroed sectors\n", PAD_SECS);
- fprintf(stderr, "\t Pad audio tracks to a multiple of %d bytes\n", AUDIO_SEC_SIZE);
- fprintf(stderr, "\t-nopad Do not pad data tracks (default)\n");
- fprintf(stderr, "\t-shorttrack Subsequent tracks may be non Red Book < 4 seconds if in SAO or RAW mode\n");
- fprintf(stderr, "\t-noshorttrack Subsequent tracks must be >= 4 seconds\n");
- fprintf(stderr, "\t-swab Audio data source is byte-swapped (little-endian/Intel)\n");
- fprintf(stderr, "The type of the first track is used for the toc type.\n");
- fprintf(stderr, "Currently only form 1 tracks are supported.\n");
- exit(excode);
-}
-
-static void
-blusage(int ret)
-{
- fprintf(stderr, "Blanking options:\n");
- fprintf(stderr, "\tall\t\tblank the entire disk\n");
- fprintf(stderr, "\tdisc\t\tblank the entire disk\n");
- fprintf(stderr, "\tdisk\t\tblank the entire disk\n");
- fprintf(stderr, "\tfast\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
- fprintf(stderr, "\tminimal\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
- fprintf(stderr, "\ttrack\t\tblank a track\n");
- fprintf(stderr, "\tunreserve\tunreserve a track\n");
- fprintf(stderr, "\ttrtail\t\tblank a track tail\n");
- fprintf(stderr, "\tunclose\t\tunclose last session\n");
- fprintf(stderr, "\tsession\t\tblank last session\n");
-
- exit(ret);
- /* NOTREACHED */
-}
-
-static void
-formattypeusage(int ret)
-{
- fprintf(stderr, "Formating options:\n");
- fprintf(stderr, "\tfull\t\tstandard formating\n");
- fprintf(stderr, "\tbackground\t\tbackground formating\n");
- fprintf(stderr, "\tforce\t\tforce reformat\n");
-
- exit(ret);
- /* NOTREACHED */
-}
-
-/* ARGSUSED */
-static void
-intr(int sig)
-{
- sig = 0; /* Fake usage for gcc */
-
- signal(SIGINT, intr);
-
- didintr++;
-}
-
-static void
-catchsig(int sig)
-{
- signal(sig, catchsig);
-}
-
-static int
-scsi_cb(void *arg)
-{
- comexit(EX_BAD);
- /* NOTREACHED */
- return (0); /* Keep lint happy */
-}
-
-static void
-intfifo(int sig)
-{
- errmsgno(EX_BAD, "Caught interrupt.\n");
- if (exargs.scgp) {
- SCSI *scgp = exargs.scgp;
-
- if (scgp->running) {
- if (scgp->cb_fun != NULL) {
- comerrno(EX_BAD, "Second interrupt. Doing hard abort.\n");
- /* NOTREACHED */
- }
- scgp->cb_fun = scsi_cb;
- scgp->cb_arg = &exargs;
- return;
- }
- }
- comexit(sig);
-}
-
-/* ARGSUSED */
-static void
-exscsi(int excode, void *arg)
-{
- struct exargs *exp = (struct exargs *)arg;
-
- /*
- * Try to restore the old sector size.
- */
- if (exp != NULL && exp->exflags == 0) {
- if (exp->scgp->running) {
- return;
- }
- /*
- * flush cache is not supported by CD-ROMs avoid prob with -toc
- */
- exp->scgp->silent++;
- scsi_flush_cache(exp->scgp, FALSE);
- (*exp->dp->cdr_abort_session)(exp->scgp, exp->dp);
- exp->scgp->silent--;
- set_secsize(exp->scgp, exp->old_secsize);
- unload_media(exp->scgp, exp->dp, exp->flags);
-
- exp->exflags++; /* Make sure that it only get called once */
- }
-}
-
-static void
-excdr(int excode, void *arg)
-{
- struct exargs *exp = (struct exargs *)arg;
-
- exscsi(excode, arg);
-
- cdrstats(exp->dp);
- if ((exp->dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) {
- exp->dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT;
- (*exp->dp->cdr_stats)(exp->scgp, exp->dp);
- }
-
-#ifdef FIFO
- kill_faio();
- wait_faio();
- if (debug || lverbose)
- fifo_stats();
-#endif
-}
-
-int
-read_buf(int f, char *bp, int size)
-{
- char *p = bp;
- int amount = 0;
- int n;
-
- do {
- do {
- n = read(f, p, size-amount);
- } while (n < 0 && (geterrno() == EAGAIN || geterrno() == EINTR));
- if (n < 0)
- return (n);
- amount += n;
- p += n;
-
- } while (amount < size && n > 0);
- return (amount);
-}
-
-int
-fill_buf(int f, track_t *trackp, long secno, char *bp, int size)
-{
- int amount = 0;
- int nsecs;
- int rsize;
- int rmod;
- int readoffset = 0;
-
- nsecs = size / trackp->secsize;
- if (nsecs < trackp->secspt) {
- /*
- * Clear buffer to prepare for last transfer.
- * Make sure that a partial sector ends with NULs
- */
- fillbytes(bp, trackp->secspt * trackp->secsize, '\0');
- }
-
- if (!is_raw(trackp)) {
- amount = read_buf(f, bp, size);
- if (amount != size) {
- if (amount < 0)
- return (amount);
- /*
- * We got less than expected, clear rest of buf.
- */
- fillbytes(&bp[amount], size-amount, '\0');
- }
- if (is_swab(trackp))
- swabbytes(bp, amount);
- return (amount);
- }
-
- rsize = nsecs * trackp->isecsize;
- rmod = size % trackp->secsize;
- if (rmod > 0) {
- rsize += rmod;
- nsecs++;
- }
-
- readoffset = trackp->dataoff;
- amount = read_buf(f, bp + readoffset, rsize);
- if (is_swab(trackp))
- swabbytes(bp + readoffset, amount);
-
- if (trackp->isecsize == 2448 && trackp->secsize == 2368)
- subrecodesecs(trackp, (Uchar *)bp, secno, nsecs);
-
- scatter_secs(trackp, bp + readoffset, nsecs);
-
- if (amount != rsize) {
- if (amount < 0)
- return (amount);
- /*
- * We got less than expected, clear rest of buf.
- */
- fillbytes(&bp[amount], rsize-amount, '\0');
- nsecs = amount / trackp->isecsize;
- rmod = amount % trackp->isecsize;
- amount = nsecs * trackp->secsize;
- if (rmod > 0) {
- nsecs++;
- amount += rmod;
- }
- } else {
- amount = size;
- }
- if ((trackp->sectype & ST_MODE_RAW) == 0) {
- encsectors(trackp, (Uchar *)bp, secno, nsecs);
- fillsubch(trackp, (Uchar *)bp, secno, nsecs);
- } else {
- scrsectors(trackp, (Uchar *)bp, secno, nsecs);
- }
- return (amount);
-}
-
-int
-get_buf(int f, track_t *trackp, long secno, char **bpp, int size)
-{
- if (fs > 0) {
-/* return (faio_read_buf(f, *bpp, size));*/
- return (faio_get_buf(f, bpp, size));
- } else {
- return (fill_buf(f, trackp, secno, *bpp, size));
- }
-}
-
-int
-write_secs(SCSI *scgp, cdr_t *dp, char *bp, long startsec, int bytespt,
- int secspt, BOOL islast)
-{
- int amount;
-
-again:
- scgp->silent++;
- amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
- scgp->silent--;
- if (amount < 0) {
- if (scsi_in_progress(scgp)) {
- /*
- * If we sleep too long, the drive buffer is empty
- * before we start filling it again. The max. CD speed
- * is ~ 10 MB/s (52x RAW writing). The max. DVD speed
- * is ~ 25 MB/s (18x DVD 1385 kB/s).
- * With 10 MB/s, a 1 MB buffer empties within 100ms.
- * With 25 MB/s, a 1 MB buffer empties within 40ms.
- */
- if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0) {
- usleep(60000);
- } else {
-#ifndef _SC_CLK_TCK
- usleep(20000);
-#else
- if (sysconf(_SC_CLK_TCK) < 100)
- usleep(20000);
- else
- usleep(10000);
-
-#endif
- }
- goto again;
- }
- return (-1);
- }
- return (amount);
-}
-
-static int
-write_track_data(SCSI *scgp, cdr_t *dp, track_t *trackp)
-{
- int track = trackp->trackno;
- int f = -1;
- int isaudio;
- long startsec;
- Llong bytes_read = 0;
- Llong bytes = 0;
- Llong savbytes = 0;
- int count;
- Llong tracksize;
- int secsize;
- int secspt;
- int bytespt;
- int bytes_to_read;
- long amount;
- int pad;
- BOOL neednl = FALSE;
- BOOL islast = FALSE;
- char *bp = buf;
- struct timeval tlast;
- struct timeval tcur;
- float secsps = 75.0;
-long bsize;
-long bfree;
-#define BCAP
-#ifdef BCAP
-int per = 0;
-#ifdef XBCAP
-int oper = -1;
-#endif
-#endif
-
- if (dp->cdr_dstat->ds_flags & DSF_DVD)
- secsps = 676.27;
-
- scgp->silent++;
- if ((*dp->cdr_buffer_cap)(scgp, &bsize, &bfree) < 0)
- bsize = -1L;
- if (bsize == 0) /* If we have no (known) buffer, we cannot */
- bsize = -1L; /* retrieve the buffer fill ratio */
- scgp->silent--;
-
-
- if (is_packet(trackp)) /* XXX Ugly hack for now */
- return (write_packet_data(scgp, dp, trackp));
-
- if (trackp->xfp != NULL)
- f = xfileno(trackp->xfp);
-
- isaudio = is_audio(trackp);
- tracksize = trackp->tracksize;
- startsec = trackp->trackstart;
-
- secsize = trackp->secsize;
- secspt = trackp->secspt;
- bytespt = secsize * secspt;
-
- pad = !isaudio && is_pad(trackp); /* Pad only data tracks */
-
- if (debug) {
- printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n",
- secsize, secspt, bytespt, isaudio, pad);
- }
-
- if (lverbose) {
- if (tracksize > 0)
- printf("\rTrack %02d: 0 of %4lld MB written.",
- track, tracksize >> 20);
- else
- printf("\rTrack %02d: 0 MB written.", track);
- flush();
- neednl = TRUE;
- }
-
- gettimeofday(&tlast, (struct timezone *)0);
- do {
- bytes_to_read = bytespt;
- if (tracksize > 0) {
- if ((tracksize - bytes_read) > bytespt)
- bytes_to_read = bytespt;
- else
- bytes_to_read = tracksize - bytes_read;
- }
- count = get_buf(f, trackp, startsec, &bp, bytes_to_read);
-
- if (count < 0)
- comerr("read error on input file\n");
- if (count == 0)
- break;
- bytes_read += count;
- if (tracksize >= 0 && bytes_read >= tracksize) {
- count -= bytes_read - tracksize;
- /*
- * Paranoia: tracksize is known (trackp->tracksize >= 0)
- * At this point, trackp->padsize should alway be set
- * if the tracksize is less than 300 sectors.
- */
- if (trackp->padsecs == 0 &&
- (is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
- islast = TRUE;
- }
-
- if (count < bytespt) {
- if (debug) {
- printf("\nNOTICE: reducing block size for last record.\n");
- neednl = FALSE;
- }
-
- if ((amount = count % secsize) != 0) {
- amount = secsize - amount;
- count += amount;
- printf("\nWARNING: padding up to secsize.\n");
- neednl = FALSE;
- }
- bytespt = count;
- secspt = count / secsize;
- /*
- * If tracksize is not known (trackp->tracksize < 0)
- * we may need to set trackp->padsize
- * if the tracksize is less than 300 sectors.
- */
- if (trackp->padsecs == 0 &&
- (is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
- islast = TRUE;
- }
-
- amount = write_secs(scgp, dp, bp, startsec, bytespt, secspt, islast);
- if (amount < 0) {
- printf("%swrite track data: error after %lld bytes\n",
- neednl?"\n":"", bytes);
- return (-1);
- }
- bytes += amount;
- startsec += amount / secsize;
-
- if (lverbose && (bytes >= (savbytes + 0x100000))) {
- int fper;
- int nsecs = (bytes - savbytes) / secsize;
- float fspeed;
-
- gettimeofday(&tcur, (struct timezone *)0);
- printf("\rTrack %02d: %4lld", track, bytes >> 20);
- if (tracksize > 0)
- printf(" of %4lld MB", tracksize >> 20);
- else
- printf(" MB");
- printf(" written");
- fper = fifo_percent(TRUE);
- if (fper >= 0)
- printf(" (fifo %3d%%)", fper);
-#ifdef BCAP
- if (bsize > 0) { /* buffer size known */
- scgp->silent++;
- per = (*dp->cdr_buffer_cap)(scgp, (long *)0, &bfree);
- scgp->silent--;
- if (per >= 0) {
- per = 100*(bsize - bfree) / bsize;
- if ((bsize - bfree) <= amount || per <= 5)
- dp->cdr_dstat->ds_buflow++;
- if (per < (int)dp->cdr_dstat->ds_minbuf &&
- (startsec*secsize) > bsize) {
- dp->cdr_dstat->ds_minbuf = per;
- }
- printf(" [buf %3d%%]", per);
-#ifdef BCAPDBG
- printf(" %3ld %3ld", bsize >> 10, bfree >> 10);
-#endif
- }
- }
-#endif
-
- tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
- tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
- while (tlast.tv_usec < 0) {
- tlast.tv_usec += 1000000;
- tlast.tv_sec -= 1;
- }
- fspeed = (nsecs / secsps) /
- (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
- if (fspeed > 999.0)
- fspeed = 999.0;
-#ifdef BCAP
- if (bsize > 0 && per > dminbuf &&
- dp->cdr_dstat->ds_cdrflags & RF_WR_WAIT) {
- int wsecs = (per-dminbuf)*(bsize/secsize)/100;
- int msecs = 0x100000/secsize;
- int wt;
- int mt;
- int s = dp->cdr_dstat->ds_dr_cur_wspeed;
-
-
- if (s <= 0) {
- if (dp->cdr_dstat->ds_flags & DSF_DVD)
- s = 4;
- else
- s = 50;
- }
- if (wsecs > msecs) /* Less that 1 MB */
- wsecs = msecs;
- wt = wsecs * 1000 / secsps / fspeed;
- mt = (per-dminbuf)*(bsize/secsize)/100 * 1000 / secsps/s;
-
- if (wt > mt)
- wt = mt;
- if (wt > 1000) /* Max 1 second */
- wt = 1000;
- if (wt < 20) /* Min 20 ms */
- wt = 0;
-
- if (xdebug)
- printf(" |%3d %4dms %5dms|", wsecs, wt, mt);
- else
- printf(" |%3d %4dms|", wsecs, wt);
- if (wt > 0)
- usleep(wt*1000);
- }
-#endif
- if (dp->is_dvd) fspeed /= 9;
- printf(" %5.1fx", fspeed);
- printf(".");
- savbytes = (bytes >> 20) << 20;
- flush();
- neednl = TRUE;
- tlast = tcur;
- }
-#ifdef XBCAP
- if (bsize > 0) { /* buffer size known */
- (*dp->cdr_buffer_cap)(scgp, (long *)0, &bfree);
- per = 100*(bsize - bfree) / bsize;
- if (per != oper)
- printf("[buf %3d%%] %3ld %3ld\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",
- per, bsize >> 10, bfree >> 10);
- oper = per;
- flush();
- }
-
-
-#endif
- } while (tracksize < 0 || bytes_read < tracksize);
-
- if (!is_shorttrk(trackp) && (bytes / secsize) < 300) {
- /*
- * If tracksize is not known (trackp->tracksize < 0) or
- * for some strange reason we did not set padsecs properly
- * we may need to modify trackp->padsecs if
- * tracksize+padsecs is less than 300 sectors.
- */
- if ((trackp->padsecs + (bytes / secsize)) < 300)
- trackp->padsecs = 300 - (bytes / secsize);
- }
- if (trackp->padsecs > 0) {
- Llong padbytes;
-
- /*
- * pad_track() is based on secsize. Compute the amount of bytes
- * assumed by pad_track().
- */
- padbytes = (Llong)trackp->padsecs * secsize;
-
- if (neednl) {
- printf("\n");
- neednl = FALSE;
- }
- if ((padbytes >> 20) > 0) {
- neednl = TRUE;
- } else if (lverbose) {
- printf("Track %02d: writing %3lld KB of pad data.\n",
- track, (Llong)(padbytes >> 10));
- neednl = FALSE;
- }
- pad_track(scgp, dp, trackp, startsec, padbytes,
- TRUE, &savbytes);
- bytes += savbytes;
- startsec += savbytes / secsize;
- }
- printf("%sTrack %02d: Total bytes read/written: %lld/%lld (%lld sectors).\n",
- neednl?"\n":"", track, bytes_read, bytes, bytes/secsize);
- flush();
- return (0);
-}
-
-int
-pad_track(SCSI *scgp, cdr_t *dp, track_t *trackp, long startsec, Llong amt,
- BOOL dolast, Llong *bytesp)
-{
- int track = trackp->trackno;
- Llong bytes = 0;
- Llong savbytes = 0;
- Llong padsize = amt;
- int secsize;
- int secspt;
- int bytespt;
- int amount;
- BOOL neednl = FALSE;
- BOOL islast = FALSE;
- struct timeval tlast;
- struct timeval tcur;
- float secsps = 75.0;
-long bsize;
-long bfree;
-#define BCAP
-#ifdef BCAP
-int per;
-#ifdef XBCAP
-int oper = -1;
-#endif
-#endif
-
- if (dp->cdr_dstat->ds_flags & DSF_DVD)
- secsps = 676.27;
-
- scgp->silent++;
- if ((*dp->cdr_buffer_cap)(scgp, &bsize, &bfree) < 0)
- bsize = -1L;
- if (bsize == 0) /* If we have no (known) buffer, we cannot */
- bsize = -1L; /* retrieve the buffer fill ratio */
- scgp->silent--;
-
- secsize = trackp->secsize;
- secspt = trackp->secspt;
- bytespt = secsize * secspt;
-
- fillbytes(buf, bytespt, '\0');
-
- if ((amt >> 20) > 0) {
- printf("\rTrack %02d: 0 of %4lld MB pad written.",
- track, amt >> 20);
- flush();
- }
- gettimeofday(&tlast, (struct timezone *)0);
- do {
- if (amt < bytespt) {
- bytespt = roundup(amt, secsize);
- secspt = bytespt / secsize;
- }
- if (dolast && (amt - bytespt) <= 0)
- islast = TRUE;
-
- if (is_raw(trackp)) {
- encsectors(trackp, (Uchar *)buf, startsec, secspt);
- fillsubch(trackp, (Uchar *)buf, startsec, secspt);
- }
-
- amount = write_secs(scgp, dp, buf, startsec, bytespt, secspt, islast);
- if (amount < 0) {
- printf("%swrite track pad data: error after %lld bytes\n",
- neednl?"\n":"", bytes);
- if (bytesp)
- *bytesp = bytes;
-(*dp->cdr_buffer_cap)(scgp, (long *)0, (long *)0);
- return (-1);
- }
- amt -= amount;
- bytes += amount;
- startsec += amount / secsize;
-
- if (lverbose && (bytes >= (savbytes + 0x100000))) {
- int nsecs = (bytes - savbytes) / secsize;
- float fspeed;
-
- gettimeofday(&tcur, (struct timezone *)0);
- printf("\rTrack %02d: %4lld", track, bytes >> 20);
- if (padsize > 0)
- printf(" of %4lld MB", padsize >> 20);
- else
- printf(" MB");
- printf(" pad written");
- savbytes = (bytes >> 20) << 20;
-
-#ifdef BCAP
- if (bsize > 0) { /* buffer size known */
- scgp->silent++;
- per = (*dp->cdr_buffer_cap)(scgp, (long *)0, &bfree);
- scgp->silent--;
- if (per >= 0) {
- per = 100*(bsize - bfree) / bsize;
- if ((bsize - bfree) <= amount || per <= 5)
- dp->cdr_dstat->ds_buflow++;
- if (per < (int)dp->cdr_dstat->ds_minbuf &&
- (startsec*secsize) > bsize) {
- dp->cdr_dstat->ds_minbuf = per;
- }
- printf(" [buf %3d%%]", per);
-#ifdef BCAPDBG
- printf(" %3ld %3ld", bsize >> 10, bfree >> 10);
-#endif
- }
- }
-#endif
- tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
- tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
- while (tlast.tv_usec < 0) {
- tlast.tv_usec += 1000000;
- tlast.tv_sec -= 1;
- }
- fspeed = (nsecs / secsps) /
- (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
- if (fspeed > 999.0)
- fspeed = 999.0;
- printf(" %5.1fx", fspeed);
- printf(".");
- flush();
- neednl = TRUE;
- tlast = tcur;
- }
- } while (amt > 0);
-
- if (bytesp)
- *bytesp = bytes;
- if (bytes == 0)
- return (0);
- return (bytes > 0 ? 1:-1);
-}
-
-#ifdef USE_WRITE_BUF
-int
-write_buf(SCSI *scgp, cdr_t *dp, track_t *trackp, char *bp, long startsec,
- Llong amt, int secsize, BOOL dolast, Llong *bytesp)
-{
- int track = trackp->trackno;
- Llong bytes = 0;
- Llong savbytes = 0;
-/* int secsize;*/
- int secspt;
- int bytespt;
- int amount;
- BOOL neednl = FALSE;
- BOOL islast = FALSE;
-
-/* secsize = trackp->secsize;*/
-/* secspt = trackp->secspt;*/
-
- secspt = bufsize/secsize;
- secspt = min(255, secspt);
- bytespt = secsize * secspt;
-
-/* fillbytes(buf, bytespt, '\0');*/
-
- if ((amt >> 20) > 0) {
- printf("\rTrack %02d: 0 of %4ld MB pad written.",
- track, amt >> 20);
- flush();
- }
- do {
- if (amt < bytespt) {
- bytespt = roundup(amt, secsize);
- secspt = bytespt / secsize;
- }
- if (dolast && (amt - bytespt) <= 0)
- islast = TRUE;
-
- amount = write_secs(scgp, dp, bp, startsec, bytespt, secspt, islast);
- if (amount < 0) {
- printf("%swrite track data: error after %ld bytes\n",
- neednl?"\n":"", bytes);
- if (bytesp)
- *bytesp = bytes;
-(*dp->cdr_buffer_cap)(scgp, (long *)0, (long *)0);
- return (-1);
- }
- amt -= amount;
- bytes += amount;
- startsec += amount / secsize;
-
- if (lverbose && (bytes >= (savbytes + 0x100000))) {
- printf("\rTrack %02d: %3ld", track, bytes >> 20);
- savbytes = (bytes >> 20) << 20;
- flush();
- neednl = TRUE;
- }
- } while (amt > 0);
-
- if (bytesp)
- *bytesp = bytes;
- return (bytes);
-}
-#endif /* USE_WRITE_BUF */
-
-static void
-printdata(int track, track_t *trackp)
-{
- if (trackp->itracksize >= 0) {
- printf("Track %02d: data %4lld MB ",
- track, (Llong)(trackp->itracksize >> 20));
- } else {
- printf("Track %02d: data unknown length",
- track);
- }
- if (trackp->padsecs > 0) {
- Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize;
-
- if ((padbytes >> 20) > 0)
- printf(" padsize: %4lld MB", (Llong)(padbytes >> 20));
- else
- printf(" padsize: %4lld KB", (Llong)(padbytes >> 10));
- }
- if (trackp->pregapsize != (trackp->flags & TI_DVD)? 0 : 150) {
- printf(" pregapsize: %3ld", trackp->pregapsize);
- }
- if (xdebug)
- printf(" START: %ld SECTORS: %ld INDEX0 %ld",
- trackp->trackstart, trackp->tracksecs, trackp->index0start);
- printf("\n");
-}
-
-static void
-printaudio(int track, track_t *trackp)
-{
- if (trackp->itracksize >= 0) {
- printf("Track %02d: audio %4lld MB (%02d:%02d.%02d) %spreemp%s%s",
- track, (Llong)(trackp->itracksize >> 20),
- minutes(trackp->itracksize),
- seconds(trackp->itracksize),
- hseconds(trackp->itracksize),
- is_preemp(trackp) ? "" : "no ",
- is_swab(trackp) ? " swab":"",
- ((trackp->itracksize < 300L*trackp->isecsize) ||
- (trackp->itracksize % trackp->isecsize)) &&
- is_pad(trackp) ? " pad" : "");
- } else {
- printf("Track %02d: audio unknown length %spreemp%s%s",
- track, is_preemp(trackp) ? "" : "no ",
- is_swab(trackp) ? " swab":"",
- (trackp->itracksize % trackp->isecsize) && is_pad(trackp) ? " pad" : "");
- }
- if (is_scms(trackp))
- printf(" scms");
- else if (is_copy(trackp))
- printf(" copy");
- else
- printf(" ");
-
- if (trackp->padsecs > 0) {
- Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize;
-
- if ((padbytes >> 20) > 0)
- printf(" padsize: %4lld MB", (Llong)(padbytes >> 20));
- else
- printf(" padsize: %4lld KB", (Llong)(padbytes >> 10));
- printf(" (%02d:%02d.%02d)",
- Sminutes(trackp->padsecs),
- Sseconds(trackp->padsecs),
- Shseconds(trackp->padsecs));
- }
- if (trackp->pregapsize != ((trackp->flags & TI_DVD)? 0 : 150) || xdebug > 0) {
- printf(" pregapsize: %3ld", trackp->pregapsize);
- }
- if (xdebug)
- printf(" START: %ld SECTORS: %ld INDEX0 %ld",
- trackp->trackstart, trackp->tracksecs, trackp->index0start);
- printf("\n");
-}
-
-static void
-checkfile(int track, track_t *trackp)
-{
- if (trackp->itracksize > 0 &&
- is_audio(trackp) &&
- ((!is_shorttrk(trackp) &&
- (trackp->itracksize < 300L*trackp->isecsize)) ||
- (trackp->itracksize % trackp->isecsize)) &&
- !is_pad(trackp)) {
- errmsgno(EX_BAD, "Bad audio track size %lld for track %02d.\n",
- (Llong)trackp->itracksize, track);
- errmsgno(EX_BAD, "Audio tracks must be at least %ld bytes and a multiple of %d.\n",
- 300L*trackp->isecsize, trackp->isecsize);
-
- if (!is_shorttrk(trackp) && (trackp->itracksize < 300L*trackp->isecsize))
- comerrno(EX_BAD, "See -shorttrack option.\n");
- if (!is_pad(trackp) && (trackp->itracksize % trackp->isecsize))
- comerrno(EX_BAD, "See -pad option.\n");
- }
-
- if (lverbose == 0 && xdebug == 0)
- return;
-
- if (is_audio(trackp))
- printaudio(track, trackp);
- else
- printdata(track, trackp);
-}
-
-static int
-checkfiles(int tracks, track_t *trackp)
-{
- int i;
- int isaudio = 1;
- int starttrack = 1;
- int endtrack = tracks;
-
- if (xdebug) {
- /*
- * Include Lead-in & Lead-out.
- */
- starttrack--;
- endtrack++;
- }
- for (i = starttrack; i <= endtrack; i++) {
- if (!is_audio(&trackp[i]))
- isaudio = 0;
- if (xdebug)
- printf("SECTYPE %X ", trackp[i].sectype);
- checkfile(i, &trackp[i]);
- }
- return (isaudio);
-}
-
-static void
-setleadinout(int tracks, track_t *trackp)
-{
- /*
- * Set some values for track 0 (the lead-in)
- */
- if (!is_clone(&trackp[0])) {
- trackp[0].sectype = trackp[1].sectype;
- trackp[0].dbtype = trackp[1].dbtype;
- trackp[0].dataoff = trackp[1].dataoff;
-
- /*
- * XXX Which other flags should be copied to Track 0 ?
- */
- if (is_audio(&trackp[1]))
- trackp[0].flags |= TI_AUDIO;
- }
-
- /*
- * Set some values for track 0xAA (the lead-out)
- */
- trackp[tracks+1].pregapsize = 0;
- trackp[tracks+1].isecsize = trackp[tracks].isecsize;
- trackp[tracks+1].secsize = trackp[tracks].secsize;
-
- if (!is_clone(&trackp[0])) {
- trackp[tracks+1].tracktype = trackp[tracks].tracktype;
- trackp[tracks+1].sectype = trackp[tracks].sectype;
- trackp[tracks+1].dbtype = trackp[tracks].dbtype;
- trackp[tracks+1].dataoff = trackp[tracks].dataoff;
- }
-
- trackp[tracks+1].flags = trackp[tracks].flags;
-}
-
-static void
-setpregaps(int tracks, track_t *trackp)
-{
- int i;
- int sectype;
- long pregapsize;
- track_t *tp;
-
- sectype = trackp[1].sectype;
- sectype &= ST_MASK;
-
- for (i = 1; i <= tracks; i++) {
- tp = &trackp[i];
- if (tp->pregapsize == -1L) {
- tp->pregapsize = 150; /* Default CD Pre GAP*/
- if (trackp->flags & TI_DVD) {
- tp->pregapsize = 0;
- } else if (sectype != (tp->sectype & ST_MASK)) {
- tp->pregapsize = 255; /* Pre GAP is 255 */
- tp->flags &= ~TI_PREGAP;
- }
- }
- sectype = tp->sectype & ST_MASK; /* Save old sectype */
- }
- trackp[tracks+1].pregapsize = 0;
- trackp[tracks+1].index0start = 0;
-
- for (i = 1; i <= tracks; i++) {
- /*
- * index0start is set below tracksecks if this track contains
- * the pregap (index 0) of the next track.
- */
- trackp[i].index0start = trackp[i].tracksecs;
-
- pregapsize = trackp[i+1].pregapsize;
- if (is_pregap(&trackp[i+1]) && pregapsize > 0)
- trackp[i].index0start -= pregapsize;
- }
-}
-
-/*
- * Check total size of the medium
- */
-static long
-checktsize(int tracks, track_t *trackp)
-{
- int i;
- Llong curr;
- Llong total = -150; /* CD track #1 pregap compensation */
- Ullong btotal;
- track_t *tp;
-
- if (trackp->flags & TI_DVD)
- total = 0;
- for (i = 1; i <= tracks; i++) {
- tp = &trackp[i];
- if (!is_pregap(tp))
- total += tp->pregapsize;
-
- if (lverbose > 1) {
- printf("track: %d start: %lld pregap: %ld\n",
- i, total, tp->pregapsize);
- }
- tp->trackstart = total;
- if (tp->itracksize >= 0) {
- curr = (tp->itracksize + (tp->isecsize-1)) / tp->isecsize;
- curr += tp->padsecs;
- /*
- * Minimum track size is 4s
- */
- if (!is_shorttrk(tp) && curr < 300)
- curr = 300;
- if ((trackp->flags & TI_DVD) == 0) {
- /*
- * XXX Was passiert hier bei is_packet() ???
- */
- if (is_tao(tp) && !is_audio(tp)) {
- curr += 2;
- }
- }
- total += curr;
- } else if (is_sao(tp) || is_raw(tp)) {
- errmsgno(EX_BAD, "Track %d has unknown length.\n", i);
- comerrno(EX_BAD,
- "Use tsize= option in %s mode to specify track size.\n",
- is_sao(tp) ? "SAO" : "RAW");
- }
- }
- tp = &trackp[i];
- tp->trackstart = total;
- tp->tracksecs = 6750; /* Size of first session Lead-Out */
- if (!lverbose)
- return (total);
-
- if (trackp->flags & TI_DVD)
- btotal = (Ullong)total * 2048;
- else
- btotal = (Ullong)total * 2352;
-/* XXX CD Sector Size ??? */
- if (tracks > 0) {
- if (trackp->flags & TI_DVD) {
- printf("Total size: %4llu MB = %lld sectors\n",
- btotal >> 20, total);
- } else {
- printf("Total size: %4llu MB (%02d:%02d.%02d) = %lld sectors\n",
- btotal >> 20,
- minutes(btotal),
- seconds(btotal),
- hseconds(btotal), total);
- btotal += 150 * 2352;
- printf("Lout start: %4llu MB (%02d:%02d/%02d) = %lld sectors\n",
- btotal >> 20,
- minutes(btotal),
- seconds(btotal),
- frames(btotal), total);
- }
- }
- return (total);
-}
-
-static void
-opentracks(track_t *trackp)
-{
- track_t *tp;
- int i;
- int tracks = trackp[0].tracks;
-
- Llong tracksize;
- int secsize;
-
- for (i = 1; i <= tracks; i++) {
- tp = &trackp[i];
-
- if (auinfosize(tp->filename, tp)) {
- /*
- * open stdin
- */
- tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0);
- } else if (strcmp("-", tp->filename) == 0) {
- /*
- * open stdin
- */
- tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0);
- } else {
- if ((tp->xfp = xopen(tp->filename,
- O_RDONLY|O_BINARY, 0)) == NULL) {
- comerr("Cannot open '%s'.\n", tp->filename);
- }
- }
-
- checksize(tp);
- tracksize = tp->itracksize;
- secsize = tp->isecsize;
- if (!is_shorttrk(tp) &&
- tracksize > 0 && (tracksize / secsize) < 300) {
-
- tracksize = roundup(tracksize, secsize);
- if ((tp->padsecs +
- (tracksize / secsize)) < 300) {
- tp->padsecs =
- 300 - tracksize / secsize;
- }
- if (xdebug) {
- printf("TRACK %d SECTORS: %ld",
- i, tp->tracksecs);
- printf(" pasdize %lld (%ld sectors)\n",
- (Llong)tp->padsecs * secsize,
- tp->padsecs);
- }
- }
-#ifdef AUINFO
- if (tp->flags & TI_USEINFO) {
- auinfo(tp->filename, i, trackp);
- if (lverbose > 0 && i == 1)
- printf("pregap1: %ld\n", trackp[1].pregapsize);
- }
-#endif
- /*
- * tracksecks is total numbers of sectors in track (starting from
- * index 0).
- */
- if (tp->padsecs > 0)
- tp->tracksecs += tp->padsecs;
-
- if (debug) {
- printf("File: '%s' itracksize: %lld isecsize: %d tracktype: %d = %s sectype: %X = %s dbtype: %s flags %X\n",
- tp->filename, (Llong)tp->itracksize,
- tp->isecsize,
- tp->tracktype & TOC_MASK, toc2name[tp->tracktype & TOC_MASK],
- tp->sectype, st2name[tp->sectype & ST_MASK], db2name[tp->dbtype], tp->flags);
- }
- }
-}
-
-static void
-checksize(track_t *trackp)
-{
- struct stat st;
- Llong lsize;
- int f = -1;
-
- if (trackp->xfp != NULL)
- f = xfileno(trackp->xfp);
-
- /*
- * If the current input file is a regular file and
- * 'padsize=' has not been specified,
- * use fstat() or file parser to get the size of the file.
- */
- if (trackp->itracksize < 0 && (trackp->flags & TI_ISOSIZE) != 0) {
- lsize = isosize(f);
- trackp->itracksize = lsize;
- if (trackp->itracksize != lsize)
- comerrno(EX_BAD, "This OS cannot handle large ISO-9660 images.\n");
- }
- if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
- lsize = ausize(f);
- trackp->itracksize = lsize;
- if (trackp->itracksize != lsize)
- comerrno(EX_BAD, "This OS cannot handle large audio images.\n");
- }
- if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
- lsize = wavsize(f);
- trackp->itracksize = lsize;
- if (trackp->itracksize != lsize)
- comerrno(EX_BAD, "This OS cannot handle large WAV images.\n");
- if (trackp->itracksize > 0) /* Force little endian input */
- trackp->flags |= TI_SWAB;
- }
- if (trackp->itracksize == AU_BAD_CODING) {
- comerrno(EX_BAD, "Inappropriate audio coding in '%s'.\n",
- trackp->filename);
- }
- if (trackp->itracksize < 0 &&
- fstat(f, &st) >= 0 && S_ISREG(st.st_mode)) {
- trackp->itracksize = st.st_size;
- }
- if (trackp->itracksize >= 0) {
- /*
- * We do not allow cdrecord to start if itracksize is not
- * a multiple of isecsize or we are allowed to pad to secsize via -pad.
- * For this reason, we may safely always assume padding.
- */
- trackp->tracksecs = (trackp->itracksize + trackp->isecsize -1) / trackp->isecsize;
- trackp->tracksize = (trackp->itracksize / trackp->isecsize) * trackp->secsize
- + trackp->itracksize % trackp->isecsize;
- } else {
- trackp->tracksecs = -1L;
- }
-}
-
-static BOOL
-checkdsize(SCSI *scgp, cdr_t *dp, long tsize, int flags)
-{
- long startsec = 0L;
- long endsec = 0L;
- dstat_t *dsp = dp->cdr_dstat;
- int profile;
-
- scgp->silent++;
- (*dp->cdr_next_wr_address)(scgp, (track_t *)0, &startsec);
- scgp->silent--;
-
- /*
- * This only should happen when the drive is currently in SAO mode.
- * We rely on the drive being in TAO mode, a negative value for
- * startsec is not correct here it may be caused by bad firmware or
- * by a drive in SAO mode. In SAO mode the drive will report the
- * pre-gap as part of the writable area.
- */
- if (startsec < 0)
- startsec = 0;
-
- /*
- * Size limitations (sectors) for CD's:
- *
- * 404850 == 90 min Red book calls this the
- * first negative time
- * allows lead out start up to
- * block 404700
- *
- * 449850 == 100 min This is the first time that
- * is no more representable
- * in a two digit BCD number.
- * allows lead out start up to
- * block 449700
- *
- * ~540000 == 120 min The largest CD ever made.
- *
- * ~650000 == 1.3 GB a Double Density (DD) CD.
- */
-
- endsec = startsec + tsize;
- dsp->ds_startsec = startsec;
- dsp->ds_endsec = endsec;
-
-
- if (dsp->ds_maxblocks > 0) {
- /*
- * dsp->ds_maxblocks > 0 (disk capacity is known).
- */
- if (lverbose)
- printf("Blocks total: %ld Blocks current: %ld Blocks remaining: %ld\n",
- (long)dsp->ds_maxblocks,
- (long)dsp->ds_maxblocks - startsec,
- (long)dsp->ds_maxblocks - endsec);
-
- if (endsec > dsp->ds_maxblocks) {
- if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */
- /*
- * There is no overburning on DVD...
- */
- errmsgno(EX_BAD,
- "Data does not fit on current disk.\n");
- goto toolarge;
- }
- errmsgno(EX_BAD,
- "WARNING: Data may not fit on current disk.\n");
-
- /* XXX Check for flags & CDR_NO_LOLIMIT */
-/* goto toolarge;*/
- }
- if (lverbose && dsp->ds_maxrblocks > 0)
- printf("RBlocks total: %ld RBlocks current: %ld RBlocks remaining: %ld\n",
- (long)dsp->ds_maxrblocks,
- (long)dsp->ds_maxrblocks - startsec,
- (long)dsp->ds_maxrblocks - endsec);
- if (dsp->ds_maxrblocks > 0 && endsec > dsp->ds_maxrblocks) {
- errmsgno(EX_BAD,
- "Data does not fit on current disk.\n");
- goto toolarge;
- }
- if ((endsec > dsp->ds_maxblocks && endsec > 404700) ||
- (dsp->ds_maxrblocks > 404700 && 449850 > dsp->ds_maxrblocks)) {
- /*
- * Assume that this must be a CD and not a DVD.
- * So this is a non Red Book compliant CD with a
- * capacity between 90 and 99 minutes.
- */
- if (dsp->ds_maxrblocks > 404700)
- printf("RedBook total: %ld RedBook current: %ld RedBook remaining: %ld\n",
- 404700L,
- 404700L - startsec,
- 404700L - endsec);
- if (endsec > dsp->ds_maxblocks && endsec > 404700) {
- if ((flags & (F_IGNSIZE|F_FORCE)) == 0) {
- errmsgno(EX_BAD,
- "Notice: Most recorders cannot write CD's >= 90 minutes.\n");
- errmsgno(EX_BAD,
- "Notice: Use -ignsize option to allow >= 90 minutes.\n");
- }
- goto toolarge;
- }
- }
- } else {
- /*
- * dsp->ds_maxblocks == 0 (disk capacity is unknown).
- */
- profile = dp->profile;
- if (endsec >= (4200000)) {
- errmsgno(EX_BAD,
- "ERROR: Could not manage to find medium size, and more than 8.0 GB of data.\n");
- goto toolarge;
- } else if (profile != 0x2B) {
- if (endsec >= (2300000)) {
- errmsgno(EX_BAD,
- "ERROR: Could not manage to find medium size, and more than 4.3 GB of data for a non dual layer disc.\n");
- goto toolarge;
- } else if (endsec >= (405000-300)) { /*<90 min disk or DVD*/
- errmsgno(EX_BAD,
- "WARNING: Could not manage to find medium size, and more than 90 mins of data.\n");
- } else if (endsec >= (333000-150)) { /* 74 min disk*/
- errmsgno(EX_BAD,
- "WARNING: Data may not fit on standard 74min disk.\n");
- }
- }
- }
- if (dsp->ds_maxblocks <= 0 || endsec <= dsp->ds_maxblocks)
- return (TRUE);
- /* FALLTHROUGH */
-toolarge:
- if (dsp->ds_maxblocks > 0 && endsec > dsp->ds_maxblocks) {
- if ((flags & (F_OVERBURN|F_IGNSIZE|F_FORCE)) != 0) {
- if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */
- errmsgno(EX_BAD,
- "Notice: -overburn is not expected to work with DVD media.\n");
- }
- errmsgno(EX_BAD,
- "Notice: Overburning active. Trying to write more than the official disk capacity.\n");
- return (TRUE);
- } else {
- if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */
- errmsgno(EX_BAD,
- "Notice: Use -overburn option to write more than the official disk capacity.\n");
- errmsgno(EX_BAD,
- "Notice: Most CD-writers do overburning only on SAO or RAW mode.\n");
- }
- return (FALSE);
- }
- }
- if (dsp->ds_maxblocks < 449850) {
- if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */
- if (endsec <= dsp->ds_maxblocks)
- return (TRUE);
- errmsgno(EX_BAD, "Cannot write more than remaining DVD capacity.\n");
- return (FALSE);
- }
- /*
- * Assume that this must be a CD and not a DVD.
- */
- if (endsec > 449700) {
- errmsgno(EX_BAD, "Cannot write CD's >= 100 minutes.\n");
- return (FALSE);
- }
- }
- if ((flags & (F_IGNSIZE|F_FORCE)) != 0)
- return (TRUE);
- return (FALSE);
-}
-
-static void
-raise_fdlim()
-{
-#ifdef RLIMIT_NOFILE
-
- struct rlimit rlim;
-
- /*
- * Set max # of file descriptors to be able to hold all files open
- */
- getrlimit(RLIMIT_NOFILE, &rlim);
- if (rlim.rlim_cur >= (MAX_TRACK + 10))
- return;
-
- rlim.rlim_cur = MAX_TRACK + 10;
- if (rlim.rlim_cur > rlim.rlim_max)
- errmsgno(EX_BAD,
- "Warning: low file descriptor limit (%lld)\n",
- (Llong)rlim.rlim_max);
- setrlimit(RLIMIT_NOFILE, &rlim);
-
-#endif /* RLIMIT_NOFILE */
-}
-
-static void
-raise_memlock()
-{
-#ifdef RLIMIT_MEMLOCK
- struct rlimit rlim;
-
- rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
-
- if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0)
- errmsg("Warning: Cannot raise RLIMIT_MEMLOCK limits.");
-#endif /* RLIMIT_MEMLOCK */
-}
-
-char *opts =
-"help,version,checkdrive,prcap,inq,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#";
-
-/*
- * Defines used to find whether a write mode has been specified.
- */
-#define M_TAO 1 /* Track at Once mode */
-#define M_SAO 2 /* Session at Once mode (also known as DAO) */
-#define M_RAW 4 /* Raw mode */
-#define M_PACKET 8 /* Packed mode */
-static int
-gargs(int ac, char **av, int *tracksp, track_t *trackp, char **devp,
- int *timeoutp, cdr_t **dpp, int *speedp, long *flagsp, int *blankp,
- int *formatp)
-{
- int cac;
- char * const*cav;
- char *driver = NULL;
- char *dev = NULL;
- char *isrc = NULL;
- char *mcn = NULL;
- char *tindex = NULL;
- char *cuefile = NULL;
- char *textfile = NULL;
- long bltype = -1;
- int doformat = 0;
- int formattype = -1;
- Llong tracksize;
- Llong padsize;
- long pregapsize;
- long defpregap = -1L;
- int pktsize;
- int speed = -1;
- int help = 0;
- int version = 0;
- int checkdrive = 0;
- int setdropts = 0;
- int prcap = 0;
- int inq = 0;
- int scanbus = 0;
- int reset = 0;
- int doabort = 0;
- int overburn = 0;
- int ignsize = 0;
- int useinfo = 0;
- int load = 0;
- int lock = 0;
- int eject = 0;
- int dummy = 0;
- int msinfo = 0;
- int toc = 0;
- int atip = 0;
- int multi = 0;
- int fix = 0;
- int nofix = 0;
- int waiti = 0;
- int immed = 0;
- int audio;
- int autoaudio = 0;
- int data;
- int mode2;
- int xa;
- int xa1;
- int xa2;
- int xamix;
- int cdi;
- int isize;
- int ispacket = 0;
- int noclose = 0;
- int force = 0;
- int tao = 0;
- int dao = 0;
- int raw = 0;
- int raw96r = 0;
- int raw96p = 0;
- int raw16 = 0;
- int clone = 0;
- int scms = 0;
- int preemp = 0;
- int nopreemp;
- int copy = 0;
- int nocopy;
- int pad = 0;
- int bswab = 0;
- int nopad;
- int usetext = 0;
- int shorttrack = 0;
- int noshorttrack;
- int flags;
- int tracks = *tracksp;
- int tracktype = TOC_ROM;
-/* int sectype = ST_ROM_MODE1 | ST_MODE_1;*/
- int sectype = SECT_ROM;
- int dbtype = DB_ROM_MODE1;
- int secsize = DATA_SEC_SIZE;
- int dataoff = 16;
- int ga_ret;
- int wm = 0;
-
- trackp[0].flags |= TI_TAO;
- trackp[1].pregapsize = -1;
- *flagsp |= F_WRITE;
-
- cac = --ac;
- cav = ++av;
- for (; ; cac--, cav++) {
- tracksize = (Llong)-1L;
- padsize = (Llong)0L;
- pregapsize = defpregap;
- audio = data = mode2 = xa = xa1 = xa2 = xamix = cdi = 0;
- isize = nopreemp = nocopy = nopad = noshorttrack = 0;
- pktsize = 0;
- isrc = NULL;
- tindex = NULL;
- /*
- * Get options up to next file type arg.
- */
- if ((ga_ret = getargs(&cac, &cav, opts,
- &help, &version, &checkdrive, &prcap,
- &inq, &scanbus, &reset, &doabort, &overburn, &ignsize,
- &useinfo,
- devp, timeoutp, &driver, &driveropts, &setdropts,
- getllnum, &tracksize,
- getllnum, &padsize,
- getnum, &pregapsize,
- getnum, &defpregap,
- &speed,
- &load, &lock,
- &eject, &dummy, &msinfo, &toc, &atip,
- &multi, &fix, &nofix, &waiti, &immed,
- &debug, &debug,
- &kdebug, &kdebug,
- &lverbose, &lverbose,
- &scsi_verbose, &scsi_verbose,
- &xdebug, &xdebug,
- &silent, &silent,
- &audio, &data, &mode2,
- &xa, &xa1, &xa2, &xamix, &cdi,
- &isize,
- &nopreemp, &preemp,
- &nocopy, ©,
- &nopad, &pad, &bswab, getnum, &fs, getnum, &bufsize,
- getbltype, &bltype, &doformat, getformattype, &formattype, &pktsize,
- &ispacket, &noclose, &force,
- &tao, &dao, &dao, &raw, &raw96r, &raw96p, &raw16,
- &clone,
- &scms, &isrc, &mcn, &tindex,
- &cuefile, &textfile, &usetext,
- &shorttrack, &noshorttrack,
- &gracetime, &dminbuf)) < 0) {
- errmsgno(EX_BAD, "Bad Option: %s.\n", cav[0]);
- susage(EX_BAD);
- }
- if (help)
- usage(0);
- if (tracks == 0) {
- if (driver)
- set_cdrcmds(driver, dpp);
- if (version)
- *flagsp |= F_VERSION;
- if (checkdrive)
- *flagsp |= F_CHECKDRIVE;
- if (prcap)
- *flagsp |= F_PRCAP;
- if (inq)
- *flagsp |= F_INQUIRY;
- if (scanbus)
- *flagsp |= F_SCANBUS;
- if (reset)
- *flagsp |= F_RESET;
- if (doabort)
- *flagsp |= F_ABORT;
- if (overburn)
- *flagsp |= F_OVERBURN;
- if (ignsize)
- *flagsp |= F_IGNSIZE;
- if (load)
- *flagsp |= F_LOAD;
- if (lock)
- *flagsp |= F_DLCK;
- if (eject)
- *flagsp |= F_EJECT;
- if (dummy)
- *flagsp |= F_DUMMY;
- if (setdropts)
- *flagsp |= F_SETDROPTS;
- if (msinfo)
- *flagsp |= F_MSINFO;
- if (toc) {
- *flagsp |= F_TOC;
- *flagsp &= ~F_WRITE;
- }
- if (atip) {
- *flagsp |= F_PRATIP;
- *flagsp &= ~F_WRITE;
- }
- if (multi) {
- /*
- * 2048 Bytes user data
- */
- *flagsp |= F_MULTI;
- tracktype = TOC_XA2;
- sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
- sectype = SECT_MODE_2_F1;
- dbtype = DB_XA_MODE2; /* XXX -multi nimmt DB_XA_MODE2_F1 !!! */
- secsize = DATA_SEC_SIZE; /* 2048 */
- dataoff = 24;
- }
- if (fix)
- *flagsp |= F_FIX;
- if (nofix)
- *flagsp |= F_NOFIX;
- if (waiti)
- *flagsp |= F_WAITI;
- if (immed)
- *flagsp |= F_IMMED;
- if (force)
- *flagsp |= F_FORCE;
-
- if (bltype >= 0) {
- *flagsp |= F_BLANK;
- *blankp = bltype;
- }
- if (doformat > 0) {
- *flagsp |= F_FORMAT;
- *formatp |= FULL_FORMAT;
- }
- if (formattype >= 0) {
- *flagsp |= F_FORMAT;
- *formatp |= formattype;
- }
- if (ispacket)
- wm |= M_PACKET;
- if (tao)
- wm |= M_TAO;
- if (dao) {
- *flagsp |= F_SAO;
- trackp[0].flags &= ~TI_TAO;
- trackp[0].flags |= TI_SAO;
- wm |= M_SAO;
-
- } else if ((raw == 0) && (raw96r + raw96p + raw16) > 0)
- raw = 1;
- if ((raw != 0) && (raw96r + raw96p + raw16) == 0)
- raw96r = 1;
- if (raw96r) {
- if (!dao)
- *flagsp |= F_RAW;
- trackp[0].flags &= ~TI_TAO;
- trackp[0].flags |= TI_RAW;
- trackp[0].flags |= TI_RAW96R;
- wm |= M_RAW;
- }
- if (raw96p) {
- if (!dao)
- *flagsp |= F_RAW;
- trackp[0].flags &= ~TI_TAO;
- trackp[0].flags |= TI_RAW;
- wm |= M_RAW;
- }
- if (raw16) {
- if (!dao)
- *flagsp |= F_RAW;
- trackp[0].flags &= ~TI_TAO;
- trackp[0].flags |= TI_RAW;
- trackp[0].flags |= TI_RAW16;
- wm |= M_RAW;
- }
- if (mcn) {
-#ifdef AUINFO
- setmcn(mcn, &trackp[0]);
-#else
- trackp[0].isrc = malloc(16);
- fillbytes(trackp[0].isrc, 16, '\0');
- strncpy(trackp[0].isrc, mcn, 13);
-#endif
- mcn = NULL;
- }
- if ((raw96r + raw96p + raw16) > 1) {
- errmsgno(EX_BAD, "Too many raw modes.\n");
- comerrno(EX_BAD, "Only one of -raw16, -raw96p, -raw96r allowed.\n");
- }
- if ((tao + ispacket + dao + raw) > 1) {
- errmsgno(EX_BAD, "Too many write modes.\n");
- comerrno(EX_BAD, "Only one of -packet, -dao, -raw allowed.\n");
- }
- if (dao && (raw96r + raw96p + raw16) > 0) {
- if (raw16)
- comerrno(EX_BAD, "SAO RAW writing does not allow -raw16.\n");
- if (!clone)
- comerrno(EX_BAD, "SAO RAW writing only makes sense in clone mode.\n");
-#ifndef CLONE_WRITE
- comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n");
-#endif
- comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n");
- }
- if (clone) {
- *flagsp |= F_CLONE;
- trackp[0].flags |= TI_CLONE;
-#ifndef CLONE_WRITE
- comerrno(EX_BAD, "Clone writing not compiled in.\n");
-#endif
- }
- if (textfile) {
- if (!checktextfile(textfile)) {
- if ((*flagsp & F_WRITE) != 0) {
- comerrno(EX_BAD,
- "Cannot use '%s' as CD-Text file.\n",
- textfile);
- }
- }
- if ((*flagsp & F_WRITE) != 0) {
- if ((dao + raw96r + raw96p) == 0)
- comerrno(EX_BAD,
- "CD-Text needs -dao, -raw96r or -raw96p.\n");
- }
- trackp[0].flags |= TI_TEXT;
- }
- version = checkdrive = prcap = inq = scanbus = reset = doabort =
- overburn = ignsize =
- load = lock = eject = dummy = msinfo = toc = atip = multi = fix = nofix =
- waiti = immed = force = dao = setdropts = 0;
- raw96r = raw96p = raw16 = clone = 0;
- } else if ((version + checkdrive + prcap + inq + scanbus +
- reset + doabort + overburn + ignsize +
- load + lock + eject + dummy + msinfo + toc + atip + multi + fix + nofix +
- waiti + immed + force + dao + setdropts +
- raw96r + raw96p + raw16 + clone) > 0 ||
- mcn != NULL)
- comerrno(EX_BAD, "Badly placed option. Global options must be before any track.\n");
-
- if (nopreemp)
- preemp = 0;
- if (nocopy)
- copy = 0;
- if (nopad)
- pad = 0;
- if (noshorttrack)
- shorttrack = 0;
-
- if ((audio + data + mode2 + xa + xa1 + xa2 + xamix) > 1) {
- errmsgno(EX_BAD, "Too many types for track %d.\n", tracks+1);
- comerrno(EX_BAD, "Only one of -audio, -data, -mode2, -xa, -xa1, -xa2, -xamix allowed.\n");
- }
- if (ispacket && audio) {
- comerrno(EX_BAD, "Audio data cannot be written in packet mode.\n");
- }
- /*
- * Check whether the next argument is a file type arg.
- * If this is true, then we got a track file name.
- * If getargs() did previously return NOTAFLAG, we may have hit
- * an argument that has been escaped via "--", so we may not
- * call getfiles() again in this case. If we would call
- * getfiles() and the current arg has been escaped and looks
- * like an option, a call to getfiles() would skip it.
- */
- if (ga_ret != NOTAFLAG)
- ga_ret = getfiles(&cac, &cav, opts);
- if (autoaudio) {
- autoaudio = 0;
- tracktype = TOC_ROM;
- sectype = ST_ROM_MODE1 | ST_MODE_1;
- sectype = SECT_ROM;
- dbtype = DB_ROM_MODE1;
- secsize = DATA_SEC_SIZE; /* 2048 */
- dataoff = 16;
- }
- if (ga_ret == NOTAFLAG && (is_auname(cav[0]) || is_wavname(cav[0]))) {
- /*
- * We got a track and autodetection decided that it
- * is an audio track.
- */
- autoaudio++;
- audio++;
- }
- if (data) {
- /*
- * 2048 Bytes user data
- */
- tracktype = TOC_ROM;
- sectype = ST_ROM_MODE1 | ST_MODE_1;
- sectype = SECT_ROM;
- dbtype = DB_ROM_MODE1;
- secsize = DATA_SEC_SIZE; /* 2048 */
- dataoff = 16;
- }
- if (mode2) {
- /*
- * 2336 Bytes user data
- */
- tracktype = TOC_ROM;
- sectype = ST_ROM_MODE2 | ST_MODE_2;
- sectype = SECT_MODE_2;
- dbtype = DB_ROM_MODE2;
- secsize = MODE2_SEC_SIZE; /* 2336 */
- dataoff = 16;
- }
- if (audio) {
- /*
- * 2352 Bytes user data
- */
- tracktype = TOC_DA;
- sectype = preemp ? ST_AUDIO_PRE : ST_AUDIO_NOPRE;
- sectype |= ST_MODE_AUDIO;
- sectype = SECT_AUDIO;
- if (preemp)
- sectype |= ST_PREEMPMASK;
- dbtype = DB_RAW;
- secsize = AUDIO_SEC_SIZE; /* 2352 */
- dataoff = 0;
- }
- if (xa) {
- /*
- * 2048 Bytes user data
- */
- if (tracktype != TOC_CDI)
- tracktype = TOC_XA2;
- sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
- sectype = SECT_MODE_2_F1;
- dbtype = DB_XA_MODE2;
- secsize = DATA_SEC_SIZE; /* 2048 */
- dataoff = 24;
- }
- if (xa1) {
- /*
- * 8 Bytes subheader + 2048 Bytes user data
- */
- if (tracktype != TOC_CDI)
- tracktype = TOC_XA2;
- sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
- sectype = SECT_MODE_2_F1;
- dbtype = DB_XA_MODE2_F1;
- secsize = 2056;
- dataoff = 16;
- }
- if (xa2) {
- /*
- * 2324 Bytes user data
- */
- if (tracktype != TOC_CDI)
- tracktype = TOC_XA2;
- sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_2;
- sectype = SECT_MODE_2_F2;
- dbtype = DB_XA_MODE2_F2;
- secsize = 2324;
- dataoff = 24;
- }
- if (xamix) {
- /*
- * 8 Bytes subheader + 2324 Bytes user data
- */
- if (tracktype != TOC_CDI)
- tracktype = TOC_XA2;
- sectype = ST_ROM_MODE2 | ST_MODE_2_MIXED;
- sectype = SECT_MODE_2_MIX;
- dbtype = DB_XA_MODE2_MIX;
- secsize = 2332;
- dataoff = 16;
- }
- if (cdi) {
- tracktype = TOC_CDI;
- }
- if (tracks == 0) {
- trackp[0].tracktype = tracktype;
- trackp[0].dbtype = dbtype;
- trackp[0].isecsize = secsize;
- trackp[0].secsize = secsize;
- if ((*flagsp & F_RAW) != 0) {
- trackp[0].secsize = is_raw16(&trackp[0]) ?
- RAW16_SEC_SIZE:RAW96_SEC_SIZE;
- }
- if ((*flagsp & F_DUMMY) != 0)
- trackp[0].tracktype |= TOCF_DUMMY;
- if ((*flagsp & F_MULTI) != 0)
- trackp[0].tracktype |= TOCF_MULTI;
- }
-
- flags = trackp[0].flags;
-
- if ((sectype & ST_AUDIOMASK) != 0)
- flags |= TI_AUDIO;
- if (isize) {
- flags |= TI_ISOSIZE;
- if ((*flagsp & F_MULTI) != 0)
- comerrno(EX_BAD, "Cannot get isosize for multi session disks.\n");
- /*
- * As we do not get the padding from the ISO-9660
- * formatting utility, we need to force padding here.
- */
- flags |= TI_PAD;
- if (padsize == (Llong)0L)
- padsize = (Llong)PAD_SIZE;
- }
-
- if ((flags & TI_AUDIO) != 0) {
- if (preemp)
- flags |= TI_PREEMP;
- if (copy)
- flags |= TI_COPY;
- if (scms)
- flags |= TI_SCMS;
- }
- if (pad || ((flags & TI_AUDIO) == 0 && padsize > (Llong)0L)) {
- flags |= TI_PAD;
- if ((flags & TI_AUDIO) == 0 && padsize == (Llong)0L)
- padsize = (Llong)PAD_SIZE;
- }
- if (shorttrack && (*flagsp & (F_SAO|F_RAW)) != 0)
- flags |= TI_SHORT_TRACK;
- if (noshorttrack)
- flags &= ~TI_SHORT_TRACK;
- if (bswab)
- flags |= TI_SWAB;
- if (ispacket) {
- flags |= TI_PACKET;
- trackp[0].flags &= ~TI_TAO;
- }
- if (noclose)
- flags |= TI_NOCLOSE;
- if (useinfo)
- flags |= TI_USEINFO;
-
- if (ga_ret == NOARGS) {
- /*
- * All options have already been parsed and no more
- * file type arguments are present.
- */
- break;
- }
- if (tracks == 0 && (wm == 0)) {
- errmsgno(EX_BAD, "No write mode specified.\n");
- errmsgno(EX_BAD, "Asuming -tao mode.\n");
- errmsgno(EX_BAD, "Future versions of wodim may have different drive dependent defaults.\n");
- tao = 1;
- }
- tracks++;
-
- if (tracks > MAX_TRACK)
- comerrno(EX_BAD, "Track limit (%d) exceeded\n",
- MAX_TRACK);
- /*
- * Make 'tracks' immediately usable in track structure.
- */
- { register int i;
- for (i = 0; i < MAX_TRACK+2; i++)
- trackp[i].tracks = tracks;
- }
-
- if (strcmp("-", cav[0]) == 0)
- *flagsp |= F_STDIN;
-
- if (!is_auname(cav[0]) && !is_wavname(cav[0]))
- flags |= TI_NOAUHDR;
-
- if ((*flagsp & (F_SAO|F_RAW)) != 0 && (flags & TI_AUDIO) != 0)
- flags |= TI_PREGAP; /* Hack for now */
- if (tracks == 1)
- flags &= ~TI_PREGAP;
-
- if (tracks == 1 && (pregapsize != -1L && pregapsize != 150))
- pregapsize = -1L;
- trackp[tracks].filename = cav[0];
- trackp[tracks].trackstart = 0L;
- trackp[tracks].itracksize = tracksize;
- trackp[tracks].tracksize = tracksize;
- trackp[tracks].tracksecs = -1L;
- if (tracksize >= 0)
- trackp[tracks].tracksecs = (tracksize+secsize-1)/secsize;
- if (trackp[tracks].pregapsize < 0)
- trackp[tracks].pregapsize = pregapsize;
- trackp[tracks+1].pregapsize = -1;
- trackp[tracks].padsecs = (padsize+2047)/2048;
- trackp[tracks].isecsize = secsize;
- trackp[tracks].secsize = secsize;
- trackp[tracks].flags = flags;
- /*
- * XXX Dies ist falsch: auch bei SAO/RAW kann
- * XXX secsize != isecsize sein.
- */
- if ((*flagsp & F_RAW) != 0) {
- if (is_raw16(&trackp[tracks]))
- trackp[tracks].secsize = RAW16_SEC_SIZE;
- else
- trackp[tracks].secsize = RAW96_SEC_SIZE;
-#ifndef HAVE_LIB_EDC_ECC
- if ((sectype & ST_MODE_MASK) != ST_MODE_AUDIO) {
- errmsgno(EX_BAD,
- "EDC/ECC library not compiled in.\n");
- comerrno(EX_BAD,
- "Data sectors are not supported in RAW mode.\n");
- }
-#endif
- }
- trackp[tracks].secspt = 0; /* transfer size is set up in set_trsizes() */
- trackp[tracks].pktsize = pktsize;
- trackp[tracks].trackno = tracks;
- trackp[tracks].sectype = sectype;
-#ifdef CLONE_WRITE
- if ((*flagsp & F_CLONE) != 0) {
- trackp[tracks].isecsize = 2448;
- trackp[tracks].sectype |= ST_MODE_RAW;
- dataoff = 0;
- }
-#endif
- trackp[tracks].dataoff = dataoff;
- trackp[tracks].tracktype = tracktype;
- trackp[tracks].dbtype = dbtype;
- trackp[tracks].flags = flags;
- trackp[tracks].nindex = 1;
- trackp[tracks].tindex = 0;
- if (isrc) {
-#ifdef AUINFO
- setisrc(isrc, &trackp[tracks]);
-#else
- trackp[tracks].isrc = malloc(16);
- fillbytes(trackp[tracks].isrc, 16, '\0');
- strncpy(trackp[tracks].isrc, isrc, 12);
-#endif
- }
- if (tindex) {
-#ifdef AUINFO
- setindex(tindex, &trackp[tracks]);
-#endif
- }
- }
-
- if (dminbuf >= 0) {
- if (dminbuf < 25 || dminbuf > 95)
- comerrno(EX_BAD,
- "Bad minbuf=%d option (must be between 25 and 95)\n",
- dminbuf);
- }
-
- if (speed < 0 && speed != -1)
- comerrno(EX_BAD, "Bad speed option.\n");
-
- if (fs < 0L && fs != -1L)
- comerrno(EX_BAD, "Bad fifo size option.\n");
-
- if (bufsize < 0L && bufsize != -1L)
- comerrno(EX_BAD, "Bad transfer size option.\n");
- if (bufsize < 0L)
- bufsize = CDR_BUF_SIZE;
- if (bufsize > CDR_MAX_BUF_SIZE)
- bufsize = CDR_MAX_BUF_SIZE;
-
- dev = *devp;
- cdr_defaults(&dev, &speed, &fs, &driveropts);
- if (debug) {
- printf("dev: '%s' speed: %d fs: %ld driveropts '%s'\n",
- dev, speed, fs, driveropts);
- }
- if (speed >= 0)
- *speedp = speed;
-
- if (fs < 0L)
- fs = DEFAULT_FIFOSIZE;
- if (fs < 2*bufsize) {
- errmsgno(EX_BAD, "Fifo size %ld too small, turning fifo off.\n", fs);
- fs = 0L;
- }
-
- if (dev != *devp && (*flagsp & F_SCANBUS) == 0)
- *devp = dev;
-
- if (!*devp && (*flagsp & (F_VERSION|F_SCANBUS)) == 0) {
- errmsgno(EX_BAD, "No CD/DVD-Recorder device specified.\n");
- susage(EX_BAD);
- }
- if (*devp &&
- ((strncmp(*devp, "HELP", 4) == 0) ||
- (strncmp(*devp, "help", 4) == 0))) {
- *flagsp |= F_CHECKDRIVE; /* Set this for not calling mlockall() */
- return ispacket;
- }
- 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)) {
- if (tracks != 0) {
- errmsgno(EX_BAD, "No tracks allowed with this option\n");
- susage(EX_BAD);
- }
- return ispacket;
- }
- *tracksp = tracks;
- if (*flagsp & F_SAO) {
- /*
- * Make sure that you change WRITER_MAXWAIT & READER_MAXWAIT
- * too if you change this timeout.
- */
- if (*timeoutp < 200) /* Lead in size is 2:30 */
- *timeoutp = 200; /* 200s is 150s *1.33 */
- }
- if (usetext) {
- trackp[MAX_TRACK+1].flags |= TI_TEXT;
- }
- if (cuefile) {
-#ifdef FUTURE
- if ((*flagsp & F_SAO) == 0 &&
- (*flagsp & F_RAW) == 0) {
-#else
- if ((*flagsp & F_SAO) == 0) {
-#endif
- errmsgno(EX_BAD, "The cuefile= option only works with -dao.\n");
- susage(EX_BAD);
- }
- if (tracks > 0) {
- errmsgno(EX_BAD, "No tracks allowed with the cuefile= option\n");
- susage(EX_BAD);
- }
- cuefilename = cuefile;
- return ispacket;
- }
- if (tracks == 0 && (*flagsp & (F_LOAD|F_DLCK|F_EJECT|F_BLANK|F_FORMAT)) == 0) {
- errmsgno(EX_BAD, "No tracks specified. Need at least one.\n");
- susage(EX_BAD);
- }
- return ispacket;
-}
-
-static void
-set_trsizes(cdr_t *dp, int tracks, track_t *trackp)
-{
- int i;
- int secsize;
- int secspt;
-
- trackp[1].flags |= TI_FIRST;
- trackp[tracks].flags |= TI_LAST;
-
- if (xdebug)
- printf("Set Transfersizes start\n");
- for (i = 0; i <= tracks+1; i++) {
- if ((dp->cdr_flags & CDR_SWABAUDIO) != 0 &&
- is_audio(&trackp[i])) {
- trackp[i].flags ^= TI_SWAB;
- }
- if (!is_audio(&trackp[i]))
- trackp[i].flags &= ~TI_SWAB; /* Only swab audio */
-
- /*
- * Use the biggest sector size to compute how many
- * sectors may fit into one single DMA buffer.
- */
- secsize = trackp[i].secsize;
- if (trackp[i].isecsize > secsize)
- secsize = trackp[i].isecsize;
-
- /*
- * We are using SCSI Group 0 write
- * and cannot write more than 255 secs at once.
- */
- secspt = bufsize/secsize;
- secspt = min(255, secspt);
- trackp[i].secspt = secspt;
-
- if (is_packet(&trackp[i]) && trackp[i].pktsize > 0) {
- if (trackp[i].secspt >= trackp[i].pktsize) {
- trackp[i].secspt = trackp[i].pktsize;
- } else {
- comerrno(EX_BAD,
- "Track %d packet size %d exceeds buffer limit of %d sectors",
- i, trackp[i].pktsize, trackp[i].secspt);
- }
- }
- if (xdebug) {
- printf("Track %d flags %X secspt %d secsize: %d isecsize: %d\n",
- i, trackp[i].flags, trackp[i].secspt,
- trackp[i].secsize, trackp[i].isecsize);
- }
- }
- if (xdebug)
- printf("Set Transfersizes end\n");
-}
-
-void
-load_media(SCSI *scgp, cdr_t *dp, BOOL doexit)
-{
- int code;
- int key;
- BOOL immed = (dp->cdr_cmdflags&F_IMMED) != 0;
-
- /*
- * Do some preparation before...
- */
- scgp->silent++; /* Be quiet if this fails */
- test_unit_ready(scgp); /* First eat up unit attention */
- if ((*dp->cdr_load)(scgp, dp) < 0) { /* now try to load media and */
- if (!doexit)
- return;
- comerrno(EX_BAD, "Cannot load media.\n");
- }
- scsi_start_stop_unit(scgp, 1, 0, immed); /* start unit in silent mode */
- scgp->silent--;
-
- if (!wait_unit_ready(scgp, 60)) {
- code = scg_sense_code(scgp);
- key = scg_sense_key(scgp);
- scgp->silent++;
- scsi_prevent_removal(scgp, 0); /* In case someone locked it */
- scgp->silent--;
-
- if (!doexit)
- return;
- if (key == SC_NOT_READY && (code == 0x3A || code == 0x30))
- comerrno(EX_BAD, "No disk / Wrong disk!\n");
- comerrno(EX_BAD, "CD/DVD-Recorder not ready.\n");
- }
-
- scsi_prevent_removal(scgp, 1);
- scsi_start_stop_unit(scgp, 1, 0, immed);
- wait_unit_ready(scgp, 120);
- scgp->silent++;
- if(geteuid() == 0) /* EB: needed? Not allowed for non-root, that is sure. */
- rezero_unit(scgp); /* Is this needed? Not supported by some drvives */
- scgp->silent--;
- test_unit_ready(scgp);
- scsi_start_stop_unit(scgp, 1, 0, immed);
- wait_unit_ready(scgp, 120);
-}
-
-void
-unload_media(SCSI *scgp, cdr_t *dp, int flags)
-{
- scsi_prevent_removal(scgp, 0);
- if ((flags & F_EJECT) != 0) {
- if ((*dp->cdr_unload)(scgp, dp) < 0)
- errmsgno(EX_BAD, "Cannot eject media.\n");
- }
-}
-
-void
-reload_media(SCSI *scgp, cdr_t *dp)
-{
- char ans[2];
-#ifdef F_GETFL
- int f = -1;
-#endif
-
- errmsgno(EX_BAD, "Drive needs to reload the media to return to proper status.\n");
- unload_media(scgp, dp, F_EJECT);
-
- /*
- * Note that even Notebook drives identify as CDR_TRAYLOAD
- */
- if ((dp->cdr_flags & CDR_TRAYLOAD) != 0) {
- scgp->silent++;
- load_media(scgp, dp, FALSE);
- scgp->silent--;
- }
-
- scgp->silent++;
- if (((dp->cdr_flags & CDR_TRAYLOAD) == 0) ||
- !wait_unit_ready(scgp, 5)) {
- static FILE *tty = NULL;
-
- printf("Re-load disk and hit <CR>");
- if (isgui)
- printf("\n");
- flush();
-
- if (tty == NULL) {
- tty = stdin;
- if ((dp->cdr_cmdflags & F_STDIN) != 0)
- tty = fileluopen(STDERR_FILENO, "rw");
- }
-#ifdef F_GETFL
- if (tty != NULL)
- f = fcntl(fileno(tty), F_GETFL, 0);
- if (f < 0 || (f & O_ACCMODE) == O_WRONLY) {
-#ifdef SIGUSR1
- signal(SIGUSR1, catchsig);
- printf("Controlling file not open for reading, send SIGUSR1 to continue.\n");
- flush();
- pause();
-#endif
- } else
-#endif
- if (fgetline(tty, ans, 1) < 0)
- comerrno(EX_BAD, "Aborted by EOF on input.\n");
- }
- scgp->silent--;
-
- load_media(scgp, dp, TRUE);
-}
-
-void
-set_secsize(SCSI *scgp, int secsize)
-{
- if (secsize > 0) {
- /*
- * Try to restore the old sector size.
- */
- scgp->silent++;
- select_secsize(scgp, secsize);
- scgp->silent--;
- }
-}
-
-static int
-get_dmaspeed(SCSI *scgp, cdr_t *dp)
-{
- int i;
- long t;
- int bs;
- int tsize;
-
- if(getenv("CDR_NODMATEST"))
- return -1;
-
- if (debug || lverbose)
- fprintf( stderr,
- "Beginning DMA speed test. Set CDR_NODMATEST environment variable if device\n"
- "communication breaks or freezes immediately after that.\n" );
-
- fillbytes((caddr_t)buf, 4, '\0');
- tsize = 0;
- scgp->silent++;
- i = read_buffer(scgp, buf, 4, 0);
- scgp->silent--;
- if (i < 0)
- return (-1);
- tsize = a_to_u_4_byte(buf);
- if (tsize <= 0)
- return (-1);
-
- if (gettimeofday(&starttime, (struct timezone *)0) < 0)
- return (-1);
-
- bs = bufsize;
- if (tsize < bs)
- bs = tsize;
- for (i = 0; i < 100; i++) {
- if (read_buffer(scgp, buf, bs, 0) < 0)
- return (-1);
- }
- if (gettimeofday(&fixtime, (struct timezone *)0) < 0) {
- errmsg("Cannot get DMA stop time\n");
- return (-1);
- }
- timevaldiff(&starttime, &fixtime);
- tsize = bs * 100;
- t = fixtime.tv_sec * 1000 + fixtime.tv_usec / 1000;
- if (t <= 0)
- return (-1);
-#ifdef DEBUG
- fprintf(stderr, "Read Speed: %lu %ld %ld kB/s %ldx CD %ldx DVD\n",
- tsize, t, tsize/t, tsize/t/176, tsize/t/1385);
-#endif
-
- return (tsize/t);
-}
-
-
-static BOOL
-do_opc(SCSI *scgp, cdr_t *dp, int flags)
-{
- if ((flags & F_DUMMY) == 0 && dp->cdr_opc) {
- if (debug || lverbose) {
- printf("Performing OPC...\n");
- flush();
- }
- if (dp->cdr_opc(scgp, NULL, 0, TRUE) < 0) {
- errmsgno(EX_BAD, "OPC failed.\n");
- if ((flags & F_FORCE) == 0)
- return (FALSE);
- }
- }
- return (TRUE);
-}
-
-static void
-check_recovery(SCSI *scgp, cdr_t *dp, int flags)
-{
- if ((*dp->cdr_check_recovery)(scgp, dp)) {
- errmsgno(EX_BAD, "Recovery needed.\n");
- unload_media(scgp, dp, flags);
- comexit(EX_BAD);
- }
-}
-
-#ifndef DEBUG
-#define DEBUG
-#endif
-void
-audioread(SCSI *scgp, cdr_t *dp, int flags)
-{
-#ifdef DEBUG
- int speed = 1;
- int oflags = dp->cdr_cmdflags;
-
- dp->cdr_cmdflags &= ~F_DUMMY;
- if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0)
- comexit(-1);
- dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
- dp->cdr_cmdflags = oflags;
-
- if ((*dp->cdr_set_secsize)(scgp, 2352) < 0)
- comexit(-1);
- scgp->cap->c_bsize = 2352;
-
- read_scsi(scgp, buf, 1000, 1);
- printf("XXX:\n");
- write(1, buf, 512);
- unload_media(scgp, dp, flags);
- comexit(0);
-#endif
-}
-
-static void
-print_msinfo(SCSI *scgp, cdr_t *dp)
-{
- long off;
- long fa;
-
- if ((*dp->cdr_session_offset)(scgp, &off) < 0) {
- errmsgno(EX_BAD, "Cannot read session offset\n");
- return;
- }
- if (lverbose)
- printf("session offset: %ld\n", off);
-
- if (dp->cdr_next_wr_address(scgp, (track_t *)0, &fa) < 0) {
- errmsgno(EX_BAD, "Cannot read first writable address\n");
- return;
- }
- printf("%ld,%ld\n", off, fa);
-}
-
-static void
-print_toc(SCSI *scgp, cdr_t *dp)
-{
- int first;
- int last;
- long lba;
- long xlba;
- struct msf msf;
- int adr;
- int control;
- int mode;
- int i;
-
- scgp->silent++;
- if (read_capacity(scgp) < 0) {
- scgp->silent--;
- errmsgno(EX_BAD, "Cannot read capacity\n");
- return;
- }
- scgp->silent--;
- if (read_tochdr(scgp, dp, &first, &last) < 0) {
- errmsgno(EX_BAD, "Cannot read TOC/PMA\n");
- return;
- }
- printf("first: %d last %d\n", first, last);
- for (i = first; i <= last; i++) {
- read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
- xlba = -150 +
- msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
- if (xlba == lba/4)
- lba = xlba;
- print_track(i, lba, &msf, adr, control, mode);
- }
- i = 0xAA;
- read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
- xlba = -150 +
- msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
- if (xlba == lba/4)
- lba = xlba;
- print_track(i, lba, &msf, adr, control, mode);
- if (lverbose > 1) {
- scgp->silent++;
- if (read_cdtext(scgp) < 0)
- errmsgno(EX_BAD, "No CD-Text or CD-Text unaware drive.\n");
- scgp->silent++;
- }
-}
-
-static void
-print_track(int track, long lba, struct msf *msp, int adr,
- int control, int mode)
-{
- long lba_512 = lba*4;
-
- if (track == 0xAA)
- printf("track:lout ");
- else
- printf("track: %3d ", track);
-
- printf("lba: %9ld (%9ld) %02d:%02d:%02d adr: %X control: %X mode: %d\n",
- lba, lba_512,
- msp->msf_min,
- msp->msf_sec,
- msp->msf_frame,
- adr, control, mode);
-}
-
-#ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */
-
-#include <sys/procset.h> /* Needed for SCO Openserver */
-#include <sys/priocntl.h>
-#include <sys/rtpriocntl.h>
-
-void
-raisepri(int pri)
-{
- int pid;
- int classes;
- int ret;
- pcinfo_t info;
- pcparms_t param;
- rtinfo_t rtinfo;
- rtparms_t rtparam;
-
- pid = getpid();
-
- /* get info */
- strcpy(info.pc_clname, "RT");
- classes = priocntl(P_PID, pid, PC_GETCID, (void *)&info);
- if (classes == -1)
- comerr("Cannot get priority class id priocntl(PC_GETCID)\n");
-
- movebytes(info.pc_clinfo, &rtinfo, sizeof (rtinfo_t));
-
- /* set priority to max */
- rtparam.rt_pri = rtinfo.rt_maxpri - pri;
- rtparam.rt_tqsecs = 0;
- rtparam.rt_tqnsecs = RT_TQDEF;
- param.pc_cid = info.pc_cid;
- movebytes(&rtparam, param.pc_clparms, sizeof (rtparms_t));
- ret = priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m);
- if (ret == -1) {
- errmsg("WARNING: Cannot set priority class parameters priocntl(PC_SETPARMS)\n");
- errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
- }
-}
-
-#else /* HAVE_SYS_PRIOCNTL_H */
-
-#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0
-/*
- * The second best choice: POSIX real time scheduling.
- */
-/*
- * XXX Ugly but needed because of a typo in /usr/iclude/sched.h on Linux.
- * XXX This should be removed as soon as we are sure that Linux-2.0.29 is gone.
- */
-#ifdef __linux
-#define _P __P
-#endif
-
-#include <sched.h>
-
-#ifdef __linux
-#undef _P
-#endif
-
-static int
-rt_raisepri(int pri)
-{
- struct sched_param scp;
-
- /*
- * Verify that scheduling is available
- */
-#ifdef _SC_PRIORITY_SCHEDULING
- if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) {
- errmsg("WARNING: RR-scheduler not available, disabling.\n");
- return (-1);
- }
-#endif
- fillbytes(&scp, sizeof (scp), '\0');
- scp.sched_priority = sched_get_priority_max(SCHED_RR) - pri;
- if (sched_setscheduler(0, SCHED_RR, &scp) < 0) {
- errmsg("WARNING: Cannot set RR-scheduler\n");
- return (-1);
- }
- return (0);
-}
-
-#else /* _POSIX_PRIORITY_SCHEDULING */
-
-#ifdef __CYGWIN32__
-/*
- * Win32 specific priority settings.
- */
-/*
- * NOTE: Base.h from Cygwin-B20 has a second typedef for BOOL.
- * We define BOOL to make all static code use BOOL
- * from Windows.h and use the hidden __SBOOL for
- * our global interfaces.
- *
- * NOTE: windows.h from Cygwin-1.x includes a structure field named sample,
- * so me may not define our own 'sample' or need to #undef it now.
- * With a few nasty exceptions, Microsoft assumes that any global
- * defines or identifiers will begin with an Uppercase letter, so
- * there may be more of these problems in the future.
- *
- * NOTE: windows.h defines interface as an alias for struct, this
- * is used by COM/OLE2, I guess it is class on C++
- * We man need to #undef 'interface'
- */
-#define BOOL WBOOL /* This is the Win BOOL */
-#define format __format /* Avoid format parameter hides global ... */
-#include <windows.h>
-#undef format
-#undef interface
-
-static int
-rt_raisepri(int pri)
-{
- int prios[] = {THREAD_PRIORITY_TIME_CRITICAL, THREAD_PRIORITY_HIGHEST};
-
- /* set priority class */
- if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) {
- errmsgno(EX_BAD, "No realtime priority class possible.\n");
- return (-1);
- }
-
- /* set thread priority */
- if (pri >= 0 && pri <= 1 && SetThreadPriority(GetCurrentThread(), prios[pri]) == FALSE) {
- errmsgno(EX_BAD, "Could not set realtime priority.\n");
- return (-1);
- }
- return (0);
-}
-
-#else
-/*
- * This OS does not support real time scheduling.
- */
-static int
-rt_raisepri(int pri)
-{
- return (-1);
-}
-
-#endif /* __CYGWIN32__ */
-
-#endif /* _POSIX_PRIORITY_SCHEDULING */
-
-void
-raisepri(int pri)
-{
- if (rt_raisepri(pri) >= 0)
- return;
-#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
-
- if (setpriority(PRIO_PROCESS, getpid(), -20 + pri) < 0) {
- errmsg("WARNING: Cannot set priority using setpriority().\n");
- errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
- }
-#else
-#ifdef HAVE_DOSSETPRIORITY /* RT priority on OS/2 */
- /*
- * Set priority to timecritical 31 - pri (arg)
- */
- DosSetPriority(0, 3, 31, 0);
- DosSetPriority(0, 3, -pri, 0);
-#else
-#if defined(HAVE_NICE) && !defined(__DJGPP__) /* DOS has nice but no multitasking */
- if (nice(-20 + pri) == -1) {
- errmsg("WARNING: Cannot set priority using nice().\n");
- errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
- }
-#else
- errmsgno(EX_BAD, "WARNING: Cannot set priority on this OS.\n");
- errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
-#endif
-#endif
-#endif
-}
-
-#endif /* HAVE_SYS_PRIOCNTL_H */
-
-#ifdef HAVE_SELECT
-/*
- * sys/types.h and sys/time.h are already included.
- */
-#else
-# include <stropts.h>
-# include <poll.h>
-
-#ifndef INFTIM
-#define INFTIM (-1)
-#endif
-#endif
-
-#if defined(HAVE_SELECT) && defined(NEED_SYS_SELECT_H)
-#include <sys/select.h>
-#endif
-#if defined(HAVE_SELECT) && defined(NEED_SYS_SOCKET_H)
-#include <sys/socket.h>
-#endif
-
-static void
-wait_input()
-{
-#ifdef HAVE_SELECT
- fd_set in;
-
- FD_ZERO(&in);
- FD_SET(STDIN_FILENO, &in);
- select(1, &in, NULL, NULL, 0);
-#else
- struct pollfd pfd;
-
- pfd.fd = STDIN_FILENO;
- pfd.events = POLLIN;
- pfd.revents = 0;
- poll(&pfd, (unsigned long)1, INFTIM);
-#endif
-}
-
-static void
-checkgui()
-{
- struct stat st;
-
- if (fstat(STDERR_FILENO, &st) >= 0 && !S_ISCHR(st.st_mode)) {
- isgui = TRUE;
- if (lverbose > 1)
- printf("Using remote (pipe) mode for interactive i/o.\n");
- }
-}
-
-static int
-getbltype(char *optstr, long *typep)
-{
- if (streql(optstr, "all")) {
- *typep = BLANK_DISC;
- } else if (streql(optstr, "disc")) {
- *typep = BLANK_DISC;
- } else if (streql(optstr, "disk")) {
- *typep = BLANK_DISC;
- } else if (streql(optstr, "fast")) {
- *typep = BLANK_MINIMAL;
- } else if (streql(optstr, "minimal")) {
- *typep = BLANK_MINIMAL;
- } else if (streql(optstr, "track")) {
- *typep = BLANK_TRACK;
- } else if (streql(optstr, "unreserve")) {
- *typep = BLANK_UNRESERVE;
- } else if (streql(optstr, "trtail")) {
- *typep = BLANK_TAIL;
- } else if (streql(optstr, "unclose")) {
- *typep = BLANK_UNCLOSE;
- } else if (streql(optstr, "session")) {
- *typep = BLANK_SESSION;
- } else if (streql(optstr, "help")) {
- blusage(0);
- } else {
- fprintf(stderr, "Illegal blanking type '%s'.\n", optstr);
- blusage(EX_BAD);
- return (-1);
- }
- return (TRUE);
-}
-
-static int
-getformattype(char *optstr, long *typep)
-{
- if (streql(optstr, "full")) {
- *typep = FULL_FORMAT;
- } else if (streql(optstr, "background")) {
- *typep = BACKGROUND_FORMAT;
- } else if (streql(optstr, "force")) {
- *typep = FORCE_FORMAT;
- } else if (streql(optstr, "help")) {
- formattypeusage(0);
- } else {
- fprintf(stderr, "Illegal blanking type '%s'.\n", optstr);
- formattypeusage(EX_BAD);
- return (-1);
- }
- return (TRUE);
-}
-static void
-print_drflags(cdr_t *dp)
-{
- printf("Driver flags : ");
-
- if ((dp->cdr_flags & CDR_DVD) != 0)
- printf("DVD ");
-
- if ((dp->cdr_flags & CDR_MMC3) != 0)
- printf("MMC-3 ");
- else if ((dp->cdr_flags & CDR_MMC2) != 0)
- printf("MMC-2 ");
- else if ((dp->cdr_flags & CDR_MMC) != 0)
- printf("MMC ");
-
- if ((dp->cdr_flags & CDR_SWABAUDIO) != 0)
- printf("SWABAUDIO ");
- if ((dp->cdr_flags & CDR_BURNFREE) != 0)
- printf("BURNFREE ");
- if ((dp->cdr_flags & CDR_VARIREC) != 0)
- printf("VARIREC ");
- if ((dp->cdr_flags & CDR_GIGAREC) != 0)
- printf("GIGAREC ");
- if ((dp->cdr_flags & CDR_AUDIOMASTER) != 0)
- printf("AUDIOMASTER ");
- if ((dp->cdr_flags & CDR_FORCESPEED) != 0)
- printf("FORCESPEED ");
- if ((dp->cdr_flags & CDR_SPEEDREAD) != 0)
- printf("SPEEDREAD ");
- if ((dp->cdr_flags & CDR_DISKTATTOO) != 0)
- printf("DISKTATTOO ");
- if ((dp->cdr_flags & CDR_SINGLESESS) != 0)
- printf("SINGLESESSION ");
- if ((dp->cdr_flags & CDR_HIDE_CDR) != 0)
- printf("HIDECDR ");
- printf("\n");
-}
-
-static void
-print_wrmodes(cdr_t *dp)
-{
- BOOL needblank = FALSE;
-
- printf("Supported modes: ");
- if ((dp->cdr_flags & CDR_TAO) != 0) {
- printf("TAO");
- needblank = TRUE;
- }
- if ((dp->cdr_flags & CDR_PACKET) != 0) {
- printf("%sPACKET", needblank?" ":"");
- needblank = TRUE;
- }
- if ((dp->cdr_flags & CDR_SAO) != 0) {
- printf("%sSAO", needblank?" ":"");
- needblank = TRUE;
- }
-#ifdef __needed__
- if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW16)) == (CDR_SAO|CDR_SRAW16)) {
- printf("%sSAO/R16", needblank?" ":"");
- needblank = TRUE;
- }
-#endif
- if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96P)) == (CDR_SAO|CDR_SRAW96P)) {
- printf("%sSAO/R96P", needblank?" ":"");
- needblank = TRUE;
- }
- if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96R)) == (CDR_SAO|CDR_SRAW96R)) {
- printf("%sSAO/R96R", needblank?" ":"");
- needblank = TRUE;
- }
- if ((dp->cdr_flags & (CDR_RAW|CDR_RAW16)) == (CDR_RAW|CDR_RAW16)) {
- printf("%sRAW/R16", needblank?" ":"");
- needblank = TRUE;
- }
- if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96P)) == (CDR_RAW|CDR_RAW96P)) {
- printf("%sRAW/R96P", needblank?" ":"");
- needblank = TRUE;
- }
- if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96R)) == (CDR_RAW|CDR_RAW96R)) {
- printf("%sRAW/R96R", needblank?" ":"");
- needblank = TRUE;
- }
- printf("\n");
-}
-
-static BOOL
-check_wrmode(cdr_t *dp, int wmode, int tflags)
-{
- int cdflags = dp->cdr_flags;
-
- if ((tflags & TI_PACKET) != 0 && (cdflags & CDR_PACKET) == 0) {
- errmsgno(EX_BAD, "Drive does not support PACKET recording.\n");
- return (FALSE);
- }
- if ((tflags & TI_TAO) != 0 && (cdflags & CDR_TAO) == 0) {
- errmsgno(EX_BAD, "Drive does not support TAO recording.\n");
- return (FALSE);
- }
- if ((wmode & F_SAO) != 0) {
- if ((cdflags & CDR_SAO) == 0) {
- errmsgno(EX_BAD, "Drive does not support SAO recording.\n");
- if ((cdflags & CDR_RAW) != 0)
- errmsgno(EX_BAD, "Try -raw option.\n");
- return (FALSE);
- }
-#ifdef __needed__
- if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_SRAW16) == 0) {
- errmsgno(EX_BAD, "Drive does not support SAO/RAW16.\n");
- goto badsecs;
- }
-#endif
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_SRAW96P) == 0) {
- errmsgno(EX_BAD, "Drive does not support SAO/RAW96P.\n");
- goto badsecs;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_SRAW96R) == 0) {
- errmsgno(EX_BAD, "Drive does not support SAO/RAW96R.\n");
- goto badsecs;
- }
- }
- if ((wmode & F_RAW) != 0) {
- if ((cdflags & CDR_RAW) == 0) {
- errmsgno(EX_BAD, "Drive does not support RAW recording.\n");
- return (FALSE);
- }
- if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_RAW16) == 0) {
- errmsgno(EX_BAD, "Drive does not support RAW/RAW16.\n");
- goto badsecs;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_RAW96P) == 0) {
- errmsgno(EX_BAD, "Drive does not support RAW/RAW96P.\n");
- goto badsecs;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_RAW96R) == 0) {
- errmsgno(EX_BAD, "Drive does not support RAW/RAW96R.\n");
- goto badsecs;
- }
- }
- return (TRUE);
-
-badsecs:
- if ((wmode & F_SAO) != 0)
- cdflags &= ~(CDR_RAW16|CDR_RAW96P|CDR_RAW96R);
- if ((wmode & F_RAW) != 0)
- cdflags &= ~(CDR_SRAW96P|CDR_SRAW96R);
-
- if ((cdflags & (CDR_SRAW96R|CDR_RAW96R)) != 0)
- errmsgno(EX_BAD, "Try -raw96r option.\n");
- else if ((cdflags & (CDR_SRAW96P|CDR_RAW96P)) != 0)
- errmsgno(EX_BAD, "Try -raw96p option.\n");
- else if ((cdflags & CDR_RAW16) != 0)
- errmsgno(EX_BAD, "Try -raw16 option.\n");
- return (FALSE);
-}
-
-static void
-set_wrmode(cdr_t *dp, int wmode, int tflags)
-{
- dstat_t *dsp = dp->cdr_dstat;
-
- if ((tflags & TI_PACKET) != 0) {
- dsp->ds_wrmode = WM_PACKET;
- return;
- }
- if ((tflags & TI_TAO) != 0) {
- dsp->ds_wrmode = WM_TAO;
- return;
- }
- if ((wmode & F_SAO) != 0) {
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == 0) {
- dsp->ds_wrmode = WM_SAO;
- return;
- }
- if ((tflags & TI_RAW16) != 0) { /* Is this needed? */
- dsp->ds_wrmode = WM_SAO_RAW16;
- return;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) {
- dsp->ds_wrmode = WM_SAO_RAW96P;
- return;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) {
- dsp->ds_wrmode = WM_SAO_RAW96R;
- return;
- }
- }
- if ((wmode & F_RAW) != 0) {
- if ((tflags & TI_RAW16) != 0) {
- dsp->ds_wrmode = WM_RAW_RAW16;
- return;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) {
- dsp->ds_wrmode = WM_RAW_RAW96P;
- return;
- }
- if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) {
- dsp->ds_wrmode = WM_RAW_RAW96R;
- return;
- }
- }
- dsp->ds_wrmode = WM_NONE;
-}
-
-#if defined(linux) || defined(__linux) || defined(__linux__)
-#ifdef HAVE_UNAME
-#include <sys/utsname.h>
-#endif
-#endif
-
-#ifdef __linux__
-static int
-get_cap(cap_value_t cap_array)
-{
- int ret;
- cap_t capa;
- capa = cap_get_proc();
- cap_set_flag(capa, CAP_EFFECTIVE, 1, &cap_array, CAP_SET);
- ret = cap_set_proc(capa);
- cap_free(capa);
- return ret;
-}
-#endif
Deleted: cdrkit/trunk/cdrecord/cdrecord.h
===================================================================
--- cdrkit/trunk/cdrecord/cdrecord.h 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/cdrecord.h 2006-11-21 18:34:28 UTC (rev 415)
@@ -1,1211 +0,0 @@
-/*
- * This file has been modified for the cdrkit suite.
- *
- * The behaviour and appearence of the program code below can differ to a major
- * extent from the version distributed by the original author(s).
- *
- * For details, see Changelog file distributed with the cdrkit package. If you
- * received this file from another source then ask the distributing person for
- * a log of modifications.
- *
- */
-
-/* @(#)cdrecord.h 1.165 05/06/11 Copyright 1995-2005 J. Schilling */
-/*
- * Definitions for cdrecord
- *
- * Copyright (c) 1995-2005 J. Schilling
- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; see the file COPYING. If not, write to the Free Software
- * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- * Make sure it is there. We need it for off_t.
- */
-#ifndef _INCL_SYS_TYPES_H
-#include <sys/types.h>
-#define _INCL_SYS_TYPES_H
-#endif
-
-#ifndef _UTYPES_H
-#include <utypes.h>
-#endif
-
-/*
- * Defines for command line option flags
- */
-#define F_DUMMY 0x00000001L /* Do dummy (simulation) writes */
-#define F_TOC 0x00000002L /* Get TOC */
-#define F_EJECT 0x00000004L /* Eject disk after doing the work */
-#define F_LOAD 0x00000008L /* Load disk only */
-#define F_MULTI 0x00000010L /* Create linkable TOC/multi-session */
-#define F_MSINFO 0x00000020L /* Get multi-session info */
-#define F_FIX 0x00000040L /* Fixate disk only */
-#define F_NOFIX 0x00000080L /* Do not fixate disk */
-#define F_VERSION 0x00000100L /* Print version info */
-#define F_CHECKDRIVE 0x00000200L /* Check for driver */
-#define F_INQUIRY 0x00000400L /* Do inquiry */
-#define F_PRCAP 0x00000800L /* Print capabilities */
-#define F_SCANBUS 0x00001000L /* Scan SCSI Bus */
-#define F_RESET 0x00002000L /* Reset SCSI Bus */
-#define F_BLANK 0x00004000L /* Blank CD-RW */
-#define F_PRATIP 0x00008000L /* Print ATIP info */
-#define F_PRDINFO 0x00010000L /* Print disk info (XXX not yet used) */
-#define F_IGNSIZE 0x00020000L /* Ignore disk size */
-#define F_SAO 0x00040000L /* Session at once */
-#define F_RAW 0x00080000L /* Raw mode */
-#define F_WRITE 0x00100000L /* Disk is going to be written */
-#define F_FORCE 0x00200000L /* Force things (e.g. blank on dead disk) */
-#define F_WAITI 0x00400000L /* Wait until data is available on stdin */
-#define F_OVERBURN 0x00800000L /* Allow oveburning */
-#define F_CLONE 0x01000000L /* Do clone writing */
-#define F_STDIN 0x02000000L /* We are using stdin as CD data */
-#define F_IMMED 0x04000000L /* Try tu use IMMED SCSI flag if possible */
-#define F_DLCK 0x08000000L /* Load disk and lock door */
-#define F_SETDROPTS 0x10000000L /* Set driver opts and exit */
-#define F_FORMAT 0x20000000L /* Format media */
-#define F_ABORT 0x40000000L /* Send abort sequence to drive */
-
-#ifdef min
-#undef min
-#endif
-#define min(a, b) ((a) < (b) ? (a):(b))
-
-#ifdef max
-#undef max
-#endif
-#define max(a, b) ((a) < (b) ? (b):(a))
-
-#undef roundup
-#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-
-/*
- * NOTICE: You should not make CDR_BUF_SIZE more than
- * the buffer size of the CD-Recorder.
- *
- * The Philips CDD 521 is the recorder with the smallest buffer.
- * It only has 256kB of buffer RAM.
- *
- * WARNING: Philips CDD 521 dies if CDR_BUF_SIZE is to big.
- * If you like to support the CDD 521 keep the buffer
- * at 63kB.
- */
-/*#define CDR_BUF_SIZE (126*1024)*/
-#define CDR_BUF_SIZE (63*1024)
-#define CDR_MAX_BUF_SIZE (256*1024)
-
-/*
- * Never set MIN_GRACE_TIME < 3 seconds. We need to give
- * the volume management a chance to settle before we
- * start writing.
- */
-#ifndef MIN_GRACE_TIME
-#define MIN_GRACE_TIME 0 /* changed to 0, there is no point in forcing it in this application. Fix your volume management if it breaks because it could not read the medium. */
-#endif
-#ifndef GRACE_TIME
-#define GRACE_TIME 9 /* 9 seconds */
-#endif
-
-/*
- * Some sector sizes used for reading/writing ...
- */
-#define DATA_SEC_SIZE 2048 /* 2048 bytes */
-#define MODE2_SEC_SIZE 2336 /* 2336 bytes */
-#define AUDIO_SEC_SIZE 2352 /* 2352 bytes */
-#define RAW16_SEC_SIZE (2352+16) /* 2368 bytes */
-#define RAW96_SEC_SIZE (2352+96) /* 2448 bytes */
-
-#define MAX_TRACK 99 /* Red Book track limit */
-
-#define PAD_SECS 15 /* NOTE: pad must be less than BUF_SIZE */
-#define PAD_SIZE (PAD_SECS * DATA_SEC_SIZE)
-
-/*
- * FIFO size must be at least 2x CDR_MAX_BUF_SIZE
- */
-#define DEFAULT_FIFOSIZE (4L*1024L*1024L)
-
-#if !defined(HAVE_LARGEFILES) && SIZEOF_LLONG > SIZEOF_LONG
-typedef Llong tsize_t;
-#else
-typedef off_t tsize_t;
-#endif
-
-#ifdef nono
-typedef struct tindex {
- int dummy; /* Not yet implemented */
-} tindex_t;
-#endif
-
-typedef struct ofile {
- struct ofile *next; /* Next open file */
- int f; /* Open file */
- char *filename; /* File name */
- int refcnt; /* open reference count */
-} ofile_t;
-
-typedef struct track {
- void *xfp; /* Open file for this track from xopen()*/
- char *filename; /* File name for this track */
-
- tsize_t itracksize; /* Size of track bytes (-1 == until EOF)*/
- /* This is in units of isecsize */
- tsize_t tracksize; /* Size of track bytes (-1 == until EOF)*/
- /* This is in units of secsize */
-
- long trackstart; /* Start sector # of this track */
- long tracksecs; /* Size of this track (sectors) */
- long padsecs; /* Pad size for this track (sectors) */
- long pregapsize; /* Pre-gap size for this track (sectors)*/
- long index0start; /* Index 0 start within this tr(sectors)*/
- int isecsize; /* Read input sector size for this track*/
- int secsize; /* Sector size for this track (bytes) */
- int secspt; /* # of sectors to copy for one transfer*/
- int pktsize; /* # of blocks per write packet */
- Uchar dataoff; /* offset of user data in raw sector */
- Uchar tracks; /* Number of tracks on this disk */
- Uchar track; /* Track # as offset in track[] array */
- Uchar trackno; /* Track # on disk for this track */
- Uchar tracktype; /* Track type (toc type) */
- Uchar dbtype; /* Data block type for this track */
- int sectype; /* Sector type */
- int flags; /* Flags (see below) */
- int nindex; /* Number of indices for track */
- long *tindex; /* Track index descriptor */
- char *isrc; /* ISRC code for this track / disk MCN */
- void *text; /* Opaque CD-Text data (txtptr_t *) */
-} track_t;
-
-#define track_base(tp) ((tp) - (tp)->track)
-
-/*
- * Defines for tp->flags
- */
-#define TI_AUDIO 0x00001 /* File is an audio track */
-#define TI_PREEMP 0x00002 /* Audio track recorded w/preemphasis */
-#define TI_MIX 0x00004 /* This is a mixed mode track */
-#define TI_RAW 0x00008 /* Write this track in raw mode */
-#define TI_PAD 0x00010 /* Pad data track */
-#define TI_SWAB 0x00020 /* Swab audio data */
-#define TI_ISOSIZE 0x00040 /* Use iso size for track */
-#define TI_NOAUHDR 0x00080 /* Don't look for audio header */
-#define TI_FIRST 0x00100 /* This is the first track */
-#define TI_LAST 0x00200 /* This is the last track */
-#define TI_PACKET 0x00400 /* Fixed- or variable-packet track */
-#define TI_NOCLOSE 0x00800 /* Don't close the track after writing */
-#define TI_TAO 0x01000 /* This track is written in TAO mode */
-#define TI_PREGAP 0x02000 /* Prev. track incl. pregap of this tr. */
-#define TI_SCMS 0x04000 /* Force to follow the SCMS rules */
-#define TI_COPY 0x08000 /* Allow digital copy */
-#define TI_SHORT_TRACK 0x10000 /* Ignore min 4 second Red Book std. */
-#define TI_RAW16 0x20000 /* This track uses 16 bytes subch. */
-#define TI_RAW96R 0x40000 /* This track uses 96 bytes RAW subch. */
-#define TI_CLONE 0x80000 /* Special clone treatment needed */
-#define TI_TEXT 0x100000 /* This track holds CD-Text information */
-#define TI_DVD 0x200000 /* We are writing a DVD track */
-#define TI_SAO 0x400000 /* This track is written in SAO mode */
-#define TI_USEINFO 0x800000 /* Use information from *.inf files */
-#define TI_QUADRO 0x1000000 /* Four Channel Audio Data */
-
-
-#define is_audio(tp) (((tp)->flags & TI_AUDIO) != 0)
-#define is_preemp(tp) (((tp)->flags & TI_PREEMP) != 0)
-#define is_pad(tp) (((tp)->flags & TI_PAD) != 0)
-#define is_swab(tp) (((tp)->flags & TI_SWAB) != 0)
-#define is_first(tp) (((tp)->flags & TI_FIRST) != 0)
-#define is_last(tp) (((tp)->flags & TI_LAST) != 0)
-#define is_packet(tp) (((tp)->flags & TI_PACKET) != 0)
-#define is_noclose(tp) (((tp)->flags & TI_NOCLOSE) != 0)
-#define is_tao(tp) (((tp)->flags & TI_TAO) != 0)
-#define is_sao(tp) (((tp)->flags & TI_SAO) != 0)
-#define is_raw(tp) (((tp)->flags & TI_RAW) != 0)
-#define is_raw16(tp) (((tp)->flags & TI_RAW16) != 0)
-#define is_raw96(tp) (((tp)->flags & (TI_RAW|TI_RAW16)) == TI_RAW)
-#define is_raw96p(tp) (((tp)->flags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW)
-#define is_raw96r(tp) (((tp)->flags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R))
-#define is_pregap(tp) (((tp)->flags & TI_PREGAP) != 0)
-#define is_scms(tp) (((tp)->flags & TI_SCMS) != 0)
-#define is_copy(tp) (((tp)->flags & TI_COPY) != 0)
-#define is_shorttrk(tp) (((tp)->flags & TI_SHORT_TRACK) != 0)
-#define is_clone(tp) (((tp)->flags & TI_CLONE) != 0)
-#define is_text(tp) (((tp)->flags & TI_TEXT) != 0)
-#define is_quadro(tp) (((tp)->flags & TI_QUADRO) != 0)
-
-/*
- * Defines for toc type / track type
- */
-#define TOC_DA 0 /* CD-DA */
-#define TOC_ROM 1 /* CD-ROM */
-#define TOC_XA1 2 /* CD_ROM XA with first track in mode 1 */
-#define TOC_XA2 3 /* CD_ROM XA with first track in mode 2 */
-#define TOC_CDI 4 /* CDI */
-
-#define TOC_MASK 7 /* Mask needed for toctname[] */
-
-/*
- * Additional flags in toc type / trackp->tracktype
- * XXX TOCF_DUMMY istr schon in dp->cdr_cmdflags & F_DUMMY
- * XXX TOCF_MULTI istr schon in dp->cdr_cmdflags & F_MULTI
- */
-#define TOCF_DUMMY 0x10 /* Write in dummy (simulation) mode */
-#define TOCF_MULTI 0x20 /* Multisession (Open Next Programarea) */
-
-#define TOCF_MASK 0xF0 /* All possible flags in tracktype */
-
-extern char *toc2name[]; /* Convert toc type to name */
-extern int toc2sess[]; /* Convert toc type to session format */
-
-/*
- * Defines for sector type
- *
- * Mode is 2 bits
- * Aud is 1 bit
- *
- * Sector is: aud << 2 | mode
- */
-#define ST_ROM_MODE1 1 /* CD-ROM in mode 1 (vanilla cdrom) */
-#define ST_ROM_MODE2 2 /* CD-ROM in mode 2 */
-#define ST_AUDIO_NOPRE 4 /* CD-DA stereo without preemphasis */
-#define ST_AUDIO_PRE 5 /* CD-DA stereo with preemphasis */
-
-#define ST_PREEMPMASK 0x01 /* Mask for preemphasis bit */
-#define ST_AUDIOMASK 0x04 /* Mask for audio bit */
-#define ST_MODEMASK 0x03 /* Mask for mode bits in sector type */
-#define ST_MASK 0x07 /* Mask needed for sectname[] */
-
-/*
- * There are 6 different generic basic sector types.
- */
-#define ST_MODE_AUDIO 0x00 /* Generic Audio mode */
-#define ST_MODE_0 0x10 /* Generic Zero mode */
-#define ST_MODE_1 0x20 /* Generic CD-ROM mode (ISO/IEC 10149) */
-#define ST_MODE_2 0x30 /* Generic Mode 2 (ISO/IEC 10149) */
-#define ST_MODE_2_FORM_1 0x40 /* Generic Mode 2 form 1 */
-#define ST_MODE_2_FORM_2 0x50 /* Generic Mode 2 form 2 */
-#define ST_MODE_2_MIXED 0x60 /* Generic Mode 2 mixed form (1/2) */
-
-#define ST_MODE_MASK 0x70 /* Mask needed to get generic sectype */
-
-#define ST_MODE_RAW 0x08 /* Do not touch EDC & subchannels */
-#define ST_NOSCRAMBLE 0x80 /* Do not srcamble sectors */
-
-#define SECT_AUDIO (ST_AUDIO_NOPRE | ST_MODE_AUDIO)
-#define SECT_AUDIO_NOPRE (ST_AUDIO_NOPRE | ST_MODE_AUDIO)
-#define SECT_AUDIO_PRE (ST_AUDIO_PRE | ST_MODE_AUDIO)
-#define SECT_MODE_0 (ST_ROM_MODE1 | ST_MODE_0)
-#define SECT_ROM (ST_ROM_MODE1 | ST_MODE_1)
-#define SECT_MODE_2 (ST_ROM_MODE2 | ST_MODE_2)
-#define SECT_MODE_2_F1 (ST_ROM_MODE2 | ST_MODE_2_FORM_1)
-#define SECT_MODE_2_F2 (ST_ROM_MODE2 | ST_MODE_2_FORM_2)
-#define SECT_MODE_2_MIX (ST_ROM_MODE2 | ST_MODE_2_MIXED)
-
-extern char *st2name[]; /* Convert sector type to name */
-extern int st2mode[]; /* Convert sector type to control nibble*/
-
-/*
- * Control nibble bits:
- *
- * 0 with preemphasis (audio) / incremental (data)
- * 1 digital copy permitted
- * 2 data (not audio) track
- * 3 4 channels (not 2)
- */
-#define TM_PREEM 0x1 /* Audio track with preemphasis */
-#define TM_INCREMENTAL 0x1 /* Incremental data track */
-#define TM_ALLOW_COPY 0x2 /* Digital copy permitted */
-#define TM_DATA 0x4 /* This is a data track */
-#define TM_QUADRO 0x8 /* Four channel audio */
-
-/*
- * Adr nibble:
- */
-#define ADR_NONE 0 /* Sub-Q mode info not supplied */
-#define ADR_POS 1 /* Sub-Q encodes position data */
-#define ADR_MCN 2 /* Sub-Q encodes Media Catalog Number */
-#define ADR_ISRC 3 /* Sub-Q encodes ISRC */
-
-/*
- * Defines for write type (from SCSI-3/mmc)
- */
-#define WT_PACKET 0x0 /* Packet writing */
-#define WT_TAO 0x1 /* Track at once */
-#define WT_SAO 0x2 /* Session at once */
-#define WT_RAW 0x3 /* Raw */
-#define WT_RES_4 0x4 /* Reserved */
-#define WT_RES_5 0x5 /* Reserved */
-#define WT_RES_6 0x6 /* Reserved */
-#define WT_RES_7 0x7 /* Reserved */
-#define WT_RES_8 0x8 /* Reserved */
-#define WT_RES_9 0x9 /* Reserved */
-#define WT_RES_A 0xA /* Reserved */
-#define WT_RES_B 0xB /* Reserved */
-#define WT_RES_C 0xC /* Reserved */
-#define WT_RES_D 0xD /* Reserved */
-#define WT_RES_E 0xE /* Reserved */
-#define WT_RES_F 0xF /* Reserved */
-
-/*
- * Data block layout:
- *
- * - Sync pattern 12 Bytes: 0x00 0xFF 0xFF ... 0xFF 0xFF 0x00
- * - Block header 4 Bytes: | minute | second | frame | mode |
- * Mode byte:
- * Bits 7, 6, 5 Run-in/Run-out/Link
- * Bits 4, 3, 2 Reserved
- * Bits 1, 0 Mode
- * - Rest of sector see below.
- *
- * Mode 0 Format:
- * 0 12 Bytes Sync header
- * 12 4 Bytes Block header with Data mode == 0
- * 16 2336 Bytes of zero data
- *
- * Mode 1 Format:
- * 0 12 Bytes Sync header
- * 12 4 Bytes Block header with Data mode == 1
- * 16 2048 Bytes of user data
- * 2064 4 Bytes CRC for Bytes 0-2063
- * 2068 8 Bytes Zero fill
- * 2076 172 Bytes P parity symbols
- * 2248 104 Bytes Q parity symbols
- *
- * Mode 2 Format (formless):
- * 0 12 Bytes Sync header
- * 12 4 Bytes Block header with Data mode == 2
- * 16 2336 Bytes of user data
- *
- * Mode 2 form 1 Format:
- * 0 12 Bytes Sync header
- * 12 4 Bytes Block header with Data mode == 2
- * 16 4 Bytes subheader first copy
- * 20 4 Bytes subheader second copy
- * 24 2048 Bytes of user data
- * 2072 4 Bytes CRC for Bytes 16-2071
- * 2076 172 Bytes P parity symbols
- * 2248 104 Bytes Q parity symbols
- *
- * Mode 2 form 2 Format:
- * 0 12 Bytes Sync header
- * 12 4 Bytes Block header with Data mode == 2
- * 16 4 Bytes subheader first copy
- * 20 4 Bytes subheader second copy
- * 24 2324 Bytes of user data
- * 2348 4 Bytes Optional CRC for Bytes 16-2347
- */
-
-/*
- * Mode Byte definitions (the 4th Byte in the Block header)
- */
-#define SH_MODE_DATA 0x00 /* User Data Block */
-#define SH_MODE_RI4 0x20 /* Fourth run in Block */
-#define SH_MODE_RI3 0x40 /* Third run in Block */
-#define SH_MODE_RI2 0x60 /* Second run in Block */
-#define SH_MODE_RI1 0x80 /* First run in Block */
-#define SH_MODE_LINK 0xA0 /* Link Block */
-#define SH_MODE_RO2 0xC0 /* Second run out Block */
-#define SH_MODE_RO1 0xE0 /* First run out Block */
-#define SH_MODE_M0 0x00 /* Mode 0 Data */
-#define SH_MODE_M1 0x01 /* Mode 1 Data */
-#define SH_MODE_M2 0x02 /* Mode 2 Data */
-#define SH_MODE_MR 0x03 /* Reserved */
-
-/*
- * Defines for data block type (from SCSI-3/mmc)
- *
- * Mandatory are only:
- * DB_ROM_MODE1 (8) Mode 1 (ISO/IEC 10149)
- * DB_XA_MODE2 (10) Mode 2-F1 (CD-ROM XA form 1)
- * DB_XA_MODE2_MIX (13) Mode 2-MIX (CD-ROM XA 1/2+subhdr)
- */
-#define DB_RAW 0 /* 2352 bytes of raw data */
-#define DB_RAW_PQ 1 /* 2368 bytes (raw data + P/Q Subchannel) */
-#define DB_RAW_PW 2 /* 2448 bytes (raw data + P-W Subchannel) */
-#define DB_RAW_PW_R 3 /* 2448 bytes (raw data + P-W raw Subchannel)*/
-#define DB_RES_4 4 /* - Reserved */
-#define DB_RES_5 5 /* - Reserved */
-#define DB_RES_6 6 /* - Reserved */
-#define DB_VU_7 7 /* - Vendor specific */
-#define DB_ROM_MODE1 8 /* 2048 bytes Mode 1 (ISO/IEC 10149) */
-#define DB_ROM_MODE2 9 /* 2336 bytes Mode 2 (ISO/IEC 10149) */
-#define DB_XA_MODE2 10 /* 2048 bytes Mode 2 (CD-ROM XA form 1) */
-#define DB_XA_MODE2_F1 11 /* 2056 bytes Mode 2 (CD-ROM XA form 1) */
-#define DB_XA_MODE2_F2 12 /* 2324 bytes Mode 2 (CD-ROM XA form 2) */
-#define DB_XA_MODE2_MIX 13 /* 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */
-#define DB_RES_14 14 /* - Reserved */
-#define DB_VU_15 15 /* - Vendor specific */
-
-extern char *db2name[]; /* Convert data block type to name */
-
-/*
- * Defines for multi session type (from SCSI-3/mmc)
- */
-#define MS_NONE 0 /* No B0 pointer. Next session not allowed*/
-#define MS_FINAL 1 /* B0 = FF:FF:FF. Next session not allowed*/
-#define MS_RES 2 /* Reserved */
-#define MS_MULTI 3 /* B0 = Next PA. Next session allowed */
-
-/*
- * Defines for session format (from SCSI-3/mmc)
- */
-#define SES_DA_ROM 0x00 /* CD-DA or CD-ROM disk */
-#define SES_CDI 0x10 /* CD-I disk */
-#define SES_XA 0x20 /* CD-ROM XA disk */
-#define SES_UNDEF 0xFF /* Undefined disk type (read disk info) */
-
-/*
- * Defines for blanking of CD-RW discs (from SCSI-3/mmc)
- */
-#define BLANK_DISC 0x00 /* Erase the entire disc */
-#define BLANK_MINIMAL 0x01 /* Erase the PMA, 1st session TOC, pregap */
-#define BLANK_TRACK 0x02 /* Erase an incomplete track */
-#define BLANK_UNRESERVE 0x03 /* Unreserve a track */
-#define BLANK_TAIL 0x04 /* Erase the tail of a track */
-#define BLANK_UNCLOSE 0x05 /* Unclose the last session */
-#define BLANK_SESSION 0x06 /* Erase the last session */
-
-/*
- * Defines for formating DVD (custom values)
- */
-#define FULL_FORMAT 0x00 /* Interactive format */
-#define BACKGROUND_FORMAT 0x01 /* Background format */
-#define FORCE_FORMAT 0x02 /* Force reformat */
-
-/*
- * Defines for formating DVD (custom values)
- */
-#define FULL_FORMAT 0x00 /* Interactive format */
-#define BACKGROUND_FORMAT 0x01 /* Background format */
-#define FORCE_FORMAT 0x02 /* Force reformat */
-
-/*
- * Useful definitions for audio tracks
- */
-#define msample (44100 * 2) /* one 16bit audio sample */
-#define ssample (msample * 2) /* one stereo sample */
-#define samples(v) ((v) / ssample) /* # of stereo samples */
-#define hsamples(v) ((v) / (ssample/100)) /* 100* # of stereo samples/s*/
-#define fsamples(v) ((v) / (ssample/75)) /* 75* # of stereo samples/s */
-
-#define minutes(v) ((int)(samples(v) / 60))
-#define seconds(v) ((int)(samples(v) % 60))
-#define hseconds(v) ((int)(hsamples(v) % 100))
-#define frames(v) ((int)(fsamples(v) % 75))
-
-/*
- * sector based macros
- */
-#define Sminutes(s) ((int)((s) / (60*75)))
-#define Sseconds(s) ((int)((s) / 75))
-#define Shseconds(s) ((int)(((s) % 75)*100)/75)
-#define Sframes(s) ((int)((s) % 75))
-
-typedef struct msf {
- char msf_min;
- char msf_sec;
- char msf_frame;
-} msf_t;
-
-/*
- * Definitions for read TOC/PMA/ATIP command
- */
-#define FMT_TOC 0
-#define FMT_SINFO 1
-#define FMT_FULLTOC 2
-#define FMT_PMA 3
-#define FMT_ATIP 4
-#define FMT_CDTEXT 5
-
-/*
- * Definitions for read disk information "recording flags"
- * used in UInt16_t "ds_cdrflags".
- */
-#define RF_WRITE 0x0001 /* Disk is going to be written */
-#define RF_BLANK 0x0002 /* Disk is going to be erased */
-#define RF_PRATIP 0x0004 /* Print ATIP info */
-#define RF_LEADIN 0x0008 /* Lead-in has been "manually" written */
-#define RF_BURNFREE 0x0010 /* BUFFER underrun free recording */
-#define RF_VARIREC 0x0020 /* Plextor VariRec */
-#define RF_AUDIOMASTER 0x0040 /* Yamaha AudioMaster */
-#define RF_FORCESPEED 0x0080 /* WriteSpeed forced high */
-#define RF_DID_STAT 0x0100 /* Already did call cdrstats() */
-#define RF_DID_CDRSTAT 0x0200 /* Already did call (*dp->cdr_stats)() */
-#define RF_WR_WAIT 0x0400 /* Wait during writing to free bus */
-#define RF_SINGLESESS 0x0800 /* Plextor single sess. mode */
-#define RF_HIDE_CDR 0x1000 /* Plextor hide CDR features */
-#define RF_SPEEDREAD 0x2000 /* Plextor SpeedReed */
-#define RF_GIGAREC 0x4000 /* Plextor GigaRec */
-
-/*
- * Definitions for read disk information "disk status"
- * used in "ds_diskstat".
- */
-#define DS_EMPTY 0 /* Empty disk */
-#define DS_APPENDABLE 1 /* Incomplete disk (appendable) */
-#define DS_COMPLETE 2 /* Complete disk (closed/no B0 pointer) */
-#define DS_RESERVED 3 /* Reserved */
-
-/*
- * Definitions for read disk information "session status"
- * used in "ds_sessstat".
- */
-#define SS_EMPTY 0 /* Empty session */
-#define SS_APPENDABLE 1 /* Incomplete session */
-#define SS_RESERVED 2 /* Reserved */
-#define SS_COMPLETE 3 /* Complete session (needs DS_COMPLETE) */
-
-/*
- * Definitions for disk_status write mode
- * used in "ds_wrmode".
- */
-#define WM_NONE 0 /* No write mode selected */
-#define WM_BLANK 1 /* Blanking mode */
-#define WM_FORMAT 2 /* Formatting */
-#define WM_PACKET 4 /* Packet writing */
-#define WM_TAO 8 /* Track at Once */
-#define WM_SAO 12 /* Session at Once w/ cooked sectors */
-#define WM_SAO_RAW16 13 /* Session at Once RAW+16 byte sectors */
-#define WM_SAO_RAW96P 14 /* Session at Once RAW+96P byte sectors */
-#define WM_SAO_RAW96R 15 /* Session at Once RAW+96R byte sectors */
-#define WM_RAW 16 /* RAW with cooked sectors is impossible*/
-#define WM_RAW_RAW16 17 /* RAW with RAW+16 byte sectors */
-#define WM_RAW_RAW96P 18 /* RAW with RAW+96P byte sectors */
-#define WM_RAW_RAW96R 19 /* RAW with RAW+96R byte sectors */
-
-#define wm_base(wm) ((wm)/4*4) /* The basic write mode for this mode */
-
-/*
- * Definitions for disk_status flags
- * used in UInt16_t "ds_flags".
- */
-#define DSF_DID_V 0x0001 /* Disk id valid */
-#define DSF_DBC_V 0x0002 /* Disk bar code valid */
-#define DSF_URU 0x0004 /* Disk is for unrestricted use */
-#define DSF_ERA 0x0008 /* Disk is erasable */
-#define DSF_HIGHSP_ERA 0x0010 /* Disk is high speed erasable */
-#define DSF_ULTRASP_ERA 0x0020 /* Disk is ultra speed erasable */
-#define DSF_ULTRASPP_ERA 0x0040 /* Disk is ultra speed+ erasable */
-
-
-#define DSF_DVD 0x0100 /* Disk is a DVD */
-#define DSF_DVD_PLUS_R 0x0200 /* Disk is a DVD+R */
-#define DSF_DVD_PLUS_RW 0x0400 /* Disk is a DVD+RW */
-#define DSF_NEED_FORMAT 0x0800 /* Disk needs to be formatted */
-
-/*
- * Definitions for disktype flags
- */
-#define DT_CD 0x001 /*is a CD */
-#define DT_DVD 0x002 /*is a DVD */
-
-/*
- * Definitions for disktype flags
- */
-#define DT_CD 0x001 /*is a CD */
-#define DT_DVD 0x002 /*is a DVD */
-
-/*
- * Definitions for disk_status disk type
- * used in "ds_type".
- */
-/* None defined yet */
-
-typedef struct disk_status dstat_t;
-
-struct disk_status {
- UInt32_t ds_diskid; /* Disk identification */
- UInt16_t ds_cdrflags; /* Recording flags from cdrecord*/
- UInt16_t ds_flags; /* Disk_status flags */
- Uchar ds_wrmode; /* Selected write mode */
- Uchar ds_type; /* Abstract disk type */
-
- Uchar ds_disktype; /* Disk type (from TOC/PMA) */
- Uchar ds_diskstat; /* Disk status (MMC) */
- Uchar ds_sessstat; /* Status of last sesion (MMC) */
- Uchar ds_trfirst; /* first track # */
- Uchar ds_trlast; /* last track # */
- Uchar ds_trfirst_ls; /* first track # in last session*/
- Uchar ds_barcode[8]; /* Disk bar code */
-
- Int32_t ds_first_leadin; /* Start of first lead in (ATIP)*/
- Int32_t ds_last_leadout; /* Start of last lead out (ATIP)*/
- Int32_t ds_curr_leadin; /* Start of next lead in */
- Int32_t ds_curr_leadout; /* Start of next lead out */
-
- Int32_t ds_maxblocks; /* # of official blocks on disk */
- Int32_t ds_maxrblocks; /* # real blocks on disk */
- Int32_t ds_fwa; /* first writable addr */
-
- Int32_t ds_startsec; /* Actual start sector */
- Int32_t ds_endsec; /* Actual end sector */
- Int32_t ds_buflow; /* # of times drive buffer empty*/
-
- UInt16_t ds_minbuf; /* Minimum drive bufer fill rt. */
-
- UInt16_t ds_at_min_speed; /* The minimal ATIP write speed */
- UInt16_t ds_at_max_speed; /* The maximal ATIP write speed */
- UInt16_t ds_dr_cur_rspeed; /* The drive's cur read speed */
- UInt16_t ds_dr_max_rspeed; /* The drive's max read speed */
- UInt16_t ds_dr_cur_wspeed; /* The drive's cur write speed */
- UInt16_t ds_dr_max_wspeed; /* The drive's max write speed */
- UInt16_t ds_wspeed; /* The selected/drive wr. speed */
-};
-
-/*
- * First approach of a CDR device abstraction layer.
- * This interface will change as long as I did not find the
- * optimum that fits for all devices.
- *
- * Called with pointer to whole track array:
- * cdr_send_cue()
- * cdr_write_leadin()
- * cdr_open_session()
- * cdr_fixate()
- *
- * Called with (track_t *) 0 or pointer to current track:
- * cdr_next_wr_address()
- *
- * Called with pointer to current track:
- * cdr_open_track()
- * cdr_close_track()
- *
- * Calling sequence:
- * cdr_identify() May modify driver
- * Here, the cdr_t will be allocated and
- * copied to a new writable area.
- * cdr_attach() Get drive properties
- * cdr_buffer_cap()
- * cdr_getdisktype() GET ATIP
- * cdr_init() set TAO for -msinfo
- * cdr_check_session XXX ????
- * cdr_opt1() set early options
- * cdr_set_speed_dummy(scgp, dp, &speed)
- * <--- Grace time processing goes here
- * { do_opc(); cdr_blank() }
- * cdr_opt2() set late options
- * cdr_open_session() set up params (no wrt.)
- * do_opc()
- * cdr_write_leadin() start writing
- * LOOP {
- * cdr_open_track()
- * cdr_next_wr_address() only TAO / Packet
- * write_track_data()
- * cdr_close_track()
- * }
- * write_leadout() XXX should go -> driver!
- * cdr_fixate()
- * cdr_stats()
- */
-/*--------------------------------------------------------------------------*/
-typedef struct cdr_cmd cdr_t;
-
-#ifdef _SCG_SCSITRANSP_H
-struct cdr_cmd {
- int cdr_dev; /* Numerical device type */
- UInt32_t cdr_cmdflags; /* Command line options */
- UInt32_t cdr_flags; /* Drive related flags */
- UInt8_t cdr_cdrw_support; /* CD-RW write media types */
- UInt16_t cdr_speeddef; /* Default write speed */
- UInt16_t cdr_speedmax; /* Max. write speed */
-
- char *cdr_drname; /* Driver ID string */
- char *cdr_drtext; /* Driver ID text */
- struct cd_mode_page_2A *cdr_cdcap;
- dstat_t *cdr_dstat;
-#ifdef _SCG_SCSIREG_H
- /* identify drive */
- cdr_t *(*cdr_identify)(SCSI *scgp, cdr_t *, struct scsi_inquiry *);
-#else
- /* identify drive */
- cdr_t *(*cdr_identify)(SCSI *scgp, cdr_t *, void *);
-#endif
- /* init error decoding etc*/
- int (*cdr_attach)(SCSI *scgp, cdr_t *);
- /* init drive to useful deflts */
- int (*cdr_init)(SCSI *scgp, cdr_t *);
- /* get disk type */
- int (*cdr_getdisktype)(SCSI *scgp, cdr_t *);
- /* load disk */
- int (*cdr_load)(SCSI *scgp, cdr_t *);
- /* unload disk */
- int (*cdr_unload)(SCSI *scgp, cdr_t *);
- /* read buffer capacity */
- int (*cdr_buffer_cap)(SCSI *scgp, long *sizep, long *freep);
- /* check if recover is needed */
- int (*cdr_check_recovery)(SCSI *scgp, cdr_t *);
- /* do recover */
- int (*cdr_recover)(SCSI *scgp, cdr_t *, int track);
- /* set recording speed & dummy write */
- int (*cdr_set_speed_dummy)(SCSI *scgp, cdr_t *, int *speedp);
- /* set sector size */
- int (*cdr_set_secsize)(SCSI *scgp, int secsize);
- /* get next writable addr. */
- int (*cdr_next_wr_address)(SCSI *scgp, track_t *trackp, long *ap);
- /* reserve track for future use */
- int (*cdr_reserve_track)(SCSI *scgp, Ulong len);
- int (*cdr_write_trackdata)(SCSI *scgp, caddr_t buf, long daddr, long bytecnt,
- int seccnt, BOOL islast);
- /* generate cue sheet */
- int (*cdr_gen_cue)(track_t *trackp, void *cuep, BOOL needgap);
- /* send cue sheet */
- int (*cdr_send_cue)(SCSI *scgp, cdr_t *, track_t *trackp);
- /* write leadin */
- int (*cdr_write_leadin)(SCSI *scgp, cdr_t *, track_t *trackp);
- /* open new track */
- int (*cdr_open_track)(SCSI *scgp, cdr_t *, track_t *trackp);
- /* close written track */
- int (*cdr_close_track)(SCSI *scgp, cdr_t *, track_t *trackp);
- /* open new session */
- int (*cdr_open_session)(SCSI *scgp, cdr_t *, track_t *trackp);
- /* really needed ??? */
- int (*cdr_close_session)(SCSI *scgp, cdr_t *);
- /* abort current write */
- int (*cdr_abort_session)(SCSI *scgp, cdr_t *);
- /* read session offset*/
- int (*cdr_session_offset)(SCSI *scgp, long *soff);
- /* write toc on disk */
- int (*cdr_fixate)(SCSI *scgp, cdr_t *, track_t *trackp);
- /* final statistics printing*/
- int (*cdr_stats)(SCSI *scgp, cdr_t *);
- /* blank something */
- int (*cdr_blank)(SCSI *scgp, cdr_t *, long addr, int blanktype);
- /* format media */
- int (*cdr_format)(SCSI *scgp, cdr_t *, int fmtflags);
- /* Do OPC */
- int (*cdr_opc)(SCSI *scgp, caddr_t bp, int cnt, int doopc);
- /* do early option processing*/
- int (*cdr_opt1)(SCSI *scgp, cdr_t *);
- /* do late option processing */
- int (*cdr_opt2)(SCSI *scgp, cdr_t *);
- /* calculate optimale split */
- int (*cdr_layer_split)(SCSI *scgp, cdr_t *, long tsize);
- int profile;
- BOOL is_dvd;
-};
-#endif
-
-/*
- * Definitions for cdr_flags
- */
-#define CDR_TAO 0x01 /* Drive supports Track at once */
-#define CDR_SAO 0x02 /* Drive supports Sess at once */
-#define CDR_PACKET 0x04 /* Drive supports packet writing*/
-#define CDR_RAW 0x08 /* Drive supports raw writing */
-#define CDR_RAW16 0x10 /* Drive supports RAW raw16 */
-#define CDR_RAW96P 0x20 /* Drive supports RAW raw96 pak */
-#define CDR_RAW96R 0x40 /* Drive supports RAW raw96 raw */
-#ifdef __needed__
-#define CDR_SRAW16 0x100 /* Drive supports SAO raw16 */
-#endif
-#define CDR_SRAW96P 0x200 /* Drive supports SAO raw96 pak */
-#define CDR_SRAW96R 0x400 /* Drive supports SAO raw96 raw */
-#define CDR_SWABAUDIO 0x1000 /* Drive swabs audio data */
-#define CDR_ISREADER 0x2000 /* Drive is s CD-ROM reader */
-#define CDR_TRAYLOAD 0x4000 /* Drive loads CD with tray */
-#define CDR_CADDYLOAD 0x8000 /* Drive loads CD with caddy */
-#define CDR_NO_LOLIMIT 0x10000 /* Drive ignores lead-out limit */
-#define CDR_DVD 0x20000 /* Drive is a DVD drive */
-#define CDR_SIMUL 0x40000 /* Drive is simulated */
-#define CDR_BURNFREE 0x80000 /* Drive sup. BUFund. free rec. */
-#define CDR_VARIREC 0x100000 /* Drive sup. VariRec Plex. */
-#define CDR_AUDIOMASTER 0x200000 /* Drive sup. AudioMaster Yamah.*/
-#define CDR_FORCESPEED 0x400000 /* Drive sup. WriteSpeed ctl. */
-#define CDR_DISKTATTOO 0x800000 /* Drive sup. Yamaha DiskT at 2 */
-#define CDR_SINGLESESS 0x1000000 /* Drive sup. single sess. mode */
-#define CDR_HIDE_CDR 0x2000000 /* Drive sup. hide CDR features */
-#define CDR_SPEEDREAD 0x4000000 /* Drive sup. SpeedReed */
-#define CDR_GIGAREC 0x8000000 /* Drive sup. GigaRec Plex. */
-#define CDR_MMC 0x10000000 /* Drive is MMC compliant */
-#define CDR_MMC2 0x20000000 /* Drive is MMC-2 compliant */
-#define CDR_MMC3 0x40000000 /* Drive is MMC-3 compliant */
-#ifdef PROTOTYPES
-#define CDR_ALLOC 0x80000000UL /* structure is allocated */
-#else
-#define CDR_ALLOC 0x80000000 /* structure is allocated */
-#endif
-
-/*
- * Definitions for cdr_cdrw_support
- */
-#define CDR_CDRW_NONE 0x00 /* CD-RW writing not supported */
-#define CDR_CDRW_MULTI 0x01 /* CD-RW multi speed supported */
-#define CDR_CDRW_HIGH 0x02 /* CD-RW high speed supported */
-#define CDR_CDRW_ULTRA 0x04 /* CD-RW ultra high speed supported */
-#define CDR_CDRW_ULTRAP 0x08 /* CD-RW ultra high speed+ supported */
-#define CDR_CDRW_ALL 0xFF /* All bits set: unknown - support all */
-
-/*
- * cdrecord.c
- */
-extern int read_buf(int f, char *bp, int size);
-extern int fill_buf(int f, track_t *trackp, long secno, char *bp, int size);
-extern int get_buf(int f, track_t *trackp, long secno, char **bpp, int size);
-#ifdef _SCG_SCSITRANSP_H
-extern int write_secs(SCSI *scgp, cdr_t *dp, char *bp, long startsec,
- int bytespt, int secspt, BOOL islast);
-extern int pad_track(SCSI *scgp, cdr_t *dp, track_t *trackp,
- long startsec, Llong amt,
- BOOL dolast, Llong *bytesp);
-extern void load_media(SCSI *scgp, cdr_t *, BOOL);
-extern void unload_media(SCSI *scgp, cdr_t *, int);
-extern void reload_media(SCSI *scgp, cdr_t *);
-#endif
-extern void raisepri(int);
-extern int getnum(char *arg, long *valp);
-
-/*
- * cd_misc.c
- */
-extern int from_bcd(int b);
-extern int to_bcd(int i);
-extern long msf_to_lba(int m, int s, int f, BOOL force_positive);
-extern BOOL lba_to_msf(long lba, msf_t *mp);
-extern void sec_to_msf(long sec, msf_t *mp);
-extern void print_min_atip(long li, long lo);
-
-/*
- * fifo.c
- */
-extern void init_fifo(long);
-extern BOOL init_faio(track_t *track, int);
-extern BOOL await_faio(void);
-extern void kill_faio(void);
-extern int wait_faio(void);
-extern int faio_read_buf(int f, char *bp, int size);
-extern int faio_get_buf(int f, char **bpp, int size);
-extern void fifo_stats(void);
-extern int fifo_percent(BOOL addone);
-
-/*
- * wm_session.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern int write_session_data(SCSI *scgp, cdr_t *dp, track_t *trackp);
-#endif
-
-/*
- * wm_track.c
- */
-#ifdef _SCG_SCSITRANSP_H
-/*extern int write_track_data __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));*/
-#endif
-
-/*
- * wm_packet.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern int write_packet_data(SCSI *scgp, cdr_t *dp, track_t *trackp);
-#endif
-
-/*
- * modes.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern BOOL get_mode_params(SCSI *scgp, int page, char *pagename,
- Uchar *modep, Uchar *cmodep,
- Uchar *dmodep, Uchar *smodep,
- int *lenp);
-extern BOOL set_mode_params(SCSI *scgp, char *pagename, Uchar *modep,
- int len, int save, int secsize);
-#endif
-
-/*
- * misc.c
- */
-#ifdef timerclear
-extern void timevaldiff(struct timeval *start, struct timeval *stop);
-extern void prtimediff(const char *fmt, struct timeval *start,
- struct timeval *stop);
-#endif
-
-/*
- * getnum.c
- */
-extern int getnum(char *arg, long *valp);
-extern int getllnum(char *arg, Llong *lvalp);
-
-/*
- * scsi_cdr.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern BOOL unit_ready(SCSI *scgp);
-extern BOOL wait_unit_ready(SCSI *scgp, int secs);
-extern BOOL scsi_in_progress(SCSI *scgp);
-extern BOOL cdr_underrun(SCSI *scgp);
-extern int test_unit_ready(SCSI *scgp);
-extern int rezero_unit(SCSI *scgp);
-extern int request_sense(SCSI *scgp);
-extern int request_sense_b(SCSI *scgp, caddr_t bp, int cnt);
-extern int inquiry(SCSI *scgp, caddr_t, int);
-extern int read_capacity(SCSI *scgp);
-#ifdef EOF /* stdio.h has been included */
-extern void print_capacity(SCSI *scgp, FILE *f);
-#endif
-extern int scsi_load_unload(SCSI *scgp, int);
-extern int scsi_prevent_removal(SCSI *scgp, int);
-extern int scsi_start_stop_unit(SCSI *scgp, int, int, BOOL immed);
-
-#define ROTCTL_CLV 0 /* CLV or PCAV */
-#define ROTCTL_CAV 1 /* True CAV */
-
-extern int scsi_set_speed(SCSI *scgp, int readspeed, int writespeed,
- int rotctl);
-extern int scsi_get_speed(SCSI *scgp, int *readspeedp, int *writespeedp);
-extern int qic02(SCSI *scgp, int);
-extern int write_xscsi(SCSI *scgp, caddr_t, long, long, int);
-extern int write_xg0(SCSI *scgp, caddr_t, long, long, int);
-extern int write_xg1(SCSI *scgp, caddr_t, long, long, int);
-extern int write_xg5(SCSI *scgp, caddr_t, long, long, int);
-extern int seek_scsi(SCSI *scgp, long addr);
-extern int seek_g0(SCSI *scgp, long addr);
-extern int seek_g1(SCSI *scgp, long addr);
-extern int scsi_flush_cache(SCSI *scgp, BOOL immed);
-extern int read_buffer(SCSI *scgp, caddr_t bp, int cnt, int mode);
-extern int write_buffer(SCSI *scgp, char *buffer, long length, int mode,
- int bufferid, long offset);
-extern int read_subchannel(SCSI *scgp, caddr_t bp, int track, int cnt,
- int msf, int subq, int fmt);
-extern int read_toc(SCSI *scgp, caddr_t, int, int, int, int);
-extern int read_toc_philips(SCSI *scgp, caddr_t, int, int, int, int);
-extern int read_header(SCSI *scgp, caddr_t, long, int, int);
-extern int read_disk_info(SCSI *scgp, caddr_t, int);
-
-#define TI_TYPE_LBA 0 /* Address is LBA */
-#define TI_TYPE_TRACK 1 /* Address: 0 -> TOC, xx -> Track xx, 0xFF -> Inv Track */
-#define TI_TYPE_SESS 2 /* Address is session # */
-extern int read_track_info(SCSI *scgp, caddr_t, int type, int addr, int cnt);
-extern int read_rzone_info(SCSI *scgp, caddr_t bp, int cnt);
-extern int reserve_tr_rzone(SCSI *scgp, long size);
-extern int read_dvd_structure(SCSI *scgp, caddr_t bp, int cnt, int addr,
- int layer, int fmt);
-extern int send_dvd_structure(SCSI *scgp, caddr_t bp, int cnt, int layer,
- int fmt);
-extern int send_opc(SCSI *scgp, caddr_t, int cnt, int doopc);
-
-#define CL_TYPE_STOP_DEICE 0 /* Stop De-icing a DVD+RW Media */
-#define CL_TYPE_TRACK 1 /* Close Track # */
-#define CL_TYPE_SESSION 2 /* Close Session/Border / Stop backgrnd. format */
-#define CL_TYPE_INTER_BORDER 3 /* Close intermediate Border */
-#define CL_TYPE_OPEN_SESSION 4 /* Close the Open Session and Record an Extended lead-out */
-#define CL_TYPE_FINALISE_MINRAD 5 /* Finalize the Disc with a Minimum Recorded Radius */
-#define CL_TYPE_FINALISE 6 /* Finalize the disc */
-extern int scsi_close_tr_session(SCSI *scgp, int type, int track,
- BOOL immed);
-extern int read_master_cue(SCSI *scgp, caddr_t bp, int sheet, int cnt);
-extern int send_cue_sheet(SCSI *scgp, caddr_t bp, long size);
-extern int read_buff_cap(SCSI *scgp, long *, long *);
-extern int scsi_blank(SCSI *scgp, long addr, int blanktype, BOOL immed);
-extern BOOL allow_atapi(SCSI *scgp, BOOL new);
-extern int mode_select(SCSI *scgp, Uchar *, int, int, int);
-extern int mode_sense(SCSI *scgp, Uchar *dp, int cnt, int page, int pcf);
-extern int mode_select_sg0(SCSI *scgp, Uchar *, int, int, int);
-extern int mode_sense_sg0(SCSI *scgp, Uchar *dp, int cnt, int page, int pcf);
-extern int mode_select_g0(SCSI *scgp, Uchar *, int, int, int);
-extern int mode_select_g1(SCSI *scgp, Uchar *, int, int, int);
-extern int mode_sense_g0(SCSI *scgp, Uchar *dp, int cnt, int page, int pcf);
-extern int mode_sense_g1(SCSI *scgp, Uchar *dp, int cnt, int page, int pcf);
-extern int read_tochdr(SCSI *scgp, cdr_t *, int *, int *);
-extern int read_cdtext(SCSI *scgp);
-extern int read_trackinfo(SCSI *scgp, int, long *, struct msf *, int *,
- int *, int *);
-extern int read_B0(SCSI *scgp, BOOL isbcd, long *b0p, long *lop);
-extern int read_session_offset(SCSI *scgp, long *);
-extern int read_session_offset_philips(SCSI *scgp, long *);
-extern int sense_secsize(SCSI *scgp, int current);
-extern int select_secsize(SCSI *scgp, int);
-extern BOOL is_cddrive(SCSI *scgp);
-extern BOOL is_unknown_dev(SCSI *scgp);
-extern int read_scsi(SCSI *scgp, caddr_t, long, int);
-extern int read_g0(SCSI *scgp, caddr_t, long, int);
-extern int read_g1(SCSI *scgp, caddr_t, long, int);
-extern BOOL getdev(SCSI *scgp, BOOL);
-#ifdef EOF /* stdio.h has been included */
-extern void printinq(SCSI *scgp, FILE *f);
-#endif
-extern void printdev(SCSI *scgp);
-extern BOOL do_inquiry(SCSI *scgp, BOOL);
-extern BOOL recovery_needed(SCSI *scgp, cdr_t *);
-extern int scsi_load(SCSI *scgp, cdr_t *);
-extern int scsi_unload(SCSI *scgp, cdr_t *);
-extern int scsi_cdr_write(SCSI *scgp, caddr_t bp, long sectaddr,
- long size, int blocks, BOOL islast);
-extern struct cd_mode_page_2A *mmc_cap(SCSI *scgp, Uchar *modep);
-extern void mmc_getval(struct cd_mode_page_2A *mp, BOOL *cdrrp, BOOL *cdwrp,
- BOOL *cdrrwp, BOOL *cdwrwp, BOOL *dvdp, BOOL *dvdwp);
-extern BOOL is_mmc(SCSI *scgp, BOOL *cdwp, BOOL *dvdwp);
-extern BOOL mmc_check(SCSI *scgp, BOOL *cdrrp, BOOL *cdwrp, BOOL *cdrrwp,
- BOOL *cdwrwp, BOOL *dvdp, BOOL *dvdwp);
-extern void print_capabilities(SCSI *scgp);
-#endif
-
-/*
- * scsi_cdr.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern void print_capabilities_mmc4(SCSI *scgp);
-#endif
-
-/*
- * scsi_mmc.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern int get_configuration(SCSI *scgp, caddr_t bp, int cnt,
- int st_feature, int rt);
-extern int get_curprofile(SCSI *scgp);
-extern int print_profiles(SCSI *scgp);
-extern int get_proflist(SCSI *scgp, BOOL *wp, BOOL *cdp, BOOL *dvdp,
- BOOL *dvdplusp, BOOL *ddcdp);
-extern int get_wproflist(SCSI *scgp, BOOL *cdp, BOOL *dvdp,
- BOOL *dvdplusp, BOOL *ddcdp);
-#endif
-
-/*
- * scsi_mmc.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern int get_supported_cdrw_media_types(SCSI *scgp);
-#endif
-
-/*
- * mmc_misc.c
- */
-#ifdef _SCG_SCSITRANSP_H
-extern int check_writemodes_mmc(SCSI *scgp, cdr_t *dp);
-#endif /* _SCG_SCSITRANSP_H */
-
-/*
- * cdr_drv.c
- */
-#ifdef _SCG_SCSITRANSP_H
-#ifdef _SCG_SCSIREG_H
-extern cdr_t *drive_identify(SCSI *scgp, cdr_t *, struct scsi_inquiry *ip);
-#else
-extern cdr_t *drive_identify(SCSI *scgp, cdr_t *, void *ip);
-#endif
-extern int drive_attach(SCSI *scgp, cdr_t *);
-#endif
-extern int attach_unknown(void);
-#ifdef _SCG_SCSITRANSP_H
-extern int blank_dummy(SCSI *scgp, cdr_t *, long addr, int blanktype);
-int format_dummy(SCSI *scgp, cdr_t *, int fmtflags);
-extern int drive_getdisktype(SCSI *scgp, cdr_t *dp);
-extern int cmd_ill(SCSI *scgp);
-extern int cmd_dummy(SCSI *scgp, cdr_t *);
-extern int no_sendcue(SCSI *scgp, cdr_t *, track_t *trackp);
-extern int buf_dummy(SCSI *scgp, long *sp, long *fp);
-#endif
-extern BOOL set_cdrcmds(char *name, cdr_t **dpp);
-#ifdef _SCG_SCSITRANSP_H
-extern cdr_t *get_cdrcmds(SCSI *scgp);
-#endif
-
-
-/*
- * drv_mmc.c
- */
-extern void mmc_opthelp(cdr_t *dp, int excode);
-extern char *hasdrvopt(char *optstr, char *optname);
-#ifdef _SCG_SCSITRANSP_H
-extern struct ricoh_mode_page_30 *get_justlink_ricoh(SCSI *scgp, Uchar *mode);
-#endif
-
-/*
- * isosize.c
- */
-extern Llong isosize(int f);
-
-/*
- * audiosize.c
- */
-extern BOOL is_auname(const char *name);
-extern off_t ausize(int f);
-extern BOOL is_wavname(const char *name);
-extern off_t wavsize(int f);
-
-/*
- * auinfo.c
- */
-extern BOOL auinfosize(char *name, track_t *trackp);
-extern void auinfo(char *name, int track, track_t *trackp);
-#ifdef CDTEXT_H
-extern textptr_t *gettextptr(int track, track_t *trackp);
-#endif
-extern void setmcn(char *mcn, track_t *trackp);
-extern void setisrc(char *isrc, track_t *trackp);
-extern void setindex(char *tindex, track_t *trackp);
-
-/*
- * diskid.c
- */
-extern void pr_manufacturer(msf_t *mp, BOOL rw, BOOL audio);
-extern int manufacturer_id(msf_t *mp);
-extern long disk_rcap(msf_t *mp, long maxblock, BOOL rw, BOOL audio);
-
-/*--------------------------------------------------------------------------*/
-/* Test only */
-/*--------------------------------------------------------------------------*/
-#ifdef _SCSIMMC_H
-/*extern int do_cue __PR((track_t *trackp, struct mmc_cue **cuep));*/
-#else
-/*extern int do_cue __PR((track_t *trackp, void *cuep));*/
-#endif
-
-/*
- * subchan.c
- */
-extern int do_leadin(track_t *trackp);
-#ifdef _SCG_SCSITRANSP_H
-extern int write_leadin(SCSI *scgp, cdr_t *dp, track_t *trackp,
- int leadinstart);
-extern int write_leadout(SCSI *scgp, cdr_t *dp, track_t *trackp);
-#endif
-extern void fillsubch(track_t *trackp, Uchar *sp, int secno, int nsecs);
-extern void filltpoint(Uchar *sub, int ctrl_adr, int point, msf_t *mp);
-extern void fillttime(Uchar *sub, msf_t *mp);
-extern void qpto96(Uchar *sub, Uchar *subq, int dop);
-extern void addrw(Uchar *sub, Uchar *subrwptr);
-extern void qwto16(Uchar *subq, Uchar *subptr);
-extern void subrecodesecs(track_t *trackp, Uchar *bp, int address, int nsecs);
-
-/*
- * sector.c
- */
-extern int encspeed(BOOL be_verbose);
-extern void encsectors(track_t *trackp, Uchar *bp, int address, int nsecs);
-extern void scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs);
-extern void encodesector(Uchar *sp, int sectype, int address);
-extern void fillsector(Uchar *sp, int sectype, int address);
-
-/*
- * clone.c
- */
-extern void clone_toc(track_t *trackp);
-extern void clone_tracktype(track_t *trackp);
-
-/*
- * cdtext.c
- */
-extern BOOL checktextfile(char *fname);
-extern void packtext(int tracks, track_t *trackp);
-#ifdef _SCG_SCSITRANSP_H
-extern int write_cdtext(SCSI *scgp, cdr_t *dp, long startsec);
-#endif
-
-/*
- * cue.c
- */
-extern int parsecue(char *cuefname, track_t trackp[]);
-#ifdef EOF /* stdio.h has been included */
-extern void fparsecue(FILE *f, track_t trackp[]);
-#endif
Modified: cdrkit/trunk/cdrecord/cdtext.c
===================================================================
--- cdrkit/trunk/cdrecord/cdtext.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/cdtext.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -47,7 +47,7 @@
#include <scg/scsitransp.h> /* For write_leadin() */
#include "cdtext.h"
-#include "cdrecord.h"
+#include "wodim.h"
#include "crc16.h"
#define PTI_TITLE 0x80 /* Album name and Track titles */
Modified: cdrkit/trunk/cdrecord/clone.c
===================================================================
--- cdrkit/trunk/cdrecord/clone.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/clone.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -48,7 +48,7 @@
#include <scg/scgcmd.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "crc16.h"
#include <scg/scsireg.h>
Modified: cdrkit/trunk/cdrecord/cue.c
===================================================================
--- cdrkit/trunk/cdrecord/cue.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/cue.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -51,7 +51,7 @@
#include "xio.h"
#include "cdtext.h"
-#include "cdrecord.h"
+#include "wodim.h"
#include "auheader.h"
#include "libport.h"
Modified: cdrkit/trunk/cdrecord/diskid.c
===================================================================
--- cdrkit/trunk/cdrecord/diskid.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/diskid.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -41,7 +41,7 @@
#include <standard.h>
#include <utypes.h>
-#include "cdrecord.h"
+#include "wodim.h"
void pr_manufacturer(msf_t *mp, BOOL rw, BOOL audio);
static struct disk_man *man_ptr(msf_t *mp);
Modified: cdrkit/trunk/cdrecord/drv_7501.c
===================================================================
--- cdrkit/trunk/cdrecord/drv_7501.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/drv_7501.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -71,7 +71,7 @@
#include <libport.h>
-#include "cdrecord.h"
+#include "wodim.h"
extern int silent;
extern int debug;
Modified: cdrkit/trunk/cdrecord/drv_jvc.c
===================================================================
--- cdrkit/trunk/cdrecord/drv_jvc.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/drv_jvc.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -60,7 +60,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
/* just a hack */
long lba_addr;
Modified: cdrkit/trunk/cdrecord/drv_mmc.c
===================================================================
--- cdrkit/trunk/cdrecord/drv_mmc.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/drv_mmc.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -62,7 +62,7 @@
#include "scsimmc.h"
#include "mmcvendor.h"
-#include "cdrecord.h"
+#include "wodim.h"
extern char *driveropts;
Modified: cdrkit/trunk/cdrecord/drv_philips.c
===================================================================
--- cdrkit/trunk/cdrecord/drv_philips.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/drv_philips.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -49,7 +49,7 @@
#include <scg/scgcmd.h>
#include <scg/scsidefs.h> /* XXX Only for DEV_RICOH_RO_1060C */
-#include "cdrecord.h"
+#include "wodim.h"
extern int debug;
extern int lverbose;
Modified: cdrkit/trunk/cdrecord/drv_simul.c
===================================================================
--- cdrkit/trunk/cdrecord/drv_simul.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/drv_simul.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -58,7 +58,7 @@
#include <libport.h>
-#include "cdrecord.h"
+#include "wodim.h"
extern int silent;
extern int verbose;
Modified: cdrkit/trunk/cdrecord/drv_sony.c
===================================================================
--- cdrkit/trunk/cdrecord/drv_sony.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/drv_sony.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -59,7 +59,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#ifdef SONY_DEBUG
# define inc_verbose() scgp->verbose++
Modified: cdrkit/trunk/cdrecord/fifo.c
===================================================================
--- cdrkit/trunk/cdrecord/fifo.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/fifo.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -103,7 +103,7 @@
#include <libport.h>
#include <schily.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "xio.h"
#ifdef DEBUG
@@ -831,7 +831,7 @@
#include <utypes.h> /* includes sys/types.h */
#include <schily.h>
-#include "cdrecord.h"
+#include "wodim.h"
void init_fifo(long);
BOOL init_faio(track_t *track, int);
Modified: cdrkit/trunk/cdrecord/isosize.c
===================================================================
--- cdrkit/trunk/cdrecord/isosize.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/isosize.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -41,7 +41,7 @@
#include <intcvt.h>
#include "iso9660.h"
-#include "cdrecord.h" /* to verify isosize() prototype */
+#include "wodim.h" /* to verify isosize() prototype */
Llong isosize(int f);
Modified: cdrkit/trunk/cdrecord/modes.c
===================================================================
--- cdrkit/trunk/cdrecord/modes.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/modes.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -43,7 +43,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
int scsi_compliant;
Modified: cdrkit/trunk/cdrecord/movesect.c
===================================================================
--- cdrkit/trunk/cdrecord/movesect.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/movesect.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -38,7 +38,7 @@
#include <utypes.h>
#include <schily.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "movesect.h"
void scatter_secs(track_t *trackp, char *bp, int nsecs);
Modified: cdrkit/trunk/cdrecord/scsi_cdr.c
===================================================================
--- cdrkit/trunk/cdrecord/scsi_cdr.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/scsi_cdr.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -70,7 +70,7 @@
#include <scg/scsitransp.h>
#include "scsimmc.h"
-#include "cdrecord.h"
+#include "wodim.h"
#define strbeg(s1, s2) (strstr((s2), (s1)) == (s2))
Modified: cdrkit/trunk/cdrecord/scsi_cdr_mmc4.c
===================================================================
--- cdrkit/trunk/cdrecord/scsi_cdr_mmc4.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/scsi_cdr_mmc4.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -58,7 +58,7 @@
#include <scg/scsitransp.h>
#include "scsimmc.h"
-#include "cdrecord.h"
+#include "wodim.h"
void print_capabilities_mmc4(SCSI *scgp);
Modified: cdrkit/trunk/cdrecord/scsi_mmc.c
===================================================================
--- cdrkit/trunk/cdrecord/scsi_mmc.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/scsi_mmc.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -60,7 +60,7 @@
#include <scg/scsitransp.h>
#include "scsimmc.h"
-#include "cdrecord.h"
+#include "wodim.h"
extern int xdebug;
Modified: cdrkit/trunk/cdrecord/scsi_mmc4.c
===================================================================
--- cdrkit/trunk/cdrecord/scsi_mmc4.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/scsi_mmc4.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -59,7 +59,7 @@
#include <scg/scsitransp.h>
#include "scsimmc.h"
-#include "cdrecord.h"
+#include "wodim.h"
int get_supported_cdrw_media_types(SCSI *scgp);
Modified: cdrkit/trunk/cdrecord/scsi_scan.c
===================================================================
--- cdrkit/trunk/cdrecord/scsi_scan.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/scsi_scan.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -51,7 +51,7 @@
#include <scg/scsitransp.h>
#include "scsi_scan.h"
-#include "cdrecord.h"
+#include "wodim.h"
static void print_product(FILE *f, struct scsi_inquiry *ip);
int select_target(SCSI *scgp, FILE *f);
Modified: cdrkit/trunk/cdrecord/sector.c
===================================================================
--- cdrkit/trunk/cdrecord/sector.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/sector.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -42,7 +42,7 @@
#include <timedefs.h>
#include <schily.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "movesect.h"
#ifdef HAVE_LIB_EDC_ECC
Modified: cdrkit/trunk/cdrecord/subchan.c
===================================================================
--- cdrkit/trunk/cdrecord/subchan.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/subchan.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -44,7 +44,7 @@
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "crc16.h"
int do_leadin(track_t *trackp);
Modified: cdrkit/trunk/cdrecord/wm_packet.c
===================================================================
--- cdrkit/trunk/cdrecord/wm_packet.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/wm_packet.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -46,7 +46,7 @@
#include <schily.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "xio.h"
extern int debug;
Modified: cdrkit/trunk/cdrecord/wm_session.c
===================================================================
--- cdrkit/trunk/cdrecord/wm_session.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/wm_session.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -44,7 +44,7 @@
#include <utypes.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
extern int debug;
extern int verbose;
Modified: cdrkit/trunk/cdrecord/wm_track.c
===================================================================
--- cdrkit/trunk/cdrecord/wm_track.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/cdrecord/wm_track.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -43,7 +43,7 @@
#include <standard.h>
#include <utypes.h>
-#include "cdrecord.h"
+#include "wodim.h"
extern int debug;
extern int verbose;
Copied: cdrkit/trunk/cdrecord/wodim.c (from rev 413, cdrkit/trunk/cdrecord/cdrecord.c)
===================================================================
--- cdrkit/trunk/cdrecord/cdrecord.c 2006-11-20 22:38:39 UTC (rev 413)
+++ cdrkit/trunk/cdrecord/wodim.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -0,0 +1,4659 @@
+/*
+ * This file has been modified for the cdrkit suite.
+ *
+ * The behaviour and appearence of the program code below can differ to a major
+ * extent from the version distributed by the original author(s).
+ *
+ * For details, see Changelog file distributed with the cdrkit package. If you
+ * received this file from another source then ask the distributing person for
+ * a log of modifications.
+ *
+ */
+
+/*
+ *
+ * Modified by Eduard Bloch in 08/2006
+ */
+
+/* @(#)cdrecord.c 1.310 06/02/09 Copyright 1995-2006 J. Schilling */
+#ifndef lint
+static char sccsid[] =
+ "@(#)cdrecord.c 1.310 06/02/09 Copyright 1995-2006 J. Schilling";
+#endif
+/*
+ * Record data on a CD/CVD-Recorder
+ *
+ * Copyright (c) 1995-2006 J. Schilling
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <mconfig.h>
+#include <stdio.h>
+#include <standard.h>
+#include <stdxlib.h>
+#include <fctldefs.h>
+#include <errno.h>
+#include <timedefs.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h> /* for rlimit */
+#endif
+#include <statdefs.h>
+#include <unixstd.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <strdefs.h>
+#include <utypes.h>
+#include <intcvt.h>
+#include <signal.h>
+#include <schily.h>
+#include <getargs.h>
+#ifdef HAVE_PRIV_H
+#include <priv.h>
+#endif
+
+#include "xio.h"
+
+#include <scg/scsireg.h> /* XXX wegen SC_NOT_READY */
+#include <scg/scsitransp.h>
+#include <scg/scgcmd.h> /* XXX fuer read_buffer */
+#include "scsi_scan.h"
+
+#include "auheader.h"
+#include "wodim.h"
+#include "defaults.h"
+#include "movesect.h"
+
+#ifdef __linux__
+#include <sys/capability.h> /* for rawio capability */
+#endif
+
+#define cdr_version "1.0"
+
+#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0
+#ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */
+#else
+#define USE_POSIX_PRIORITY_SCHEDULING
+#endif
+#endif
+
+/*
+ * Map toc/track types into names.
+ */
+char *toc2name[] = {
+ "CD-DA",
+ "CD-ROM",
+ "CD-ROM XA mode 1",
+ "CD-ROM XA mode 2",
+ "CD-I",
+ "Illegal toc type 5",
+ "Illegal toc type 6",
+ "Illegal toc type 7",
+};
+
+/*
+ * Map sector types into names.
+ */
+char *st2name[] = {
+ "Illegal sector type 0",
+ "CD-ROM mode 1",
+ "CD-ROM mode 2",
+ "Illegal sector type 3",
+ "CD-DA without preemphasis",
+ "CD-DA with preemphasis",
+ "Illegal sector type 6",
+ "Illegal sector type 7",
+};
+
+/*
+ * Map data block types into names.
+ */
+char *db2name[] = {
+ "Raw (audio)",
+ "Raw (audio) with P/Q sub channel",
+ "Raw (audio) with P/W packed sub channel",
+ "Raw (audio) with P/W raw sub channel",
+ "Reserved mode 4",
+ "Reserved mode 5",
+ "Reserved mode 6",
+ "Vendor unique mode 7",
+ "CD-ROM mode 1",
+ "CD-ROM mode 2",
+ "CD-ROM XA mode 2 form 1",
+ "CD-ROM XA mode 2 form 1 (with subheader)",
+ "CD-ROM XA mode 2 form 2",
+ "CD-ROM XA mode 2 form 1/2/mix",
+ "Reserved mode 14",
+ "Vendor unique mode 15",
+};
+
+/*
+ * Map write modes into names.
+ */
+static char wm_none[] = "unknown";
+static char wm_ill[] = "illegal";
+
+char *wm2name[] = {
+ wm_none,
+ "BLANK",
+ "FORMAT",
+ wm_ill,
+ "PACKET",
+ wm_ill,
+ wm_ill,
+ wm_ill,
+ "TAO",
+ wm_ill,
+ wm_ill,
+ wm_ill,
+ "SAO",
+ "SAO/RAW16", /* Most liklely not needed */
+ "SAO/RAW96P",
+ "SAO/RAW96R",
+ "RAW",
+ "RAW/RAW16",
+ "RAW/RAW96P",
+ "RAW/RAW96R",
+};
+
+int debug; /* print debug messages */
+static int kdebug; /* print kernel debug messages */
+static int scsi_verbose; /* SCSI verbose flag */
+static int silent; /* SCSI silent flag */
+int lverbose; /* static verbose flag */
+int xdebug; /* extended debug flag */
+
+char *buf; /* The transfer buffer */
+long bufsize = -1; /* The size of the transfer buffer */
+
+static int gracetime = GRACE_TIME;
+static int raw_speed = -1;
+static int dma_speed = -1;
+static int dminbuf = -1; /* XXX Hack for now drive min buf fill */
+BOOL isgui;
+static int didintr;
+char *driveropts;
+static char *cuefilename;
+static uid_t oeuid = (uid_t)-1;
+
+struct timeval starttime;
+struct timeval wstarttime;
+struct timeval stoptime;
+struct timeval fixtime;
+
+static long fs = -1L; /* fifo (ring buffer) size */
+
+static int gracewait(cdr_t *dp, BOOL *didgracep);
+static void cdrstats(cdr_t *dp);
+static void susage(int);
+static void usage(int);
+static void blusage(int);
+static void formattypeusage(int);
+static void intr(int sig);
+static void catchsig(int sig);
+static int scsi_cb(void *arg);
+static void intfifo(int sig);
+static void exscsi(int excode, void *arg);
+static void excdr(int excode, void *arg);
+int read_buf(int f, char *bp, int size);
+int fill_buf(int f, track_t *trackp, long secno, char *bp, int size);
+int get_buf(int f, track_t *trackp, long secno, char **bpp, int size);
+int write_secs(SCSI *scgp, cdr_t *dp, char *bp, long startsec, int bytespt,
+ int secspt, BOOL islast);
+static int write_track_data(SCSI *scgp, cdr_t *, track_t *);
+int pad_track(SCSI *scgp, cdr_t *dp, track_t *trackp, long startsec,
+ Llong amt, BOOL dolast, Llong *bytesp);
+int write_buf(SCSI *scgp, cdr_t *dp, track_t *trackp, char *bp,
+ long startsec, Llong amt, int secsize, BOOL dolast,
+ Llong *bytesp);
+static void printdata(int, track_t *);
+static void printaudio(int, track_t *);
+static void checkfile(int, track_t *);
+static int checkfiles(int, track_t *);
+static void setleadinout(int, track_t *);
+static void setpregaps(int, track_t *);
+static long checktsize(int, track_t *);
+static void opentracks(track_t *);
+static void checksize(track_t *);
+static BOOL checkdsize(SCSI *scgp, cdr_t *dp, long tsize, int flags);
+static void raise_fdlim(void);
+static void raise_memlock(void);
+static int gargs(int, char **, int *, track_t *, char **, int *, cdr_t **,
+ int *, long *, int *, int *);
+static void set_trsizes(cdr_t *, int, track_t *);
+void load_media(SCSI *scgp, cdr_t *, BOOL);
+void unload_media(SCSI *scgp, cdr_t *, int);
+void reload_media(SCSI *scgp, cdr_t *);
+void set_secsize(SCSI *scgp, int secsize);
+static int get_dmaspeed(SCSI *scgp, cdr_t *);
+static BOOL do_opc(SCSI *scgp, cdr_t *, int);
+static void check_recovery(SCSI *scgp, cdr_t *, int);
+void audioread(SCSI *scgp, cdr_t *, int);
+static void print_msinfo(SCSI *scgp, cdr_t *);
+static void print_toc(SCSI *scgp, cdr_t *);
+static void print_track(int, long, struct msf *, int, int, int);
+#if !defined(HAVE_SYS_PRIOCNTL_H)
+static int rt_raisepri(int);
+#endif
+void raisepri(int);
+static void wait_input(void);
+static void checkgui(void);
+static int getbltype(char *optstr, long *typep);
+static int getformattype(char *optstr, long *typep);
+static void print_drflags(cdr_t *dp);
+static void print_wrmodes(cdr_t *dp);
+static BOOL check_wrmode(cdr_t *dp, int wmode, int tflags);
+static void set_wrmode(cdr_t *dp, int wmode, int tflags);
+static void linuxcheck(void);
+
+#ifdef __linux__
+static int get_cap(cap_value_t cap_array);
+#endif
+
+struct exargs {
+ SCSI *scgp;
+ cdr_t *dp;
+ int old_secsize;
+ int flags;
+ int exflags;
+} exargs;
+
+void fifo_cleanup(void) {
+ kill_faio();
+}
+
+int main(int argc, char *argv[])
+{
+ char *dev = NULL;
+ int timeout = 40; /* Set default timeout to 40s CW-7502 is slow*/
+ int speed = -1;
+ long flags = 0L;
+ int blanktype = 0;
+ int formattype = 0;
+ int i;
+ int tracks = 0;
+ int trackno;
+ long tsize;
+ track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */
+ cdr_t *dp = (cdr_t *)0;
+ long startsec = 0L;
+ int errs = 0;
+ SCSI *scgp = NULL;
+ char errstr[80];
+ BOOL gracedone = FALSE;
+ int ispacket;
+ BOOL is_cdwr = FALSE;
+ BOOL is_dvdwr = FALSE;
+
+
+#ifdef __EMX__
+ /* This gives wildcard expansion with Non-Posix shells with EMX */
+ _wildcard(&argc, &argv);
+#endif
+ save_args(argc, argv);
+ oeuid = geteuid(); /* Remember saved set uid */
+
+ fillbytes(track, sizeof (track), '\0');
+ for (i = 0; i < MAX_TRACK+2; i++)
+ track[i].track = track[i].trackno = i;
+ track[0].tracktype = TOC_MASK;
+ raise_fdlim();
+ ispacket = gargs(argc, argv, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
+ &blanktype, &formattype);
+ if ((track[0].tracktype & TOC_MASK) == TOC_MASK)
+ comerrno(EX_BAD, "Internal error: Bad TOC type.\n");
+
+ if (flags & F_VERSION) {
+ fprintf(stderr,
+ "Cdrecord-yelling-line-to-tell-frontends-to-use-it-like-version 2.01.01a03-dvd \n"
+ "Wodim " cdr_version "\n"
+ "Copyright (C) 2006 Cdrkit suite contributors\n"
+ "Based on works from Joerg Schilling, Copyright (C) 1995-2006, J. Schilling\n"
+ );
+ exit(0);
+ }
+
+ checkgui();
+
+ if (debug || lverbose) {
+ printf("TOC Type: %d = %s\n",
+ track[0].tracktype & TOC_MASK,
+ toc2name[track[0].tracktype & TOC_MASK]);
+ }
+
+ if ((flags & (F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_INQUIRY|F_SCANBUS|F_RESET)) == 0) {
+ /*
+ * Try to lock us im memory (will only work for root)
+ * but you need access to root anyway to send SCSI commands.
+ * We need to be root to open /dev/scg? or similar devices
+ * on other OS variants and we need to be root to be able
+ * to send SCSI commands at least on AIX and
+ * Solaris (USCSI only) regardless of the permissions for
+ * opening files
+ *
+ * XXX The folowing test used to be
+ * XXX #if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK)
+ * XXX but the definition for _POSIX_MEMLOCK did change during
+ * XXX the last 8 years and the autoconf test is better for
+ * XXX the static case. sysconf() only makes sense if we like
+ * XXX to check dynamically.
+ */
+ raise_memlock();
+#if defined(HAVE_MLOCKALL)
+ /*
+ * XXX mlockall() needs root privilleges.
+ */
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
+ errmsg("WARNING: Cannot do mlockall(2).\n");
+ errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
+ }
+#endif
+
+ /*
+ * XXX raisepri() needs root privilleges.
+ */
+ raisepri(0); /* max priority */
+ /*
+ * XXX shmctl(id, SHM_LOCK, 0) needs root privilleges.
+ * XXX So if we use SysV shared memory, wee need to be root.
+ *
+ * Note that not being able to set up a FIFO bombs us
+ * back to the DOS ages. Trying to run cdrecord without
+ * root privillegs is extremely silly, it breaks most
+ * of the advanced features. We need to be at least installed
+ * suid root or called by RBACs pfexec.
+ */
+ init_fifo(fs); /* Attach shared memory (still one process) */
+ }
+
+ if ((flags & F_WAITI) != 0) {
+ if (lverbose)
+ printf("Waiting for data on stdin...\n");
+ wait_input();
+ }
+
+ /*
+ * Call scg_remote() to force loading the remote SCSI transport library
+ * code that is located in librscg instead of the dummy remote routines
+ * that are located inside libscg.
+ */
+ scg_remote();
+ if (dev != NULL &&
+ ((strncmp(dev, "HELP", 4) == 0) ||
+ (strncmp(dev, "help", 4) == 0))) {
+ scg_help(stderr);
+ exit(0);
+ }
+
+ scgp = scg_open(dev, errstr, sizeof (errstr),
+ debug, lverbose);
+ if(!scgp && dev) {
+ char *dalt;
+ int len=5+strlen(dev);
+ dalt=calloc(len, sizeof(char));
+ strcat(dalt, "ATA:");
+ strcat(dalt+4, dev);
+ scgp = scg_open(dalt, errstr, sizeof (errstr),
+ debug, lverbose);
+ }
+ if(!scgp)
+ {
+ errmsg("\nCannot open SCSI driver!\n"
+ "For possible targets try 'wodim -scanbus'.\n"
+ "For possible transport specifiers try 'wodim dev=help'.\n"
+ "For IDE/ATAPI devices configuration, see the file README.ATAPI.setup from\n"
+ "the wodim documentation.\n");
+ exit(EX_BAD);
+ }
+#ifdef HAVE_PRIV_SET
+#ifdef PRIV_DEBUG
+ fprintf(stderr, "file_dac_read: %d\n", priv_ineffect(PRIV_FILE_DAC_READ));
+#endif
+ /*
+ * Give up privs we do not need anymore.
+ * We no longer need:
+ * file_dac_read,proc_lock_memory,proc_priocntl,net_privaddr
+ * We still need:
+ * sys_devices
+ */
+ priv_set(PRIV_OFF, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
+ PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL);
+ priv_set(PRIV_OFF, PRIV_PERMITTED,
+ PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
+ PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL);
+ priv_set(PRIV_OFF, PRIV_INHERITABLE,
+ PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY,
+ PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL);
+#endif
+ /*
+ * This is only for OS that do not support fine grained privs.
+ *
+ * XXX Below this point we do not need root privilleges anymore.
+ */
+ if (geteuid() != getuid()) { /* AIX does not like to do this */
+ /* If we are not root */
+#ifdef HAVE_SETREUID
+ if (setreuid(-1, getuid()) < 0)
+#else
+#ifdef HAVE_SETEUID
+ if (seteuid(getuid()) < 0)
+#else
+ if (setuid(getuid()) < 0)
+#endif
+#endif
+ comerr("Panic cannot set back effective uid.\n");
+ }
+
+#ifdef __linux__
+ /* get the rawio capability */
+ if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose))
+ {
+ perror("Warning: Cannot gain SYS_RAWIO capability");
+ fprintf(stderr, "Possible reason: wodim not installed SUID root.\n");
+ }
+#endif
+
+ /*
+ * WARNING: We now are no more able to do any privilleged operation
+ * unless we have been called by root.
+ *
+ * XXX It may be that we later get problems in init_faio() because
+ * XXX this function calls raisepri() to lower the priority slightly.
+ */
+ scg_settimeout(scgp, timeout);
+ scgp->verbose = scsi_verbose;
+ scgp->silent = silent;
+ scgp->debug = debug;
+ scgp->kdebug = kdebug;
+ scgp->cap->c_bsize = DATA_SEC_SIZE;
+
+ if ((flags & F_MSINFO) == 0 || lverbose) {
+ char *vers;
+ char *auth;
+
+ vers = scg_version(0, SCG_VERSION);
+ auth = scg_version(0, SCG_AUTHOR);
+ if(lverbose >1 && auth && vers)
+ fprintf(stderr, "Using libscg version '%s-%s'.\n", auth, vers);
+
+
+ vers = scg_version(scgp, SCG_RVERSION);
+ auth = scg_version(scgp, SCG_RAUTHOR);
+ if (lverbose > 1 && vers && auth)
+ fprintf(stderr, "Using remote transport code version '%s-%s'\n", auth, vers);
+ }
+
+ if (lverbose && driveropts)
+ printf("Driveropts: '%s'\n", driveropts);
+
+/* bufsize = scg_bufsize(scgp, CDR_BUF_SIZE);*/
+ bufsize = scg_bufsize(scgp, bufsize);
+ if (lverbose || debug)
+ fprintf(stderr, "SCSI buffer size: %ld\n", bufsize);
+ if ((buf = scg_getbuf(scgp, bufsize)) == NULL)
+ comerr("Cannot get SCSI I/O buffer.\n");
+
+ if ((flags & F_SCANBUS) != 0) {
+ select_target(scgp, stdout);
+ exit(0);
+ }
+ if ((flags & F_RESET) != 0) {
+ if (scg_reset(scgp, SCG_RESET_NOP) < 0)
+ comerr("Cannot reset (OS does not implement reset).\n");
+ if (scg_reset(scgp, SCG_RESET_TGT) >= 0)
+ exit(0);
+ if (scg_reset(scgp, SCG_RESET_BUS) < 0)
+ comerr("Cannot reset target.\n");
+ exit(0);
+ }
+
+ /*
+ * First try to check which type of SCSI device we
+ * have.
+ */
+ if (debug || lverbose)
+ printf("atapi: %d\n", scg_isatapi(scgp));
+ scgp->silent++;
+ test_unit_ready(scgp); /* eat up unit attention */
+ scgp->silent--;
+ if (!do_inquiry(scgp, (flags & F_MSINFO) == 0 || lverbose)) {
+ errmsgno(EX_BAD, "Cannot do inquiry for CD/DVD-Recorder.\n");
+ if (unit_ready(scgp))
+ errmsgno(EX_BAD, "The unit seems to be hung and needs power cycling.\n");
+ exit(EX_BAD);
+ }
+#ifdef GCONF
+/*
+ * Debug only
+ */
+{
+extern void gconf(SCSI *);
+
+if (lverbose > 2)
+ gconf(scgp);
+}
+#endif
+
+ if ((flags & F_PRCAP) != 0) {
+ print_capabilities(scgp);
+ print_capabilities_mmc4(scgp);
+ exit(0);
+ }
+ if ((flags & F_INQUIRY) != 0)
+ exit(0);
+
+ if (dp == (cdr_t *)NULL) { /* No driver= option specified */
+ dp = get_cdrcmds(scgp); /* Calls dp->cdr_identify() */
+ } else if (!is_unknown_dev(scgp) && dp != get_cdrcmds(scgp)) {
+ errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n");
+ }
+ is_mmc(scgp, &is_cdwr, &is_dvdwr);
+ if (ispacket) {
+ if (is_dvdwr) {
+ track[0].flags |= TI_PACKET;
+ /*XXX put here to only affect DVD writing, should be in gargs.
+ * however if set in args for all mode, packet writing is then
+ * broken for all disc as cdrecord assume that PACKET imply TAO which
+ * is not true at all???? */
+ track[0].flags &= ~TI_TAO;
+ }
+ }
+
+ if (dp == (cdr_t *)0)
+ comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.\n");
+
+ /* DVD does not support TAO */
+ if (dp->is_dvd) {
+ if(lverbose>1)
+ fprintf(stderr, "Using Session At Once (SAO) for DVD mode.\n");
+ dp->cdr_flags |= F_SAO;
+ for (i = 0; i <= MAX_TRACK; i++) {
+ track[i].flags &= ~TI_TAO;
+ track[i].flags |= TI_SAO;
+ }
+ }
+
+ if (!is_cddrive(scgp))
+ comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n");
+ /*
+ * The driver is known, set up data structures...
+ */
+ {
+ cdr_t *ndp;
+ dstat_t *dsp;
+
+ ndp = malloc(sizeof (cdr_t));
+ dsp = malloc(sizeof (dstat_t));
+ if (ndp == NULL || dsp == NULL)
+ comerr("Cannot allocate memory for driver structure.\n");
+ movebytes(dp, ndp, sizeof (cdr_t));
+ dp = ndp;
+ dp->cdr_flags |= CDR_ALLOC;
+ dp->cdr_cmdflags = flags;
+
+ fillbytes(dsp, sizeof (*dsp), '\0');
+ dsp->ds_minbuf = 0xFFFF;
+ dp->cdr_dstat = dsp;
+ }
+
+ if ((flags & (F_MSINFO|F_TOC|F_LOAD|F_DLCK|F_EJECT)) == 0 ||
+ tracks > 0 ||
+ cuefilename != NULL) {
+
+
+ if ((dp->cdr_flags & CDR_ISREADER) != 0) {
+ errmsgno(EX_BAD,
+ "Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.\n");
+ }
+
+ if (!is_mmc(scgp, &is_cdwr, &is_dvdwr))
+ is_cdwr = TRUE; /* If it is not MMC, it must be a CD writer */
+
+ if (is_dvdwr && !set_cdrcmds("mmc_mdvd", (cdr_t **)NULL)) {
+ errmsgno(EX_BAD,
+ "Internal error, DVD driver failure. Please report to debburn-devel at lists.alioth.debian.org.\n");
+ /*
+ errmsgno(EX_BAD,
+ "This version of cdrecord does not include DVD-R/DVD-RW support code.\n");
+ errmsgno(EX_BAD,
+ "See /usr/share/doc/cdrecord/README.DVD.Debian for details on DVD support.\n");
+ */
+ }
+ /*
+ * Only exit if this is not the ProDVD test binary.
+ */
+ if (!is_cdwr)
+ exit(EX_BAD);
+ }
+
+ /*
+ * Set up data structures for current drive state.
+ */
+ if ((*dp->cdr_attach)(scgp, dp) != 0)
+ comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.\n");
+
+ if (lverbose > 1) {
+ printf("Drive current speed: %d\n", dp->cdr_dstat->ds_dr_cur_wspeed);
+ printf("Drive default speed: %d\n", dp->cdr_speeddef);
+ printf("Drive max speed : %d\n", dp->cdr_speedmax);
+ }
+ if (speed > (int)dp->cdr_speedmax && (flags & F_FORCE) == 0)
+ speed = dp->cdr_speedmax;
+ if (speed < 0)
+ speed = dp->cdr_speeddef;
+
+ if (lverbose > 1) {
+ printf("Selected speed : %d\n", speed);
+ }
+ dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
+
+ exargs.scgp = scgp;
+ exargs.dp = dp;
+ exargs.old_secsize = -1;
+ exargs.flags = flags;
+
+ if ((flags & F_MSINFO) == 0 || lverbose) {
+ printf("Using %s (%s).\n", dp->cdr_drtext, dp->cdr_drname);
+ print_drflags(dp);
+ print_wrmodes(dp);
+ }
+ scgp->silent++;
+ if ((debug || lverbose)) {
+ tsize = -1;
+ if ((*dp->cdr_buffer_cap)(scgp, &tsize, (long *)0) < 0 || tsize < 0) {
+ if (read_buffer(scgp, buf, 4, 0) >= 0)
+ tsize = a_to_u_4_byte(buf);
+ }
+ if (tsize > 0) {
+ printf("Drive buf size : %lu = %lu KB\n",
+ tsize, tsize >> 10);
+ }
+ }
+ scgp->silent--;
+
+ dma_speed = get_dmaspeed(scgp, dp);
+ if ((debug || lverbose) && dma_speed > 0) {
+ /*
+ * We do not yet know what medium type is in...
+ */
+ printf("Drive DMA Speed: %d kB/s %dx CD %dx DVD\n",
+ dma_speed, dma_speed/176, dma_speed/1385);
+ }
+ if ((tracks > 0 || cuefilename != NULL) && (debug || lverbose))
+ printf("FIFO size : %lu = %lu KB\n", fs, fs >> 10);
+
+#ifdef HAVE_LIB_EDC_ECC
+ if ((flags & F_RAW) != 0 && (dp->cdr_dstat->ds_flags & DSF_DVD) == 0)
+ raw_speed = encspeed(debug || lverbose);
+#endif
+
+ if ((flags & F_CHECKDRIVE) != 0)
+ exit(0);
+
+ if ((flags & F_ABORT) != 0) {
+ /*
+ * flush cache is not supported by CD-ROMs avoid prob with -toc
+ */
+ scgp->silent++;
+ scsi_flush_cache(scgp, FALSE);
+ (*dp->cdr_abort_session)(scgp, dp);
+ scgp->silent--;
+ exit(0);
+ }
+
+ if (tracks == 0 && cuefilename == NULL &&
+ (flags & (F_FIX|F_BLANK)) == 0 && (flags & F_EJECT) != 0) {
+ /*
+ * Do not check if the unit is ready here to allow to open
+ * an empty unit too.
+ */
+ unload_media(scgp, dp, flags);
+ exit(0);
+ }
+ flush();
+
+ if (cuefilename) {
+ parsecue(cuefilename, track);
+ tracks = track[0].tracks;
+ } else {
+ opentracks(track);
+ }
+
+ if (tracks > 1)
+ sleep(2); /* Let the user watch the inquiry messages */
+
+ if (tracks > 0 && !check_wrmode(dp, flags, track[1].flags))
+ comerrno(EX_BAD, "Illegal write mode for this drive.\n");
+
+ if ((track[0].flags & TI_TEXT) == 0 && /* CD-Text not yet processed */
+ (track[MAX_TRACK+1].flags & TI_TEXT) != 0) {
+ /*
+ * CD-Text from textfile= or from CUE CDTEXTFILE will win
+ * over CD-Text from *.inf files and over CD-Text from
+ * CUE SONGWRITER, ...
+ */
+ packtext(tracks, track);
+ track[0].flags |= TI_TEXT;
+ }
+#ifdef CLONE_WRITE
+ if (flags & F_CLONE) {
+ clone_toc(track);
+ clone_tracktype(track);
+ }
+#endif
+ setleadinout(tracks, track);
+ set_trsizes(dp, tracks, track);
+ setpregaps(tracks, track);
+ checkfiles(tracks, track);
+ tsize = checktsize(tracks, track);
+
+ /*
+ * Make wm2name[wrmode] work.
+ * This must be done after the track flags have been set up
+ * by the functions above.
+ */
+ if (tracks == 0 && (flags & F_BLANK) != 0)
+ dp->cdr_dstat->ds_wrmode = WM_BLANK;
+ else if (tracks == 0 && (flags & F_FORMAT) != 0)
+ dp->cdr_dstat->ds_wrmode = WM_FORMAT;
+ else
+ set_wrmode(dp, flags, track[1].flags);
+
+ /*
+ * Debug only
+ */
+ {
+ void *cp = NULL;
+
+ (*dp->cdr_gen_cue)(track, &cp, FALSE);
+ if (cp)
+ free(cp);
+ }
+
+ /*
+ * Create Lead-in data. Only needed in RAW mode.
+ */
+ do_leadin(track);
+
+
+ /*
+ * Install exit handler before we change the drive status.
+ */
+ on_comerr(exscsi, &exargs);
+
+ if ((flags & F_FORCE) == 0)
+ load_media(scgp, dp, TRUE);
+
+ if ((flags & (F_LOAD|F_DLCK)) != 0) {
+ if ((flags & F_DLCK) == 0) {
+ scgp->silent++; /* silently */
+ scsi_prevent_removal(
+ scgp, 0); /* allow manual open */
+ scgp->silent--; /* if load failed... */
+ }
+ exit(0); /* we did not change status */
+ }
+ exargs.old_secsize = sense_secsize(scgp, 1);
+ if (exargs.old_secsize < 0)
+ exargs.old_secsize = sense_secsize(scgp, 0);
+ if (debug)
+ printf("Current Secsize: %d\n", exargs.old_secsize);
+ scgp->silent++;
+ if (read_capacity(scgp) < 0) {
+ if (exargs.old_secsize > 0)
+ scgp->cap->c_bsize = exargs.old_secsize;
+ }
+ scgp->silent--;
+ if (exargs.old_secsize < 0)
+ exargs.old_secsize = scgp->cap->c_bsize;
+ if (exargs.old_secsize != scgp->cap->c_bsize)
+ errmsgno(EX_BAD, "Warning: blockdesc secsize %d differs from cap secsize %d\n",
+ exargs.old_secsize, scgp->cap->c_bsize);
+
+ if (lverbose)
+ printf("Current Secsize: %d\n", exargs.old_secsize);
+
+ if (exargs.old_secsize > 0 && exargs.old_secsize != DATA_SEC_SIZE) {
+ /*
+ * Some drives (e.g. Plextor) don't like to write correctly
+ * in SAO mode if the sector size is set to 512 bytes.
+ * In addition, cdrecord -msinfo will not work properly
+ * if the sector size is not 2048 bytes.
+ */
+ set_secsize(scgp, DATA_SEC_SIZE);
+ }
+
+ /*
+ * Is this the right place to do this ?
+ */
+ check_recovery(scgp, dp, flags);
+
+/*audioread(dp, flags);*/
+/*unload_media(scgp, dp, flags);*/
+/*return 0;*/
+ if (flags & F_WRITE)
+ dp->cdr_dstat->ds_cdrflags |= RF_WRITE;
+ if (flags & F_BLANK)
+ dp->cdr_dstat->ds_cdrflags |= RF_BLANK;
+ if (flags & F_PRATIP || lverbose > 0) {
+ dp->cdr_dstat->ds_cdrflags |= RF_PRATIP;
+ }
+ if (flags & F_IMMED || dminbuf > 0) {
+ if (dminbuf <= 0)
+ dminbuf = 50;
+ if (lverbose <= 0) /* XXX Hack needed for now */
+ lverbose++;
+ dp->cdr_dstat->ds_cdrflags |= RF_WR_WAIT;
+ }
+ if ((*dp->cdr_getdisktype)(scgp, dp) < 0) {
+ errmsgno(EX_BAD, "Cannot get disk type.\n");
+ if ((flags & F_FORCE) == 0)
+ comexit(EX_BAD);
+ }
+ if (flags & F_PRATIP) {
+ comexit(0);
+ }
+ /*
+ * The next actions should depend on the disk type.
+ */
+ if (dma_speed > 0) {
+ if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0)
+ dma_speed /= 176;
+ else
+ dma_speed /= 1385;
+ }
+
+ /*
+ * Init drive to default modes:
+ *
+ * We set TAO unconditionally to make checkdsize() work
+ * currectly in SAO mode too.
+ *
+ * At least MMC drives will not return the next writable
+ * address we expect when the drive's write mode is set
+ * to SAO. We need this address for mkisofs and thus
+ * it must be the first user accessible sector and not the
+ * first sector of the pregap.
+ *
+ * XXX The ACER drive:
+ * XXX Vendor_info : 'ATAPI '
+ * XXX Identifikation : 'CD-R/RW 8X4X32 '
+ * XXX Revision : '5.EW'
+ * XXX Will not return from -dummy to non-dummy without
+ * XXX opening the tray.
+ */
+ scgp->silent++;
+ if ((*dp->cdr_init)(scgp, dp) < 0)
+ comerrno(EX_BAD, "Cannot init drive.\n");
+ scgp->silent--;
+
+ if (flags & F_SETDROPTS) {
+ /*
+ * Note that the set speed function also contains
+ * drive option processing for speed related drive options.
+ */
+ if ((*dp->cdr_opt1)(scgp, dp) < 0) {
+ errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n");
+ }
+ if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0) {
+ errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
+ }
+ dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
+ if ((*dp->cdr_opt2)(scgp, dp) < 0) {
+ errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n");
+ }
+ comexit(0);
+ }
+ /*
+ * XXX If dp->cdr_opt1() ever affects the result for
+ * XXX the multi session info we would need to move it here.
+ */
+ if (flags & F_MSINFO) {
+ print_msinfo(scgp, dp);
+ comexit(0);
+ }
+ if (flags & F_TOC) {
+ print_toc(scgp, dp);
+ comexit(0);
+ }
+#ifdef XXX
+ if ((*dp->cdr_check_session)() < 0) {
+ comexit(EX_BAD);
+ }
+#endif
+ {
+ Int32_t omb = dp->cdr_dstat->ds_maxblocks;
+
+ if ((*dp->cdr_opt1)(scgp, dp) < 0) {
+ errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n");
+ }
+ if (tsize > 0 && omb != dp->cdr_dstat->ds_maxblocks) {
+ printf("Disk size changed by user options.\n");
+ printf("Checking disk capacity according to new values.\n");
+ }
+ }
+ if (tsize == 0) {
+ if (tracks > 0) {
+ errmsgno(EX_BAD,
+ "WARNING: Total disk size unknown. Data may not fit on disk.\n");
+ }
+ } else if (tracks > 0) {
+ /*
+ * XXX How do we let the user check the remaining
+ * XXX disk size witout starting the write process?
+ */
+ if (!checkdsize(scgp, dp, tsize, flags))
+ comexit(EX_BAD);
+ }
+ if (tracks > 0 && fs > 0l) {
+#if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID)
+ /*
+ * Hack to work around the POSIX design bug in real time
+ * priority handling: we need to be root even to lower
+ * our priority.
+ * Note that we need to find a more general way that works
+ * even on OS that do not support getreuid() which is *BSD
+ * and SUSv3 only.
+ */
+ if (oeuid != getuid()) {
+ if (setreuid(-1, oeuid) < 0)
+ errmsg("Could set back effective uid.\n");
+ }
+
+#endif
+ /*
+ * fork() here to start the extra process needed for
+ * improved buffering.
+ */
+ if (!init_faio(track, bufsize))
+ fs = 0L;
+ else
+ on_comerr(excdr, &exargs);
+
+ atexit(fifo_cleanup);
+
+#if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID)
+ /*
+ * XXX Below this point we never need root privilleges anymore.
+ */
+ if (geteuid() != getuid()) { /* AIX does not like to do this */
+ /* If we are not root */
+ if (setreuid(-1, getuid()) < 0)
+ comerr("Panic cannot set back effective uid.\n");
+ }
+#ifdef __linux__
+ if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose))
+ perror("Error: Cannot gain SYS_RAWIO capability, is wodim installed SUID root? Reason");
+#endif
+
+#endif
+ }
+ if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0) {
+ errmsgno(EX_BAD, "Cannot set speed/dummy.\n");
+ if ((flags & F_FORCE) == 0)
+ comexit(EX_BAD);
+ }
+ dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
+ if ((flags & F_WRITE) != 0 && raw_speed >= 0) {
+ int max_raw = (flags & F_FORCE) != 0 ? raw_speed:raw_speed/2;
+
+ if (getenv("CDR_FORCERAWSPEED"))
+ max_raw = raw_speed;
+
+ for (i = 1; i <= MAX_TRACK; i++) {
+ /*
+ * Check for Clone tracks
+ */
+ if ((track[i].sectype & ST_MODE_RAW) != 0)
+ continue;
+ /*
+ * Check for non-data tracks
+ */
+ if ((track[i].sectype & ST_MODE_MASK) == ST_MODE_AUDIO)
+ continue;
+
+ if (speed > max_raw) {
+ errmsgno(EX_BAD,
+ "Processor too slow. Cannot write RAW data at speed %d.\n",
+ speed);
+ comerrno(EX_BAD, "Max RAW data speed on this processor is %d.\n",
+ max_raw);
+ }
+ break;
+ }
+ }
+ if (tracks > 0 && (flags & F_WRITE) != 0 && dma_speed > 0) {
+ int max_dma = (flags & F_FORCE) != 0 ? dma_speed:(dma_speed+1)*4/5;
+
+ if (getenv("CDR_FORCESPEED"))
+ max_dma = dma_speed;
+
+ if (speed > max_dma) {
+ errmsgno(EX_BAD,
+ "DMA speed too slow (OK for %dx). Cannot write at speed %dx.\n",
+ max_dma, speed);
+ if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
+ errmsgno(EX_BAD, "Max DMA data speed is %d.\n", max_dma);
+ comerrno(EX_BAD, "Try to use 'driveropts=burnfree'.\n");
+ }
+ }
+ }
+ if ((flags & (F_WRITE|F_BLANK)) != 0 &&
+ (dp->cdr_dstat->ds_flags & DSF_ERA) != 0) {
+ if (xdebug) {
+ printf("Current speed %d, medium low speed: %d medium high speed: %d\n",
+ speed,
+ dp->cdr_dstat->ds_at_min_speed,
+ dp->cdr_dstat->ds_at_max_speed);
+ }
+ if (dp->cdr_dstat->ds_at_max_speed > 0 &&
+ speed <= 8 &&
+ speed > (int)dp->cdr_dstat->ds_at_max_speed) {
+ /*
+ * Be careful here: 10x media may be written faster.
+ * The current code will work as long as there is no
+ * writer that can only write faster than 8x
+ */
+ if ((flags & F_FORCE) == 0) {
+ errmsgno(EX_BAD,
+ "Write speed %d of medium not sufficient for this writer.\n",
+ dp->cdr_dstat->ds_at_max_speed);
+ comerrno(EX_BAD,
+ "You may have used an ultra low speed medium on a high speed writer.\n");
+ }
+ }
+
+ if ((dp->cdr_dstat->ds_flags & DSF_ULTRASPP_ERA) != 0 &&
+ (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0)) {
+ if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0) {
+ comerrno(EX_BAD,
+ "Trying to use ultra high speed+ medium on a writer which is not\ncompatible with ultra high speed+ media.\n");
+ } else if ((flags & F_FORCE) == 0) {
+ comerrno(EX_BAD,
+ "Probably trying to use ultra high speed+ medium on improper writer.\n");
+ }
+ } else if ((dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA) != 0 &&
+ (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0)) {
+ if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0) {
+ comerrno(EX_BAD,
+ "Trying to use ultra high speed medium on a writer which is not\ncompatible with ultra high speed media.\n");
+ } else if ((flags & F_FORCE) == 0) {
+ comerrno(EX_BAD,
+ "Probably trying to use ultra high speed medium on improper writer.\n");
+ }
+ }
+ if (dp->cdr_dstat->ds_at_min_speed >= 4 &&
+ dp->cdr_dstat->ds_at_max_speed > 4 &&
+ dp->cdr_dstat->ds_dr_max_wspeed <= 4) {
+ if ((flags & F_FORCE) == 0) {
+ comerrno(EX_BAD,
+ "Trying to use high speed medium on low speed writer.\n");
+ }
+ }
+ if ((int)dp->cdr_dstat->ds_at_min_speed > speed) {
+ if ((flags & F_FORCE) == 0) {
+ errmsgno(EX_BAD,
+ "Write speed %d of writer not sufficient for this medium.\n",
+ speed);
+ errmsgno(EX_BAD,
+ "You did use a %s speed medium on an improper writer or\n",
+ dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA ?
+ "ultra high": "high");
+ comerrno(EX_BAD,
+ "you used a speed=# option with a speed too low for this medium.\n");
+ }
+ }
+ }
+ if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) {
+ printf("Waiting for drive to calm down.\n");
+ wait_unit_ready(scgp, 120);
+ if (gracewait(dp, &gracedone) < 0) {
+ /*
+ * In case kill() did not work ;-)
+ */
+ errs++;
+ goto restore_it;
+ }
+ scsi_blank(scgp, 0L, blanktype, FALSE);
+ }
+
+ /*
+ * Last chance to quit!
+ */
+ if (gracewait(dp, &gracedone) < 0) {
+ /*
+ * In case kill() did not work ;-)
+ */
+ errs++;
+ goto restore_it;
+ }
+
+ if (dp->profile == 0x2B && flags & F_SAO && tsize > 0) {
+ printf("Preparing middle zone location for this DVD+R dual layer disc\n");
+ if (!dp->cdr_layer_split(scgp, dp, tsize)) {
+ errmsgno(EX_BAD, "Cannot send structure for middle zone location.\n");
+ comexit(EX_BAD);
+ }
+ }
+
+ if (tracks > 0 && fs > 0l) {
+ /*
+ * Wait for the read-buffer to become full.
+ * This should be take no extra time if the input is a file.
+ * If the input is a pipe (e.g. mkisofs) this can take a
+ * while. If mkisofs dumps core before it starts writing,
+ * we abort before the writing process started.
+ */
+ if (!await_faio()) {
+ comerrno(EX_BAD, "Input buffer error, aborting.\n");
+ }
+ }
+ wait_unit_ready(scgp, 120);
+
+ starttime.tv_sec = 0;
+ wstarttime.tv_sec = 0;
+ stoptime.tv_sec = 0;
+ fixtime.tv_sec = 0;
+ if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+ errmsg("Cannot get start time\n");
+
+ /*
+ * Blank the media if we were requested to do so
+ */
+ if (flags & F_BLANK) {
+ /*
+ * Do not abort if OPC failes. Just give it a chance
+ * for better laser power calibration than without OPC.
+ *
+ * Ricoh drives return with a vendor unique sense code.
+ * This is most likely because they refuse to do OPC
+ * on a non blank media.
+ */
+ scgp->silent++;
+ do_opc(scgp, dp, flags);
+ scgp->silent--;
+ wait_unit_ready(scgp, 120);
+ if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+ errmsg("Cannot get start time\n");
+
+ if ((*dp->cdr_blank)(scgp, dp, 0L, blanktype) < 0) {
+ errmsgno(EX_BAD, "Cannot blank disk, aborting.\n");
+ if (blanktype != BLANK_DISC) {
+ errmsgno(EX_BAD, "Some drives do not support all blank types.\n");
+ errmsgno(EX_BAD, "Try again with wodim blank=all.\n");
+ }
+ comexit(EX_BAD);
+ }
+ if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
+ errmsg("Cannot get blank time\n");
+ if (lverbose)
+ prtimediff("Blanking time: ", &starttime, &fixtime);
+
+ /*
+ * XXX Erst blank und dann format?
+ * XXX Wenn ja, dann hier (flags & F_FORMAT) testen
+ */
+ if (!wait_unit_ready(scgp, 240) || tracks == 0) {
+ comexit(0);
+ }
+ if (flags & F_FORMAT) {
+ printf("wodim: media format asked\n");
+ /*
+ * Do not abort if OPC failes. Just give it a chance
+ * for better laser power calibration than without OPC.
+ *
+ * Ricoh drives return with a vendor unique sense code.
+ * This is most likely because they refuse to do OPC
+ * on a non blank media.
+ */
+ scgp->silent++;
+ do_opc(scgp, dp, flags);
+ scgp->silent--;
+ wait_unit_ready(scgp, 120);
+ if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+ errmsg("Cannot get start time\n");
+
+ if ((*dp->cdr_format)(scgp, dp, formattype) < 0) {
+ errmsgno(EX_BAD, "Cannot format disk, aborting.\n");
+ comexit(EX_BAD);
+ }
+ if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
+ errmsg("Cannot get format time\n");
+ if (lverbose)
+ prtimediff("Formatting time: ", &starttime, &fixtime);
+
+ if (!wait_unit_ready(scgp, 240) || tracks == 0) {
+ comexit(0);
+ }
+ if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+ errmsg("Cannot get start time\n");
+ }
+ /*
+ * Reset start time so we will not see blanking time and
+ * writing time counted together.
+ */
+ if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+ errmsg("Cannot get start time\n");
+ }
+ if (tracks == 0 && (flags & F_FIX) == 0)
+ comerrno(EX_BAD, "No tracks found.\n");
+ /*
+ * Get the number of the next recordable track by reading the TOC and
+ * use the number the last current track number.
+ */
+ scgp->silent++;
+ if (read_tochdr(scgp, dp, NULL, &trackno) < 0) {
+ trackno = 0;
+ }
+ scgp->silent--;
+
+ /* If it is DVD, the information in TOC is fabricated :)
+ The real information is from read disk info command*/
+ if((dp->cdr_dstat->ds_disktype&DT_DVD) && (dp->cdr_dstat->ds_trlast>0)){
+ trackno=dp->cdr_dstat->ds_trlast-1;
+ if (lverbose > 2)
+ printf("trackno=%d\n",trackno);
+ }
+
+ if ((tracks + trackno) > MAX_TRACK) {
+ /*
+ * XXX How many tracks are allowed on a DVD?
+ */
+ comerrno(EX_BAD, "Too many tracks for this disk, last track number is %d.\n",
+ tracks + trackno);
+ }
+
+ for (i = 0; i <= tracks+1; i++) { /* Lead-in ... Lead-out */
+ track[i].trackno = i + trackno; /* Set up real track # */
+ }
+
+ if ((*dp->cdr_opt2)(scgp, dp) < 0) {
+ errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n");
+ }
+
+ /*
+ * Now we actually start writing to the CD/DVD.
+ * XXX Check total size of the tracks and remaining size of disk.
+ */
+ if ((*dp->cdr_open_session)(scgp, dp, track) < 0) {
+ comerrno(EX_BAD, "Cannot open new session.\n");
+ }
+ if (!do_opc(scgp, dp, flags))
+ comexit(EX_BAD);
+
+ /*
+ * As long as open_session() will do nothing but
+ * set up parameters, we may leave fix_it here.
+ * I case we have to add an open_session() for a drive
+ * that wants to do something that modifies the disk
+ * We have to think about a new solution.
+ */
+ if (flags & F_FIX)
+ goto fix_it;
+
+ /*
+ * This call may modify trackp[i].trackstart for all tracks.
+ */
+ if ((*dp->cdr_write_leadin)(scgp, dp, track) < 0)
+ comerrno(EX_BAD, "Could not write Lead-in.\n");
+
+ if (lverbose && (dp->cdr_dstat->ds_cdrflags & RF_LEADIN) != 0) {
+
+ if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
+ errmsg("Cannot get lead-in write time\n");
+ prtimediff("Lead-in write time: ", &starttime, &fixtime);
+ }
+
+ if (gettimeofday(&wstarttime, (struct timezone *)0) < 0)
+ errmsg("Cannot get start time\n");
+ for (i = 1; i <= tracks; i++) {
+ startsec = 0L;
+
+ if ((*dp->cdr_open_track)(scgp, dp, &track[i]) < 0) {
+ errmsgno(EX_BAD, "Cannot open next track.\n");
+ errs++;
+ break;
+ }
+
+ if ((flags & (F_SAO|F_RAW)) == 0) {
+ if ((*dp->cdr_next_wr_address)(scgp, &track[i], &startsec) < 0) {
+ errmsgno(EX_BAD, "Cannot get next writable address.\n");
+ errs++;
+ break;
+ }
+ track[i].trackstart = startsec;
+ }
+ if (debug || lverbose) {
+ printf("Starting new track at sector: %ld\n",
+ track[i].trackstart);
+ flush();
+ }
+ if (write_track_data(scgp, dp, &track[i]) < 0) {
+ if (cdr_underrun(scgp)) {
+ errmsgno(EX_BAD,
+ "The current problem looks like a buffer underrun.\n");
+ if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
+ errmsgno(EX_BAD,
+ "Try to use 'driveropts=burnfree'.\n");
+ else {
+ errmsgno(EX_BAD,
+ "It looks like 'driveropts=burnfree' does not work for this drive.\n");
+ errmsgno(EX_BAD, "Please report.\n");
+ }
+
+ errmsgno(EX_BAD,
+ "Make sure that you are root, enable DMA and check your HW/OS set up.\n");
+ } else {
+ errmsgno(EX_BAD, "A write error occured.\n");
+ errmsgno(EX_BAD, "Please properly read the error message above.\n");
+ }
+ errs++;
+ sleep(5);
+ unit_ready(scgp);
+ (*dp->cdr_close_track)(scgp, dp, &track[i]);
+ break;
+ }
+ if ((*dp->cdr_close_track)(scgp, dp, &track[i]) < 0) {
+ /*
+ * Check for "Dummy blocks added" message first.
+ */
+ if (scg_sense_key(scgp) != SC_ILLEGAL_REQUEST ||
+ scg_sense_code(scgp) != 0xB5) {
+ errmsgno(EX_BAD, "Cannot close track.\n");
+ errs++;
+ break;
+ }
+ }
+ }
+fix_it:
+ if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
+ errmsg("Cannot get stop time\n");
+ cdrstats(dp);
+
+ if (flags & F_RAW) {
+ if (lverbose) {
+ printf("Writing Leadout...\n");
+ flush();
+ }
+ write_leadout(scgp, dp, track);
+ }
+ if ((flags & F_NOFIX) == 0) {
+ if (lverbose) {
+ printf("Fixating...\n");
+ flush();
+ }
+ if ((*dp->cdr_fixate)(scgp, dp, track) < 0) {
+ /*
+ * Ignore fixating errors in dummy mode.
+ */
+ if ((flags & F_DUMMY) == 0) {
+ errmsgno(EX_BAD, "Cannot fixate disk.\n");
+ errs++;
+ }
+ }
+ if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
+ errmsg("Cannot get fix time\n");
+ if (lverbose)
+ prtimediff("Fixating time: ", &stoptime, &fixtime);
+ }
+ if ((dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) {
+ dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT;
+ (*dp->cdr_stats)(scgp, dp);
+ }
+ if ((flags & (F_RAW|F_EJECT)) == F_RAW) {
+ /*
+ * Most drives seem to forget to reread the TOC from disk
+ * if they are in RAW mode.
+ */
+ scgp->silent++;
+ if (read_tochdr(scgp, dp, NULL, NULL) < 0) {
+ scgp->silent--;
+ if ((flags & F_DUMMY) == 0)
+ reload_media(scgp, dp);
+ } else {
+ scgp->silent--;
+ }
+ }
+
+restore_it:
+ /*
+ * Try to restore the old sector size and stop FIFO.
+ */
+ kill_faio();
+ comexit(errs?-2:0);
+ return (0);
+}
+
+static int
+gracewait(cdr_t *dp, BOOL *didgracep)
+{
+ int i;
+ BOOL didgrace = FALSE;
+
+ if (didgracep)
+ didgrace = *didgracep;
+
+ if (gracetime < MIN_GRACE_TIME)
+ gracetime = MIN_GRACE_TIME;
+ if (gracetime > 999)
+ gracetime = 999;
+
+ printf("Starting to write CD/DVD at speed %5.1f in %s%s %s mode for %s session.\n",
+ (float)dp->cdr_dstat->ds_wspeed,
+ (dp->cdr_cmdflags & F_DUMMY) ? "dummy" : "real",
+ (dp->cdr_cmdflags & F_FORCE) ? " force" : "",
+ wm2name[dp->cdr_dstat->ds_wrmode],
+ (dp->cdr_cmdflags & F_MULTI) ? "multi" : "single");
+ if (didgrace) {
+ printf("No chance to quit anymore.");
+ goto grace_done;
+ }
+ printf("Last chance to quit, starting %s write in %d seconds.",
+ (dp->cdr_cmdflags & F_DUMMY)?"dummy":"real", gracetime);
+ flush();
+ signal(SIGINT, intr);
+ signal(SIGHUP, intr);
+ signal(SIGTERM, intr);
+
+ for (i = gracetime; --i >= 0; ) {
+ sleep(1);
+ if (didintr) {
+ printf("\n");
+ excdr(SIGINT, &exargs);
+ signal(SIGINT, SIG_DFL);
+ kill(getpid(), SIGINT);
+ /*
+ * In case kill() did not work ;-)
+ */
+ if (didgracep)
+ *didgracep = FALSE;
+ return (-1);
+ }
+ printf("\b\b\b\b\b\b\b\b\b\b\b\b\b%4d seconds.", i);
+ flush();
+ }
+grace_done:
+ printf(" Operation starts.");
+ flush();
+ signal(SIGINT, SIG_DFL);
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGINT, intfifo);
+ signal(SIGHUP, intfifo);
+ signal(SIGTERM, intfifo);
+ printf("\n");
+
+ if (didgracep)
+ *didgracep = TRUE;
+ return (0);
+}
+
+static void
+cdrstats(cdr_t *dp)
+{
+ float secsps = 75.0;
+ int nsecs;
+ float fspeed;
+ struct timeval tcur;
+ struct timeval tlast;
+ BOOL nostop = FALSE;
+
+ if (starttime.tv_sec == 0)
+ return;
+
+ if (stoptime.tv_sec == 0) {
+ gettimeofday(&stoptime, (struct timezone *)0);
+ nostop = TRUE;
+ }
+
+ if ((dp->cdr_dstat->ds_cdrflags & RF_DID_STAT) != 0)
+ return;
+ dp->cdr_dstat->ds_cdrflags |= RF_DID_STAT;
+
+ if (lverbose == 0)
+ return;
+
+ if (dp->cdr_cmdflags & F_FIX)
+ return;
+
+ if ((dp->cdr_cmdflags & (F_WRITE|F_BLANK)) == F_BLANK)
+ return;
+
+ tlast = wstarttime;
+ tcur = stoptime;
+
+ prtimediff("Writing time: ", &starttime, &stoptime);
+
+ nsecs = dp->cdr_dstat->ds_endsec - dp->cdr_dstat->ds_startsec;
+
+ if (dp->cdr_dstat->ds_flags & DSF_DVD)
+ secsps = 676.27;
+
+ tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
+ tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
+ while (tlast.tv_usec < 0) {
+ tlast.tv_usec += 1000000;
+ tlast.tv_sec -= 1;
+ }
+ if (!nostop && nsecs != 0 && dp->cdr_dstat->ds_endsec > 0) {
+ /*
+ * May not be known (e.g. cdrecord -)
+ *
+ * XXX if we later allow this code to know how much has
+ * XXX actually been written, then we may remove the
+ * XXX dependance from nostop & nsecs != 0
+ */
+ fspeed = (nsecs / secsps) /
+ (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
+ if (fspeed > 999.0)
+ fspeed = 999.0;
+ if (dp->is_dvd) fspeed /= 9;
+ printf("Average write speed %5.1fx.\n", fspeed);
+ }
+
+ if (dp->cdr_dstat->ds_minbuf <= 100) {
+ printf("Min drive buffer fill was %u%%\n",
+ (unsigned int)dp->cdr_dstat->ds_minbuf);
+ }
+ if (dp->cdr_dstat->ds_buflow > 0) {
+ printf("Total of %ld possible drive buffer underruns predicted.\n",
+ (long)dp->cdr_dstat->ds_buflow);
+ }
+}
+
+/*
+ * Short usage
+ */
+static void
+susage(int ret)
+{
+ fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname());
+ fprintf(stderr, "\nUse\t%s -help\n", get_progname());
+ fprintf(stderr, "to get a list of valid options.\n");
+ fprintf(stderr, "\nUse\t%s blank=help\n", get_progname());
+ fprintf(stderr, "to get a list of valid blanking options.\n");
+ fprintf(stderr, "\nUse\t%s dev=b,t,l driveropts=help -checkdrive\n", get_progname());
+ fprintf(stderr, "to get a list of drive specific options.\n");
+ fprintf(stderr, "\nUse\t%s dev=help\n", get_progname());
+ fprintf(stderr, "to get a list of possible SCSI transport specifiers.\n");
+ exit(ret);
+ /* NOTREACHED */
+}
+
+static void
+usage(int excode)
+{
+ fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname());
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, "\t-version print version information and exit\n");
+ fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n");
+ fprintf(stderr, "\tgracetime=# set the grace time before starting to write to #.\n");
+ fprintf(stderr, "\ttimeout=# set the default SCSI command timeout to #.\n");
+ fprintf(stderr, "\tdebug=#,-d Set to # or increment misc debug level\n");
+ fprintf(stderr, "\tkdebug=#,kd=# do Kernel debugging\n");
+ fprintf(stderr, "\t-verbose,-v increment general verbose level by one\n");
+ fprintf(stderr, "\t-Verbose,-V increment SCSI command transport verbose level by one\n");
+ fprintf(stderr, "\t-silent,-s do not print status of failed SCSI commands\n");
+ fprintf(stderr, "\tdriver=name user supplied driver name, use with extreme care\n");
+ fprintf(stderr, "\tdriveropts=opt a comma separated list of driver specific options\n");
+ fprintf(stderr, "\t-setdropts set driver specific options and exit\n");
+ fprintf(stderr, "\t-checkdrive check if a driver for the drive is present\n");
+ fprintf(stderr, "\t-prcap print drive capabilities for MMC compliant drives\n");
+ fprintf(stderr, "\t-inq do an inquiry for the drive and exit\n");
+ fprintf(stderr, "\t-scanbus scan the SCSI and IDE buses and exit\n");
+ fprintf(stderr, "\t-reset reset the SCSI bus with the cdrecorder (if possible)\n");
+ fprintf(stderr, "\t-abort send an abort sequence to the drive (may help if hung)\n");
+ fprintf(stderr, "\t-overburn allow to write more than the official size of a medium\n");
+ fprintf(stderr, "\t-ignsize ignore the known size of a medium (may cause problems)\n");
+ fprintf(stderr, "\t-useinfo use *.inf files to overwrite audio options.\n");
+ fprintf(stderr, "\tspeed=# set speed of drive\n");
+ fprintf(stderr, "\tblank=type blank a CD-RW disc (see blank=help)\n");
+ fprintf(stderr, "\t-format format a CD-RW/DVD-RW/DVD+RW disc\n");
+ fprintf(stderr, "\tformattype=# select the format method for DVD+RW disc\n");
+#ifdef FIFO
+ fprintf(stderr, "\tfs=# Set fifo size to # (0 to disable, default is %ld MB)\n",
+ DEFAULT_FIFOSIZE/(1024L*1024L));
+#endif
+ fprintf(stderr, "\tts=# set maximum transfer size for a single SCSI command\n");
+ fprintf(stderr, "\t-load load the disk and exit (works only with tray loader)\n");
+ fprintf(stderr, "\t-lock load and lock the disk and exit (works only with tray loader)\n");
+ fprintf(stderr, "\t-eject eject the disk after doing the work\n");
+ fprintf(stderr, "\t-dummy do everything with laser turned off\n");
+ fprintf(stderr, "\t-msinfo retrieve multi-session info for mkisofs >= 1.10\n");
+ fprintf(stderr, "\t-toc retrieve and print TOC/PMA data\n");
+ fprintf(stderr, "\t-atip retrieve and print ATIP data\n");
+ fprintf(stderr, "\t-multi generate a TOC that allows multi session\n");
+ fprintf(stderr, "\t In this case default track type is CD-ROM XA mode 2 form 1 - 2048 bytes\n");
+ fprintf(stderr, "\t-fix fixate a corrupt or unfixated disk (generate a TOC)\n");
+ fprintf(stderr, "\t-nofix do not fixate disk after writing tracks\n");
+ fprintf(stderr, "\t-waiti wait until input is available before opening SCSI\n");
+ fprintf(stderr, "\t-immed Try to use the SCSI IMMED flag with certain long lasting commands\n");
+ fprintf(stderr, "\t-force force to continue on some errors to allow blanking bad disks\n");
+ fprintf(stderr, "\t-tao Write disk in TAO mode. This option will be replaced in the future.\n");
+ fprintf(stderr, "\t-dao Write disk in SAO mode. This option will be replaced in the future.\n");
+ fprintf(stderr, "\t-sao Write disk in SAO mode. This option will be replaced in the future.\n");
+ fprintf(stderr, "\t-raw Write disk in RAW mode. This option will be replaced in the future.\n");
+ fprintf(stderr, "\t-raw96r Write disk in RAW/RAW96R mode. This option will be replaced in the future.\n");
+ fprintf(stderr, "\t-raw96p Write disk in RAW/RAW96P mode. This option will be replaced in the future.\n");
+ fprintf(stderr, "\t-raw16 Write disk in RAW/RAW16 mode. This option will be replaced in the future.\n");
+#ifdef CLONE_WRITE
+ fprintf(stderr, "\t-clone Write disk in clone write mode.\n");
+#endif
+ fprintf(stderr, "\ttsize=# Length of valid data in next track\n");
+ fprintf(stderr, "\tpadsize=# Amount of padding for next track\n");
+ fprintf(stderr, "\tpregap=# Amount of pre-gap sectors before next track\n");
+ fprintf(stderr, "\tdefpregap=# Amount of pre-gap sectors for all but track #1\n");
+ fprintf(stderr, "\tmcn=text Set the media catalog number for this CD to 'text'\n");
+ fprintf(stderr, "\tisrc=text Set the ISRC number for the next track to 'text'\n");
+ fprintf(stderr, "\tindex=list Set the index list for the next track to 'list'\n");
+ fprintf(stderr, "\t-text Write CD-Text from information from *.inf or *.cue files\n");
+ fprintf(stderr, "\ttextfile=name Set the file with CD-Text data to 'name'\n");
+ fprintf(stderr, "\tcuefile=name Set the file with CDRWIN CUE data to 'name'\n");
+
+ fprintf(stderr, "\t-audio Subsequent tracks are CD-DA audio tracks\n");
+ fprintf(stderr, "\t-data Subsequent tracks are CD-ROM data mode 1 - 2048 bytes (default)\n");
+ fprintf(stderr, "\t-mode2 Subsequent tracks are CD-ROM data mode 2 - 2336 bytes\n");
+ fprintf(stderr, "\t-xa Subsequent tracks are CD-ROM XA mode 2 form 1 - 2048 bytes\n");
+ fprintf(stderr, "\t-xa1 Subsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n");
+ fprintf(stderr, "\t-xa2 Subsequent tracks are CD-ROM XA mode 2 form 2 - 2324 bytes\n");
+ fprintf(stderr, "\t-xamix Subsequent tracks are CD-ROM XA mode 2 form 1/2 - 2332 bytes\n");
+ fprintf(stderr, "\t-cdi Subsequent tracks are CDI tracks\n");
+ fprintf(stderr, "\t-isosize Use iso9660 file system size for next data track\n");
+ fprintf(stderr, "\t-preemp Audio tracks are mastered with 50/15 µs preemphasis\n");
+ fprintf(stderr, "\t-nopreemp Audio tracks are mastered with no preemphasis (default)\n");
+ fprintf(stderr, "\t-copy Audio tracks have unlimited copy permission\n");
+ fprintf(stderr, "\t-nocopy Audio tracks may only be copied once for personal use (default)\n");
+ fprintf(stderr, "\t-scms Audio tracks will not have any copy permission at all\n");
+ fprintf(stderr, "\t-pad Pad data tracks with %d zeroed sectors\n", PAD_SECS);
+ fprintf(stderr, "\t Pad audio tracks to a multiple of %d bytes\n", AUDIO_SEC_SIZE);
+ fprintf(stderr, "\t-nopad Do not pad data tracks (default)\n");
+ fprintf(stderr, "\t-shorttrack Subsequent tracks may be non Red Book < 4 seconds if in SAO or RAW mode\n");
+ fprintf(stderr, "\t-noshorttrack Subsequent tracks must be >= 4 seconds\n");
+ fprintf(stderr, "\t-swab Audio data source is byte-swapped (little-endian/Intel)\n");
+ fprintf(stderr, "The type of the first track is used for the toc type.\n");
+ fprintf(stderr, "Currently only form 1 tracks are supported.\n");
+ exit(excode);
+}
+
+static void
+blusage(int ret)
+{
+ fprintf(stderr, "Blanking options:\n");
+ fprintf(stderr, "\tall\t\tblank the entire disk\n");
+ fprintf(stderr, "\tdisc\t\tblank the entire disk\n");
+ fprintf(stderr, "\tdisk\t\tblank the entire disk\n");
+ fprintf(stderr, "\tfast\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
+ fprintf(stderr, "\tminimal\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");
+ fprintf(stderr, "\ttrack\t\tblank a track\n");
+ fprintf(stderr, "\tunreserve\tunreserve a track\n");
+ fprintf(stderr, "\ttrtail\t\tblank a track tail\n");
+ fprintf(stderr, "\tunclose\t\tunclose last session\n");
+ fprintf(stderr, "\tsession\t\tblank last session\n");
+
+ exit(ret);
+ /* NOTREACHED */
+}
+
+static void
+formattypeusage(int ret)
+{
+ fprintf(stderr, "Formating options:\n");
+ fprintf(stderr, "\tfull\t\tstandard formating\n");
+ fprintf(stderr, "\tbackground\t\tbackground formating\n");
+ fprintf(stderr, "\tforce\t\tforce reformat\n");
+
+ exit(ret);
+ /* NOTREACHED */
+}
+
+/* ARGSUSED */
+static void
+intr(int sig)
+{
+ sig = 0; /* Fake usage for gcc */
+
+ signal(SIGINT, intr);
+
+ didintr++;
+}
+
+static void
+catchsig(int sig)
+{
+ signal(sig, catchsig);
+}
+
+static int
+scsi_cb(void *arg)
+{
+ comexit(EX_BAD);
+ /* NOTREACHED */
+ return (0); /* Keep lint happy */
+}
+
+static void
+intfifo(int sig)
+{
+ errmsgno(EX_BAD, "Caught interrupt.\n");
+ if (exargs.scgp) {
+ SCSI *scgp = exargs.scgp;
+
+ if (scgp->running) {
+ if (scgp->cb_fun != NULL) {
+ comerrno(EX_BAD, "Second interrupt. Doing hard abort.\n");
+ /* NOTREACHED */
+ }
+ scgp->cb_fun = scsi_cb;
+ scgp->cb_arg = &exargs;
+ return;
+ }
+ }
+ comexit(sig);
+}
+
+/* ARGSUSED */
+static void
+exscsi(int excode, void *arg)
+{
+ struct exargs *exp = (struct exargs *)arg;
+
+ /*
+ * Try to restore the old sector size.
+ */
+ if (exp != NULL && exp->exflags == 0) {
+ if (exp->scgp->running) {
+ return;
+ }
+ /*
+ * flush cache is not supported by CD-ROMs avoid prob with -toc
+ */
+ exp->scgp->silent++;
+ scsi_flush_cache(exp->scgp, FALSE);
+ (*exp->dp->cdr_abort_session)(exp->scgp, exp->dp);
+ exp->scgp->silent--;
+ set_secsize(exp->scgp, exp->old_secsize);
+ unload_media(exp->scgp, exp->dp, exp->flags);
+
+ exp->exflags++; /* Make sure that it only get called once */
+ }
+}
+
+static void
+excdr(int excode, void *arg)
+{
+ struct exargs *exp = (struct exargs *)arg;
+
+ exscsi(excode, arg);
+
+ cdrstats(exp->dp);
+ if ((exp->dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) {
+ exp->dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT;
+ (*exp->dp->cdr_stats)(exp->scgp, exp->dp);
+ }
+
+#ifdef FIFO
+ kill_faio();
+ wait_faio();
+ if (debug || lverbose)
+ fifo_stats();
+#endif
+}
+
+int
+read_buf(int f, char *bp, int size)
+{
+ char *p = bp;
+ int amount = 0;
+ int n;
+
+ do {
+ do {
+ n = read(f, p, size-amount);
+ } while (n < 0 && (geterrno() == EAGAIN || geterrno() == EINTR));
+ if (n < 0)
+ return (n);
+ amount += n;
+ p += n;
+
+ } while (amount < size && n > 0);
+ return (amount);
+}
+
+int
+fill_buf(int f, track_t *trackp, long secno, char *bp, int size)
+{
+ int amount = 0;
+ int nsecs;
+ int rsize;
+ int rmod;
+ int readoffset = 0;
+
+ nsecs = size / trackp->secsize;
+ if (nsecs < trackp->secspt) {
+ /*
+ * Clear buffer to prepare for last transfer.
+ * Make sure that a partial sector ends with NULs
+ */
+ fillbytes(bp, trackp->secspt * trackp->secsize, '\0');
+ }
+
+ if (!is_raw(trackp)) {
+ amount = read_buf(f, bp, size);
+ if (amount != size) {
+ if (amount < 0)
+ return (amount);
+ /*
+ * We got less than expected, clear rest of buf.
+ */
+ fillbytes(&bp[amount], size-amount, '\0');
+ }
+ if (is_swab(trackp))
+ swabbytes(bp, amount);
+ return (amount);
+ }
+
+ rsize = nsecs * trackp->isecsize;
+ rmod = size % trackp->secsize;
+ if (rmod > 0) {
+ rsize += rmod;
+ nsecs++;
+ }
+
+ readoffset = trackp->dataoff;
+ amount = read_buf(f, bp + readoffset, rsize);
+ if (is_swab(trackp))
+ swabbytes(bp + readoffset, amount);
+
+ if (trackp->isecsize == 2448 && trackp->secsize == 2368)
+ subrecodesecs(trackp, (Uchar *)bp, secno, nsecs);
+
+ scatter_secs(trackp, bp + readoffset, nsecs);
+
+ if (amount != rsize) {
+ if (amount < 0)
+ return (amount);
+ /*
+ * We got less than expected, clear rest of buf.
+ */
+ fillbytes(&bp[amount], rsize-amount, '\0');
+ nsecs = amount / trackp->isecsize;
+ rmod = amount % trackp->isecsize;
+ amount = nsecs * trackp->secsize;
+ if (rmod > 0) {
+ nsecs++;
+ amount += rmod;
+ }
+ } else {
+ amount = size;
+ }
+ if ((trackp->sectype & ST_MODE_RAW) == 0) {
+ encsectors(trackp, (Uchar *)bp, secno, nsecs);
+ fillsubch(trackp, (Uchar *)bp, secno, nsecs);
+ } else {
+ scrsectors(trackp, (Uchar *)bp, secno, nsecs);
+ }
+ return (amount);
+}
+
+int
+get_buf(int f, track_t *trackp, long secno, char **bpp, int size)
+{
+ if (fs > 0) {
+/* return (faio_read_buf(f, *bpp, size));*/
+ return (faio_get_buf(f, bpp, size));
+ } else {
+ return (fill_buf(f, trackp, secno, *bpp, size));
+ }
+}
+
+int
+write_secs(SCSI *scgp, cdr_t *dp, char *bp, long startsec, int bytespt,
+ int secspt, BOOL islast)
+{
+ int amount;
+
+again:
+ scgp->silent++;
+ amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
+ scgp->silent--;
+ if (amount < 0) {
+ if (scsi_in_progress(scgp)) {
+ /*
+ * If we sleep too long, the drive buffer is empty
+ * before we start filling it again. The max. CD speed
+ * is ~ 10 MB/s (52x RAW writing). The max. DVD speed
+ * is ~ 25 MB/s (18x DVD 1385 kB/s).
+ * With 10 MB/s, a 1 MB buffer empties within 100ms.
+ * With 25 MB/s, a 1 MB buffer empties within 40ms.
+ */
+ if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0) {
+ usleep(60000);
+ } else {
+#ifndef _SC_CLK_TCK
+ usleep(20000);
+#else
+ if (sysconf(_SC_CLK_TCK) < 100)
+ usleep(20000);
+ else
+ usleep(10000);
+
+#endif
+ }
+ goto again;
+ }
+ return (-1);
+ }
+ return (amount);
+}
+
+static int
+write_track_data(SCSI *scgp, cdr_t *dp, track_t *trackp)
+{
+ int track = trackp->trackno;
+ int f = -1;
+ int isaudio;
+ long startsec;
+ Llong bytes_read = 0;
+ Llong bytes = 0;
+ Llong savbytes = 0;
+ int count;
+ Llong tracksize;
+ int secsize;
+ int secspt;
+ int bytespt;
+ int bytes_to_read;
+ long amount;
+ int pad;
+ BOOL neednl = FALSE;
+ BOOL islast = FALSE;
+ char *bp = buf;
+ struct timeval tlast;
+ struct timeval tcur;
+ float secsps = 75.0;
+long bsize;
+long bfree;
+#define BCAP
+#ifdef BCAP
+int per = 0;
+#ifdef XBCAP
+int oper = -1;
+#endif
+#endif
+
+ if (dp->cdr_dstat->ds_flags & DSF_DVD)
+ secsps = 676.27;
+
+ scgp->silent++;
+ if ((*dp->cdr_buffer_cap)(scgp, &bsize, &bfree) < 0)
+ bsize = -1L;
+ if (bsize == 0) /* If we have no (known) buffer, we cannot */
+ bsize = -1L; /* retrieve the buffer fill ratio */
+ scgp->silent--;
+
+
+ if (is_packet(trackp)) /* XXX Ugly hack for now */
+ return (write_packet_data(scgp, dp, trackp));
+
+ if (trackp->xfp != NULL)
+ f = xfileno(trackp->xfp);
+
+ isaudio = is_audio(trackp);
+ tracksize = trackp->tracksize;
+ startsec = trackp->trackstart;
+
+ secsize = trackp->secsize;
+ secspt = trackp->secspt;
+ bytespt = secsize * secspt;
+
+ pad = !isaudio && is_pad(trackp); /* Pad only data tracks */
+
+ if (debug) {
+ printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n",
+ secsize, secspt, bytespt, isaudio, pad);
+ }
+
+ if (lverbose) {
+ if (tracksize > 0)
+ printf("\rTrack %02d: 0 of %4lld MB written.",
+ track, tracksize >> 20);
+ else
+ printf("\rTrack %02d: 0 MB written.", track);
+ flush();
+ neednl = TRUE;
+ }
+
+ gettimeofday(&tlast, (struct timezone *)0);
+ do {
+ bytes_to_read = bytespt;
+ if (tracksize > 0) {
+ if ((tracksize - bytes_read) > bytespt)
+ bytes_to_read = bytespt;
+ else
+ bytes_to_read = tracksize - bytes_read;
+ }
+ count = get_buf(f, trackp, startsec, &bp, bytes_to_read);
+
+ if (count < 0)
+ comerr("read error on input file\n");
+ if (count == 0)
+ break;
+ bytes_read += count;
+ if (tracksize >= 0 && bytes_read >= tracksize) {
+ count -= bytes_read - tracksize;
+ /*
+ * Paranoia: tracksize is known (trackp->tracksize >= 0)
+ * At this point, trackp->padsize should alway be set
+ * if the tracksize is less than 300 sectors.
+ */
+ if (trackp->padsecs == 0 &&
+ (is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
+ islast = TRUE;
+ }
+
+ if (count < bytespt) {
+ if (debug) {
+ printf("\nNOTICE: reducing block size for last record.\n");
+ neednl = FALSE;
+ }
+
+ if ((amount = count % secsize) != 0) {
+ amount = secsize - amount;
+ count += amount;
+ printf("\nWARNING: padding up to secsize.\n");
+ neednl = FALSE;
+ }
+ bytespt = count;
+ secspt = count / secsize;
+ /*
+ * If tracksize is not known (trackp->tracksize < 0)
+ * we may need to set trackp->padsize
+ * if the tracksize is less than 300 sectors.
+ */
+ if (trackp->padsecs == 0 &&
+ (is_shorttrk(trackp) || (bytes_read/secsize) >= 300))
+ islast = TRUE;
+ }
+
+ amount = write_secs(scgp, dp, bp, startsec, bytespt, secspt, islast);
+ if (amount < 0) {
+ printf("%swrite track data: error after %lld bytes\n",
+ neednl?"\n":"", bytes);
+ return (-1);
+ }
+ bytes += amount;
+ startsec += amount / secsize;
+
+ if (lverbose && (bytes >= (savbytes + 0x100000))) {
+ int fper;
+ int nsecs = (bytes - savbytes) / secsize;
+ float fspeed;
+
+ gettimeofday(&tcur, (struct timezone *)0);
+ printf("\rTrack %02d: %4lld", track, bytes >> 20);
+ if (tracksize > 0)
+ printf(" of %4lld MB", tracksize >> 20);
+ else
+ printf(" MB");
+ printf(" written");
+ fper = fifo_percent(TRUE);
+ if (fper >= 0)
+ printf(" (fifo %3d%%)", fper);
+#ifdef BCAP
+ if (bsize > 0) { /* buffer size known */
+ scgp->silent++;
+ per = (*dp->cdr_buffer_cap)(scgp, (long *)0, &bfree);
+ scgp->silent--;
+ if (per >= 0) {
+ per = 100*(bsize - bfree) / bsize;
+ if ((bsize - bfree) <= amount || per <= 5)
+ dp->cdr_dstat->ds_buflow++;
+ if (per < (int)dp->cdr_dstat->ds_minbuf &&
+ (startsec*secsize) > bsize) {
+ dp->cdr_dstat->ds_minbuf = per;
+ }
+ printf(" [buf %3d%%]", per);
+#ifdef BCAPDBG
+ printf(" %3ld %3ld", bsize >> 10, bfree >> 10);
+#endif
+ }
+ }
+#endif
+
+ tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
+ tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
+ while (tlast.tv_usec < 0) {
+ tlast.tv_usec += 1000000;
+ tlast.tv_sec -= 1;
+ }
+ fspeed = (nsecs / secsps) /
+ (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
+ if (fspeed > 999.0)
+ fspeed = 999.0;
+#ifdef BCAP
+ if (bsize > 0 && per > dminbuf &&
+ dp->cdr_dstat->ds_cdrflags & RF_WR_WAIT) {
+ int wsecs = (per-dminbuf)*(bsize/secsize)/100;
+ int msecs = 0x100000/secsize;
+ int wt;
+ int mt;
+ int s = dp->cdr_dstat->ds_dr_cur_wspeed;
+
+
+ if (s <= 0) {
+ if (dp->cdr_dstat->ds_flags & DSF_DVD)
+ s = 4;
+ else
+ s = 50;
+ }
+ if (wsecs > msecs) /* Less that 1 MB */
+ wsecs = msecs;
+ wt = wsecs * 1000 / secsps / fspeed;
+ mt = (per-dminbuf)*(bsize/secsize)/100 * 1000 / secsps/s;
+
+ if (wt > mt)
+ wt = mt;
+ if (wt > 1000) /* Max 1 second */
+ wt = 1000;
+ if (wt < 20) /* Min 20 ms */
+ wt = 0;
+
+ if (xdebug)
+ printf(" |%3d %4dms %5dms|", wsecs, wt, mt);
+ else
+ printf(" |%3d %4dms|", wsecs, wt);
+ if (wt > 0)
+ usleep(wt*1000);
+ }
+#endif
+ if (dp->is_dvd) fspeed /= 9;
+ printf(" %5.1fx", fspeed);
+ printf(".");
+ savbytes = (bytes >> 20) << 20;
+ flush();
+ neednl = TRUE;
+ tlast = tcur;
+ }
+#ifdef XBCAP
+ if (bsize > 0) { /* buffer size known */
+ (*dp->cdr_buffer_cap)(scgp, (long *)0, &bfree);
+ per = 100*(bsize - bfree) / bsize;
+ if (per != oper)
+ printf("[buf %3d%%] %3ld %3ld\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",
+ per, bsize >> 10, bfree >> 10);
+ oper = per;
+ flush();
+ }
+
+
+#endif
+ } while (tracksize < 0 || bytes_read < tracksize);
+
+ if (!is_shorttrk(trackp) && (bytes / secsize) < 300) {
+ /*
+ * If tracksize is not known (trackp->tracksize < 0) or
+ * for some strange reason we did not set padsecs properly
+ * we may need to modify trackp->padsecs if
+ * tracksize+padsecs is less than 300 sectors.
+ */
+ if ((trackp->padsecs + (bytes / secsize)) < 300)
+ trackp->padsecs = 300 - (bytes / secsize);
+ }
+ if (trackp->padsecs > 0) {
+ Llong padbytes;
+
+ /*
+ * pad_track() is based on secsize. Compute the amount of bytes
+ * assumed by pad_track().
+ */
+ padbytes = (Llong)trackp->padsecs * secsize;
+
+ if (neednl) {
+ printf("\n");
+ neednl = FALSE;
+ }
+ if ((padbytes >> 20) > 0) {
+ neednl = TRUE;
+ } else if (lverbose) {
+ printf("Track %02d: writing %3lld KB of pad data.\n",
+ track, (Llong)(padbytes >> 10));
+ neednl = FALSE;
+ }
+ pad_track(scgp, dp, trackp, startsec, padbytes,
+ TRUE, &savbytes);
+ bytes += savbytes;
+ startsec += savbytes / secsize;
+ }
+ printf("%sTrack %02d: Total bytes read/written: %lld/%lld (%lld sectors).\n",
+ neednl?"\n":"", track, bytes_read, bytes, bytes/secsize);
+ flush();
+ return (0);
+}
+
+int
+pad_track(SCSI *scgp, cdr_t *dp, track_t *trackp, long startsec, Llong amt,
+ BOOL dolast, Llong *bytesp)
+{
+ int track = trackp->trackno;
+ Llong bytes = 0;
+ Llong savbytes = 0;
+ Llong padsize = amt;
+ int secsize;
+ int secspt;
+ int bytespt;
+ int amount;
+ BOOL neednl = FALSE;
+ BOOL islast = FALSE;
+ struct timeval tlast;
+ struct timeval tcur;
+ float secsps = 75.0;
+long bsize;
+long bfree;
+#define BCAP
+#ifdef BCAP
+int per;
+#ifdef XBCAP
+int oper = -1;
+#endif
+#endif
+
+ if (dp->cdr_dstat->ds_flags & DSF_DVD)
+ secsps = 676.27;
+
+ scgp->silent++;
+ if ((*dp->cdr_buffer_cap)(scgp, &bsize, &bfree) < 0)
+ bsize = -1L;
+ if (bsize == 0) /* If we have no (known) buffer, we cannot */
+ bsize = -1L; /* retrieve the buffer fill ratio */
+ scgp->silent--;
+
+ secsize = trackp->secsize;
+ secspt = trackp->secspt;
+ bytespt = secsize * secspt;
+
+ fillbytes(buf, bytespt, '\0');
+
+ if ((amt >> 20) > 0) {
+ printf("\rTrack %02d: 0 of %4lld MB pad written.",
+ track, amt >> 20);
+ flush();
+ }
+ gettimeofday(&tlast, (struct timezone *)0);
+ do {
+ if (amt < bytespt) {
+ bytespt = roundup(amt, secsize);
+ secspt = bytespt / secsize;
+ }
+ if (dolast && (amt - bytespt) <= 0)
+ islast = TRUE;
+
+ if (is_raw(trackp)) {
+ encsectors(trackp, (Uchar *)buf, startsec, secspt);
+ fillsubch(trackp, (Uchar *)buf, startsec, secspt);
+ }
+
+ amount = write_secs(scgp, dp, buf, startsec, bytespt, secspt, islast);
+ if (amount < 0) {
+ printf("%swrite track pad data: error after %lld bytes\n",
+ neednl?"\n":"", bytes);
+ if (bytesp)
+ *bytesp = bytes;
+(*dp->cdr_buffer_cap)(scgp, (long *)0, (long *)0);
+ return (-1);
+ }
+ amt -= amount;
+ bytes += amount;
+ startsec += amount / secsize;
+
+ if (lverbose && (bytes >= (savbytes + 0x100000))) {
+ int nsecs = (bytes - savbytes) / secsize;
+ float fspeed;
+
+ gettimeofday(&tcur, (struct timezone *)0);
+ printf("\rTrack %02d: %4lld", track, bytes >> 20);
+ if (padsize > 0)
+ printf(" of %4lld MB", padsize >> 20);
+ else
+ printf(" MB");
+ printf(" pad written");
+ savbytes = (bytes >> 20) << 20;
+
+#ifdef BCAP
+ if (bsize > 0) { /* buffer size known */
+ scgp->silent++;
+ per = (*dp->cdr_buffer_cap)(scgp, (long *)0, &bfree);
+ scgp->silent--;
+ if (per >= 0) {
+ per = 100*(bsize - bfree) / bsize;
+ if ((bsize - bfree) <= amount || per <= 5)
+ dp->cdr_dstat->ds_buflow++;
+ if (per < (int)dp->cdr_dstat->ds_minbuf &&
+ (startsec*secsize) > bsize) {
+ dp->cdr_dstat->ds_minbuf = per;
+ }
+ printf(" [buf %3d%%]", per);
+#ifdef BCAPDBG
+ printf(" %3ld %3ld", bsize >> 10, bfree >> 10);
+#endif
+ }
+ }
+#endif
+ tlast.tv_sec = tcur.tv_sec - tlast.tv_sec;
+ tlast.tv_usec = tcur.tv_usec - tlast.tv_usec;
+ while (tlast.tv_usec < 0) {
+ tlast.tv_usec += 1000000;
+ tlast.tv_sec -= 1;
+ }
+ fspeed = (nsecs / secsps) /
+ (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
+ if (fspeed > 999.0)
+ fspeed = 999.0;
+ printf(" %5.1fx", fspeed);
+ printf(".");
+ flush();
+ neednl = TRUE;
+ tlast = tcur;
+ }
+ } while (amt > 0);
+
+ if (bytesp)
+ *bytesp = bytes;
+ if (bytes == 0)
+ return (0);
+ return (bytes > 0 ? 1:-1);
+}
+
+#ifdef USE_WRITE_BUF
+int
+write_buf(SCSI *scgp, cdr_t *dp, track_t *trackp, char *bp, long startsec,
+ Llong amt, int secsize, BOOL dolast, Llong *bytesp)
+{
+ int track = trackp->trackno;
+ Llong bytes = 0;
+ Llong savbytes = 0;
+/* int secsize;*/
+ int secspt;
+ int bytespt;
+ int amount;
+ BOOL neednl = FALSE;
+ BOOL islast = FALSE;
+
+/* secsize = trackp->secsize;*/
+/* secspt = trackp->secspt;*/
+
+ secspt = bufsize/secsize;
+ secspt = min(255, secspt);
+ bytespt = secsize * secspt;
+
+/* fillbytes(buf, bytespt, '\0');*/
+
+ if ((amt >> 20) > 0) {
+ printf("\rTrack %02d: 0 of %4ld MB pad written.",
+ track, amt >> 20);
+ flush();
+ }
+ do {
+ if (amt < bytespt) {
+ bytespt = roundup(amt, secsize);
+ secspt = bytespt / secsize;
+ }
+ if (dolast && (amt - bytespt) <= 0)
+ islast = TRUE;
+
+ amount = write_secs(scgp, dp, bp, startsec, bytespt, secspt, islast);
+ if (amount < 0) {
+ printf("%swrite track data: error after %ld bytes\n",
+ neednl?"\n":"", bytes);
+ if (bytesp)
+ *bytesp = bytes;
+(*dp->cdr_buffer_cap)(scgp, (long *)0, (long *)0);
+ return (-1);
+ }
+ amt -= amount;
+ bytes += amount;
+ startsec += amount / secsize;
+
+ if (lverbose && (bytes >= (savbytes + 0x100000))) {
+ printf("\rTrack %02d: %3ld", track, bytes >> 20);
+ savbytes = (bytes >> 20) << 20;
+ flush();
+ neednl = TRUE;
+ }
+ } while (amt > 0);
+
+ if (bytesp)
+ *bytesp = bytes;
+ return (bytes);
+}
+#endif /* USE_WRITE_BUF */
+
+static void
+printdata(int track, track_t *trackp)
+{
+ if (trackp->itracksize >= 0) {
+ printf("Track %02d: data %4lld MB ",
+ track, (Llong)(trackp->itracksize >> 20));
+ } else {
+ printf("Track %02d: data unknown length",
+ track);
+ }
+ if (trackp->padsecs > 0) {
+ Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize;
+
+ if ((padbytes >> 20) > 0)
+ printf(" padsize: %4lld MB", (Llong)(padbytes >> 20));
+ else
+ printf(" padsize: %4lld KB", (Llong)(padbytes >> 10));
+ }
+ if (trackp->pregapsize != (trackp->flags & TI_DVD)? 0 : 150) {
+ printf(" pregapsize: %3ld", trackp->pregapsize);
+ }
+ if (xdebug)
+ printf(" START: %ld SECTORS: %ld INDEX0 %ld",
+ trackp->trackstart, trackp->tracksecs, trackp->index0start);
+ printf("\n");
+}
+
+static void
+printaudio(int track, track_t *trackp)
+{
+ if (trackp->itracksize >= 0) {
+ printf("Track %02d: audio %4lld MB (%02d:%02d.%02d) %spreemp%s%s",
+ track, (Llong)(trackp->itracksize >> 20),
+ minutes(trackp->itracksize),
+ seconds(trackp->itracksize),
+ hseconds(trackp->itracksize),
+ is_preemp(trackp) ? "" : "no ",
+ is_swab(trackp) ? " swab":"",
+ ((trackp->itracksize < 300L*trackp->isecsize) ||
+ (trackp->itracksize % trackp->isecsize)) &&
+ is_pad(trackp) ? " pad" : "");
+ } else {
+ printf("Track %02d: audio unknown length %spreemp%s%s",
+ track, is_preemp(trackp) ? "" : "no ",
+ is_swab(trackp) ? " swab":"",
+ (trackp->itracksize % trackp->isecsize) && is_pad(trackp) ? " pad" : "");
+ }
+ if (is_scms(trackp))
+ printf(" scms");
+ else if (is_copy(trackp))
+ printf(" copy");
+ else
+ printf(" ");
+
+ if (trackp->padsecs > 0) {
+ Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize;
+
+ if ((padbytes >> 20) > 0)
+ printf(" padsize: %4lld MB", (Llong)(padbytes >> 20));
+ else
+ printf(" padsize: %4lld KB", (Llong)(padbytes >> 10));
+ printf(" (%02d:%02d.%02d)",
+ Sminutes(trackp->padsecs),
+ Sseconds(trackp->padsecs),
+ Shseconds(trackp->padsecs));
+ }
+ if (trackp->pregapsize != ((trackp->flags & TI_DVD)? 0 : 150) || xdebug > 0) {
+ printf(" pregapsize: %3ld", trackp->pregapsize);
+ }
+ if (xdebug)
+ printf(" START: %ld SECTORS: %ld INDEX0 %ld",
+ trackp->trackstart, trackp->tracksecs, trackp->index0start);
+ printf("\n");
+}
+
+static void
+checkfile(int track, track_t *trackp)
+{
+ if (trackp->itracksize > 0 &&
+ is_audio(trackp) &&
+ ((!is_shorttrk(trackp) &&
+ (trackp->itracksize < 300L*trackp->isecsize)) ||
+ (trackp->itracksize % trackp->isecsize)) &&
+ !is_pad(trackp)) {
+ errmsgno(EX_BAD, "Bad audio track size %lld for track %02d.\n",
+ (Llong)trackp->itracksize, track);
+ errmsgno(EX_BAD, "Audio tracks must be at least %ld bytes and a multiple of %d.\n",
+ 300L*trackp->isecsize, trackp->isecsize);
+
+ if (!is_shorttrk(trackp) && (trackp->itracksize < 300L*trackp->isecsize))
+ comerrno(EX_BAD, "See -shorttrack option.\n");
+ if (!is_pad(trackp) && (trackp->itracksize % trackp->isecsize))
+ comerrno(EX_BAD, "See -pad option.\n");
+ }
+
+ if (lverbose == 0 && xdebug == 0)
+ return;
+
+ if (is_audio(trackp))
+ printaudio(track, trackp);
+ else
+ printdata(track, trackp);
+}
+
+static int
+checkfiles(int tracks, track_t *trackp)
+{
+ int i;
+ int isaudio = 1;
+ int starttrack = 1;
+ int endtrack = tracks;
+
+ if (xdebug) {
+ /*
+ * Include Lead-in & Lead-out.
+ */
+ starttrack--;
+ endtrack++;
+ }
+ for (i = starttrack; i <= endtrack; i++) {
+ if (!is_audio(&trackp[i]))
+ isaudio = 0;
+ if (xdebug)
+ printf("SECTYPE %X ", trackp[i].sectype);
+ checkfile(i, &trackp[i]);
+ }
+ return (isaudio);
+}
+
+static void
+setleadinout(int tracks, track_t *trackp)
+{
+ /*
+ * Set some values for track 0 (the lead-in)
+ */
+ if (!is_clone(&trackp[0])) {
+ trackp[0].sectype = trackp[1].sectype;
+ trackp[0].dbtype = trackp[1].dbtype;
+ trackp[0].dataoff = trackp[1].dataoff;
+
+ /*
+ * XXX Which other flags should be copied to Track 0 ?
+ */
+ if (is_audio(&trackp[1]))
+ trackp[0].flags |= TI_AUDIO;
+ }
+
+ /*
+ * Set some values for track 0xAA (the lead-out)
+ */
+ trackp[tracks+1].pregapsize = 0;
+ trackp[tracks+1].isecsize = trackp[tracks].isecsize;
+ trackp[tracks+1].secsize = trackp[tracks].secsize;
+
+ if (!is_clone(&trackp[0])) {
+ trackp[tracks+1].tracktype = trackp[tracks].tracktype;
+ trackp[tracks+1].sectype = trackp[tracks].sectype;
+ trackp[tracks+1].dbtype = trackp[tracks].dbtype;
+ trackp[tracks+1].dataoff = trackp[tracks].dataoff;
+ }
+
+ trackp[tracks+1].flags = trackp[tracks].flags;
+}
+
+static void
+setpregaps(int tracks, track_t *trackp)
+{
+ int i;
+ int sectype;
+ long pregapsize;
+ track_t *tp;
+
+ sectype = trackp[1].sectype;
+ sectype &= ST_MASK;
+
+ for (i = 1; i <= tracks; i++) {
+ tp = &trackp[i];
+ if (tp->pregapsize == -1L) {
+ tp->pregapsize = 150; /* Default CD Pre GAP*/
+ if (trackp->flags & TI_DVD) {
+ tp->pregapsize = 0;
+ } else if (sectype != (tp->sectype & ST_MASK)) {
+ tp->pregapsize = 255; /* Pre GAP is 255 */
+ tp->flags &= ~TI_PREGAP;
+ }
+ }
+ sectype = tp->sectype & ST_MASK; /* Save old sectype */
+ }
+ trackp[tracks+1].pregapsize = 0;
+ trackp[tracks+1].index0start = 0;
+
+ for (i = 1; i <= tracks; i++) {
+ /*
+ * index0start is set below tracksecks if this track contains
+ * the pregap (index 0) of the next track.
+ */
+ trackp[i].index0start = trackp[i].tracksecs;
+
+ pregapsize = trackp[i+1].pregapsize;
+ if (is_pregap(&trackp[i+1]) && pregapsize > 0)
+ trackp[i].index0start -= pregapsize;
+ }
+}
+
+/*
+ * Check total size of the medium
+ */
+static long
+checktsize(int tracks, track_t *trackp)
+{
+ int i;
+ Llong curr;
+ Llong total = -150; /* CD track #1 pregap compensation */
+ Ullong btotal;
+ track_t *tp;
+
+ if (trackp->flags & TI_DVD)
+ total = 0;
+ for (i = 1; i <= tracks; i++) {
+ tp = &trackp[i];
+ if (!is_pregap(tp))
+ total += tp->pregapsize;
+
+ if (lverbose > 1) {
+ printf("track: %d start: %lld pregap: %ld\n",
+ i, total, tp->pregapsize);
+ }
+ tp->trackstart = total;
+ if (tp->itracksize >= 0) {
+ curr = (tp->itracksize + (tp->isecsize-1)) / tp->isecsize;
+ curr += tp->padsecs;
+ /*
+ * Minimum track size is 4s
+ */
+ if (!is_shorttrk(tp) && curr < 300)
+ curr = 300;
+ if ((trackp->flags & TI_DVD) == 0) {
+ /*
+ * XXX Was passiert hier bei is_packet() ???
+ */
+ if (is_tao(tp) && !is_audio(tp)) {
+ curr += 2;
+ }
+ }
+ total += curr;
+ } else if (is_sao(tp) || is_raw(tp)) {
+ errmsgno(EX_BAD, "Track %d has unknown length.\n", i);
+ comerrno(EX_BAD,
+ "Use tsize= option in %s mode to specify track size.\n",
+ is_sao(tp) ? "SAO" : "RAW");
+ }
+ }
+ tp = &trackp[i];
+ tp->trackstart = total;
+ tp->tracksecs = 6750; /* Size of first session Lead-Out */
+ if (!lverbose)
+ return (total);
+
+ if (trackp->flags & TI_DVD)
+ btotal = (Ullong)total * 2048;
+ else
+ btotal = (Ullong)total * 2352;
+/* XXX CD Sector Size ??? */
+ if (tracks > 0) {
+ if (trackp->flags & TI_DVD) {
+ printf("Total size: %4llu MB = %lld sectors\n",
+ btotal >> 20, total);
+ } else {
+ printf("Total size: %4llu MB (%02d:%02d.%02d) = %lld sectors\n",
+ btotal >> 20,
+ minutes(btotal),
+ seconds(btotal),
+ hseconds(btotal), total);
+ btotal += 150 * 2352;
+ printf("Lout start: %4llu MB (%02d:%02d/%02d) = %lld sectors\n",
+ btotal >> 20,
+ minutes(btotal),
+ seconds(btotal),
+ frames(btotal), total);
+ }
+ }
+ return (total);
+}
+
+static void
+opentracks(track_t *trackp)
+{
+ track_t *tp;
+ int i;
+ int tracks = trackp[0].tracks;
+
+ Llong tracksize;
+ int secsize;
+
+ for (i = 1; i <= tracks; i++) {
+ tp = &trackp[i];
+
+ if (auinfosize(tp->filename, tp)) {
+ /*
+ * open stdin
+ */
+ tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0);
+ } else if (strcmp("-", tp->filename) == 0) {
+ /*
+ * open stdin
+ */
+ tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0);
+ } else {
+ if ((tp->xfp = xopen(tp->filename,
+ O_RDONLY|O_BINARY, 0)) == NULL) {
+ comerr("Cannot open '%s'.\n", tp->filename);
+ }
+ }
+
+ checksize(tp);
+ tracksize = tp->itracksize;
+ secsize = tp->isecsize;
+ if (!is_shorttrk(tp) &&
+ tracksize > 0 && (tracksize / secsize) < 300) {
+
+ tracksize = roundup(tracksize, secsize);
+ if ((tp->padsecs +
+ (tracksize / secsize)) < 300) {
+ tp->padsecs =
+ 300 - tracksize / secsize;
+ }
+ if (xdebug) {
+ printf("TRACK %d SECTORS: %ld",
+ i, tp->tracksecs);
+ printf(" pasdize %lld (%ld sectors)\n",
+ (Llong)tp->padsecs * secsize,
+ tp->padsecs);
+ }
+ }
+#ifdef AUINFO
+ if (tp->flags & TI_USEINFO) {
+ auinfo(tp->filename, i, trackp);
+ if (lverbose > 0 && i == 1)
+ printf("pregap1: %ld\n", trackp[1].pregapsize);
+ }
+#endif
+ /*
+ * tracksecks is total numbers of sectors in track (starting from
+ * index 0).
+ */
+ if (tp->padsecs > 0)
+ tp->tracksecs += tp->padsecs;
+
+ if (debug) {
+ printf("File: '%s' itracksize: %lld isecsize: %d tracktype: %d = %s sectype: %X = %s dbtype: %s flags %X\n",
+ tp->filename, (Llong)tp->itracksize,
+ tp->isecsize,
+ tp->tracktype & TOC_MASK, toc2name[tp->tracktype & TOC_MASK],
+ tp->sectype, st2name[tp->sectype & ST_MASK], db2name[tp->dbtype], tp->flags);
+ }
+ }
+}
+
+static void
+checksize(track_t *trackp)
+{
+ struct stat st;
+ Llong lsize;
+ int f = -1;
+
+ if (trackp->xfp != NULL)
+ f = xfileno(trackp->xfp);
+
+ /*
+ * If the current input file is a regular file and
+ * 'padsize=' has not been specified,
+ * use fstat() or file parser to get the size of the file.
+ */
+ if (trackp->itracksize < 0 && (trackp->flags & TI_ISOSIZE) != 0) {
+ lsize = isosize(f);
+ trackp->itracksize = lsize;
+ if (trackp->itracksize != lsize)
+ comerrno(EX_BAD, "This OS cannot handle large ISO-9660 images.\n");
+ }
+ if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
+ lsize = ausize(f);
+ trackp->itracksize = lsize;
+ if (trackp->itracksize != lsize)
+ comerrno(EX_BAD, "This OS cannot handle large audio images.\n");
+ }
+ if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) {
+ lsize = wavsize(f);
+ trackp->itracksize = lsize;
+ if (trackp->itracksize != lsize)
+ comerrno(EX_BAD, "This OS cannot handle large WAV images.\n");
+ if (trackp->itracksize > 0) /* Force little endian input */
+ trackp->flags |= TI_SWAB;
+ }
+ if (trackp->itracksize == AU_BAD_CODING) {
+ comerrno(EX_BAD, "Inappropriate audio coding in '%s'.\n",
+ trackp->filename);
+ }
+ if (trackp->itracksize < 0 &&
+ fstat(f, &st) >= 0 && S_ISREG(st.st_mode)) {
+ trackp->itracksize = st.st_size;
+ }
+ if (trackp->itracksize >= 0) {
+ /*
+ * We do not allow cdrecord to start if itracksize is not
+ * a multiple of isecsize or we are allowed to pad to secsize via -pad.
+ * For this reason, we may safely always assume padding.
+ */
+ trackp->tracksecs = (trackp->itracksize + trackp->isecsize -1) / trackp->isecsize;
+ trackp->tracksize = (trackp->itracksize / trackp->isecsize) * trackp->secsize
+ + trackp->itracksize % trackp->isecsize;
+ } else {
+ trackp->tracksecs = -1L;
+ }
+}
+
+static BOOL
+checkdsize(SCSI *scgp, cdr_t *dp, long tsize, int flags)
+{
+ long startsec = 0L;
+ long endsec = 0L;
+ dstat_t *dsp = dp->cdr_dstat;
+ int profile;
+
+ scgp->silent++;
+ (*dp->cdr_next_wr_address)(scgp, (track_t *)0, &startsec);
+ scgp->silent--;
+
+ /*
+ * This only should happen when the drive is currently in SAO mode.
+ * We rely on the drive being in TAO mode, a negative value for
+ * startsec is not correct here it may be caused by bad firmware or
+ * by a drive in SAO mode. In SAO mode the drive will report the
+ * pre-gap as part of the writable area.
+ */
+ if (startsec < 0)
+ startsec = 0;
+
+ /*
+ * Size limitations (sectors) for CD's:
+ *
+ * 404850 == 90 min Red book calls this the
+ * first negative time
+ * allows lead out start up to
+ * block 404700
+ *
+ * 449850 == 100 min This is the first time that
+ * is no more representable
+ * in a two digit BCD number.
+ * allows lead out start up to
+ * block 449700
+ *
+ * ~540000 == 120 min The largest CD ever made.
+ *
+ * ~650000 == 1.3 GB a Double Density (DD) CD.
+ */
+
+ endsec = startsec + tsize;
+ dsp->ds_startsec = startsec;
+ dsp->ds_endsec = endsec;
+
+
+ if (dsp->ds_maxblocks > 0) {
+ /*
+ * dsp->ds_maxblocks > 0 (disk capacity is known).
+ */
+ if (lverbose)
+ printf("Blocks total: %ld Blocks current: %ld Blocks remaining: %ld\n",
+ (long)dsp->ds_maxblocks,
+ (long)dsp->ds_maxblocks - startsec,
+ (long)dsp->ds_maxblocks - endsec);
+
+ if (endsec > dsp->ds_maxblocks) {
+ if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */
+ /*
+ * There is no overburning on DVD...
+ */
+ errmsgno(EX_BAD,
+ "Data does not fit on current disk.\n");
+ goto toolarge;
+ }
+ errmsgno(EX_BAD,
+ "WARNING: Data may not fit on current disk.\n");
+
+ /* XXX Check for flags & CDR_NO_LOLIMIT */
+/* goto toolarge;*/
+ }
+ if (lverbose && dsp->ds_maxrblocks > 0)
+ printf("RBlocks total: %ld RBlocks current: %ld RBlocks remaining: %ld\n",
+ (long)dsp->ds_maxrblocks,
+ (long)dsp->ds_maxrblocks - startsec,
+ (long)dsp->ds_maxrblocks - endsec);
+ if (dsp->ds_maxrblocks > 0 && endsec > dsp->ds_maxrblocks) {
+ errmsgno(EX_BAD,
+ "Data does not fit on current disk.\n");
+ goto toolarge;
+ }
+ if ((endsec > dsp->ds_maxblocks && endsec > 404700) ||
+ (dsp->ds_maxrblocks > 404700 && 449850 > dsp->ds_maxrblocks)) {
+ /*
+ * Assume that this must be a CD and not a DVD.
+ * So this is a non Red Book compliant CD with a
+ * capacity between 90 and 99 minutes.
+ */
+ if (dsp->ds_maxrblocks > 404700)
+ printf("RedBook total: %ld RedBook current: %ld RedBook remaining: %ld\n",
+ 404700L,
+ 404700L - startsec,
+ 404700L - endsec);
+ if (endsec > dsp->ds_maxblocks && endsec > 404700) {
+ if ((flags & (F_IGNSIZE|F_FORCE)) == 0) {
+ errmsgno(EX_BAD,
+ "Notice: Most recorders cannot write CD's >= 90 minutes.\n");
+ errmsgno(EX_BAD,
+ "Notice: Use -ignsize option to allow >= 90 minutes.\n");
+ }
+ goto toolarge;
+ }
+ }
+ } else {
+ /*
+ * dsp->ds_maxblocks == 0 (disk capacity is unknown).
+ */
+ profile = dp->profile;
+ if (endsec >= (4200000)) {
+ errmsgno(EX_BAD,
+ "ERROR: Could not manage to find medium size, and more than 8.0 GB of data.\n");
+ goto toolarge;
+ } else if (profile != 0x2B) {
+ if (endsec >= (2300000)) {
+ errmsgno(EX_BAD,
+ "ERROR: Could not manage to find medium size, and more than 4.3 GB of data for a non dual layer disc.\n");
+ goto toolarge;
+ } else if (endsec >= (405000-300)) { /*<90 min disk or DVD*/
+ errmsgno(EX_BAD,
+ "WARNING: Could not manage to find medium size, and more than 90 mins of data.\n");
+ } else if (endsec >= (333000-150)) { /* 74 min disk*/
+ errmsgno(EX_BAD,
+ "WARNING: Data may not fit on standard 74min disk.\n");
+ }
+ }
+ }
+ if (dsp->ds_maxblocks <= 0 || endsec <= dsp->ds_maxblocks)
+ return (TRUE);
+ /* FALLTHROUGH */
+toolarge:
+ if (dsp->ds_maxblocks > 0 && endsec > dsp->ds_maxblocks) {
+ if ((flags & (F_OVERBURN|F_IGNSIZE|F_FORCE)) != 0) {
+ if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */
+ errmsgno(EX_BAD,
+ "Notice: -overburn is not expected to work with DVD media.\n");
+ }
+ errmsgno(EX_BAD,
+ "Notice: Overburning active. Trying to write more than the official disk capacity.\n");
+ return (TRUE);
+ } else {
+ if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */
+ errmsgno(EX_BAD,
+ "Notice: Use -overburn option to write more than the official disk capacity.\n");
+ errmsgno(EX_BAD,
+ "Notice: Most CD-writers do overburning only on SAO or RAW mode.\n");
+ }
+ return (FALSE);
+ }
+ }
+ if (dsp->ds_maxblocks < 449850) {
+ if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */
+ if (endsec <= dsp->ds_maxblocks)
+ return (TRUE);
+ errmsgno(EX_BAD, "Cannot write more than remaining DVD capacity.\n");
+ return (FALSE);
+ }
+ /*
+ * Assume that this must be a CD and not a DVD.
+ */
+ if (endsec > 449700) {
+ errmsgno(EX_BAD, "Cannot write CD's >= 100 minutes.\n");
+ return (FALSE);
+ }
+ }
+ if ((flags & (F_IGNSIZE|F_FORCE)) != 0)
+ return (TRUE);
+ return (FALSE);
+}
+
+static void
+raise_fdlim()
+{
+#ifdef RLIMIT_NOFILE
+
+ struct rlimit rlim;
+
+ /*
+ * Set max # of file descriptors to be able to hold all files open
+ */
+ getrlimit(RLIMIT_NOFILE, &rlim);
+ if (rlim.rlim_cur >= (MAX_TRACK + 10))
+ return;
+
+ rlim.rlim_cur = MAX_TRACK + 10;
+ if (rlim.rlim_cur > rlim.rlim_max)
+ errmsgno(EX_BAD,
+ "Warning: low file descriptor limit (%lld)\n",
+ (Llong)rlim.rlim_max);
+ setrlimit(RLIMIT_NOFILE, &rlim);
+
+#endif /* RLIMIT_NOFILE */
+}
+
+static void
+raise_memlock()
+{
+#ifdef RLIMIT_MEMLOCK
+ struct rlimit rlim;
+
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+
+ if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0)
+ errmsg("Warning: Cannot raise RLIMIT_MEMLOCK limits.");
+#endif /* RLIMIT_MEMLOCK */
+}
+
+char *opts =
+"help,version,checkdrive,prcap,inq,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#";
+
+/*
+ * Defines used to find whether a write mode has been specified.
+ */
+#define M_TAO 1 /* Track at Once mode */
+#define M_SAO 2 /* Session at Once mode (also known as DAO) */
+#define M_RAW 4 /* Raw mode */
+#define M_PACKET 8 /* Packed mode */
+static int
+gargs(int ac, char **av, int *tracksp, track_t *trackp, char **devp,
+ int *timeoutp, cdr_t **dpp, int *speedp, long *flagsp, int *blankp,
+ int *formatp)
+{
+ int cac;
+ char * const*cav;
+ char *driver = NULL;
+ char *dev = NULL;
+ char *isrc = NULL;
+ char *mcn = NULL;
+ char *tindex = NULL;
+ char *cuefile = NULL;
+ char *textfile = NULL;
+ long bltype = -1;
+ int doformat = 0;
+ int formattype = -1;
+ Llong tracksize;
+ Llong padsize;
+ long pregapsize;
+ long defpregap = -1L;
+ int pktsize;
+ int speed = -1;
+ int help = 0;
+ int version = 0;
+ int checkdrive = 0;
+ int setdropts = 0;
+ int prcap = 0;
+ int inq = 0;
+ int scanbus = 0;
+ int reset = 0;
+ int doabort = 0;
+ int overburn = 0;
+ int ignsize = 0;
+ int useinfo = 0;
+ int load = 0;
+ int lock = 0;
+ int eject = 0;
+ int dummy = 0;
+ int msinfo = 0;
+ int toc = 0;
+ int atip = 0;
+ int multi = 0;
+ int fix = 0;
+ int nofix = 0;
+ int waiti = 0;
+ int immed = 0;
+ int audio;
+ int autoaudio = 0;
+ int data;
+ int mode2;
+ int xa;
+ int xa1;
+ int xa2;
+ int xamix;
+ int cdi;
+ int isize;
+ int ispacket = 0;
+ int noclose = 0;
+ int force = 0;
+ int tao = 0;
+ int dao = 0;
+ int raw = 0;
+ int raw96r = 0;
+ int raw96p = 0;
+ int raw16 = 0;
+ int clone = 0;
+ int scms = 0;
+ int preemp = 0;
+ int nopreemp;
+ int copy = 0;
+ int nocopy;
+ int pad = 0;
+ int bswab = 0;
+ int nopad;
+ int usetext = 0;
+ int shorttrack = 0;
+ int noshorttrack;
+ int flags;
+ int tracks = *tracksp;
+ int tracktype = TOC_ROM;
+/* int sectype = ST_ROM_MODE1 | ST_MODE_1;*/
+ int sectype = SECT_ROM;
+ int dbtype = DB_ROM_MODE1;
+ int secsize = DATA_SEC_SIZE;
+ int dataoff = 16;
+ int ga_ret;
+ int wm = 0;
+
+ trackp[0].flags |= TI_TAO;
+ trackp[1].pregapsize = -1;
+ *flagsp |= F_WRITE;
+
+ cac = --ac;
+ cav = ++av;
+ for (; ; cac--, cav++) {
+ tracksize = (Llong)-1L;
+ padsize = (Llong)0L;
+ pregapsize = defpregap;
+ audio = data = mode2 = xa = xa1 = xa2 = xamix = cdi = 0;
+ isize = nopreemp = nocopy = nopad = noshorttrack = 0;
+ pktsize = 0;
+ isrc = NULL;
+ tindex = NULL;
+ /*
+ * Get options up to next file type arg.
+ */
+ if ((ga_ret = getargs(&cac, &cav, opts,
+ &help, &version, &checkdrive, &prcap,
+ &inq, &scanbus, &reset, &doabort, &overburn, &ignsize,
+ &useinfo,
+ devp, timeoutp, &driver, &driveropts, &setdropts,
+ getllnum, &tracksize,
+ getllnum, &padsize,
+ getnum, &pregapsize,
+ getnum, &defpregap,
+ &speed,
+ &load, &lock,
+ &eject, &dummy, &msinfo, &toc, &atip,
+ &multi, &fix, &nofix, &waiti, &immed,
+ &debug, &debug,
+ &kdebug, &kdebug,
+ &lverbose, &lverbose,
+ &scsi_verbose, &scsi_verbose,
+ &xdebug, &xdebug,
+ &silent, &silent,
+ &audio, &data, &mode2,
+ &xa, &xa1, &xa2, &xamix, &cdi,
+ &isize,
+ &nopreemp, &preemp,
+ &nocopy, ©,
+ &nopad, &pad, &bswab, getnum, &fs, getnum, &bufsize,
+ getbltype, &bltype, &doformat, getformattype, &formattype, &pktsize,
+ &ispacket, &noclose, &force,
+ &tao, &dao, &dao, &raw, &raw96r, &raw96p, &raw16,
+ &clone,
+ &scms, &isrc, &mcn, &tindex,
+ &cuefile, &textfile, &usetext,
+ &shorttrack, &noshorttrack,
+ &gracetime, &dminbuf)) < 0) {
+ errmsgno(EX_BAD, "Bad Option: %s.\n", cav[0]);
+ susage(EX_BAD);
+ }
+ if (help)
+ usage(0);
+ if (tracks == 0) {
+ if (driver)
+ set_cdrcmds(driver, dpp);
+ if (version)
+ *flagsp |= F_VERSION;
+ if (checkdrive)
+ *flagsp |= F_CHECKDRIVE;
+ if (prcap)
+ *flagsp |= F_PRCAP;
+ if (inq)
+ *flagsp |= F_INQUIRY;
+ if (scanbus)
+ *flagsp |= F_SCANBUS;
+ if (reset)
+ *flagsp |= F_RESET;
+ if (doabort)
+ *flagsp |= F_ABORT;
+ if (overburn)
+ *flagsp |= F_OVERBURN;
+ if (ignsize)
+ *flagsp |= F_IGNSIZE;
+ if (load)
+ *flagsp |= F_LOAD;
+ if (lock)
+ *flagsp |= F_DLCK;
+ if (eject)
+ *flagsp |= F_EJECT;
+ if (dummy)
+ *flagsp |= F_DUMMY;
+ if (setdropts)
+ *flagsp |= F_SETDROPTS;
+ if (msinfo)
+ *flagsp |= F_MSINFO;
+ if (toc) {
+ *flagsp |= F_TOC;
+ *flagsp &= ~F_WRITE;
+ }
+ if (atip) {
+ *flagsp |= F_PRATIP;
+ *flagsp &= ~F_WRITE;
+ }
+ if (multi) {
+ /*
+ * 2048 Bytes user data
+ */
+ *flagsp |= F_MULTI;
+ tracktype = TOC_XA2;
+ sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
+ sectype = SECT_MODE_2_F1;
+ dbtype = DB_XA_MODE2; /* XXX -multi nimmt DB_XA_MODE2_F1 !!! */
+ secsize = DATA_SEC_SIZE; /* 2048 */
+ dataoff = 24;
+ }
+ if (fix)
+ *flagsp |= F_FIX;
+ if (nofix)
+ *flagsp |= F_NOFIX;
+ if (waiti)
+ *flagsp |= F_WAITI;
+ if (immed)
+ *flagsp |= F_IMMED;
+ if (force)
+ *flagsp |= F_FORCE;
+
+ if (bltype >= 0) {
+ *flagsp |= F_BLANK;
+ *blankp = bltype;
+ }
+ if (doformat > 0) {
+ *flagsp |= F_FORMAT;
+ *formatp |= FULL_FORMAT;
+ }
+ if (formattype >= 0) {
+ *flagsp |= F_FORMAT;
+ *formatp |= formattype;
+ }
+ if (ispacket)
+ wm |= M_PACKET;
+ if (tao)
+ wm |= M_TAO;
+ if (dao) {
+ *flagsp |= F_SAO;
+ trackp[0].flags &= ~TI_TAO;
+ trackp[0].flags |= TI_SAO;
+ wm |= M_SAO;
+
+ } else if ((raw == 0) && (raw96r + raw96p + raw16) > 0)
+ raw = 1;
+ if ((raw != 0) && (raw96r + raw96p + raw16) == 0)
+ raw96r = 1;
+ if (raw96r) {
+ if (!dao)
+ *flagsp |= F_RAW;
+ trackp[0].flags &= ~TI_TAO;
+ trackp[0].flags |= TI_RAW;
+ trackp[0].flags |= TI_RAW96R;
+ wm |= M_RAW;
+ }
+ if (raw96p) {
+ if (!dao)
+ *flagsp |= F_RAW;
+ trackp[0].flags &= ~TI_TAO;
+ trackp[0].flags |= TI_RAW;
+ wm |= M_RAW;
+ }
+ if (raw16) {
+ if (!dao)
+ *flagsp |= F_RAW;
+ trackp[0].flags &= ~TI_TAO;
+ trackp[0].flags |= TI_RAW;
+ trackp[0].flags |= TI_RAW16;
+ wm |= M_RAW;
+ }
+ if (mcn) {
+#ifdef AUINFO
+ setmcn(mcn, &trackp[0]);
+#else
+ trackp[0].isrc = malloc(16);
+ fillbytes(trackp[0].isrc, 16, '\0');
+ strncpy(trackp[0].isrc, mcn, 13);
+#endif
+ mcn = NULL;
+ }
+ if ((raw96r + raw96p + raw16) > 1) {
+ errmsgno(EX_BAD, "Too many raw modes.\n");
+ comerrno(EX_BAD, "Only one of -raw16, -raw96p, -raw96r allowed.\n");
+ }
+ if ((tao + ispacket + dao + raw) > 1) {
+ errmsgno(EX_BAD, "Too many write modes.\n");
+ comerrno(EX_BAD, "Only one of -packet, -dao, -raw allowed.\n");
+ }
+ if (dao && (raw96r + raw96p + raw16) > 0) {
+ if (raw16)
+ comerrno(EX_BAD, "SAO RAW writing does not allow -raw16.\n");
+ if (!clone)
+ comerrno(EX_BAD, "SAO RAW writing only makes sense in clone mode.\n");
+#ifndef CLONE_WRITE
+ comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n");
+#endif
+ comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n");
+ }
+ if (clone) {
+ *flagsp |= F_CLONE;
+ trackp[0].flags |= TI_CLONE;
+#ifndef CLONE_WRITE
+ comerrno(EX_BAD, "Clone writing not compiled in.\n");
+#endif
+ }
+ if (textfile) {
+ if (!checktextfile(textfile)) {
+ if ((*flagsp & F_WRITE) != 0) {
+ comerrno(EX_BAD,
+ "Cannot use '%s' as CD-Text file.\n",
+ textfile);
+ }
+ }
+ if ((*flagsp & F_WRITE) != 0) {
+ if ((dao + raw96r + raw96p) == 0)
+ comerrno(EX_BAD,
+ "CD-Text needs -dao, -raw96r or -raw96p.\n");
+ }
+ trackp[0].flags |= TI_TEXT;
+ }
+ version = checkdrive = prcap = inq = scanbus = reset = doabort =
+ overburn = ignsize =
+ load = lock = eject = dummy = msinfo = toc = atip = multi = fix = nofix =
+ waiti = immed = force = dao = setdropts = 0;
+ raw96r = raw96p = raw16 = clone = 0;
+ } else if ((version + checkdrive + prcap + inq + scanbus +
+ reset + doabort + overburn + ignsize +
+ load + lock + eject + dummy + msinfo + toc + atip + multi + fix + nofix +
+ waiti + immed + force + dao + setdropts +
+ raw96r + raw96p + raw16 + clone) > 0 ||
+ mcn != NULL)
+ comerrno(EX_BAD, "Badly placed option. Global options must be before any track.\n");
+
+ if (nopreemp)
+ preemp = 0;
+ if (nocopy)
+ copy = 0;
+ if (nopad)
+ pad = 0;
+ if (noshorttrack)
+ shorttrack = 0;
+
+ if ((audio + data + mode2 + xa + xa1 + xa2 + xamix) > 1) {
+ errmsgno(EX_BAD, "Too many types for track %d.\n", tracks+1);
+ comerrno(EX_BAD, "Only one of -audio, -data, -mode2, -xa, -xa1, -xa2, -xamix allowed.\n");
+ }
+ if (ispacket && audio) {
+ comerrno(EX_BAD, "Audio data cannot be written in packet mode.\n");
+ }
+ /*
+ * Check whether the next argument is a file type arg.
+ * If this is true, then we got a track file name.
+ * If getargs() did previously return NOTAFLAG, we may have hit
+ * an argument that has been escaped via "--", so we may not
+ * call getfiles() again in this case. If we would call
+ * getfiles() and the current arg has been escaped and looks
+ * like an option, a call to getfiles() would skip it.
+ */
+ if (ga_ret != NOTAFLAG)
+ ga_ret = getfiles(&cac, &cav, opts);
+ if (autoaudio) {
+ autoaudio = 0;
+ tracktype = TOC_ROM;
+ sectype = ST_ROM_MODE1 | ST_MODE_1;
+ sectype = SECT_ROM;
+ dbtype = DB_ROM_MODE1;
+ secsize = DATA_SEC_SIZE; /* 2048 */
+ dataoff = 16;
+ }
+ if (ga_ret == NOTAFLAG && (is_auname(cav[0]) || is_wavname(cav[0]))) {
+ /*
+ * We got a track and autodetection decided that it
+ * is an audio track.
+ */
+ autoaudio++;
+ audio++;
+ }
+ if (data) {
+ /*
+ * 2048 Bytes user data
+ */
+ tracktype = TOC_ROM;
+ sectype = ST_ROM_MODE1 | ST_MODE_1;
+ sectype = SECT_ROM;
+ dbtype = DB_ROM_MODE1;
+ secsize = DATA_SEC_SIZE; /* 2048 */
+ dataoff = 16;
+ }
+ if (mode2) {
+ /*
+ * 2336 Bytes user data
+ */
+ tracktype = TOC_ROM;
+ sectype = ST_ROM_MODE2 | ST_MODE_2;
+ sectype = SECT_MODE_2;
+ dbtype = DB_ROM_MODE2;
+ secsize = MODE2_SEC_SIZE; /* 2336 */
+ dataoff = 16;
+ }
+ if (audio) {
+ /*
+ * 2352 Bytes user data
+ */
+ tracktype = TOC_DA;
+ sectype = preemp ? ST_AUDIO_PRE : ST_AUDIO_NOPRE;
+ sectype |= ST_MODE_AUDIO;
+ sectype = SECT_AUDIO;
+ if (preemp)
+ sectype |= ST_PREEMPMASK;
+ dbtype = DB_RAW;
+ secsize = AUDIO_SEC_SIZE; /* 2352 */
+ dataoff = 0;
+ }
+ if (xa) {
+ /*
+ * 2048 Bytes user data
+ */
+ if (tracktype != TOC_CDI)
+ tracktype = TOC_XA2;
+ sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
+ sectype = SECT_MODE_2_F1;
+ dbtype = DB_XA_MODE2;
+ secsize = DATA_SEC_SIZE; /* 2048 */
+ dataoff = 24;
+ }
+ if (xa1) {
+ /*
+ * 8 Bytes subheader + 2048 Bytes user data
+ */
+ if (tracktype != TOC_CDI)
+ tracktype = TOC_XA2;
+ sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1;
+ sectype = SECT_MODE_2_F1;
+ dbtype = DB_XA_MODE2_F1;
+ secsize = 2056;
+ dataoff = 16;
+ }
+ if (xa2) {
+ /*
+ * 2324 Bytes user data
+ */
+ if (tracktype != TOC_CDI)
+ tracktype = TOC_XA2;
+ sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_2;
+ sectype = SECT_MODE_2_F2;
+ dbtype = DB_XA_MODE2_F2;
+ secsize = 2324;
+ dataoff = 24;
+ }
+ if (xamix) {
+ /*
+ * 8 Bytes subheader + 2324 Bytes user data
+ */
+ if (tracktype != TOC_CDI)
+ tracktype = TOC_XA2;
+ sectype = ST_ROM_MODE2 | ST_MODE_2_MIXED;
+ sectype = SECT_MODE_2_MIX;
+ dbtype = DB_XA_MODE2_MIX;
+ secsize = 2332;
+ dataoff = 16;
+ }
+ if (cdi) {
+ tracktype = TOC_CDI;
+ }
+ if (tracks == 0) {
+ trackp[0].tracktype = tracktype;
+ trackp[0].dbtype = dbtype;
+ trackp[0].isecsize = secsize;
+ trackp[0].secsize = secsize;
+ if ((*flagsp & F_RAW) != 0) {
+ trackp[0].secsize = is_raw16(&trackp[0]) ?
+ RAW16_SEC_SIZE:RAW96_SEC_SIZE;
+ }
+ if ((*flagsp & F_DUMMY) != 0)
+ trackp[0].tracktype |= TOCF_DUMMY;
+ if ((*flagsp & F_MULTI) != 0)
+ trackp[0].tracktype |= TOCF_MULTI;
+ }
+
+ flags = trackp[0].flags;
+
+ if ((sectype & ST_AUDIOMASK) != 0)
+ flags |= TI_AUDIO;
+ if (isize) {
+ flags |= TI_ISOSIZE;
+ if ((*flagsp & F_MULTI) != 0)
+ comerrno(EX_BAD, "Cannot get isosize for multi session disks.\n");
+ /*
+ * As we do not get the padding from the ISO-9660
+ * formatting utility, we need to force padding here.
+ */
+ flags |= TI_PAD;
+ if (padsize == (Llong)0L)
+ padsize = (Llong)PAD_SIZE;
+ }
+
+ if ((flags & TI_AUDIO) != 0) {
+ if (preemp)
+ flags |= TI_PREEMP;
+ if (copy)
+ flags |= TI_COPY;
+ if (scms)
+ flags |= TI_SCMS;
+ }
+ if (pad || ((flags & TI_AUDIO) == 0 && padsize > (Llong)0L)) {
+ flags |= TI_PAD;
+ if ((flags & TI_AUDIO) == 0 && padsize == (Llong)0L)
+ padsize = (Llong)PAD_SIZE;
+ }
+ if (shorttrack && (*flagsp & (F_SAO|F_RAW)) != 0)
+ flags |= TI_SHORT_TRACK;
+ if (noshorttrack)
+ flags &= ~TI_SHORT_TRACK;
+ if (bswab)
+ flags |= TI_SWAB;
+ if (ispacket) {
+ flags |= TI_PACKET;
+ trackp[0].flags &= ~TI_TAO;
+ }
+ if (noclose)
+ flags |= TI_NOCLOSE;
+ if (useinfo)
+ flags |= TI_USEINFO;
+
+ if (ga_ret == NOARGS) {
+ /*
+ * All options have already been parsed and no more
+ * file type arguments are present.
+ */
+ break;
+ }
+ if (tracks == 0 && (wm == 0)) {
+ errmsgno(EX_BAD, "No write mode specified.\n");
+ errmsgno(EX_BAD, "Asuming -tao mode.\n");
+ errmsgno(EX_BAD, "Future versions of wodim may have different drive dependent defaults.\n");
+ tao = 1;
+ }
+ tracks++;
+
+ if (tracks > MAX_TRACK)
+ comerrno(EX_BAD, "Track limit (%d) exceeded\n",
+ MAX_TRACK);
+ /*
+ * Make 'tracks' immediately usable in track structure.
+ */
+ { register int i;
+ for (i = 0; i < MAX_TRACK+2; i++)
+ trackp[i].tracks = tracks;
+ }
+
+ if (strcmp("-", cav[0]) == 0)
+ *flagsp |= F_STDIN;
+
+ if (!is_auname(cav[0]) && !is_wavname(cav[0]))
+ flags |= TI_NOAUHDR;
+
+ if ((*flagsp & (F_SAO|F_RAW)) != 0 && (flags & TI_AUDIO) != 0)
+ flags |= TI_PREGAP; /* Hack for now */
+ if (tracks == 1)
+ flags &= ~TI_PREGAP;
+
+ if (tracks == 1 && (pregapsize != -1L && pregapsize != 150))
+ pregapsize = -1L;
+ trackp[tracks].filename = cav[0];
+ trackp[tracks].trackstart = 0L;
+ trackp[tracks].itracksize = tracksize;
+ trackp[tracks].tracksize = tracksize;
+ trackp[tracks].tracksecs = -1L;
+ if (tracksize >= 0)
+ trackp[tracks].tracksecs = (tracksize+secsize-1)/secsize;
+ if (trackp[tracks].pregapsize < 0)
+ trackp[tracks].pregapsize = pregapsize;
+ trackp[tracks+1].pregapsize = -1;
+ trackp[tracks].padsecs = (padsize+2047)/2048;
+ trackp[tracks].isecsize = secsize;
+ trackp[tracks].secsize = secsize;
+ trackp[tracks].flags = flags;
+ /*
+ * XXX Dies ist falsch: auch bei SAO/RAW kann
+ * XXX secsize != isecsize sein.
+ */
+ if ((*flagsp & F_RAW) != 0) {
+ if (is_raw16(&trackp[tracks]))
+ trackp[tracks].secsize = RAW16_SEC_SIZE;
+ else
+ trackp[tracks].secsize = RAW96_SEC_SIZE;
+#ifndef HAVE_LIB_EDC_ECC
+ if ((sectype & ST_MODE_MASK) != ST_MODE_AUDIO) {
+ errmsgno(EX_BAD,
+ "EDC/ECC library not compiled in.\n");
+ comerrno(EX_BAD,
+ "Data sectors are not supported in RAW mode.\n");
+ }
+#endif
+ }
+ trackp[tracks].secspt = 0; /* transfer size is set up in set_trsizes() */
+ trackp[tracks].pktsize = pktsize;
+ trackp[tracks].trackno = tracks;
+ trackp[tracks].sectype = sectype;
+#ifdef CLONE_WRITE
+ if ((*flagsp & F_CLONE) != 0) {
+ trackp[tracks].isecsize = 2448;
+ trackp[tracks].sectype |= ST_MODE_RAW;
+ dataoff = 0;
+ }
+#endif
+ trackp[tracks].dataoff = dataoff;
+ trackp[tracks].tracktype = tracktype;
+ trackp[tracks].dbtype = dbtype;
+ trackp[tracks].flags = flags;
+ trackp[tracks].nindex = 1;
+ trackp[tracks].tindex = 0;
+ if (isrc) {
+#ifdef AUINFO
+ setisrc(isrc, &trackp[tracks]);
+#else
+ trackp[tracks].isrc = malloc(16);
+ fillbytes(trackp[tracks].isrc, 16, '\0');
+ strncpy(trackp[tracks].isrc, isrc, 12);
+#endif
+ }
+ if (tindex) {
+#ifdef AUINFO
+ setindex(tindex, &trackp[tracks]);
+#endif
+ }
+ }
+
+ if (dminbuf >= 0) {
+ if (dminbuf < 25 || dminbuf > 95)
+ comerrno(EX_BAD,
+ "Bad minbuf=%d option (must be between 25 and 95)\n",
+ dminbuf);
+ }
+
+ if (speed < 0 && speed != -1)
+ comerrno(EX_BAD, "Bad speed option.\n");
+
+ if (fs < 0L && fs != -1L)
+ comerrno(EX_BAD, "Bad fifo size option.\n");
+
+ if (bufsize < 0L && bufsize != -1L)
+ comerrno(EX_BAD, "Bad transfer size option.\n");
+ if (bufsize < 0L)
+ bufsize = CDR_BUF_SIZE;
+ if (bufsize > CDR_MAX_BUF_SIZE)
+ bufsize = CDR_MAX_BUF_SIZE;
+
+ dev = *devp;
+ cdr_defaults(&dev, &speed, &fs, &driveropts);
+ if (debug) {
+ printf("dev: '%s' speed: %d fs: %ld driveropts '%s'\n",
+ dev, speed, fs, driveropts);
+ }
+ if (speed >= 0)
+ *speedp = speed;
+
+ if (fs < 0L)
+ fs = DEFAULT_FIFOSIZE;
+ if (fs < 2*bufsize) {
+ errmsgno(EX_BAD, "Fifo size %ld too small, turning fifo off.\n", fs);
+ fs = 0L;
+ }
+
+ if (dev != *devp && (*flagsp & F_SCANBUS) == 0)
+ *devp = dev;
+
+ if (!*devp && (*flagsp & (F_VERSION|F_SCANBUS)) == 0) {
+ errmsgno(EX_BAD, "No CD/DVD-Recorder device specified.\n");
+ susage(EX_BAD);
+ }
+ if (*devp &&
+ ((strncmp(*devp, "HELP", 4) == 0) ||
+ (strncmp(*devp, "help", 4) == 0))) {
+ *flagsp |= F_CHECKDRIVE; /* Set this for not calling mlockall() */
+ return ispacket;
+ }
+ 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)) {
+ if (tracks != 0) {
+ errmsgno(EX_BAD, "No tracks allowed with this option\n");
+ susage(EX_BAD);
+ }
+ return ispacket;
+ }
+ *tracksp = tracks;
+ if (*flagsp & F_SAO) {
+ /*
+ * Make sure that you change WRITER_MAXWAIT & READER_MAXWAIT
+ * too if you change this timeout.
+ */
+ if (*timeoutp < 200) /* Lead in size is 2:30 */
+ *timeoutp = 200; /* 200s is 150s *1.33 */
+ }
+ if (usetext) {
+ trackp[MAX_TRACK+1].flags |= TI_TEXT;
+ }
+ if (cuefile) {
+#ifdef FUTURE
+ if ((*flagsp & F_SAO) == 0 &&
+ (*flagsp & F_RAW) == 0) {
+#else
+ if ((*flagsp & F_SAO) == 0) {
+#endif
+ errmsgno(EX_BAD, "The cuefile= option only works with -dao.\n");
+ susage(EX_BAD);
+ }
+ if (tracks > 0) {
+ errmsgno(EX_BAD, "No tracks allowed with the cuefile= option\n");
+ susage(EX_BAD);
+ }
+ cuefilename = cuefile;
+ return ispacket;
+ }
+ if (tracks == 0 && (*flagsp & (F_LOAD|F_DLCK|F_EJECT|F_BLANK|F_FORMAT)) == 0) {
+ errmsgno(EX_BAD, "No tracks specified. Need at least one.\n");
+ susage(EX_BAD);
+ }
+ return ispacket;
+}
+
+static void
+set_trsizes(cdr_t *dp, int tracks, track_t *trackp)
+{
+ int i;
+ int secsize;
+ int secspt;
+
+ trackp[1].flags |= TI_FIRST;
+ trackp[tracks].flags |= TI_LAST;
+
+ if (xdebug)
+ printf("Set Transfersizes start\n");
+ for (i = 0; i <= tracks+1; i++) {
+ if ((dp->cdr_flags & CDR_SWABAUDIO) != 0 &&
+ is_audio(&trackp[i])) {
+ trackp[i].flags ^= TI_SWAB;
+ }
+ if (!is_audio(&trackp[i]))
+ trackp[i].flags &= ~TI_SWAB; /* Only swab audio */
+
+ /*
+ * Use the biggest sector size to compute how many
+ * sectors may fit into one single DMA buffer.
+ */
+ secsize = trackp[i].secsize;
+ if (trackp[i].isecsize > secsize)
+ secsize = trackp[i].isecsize;
+
+ /*
+ * We are using SCSI Group 0 write
+ * and cannot write more than 255 secs at once.
+ */
+ secspt = bufsize/secsize;
+ secspt = min(255, secspt);
+ trackp[i].secspt = secspt;
+
+ if (is_packet(&trackp[i]) && trackp[i].pktsize > 0) {
+ if (trackp[i].secspt >= trackp[i].pktsize) {
+ trackp[i].secspt = trackp[i].pktsize;
+ } else {
+ comerrno(EX_BAD,
+ "Track %d packet size %d exceeds buffer limit of %d sectors",
+ i, trackp[i].pktsize, trackp[i].secspt);
+ }
+ }
+ if (xdebug) {
+ printf("Track %d flags %X secspt %d secsize: %d isecsize: %d\n",
+ i, trackp[i].flags, trackp[i].secspt,
+ trackp[i].secsize, trackp[i].isecsize);
+ }
+ }
+ if (xdebug)
+ printf("Set Transfersizes end\n");
+}
+
+void
+load_media(SCSI *scgp, cdr_t *dp, BOOL doexit)
+{
+ int code;
+ int key;
+ BOOL immed = (dp->cdr_cmdflags&F_IMMED) != 0;
+
+ /*
+ * Do some preparation before...
+ */
+ scgp->silent++; /* Be quiet if this fails */
+ test_unit_ready(scgp); /* First eat up unit attention */
+ if ((*dp->cdr_load)(scgp, dp) < 0) { /* now try to load media and */
+ if (!doexit)
+ return;
+ comerrno(EX_BAD, "Cannot load media.\n");
+ }
+ scsi_start_stop_unit(scgp, 1, 0, immed); /* start unit in silent mode */
+ scgp->silent--;
+
+ if (!wait_unit_ready(scgp, 60)) {
+ code = scg_sense_code(scgp);
+ key = scg_sense_key(scgp);
+ scgp->silent++;
+ scsi_prevent_removal(scgp, 0); /* In case someone locked it */
+ scgp->silent--;
+
+ if (!doexit)
+ return;
+ if (key == SC_NOT_READY && (code == 0x3A || code == 0x30))
+ comerrno(EX_BAD, "No disk / Wrong disk!\n");
+ comerrno(EX_BAD, "CD/DVD-Recorder not ready.\n");
+ }
+
+ scsi_prevent_removal(scgp, 1);
+ scsi_start_stop_unit(scgp, 1, 0, immed);
+ wait_unit_ready(scgp, 120);
+ scgp->silent++;
+ if(geteuid() == 0) /* EB: needed? Not allowed for non-root, that is sure. */
+ rezero_unit(scgp); /* Is this needed? Not supported by some drvives */
+ scgp->silent--;
+ test_unit_ready(scgp);
+ scsi_start_stop_unit(scgp, 1, 0, immed);
+ wait_unit_ready(scgp, 120);
+}
+
+void
+unload_media(SCSI *scgp, cdr_t *dp, int flags)
+{
+ scsi_prevent_removal(scgp, 0);
+ if ((flags & F_EJECT) != 0) {
+ if ((*dp->cdr_unload)(scgp, dp) < 0)
+ errmsgno(EX_BAD, "Cannot eject media.\n");
+ }
+}
+
+void
+reload_media(SCSI *scgp, cdr_t *dp)
+{
+ char ans[2];
+#ifdef F_GETFL
+ int f = -1;
+#endif
+
+ errmsgno(EX_BAD, "Drive needs to reload the media to return to proper status.\n");
+ unload_media(scgp, dp, F_EJECT);
+
+ /*
+ * Note that even Notebook drives identify as CDR_TRAYLOAD
+ */
+ if ((dp->cdr_flags & CDR_TRAYLOAD) != 0) {
+ scgp->silent++;
+ load_media(scgp, dp, FALSE);
+ scgp->silent--;
+ }
+
+ scgp->silent++;
+ if (((dp->cdr_flags & CDR_TRAYLOAD) == 0) ||
+ !wait_unit_ready(scgp, 5)) {
+ static FILE *tty = NULL;
+
+ printf("Re-load disk and hit <CR>");
+ if (isgui)
+ printf("\n");
+ flush();
+
+ if (tty == NULL) {
+ tty = stdin;
+ if ((dp->cdr_cmdflags & F_STDIN) != 0)
+ tty = fileluopen(STDERR_FILENO, "rw");
+ }
+#ifdef F_GETFL
+ if (tty != NULL)
+ f = fcntl(fileno(tty), F_GETFL, 0);
+ if (f < 0 || (f & O_ACCMODE) == O_WRONLY) {
+#ifdef SIGUSR1
+ signal(SIGUSR1, catchsig);
+ printf("Controlling file not open for reading, send SIGUSR1 to continue.\n");
+ flush();
+ pause();
+#endif
+ } else
+#endif
+ if (fgetline(tty, ans, 1) < 0)
+ comerrno(EX_BAD, "Aborted by EOF on input.\n");
+ }
+ scgp->silent--;
+
+ load_media(scgp, dp, TRUE);
+}
+
+void
+set_secsize(SCSI *scgp, int secsize)
+{
+ if (secsize > 0) {
+ /*
+ * Try to restore the old sector size.
+ */
+ scgp->silent++;
+ select_secsize(scgp, secsize);
+ scgp->silent--;
+ }
+}
+
+static int
+get_dmaspeed(SCSI *scgp, cdr_t *dp)
+{
+ int i;
+ long t;
+ int bs;
+ int tsize;
+
+ if(getenv("CDR_NODMATEST"))
+ return -1;
+
+ if (debug || lverbose)
+ fprintf( stderr,
+ "Beginning DMA speed test. Set CDR_NODMATEST environment variable if device\n"
+ "communication breaks or freezes immediately after that.\n" );
+
+ fillbytes((caddr_t)buf, 4, '\0');
+ tsize = 0;
+ scgp->silent++;
+ i = read_buffer(scgp, buf, 4, 0);
+ scgp->silent--;
+ if (i < 0)
+ return (-1);
+ tsize = a_to_u_4_byte(buf);
+ if (tsize <= 0)
+ return (-1);
+
+ if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+ return (-1);
+
+ bs = bufsize;
+ if (tsize < bs)
+ bs = tsize;
+ for (i = 0; i < 100; i++) {
+ if (read_buffer(scgp, buf, bs, 0) < 0)
+ return (-1);
+ }
+ if (gettimeofday(&fixtime, (struct timezone *)0) < 0) {
+ errmsg("Cannot get DMA stop time\n");
+ return (-1);
+ }
+ timevaldiff(&starttime, &fixtime);
+ tsize = bs * 100;
+ t = fixtime.tv_sec * 1000 + fixtime.tv_usec / 1000;
+ if (t <= 0)
+ return (-1);
+#ifdef DEBUG
+ fprintf(stderr, "Read Speed: %lu %ld %ld kB/s %ldx CD %ldx DVD\n",
+ tsize, t, tsize/t, tsize/t/176, tsize/t/1385);
+#endif
+
+ return (tsize/t);
+}
+
+
+static BOOL
+do_opc(SCSI *scgp, cdr_t *dp, int flags)
+{
+ if ((flags & F_DUMMY) == 0 && dp->cdr_opc) {
+ if (debug || lverbose) {
+ printf("Performing OPC...\n");
+ flush();
+ }
+ if (dp->cdr_opc(scgp, NULL, 0, TRUE) < 0) {
+ errmsgno(EX_BAD, "OPC failed.\n");
+ if ((flags & F_FORCE) == 0)
+ return (FALSE);
+ }
+ }
+ return (TRUE);
+}
+
+static void
+check_recovery(SCSI *scgp, cdr_t *dp, int flags)
+{
+ if ((*dp->cdr_check_recovery)(scgp, dp)) {
+ errmsgno(EX_BAD, "Recovery needed.\n");
+ unload_media(scgp, dp, flags);
+ comexit(EX_BAD);
+ }
+}
+
+#ifndef DEBUG
+#define DEBUG
+#endif
+void
+audioread(SCSI *scgp, cdr_t *dp, int flags)
+{
+#ifdef DEBUG
+ int speed = 1;
+ int oflags = dp->cdr_cmdflags;
+
+ dp->cdr_cmdflags &= ~F_DUMMY;
+ if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0)
+ comexit(-1);
+ dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */
+ dp->cdr_cmdflags = oflags;
+
+ if ((*dp->cdr_set_secsize)(scgp, 2352) < 0)
+ comexit(-1);
+ scgp->cap->c_bsize = 2352;
+
+ read_scsi(scgp, buf, 1000, 1);
+ printf("XXX:\n");
+ write(1, buf, 512);
+ unload_media(scgp, dp, flags);
+ comexit(0);
+#endif
+}
+
+static void
+print_msinfo(SCSI *scgp, cdr_t *dp)
+{
+ long off;
+ long fa;
+
+ if ((*dp->cdr_session_offset)(scgp, &off) < 0) {
+ errmsgno(EX_BAD, "Cannot read session offset\n");
+ return;
+ }
+ if (lverbose)
+ printf("session offset: %ld\n", off);
+
+ if (dp->cdr_next_wr_address(scgp, (track_t *)0, &fa) < 0) {
+ errmsgno(EX_BAD, "Cannot read first writable address\n");
+ return;
+ }
+ printf("%ld,%ld\n", off, fa);
+}
+
+static void
+print_toc(SCSI *scgp, cdr_t *dp)
+{
+ int first;
+ int last;
+ long lba;
+ long xlba;
+ struct msf msf;
+ int adr;
+ int control;
+ int mode;
+ int i;
+
+ scgp->silent++;
+ if (read_capacity(scgp) < 0) {
+ scgp->silent--;
+ errmsgno(EX_BAD, "Cannot read capacity\n");
+ return;
+ }
+ scgp->silent--;
+ if (read_tochdr(scgp, dp, &first, &last) < 0) {
+ errmsgno(EX_BAD, "Cannot read TOC/PMA\n");
+ return;
+ }
+ printf("first: %d last %d\n", first, last);
+ for (i = first; i <= last; i++) {
+ read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
+ xlba = -150 +
+ msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
+ if (xlba == lba/4)
+ lba = xlba;
+ print_track(i, lba, &msf, adr, control, mode);
+ }
+ i = 0xAA;
+ read_trackinfo(scgp, i, &lba, &msf, &adr, &control, &mode);
+ xlba = -150 +
+ msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min);
+ if (xlba == lba/4)
+ lba = xlba;
+ print_track(i, lba, &msf, adr, control, mode);
+ if (lverbose > 1) {
+ scgp->silent++;
+ if (read_cdtext(scgp) < 0)
+ errmsgno(EX_BAD, "No CD-Text or CD-Text unaware drive.\n");
+ scgp->silent++;
+ }
+}
+
+static void
+print_track(int track, long lba, struct msf *msp, int adr,
+ int control, int mode)
+{
+ long lba_512 = lba*4;
+
+ if (track == 0xAA)
+ printf("track:lout ");
+ else
+ printf("track: %3d ", track);
+
+ printf("lba: %9ld (%9ld) %02d:%02d:%02d adr: %X control: %X mode: %d\n",
+ lba, lba_512,
+ msp->msf_min,
+ msp->msf_sec,
+ msp->msf_frame,
+ adr, control, mode);
+}
+
+#ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */
+
+#include <sys/procset.h> /* Needed for SCO Openserver */
+#include <sys/priocntl.h>
+#include <sys/rtpriocntl.h>
+
+void
+raisepri(int pri)
+{
+ int pid;
+ int classes;
+ int ret;
+ pcinfo_t info;
+ pcparms_t param;
+ rtinfo_t rtinfo;
+ rtparms_t rtparam;
+
+ pid = getpid();
+
+ /* get info */
+ strcpy(info.pc_clname, "RT");
+ classes = priocntl(P_PID, pid, PC_GETCID, (void *)&info);
+ if (classes == -1)
+ comerr("Cannot get priority class id priocntl(PC_GETCID)\n");
+
+ movebytes(info.pc_clinfo, &rtinfo, sizeof (rtinfo_t));
+
+ /* set priority to max */
+ rtparam.rt_pri = rtinfo.rt_maxpri - pri;
+ rtparam.rt_tqsecs = 0;
+ rtparam.rt_tqnsecs = RT_TQDEF;
+ param.pc_cid = info.pc_cid;
+ movebytes(&rtparam, param.pc_clparms, sizeof (rtparms_t));
+ ret = priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m);
+ if (ret == -1) {
+ errmsg("WARNING: Cannot set priority class parameters priocntl(PC_SETPARMS)\n");
+ errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
+ }
+}
+
+#else /* HAVE_SYS_PRIOCNTL_H */
+
+#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0
+/*
+ * The second best choice: POSIX real time scheduling.
+ */
+/*
+ * XXX Ugly but needed because of a typo in /usr/iclude/sched.h on Linux.
+ * XXX This should be removed as soon as we are sure that Linux-2.0.29 is gone.
+ */
+#ifdef __linux
+#define _P __P
+#endif
+
+#include <sched.h>
+
+#ifdef __linux
+#undef _P
+#endif
+
+static int
+rt_raisepri(int pri)
+{
+ struct sched_param scp;
+
+ /*
+ * Verify that scheduling is available
+ */
+#ifdef _SC_PRIORITY_SCHEDULING
+ if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) {
+ errmsg("WARNING: RR-scheduler not available, disabling.\n");
+ return (-1);
+ }
+#endif
+ fillbytes(&scp, sizeof (scp), '\0');
+ scp.sched_priority = sched_get_priority_max(SCHED_RR) - pri;
+ if (sched_setscheduler(0, SCHED_RR, &scp) < 0) {
+ errmsg("WARNING: Cannot set RR-scheduler\n");
+ return (-1);
+ }
+ return (0);
+}
+
+#else /* _POSIX_PRIORITY_SCHEDULING */
+
+#ifdef __CYGWIN32__
+/*
+ * Win32 specific priority settings.
+ */
+/*
+ * NOTE: Base.h from Cygwin-B20 has a second typedef for BOOL.
+ * We define BOOL to make all static code use BOOL
+ * from Windows.h and use the hidden __SBOOL for
+ * our global interfaces.
+ *
+ * NOTE: windows.h from Cygwin-1.x includes a structure field named sample,
+ * so me may not define our own 'sample' or need to #undef it now.
+ * With a few nasty exceptions, Microsoft assumes that any global
+ * defines or identifiers will begin with an Uppercase letter, so
+ * there may be more of these problems in the future.
+ *
+ * NOTE: windows.h defines interface as an alias for struct, this
+ * is used by COM/OLE2, I guess it is class on C++
+ * We man need to #undef 'interface'
+ */
+#define BOOL WBOOL /* This is the Win BOOL */
+#define format __format /* Avoid format parameter hides global ... */
+#include <windows.h>
+#undef format
+#undef interface
+
+static int
+rt_raisepri(int pri)
+{
+ int prios[] = {THREAD_PRIORITY_TIME_CRITICAL, THREAD_PRIORITY_HIGHEST};
+
+ /* set priority class */
+ if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) {
+ errmsgno(EX_BAD, "No realtime priority class possible.\n");
+ return (-1);
+ }
+
+ /* set thread priority */
+ if (pri >= 0 && pri <= 1 && SetThreadPriority(GetCurrentThread(), prios[pri]) == FALSE) {
+ errmsgno(EX_BAD, "Could not set realtime priority.\n");
+ return (-1);
+ }
+ return (0);
+}
+
+#else
+/*
+ * This OS does not support real time scheduling.
+ */
+static int
+rt_raisepri(int pri)
+{
+ return (-1);
+}
+
+#endif /* __CYGWIN32__ */
+
+#endif /* _POSIX_PRIORITY_SCHEDULING */
+
+void
+raisepri(int pri)
+{
+ if (rt_raisepri(pri) >= 0)
+ return;
+#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
+
+ if (setpriority(PRIO_PROCESS, getpid(), -20 + pri) < 0) {
+ errmsg("WARNING: Cannot set priority using setpriority().\n");
+ errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
+ }
+#else
+#ifdef HAVE_DOSSETPRIORITY /* RT priority on OS/2 */
+ /*
+ * Set priority to timecritical 31 - pri (arg)
+ */
+ DosSetPriority(0, 3, 31, 0);
+ DosSetPriority(0, 3, -pri, 0);
+#else
+#if defined(HAVE_NICE) && !defined(__DJGPP__) /* DOS has nice but no multitasking */
+ if (nice(-20 + pri) == -1) {
+ errmsg("WARNING: Cannot set priority using nice().\n");
+ errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
+ }
+#else
+ errmsgno(EX_BAD, "WARNING: Cannot set priority on this OS.\n");
+ errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n");
+#endif
+#endif
+#endif
+}
+
+#endif /* HAVE_SYS_PRIOCNTL_H */
+
+#ifdef HAVE_SELECT
+/*
+ * sys/types.h and sys/time.h are already included.
+ */
+#else
+# include <stropts.h>
+# include <poll.h>
+
+#ifndef INFTIM
+#define INFTIM (-1)
+#endif
+#endif
+
+#if defined(HAVE_SELECT) && defined(NEED_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+#if defined(HAVE_SELECT) && defined(NEED_SYS_SOCKET_H)
+#include <sys/socket.h>
+#endif
+
+static void
+wait_input()
+{
+#ifdef HAVE_SELECT
+ fd_set in;
+
+ FD_ZERO(&in);
+ FD_SET(STDIN_FILENO, &in);
+ select(1, &in, NULL, NULL, 0);
+#else
+ struct pollfd pfd;
+
+ pfd.fd = STDIN_FILENO;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ poll(&pfd, (unsigned long)1, INFTIM);
+#endif
+}
+
+static void
+checkgui()
+{
+ struct stat st;
+
+ if (fstat(STDERR_FILENO, &st) >= 0 && !S_ISCHR(st.st_mode)) {
+ isgui = TRUE;
+ if (lverbose > 1)
+ printf("Using remote (pipe) mode for interactive i/o.\n");
+ }
+}
+
+static int
+getbltype(char *optstr, long *typep)
+{
+ if (streql(optstr, "all")) {
+ *typep = BLANK_DISC;
+ } else if (streql(optstr, "disc")) {
+ *typep = BLANK_DISC;
+ } else if (streql(optstr, "disk")) {
+ *typep = BLANK_DISC;
+ } else if (streql(optstr, "fast")) {
+ *typep = BLANK_MINIMAL;
+ } else if (streql(optstr, "minimal")) {
+ *typep = BLANK_MINIMAL;
+ } else if (streql(optstr, "track")) {
+ *typep = BLANK_TRACK;
+ } else if (streql(optstr, "unreserve")) {
+ *typep = BLANK_UNRESERVE;
+ } else if (streql(optstr, "trtail")) {
+ *typep = BLANK_TAIL;
+ } else if (streql(optstr, "unclose")) {
+ *typep = BLANK_UNCLOSE;
+ } else if (streql(optstr, "session")) {
+ *typep = BLANK_SESSION;
+ } else if (streql(optstr, "help")) {
+ blusage(0);
+ } else {
+ fprintf(stderr, "Illegal blanking type '%s'.\n", optstr);
+ blusage(EX_BAD);
+ return (-1);
+ }
+ return (TRUE);
+}
+
+static int
+getformattype(char *optstr, long *typep)
+{
+ if (streql(optstr, "full")) {
+ *typep = FULL_FORMAT;
+ } else if (streql(optstr, "background")) {
+ *typep = BACKGROUND_FORMAT;
+ } else if (streql(optstr, "force")) {
+ *typep = FORCE_FORMAT;
+ } else if (streql(optstr, "help")) {
+ formattypeusage(0);
+ } else {
+ fprintf(stderr, "Illegal blanking type '%s'.\n", optstr);
+ formattypeusage(EX_BAD);
+ return (-1);
+ }
+ return (TRUE);
+}
+static void
+print_drflags(cdr_t *dp)
+{
+ printf("Driver flags : ");
+
+ if ((dp->cdr_flags & CDR_DVD) != 0)
+ printf("DVD ");
+
+ if ((dp->cdr_flags & CDR_MMC3) != 0)
+ printf("MMC-3 ");
+ else if ((dp->cdr_flags & CDR_MMC2) != 0)
+ printf("MMC-2 ");
+ else if ((dp->cdr_flags & CDR_MMC) != 0)
+ printf("MMC ");
+
+ if ((dp->cdr_flags & CDR_SWABAUDIO) != 0)
+ printf("SWABAUDIO ");
+ if ((dp->cdr_flags & CDR_BURNFREE) != 0)
+ printf("BURNFREE ");
+ if ((dp->cdr_flags & CDR_VARIREC) != 0)
+ printf("VARIREC ");
+ if ((dp->cdr_flags & CDR_GIGAREC) != 0)
+ printf("GIGAREC ");
+ if ((dp->cdr_flags & CDR_AUDIOMASTER) != 0)
+ printf("AUDIOMASTER ");
+ if ((dp->cdr_flags & CDR_FORCESPEED) != 0)
+ printf("FORCESPEED ");
+ if ((dp->cdr_flags & CDR_SPEEDREAD) != 0)
+ printf("SPEEDREAD ");
+ if ((dp->cdr_flags & CDR_DISKTATTOO) != 0)
+ printf("DISKTATTOO ");
+ if ((dp->cdr_flags & CDR_SINGLESESS) != 0)
+ printf("SINGLESESSION ");
+ if ((dp->cdr_flags & CDR_HIDE_CDR) != 0)
+ printf("HIDECDR ");
+ printf("\n");
+}
+
+static void
+print_wrmodes(cdr_t *dp)
+{
+ BOOL needblank = FALSE;
+
+ printf("Supported modes: ");
+ if ((dp->cdr_flags & CDR_TAO) != 0) {
+ printf("TAO");
+ needblank = TRUE;
+ }
+ if ((dp->cdr_flags & CDR_PACKET) != 0) {
+ printf("%sPACKET", needblank?" ":"");
+ needblank = TRUE;
+ }
+ if ((dp->cdr_flags & CDR_SAO) != 0) {
+ printf("%sSAO", needblank?" ":"");
+ needblank = TRUE;
+ }
+#ifdef __needed__
+ if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW16)) == (CDR_SAO|CDR_SRAW16)) {
+ printf("%sSAO/R16", needblank?" ":"");
+ needblank = TRUE;
+ }
+#endif
+ if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96P)) == (CDR_SAO|CDR_SRAW96P)) {
+ printf("%sSAO/R96P", needblank?" ":"");
+ needblank = TRUE;
+ }
+ if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96R)) == (CDR_SAO|CDR_SRAW96R)) {
+ printf("%sSAO/R96R", needblank?" ":"");
+ needblank = TRUE;
+ }
+ if ((dp->cdr_flags & (CDR_RAW|CDR_RAW16)) == (CDR_RAW|CDR_RAW16)) {
+ printf("%sRAW/R16", needblank?" ":"");
+ needblank = TRUE;
+ }
+ if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96P)) == (CDR_RAW|CDR_RAW96P)) {
+ printf("%sRAW/R96P", needblank?" ":"");
+ needblank = TRUE;
+ }
+ if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96R)) == (CDR_RAW|CDR_RAW96R)) {
+ printf("%sRAW/R96R", needblank?" ":"");
+ needblank = TRUE;
+ }
+ printf("\n");
+}
+
+static BOOL
+check_wrmode(cdr_t *dp, int wmode, int tflags)
+{
+ int cdflags = dp->cdr_flags;
+
+ if ((tflags & TI_PACKET) != 0 && (cdflags & CDR_PACKET) == 0) {
+ errmsgno(EX_BAD, "Drive does not support PACKET recording.\n");
+ return (FALSE);
+ }
+ if ((tflags & TI_TAO) != 0 && (cdflags & CDR_TAO) == 0) {
+ errmsgno(EX_BAD, "Drive does not support TAO recording.\n");
+ return (FALSE);
+ }
+ if ((wmode & F_SAO) != 0) {
+ if ((cdflags & CDR_SAO) == 0) {
+ errmsgno(EX_BAD, "Drive does not support SAO recording.\n");
+ if ((cdflags & CDR_RAW) != 0)
+ errmsgno(EX_BAD, "Try -raw option.\n");
+ return (FALSE);
+ }
+#ifdef __needed__
+ if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_SRAW16) == 0) {
+ errmsgno(EX_BAD, "Drive does not support SAO/RAW16.\n");
+ goto badsecs;
+ }
+#endif
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_SRAW96P) == 0) {
+ errmsgno(EX_BAD, "Drive does not support SAO/RAW96P.\n");
+ goto badsecs;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_SRAW96R) == 0) {
+ errmsgno(EX_BAD, "Drive does not support SAO/RAW96R.\n");
+ goto badsecs;
+ }
+ }
+ if ((wmode & F_RAW) != 0) {
+ if ((cdflags & CDR_RAW) == 0) {
+ errmsgno(EX_BAD, "Drive does not support RAW recording.\n");
+ return (FALSE);
+ }
+ if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_RAW16) == 0) {
+ errmsgno(EX_BAD, "Drive does not support RAW/RAW16.\n");
+ goto badsecs;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_RAW96P) == 0) {
+ errmsgno(EX_BAD, "Drive does not support RAW/RAW96P.\n");
+ goto badsecs;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_RAW96R) == 0) {
+ errmsgno(EX_BAD, "Drive does not support RAW/RAW96R.\n");
+ goto badsecs;
+ }
+ }
+ return (TRUE);
+
+badsecs:
+ if ((wmode & F_SAO) != 0)
+ cdflags &= ~(CDR_RAW16|CDR_RAW96P|CDR_RAW96R);
+ if ((wmode & F_RAW) != 0)
+ cdflags &= ~(CDR_SRAW96P|CDR_SRAW96R);
+
+ if ((cdflags & (CDR_SRAW96R|CDR_RAW96R)) != 0)
+ errmsgno(EX_BAD, "Try -raw96r option.\n");
+ else if ((cdflags & (CDR_SRAW96P|CDR_RAW96P)) != 0)
+ errmsgno(EX_BAD, "Try -raw96p option.\n");
+ else if ((cdflags & CDR_RAW16) != 0)
+ errmsgno(EX_BAD, "Try -raw16 option.\n");
+ return (FALSE);
+}
+
+static void
+set_wrmode(cdr_t *dp, int wmode, int tflags)
+{
+ dstat_t *dsp = dp->cdr_dstat;
+
+ if ((tflags & TI_PACKET) != 0) {
+ dsp->ds_wrmode = WM_PACKET;
+ return;
+ }
+ if ((tflags & TI_TAO) != 0) {
+ dsp->ds_wrmode = WM_TAO;
+ return;
+ }
+ if ((wmode & F_SAO) != 0) {
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == 0) {
+ dsp->ds_wrmode = WM_SAO;
+ return;
+ }
+ if ((tflags & TI_RAW16) != 0) { /* Is this needed? */
+ dsp->ds_wrmode = WM_SAO_RAW16;
+ return;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) {
+ dsp->ds_wrmode = WM_SAO_RAW96P;
+ return;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) {
+ dsp->ds_wrmode = WM_SAO_RAW96R;
+ return;
+ }
+ }
+ if ((wmode & F_RAW) != 0) {
+ if ((tflags & TI_RAW16) != 0) {
+ dsp->ds_wrmode = WM_RAW_RAW16;
+ return;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) {
+ dsp->ds_wrmode = WM_RAW_RAW96P;
+ return;
+ }
+ if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) {
+ dsp->ds_wrmode = WM_RAW_RAW96R;
+ return;
+ }
+ }
+ dsp->ds_wrmode = WM_NONE;
+}
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+#endif
+
+#ifdef __linux__
+static int
+get_cap(cap_value_t cap_array)
+{
+ int ret;
+ cap_t capa;
+ capa = cap_get_proc();
+ cap_set_flag(capa, CAP_EFFECTIVE, 1, &cap_array, CAP_SET);
+ ret = cap_set_proc(capa);
+ cap_free(capa);
+ return ret;
+}
+#endif
Copied: cdrkit/trunk/cdrecord/wodim.h (from rev 413, cdrkit/trunk/cdrecord/cdrecord.h)
Modified: cdrkit/trunk/debian/changelog
===================================================================
--- cdrkit/trunk/debian/changelog 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/debian/changelog 2006-11-21 18:34:28 UTC (rev 415)
@@ -1,3 +1,9 @@
+cdrkit (5:1.1.1-1) unstable; urgency=low
+
+ * Development snapshot
+
+ -- Eduard Bloch <blade at debian.org> Mon, 20 Nov 2006 23:40:19 +0100
+
cdrkit (5:1.0-1) unstable; urgency=high
[ Eduard Bloch ]
Modified: cdrkit/trunk/mkisofs/scsi.c
===================================================================
--- cdrkit/trunk/mkisofs/scsi.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/mkisofs/scsi.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -46,7 +46,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "../cdrecord/defaults.h"
/*
Modified: cdrkit/trunk/readcd/readcd.c
===================================================================
--- cdrkit/trunk/readcd/readcd.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/readcd/readcd.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -60,7 +60,7 @@
#include "scsi_scan.h"
#include "scsimmc.h"
#define qpto96 __nothing__
-#include "cdrecord.h"
+#include "wodim.h"
#include "defaults.h"
#undef qpto96
#include "movesect.h"
Modified: cdrkit/trunk/scgcheck/dmaresid.c
===================================================================
--- cdrkit/trunk/scgcheck/dmaresid.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/scgcheck/dmaresid.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -48,7 +48,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "scgcheck.h"
void dmaresid(SCSI *scgp);
Modified: cdrkit/trunk/scgcheck/scgcheck.c
===================================================================
--- cdrkit/trunk/scgcheck/scgcheck.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/scgcheck/scgcheck.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -49,7 +49,7 @@
#include <scg/scsitransp.h>
#include "scsi_scan.h"
-#include "cdrecord.h"
+#include "wodim.h"
#include "scgcheck.h"
static void usage(int ret);
Modified: cdrkit/trunk/scgcheck/sense.c
===================================================================
--- cdrkit/trunk/scgcheck/sense.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/scgcheck/sense.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -48,7 +48,7 @@
#include <scg/scsireg.h>
#include <scg/scsitransp.h>
-#include "cdrecord.h"
+#include "wodim.h"
#include "scgcheck.h"
extern char *buf; /* The transfer buffer */
Modified: cdrkit/trunk/scgskeleton/skel.c
===================================================================
--- cdrkit/trunk/scgskeleton/skel.c 2006-11-21 17:59:10 UTC (rev 414)
+++ cdrkit/trunk/scgskeleton/skel.c 2006-11-21 18:34:28 UTC (rev 415)
@@ -58,7 +58,7 @@
#include <scg/scsitransp.h>
#include "scsi_scan.h"
-#include "cdrecord.h"
+#include "wodim.h"
#include "defaults.h"
char skel_version[] = "1.1";
More information about the Debburn-changes
mailing list