readcd.c

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

C
838
字号
}EXPORT intwrite_g1(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_G1_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;	scmd->cdb.g1_cdb.cmd = SC_EWRITE;	scmd->cdb.g1_cdb.lun = scgp->lun;	g1_cdbaddr(&scmd->cdb.g1_cdb, addr);	g1_cdblen(&scmd->cdb.g1_cdb, cnt);		scgp->cmdname = "write_g1";	return (scsicmd(scgp));}#ifdef	usedLOCAL voidXrequest_sense(scgp)	SCSI	*scgp;{	char	sense_buf[32];	struct	scg_cmd ocmd;	int	sense_count;	char	*cmdsave;	register struct	scg_cmd	*scmd = scgp->scmd;	cmdsave = scgp->cmdname;	movebytes(scmd, &ocmd, sizeof(*scmd));	fillbytes((caddr_t)sense_buf, sizeof(sense_buf), '\0');	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');	scmd->addr = (caddr_t)sense_buf;	scmd->size = sizeof(sense_buf);	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;	scmd->cdb_len = SC_G0_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;	scmd->cdb.g1_cdb.cmd = 0x3;	scmd->cdb.g1_cdb.lun = scgp->lun;	scmd->cdb.g0_cdb.count = sizeof(sense_buf);		scgp->cmdname = "request sense";	scsicmd(scgp);	sense_count = sizeof(sense_buf) - scsigetresid(scgp);	movebytes(&ocmd, scmd, sizeof(*scmd));	scmd->sense_count = sense_count;	movebytes(sense_buf, (u_char *)&scmd->sense, scmd->sense_count);	scgp->cmdname = cmdsave;	scsiprinterr(scgp);	scsiprintresult(scgp);	/* XXX restore key/code in future */}#endif/*#define	MAX_RETRY	32*/#define	MAX_RETRY	128LOCAL intrrr(scgp, addr, cnt)	SCSI	*scgp;	long	addr;	long	cnt;{	int	secsize = scgp->cap->c_bsize;	int	try = 0;	int	err;	char	dummybuf[4000];	errmsgno(EX_BAD, "Retrying from sector %d.\n", addr);	while (cnt > 0) {		error(".");		do {			if (try != 0) {				if ((try % 8) == 0) {					error("+");					scgp->silent++;					read_g1(scgp, dummybuf, scgp->cap->c_baddr, 1);					scgp->silent--;				} else if ((try % 4) == 0) {					error("-");					scgp->silent++;					read_g1(scgp, dummybuf, 0, 1);					scgp->silent--;				} else {					error("~");					scgp->silent++;					read_g1(scgp, dummybuf, choice(scgp->cap->c_baddr), 1);					scgp->silent--;				}			}			scgp->silent++;/*			err = read_scsi(scgp, Sbuf, addr, 1);*/			err = read_g1(scgp, Sbuf, addr, 1);			scgp->silent--;			if (err < 0) {/*				err = geterrno();*/				err = scgp->scmd->ux_errno;/*				error("\n");*//*				errmsgno(err, "Cannot read source disk\n");*/			} else {				break;			}		} while (++try < MAX_RETRY);		if (try >= MAX_RETRY) {			errmsgno(err, "Error not corrected.\n");			return (-1);		} else {			if (try > 1)				errmsgno(EX_BAD, "Error corrected after %d tries.\n", try);		}		try = 0;		cnt -= 1;		addr += 1;		Sbuf += secsize;	}	return (0);}LOCAL voidread_disk(scgp, parmp)	SCSI	*scgp;	parm_t	*parmp;{	char	filename[512];	char	*defname = "disk.out";	FILE	*f;	long	addr;	long	cnt;	long	end;	int	nsec;	long	start = 0L;	int	err = 0;/*int try;*/	if (is_suid) {		if (scgp->inq->type != INQ_ROMD)			comerrno(EX_BAD, "Not root. Will only read from CD in suid mode\n");	}	filename[0] ='\0';	read_capacity(scgp);	end = scgp->cap->c_baddr + 1;	if (end <= 0)		end = 10000000;	/* Hack to read empty (e.g. blank=fast) disks */	if (parmp) {		if (parmp->name)			defname = parmp->name;		error("Copy from SCSI (%d,%d,%d) disk to file '%s'\n",					scgp->scsibus, scgp->target, scgp->lun,					defname);		addr = start = parmp->start;		if (parmp->end != -1 && parmp->end < end)			end = parmp->end;		cnt = Sbufsize / scgp->cap->c_bsize;	}else {	error("Copy from SCSI (%d,%d,%d) disk to file\n",					scgp->scsibus, scgp->target, scgp->lun);	error("Enter filename [%s]: ", defname);flush();	(void)getline(filename, sizeof(filename));	addr = start;	getlong("Enter starting sector for copy:", &addr, start, end-1);	start = addr;	cnt = end - addr;	getlong("Enter number of sectors to copy:", &cnt, 1L, cnt);	end = addr + cnt;	cnt = Sbufsize / scgp->cap->c_bsize;	getlong("Enter number of sectors per copy:", &cnt, 1L, cnt);/*	error("end:  %8ld\n", end);*/}	if (filename[0] == '\0')		strcpy(filename, defname);	if (streql(filename, "-")) {		f = stdout;#if	defined(__CYGWIN32__) || defined(__EMX__)		setmode(STDOUT_FILENO, O_BINARY);#endif	} else if ((f = fileopen(filename, "wcub")) == NULL)		comerr("Cannot open '%s'.\n", filename);	error("end:  %8ld\n", end);	if (gettimeofday(&starttime, (struct timezone *)0) < 0)		comerr("Cannot get start time\n");	for(;addr < end; addr += cnt)                         {		if ((addr + cnt) > end)			cnt = end - addr;		error("addr: %8d cnt: %d\r", addr, cnt);/*	try = 0;*//*	do {*//*		if (read_scsi(scgp, Sbuf, addr, cnt) < 0) {*/		if (read_g1(scgp, Sbuf, addr, cnt) < 0) {/*			err = geterrno();*/			err = scgp->scmd->ux_errno;			error("\n");			errmsgno(err, "Cannot read source disk\n");/*			break;*/			if (rrr(scgp, addr, cnt) < 0)				goto out;		}/*		else break;*//*	} while (++try < 10);*//*	if (try >= 10)*//*		break;*/		if (filewrite(f, Sbuf, cnt * scgp->cap->c_bsize) < 0) {			err = geterrno();			error("\n");			errmsgno(err, "Cannot write '%s'\n", filename);			break;		}	}	error("addr: %8d", addr);out:	error("\n");	nsec = prstats();/*	error("%d\n",nsec);*/	error("Read %.2f kB at %.1f kB/sec.\n",		(addr - start)/(1024.0/scgp->cap->c_bsize),		((addr - start)/(1024.0/scgp->cap->c_bsize)) / (0.001*nsec));	if (err)		exit(err);}LOCAL voidwrite_disk(scgp, parmp)	SCSI	*scgp;	parm_t	*parmp;{	char	filename[512];	char	*defname = "disk.out";	FILE	*f;	long	addr = 0L;	long	cnt;	long	amt;	long	end;	int	nsec;	int	start;	if (is_suid)		comerrno(EX_BAD, "Not root. Will not write in suid mode\n");	read_capacity(scgp);	end = scgp->cap->c_baddr + 1;	if (end <= 0)		end = 10000000;	/* Hack to write empty disks */	if (parmp) {		if (parmp->name)			defname = parmp->name;		error("Copy from file '%s' tp SCSI (%d,%d,%d) disk\n",					defname,					scgp->scsibus, scgp->target, scgp->lun);		addr = start = parmp->start;		if (parmp->end != -1 && parmp->end < end)			end = parmp->end;		cnt = Sbufsize / scgp->cap->c_bsize;	}else {	error("Copy from file to SCSI (%d,%d,%d) disk\n",					scgp->scsibus, scgp->target, scgp->lun);	error("Enter filename [%s]: ", defname);flush();	(void)getline(filename, sizeof(filename));	error("Notice: reading from file always starts at file offset 0.\n");	getlong("Enter starting sector for copy:", &addr, 0L, end-1);	start = addr;	cnt = end - addr;	getlong("Enter number of sectors to copy:", &end, 1L, end);	end = addr + cnt;	cnt = Sbufsize / scgp->cap->c_bsize;	getlong("Enter number of sectors per copy:", &cnt, 1L, cnt);/*	error("end:  %8ld\n", end);*/}	if (filename[0] == '\0')		strcpy(filename, defname);	if (streql(filename, "-")) {		f = stdin;#if	defined(__CYGWIN32__) || defined(__EMX__)		setmode(STDIN_FILENO, O_BINARY);#endif	} else if ((f = fileopen(filename, "rub")) == NULL)		comerr("Cannot open '%s'.\n", filename);	error("end:  %8ld\n", end);	if (gettimeofday(&starttime, (struct timezone *)0) < 0)		comerr("Cannot get start time\n");	for(;addr < end; addr += cnt) {		if ((addr + cnt) > end)			cnt = end - addr;		error("addr: %8d cnt: %d\r", addr, cnt);		if ((amt = fileread(f, Sbuf, cnt * scgp->cap->c_bsize)) < 0)			comerr("Cannot read '%s'\n", filename);		if (amt == 0)			break;		if ((amt / scgp->cap->c_bsize) < cnt)			cnt = amt / scgp->cap->c_bsize;		if (write_scsi(scgp, Sbuf, addr, cnt) < 0)			comerrno(scgp->scmd->ux_errno,					"Cannot write destination disk\n");	}	error("addr: %8d\n", addr);	nsec = prstats();	error("Wrote %.2f kB at %.1f kB/sec.\n",		(double)(addr - start)/(1024.0/scgp->cap->c_bsize),		(double)((addr - start)/(1024.0/scgp->cap->c_bsize)) / nsec);}LOCAL intchoice(n)	int	n;{#if	!defined(__CYGWIN32__) && !defined(__EMX__)	extern	double	drand48 __PR((void));	return drand48() * n;#else	return (0);#endif}LOCAL voidra(scgp)	SCSI	*scgp;{/*	char	filename[512];*/	FILE	*f;/*	long	addr = 0L;*//*	long	cnt;*//*	long	end;*//*	int	nsec;*//*	int	start;*//*	int	err = 0;*/	select_secsize(scgp, 2352);	read_capacity(scgp);	fillbytes(Sbuf, 50*2352, 0);	if (read_g1(scgp, Sbuf, 0, 50) < 0)		errmsg("read CD\n");	f = fileopen("DDA", "wctb");/*	filewrite(f, Sbuf, 50 * 2352 - scsigetresid(scgp));*/	filewrite(f, Sbuf, 50 * 2352 );	fclose(f);}#ifdef	XXXEXPORT intread_da(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_RECV_DATA|SCG_DISRE_ENA;	scmd->cdb_len = SC_G5_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;/*	scmd->cdb.g5_cdb.cmd = SC_EREAD;*/	scmd->cdb.g5_cdb.cmd = 0xd9;	scmd->cdb.g5_cdb.lun = scgp->lun;	g5_cdbaddr(&scmd->cdb.g1_cdb, addr);	g5_cdblen(&scmd->cdb.g1_cdb, cnt);/* XXX subscript out of range ?? */		scgp->cmdname = "read_g1";	return (scsicmd(scgp));}#endif

⌨️ 快捷键说明

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