[Debburn-changes] r433 - in cdrkit/trunk: . readom

Eduard Bloch blade at alioth.debian.org
Thu Nov 23 20:16:00 CET 2006


Author: blade
Date: 2006-11-23 20:15:59 +0100 (Thu, 23 Nov 2006)
New Revision: 433

Added:
   cdrkit/trunk/readom/
   cdrkit/trunk/readom/CMakeLists.txt
   cdrkit/trunk/readom/readcd.1
   cdrkit/trunk/readom/readcd.c
Removed:
   cdrkit/trunk/readcd/
   cdrkit/trunk/readom/CMakeLists.txt
   cdrkit/trunk/readom/readcd.1
   cdrkit/trunk/readom/readcd.c
Modified:
   cdrkit/trunk/CMakeLists.txt
Log:
readcd -> readom, part I

Modified: cdrkit/trunk/CMakeLists.txt
===================================================================
--- cdrkit/trunk/CMakeLists.txt	2006-11-23 19:03:00 UTC (rev 432)
+++ cdrkit/trunk/CMakeLists.txt	2006-11-23 19:15:59 UTC (rev 433)
@@ -1,3 +1,3 @@
 PROJECT (cdrkit)
-SUBDIRS(cdda2wav wodim libdeflt libedc libhfs_iso libparanoia libusal libschily libunls mkisofs readcd rscsi 3rd-party/dirsplit include)
+SUBDIRS(cdda2wav wodim libdeflt libedc libhfs_iso libparanoia libusal libschily libunls mkisofs readom rscsi 3rd-party/dirsplit include)
 

Copied: cdrkit/trunk/readom (from rev 427, cdrkit/trunk/readcd)

Deleted: cdrkit/trunk/readom/CMakeLists.txt
===================================================================
--- cdrkit/trunk/readcd/CMakeLists.txt	2006-11-23 11:16:23 UTC (rev 427)
+++ cdrkit/trunk/readom/CMakeLists.txt	2006-11-23 19:15:59 UTC (rev 433)
@@ -1,19 +0,0 @@
-PROJECT (READECD)
-INCLUDE_DIRECTORIES(../include ../wodim ${CMAKE_BINARY_DIR})
-INCLUDE(../include/AddScgBits.cmake)
-INCLUDE(../include/AddSchilyBits.cmake)
-
-AUX_SOURCE_DIRECTORY(. READCD_SRCS)
-
-LINK_DIRECTORIES(../libschily ../libscg ../libdeflt)
-
-ADD_DEFINITIONS(-DCLONE_WRITE)
-
-ADD_EXECUTABLE (readcd ${READCD_SRCS})
-TARGET_LINK_LIBRARIES(readcd ${EXTRA_LIBS} deflt)
-SET_TARGET_PROPERTIES(readcd PROPERTIES  SKIP_BUILD_RPATH TRUE)
-
-INSTALL(TARGETS readcd DESTINATION bin)
-INSTALL(FILES 
-readcd.1
-DESTINATION share/man/man1)

Copied: cdrkit/trunk/readom/CMakeLists.txt (from rev 432, cdrkit/trunk/readcd/CMakeLists.txt)

