⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdrecord.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* @(#)cdrecord.c	1.94 00/01/28 Copyright 1995-2000 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)cdrecord.c	1.94 00/01/28 Copyright 1995-2000 J. Schilling";#endif/* *	Record data on a CD/CVD-Recorder * *	Copyright (c) 1995-2000 J. Schilling *//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * 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, 675 Mass Ave, Cambridge, MA 02139, USA. */#include <mconfig.h>#include <stdio.h>#include <standard.h>#include <stdxlib.h>#include <fctldefs.h>#include <errno.h>#include <sys/types.h>#include <sys/time.h>#ifdef	HAVE_SYS_RESOURCE_H#include <sys/resource.h>	/* for rlimit */#endif#include <sys/stat.h>#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 <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"char	cdr_version[] = "1.8";/* * 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 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 1",		"CD-ROM XA mode 2 form 1",		"CD-ROM XA mode 2 form 2",		"CD-ROM XA mode 2 form 1/2/mix",		"Reserved mode 14",		"Vendor unique mode 15",};int		debug;		/* print debug messages */LOCAL	int	scsi_verbose;	/* SCSI verbose flag */int		lverbose;	/* local verbose flag *//* * NOTICE:	You should not make BUF_SIZE more than *		the buffer size of the CD-Recorder. * * Do not set BUF_SIZE to be more than 126 KBytes * if you are running cdrecord on a sun4c machine. * * WARNING:	Philips CDD 521 dies if BUF_SIZE is to big. *//*#define	BUF_SIZE	(126*1024)*//*#define	BUF_SIZE	(100*1024)*/#define	BUF_SIZE	(63*1024)/*#define	BUF_SIZE	(56*1024)*/char	*buf;			/* The transfer buffer */long	bufsize;		/* The size of the transfer buffer */int	data_secs_per_tr;	/* # of data secs per transfer */int	audio_secs_per_tr;	/* # of audio secs per transfer */BOOL	isgui;int	didintr;struct timeval	starttime;struct timeval	stoptime;struct timeval	fixtime;static	long	fs = -1L;	/* fifo (ring buffer) size */EXPORT	int 	main		__PR((int ac, char **av));LOCAL	void	usage		__PR((int));LOCAL	void	blusage		__PR((int));LOCAL	void	intr		__PR((int sig));LOCAL	void	intfifo		__PR((int sig));LOCAL	void	exscsi		__PR((int excode, void *arg));LOCAL	void	excdr		__PR((int excode, void *arg));EXPORT	int	read_buf	__PR((int f, char *bp, int size));EXPORT	int	get_buf		__PR((int f, char **bpp, int size));LOCAL	int	write_track_data __PR((SCSI *scgp, cdr_t *, int , track_t *));EXPORT	int	pad_track	__PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp,				     long startsec, long amt,				     BOOL dolast, long *bytesp));EXPORT	int	write_buf	__PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp,				     char *bp, long startsec, long amt, int secsize,				     BOOL dolast, long *bytesp));LOCAL	void	printdata	__PR((int, track_t *));LOCAL	void	printaudio	__PR((int, track_t *));LOCAL	void	checkfile	__PR((int, track_t *));LOCAL	int	checkfiles	__PR((int, track_t *));LOCAL	void	setpregaps	__PR((int, track_t *));LOCAL	long	checktsize	__PR((int, track_t *));LOCAL	void	checksize	__PR((track_t *));LOCAL	BOOL	checkdsize	__PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp, long tsize));LOCAL	void	raise_fdlim	__PR((void));LOCAL	void	gargs		__PR((int, char **, int *, track_t *, char **,					int *, cdr_t **,					int *, long *, int *, int *));LOCAL	void	set_trsizes	__PR((cdr_t *, int, track_t *));EXPORT	void	load_media	__PR((SCSI *scgp, cdr_t *, BOOL));EXPORT	void	unload_media	__PR((SCSI *scgp, cdr_t *, int));EXPORT	void	set_secsize	__PR((SCSI *scgp, int secsize));LOCAL	void	check_recovery	__PR((SCSI *scgp, cdr_t *, int));	void	audioread	__PR((SCSI *scgp, cdr_t *, int));LOCAL	void	print_msinfo	__PR((SCSI *scgp, cdr_t *));LOCAL	void	print_toc	__PR((SCSI *scgp, cdr_t *));LOCAL	void	print_track	__PR((int, long, struct msf *, int, int, int));LOCAL	void	prtimediff	__PR((const char *fmt,					struct timeval *start,					struct timeval *stop));#if !defined(HAVE_SYS_PRIOCNTL_H)LOCAL	int	rt_raisepri	__PR((int));#endifEXPORT	void	raisepri	__PR((int));LOCAL	void	checkgui	__PR((void));LOCAL	char *	astoll		__PR((const char *s, Llong *ll));LOCAL	Llong	number		__PR((char* arg, int* retp));EXPORT	int	getnum		__PR((char* arg, long* valp));EXPORT	int	getllnum	__PR((char *arg, Llong* lvalp));LOCAL	int	getbltype	__PR((char* optstr, long *typep));struct exargs {	SCSI	*scgp;	cdr_t	*dp;	int	old_secsize;	int	flags;	int	exflags;} exargs;EXPORT int main(ac, av)	int	ac;	char	*av[];{	char	*dev = NULL;	int	timeout = 40;	/* Set default timeout to 40s CW-7502 is slow*/	int	speed = 1;	long	flags = 0L;	int	toctype = -1;	int	blanktype = 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;	dstat_t	ds;	long	startsec = 0L;	int	errs = 0;	SCSI	*scgp;	char	errstr[80];#ifdef __EMX__ 	/* This gives wildcard expansion with Non-Posix shells with EMX */ 	_wildcard(&ac, &av); #endif 	save_args(ac, av);	fillbytes(track, sizeof(track), '\0');	raise_fdlim();	gargs(ac, av, &tracks, track, &dev, &timeout, &dp, &speed, &flags,							&toctype, &blanktype);	if (toctype < 0)		comerrno(EX_BAD, "Internal error: Bad TOC type.\n");	/*	 * Warning: you are not allowed to modify or to remove this	 * version printing code!	 */#ifdef	DRV_DVD	i = set_cdrcmds("mmc_dvd", (cdr_t **)NULL);#endif	if ((flags & F_MSINFO) == 0 || lverbose || flags & F_VERSION)		printf("Cdrecord%s %s (%s-%s-%s) Copyright (C) 1995-2000 J鰎g Schilling\n",#ifdef	DRV_DVD								i?"-ProDVD":"",#else								"",#endif								cdr_version,								HOST_CPU, HOST_VENDOR, HOST_OS);	if (flags & F_VERSION)		exit(0);	checkgui();	if (debug || lverbose) {		printf("TOC Type: %d = %s\n",			toctype, toc2name[toctype & 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 use /dev/scg?		 */#if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK)		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		raisepri(0); /* max priority */		init_fifo(fs);	}	if ((scgp = open_scsi(dev, errstr, sizeof(errstr),				debug, (flags & F_MSINFO) == 0 || lverbose)) == (SCSI *)0) {			errmsg("%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":"");			comerrno(EX_BAD, "For possible targets try 'cdrecord -scanbus'. Make sure you are root.\n");	}	scsi_settimeout(scgp, timeout);	scgp->verbose = scsi_verbose;	scgp->debug = debug;	scgp->cap->c_bsize = 2048;	if ((flags & F_MSINFO) == 0 || lverbose) {		char	*vers;		char	*auth;		/*		 * Warning: you are not allowed to modify or to remove this 		 * version checking code!		 */		vers = scg_version(0, SCG_VERSION);		auth = scg_version(0, SCG_AUTHOR);		printf("Using libscg version '%s-%s'\n", auth, vers);		if (auth == 0 || strcmp("schily", auth) != 0) {			errmsgno(EX_BAD,			"Warning: using inofficial version of libscg (%s-%s '%s').\n",				auth, vers, scg_version(0, SCG_SCCS_ID));		}		vers = scg_version(scgp, SCG_VERSION);		auth = scg_version(scgp, SCG_AUTHOR);		if (lverbose > 1)			error("Using libscg transport code version '%s-%s'\n", auth, vers);		if (auth == 0 || strcmp("schily", auth) != 0) {			errmsgno(EX_BAD,			"Warning: using inofficial libscg transport code version (%s-%s '%s').\n",				auth, vers, scg_version(scgp, SCG_SCCS_ID));		}	}	bufsize = scsi_bufsize(scgp, BUF_SIZE);	if ((buf = scsi_getbuf(scgp, bufsize)) == NULL)		comerr("Cannot get SCSI I/O buffer.\n");	if ((flags & F_SCANBUS) != 0) {		select_target(scgp);		exit(0);	}	if ((flags & F_RESET) != 0) {		scsireset(scgp);		exit(0);	}	/*	 * First try to check which type of SCSI device we	 * have.	 */	if (debug || lverbose)		printf("atapi: %d\n", scsi_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);	}	if ((flags & F_PRCAP) != 0) {		print_capabilities(scgp);		exit(0);	}	if ((flags & F_INQUIRY) != 0)		exit(0);	if (dp == (cdr_t *)NULL) {	/* No driver= option specified */		dp = get_cdrcmds(scgp);	} else if (!is_unknown_dev(scgp) && dp != get_cdrcmds(scgp)) {		errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n");	}	if (!is_cddrive(scgp))		comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n");	if (dp == (cdr_t *)0)		comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.\n");	if (((flags & (F_MSINFO|F_TOC|F_LOAD|F_EJECT)) == 0 || tracks > 0) &&					(dp->cdr_flags & CDR_ISREADER) != 0) {		comerrno(EX_BAD,		"Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.\n");	}	if ((*dp->cdr_attach)(scgp, dp) != 0)		comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.\n");	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);		printf("Driver flags   : ");		if ((dp->cdr_flags & CDR_SWABAUDIO) != 0)			printf("SWABAUDIO");		printf("\n");	}	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--;	if (tracks > 0 && (debug || lverbose))		printf("FIFO size      : %lu = %lu KB\n", fs, fs >> 10);	if ((flags & F_CHECKDRIVE) != 0)		exit(0);	if (tracks == 0 && (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 (tracks > 1)		sleep(2);	/* Let the user watch the inquiry messages */	set_trsizes(dp, tracks, track);	setpregaps(tracks, track);	checkfiles(tracks, track);	tsize = checktsize(tracks, track);do_cue(tracks, track, 0);	/*	 * Is this the right place to do this ?	 */	check_recovery(scgp, dp, flags);	if ((flags & F_FORCE) == 0)		load_media(scgp, dp, TRUE);	if ((flags & F_LOAD) != 0) {		scgp->silent++;			/* silently	     */		scsi_prevent_removal(scgp, 0);	/* allow manual open */		scgp->silent--;			/* if load failed... */		exit(0);	}	exargs.old_secsize = sense_secsize(scgp, 1);	if (exargs.old_secsize < 0)		exargs.old_secsize = sense_secsize(scgp, 0);	on_comerr(exscsi, &exargs);	if (lverbose)		printf("Current Secsize: %d\n", exargs.old_secsize);	if (exargs.old_secsize > 0 && exargs.old_secsize != 2048) {		/*		 * Some drives (e.g. Plextor) don't like to write correctly		 * in DAO 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, 2048);	}/*audioread(dp, flags);*//*unload_media(scgp, dp, flags);*//*return 0;*/	fillbytes(&ds, sizeof(ds), '\0');	if (flags & F_WRITE)		ds.ds_cdrflags = RF_WRITE;	if (flags & F_PRATIP) {		lverbose++;			/* XXX Hack */	}	if ((*dp->cdr_getdisktype)(scgp, dp, &ds) < 0) {		errmsgno(EX_BAD, "Cannot get disk type.\n");		exscsi(EX_BAD, &exargs);		if ((flags & F_FORCE) == 0)			exit(EX_BAD);	}	if (flags & F_PRATIP) {		lverbose--;			/* XXX Hack */		exscsi(0, &exargs);		exit(0);	}	/*	 * The next actions should depend on the disk type.	 */	/*	 * Dirty hack!	 * At least MMC drives will not return the next writable	 * address we expect when the drive's write mode is set	 * tp DAO/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. Set_speed_dummy() witha a	 * 'speedp' f 0 sets the write mode to TAO on MMC drives.	 *	 * We set TAO unconditionally to make checkdsize() work	 * currectly in DAO mode too.	 */	scgp->silent++;	(*dp->cdr_set_speed_dummy)(scgp, 0, TRUE);	scgp->silent--;	if (flags & F_MSINFO) {		print_msinfo(scgp, dp);		exscsi(0, &exargs);		exit(0);	}	if (flags & F_TOC) {		print_toc(scgp, dp);		exscsi(0, &exargs);		exit(0);	}#ifdef	XXX	if ((*dp->cdr_check_session)() < 0) {		exscsi(EX_BAD, &exargs);		exit(EX_BAD);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -