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

📄 cdrecord.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	}#endif	if (tsize == 0) {		if (tracks > 0) {			errmsgno(EX_BAD,			"WARNING: Track size unknown. Data may not fit on disk.\n");		}	} else if (!checkdsize(scgp, dp, &ds, tsize) && (flags & (F_IGNSIZE|F_FORCE)) == 0) {		exscsi(EX_BAD, &exargs);		exit(EX_BAD);	}	if (tracks > 0 && fs > 0l) {		/*		 * Start the extra process needed for improved buffering.		 */		if (!init_faio(tracks, track, bufsize))			fs = 0L;		else			on_comerr(excdr, &exargs);	}	if ((*dp->cdr_set_speed_dummy)(scgp, &speed, flags & F_DUMMY) < 0) {		errmsgno(EX_BAD, "Cannot set speed/dummy.\n");		excdr(EX_BAD, &exargs);		exit(EX_BAD);	}	if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) {		wait_unit_ready(scgp, 120);		scsi_blank(scgp, 0L, blanktype);		excdr(0, &exargs);		exit(0);	}	/*	 * Last chance to quit!	 */	printf("Starting to write CD/DVD at speed %d in %s mode for %s session.\n",		speed,		(flags & F_DUMMY) ? "dummy" : "write",		(flags & F_MULTI) ? "multi" : "single");	printf("Last chance to quit, starting %s write in 9 seconds.",		(flags & F_DUMMY)?"dummy":"real");	flush();	signal(SIGINT, intr);	for (i=9; --i > 0;) {		sleep(1);		if (didintr) {			printf("\n");			goto restore_it;		}		printf("\b\b\b\b\b\b\b\b\b\b%d seconds.", i);		flush();	}	signal(SIGINT, SIG_DFL);	signal(SIGINT, intfifo);	signal(SIGTERM, intfifo);	printf("\n");	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()) {			errmsgno(EX_BAD, "Input buffer error, aborting.\n");			excdr(EX_BAD, &exargs);			exit(EX_BAD);		}	}	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) {		if ((*dp->cdr_blank)(scgp, 0L, blanktype) < 0) {			errmsgno(EX_BAD, "Cannot blank disk, aborting.\n");			excdr(EX_BAD, &exargs);			exit(EX_BAD);		}		if (gettimeofday(&fixtime, (struct timezone *)0) < 0)			errmsg("Cannot get blank time\n");		if (lverbose)			prtimediff("Blanking time: ", &starttime, &fixtime);		if (!wait_unit_ready(scgp, 60) || tracks == 0) {			excdr(0, &exargs);			exit(0);		}		/*		 * 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");	}	/*	 * Get the number of the next recordable track.	 */	scgp->silent++;	if (read_tochdr(scgp, dp, NULL, &trackno) < 0) {		trackno = 0;	}	scgp->silent--;	for (i = 1; i <= tracks; i++) {		track[i].trackno = i + trackno;	}	trackno++;	track[0].trackno = trackno;	/* XXX Hack for TEAC fixate */	/*	 * 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, tracks, track, toctype, flags & F_MULTI) < 0) {		errmsgno(EX_BAD, "Cannot open new session.\n");		excdr(EX_BAD, &exargs);		exit(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;	if (flags & F_SAO) {		if (debug || lverbose) {			printf("Sending CUE sheet...\n");			flush();		}		if ((*dp->cdr_send_cue)(scgp, tracks, track) < 0) {			errmsgno(EX_BAD, "Cannot send CUE sheet.\n");			excdr(EX_BAD, &exargs);			exit(EX_BAD);		}	}	if ((flags & F_SAO)) {		(*dp->cdr_next_wr_address)(scgp, 0, &track[0], &startsec);		if (startsec <= 0 && startsec != -150) {			errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%d) using -150\n",					startsec);			startsec = -150;		}		if (debug)			printf("SAO startsec: %ld\n", startsec);		for (i = 1; i <= tracks; i++) {			track[i].trackstart += startsec +150;		}#ifdef	XXX		if (debug || lverbose)			printf("Writing lead-in...\n");		pad_track(scgp, dp, 1, &track[1], -150, 0,					FALSE, 0);#endif	}	/*	 * Need to set trackno to the real value from	 * the current disk status.	 */	for (i = 1; i <= tracks; i++, trackno++) {		startsec = 0L;		/*		 * trackno is the "real" track number while 'i' is a counter		 * going from 1 to tracks.		 */		if ((*dp->cdr_open_track)(scgp, dp, trackno, &track[i]) < 0) {			errs++;			break;		}		if ((flags & F_SAO) == 0) {			if ((*dp->cdr_next_wr_address)(scgp, trackno, &track[i], &startsec) < 0) {				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, trackno, &track[i]) < 0) {			errs++;			sleep(5);			request_sense(scgp);			(*dp->cdr_close_track)(scgp, trackno, &track[i]);			break;		}		if ((*dp->cdr_close_track)(scgp, trackno, &track[i]) < 0) {			/*			 * Check for "Dummy blocks added" message first.			 */			if (scsi_sense_key(scgp) != SC_ILLEGAL_REQUEST ||					scsi_sense_code(scgp) != 0xB5) {				errs++;				break;			}		}	}fix_it:	if (gettimeofday(&stoptime, (struct timezone *)0) < 0)		errmsg("Cannot get stop time\n");	if (lverbose)		prtimediff("Writing  time: ", &starttime, &stoptime);	if ((flags & F_NOFIX) == 0) {		if (lverbose) {			printf("Fixating...\n");			flush();		}		if ((*dp->cdr_fixate)(scgp, flags & F_MULTI, flags & F_DUMMY,				toctype, tracks, track) < 0)			errs++;		if (gettimeofday(&fixtime, (struct timezone *)0) < 0)			errmsg("Cannot get fix time\n");		if (lverbose)			prtimediff("Fixating time: ", &stoptime, &fixtime);	}restore_it:	/*	 * Try to restore the old sector size and stop FIFO.	 */	excdr(errs?-2:0, &exargs);	exit(errs?-2:0);	return (0);}LOCAL void usage(excode)	int excode;{	errmsgno(EX_BAD, "Usage: %s [options] track1...trackn\n",		get_progname());	error("Options:\n");	error("\t-version	print version information and exit\n");	error("\t-v		increment general verbose level by one\n");	error("\t-V		increment SCSI command transport verbose level by one\n");	error("\t-debug		print additional debug messages\n");	error("\tdev=target	SCSI target to use as CD/DVD-Recorder\n");	error("\ttimeout=#	set the default SCSI command timeout to #.\n");	error("\tdriver=name	user supplied driver name, use with extreme care\n");	error("\t-checkdrive	check if a driver for the drive is present\n");	error("\t-prcap		print drive capabilities for MMC compliant drives\n");	error("\t-inq		do an inquiry for the drive end exit\n");	error("\t-scanbus	scan the SCSI bus end exit\n");	error("\t-reset		reset the SCSI bus with the cdrecorder (if possible)\n");	error("\t-ignsize	ignore the known size of a medium (may cause problems)\n");	error("\t-useinfo	use *.inf files to overwrite audio options.\n");	error("\tspeed=#		set speed of drive\n");	error("\tblank=type	blank a CD-RW disc (see blank=help)\n");#ifdef	FIFO	error("\tfs=#		Set fifo size to # (0 to disable, default is %ld MB)\n",							DEFAULT_FIFOSIZE/(1024*1024));#endif	error("\t-load		load the disk and exit (works only with tray loader)\n");	error("\t-eject		eject the disk after doing the work\n");	error("\t-dummy		do everything with laser turned off\n");	error("\t-msinfo		retrieve multi-session info for mkisofs >= 1.10\n");	error("\t-toc		retrieve and print TOC/PMA data\n");	error("\t-atip		retrieve and print ATIP data\n");	error("\t-multi		generate a TOC that allows multi session\n");	error("\t		In this case default track type is CD-ROM XA2\n");	error("\t-fix		fixate a corrupt or unfixated disk (generate a TOC)\n");	error("\t-nofix		do not fixate disk after writing tracks\n");	error("\t-force		force to continue on some errors to allow blanking bad disks\n");	error("\t-dao		Write disk in DAO mode. This option will go away in the future.\n");	error("\ttsize=#		Length of valid data in next track\n");	error("\tpadsize=#	Amount of padding for next track\n");	error("\tpregap=#	Amount of pre-gap sectors before next track\n");	error("\tdefpregap=#	Amount of pre-gap sectors for all but track #1\n");	error("\tmcn=text	Set the media catalog number for this CD to 'text'\n");	error("\tisrc=text	Set the ISRC number for the next track to 'text'\n");	error("\tindex=list	Set the index list for the next track to 'list'\n");	error("\t-audio		Subsequent tracks are CD-DA audio tracks\n");	error("\t-data		Subsequent tracks are CD-ROM data mode 1 (default)\n");	error("\t-mode2		Subsequent tracks are CD-ROM data mode 2\n");	error("\t-xa1		Subsequent tracks are CD-ROM XA mode 1\n");	error("\t-xa2		Subsequent tracks are CD-ROM XA mode 2\n");	error("\t-cdi		Subsequent tracks are CDI tracks\n");	error("\t-isosize	Use iso9660 file system size for next data track\n");	error("\t-preemp		Audio tracks are mastered with 50/15 祍 preemphasis\n");	error("\t-nopreemp	Audio tracks are mastered with no preemphasis (default)\n");	error("\t-pad		Pad data tracks with %d zeroed sectors\n", PAD_SECS);	error("\t		Pad audio tracks to a multiple of %d bytes\n", AUDIO_SEC_SIZE);	error("\t-nopad		Do not pad data tracks (default)\n");	error("\t-swab		Audio data source is byte-swapped (little-endian/Intel)\n");	error("The type of the first track is used for the toc type.\n");	error("Currently only form 1 tracks are supported.\n");	exit(excode);}LOCAL voidblusage(ret)	int	ret;{	error("Blanking options:\n");	error("\tall\t\tblank the entire disk\n");	error("\tdisc\t\tblank the entire disk\n");	error("\tdisk\t\tblank the entire disk\n");	error("\tfast\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");	error("\tminimal\t\tminimally blank the entire disk (PMA, TOC, pregap)\n");	error("\ttrack\t\tblank a track\n");	error("\tunreserve\tunreserve a track\n");	error("\ttrtail\t\tblank a track tail\n");	error("\tunclose\t\tunclose last session\n");	error("\tsession\t\tblank last session\n");	exit(ret);	/* NOTREACHED */}LOCAL voidintr(sig)	int	sig;{	sig = 0;	/* Fake usage */	signal(SIGINT, intr);	didintr++;}LOCAL voidintfifo(sig)	int	sig;{	excdr(sig, NULL);	exit(sig);}LOCAL voidexscsi(excode, arg)	int	excode;	void	*arg;{	struct exargs	*exp = (struct exargs *)arg;	/*	 * Try to restore the old sector size.	 */	if (exp != NULL && exp->exflags == 0) {		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 */	}}LOCAL voidexcdr(excode, arg)	int	excode;	void	*arg;{	exscsi(excode, arg);#ifdef	FIFO	kill_faio();	wait_faio();	if (debug || lverbose)		fifo_stats();#endif}EXPORT intread_buf(f, bp, size)	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 && (errno == EAGAIN || errno == EINTR));		if (n < 0)			return (n);		amount += n;		p += n;	} while (amount < size && n > 0);	return (amount);}EXPORT intget_buf(f, bpp, size)	int	f;	char	**bpp;	int	size;{	if (fs > 0) {/*		return (faio_read_buf(f, *bpp, size));*/		return (faio_get_buf(f, bpp, size));	} else {		return (read_buf(f, *bpp, size));	}}LOCAL intwrite_track_data(scgp, dp, track, trackp)	SCSI	*scgp;	cdr_t	*dp;	int	track;	track_t	*trackp;{	int	f;	int	isaudio;	long	startsec;	long	bytes_read = 0;	long	bytes	= 0;	long	savbytes = 0;	int	count;	long	tracksize;	int	secsize;	int	secspt;	int	bytespt;	int	bytes_to_read;	long	amount;	int	pad;	int	bswab;	BOOL	neednl	= FALSE;	BOOL	islast	= FALSE;	char	*bp	= buf;long bsize;long bfree;#ifdef	BCAPint per;int oper = -1;#endif	scgp->silent++;	if (read_buff_cap(scgp, &bsize, &bfree) < 0)		bsize = -1;	scgp->silent--;	if (is_packet(trackp))	/* XXX Ugly hack for now */		return (write_packet_data(scgp, dp, track, trackp));	f = trackp->f;	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 */	bswab = isaudio && is_swab(trackp);	/* Swab only audio 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 %3ld MB written.",			       track, tracksize >> 20);		else			printf("\rTrack %02d:   0 MB written.", track);		flush();		neednl = TRUE;	}	do {		bytes_to_read = bytespt;		if (tracksize > 0) {			bytes_to_read = tracksize - bytes_read;			if (bytes_to_read > bytespt)				bytes_to_read = bytespt;		}		count = get_buf(f, &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;			if (trackp->padsize == 0 && (bytes_read/secsize) >= 300)				islast = TRUE;		}		if (bswab)			swabbytes(bp, count);		if (count < bytespt) {

⌨️ 快捷键说明

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