readcd.c

来自「刻录光盘的程序」· C语言 代码 · 共 838 行 · 第 1/2 页

C
838
字号
/* @(#)readcd.c	1.10 00/01/17 Copyright 1987 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)readcd.c	1.10 00/01/17 Copyright 1987 J. Schilling";#endif/* *	Skeleton for the use of the scg genearal SCSI - driver * *	Copyright (c) 1987 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 <unixstd.h>#include <stdxlib.h>#include <strdefs.h>#include <fctldefs.h>#include <timedefs.h>#include <scg/scgcmd.h>#include <scg/scsireg.h>#include <scg/scsitransp.h>#include "cdrecord.h"char	cdr_version[] = "1.8";extern	BOOL	getlong		__PR((char *, long *, long, long));extern	BOOL	getint		__PR((char *, int *, int, int));typedef struct {	long	start;	long	end;	char	*name;} parm_t;EXPORT	BOOL cvt_cyls		__PR((void));EXPORT	BOOL cvt_bcyls		__PR((void));EXPORT	void print_defect_list	__PR((void));LOCAL	void usage		__PR((int ret));EXPORT	int main		__PR((int ac, char **av));LOCAL	int prstats		__PR((void));LOCAL	void dorw		__PR((SCSI *scgp, char *filename, char* sectors));LOCAL	void doit		__PR((SCSI *scgp));#ifdef	usedLOCAL	int read_scsi_g1	__PR((SCSI *scgp, caddr_t bp, long addr, int cnt));#endifEXPORT	int	write_scsi	__PR((SCSI *scgp, caddr_t bp, long addr, int cnt));EXPORT	int	write_g0	__PR((SCSI *scgp, caddr_t bp, long addr, int cnt));EXPORT	int	write_g1	__PR((SCSI *scgp, caddr_t bp, long addr, int cnt));#ifdef	usedLOCAL	void	Xrequest_sense	__PR((SCSI *scgp));#endifLOCAL	int	rrr		__PR((SCSI *scgp, long addr, long cnt));LOCAL	void	read_disk	__PR((SCSI	*scgp, parm_t *parmp));LOCAL	void	write_disk	__PR((SCSI *scgp, parm_t *parmp));LOCAL	int	choice		__PR((int n));LOCAL	void	ra		__PR((SCSI *scgp));#ifndef	TRUE#	define	TRUE	1#	define	FALSE	0#endifstruct timeval	starttime;struct timeval	stoptime;char	*Sbuf;long	Sbufsize;int	help;BOOL	is_suid;BOOL	is_cdrom;BOOL	do_write;struct	scsi_format_data fmt;/*XXX*/EXPORT	BOOL cvt_cyls(){ return (FALSE);}/*XXX*/EXPORT	BOOL cvt_bcyls(){ return (FALSE);}/*XXX*/EXPORT	void print_defect_list(){}LOCAL voidusage(ret)	int	ret;{	error("Usage:\treadcd [options]\n");	error("options:\n");	error("\t-version	print version information and exit\n");	error("\tdev=target	SCSI target to use\n");	error("\tf=filename	Name of file to read/write\n");	error("\tsectors=range	Range of sectors to read/write\n");	error("\t-w		Switch to write mode\n");	error("\tkdebug=#,kd=#\tdo Kernel debugging\n");	error("\t-V		increment SCSI command transport verbose level by one\n");	error("\t-silent,-s\tdo not print status of erreneous commands\n");	exit(ret);}	char	opts[]   = "kdebug#,kd#,Verbose,V+,silent,s,debug,help,h,version,dev*,f*,sectors*,w";EXPORT intmain(ac, av)	int	ac;	char	*av[];{	char	*dev = NULL;	int	fcount;	int	cac;	char	* const *cav;	int	scsibus	= 0;	int	target	= 0;	int	lun	= 0;	int	silent	= 0;	int	verbose	= 0;	int	lverbose= 0;	int	kdebug	= 0;	int	debug	= 0;	int	pversion = 0;	SCSI	*scgp;	char	*filename= NULL;	char	*sectors = NULL;	save_args(ac, av);	cac = --ac;	cav = ++av;	if(getallargs(&cac, &cav, opts,			&kdebug, &kdebug,			&verbose, &verbose,			&silent, &silent, &debug,			&help, &help, &pversion,			&dev, &filename, &sectors, &do_write) < 0) {		errmsgno(EX_BAD, "Bad flag: %s.\n", cav[0]);		usage(EX_BAD);	}	if (help)		usage(0);	if (pversion) {		printf("readcd %s (%s-%s-%s) Copyright (C) 1987, 1995-2000 J鰎g Schilling\n",								cdr_version,								HOST_CPU, HOST_VENDOR, HOST_OS);		exit(0);	}	fcount = 0;	cac = ac;	cav = av;	while(getfiles(&cac, &cav, opts) > 0) {		fcount++;		if (fcount == 1) {			if (*astoi(cav[0], &target) != '\0') {				errmsgno(EX_BAD,					"Target '%s' is not a Number.\n",								cav[0]);				usage(EX_BAD);				/* NOTREACHED */			}		}		if (fcount == 2) {			if (*astoi(cav[0], &lun) != '\0') {				errmsgno(EX_BAD,					"Lun is '%s' not a Number.\n",								cav[0]);				usage(EX_BAD);				/* NOTREACHED */			}		}		if (fcount == 3) {			if (*astoi(cav[0], &scsibus) != '\0') {				errmsgno(EX_BAD,					"Scsibus is '%s' not a Number.\n",								cav[0]);				usage(EX_BAD);				/* NOTREACHED */			}		} else {			scsibus = 0;		}		cac--;		cav++;	}/*error("dev: '%s'\n", dev);*/	if (dev) {		char	errstr[80];		if ((scgp = open_scsi(dev, errstr, sizeof(errstr), debug, lverbose)) == (SCSI *)0)			comerr("%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":"");/*		scsi_settimeout(scgp, timeout);*/	} else {		if (scsibus == -1 && target >= 0 && lun >= 0)			scsibus = 0;		scgp = scsi_smalloc();		scgp->debug = debug;		scgp->kdebug = kdebug;		scgp->scsibus = scsibus;		scgp->target = target;		scgp->lun = lun;		if (!scsi_open(scgp, NULL, scsibus, target, lun))			comerr("Cannot open SCSI driver.\n");		scgp->scsibus = scsibus;		scgp->target = target;		scgp->lun = lun;	}	scgp->silent = silent;	scgp->verbose = verbose;	scgp->debug = debug;	scgp->kdebug = kdebug;	Sbufsize = scsi_bufsize(scgp, 256*1024L);	if ((Sbuf = scsi_getbuf(scgp, Sbufsize)) == NULL)		comerr("Cannot get SCSI I/O buffer.\n");	is_suid = geteuid() != getuid();	/*	 * We don't need root privilleges anymore.	 */#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 efective uid.\n");	/* code to use SCG */	do_inquiry(scgp, FALSE);	if (is_suid) {		if (scgp->inq->type != INQ_ROMD)			comerrno(EX_BAD, "Not root. Will only work on CD-ROM in suid mode\n");	}	if (filename || sectors) {		dorw(scgp, filename, sectors);	} else {		doit(scgp);	}	return (0);}LOCAL intprstats(){	int	sec;	int	usec;	int	tmsec;	if (gettimeofday(&stoptime, (struct timezone *)0) < 0)		comerr("Cannot get time\n");	sec = stoptime.tv_sec - starttime.tv_sec;	usec = stoptime.tv_usec - starttime.tv_usec;	tmsec = sec*1000 + usec/1000;#ifdef	lint	tmsec = tmsec;	/* Bisz spaeter */#endif	if (usec < 0) {		sec--;		usec += 1000000;	}	error("Time total: %d.%03dsec\n", sec, usec/1000);/*	return (sec + (usec / 500000));*/	return (1000*sec + (usec / 1000));}LOCAL voiddorw(scgp, filename, sectors)	SCSI	*scgp;	char	*filename;	char	*sectors;{	parm_t	params;	char	*p = NULL;	params.start = 0;	params.end = -1;	params.name = NULL;	if (filename)		params.name = filename;	if (sectors)		p = astol(sectors, &params.start);	if (p && *p == '-')		p = astol(++p, &params.end);	if (p && *p != '\0')		comerrno(EX_BAD, "Not a valid sector range '%s'\n", sectors);	if (!wait_unit_ready(scgp, 60))		comerr("Device not ready.\n");	if (do_write)		write_disk(scgp, &params);	else		read_disk(scgp, &params);}LOCAL voiddoit(scgp)	SCSI	*scgp;{	int	i = 0;	for(;;) {		if (!wait_unit_ready(scgp, 60))			comerr("Device not ready.\n");		printf("0:read 1:veri   2:erase   3:read buffer 4:cache 5:ovtime 6:cap\n");		printf("7:wne  8:floppy 9:verify 10:checkcmds  11:read disk 12:write disk\n");		printf("13:scsireset 14:seektest 15: readda\n");		getint("Enter selection:", &i, 0, 15);		switch (i) {		case 11:	read_disk(scgp, 0);	break;		case 12:	write_disk(scgp, 0);	break;		case 15:	ra(scgp);		break;		}	}}#ifdef	usedLOCAL intread_scsi_g1(scgp, bp, addr, cnt)	SCSI	*scgp;	caddr_t	bp;	long	addr;	int	cnt;{	register struct	scg_cmd	*scmd = scgp->scmd;	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');	scmd->addr = bp;/*	scmd->size = cnt*512;*/	scmd->size = cnt*scgp->cap->c_bsize;	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;	scmd->cdb_len = SC_G1_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;	scmd->cdb.g1_cdb.cmd = 0x28;	scmd->cdb.g1_cdb.lun = scgp->lun;	g1_cdbaddr(&scmd->cdb.g1_cdb, addr);	g1_cdblen(&scmd->cdb.g1_cdb, cnt);		scgp->cmdname = "read extended";	return (scsicmd(scgp));}#endif#define	G0_MAXADDR	0x1FFFFFLEXPORT intwrite_scsi(scgp, bp, addr, cnt)	SCSI	*scgp;	caddr_t	bp;	long	addr;	int	cnt;{	if(addr <= G0_MAXADDR)		return(write_g0(scgp, bp, addr, cnt));	else		return(write_g1(scgp, bp, addr, cnt));}EXPORT intwrite_g0(scgp, bp, addr, cnt)	SCSI	*scgp;	caddr_t	bp;	long	addr;	int	cnt;{	register struct	scg_cmd	*scmd = scgp->scmd;	if (scgp->cap->c_bsize <= 0)		raisecond("capacity_not_set", 0L);	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');	scmd->addr = bp;	scmd->size = cnt*scgp->cap->c_bsize;	scmd->flags = SCG_DISRE_ENA;	scmd->cdb_len = SC_G0_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;	scmd->cdb.g0_cdb.cmd = SC_WRITE;	scmd->cdb.g0_cdb.lun = scgp->lun;	g0_cdbaddr(&scmd->cdb.g0_cdb, addr);	scmd->cdb.g0_cdb.count = cnt;		scgp->cmdname = "write_g0";	return (scsicmd(scgp));

⌨️ 快捷键说明

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