Deleted: cdrkit/trunk/readom/readcd.1
===================================================================
--- cdrkit/trunk/readcd/readcd.1	2006-11-23 11:16:23 UTC (rev 427)
+++ cdrkit/trunk/readom/readcd.1	2006-11-23 19:15:59 UTC (rev 433)
@@ -1,495 +0,0 @@
-.\" @(#)readcd.1	1.23 06/01/12 Copyright 1996-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.
-.\"
-.\" The GNU General Public License's references to "object code"
-.\" and "executables" are to be interpreted as the output of any
-.\" document formatting or typesetting system, including
-.\" intermediate and printed output.
-.\"
-.\" This manual 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.
-.if t .ds a \v'-0.55m'\h'0.00n'\z.\h'0.40n'\z.\v'0.55m'\h'-0.40n'a
-.if t .ds o \v'-0.55m'\h'0.00n'\z.\h'0.45n'\z.\v'0.55m'\h'-0.45n'o
-.if t .ds u \v'-0.55m'\h'0.00n'\z.\h'0.40n'\z.\v'0.55m'\h'-0.40n'u
-.if t .ds A \v'-0.77m'\h'0.25n'\z.\h'0.45n'\z.\v'0.77m'\h'-0.70n'A
-.if t .ds O \v'-0.77m'\h'0.25n'\z.\h'0.45n'\z.\v'0.77m'\h'-0.70n'O
-.if t .ds U \v'-0.77m'\h'0.30n'\z.\h'0.45n'\z.\v'0.77m'\h'-0.75n'U
-.if t .ds s \\(*b
-.if t .ds S SS
-.if n .ds a ae
-.if n .ds o oe
-.if n .ds u ue
-.if n .ds s sz
-.TH READCD 1 "Version 2.0" "J\*org Schilling" "Schily\'s USER COMMANDS"
-.SH NAME
-readcd \- read or write data Compact Discs
-.SH SYNOPSIS
-.B readcd
-.BI dev= device
-[
-.I options
-]
-
-.SH DESCRIPTION
-.B Readcd
-is used to read or write Compact Discs.
-.PP
-The
-.I device
-refers to a device location similar to the one used in the wodim command. Refer to its manpage for details.
-.PP
-Also note that this version of readcd uses a modified libscg library which has
-a different behaviour compared to the one distributed by its original author.
-
-.SH OPTIONS
-.PP
-If no options except the 
-.I dev=
-option have been specified, 
-.B readcd
-goes into interactive mode.
-Select a primary function and then follow the instructions.
-.PP
-.TP
-.B \-version
-Print version information and exit.
-.TP
-.BI dev= target
-Sets the SCSI target for the drive, see notes above.
-A typical device specification is
-.BI dev= 6,0
-\&.
-If a filename must be provided together with the numerical target 
-specification, the filename is implementation specific.
-The correct filename in this case can be found in the system specific
-manuals of the target operating system.
-On a 
-.I FreeBSD
-system without 
-.I CAM
-support, you need to use the control device (e.g.
-.IR /dev/rcd0.ctl ).
-A correct device specification in this case may be
-.BI dev= /dev/rcd0.ctl:@
-\&.
-.sp
-On Linux, drives connected to a parallel port adapter are mapped
-to a virtual SCSI bus. Different adapters are mapped to different
-targets on this virtual SCSI bus.
-.sp
-If no 
-.I dev
-option is present, 
-.B readcd
-will try to get the device from the 
-.B CDR_DEVICE
-environment.
-.sp
-If the argument to the
-.B dev=
-option does not contain the characters ',', '/', '@' or ':',
-it is interpreted as an label name that may be found in the file
-/etc/wodim.conf (see FILES section).
-.TP
-.BI timeout= #
-Set the default SCSI command timeout value to 
-.IR # " seconds.
-The default SCSI command timeout is the minimum timeout used for sending
-SCSI commands.
-If a SCSI command fails due to a timeout, you may try to raise the
-default SCSI command timeout above the timeout value of the failed command.
-If the command runs correctly with a raised command timeout,
-please report the better timeout value and the corresponding command to 
-the author of the program.
-If no 
-.I timeout 
-option is present, a default timeout of 40 seconds is used.
-.TP
-.BI debug= "#, " -d
-Set the misc debug value to # (with debug=#) or increment
-the misc debug level by one (with -d). If you specify
-.I -dd,
-this equals to 
-.BI debug= 2.
-This may help to find problems while opening a driver for libscg.
-as well as with sector sizes and sector types.
-Using
-.B \-debug
-slows down the process and may be the reason for a buffer underrun.
-.TP
-.BR kdebug= "#, " kd= #
-Tell the 
-.BR scg -driver
-to modify the kernel debug value while SCSI commands are running.
-.TP
-.BR \-silent ", " \-s
-Do not print out a status report for failed SCSI commands.
-.TP
-.B \-v
-Increment the level of general verbosity by one.
-This is used e.g. to display the progress of the process.
-.TP
-.B \-V
-Increment the verbose level with respect of SCSI command transport by one.
-This helps to debug problems
-during the process, that occur in the CD-Recorder. 
-If you get incomprehensible error messages you should use this flag
-to get more detailed output.
-.B \-VV
-will show data buffer content in addition.
-Using
-.B \-V
-or
-.B \-VV
-slows down the process.
-.TP
-.BI f= file
-Specify the filename where the output should be written or the inout should
-be taken from. Using '-' as filename will cause
-.B readcd
-to use 
-.BR stdout " resp. " stdin .
-.TP
-.B \-w
-Switch to write mode. If this option is not present,
-.B readcd
-reads from the specified device.
-.TP
-.B \-c2scan
-Scans the whole CD or the range specified by the 
-.BI sectors= range
-for C2 errors. C2 errors are errors that are uncorrectable after the second
-stage of the 24/28 + 28/32 Reed Solomon correction system at audio level
-(2352 bytes sector size). If an audio CD has C2 errors, interpolation is needed
-to hide the errors. If a data CD has C2 errors, these errors are in most
-cases corrected by the ECC/EDC code that makes 2352 bytes out of 2048 data
-bytes. The ECC/EDC code should be able to correct about 100 C2 error bytes
-per sector.
-.sp
-If you find C2 errors you may want to reduce the speed using the
-.B speed=
-option as C2 errors may be a result of dynamic unbalance on the medium.
-.TP
-.B \-scanbus
-Scan all SCSI devices on all SCSI busses and print the inquiry
-strings. This option may be used to find SCSI address of the 
-devices on a system.
-The numbers printed out as labels are computed by: 
-.B "bus * 100 + target
-.TP
-.BI sectors= range
-Specify a sector range that should be read.
-The range is specified by the starting sector number, a minus sign and the
-ending sector number.
-The end sector is not included in the list, so 
-.BR sectors= 0-0
-will not read anything and may be used to check for a CD in the drive.
-.TP
-.BR speed= #
-Set the speed factor of the read or write process to #.
-# is an integer, representing a multiple of the audio speed.
-This is about 150 KB/s for CD-ROM and about 172 KB/s for CD-Audio.
-If no 
-.I speed
-option is present, 
-.B readcd
-will use maximum speed.
-Only MMC compliant drives will benefit from this option.
-The speed of non MMC drives is not changed.
-.sp
-Using a lower speed may increase the readability of a CD or DVD.
-.TP
-.BR ts= #
-Set the maximum transfer size for a single SCSI command to #.
-The syntax for the 
-.B ts=
-option is the same as for wodim fs=# or sdd bs=#.
-.sp
-If no 
-.B ts=
-option has been specified,
-.B readcd
-defaults to a transfer size of 256 kB. If libscg gets lower values from the
-operating system, the value is reduced to the maximum value that is possible
-with the current operating system.
-Sometimes, it may help to further reduce the transfer size or to enhance it,
-but note that it may take a long time to find a better value by experimenting
-with the
-.B ts=
-option.
-.TP
-.B \-notrunc
-Do not truncate the output file when opening it.
-.TP
-.B \-fulltoc
-Retrieve a full TOC from the current disk and print it in hex.
-.TP
-.B \-clone
-Do a clone read. Read the CD with all sub-channel data and a full TOC.
-The full TOC data will be put into a file with similar name as with the
-.B f=
-option but the suffix 
-.B .toc
-added.
-.TP
-.B \-noerror
-Do not abort if the high level error checking in
-.B readcd
-found an uncorrectable error in the data stream.
-.TP
-.B \-nocorr
-Switch the drive into a mode where it ignores read errors in data sectors that
-are a result of uncorrectable ECC/EDC errors before reading.
-If
-.B readcd
-completes, the error recovery mode of the drive is switched back to the remembered 
-old mode.
-.TP
-.BI retries= #
-Set the retry count for high level retries in
-.B readcd
-to 
-.IR # .
-The default is to do 128 retries which may be too much if you like to read a CD
-with many unreadable sectors.
-.TP
-.B \-overhead
-Meter the SCSI command overhead time.
-This is done by executing several commands 1000 times and printing the
-total time used. If you divide the displayed times by 1000, you get 
-the average overhead time for a single command.
-.TP
-.BR meshpoints= #
-Print read-speed at # locations.
-The purpose of this option is to create a list of read speed values suitable
-for e.g.
-.BR gnuplot .
-The speed values are calculated assuming that 1000 bytes are one kilobyte
-as documented in the SCSI standard.
-The ouput data created for this purpose is written to 
-.IR stdout .
-.TP
-.B \-factor
-Output the speed values for
-.BR meshpoints= #
-as factor based on 
-.I "single speed
-of the current medium.
-This only works if
-.B readcd
-is able to determine the current medium type.
-.SH EXAMPLES
-.PP
-For all examples below, it will be assumed that the drive is
-connected to the primary SCSI bus of the machine. The SCSI target id is
-set to 2.
-.PP
-To read the complete media from a CD-ROM writing the data to the file
-.IR cdimage.raw :
-.PP
-    readcd dev=2,0 f=cdimage.raw
-.PP
-To read sectors from range 150 ... 10000 from a CD-ROM writing the data to the file
-.IR cdimage.raw :
-.PP
-    readcd dev=2,0 sectors=150-10000 f=cdimage.raw
-.PP
-To write the data from the file
-.I cdimage.raw
-(e.g. a filesystem image from 
-.BR mkisofs )
-to a DVD-RAM, call:
-.PP
-    readcd dev=2,0 -w f=cdimage.raw
-
-.SH ENVIRONMENT
-.TP
-.B RSH
-If the 
-.B RSH
-environment is present, the remote connection will not be created via
-.BR rcmd (3)
-but by calling the program pointed to by
-.BR RSH .
-Use e.g. 
-.BR RSH= /usr/bin/ssh
-to create a secure shell connection.
-.sp
-Note that this forces 
-.B wodim
-to create a pipe to the 
-.B rsh(1)
-program and disallows
-.B wodim
-to directly access the network socket to the remote server.
-This makes it impossible to set up performance parameters and slows down
-the connection compared to a 
-.B root
-initiated
-.B rcmd(3)
-connection.
-.TP
-.B RSCSI
-If the 
-.B RSCSI
-environment is present, the remote SCSI server will not be the program
-.B /opt/schily/sbin/rscsi
-but the program pointed to by
-.BR RSCSI .
-Note that the remote SCSI server program name will be ignored if you log in
-using an account that has been created with a remote SCSI server program as
-login shell.
-.SH SEE ALSO
-.BR wodim (1),
-.BR mkisofs (1),
-.BR rcmd (3),
-.BR ssh (1).
-
-.SH NOTES
-.PP
-Unless you want to risk getting problems,
-.B readcd
-should be run as root. If you don't want to allow users to become root on your system,
-.B readcd
-may safely be installed suid root.
-For more information see the additional notes of your system/program
-distribution or README.suidroot which is part of the Cdrkit source.
-.PP
-Documentation of the
-.B wodim
-program contains more technical details which could also apply to
-.B readcd.
-
-.SH DIAGNOSTICS
-.PP
-.PP
-A typical error message for a SCSI command looks like:
-.sp
-.RS
-.nf
-readcd: I/O error. test unit ready: scsi sendcmd: no error
-CDB:  00 20 00 00 00 00
-status: 0x2 (CHECK CONDITION)
-Sense Bytes: 70 00 05 00 00 00 00 0A 00 00 00 00 25 00 00 00 00 00
-Sense Key: 0x5 Illegal Request, Segment 0
-Sense Code: 0x25 Qual 0x00 (logical unit not supported) Fru 0x0
-Sense flags: Blk 0 (not valid)
-cmd finished after 0.002s timeout 40s
-.fi
-.sp
-.RE
-The first line gives information about the transport of the command.
-The text after the first colon gives the error text for the system call
-from the view of the kernel. It usually is:
-.B "I/O error
-unless other problems happen. The next words contain a short description for
-the SCSI command that fails. The rest of the line tells you if there were
-any problems for the transport of the command over the SCSI bus.
-.B "fatal error
-means that it was not possible to transport the command (i.e. no device present
-at the requested SCSI address).
-.PP
-The second line prints the SCSI command descriptor block for the failed command.
-.PP
-The third line gives information on the SCSI status code returned by the 
-command, if the transport of the command succeeds. 
-This is error information from the SCSI device.
-.PP
-The fourth line is a hex dump of the auto request sense information for the 
-command.
-.PP
-The fifth line is the error text for the sense key if available, followed
-by the segment number that is only valid if the command was a
-.I copy
-command. If the error message is not directly related to the current command,
-the text
-.I deferred error
-is appended.
-.PP
-The sixth line is the error text for the sense code and the sense qualifier if available.
-If the type of the device is known, the sense data is decoded from tables
-in
-.IR scsierrs.c " .
-The text is followed by the error value for a field replaceable unit.
-.PP
-The seventh line prints the block number that is related to the failed command
-and text for several error flags. The block number may not be valid.
-.PP
-The eight line reports the timeout set up for this command and the time
-that the command really needed to complete.
-
-.SH BUGS
-.PP
-The 
-.B readcd
-program described here is the Cdrkit spinoff from the original
-.B reacd
-application (see AUTHOR section for details). It may contain bugs not present
-in the original implementation.
-.PP
-It is definitely less portable than the original implementation.
-.PP
-For platform specific bugs, see the corresponding README.platform file in the
-Cdrkit documentation (eg. README.linux).
-
-.SH "MAILING LISTS
-If you want to actively take part on the development of readcd,
-you may join the developer mailing list via this URL:
-.sp
-.B
-http://alioth.debian.org/mail/?group_id=31006
-.PP
-The mail address of the list is:
-.B
-debburn-devel at lists.alioth.debian.org
-
-
-
-
-.SH AUTHOR
-.nf
-J\*org Schilling
-Seestr. 110
-D-13353 Berlin
-Germany
-.fi
-
-.PP
-This is application is a spinoff from the original implementation delivered in
-the cdrtools package [1] created by Joerg Schilling, who deserves the most credits
-for its success. However, he is not involved into the development
-of this spinoff and therefore he shall not be made responsible for any problem
-caused by it. Do not try to get support from the original author!
-.PP
-Additional information can be found on:
-.br
-https://alioth.debian.org/projects/debburn/
-.PP
-If you have support questions, send them to
-.PP
-.B
-debburn-devel at lists.alioth.debian.org
-.br
-.PP
-If you have definitely found a bug, send a mail to this list or to
-.PP
-.B
-submit at bugs.debian.org
-.br
-.PP
-writing at least a short description into the Subject and "Package: cdrkit"
-into the first line of the mail body.
-.SH SOURCES
-.PP
-.br
-[1] Cdrtools 2.01.01a08 from May 2006, http://cdrecord.berlios.de
-

Copied: cdrkit/trunk/readom/readcd.1 (from rev 432, cdrkit/trunk/readcd/readcd.1)

Deleted: cdrkit/trunk/readom/readcd.c
===================================================================
--- cdrkit/trunk/readcd/readcd.c	2006-11-23 11:16:23 UTC (rev 427)
+++ cdrkit/trunk/readom/readcd.c	2006-11-23 19:15:59 UTC (rev 433)
@@ -1,2195 +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.
- *
- */
-
-/* @(#)readcd.c	1.80 06/02/05 Copyright 1987, 1995-2006 J. Schilling */
-#ifndef lint
-static	char sccsid[] =
-	"@(#)readcd.c	1.80 06/02/05 Copyright 1987, 1995-2006 J. Schilling";
-#endif
-/*
- *	Skeleton for the use of the scg genearal SCSI - driver
- *
- *	Copyright (c) 1987, 1995-2004 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 <unixstd.h>
-#include <stdxlib.h>
-#include <strdefs.h>
-#include <fctldefs.h>
-#include <timedefs.h>
-#include <signal.h>
-#include <schily.h>
-#ifdef	HAVE_PRIV_H
-#include <priv.h>
-#endif
-
-#ifdef	NEED_O_BINARY
-#include <io.h>					/* for setmode() prototype */
-#endif
-
-#include <scg/scgcmd.h>
-#include <scg/scsireg.h>
-#include <scg/scsitransp.h>
-
-#include "scsi_scan.h"
-#include "scsimmc.h"
-#define	qpto96	__nothing__
-#include "wodim.h"
-#include "defaults.h"
-#undef	qpto96
-#include "movesect.h"
-
-char	cdr_version[] = "2.01.01a05";
-
-#if	defined(PROTOTYPES)
-#define	UINT_C(a)	(a##u)
-#define	ULONG_C(a)	(a##ul)
-#define	USHORT_C(a)	(a##uh)
-#define	CONCAT(a, b)	a##b
-#else
-#define	UINT_C(a)	((unsigned)(a))
-#define	ULONG_C(a)	((unsigned long)(a))
-#define	USHORT_C(a)	((unsigned short)(a))
-/* CSTYLED */
-#define	CONCAT(a, b)	a/**/b
-#endif
-
-extern	BOOL	getlong(char *, long *, long, long);
-extern	BOOL	getint(char *, int *, int, int);
-
-typedef struct {
-	long	start;
-	long	end;
-	long	sptr;		/* sectors per transfer */
-	BOOL	askrange;
-	char	*name;
-} parm_t;
-
-typedef struct {
-	int	errors;
-	int	c2_errors;
-	int	c2_maxerrs;
-	int	c2_errsecs;
-	int	c2_badsecs;
-	int	secsize;
-	BOOL	ismmc;
-} rparm_t;
-
-struct exargs {
-	SCSI	*scgp;
-	int	old_secsize;
-	int	flags;
-	int	exflags;
-	char	oerr[3];
-} exargs;
-
-BOOL	cvt_cyls(void);
-BOOL	cvt_bcyls(void);
-void	print_defect_list(void);
-static	void	usage(int ret);
-static	void	intr(int sig);
-static	void	exscsi(int excode, void *arg);
-static	void	excdr(int excode, void *arg);
-static	int	prstats(void);
-static	int	prstats_silent(void);
-static	void	dorw(SCSI *scgp, char *filename, char *sectors);
-static	void	doit(SCSI *scgp);
-static	void	read_disk(SCSI *scgp, parm_t *parmp);
-#ifdef	CLONE_WRITE
-static	void	readcd_disk(SCSI *scgp, parm_t *parmp);
-static	void	read_lin(SCSI *scgp, parm_t *parmp);
-static	int	read_secheader(SCSI *scgp, long addr);
-static	int	read_ftoc(SCSI *scgp, parm_t *parmp, BOOL do_sectype);
-static	void	read_sectypes(SCSI *scgp, FILE *f);
-static	void	get_sectype(SCSI *scgp, long addr, char *st);
-#endif
-
-static	void	readc2_disk(SCSI *scgp, parm_t *parmp);
-static	int	fread_data(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, 
-								  int cnt);
-#ifdef	CLONE_WRITE
-static	int	fread_2448(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, 
-								  int cnt);
-static	int	fread_2448_16(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, 
-									  int cnt);
-static	int	fread_2352(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, 
-								  int cnt);
-static	int	fread_lin(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, 
-								 int cnt);
-#endif
-static	int	bits(int c);
-static	int	bitidx(int c);
-static	int	fread_c2(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, 
-								int cnt);
-
-static	int	fdata_null(rparm_t *rp, caddr_t bp, long addr, int cnt);
-static	int	fdata_c2(rparm_t *rp, caddr_t bp, long addr, int cnt);
-
-#ifdef	used
-static	int read_scsi_g1(SCSI *scgp, caddr_t bp, long addr, int cnt);
-#endif
-
-int	write_scsi(SCSI *scgp, caddr_t bp, long addr, int cnt);
-int	write_g0(SCSI *scgp, caddr_t bp, long addr, int cnt);
-int	write_g1(SCSI *scgp, caddr_t bp, long addr, int cnt);
-
-#ifdef	used
-static	void	Xrequest_sense(SCSI *scgp);
-#endif
-static	int	read_retry(SCSI *scgp, caddr_t bp, long addr, long cnt,
-								  int (*rfunc)(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt),
-								  rparm_t *rp);
-static	void	read_generic(SCSI *scgp, parm_t *parmp,
-									 int (*rfunc)(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt),
-									 rparm_t *rp,
-									 int (*dfunc)(rparm_t *rp, caddr_t bp, long addr, int cnt));
-static	void	write_disk(SCSI *scgp, parm_t *parmp);
-static	int	choice(int n);
-static	void	ra(SCSI *scgp);
-
-int	read_da(SCSI *scgp, caddr_t bp, long addr, int cnt, int framesize, 
-				  int subcode);
-int	read_cd(SCSI *scgp, caddr_t bp, long addr, int cnt, int framesize, 
-				  int data, int subch);
-
-static	void	oldmode(SCSI *scgp, int *errp, int *retrp);
-static	void	domode(SCSI *scgp, int err, int retr);
-
-static	void	qpto96(Uchar *sub, Uchar *subq, int dop);
-static	void	ovtime(SCSI *scgp);
-static	void	add_bad(long addr);
-static	void	print_bad(void);
-
-struct timeval	starttime;
-struct timeval	stoptime;
-int	didintr;
-int	exsig;
-
-char	*Sbuf;
-long	Sbufsize;
-
-/*#define	MAX_RETRY	32*/
-#define	MAX_RETRY	128
-
-int	help;
-int	xdebug;
-int	lverbose;
-int	quiet;
-BOOL	is_suid;
-BOOL	is_cdrom;
-BOOL	is_dvd;
-BOOL	do_write;
-BOOL	c2scan;
-BOOL	fulltoc;
-BOOL	clone;
-BOOL	noerror;
-BOOL	nocorr;
-BOOL	notrunc;
-int	retries = MAX_RETRY;
-int	maxtry = 0;
-int	meshpoints;
-BOOL	do_factor;
-
-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() {}
-
-static void
-usage(int ret)
-{
-	fprintf(stderr, "Usage:\treadcd [options]\n");
-	fprintf(stderr, "options:\n");
-	fprintf(stderr, "\t-version	print version information and exit\n");
-	fprintf(stderr, "\tdev=target	SCSI target to use\n");
-	fprintf(stderr, "\tf=filename	Name of file to read/write\n");
-	fprintf(stderr, "\tsectors=range	Range of sectors to read/write\n");
-	fprintf(stderr, "\tspeed=#		set speed of drive (MMC only)\n");
-	fprintf(stderr, "\tts=#		set maximum transfer size for a single SCSI command\n");
-	fprintf(stderr, "\t-w		Switch to write mode\n");
-	fprintf(stderr, "\t-c2scan		Do a C2 error scan\n");
-#ifdef	CLONE_WRITE
-	fprintf(stderr, "\t-fulltoc	Retrieve the full TOC\n");
-	fprintf(stderr, "\t-clone		Retrieve the full TOC and all data\n");
-#endif
-	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-quiet,-q	be more quiet in error retry mode\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, "\t-scanbus	scan the SCSI bus and exit\n");
-	fprintf(stderr, "\t-noerror	do not abort on error\n");
-#ifdef	CLONE_WRITE
-	fprintf(stderr, "\t-nocorr		do not apply error correction in drive\n");
-#endif
-	fprintf(stderr, "\t-notrunc	do not truncate outputfile in read mode\n");
-	fprintf(stderr, "\tretries=#	set retry count (default is %d)\n", retries);
-	fprintf(stderr, "\t-overhead	meter SCSI command overhead times\n");
-	fprintf(stderr, "\tmeshpoints=#	print read-speed at # locations\n");
-	fprintf(stderr, "\t-factor		try to use speed factor with meshpoints=# if possible\n");
-	fprintf(stderr, "\n");
-	fprintf(stderr, "sectors=0-0 will read nothing, sectors=0-1 will read one sector starting from 0\n");
-	exit(ret);
-}	
-
-/* CSTYLED */
-char	opts[]   = "debug#,d+,kdebug#,kd#,timeout#,quiet,q,verbose+,v+,Verbose+,V+,x+,xd#,silent,s,help,h,version,scanbus,dev*,sectors*,w,c2scan,fulltoc,clone,noerror,nocorr,notrunc,retries#,factor,f*,speed#,ts&,overhead,meshpoints#";
-
-int
-main(int argc, char *argv[])
-{
-	char	*dev = NULL;
-	int	fcount;
-	int	cac;
-	char	* const *cav;
-	int	scsibus	= -1;
-	int	target	= -1;
-	int	lun	= -1;
-	int	silent	= 0;
-	int	verbose	= 0;
-	int	kdebug	= 0;
-	int	debug	= 0;
-	int	deftimeout = 40;
-	int	pversion = 0;
-	int	scanbus = 0;
-	int	speed	= -1;
-	int	dooverhead = 0;
-	SCSI	*scgp;
-	char	*filename = NULL;
-	char	*sectors = NULL;
-
-	save_args(argc, argv);
-
-	cac = --argc;
-	cav = ++argv;
-
-	if (getallargs(&cac, &cav, opts,
-			&debug, &debug,
-			&kdebug, &kdebug,
-			&deftimeout,
-			&quiet, &quiet,
-			&lverbose, &lverbose,
-			&verbose, &verbose,
-			&xdebug, &xdebug,
-			&silent, &silent,
-			&help, &help, &pversion,
-			&scanbus, &dev, &sectors, &do_write,
-			&c2scan,
-			&fulltoc, &clone,
-			&noerror, &nocorr,
-			&notrunc, &retries, &do_factor, &filename,
-			&speed, getnum, &Sbufsize,
-			&dooverhead, &meshpoints) < 0) {
-		errmsgno(EX_BAD, "Bad flag: %s.\n", cav[0]);
-		usage(EX_BAD);
-	}
-	if (help)
-		usage(0);
-	if (pversion) {
-		printf("readcd %s (%s) "
-		       "Copyright (C) 1987, 1995-2006 Joerg Schilling\n",
-		       cdr_version, HOST_SYSTEM);
-		printf("(using modified version of libscg -- "
-		       "don't bother Joerg Schilling with problems)\n");
-		exit(0);
-	}
-
-	fcount = 0;
-	cac = argc;
-	cav = argv;
-
-	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 */
-			}
-		}
-		cac--;
-		cav++;
-	}
-/*fprintf(stderr, "dev: '%s'\n", dev);*/
-	if (!scanbus)
-		cdr_defaults(&dev, NULL, NULL, NULL);
-	if (debug) {
-		printf("dev: '%s'\n", dev);
-	}
-	if (!scanbus && dev == NULL &&
-	    scsibus == -1 && (target == -1 || lun == -1)) {
-		errmsgno(EX_BAD, "No SCSI device specified.\n");
-		usage(EX_BAD);
-	}
-	if (dev || scanbus) {
-		char	errstr[80];
-
-		/*
-		 * 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);
-		}
-		if ((scgp = scg_open(dev, errstr, sizeof (errstr), debug, lverbose)) == (SCSI *)0) {
-			int	err = geterrno();
-
-			errmsgno(err, "%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":"");
-			errmsgno(EX_BAD, "For possible targets try 'readcd -scanbus'.%s\n",
-						geteuid() ? " Make sure you are root.":"");
-			errmsgno(EX_BAD, "For possible transport specifiers try 'readcd dev=help'.\n");
-			exit(err);
-		}
-	} else {
-		if (scsibus == -1 && target >= 0 && lun >= 0)
-			scsibus = 0;
-
-		scgp = scg_smalloc();
-		scgp->debug = debug;
-		scgp->kdebug = kdebug;
-
-		scg_settarget(scgp, scsibus, target, lun);
-		if (scg__open(scgp, NULL) <= 0)
-			comerr("Cannot open SCSI driver.\n");
-	}
-	scgp->silent = silent;
-	scgp->verbose = verbose;
-	scgp->debug = debug;
-	scgp->kdebug = kdebug;
-	scg_settimeout(scgp, deftimeout);
-
-	if (Sbufsize == 0)
-		Sbufsize = 256*1024L;
-	Sbufsize = scg_bufsize(scgp, Sbufsize);
-	if ((Sbuf = scg_getbuf(scgp, Sbufsize)) == NULL)
-		comerr("Cannot get SCSI I/O buffer.\n");
-
-#ifdef	HAVE_PRIV_SET
-	is_suid = priv_ineffect(PRIV_FILE_DAC_READ) &&
-		    !priv_ineffect(PRIV_PROC_SETID);
-	/*
-	 * Give up privs we do not need anymore.
-	 * We no longer need:
-	 *	file_dac_read,net_privaddr
-	 * We still need:
-	 *	sys_devices
-	 */
-	priv_set(PRIV_OFF, PRIV_EFFECTIVE,
-		PRIV_FILE_DAC_READ, PRIV_NET_PRIVADDR, NULL);
-	priv_set(PRIV_OFF, PRIV_PERMITTED,
-		PRIV_FILE_DAC_READ, PRIV_NET_PRIVADDR, NULL);
-	priv_set(PRIV_OFF, PRIV_INHERITABLE,
-		PRIV_FILE_DAC_READ, PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL);
-#endif
-	/*
-	 * This is only for OS that do not support fine grained privs.
-	 */
-	if (!is_suid)
-		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 effective uid.\n");
-
-	/* code to use SCG */
-
-	if (scanbus) {
-		select_target(scgp, stdout);
-		exit(0);
-	}
-	do_inquiry(scgp, FALSE);
-	allow_atapi(scgp, TRUE);    /* Try to switch to 10 byte mode cmds */
-	if (is_mmc(scgp, NULL, NULL)) {
-		int	rspeed;
-		int	wspeed;
-		/*
-		 * At this point we know that we have a SCSI-3/mmc compliant drive.
-		 * Unfortunately ATAPI drives violate the SCSI spec in returning
-		 * a response data format of '1' which from the SCSI spec would
-		 * tell us not to use the "PF" bit in mode select. As ATAPI drives
-		 * require the "PF" bit to be set, we 'correct' the inquiry data.
-		 */
-		if (scgp->inq->data_format < 2)
-			scgp->inq->data_format = 2;
-
-		if ((rspeed = get_curprofile(scgp)) >= 0) {
-			if (rspeed >= 0x08 && rspeed < 0x10)
-				is_cdrom = TRUE;
-			if (rspeed >= 0x10 && rspeed < 0x20)
-				is_dvd = TRUE;
-		} else {
-			BOOL	dvd;
-
-			mmc_check(scgp, NULL, NULL, NULL, NULL, &dvd, NULL);
-			if (dvd == FALSE) {
-				is_cdrom = TRUE;
-			} else {
-				char	xb[32];
-
-				if (read_dvd_structure(scgp, (caddr_t)xb, 32, 0, 0, 0) >= 0) {
-				/*
-				 * If read DVD structure is supported and works, then
-				 * we must have a DVD media in the drive. Signal to
-				 * use the DVD driver.
-				 */
-					is_dvd = TRUE;
-				} else {
-					is_cdrom = TRUE;
-				}
-			}
-		}
-
-		if (speed > 0)
-			speed *= 177;
-		if (speed > 0xFFFF || speed < 0)
-			speed = 0xFFFF;
-		scsi_set_speed(scgp, speed, speed, ROTCTL_CLV);
-		if (scsi_get_speed(scgp, &rspeed, &wspeed) >= 0) {
-			fprintf(stderr, "Read  speed: %5d kB/s (CD %3dx, DVD %2dx).\n",
-				rspeed, rspeed/176, rspeed/1385);
-			fprintf(stderr, "Write speed: %5d kB/s (CD %3dx, DVD %2dx).\n",
-				wspeed, wspeed/176, wspeed/1385);
-		}
-	}
-	exargs.scgp	   = scgp;
-	exargs.old_secsize = -1;
-/*	exargs.flags	   = flags;*/
-	exargs.oerr[2]	   = 0;
-
-	/*
-	 * Install exit handler before we change the drive status.
-	 */
-	on_comerr(exscsi, &exargs);
-	signal(SIGINT, intr);
-	signal(SIGTERM, intr);
-
-	if (dooverhead) {
-		ovtime(scgp);
-		comexit(0);
-	}
-
-	if (is_suid) {
-		if (scgp->inq->type != INQ_ROMD)
-			comerrno(EX_BAD, "Not root. Will only work on CD-ROM in suid/priv mode\n");
-	}
-
-	if (filename || sectors || c2scan || meshpoints || fulltoc || clone) {
-		dorw(scgp, filename, sectors);
-	} else {
-		doit(scgp);
-	}
-	comexit(0);
-	return (0);
-}
-
-/*
- * XXX Leider kann man vim Signalhandler keine SCSI Kommandos verschicken
- * XXX da meistens das letzte SCSI Kommando noch laeuft.
- * XXX Eine Loesung waere ein Abort Callback in SCSI *.
- */
-static void
-intr(int sig)
-{
-	didintr++;
-	exsig = sig;
-/*	comexit(sig);*/
-}
-
-/* ARGSUSED */
-static void
-exscsi(int excode, void *arg)
-{
-	struct exargs	*exp = (struct exargs *)arg;
-		int	i;
-
-	/*
-	 * Try to restore the old sector size.
-	 */
-	if (exp != NULL && exp->exflags == 0) {
-		for (i = 0; i < 10*100; i++) {
-			if (!exp->scgp->running)
-				break;
-			if (i == 10) {
-				errmsgno(EX_BAD,
-					"Waiting for current SCSI command to finish.\n");
-			}
-			usleep(100000);
-		}
-
-		if (!exp->scgp->running) {
-			if (exp->oerr[2] != 0) {
-				domode(exp->scgp, exp->oerr[0], exp->oerr[1]);
-			}
-			if (exp->old_secsize > 0 && exp->old_secsize != 2048)
-				select_secsize(exp->scgp, exp->old_secsize);
-		}
-		exp->exflags++;	/* Make sure that it only get called once */
-	}
-}
-
-static void
-excdr(int excode, void *arg)
-{
-	exscsi(excode, arg);
-
-#ifdef	needed
-	/* Do several other restores/statistics here (see cdrecord.c) */
-#endif
-}
-
-/*
- * Return milliseconds since start time.
- */
-static int
-prstats()
-{
-	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;
-	}
-
-	fprintf(stderr, "Time total: %d.%03dsec\n", sec, usec/1000);
-	return (1000*sec + (usec / 1000));
-}
-
-/*
- * Return milliseconds since start time, but be silent this time.
- */
-static int
-prstats_silent()
-{
-	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;
-	}
-
-	return (1000*sec + (usec / 1000));
-}
-
-static void
-dorw(SCSI *scgp, char *filename, char *sectors)
-{
-	parm_t	params;
-	char	*p = NULL;
-
-	params.start = 0;
-	params.end = -1;
-	params.sptr = -1;
-	params.askrange = FALSE;
-	params.name = NULL;
-
-	if (filename)
-		params.name = filename;
-	if (meshpoints > 0) {
-		if (params.name == NULL)
-			params.name = "/dev/null";
-	}
-	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))
-		comerrno(EX_BAD, "Device not ready.\n");
-
-#ifdef	CLONE_WRITE
-	if (fulltoc) {
-		if (params.name == NULL)
-			params.name = "/dev/null";
-		read_ftoc(scgp, &params, FALSE);
-	} else if (clone) {
-		if (!is_mmc(scgp, NULL, NULL))
-			comerrno(EX_BAD, "Unsupported device for clone mode.\n");
-		noerror = TRUE;
-		if (retries == MAX_RETRY)
-			retries = 10;
-		if (params.name == NULL)
-			params.name = "/dev/null";
-
-		if (read_ftoc(scgp, &params, TRUE) < 0)
-			comerrno(EX_BAD, "Read fulltoc problems.\n");
-		readcd_disk(scgp, &params);
-	} else
-#endif
-	if (c2scan) {
-		noerror = TRUE;
-		if (retries == MAX_RETRY)
-			retries = 10;
-		if (params.name == NULL)
-			params.name = "/dev/null";
-		readc2_disk(scgp, &params);
-	} else if (do_write)
-		write_disk(scgp, &params);
-	else
-		read_disk(scgp, &params);
-}
-
-static void
-doit(SCSI *scgp)
-{
-	int	i = 0;
-	parm_t	params;
-
-	params.start = 0;
-	params.end = -1;
-	params.sptr = -1;
-	params.askrange = TRUE;
-	params.name = "/dev/null";
-
-	for (;;) {
-		if (!wait_unit_ready(scgp, 60))
-			comerrno(EX_BAD, "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 16: reada 17: c2err\n");
-#ifdef	CLONE_WRITE
-		printf("18:readcd 19: lin 20: full toc\n");
-#endif
-
-		getint("Enter selection:", &i, 0, 20);
-		if (didintr)
-			return;
-
-		switch (i) {
-
-		case 5:		ovtime(scgp);		break;
-		case 11:	read_disk(scgp, 0);	break;
-		case 12:	write_disk(scgp, 0);	break;
-		case 15:	ra(scgp);		break;
-/*		case 16:	reada_disk(scgp, 0, 0);	break;*/
-		case 17:	readc2_disk(scgp, &params);	break;
-#ifdef	CLONE_WRITE
-		case 18:	readcd_disk(scgp, 0);	break;
-		case 19:	read_lin(scgp, 0);	break;
-		case 20:	read_ftoc(scgp, 0, FALSE);	break;
-#endif
-		}
-	}
-}
-
-static void
-read_disk(SCSI *scgp, parm_t *parmp)
-{
-	rparm_t	rp;
-
-	read_capacity(scgp);
-	print_capacity(scgp, stderr);
-
-	rp.errors = 0;
-	rp.c2_errors = 0;
-	rp.c2_maxerrs = 0;
-	rp.c2_errsecs = 0;
-	rp.c2_badsecs = 0;
-	rp.secsize = scgp->cap->c_bsize;
-
-	read_generic(scgp, parmp, fread_data, &rp, fdata_null);
-}
-
-#ifdef	CLONE_WRITE
-static void
-readcd_disk(SCSI *scgp, parm_t *parmp)
-{
-	rparm_t	rp;
-	int	osecsize = 2048;
-	int	oerr = 0;
-	int	oretr = 10;
-	int	(*funcp)(SCSI *_scgp, rparm_t *_rp, caddr_t bp, long addr, int cnt);
-
-	scgp->silent++;
-	if (read_capacity(scgp) >= 0)
-		osecsize = scgp->cap->c_bsize;
-	scgp->silent--;
-	if (osecsize != 2048)
-		select_secsize(scgp, 2048);
-
-	read_capacity(scgp);
-	print_capacity(scgp, stderr);
-
-	rp.errors = 0;
-	rp.c2_errors = 0;
-	rp.c2_maxerrs = 0;
-	rp.c2_errsecs = 0;
-	rp.c2_badsecs = 0;
-	rp.secsize = 2448;
-	rp.ismmc = is_mmc(scgp, NULL, NULL);
-	funcp = fread_2448;
-
-	wait_unit_ready(scgp, 10);
-	if (fread_2448(scgp, &rp, Sbuf, 0, 0) < 0) {
-		errmsgno(EX_BAD, "read 2448 failed\n");
-		if (rp.ismmc &&
-		    fread_2448_16(scgp, &rp, Sbuf, 0, 0) >= 0) {
-			errmsgno(EX_BAD, "read 2448_16 : OK\n");
-
-			funcp = fread_2448_16;
-		}
-	}
-
-	oldmode(scgp, &oerr, &oretr);
-	exargs.oerr[0] = oerr;
-	exargs.oerr[1] = oretr;
-	exargs.oerr[2] = 0xFF;
-	if (parmp == NULL)		/* XXX Nur am Anfang!!! */
-		domode(scgp, -1, -1);
-	else
-		domode(scgp, nocorr?0x21:0x20, 10);
-
-	read_generic(scgp, parmp, funcp, &rp, fdata_null);
-	if (osecsize != 2048)
-		select_secsize(scgp, osecsize);
-	domode(scgp, oerr, oretr);
-}
-
-/* ARGSUSED */
-static void
-read_lin(SCSI *scgp, parm_t *parmp)
-{
-	parm_t	parm;
-	rparm_t	rp;
-
-	read_capacity(scgp);
-	print_capacity(scgp, stderr);
-
-	parm.start = ULONG_C(0xF0000000);
-	parm.end =   ULONG_C(0xFF000000);
-	parm.name = "DDD";
-
-	rp.errors = 0;
-	rp.c2_errors = 0;
-	rp.c2_maxerrs = 0;
-	rp.c2_errsecs = 0;
-	rp.c2_badsecs = 0;
-	rp.secsize = 2448;
-	rp.ismmc = is_mmc(scgp, NULL, NULL);
-	domode(scgp, -1, -1);
-	read_generic(scgp, &parm, fread_lin, &rp, fdata_null);
-}
-
-static int
-read_secheader(SCSI *scgp, long addr)
-{
-	rparm_t	rp;
-	int	osecsize = 2048;
-	int	ret = 0;
-
-	scgp->silent++;
-	if (read_capacity(scgp) >= 0)
-		osecsize = scgp->cap->c_bsize;
-	scgp->silent--;
-	if (osecsize != 2048)
-		select_secsize(scgp, 2048);
-
-	read_capacity(scgp);
-
-	rp.errors = 0;
-	rp.c2_errors = 0;
-	rp.c2_maxerrs = 0;
-	rp.c2_errsecs = 0;
-	rp.c2_badsecs = 0;
-	rp.secsize = 2352;
-	rp.ismmc = is_mmc(scgp, NULL, NULL);
-
-	wait_unit_ready(scgp, 10);
-
-	fillbytes(Sbuf, 2352, '\0');
-	if (fread_2352(scgp, &rp, Sbuf, addr, 1) < 0) {
-		ret = -1;
-	}
-	if (osecsize != 2048)
-		select_secsize(scgp, osecsize);
-	return (ret);
-}
-
-/* ARGSUSED */
-static int
-read_ftoc(SCSI *scgp, parm_t *parmp, BOOL do_sectype)
-{
-	FILE	*f;
-	int	i;
-	char	filename[1024];
-	struct	tocheader *tp;
-	char	*p;
-	char	xb[256];
-	int	len;
-	char	xxb[10000];
-
-
-	strcpy(filename, "toc.dat");
-	if (strcmp(parmp->name, "/dev/null") != 0) {
-
-		len = strlen(parmp->name);
-		if (len > (sizeof (filename)-5)) {
-			len = sizeof (filename)-5;
-		}
-		js_snprintf(filename, sizeof (filename), "%.*s.toc", len, parmp->name);
-	}
-
-	tp = (struct tocheader *)xb;
-
-	fillbytes((caddr_t)xb, sizeof (xb), '\0');
-	if (read_toc(scgp, xb, 0, sizeof (struct tocheader), 0, FMT_FULLTOC) < 0) {
-		if (scgp->silent == 0 || scgp->verbose > 0)
-			errmsgno(EX_BAD, "Cannot read TOC header\n");
-		return (-1);
-	}
-	len = a_to_u_2_byte(tp->len) + sizeof (struct tocheader)-2;
-	fprintf(stderr, "TOC len: %d. First Session: %d Last Session: %d.\n", len, tp->first, tp->last);
-
-	if (read_toc(scgp, xxb, 0, len, 0, FMT_FULLTOC) < 0) {
-		if (len & 1) {
-			/*
-			 * Work around a bug in some operating systems that do not
-			 * handle odd byte DMA correctly for ATAPI drives.
-			 */
-			wait_unit_ready(scgp, 30);
-			read_toc(scgp, xb, 0, sizeof (struct tocheader), 0, FMT_FULLTOC);
-			wait_unit_ready(scgp, 30);
-			if (read_toc(scgp, xxb, 0, len+1, 0, FMT_FULLTOC) >= 0) {
-				goto itworked;
-			}
-		}
-		if (scgp->silent == 0)
-			errmsgno(EX_BAD, "Cannot read full TOC\n");
-		return (-1);
-	}
-
-itworked:
-	f = fileopen(filename, "wctb");
-
-	if (f == NULL)
-		comerr("Cannot open '%s'.\n", filename);
-	filewrite(f, xxb, len);
-	if (do_sectype)
-		read_sectypes(scgp, f);
-	fflush(f);
-	fclose(f);
-
-	p = &xxb[4];
-	for (; p < &xxb[len]; p += 11) {
-		for (i = 0; i < 11; i++)
-			fprintf(stderr, "%02X ", p[i] & 0xFF);
-		fprintf(stderr, "\n");
-	}
-	/*
-	 * List all lead out start times to give information about multi
-	 * session disks.
-	 */
-	p = &xxb[4];
-	for (; p < &xxb[len]; p += 11) {
-		if ((p[3] & 0xFF) == 0xA2) {
-			fprintf(stderr, "Lead out %d: %ld\n", p[0], msf_to_lba(p[8], p[9], p[10], TRUE));
-		}
-	}
-	return (0);
-}
-
-static void
-read_sectypes(SCSI *scgp, FILE *f)
-{
-	char	sect;
-
-	sect = SECT_AUDIO;
-	get_sectype(scgp, 4, &sect);
-	if (f != NULL)
-		filewrite(f, &sect, 1);
-	if (xdebug)
-		scg_prbytes("sec 0", (Uchar *)Sbuf, 16);
-
-	sect = SECT_AUDIO;
-	get_sectype(scgp, scgp->cap->c_baddr-4, &sect);
-	if (f != NULL)
-		filewrite(f, &sect, 1);
-	if (xdebug) {
-		scg_prbytes("sec E", (Uchar *)Sbuf, 16);
-		fprintf(stderr, "baddr: %ld\n", (long)scgp->cap->c_baddr);
-	}
-}
-
-static void
-get_sectype(SCSI *scgp, long addr, char *st)
-{
-	char	*synchdr = "\0\377\377\377\377\377\377\377\377\377\377\0";
-	int	sectype = SECT_AUDIO;
-	int	i;
-	long	raddr = addr;
-#define	_MAX_TRY_	20
-
-	scgp->silent++;
-	for (i = 0; i < _MAX_TRY_ && read_secheader(scgp, raddr) < 0; i++) {
-		if (addr == 0)
-			raddr++;
-		else
-			raddr--;
-	}
-	scgp->silent--;
-	if (i >= _MAX_TRY_) {
-		fprintf(stderr, "Sectype (%ld) is CANNOT\n", addr);
-		return;
-	} else if (i > 0) {
-		fprintf(stderr, "Sectype (%ld) needed %d retries\n", addr, i);
-	}
-#undef	_MAX_TRY_
-
-	if (cmpbytes(Sbuf, synchdr, 12) < 12) {
-		if (xdebug)
-			fprintf(stderr, "Sectype (%ld) is AUDIO\n", addr);
-		if (st)
-			*st = SECT_AUDIO;
-		return;
-	}
-	if (xdebug)
-		fprintf(stderr, "Sectype (%ld) is DATA\n", addr);
-	if (Sbuf[15] == 0) {
-		if (xdebug)
-			fprintf(stderr, "Sectype (%ld) is MODE 0\n", addr);
-		sectype = SECT_MODE_0;
-
-	} else if (Sbuf[15] == 1) {
-		if (xdebug)
-			fprintf(stderr, "Sectype (%ld) is MODE 1\n", addr);
-		sectype = SECT_ROM;
-
-	} else if (Sbuf[15] == 2) {
-		if (xdebug)
-			fprintf(stderr, "Sectype (%ld) is MODE 2\n", addr);
-
-		if ((Sbuf[16+2]  & 0x20) == 0 &&
-		    (Sbuf[16+4+2]  & 0x20) == 0) {
-			if (xdebug)
-				fprintf(stderr, "Sectype (%ld) is MODE 2 form 1\n", addr);
-			sectype = SECT_MODE_2_F1;
-
-		} else if ((Sbuf[16+2]  & 0x20) != 0 &&
-		    (Sbuf[16+4+2]  & 0x20) != 0) {
-			if (xdebug)
-				fprintf(stderr, "Sectype (%ld) is MODE 2 form 2\n", addr);
-			sectype = SECT_MODE_2_F2;
-		} else {
-			if (xdebug)
-				fprintf(stderr, "Sectype (%ld) is MODE 2 formless\n", addr);
-			sectype = SECT_MODE_2;
-		}
-	} else {
-		fprintf(stderr, "Sectype (%ld) is UNKNOWN\n", addr);
-	}
-	if (st)
-		*st = sectype;
-	if (xdebug)
-		fprintf(stderr, "Sectype (%ld) is 0x%02X\n", addr, sectype);
-}
-
-#endif	/* CLONE_WRITE */
-
-char	zeroblk[512];
-
-static void
-readc2_disk(SCSI *scgp, parm_t *parmp)
-{
-	rparm_t	rp;
-	int	osecsize = 2048;
-	int	oerr = 0;
-	int	oretr = 10;
-
-	scgp->silent++;
-	if (read_capacity(scgp) >= 0)
-		osecsize = scgp->cap->c_bsize;
-	scgp->silent--;
-	if (osecsize != 2048)
-		select_secsize(scgp, 2048);
-
-	read_capacity(scgp);
-	print_capacity(scgp, stderr);
-
-	rp.errors = 0;
-	rp.c2_errors = 0;
-	rp.c2_maxerrs = 0;
-	rp.c2_errsecs = 0;
-	rp.c2_badsecs = 0;
-	rp.secsize = 2352 + 294;
-	rp.ismmc = is_mmc(scgp, NULL, NULL);
-
-	oldmode(scgp, &oerr, &oretr);
-	exargs.oerr[0] = oerr;
-	exargs.oerr[1] = oretr;
-	exargs.oerr[2] = 0xFF;
-	domode(scgp, 0x21, 10);
-
-
-	read_generic(scgp, parmp, fread_c2, &rp, fdata_c2);
-	if (osecsize != 2048)
-		select_secsize(scgp, osecsize);
-	domode(scgp, oerr, oretr);
-
-	printf("Total of %d hard read errors.\n", rp.errors);
-	printf("C2 errors total: %d bytes in %d sectors on disk\n", rp.c2_errors, rp.c2_errsecs);
-	printf("C2 errors rate: %f%% \n", (100.0*rp.c2_errors)/scgp->cap->c_baddr/2352);
-	printf("C2 errors on worst sector: %d, sectors with 100+ C2 errors: %d\n", rp.c2_maxerrs, rp.c2_badsecs);
-}
-
-/* ARGSUSED */
-static int
-fread_data(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	return (read_g1(scgp, bp, addr, cnt));
-}
-
-#ifdef	CLONE_WRITE
-static int
-fread_2448(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	if (rp->ismmc) {
-		return (read_cd(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC */
-			(1 << 7 | 3 << 5 | 1 << 4 | 1 << 3),
-			/* plus all subchannels RAW */
-			1));
-	} else {
-		return (read_da(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC + all subch */
-			0x02));
-	}
-}
-
-static int
-fread_2448_16(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-
-	if (rp->ismmc) {
-		track_t trackdesc;
-		int	ret;
-		int	i;
-		char	*p;
-
-		trackdesc.isecsize = 2368;
-		trackdesc.secsize = 2448;
-		ret = read_cd(scgp, bp, addr, cnt, 2368,
-			/* Sync + all headers + user data + EDC/ECC */
-			(1 << 7 | 3 << 5 | 1 << 4 | 1 << 3),
-			/* subchannels P/Q */
-			2);
-		if (ret < 0)
-			return (ret);
-
-		scatter_secs(&trackdesc, bp, cnt);
-		for (i = 0, p = bp+2352; i < cnt; i++) {
-#ifdef	more_than_q_sub
-			if ((p[15] & 0x80) != 0)
-				printf("P");
-#endif
-			/*
-			 * As the drives don't return P-sub, we check
-			 * whether the index equals 0.
-			 */
-			qpto96((Uchar *)p, (Uchar *)p, p[2] == 0);
-			p += 2448;
-		}
-		return (ret);
-	} else {
-		comerrno(EX_BAD, "Cannot fread_2448_16 on non MMC drives\n");
-
-		return (read_da(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC + all subch */
-			0x02));
-	}
-}
-
-static int
-fread_2352(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	if (rp->ismmc) {
-		return (read_cd(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC */
-			(1 << 7 | 3 << 5 | 1 << 4 | 1 << 3),
-			/* NO subchannels */
-			0));
-	} else {
-		comerrno(EX_BAD, "Cannot fread_2352 on non MMC drives\n");
-
-		return (read_da(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC + all subch */
-			0x02));
-	}
-}
-
-static int
-fread_lin(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	if (addr != ULONG_C(0xF0000000))
-		addr = ULONG_C(0xFFFFFFFF);
-
-	return (read_cd(scgp, bp, addr, cnt, rp->secsize,
-		/* Sync + all headers + user data + EDC/ECC */
-		(1 << 7 | 3 << 5 | 1 << 4 | 1 << 3),
-		/* plus all subchannels RAW */
-		1));
-}
-#endif	/* CLONE_WRITE */
-
-static int
-bits(int c)
-{
-	int	n = 0;
-
-	if (c & 0x01)
-		n++;
-	if (c & 0x02)
-		n++;
-	if (c & 0x04)
-		n++;
-	if (c & 0x08)
-		n++;
-	if (c & 0x10)
-		n++;
-	if (c & 0x20)
-		n++;
-	if (c & 0x40)
-		n++;
-	if (c & 0x80)
-		n++;
-	return (n);
-}
-
-static int
-bitidx(int c)
-{
-	if (c & 0x80)
-		return (0);
-	if (c & 0x40)
-		return (1);
-	if (c & 0x20)
-		return (2);
-	if (c & 0x10)
-		return (3);
-	if (c & 0x08)
-		return (4);
-	if (c & 0x04)
-		return (5);
-	if (c & 0x02)
-		return (6);
-	if (c & 0x01)
-		return (7);
-	return (-1);
-}
-
-static int
-fread_c2(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	if (rp->ismmc) {
-		return (read_cd(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC + C2 */
-/*			(1 << 7 | 3 << 5 | 1 << 4 | 1 << 3 | 2 << 1),*/
-			(1 << 7 | 3 << 5 | 1 << 4 | 1 << 3 | 1 << 1),
-			/* without subchannels */
-			0));
-	} else {
-		return (read_da(scgp, bp, addr, cnt, rp->secsize,
-			/* Sync + all headers + user data + EDC/ECC + C2 */
-			0x04));
-	}
-}
-
-/* ARGSUSED */
-static int
-fdata_null(rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	return (0);
-}
-
-static int
-fdata_c2(rparm_t *rp, caddr_t bp, long addr, int cnt)
-{
-	int	i;
-	int	j;
-	int	k;
-	char	*p;
-
-	p = &bp[2352];
-
-	for (i = 0; i < cnt; i++, p += (2352+294)) {
-/*		scg_prbytes("XXX ", p, 294);*/
-		if ((j = cmpbytes(p, zeroblk, 294)) < 294) {
-			printf("C2 in sector: %3ld first at byte: %4d (0x%02X)", addr+i,
-				j*8 + bitidx(p[j]), p[j]&0xFF);
-			for (j = 0, k = 0; j < 294; j++)
-				k += bits(p[j]);
-			printf(" total: %4d errors\n", k);
-/*			scg_prbytes("XXX ", p, 294);*/
-			rp->c2_errors += k;
-			if (k > rp->c2_maxerrs)
-				rp->c2_maxerrs = k;
-			rp->c2_errsecs++;
-			if (k >= 100)
-				rp->c2_badsecs += 1;
-		}
-	}
-	return (0);
-}
-
-#ifdef	used
-static int
-read_scsi_g1(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->cdb.g1_cdb.cmd = 0x28;
-	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
-	g1_cdbaddr(&scmd->cdb.g1_cdb, addr);
-	g1_cdblen(&scmd->cdb.g1_cdb, cnt);
-
-	scgp->cmdname = "read extended";
-
-	return (scg_cmd(scgp));
-}
-#endif
-
-#define	G0_MAXADDR	0x1FFFFFL
-
-int
-write_scsi(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));
-}
-
-int
-write_g0(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->cdb.g0_cdb.cmd = SC_WRITE;
-	scmd->cdb.g0_cdb.lun = scg_lun(scgp);
-	g0_cdbaddr(&scmd->cdb.g0_cdb, addr);
-	scmd->cdb.g0_cdb.count = (Uchar)cnt;
-
-	scgp->cmdname = "write_g0";
-
-	return (scg_cmd(scgp));
-}
-
-int
-write_g1(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->cdb.g1_cdb.cmd = SC_EWRITE;
-	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
-	g1_cdbaddr(&scmd->cdb.g1_cdb, addr);
-	g1_cdblen(&scmd->cdb.g1_cdb, cnt);
-
-	scgp->cmdname = "write_g1";
-
-	return (scg_cmd(scgp));
-}
-
-#ifdef	used
-static void
-Xrequest_sense(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->cdb.g1_cdb.cmd = 0x3;
-	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
-	scmd->cdb.g0_cdb.count = sizeof (sense_buf);
-
-	scgp->cmdname = "request sense";
-
-	scg_cmd(scgp);
-
-	sense_count = sizeof (sense_buf) - scg_getresid(scgp);
-	movebytes(&ocmd, scmd, sizeof (*scmd));
-	scmd->sense_count = sense_count;
-	movebytes(sense_buf, (Uchar *)&scmd->sense, scmd->sense_count);
-
-	scgp->cmdname = cmdsave;
-	scg_printerr(scgp);
-	scg_printresult(scgp);	/* XXX restore key/code in future */
-}
-#endif
-
-static int
-read_retry(SCSI *scgp, caddr_t bp, long addr, long cnt, 
-			  int (*rfunc)(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt), 
-			  rparm_t *rp)
-{
-/*	int	secsize = scgp->cap->c_bsize;*/
-	int	secsize = rp->secsize;
-	int	try = 0;
-	int	err;
-	char	dummybuf[8192];
-
-	if (secsize > sizeof (dummybuf)) {
-		errmsgno(EX_BAD, "Cannot retry, sector size %d too big.\n", secsize);
-		return (-1);
-	}
-
-	errmsgno(EX_BAD, "Retrying from sector %ld.\n", addr);
-	while (cnt > 0) {
-		fprintf(stderr, ".");
-
-		do {
-			if (didintr)
-				comexit(exsig);		/* XXX besseres Konzept?!*/
-			wait_unit_ready(scgp, 120);
-			if (try >= 10) {		/* First 10 retries without seek */
-				if ((try % 8) == 0) {
-					fprintf(stderr, "+");	/* Read last sector */
-					scgp->silent++;
-					(*rfunc)(scgp, rp, dummybuf, scgp->cap->c_baddr, 1);
-					scgp->silent--;
-				} else if ((try % 4) == 0) {
-					fprintf(stderr, "-");	/* Read first sector */
-					scgp->silent++;
-					(*rfunc)(scgp, rp, dummybuf, 0, 1);
-					scgp->silent--;
-				} else {
-					fprintf(stderr, "~");	/* Read random sector */
-					scgp->silent++;
-					(*rfunc)(scgp, rp, dummybuf, choice(scgp->cap->c_baddr), 1);
-					scgp->silent--;
-				}
-				if (didintr)
-					comexit(exsig);		/* XXX besseres Konzept?!*/
-				wait_unit_ready(scgp, 120);
-			}
-			if (didintr)
-				comexit(exsig);		/* XXX besseres Konzept?!*/
-
-			fillbytes(bp, secsize, 0);
-
-			scgp->silent++;
-			err = (*rfunc)(scgp, rp, bp, addr, 1);
-			scgp->silent--;
-
-			if (err < 0) {
-				err = scgp->scmd->ux_errno;
-/*				fprintf(stderr, "\n");*/
-/*				errmsgno(err, "Cannot read source disk\n");*/
-			} else {
-				if (scg_getresid(scgp)) {
-					fprintf(stderr, "\nresid: %d\n", scg_getresid(scgp));
-					return (-1);
-				}
-				break;
-			}
-		} while (++try < retries);
-
-		if (try >= retries) {
-			fprintf(stderr, "\n");
-			errmsgno(err, "Error on sector %ld not corrected. Total of %d errors.\n",
-					addr, ++rp->errors);
-
-			if (scgp->silent <= 1 && lverbose > 0)
-				scg_printerr(scgp);
-
-			add_bad(addr);
-
-			if (!noerror)
-				return (-1);
-			errmsgno(EX_BAD, "-noerror set, continuing ...\n");
-		} else {
-			if (try >= maxtry)
-				maxtry = try;
-
-			if (try > 1) {
-				fprintf(stderr, "\n");
-				errmsgno(EX_BAD,
-				"Error on sector %ld corrected after %d tries. Total of %d errors.\n",
-					addr, try, rp->errors);
-			}
-		}
-		try = 0;
-		cnt -= 1;
-		addr += 1;
-		bp += secsize;
-	}
-	return (0);
-}
-
-static void
-read_generic(SCSI *scgp, parm_t *parmp, 
-				 int (*rfunc)(SCSI *scgp, rparm_t *rp, caddr_t bp, long addr, int cnt),
-				 rparm_t *rp,
-				 int (*dfunc)(rparm_t *rp, caddr_t bp, long addr, int cnt))
-{
-	char	filename[512];
-	char	*defname = NULL;
-	FILE	*f;
-	long	addr = 0L;
-	long	old_addr = 0L;
-	long	num;
-	long	end = 0L;
-	long	start = 0L;
-	long	cnt = 0L;
-	long	next_point = 0L;
-	long	secs_per_point = 0L;
-	double  speed;
-	int	msec;
-	int	old_msec = 0;
-	int	err = 0;
-	BOOL	askrange = FALSE;
-	BOOL	isrange = FALSE;
-	int	secsize = rp->secsize;
-	int	i = 0;
-
-	if (is_suid) {
-		if (scgp->inq->type != INQ_ROMD)
-			comerrno(EX_BAD, "Not root. Will only read from CD in suid/priv mode\n");
-	}
-
-	if (parmp == NULL || parmp->askrange)
-		askrange = TRUE;
-	if (parmp != NULL && !askrange && (parmp->start <= parmp->end))
-		isrange = TRUE;
-
-	filename[0] = '\0';
-
-	scgp->silent++;
-	if (read_capacity(scgp) >= 0)
-		end = scgp->cap->c_baddr + 1;
-	scgp->silent--;
-
-	if ((end <= 0 && isrange) || (askrange && scg_yes("Ignore disk size? ")))
-		end = 10000000;	/* Hack to read empty (e.g. blank=fast) disks */
-
-	if (parmp) {
-		if (parmp->name)
-			defname = parmp->name;
-		if (defname != NULL) {
-			fprintf(stderr, "Copy from SCSI (%d,%d,%d) disk to file '%s'\n",
-					scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp),
-					defname);
-		}
-
-		addr = start = parmp->start;
-		if (parmp->end != -1 && parmp->end < end)
-			end = parmp->end;
-		cnt = Sbufsize / secsize;
-	}
-
-	if (defname == NULL) {
-		defname = "disk.out";
-		fprintf(stderr, "Copy from SCSI (%d,%d,%d) disk to file\n",
-					scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp));
-		fprintf(stderr, "Enter filename [%s]: ", defname); flush();
-		(void) getline(filename, sizeof (filename));
-	}
-
-	if (askrange) {
-		addr = start;
-		getlong("Enter starting sector for copy:", &addr, start, end-1);
-/*		getlong("Enter starting sector for copy:", &addr, -300, end-1);*/
-		start = addr;
-	}
-
-	if (askrange) {
-		num = end - addr;
-		getlong("Enter number of sectors to copy:", &num, 1L, num);
-		end = addr + num;
-	}
-
-	if (askrange) {
-/* XXX askcnt */
-		cnt = Sbufsize / secsize;
-		getlong("Enter number of sectors per copy:", &cnt, 1L, cnt);
-	}
-
-	if (filename[0] == '\0')
-		strncpy(filename, defname, sizeof (filename));
-	filename[sizeof (filename)-1] = '\0';
-	if (streql(filename, "-")) {
-		f = stdout;
-#ifdef	NEED_O_BINARY
-		setmode(STDOUT_FILENO, O_BINARY);
-#endif
-	} else if ((f = fileopen(filename, notrunc?"wcub":"wctub")) == NULL)
-		comerr("Cannot open '%s'.\n", filename);
-
-	fprintf(stderr, "end:  %8ld\n", end);
-	if (gettimeofday(&starttime, (struct timezone *)0) < 0)
-		comerr("Cannot get start time\n");
-
-	if (meshpoints > 0) {
-		if ((end-start) < meshpoints)
-			secs_per_point = 1;
-		else
-			secs_per_point = (end-start) / meshpoints;
-		next_point = start + secs_per_point;
-		old_addr = start;
-	}
-
-	for (; addr < end; addr += cnt) {
-		if (didintr)
-			comexit(exsig);		/* XXX besseres Konzept?!*/
-
-		if ((addr + cnt) > end)
-			cnt = end - addr;
-
-		if (meshpoints > 0) {
-			if (addr > next_point) {
-
-				msec = prstats_silent();
-				if ((msec - old_msec) == 0)		/* Avoid division by zero */
-					msec = old_msec + 1;
-				speed = ((addr - old_addr)/(1000.0/secsize)) / (0.001*(msec - old_msec));
-				if (do_factor) {
-					if (is_cdrom)
-						speed /= 176.400;
-					else if (is_dvd)
-						speed /= 1385.0;
-				}
-				fprintf(stderr, "addr: %8ld cnt: %ld", addr, cnt);
-				printf("%8ld %8.2f\n", addr, speed);
-				fprintf(stderr, "\r");
-				next_point += secs_per_point;
-				old_addr = addr;
-				old_msec = msec;
-				i++;
-				if (meshpoints < 100)
-					flush();
-				else if (i % (meshpoints/100) == 0)
-					flush();
-			}
-		}
-		fprintf(stderr, "addr: %8ld cnt: %ld\r", addr, cnt);
-
-		scgp->silent++;
-		if ((*rfunc)(scgp, rp, Sbuf, addr, cnt) < 0) {
-			scgp->silent--;
-			err = scgp->scmd->ux_errno;
-			if (quiet) {
-				fprintf(stderr, "\n");
-			} else if (scgp->silent == 0) {
-				scg_printerr(scgp);
-			}
-			errmsgno(err, "Cannot read source disk\n");
-
-			if (read_retry(scgp, Sbuf, addr, cnt, rfunc, rp) < 0)
-				goto out;
-		} else {
-			scgp->silent--;
-			if (scg_getresid(scgp)) {
-				fprintf(stderr, "\nresid: %d\n", scg_getresid(scgp));
-				goto out;
-			}
-		}
-		(*dfunc)(rp, Sbuf, addr, cnt);
-		if (filewrite(f, Sbuf, cnt * secsize) < 0) {
-			err = geterrno();
-			fprintf(stderr, "\n");
-			errmsgno(err, "Cannot write '%s'\n", filename);
-			break;
-		}
-	}
-	fprintf(stderr, "addr: %8ld", addr);
-out:
-	fprintf(stderr, "\n");
-	msec = prstats();
-	if (msec == 0)		/* Avoid division by zero */
-		msec = 1;
-#ifdef	OOO
-	fprintf(stderr, "Read %.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)) / (0.001*msec));
-#else
-	fprintf(stderr, "Read %.2f kB at %.1f kB/sec.\n",
-		(double)(addr - start)/(1024.0/secsize),
-		(double)((addr - start)/(1024.0/secsize)) / (0.001*msec));
-#endif
-	print_bad();
-}
-
-static void
-write_disk(SCSI *scgp, parm_t *parmp)
-{
-	char	filename[512];
-	char	*defname = "disk.out";
-	FILE	*f;
-	long	addr = 0L;
-	long	cnt;
-	long	amt;
-	long	end;
-	int	msec;
-	int	start;
-
-	if (is_suid)
-		comerrno(EX_BAD, "Not root. Will not write in suid/priv mode\n");
-
-	filename[0] = '\0';
-	if (read_capacity(scgp) >= 0) {
-		end = scgp->cap->c_baddr + 1;
-		print_capacity(scgp, stderr);
-	}
-
-	if (end <= 1)
-		end = 10000000;	/* Hack to write empty disks */
-
-	if (parmp) {
-		if (parmp->name)
-			defname = parmp->name;
-		fprintf(stderr, "Copy from file '%s' to SCSI (%d,%d,%d) disk\n",
-					defname,
-					scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp));
-
-		addr = start = parmp->start;
-		if (parmp->end != -1 && parmp->end < end)
-			end = parmp->end;
-		cnt = Sbufsize / scgp->cap->c_bsize;
-	} else {
-		fprintf(stderr, "Copy from file to SCSI (%d,%d,%d) disk\n",
-					scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp));
-		fprintf(stderr, "Enter filename [%s]: ", defname); flush();
-		(void) getline(filename, sizeof (filename));
-		fprintf(stderr, "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);
-/*		fprintf(stderr, "end:  %8ld\n", end);*/
-	}
-
-	if (filename[0] == '\0')
-		strncpy(filename, defname, sizeof (filename));
-	filename[sizeof (filename)-1] = '\0';
-	if (streql(filename, "-")) {
-		f = stdin;
-#ifdef	NEED_O_BINARY
-		setmode(STDIN_FILENO, O_BINARY);
-#endif
-	} else if ((f = fileopen(filename, "rub")) == NULL)
-		comerr("Cannot open '%s'.\n", filename);
-
-	fprintf(stderr, "end:  %8ld\n", end);
-	if (gettimeofday(&starttime, (struct timezone *)0) < 0)
-		comerr("Cannot get start time\n");
-
-	for (; addr < end; addr += cnt) {
-		if (didintr)
-			comexit(exsig);		/* XXX besseres Konzept?!*/
-
-		if ((addr + cnt) > end)
-			cnt = end - addr;
-
-		fprintf(stderr, "addr: %8ld cnt: %ld\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");
-	}
-	fprintf(stderr, "addr: %8ld\n", addr);
-	msec = prstats();
-	if (msec == 0)		/* Avoid division by zero */
-		msec = 1;
-	fprintf(stderr, "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)) / (0.001*msec));
-}
-
-static int
-choice(int n)
-{
-#if	defined(HAVE_DRAND48)
-	extern	double	drand48(void);
-
-	return (drand48() * n);
-#else
-#	if	defined(HAVE_RAND)
-	extern	int	rand(void);
-
-	return (rand() % n);
-#	else
-	return (0);
-#	endif
-#endif
-}
-
-static void
-ra(SCSI *scgp)
-{
-/*	char	filename[512];*/
-	FILE	*f;
-/*	long	addr = 0L;*/
-/*	long	cnt;*/
-/*	long	end;*/
-/*	int	msec;*/
-/*	int	start;*/
-/*	int	err = 0;*/
-
-	select_secsize(scgp, 2352);
-	read_capacity(scgp);
-	print_capacity(scgp, stderr);
-	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 - scg_getresid(scgp));*/
-	filewrite(f, Sbuf, 50 * 2352);
-	fclose(f);
-}
-
-#define	g5x_cdblen(cdb, len)	((cdb)->count[0] = ((len) >> 16L)& 0xFF,\
-				(cdb)->count[1] = ((len) >> 8L) & 0xFF,\
-				(cdb)->count[2] = (len) & 0xFF)
-
-int
-read_da(SCSI *scgp, caddr_t bp, long addr, int cnt, int framesize, int subcode)
-{
-	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*framesize;
-	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
-	scmd->cdb_len = SC_G5_CDBLEN;
-	scmd->sense_len = CCS_SENSE_LEN;
-	scmd->cdb.g5_cdb.cmd = 0xd8;
-	scmd->cdb.g5_cdb.lun = scg_lun(scgp);
-	g5_cdbaddr(&scmd->cdb.g5_cdb, addr);
-	g5_cdblen(&scmd->cdb.g5_cdb, cnt);
-	scmd->cdb.g5_cdb.res10 = subcode;
-
-	scgp->cmdname = "read_da";
-
-	return (scg_cmd(scgp));
-}
-
-int
-read_cd(SCSI *scgp, caddr_t bp, long addr, int cnt, int framesize, int data, 
-		  int subch)
-{
-	register struct	scg_cmd	*scmd = scgp->scmd;
-
-	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
-	scmd->addr = bp;
-	scmd->size = cnt*framesize;
-	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
-	scmd->cdb_len = SC_G5_CDBLEN;
-	scmd->sense_len = CCS_SENSE_LEN;
-	scmd->cdb.g5_cdb.cmd = 0xBE;
-	scmd->cdb.g5_cdb.lun = scg_lun(scgp);
-	scmd->cdb.g5_cdb.res = 0;	/* expected sector type field ALL */
-	g5_cdbaddr(&scmd->cdb.g5_cdb, addr);
-	g5x_cdblen(&scmd->cdb.g5_cdb, cnt);
-
-	scmd->cdb.g5_cdb.count[3] = data & 0xFF;
-	scmd->cdb.g5_cdb.res10 = subch & 0x07;
-
-	scgp->cmdname = "read_cd";
-
-	return (scg_cmd(scgp));
-}
-
-static void
-oldmode(SCSI *scgp, int *errp, int *retrp)
-{
-	Uchar	mode[0x100];
-	Uchar	cmode[0x100];
-	Uchar	*p;
-	int	i;
-	int	len;
-
-	fillbytes(mode, sizeof (mode), '\0');
-	fillbytes(cmode, sizeof (cmode), '\0');
-
-	if (!get_mode_params(scgp, 0x01, "CD error recovery parameter",
-			mode, (Uchar *)0, (Uchar *)cmode, (Uchar *)0, &len)) {
-		return;
-	}
-	if (xdebug)
-		scg_prbytes("Mode Sense Data", mode, len);
-
-	mode[0] = 0;
-	mode[2] = 0; /* ??? ist manchmal 0x80 */
-	p = mode;
-	p += mode[3] + 4;
-	*p &= 0x3F;
-
-	if (xdebug)
-		scg_prbytes("Mode page 1:", p, 0x10);
-
-	i = p[2];
-	if (errp != NULL)
-		*errp = i;
-
-	i = p[3];
-	if (retrp != NULL)
-		*retrp = i;
-}
-
-static void
-domode(SCSI *scgp, int err, int retr)
-{
-	Uchar	mode[0x100];
-	Uchar	cmode[0x100];
-	Uchar	*p;
-	int	i;
-	int	len;
-
-	fillbytes(mode, sizeof (mode), '\0');
-	fillbytes(cmode, sizeof (cmode), '\0');
-
-	if (!get_mode_params(scgp, 0x01, "CD error recovery parameter",
-			mode, (Uchar *)0, (Uchar *)cmode, (Uchar *)0, &len)) {
-		return;
-	}
-	if (xdebug || (err == -1 && retr == -1)) {
-		scg_prbytes("Mode Sense Data", mode, len);
-	}
-
-	mode[0] = 0;
-	mode[2] = 0; /* ??? ist manchmal 0x80 */
-	p = mode;
-	p += mode[3] + 4;
-	*p &= 0x3F;
-
-	if (xdebug || (err == -1 && retr == -1))
-		scg_prbytes("Mode page 1:", p, 0x10);
-
-	i = p[2];
-	if (err == -1) {
-		getint("Error handling? ", &i, 0, 255);
-		p[2] = i;
-	} else {
-		if (xdebug)
-			fprintf(stderr, "Error handling set from %02X to %02X\n",
-		p[2], err);
-		p[2] = err;
-	}
-
-	i = p[3];
-	if (retr == -1) {
-		getint("Retry count? ", &i, 0, 255);
-		p[3] = i;
-	} else {
-		if (xdebug)
-			fprintf(stderr, "Retry count set from %d to %d\n",
-		p[3] & 0xFF, retr);
-		p[3] = retr;
-	}
-
-	if (xdebug || (err == -1 && retr == -1))
-		scg_prbytes("Mode Select Data", mode, len);
-	mode_select(scgp, mode, len, 0, scgp->inq->data_format >= 2);
-}
-
-
-/*--------------------------------------------------------------------------*/
-static	void	qpto96(Uchar *sub, Uchar *subq, int dop);
-/*EXPORT	void	qpto96		__PR((Uchar *sub, Uchar *subq, int dop));*/
-/*
- * Q-Sub auf 96 Bytes blähen und P-Sub addieren
- *
- * OUT: sub, IN: subqptr
- */
-static void
-/*EXPORT void*/
-qpto96(Uchar *sub, Uchar *subqptr, int dop)
-{
-	Uchar	tmp[16];
-	Uchar	*p;
-	int	c;
-	int	i;
-
-	if (subqptr == sub) {
-		movebytes(subqptr, tmp, 12);
-		subqptr = tmp;
-	}
-	fillbytes(sub, 96, '\0');
-
-	/* CSTYLED */
-	if (dop) for (i = 0, p = sub; i < 96; i++) {
-		*p++ |= 0x80;
-	}
-	for (i = 0, p = sub; i < 12; i++) {
-		c = subqptr[i] & 0xFF;
-/*printf("%02X\n", c);*/
-		if (c & 0x80)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x40)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x20)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x10)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x08)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x04)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x02)
-			*p++ |= 0x40;
-		else
-			p++;
-		if (c & 0x01)
-			*p++ |= 0x40;
-		else
-			p++;
-	}
-}
-
-/*--------------------------------------------------------------------------*/
-
-static void
-ovtime(SCSI *scgp)
-{
-	register int	i;
-
-	scgp->silent++;
-	(void) test_unit_ready(scgp);
-	scgp->silent--;
-	if (test_unit_ready(scgp) < 0)
-		return;
-
-	printf("Doing 1000 'TEST UNIT READY' operations.\n");
-
-	if (gettimeofday(&starttime, (struct timezone *)0) < 0)
-		comerr("Cannot get start time\n");
-
-	for (i = 1000; --i >= 0; ) {
-		(void) test_unit_ready(scgp);
-
-		if (didintr)
-			return;
-	}
-
-	prstats();
-
-	/*
-	 * ATAPI drives do not like seek_g0()
-	 */
-	scgp->silent++;
-	i = seek_g0(scgp, 0L);
-	scgp->silent--;
-
-	if (i >= 0) {
-		printf("Doing 1000 'SEEK_G0 (0)' operations.\n");
-
-		if (gettimeofday(&starttime, (struct timezone *)0) < 0)
-			comerr("Cannot get start time\n");
-
-		for (i = 1000; --i >= 0; ) {
-			(void) seek_g0(scgp, 0L);
-
-			if (didintr)
-				return;
-		}
-
-		prstats();
-	}
-
-	scgp->silent++;
-	i = seek_g1(scgp, 0L);
-	scgp->silent--;
-	if (i < 0)
-		return;
-
-	printf("Doing 1000 'SEEK_G1 (0)' operations.\n");
-
-	if (gettimeofday(&starttime, (struct timezone *)0) < 0)
-		comerr("Cannot get start time\n");
-
-	for (i = 1000; --i >= 0; ) {
-		(void) seek_g1(scgp, 0L);
-
-		if (didintr)
-			return;
-	}
-
-	prstats();
-}
-
-#define	BAD_INC		16
-long	*badsecs;
-int	nbad;
-int	maxbad;
-
-static void
-add_bad(long addr)
-{
-	if (maxbad == 0) {
-		maxbad = BAD_INC;
-		badsecs = malloc(maxbad * sizeof (long));
-		if (badsecs == NULL)
-			comerr("No memory for bad sector list\n.");
-	}
-	if (nbad >= maxbad) {
-		maxbad += BAD_INC;
-		badsecs = realloc(badsecs, maxbad * sizeof (long));
-		if (badsecs == NULL)
-			comerr("No memory to grow bad sector list\n.");
-	}
-	badsecs[nbad++] = addr;
-}
-
-static void
-print_bad()
-{
-	int	i;
-
-	if (nbad == 0)
-		return;
-
-	fprintf(stderr, "Max corected retry count was %d (limited to %d).\n", maxtry, retries);
-	fprintf(stderr, "The following %d sector(s) could not be read correctly:\n", nbad);
-	for (i = 0; i < nbad; i++)
-		fprintf(stderr, "%ld\n", badsecs[i]);
-}

Copied: cdrkit/trunk/readom/readcd.c (from rev 432, cdrkit/trunk/readcd/readcd.c)




More information about the Debburn-changes mailing list