[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, &copy,
-				&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 *)&param);
-	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, &copy,
+				&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 *)&param);
+	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