[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, §ors, &do_write,
- &c2scan,
- &fulltoc, &clone,
- &noerror, &nocorr,
- ¬runc, &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, ¶ms.start);
- if (p && *p == '-')
- p = astol(++p, ¶ms.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, ¶ms, 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, ¶ms, TRUE) < 0)
- comerrno(EX_BAD, "Read fulltoc problems.\n");
- readcd_disk(scgp, ¶ms);
- } else
-#endif
- if (c2scan) {
- noerror = TRUE;
- if (retries == MAX_RETRY)
- retries = 10;
- if (params.name == NULL)
- params.name = "/dev/null";
- readc2_disk(scgp, ¶ms);
- } else if (do_write)
- write_disk(scgp, ¶ms);
- else
- read_disk(scgp, ¶ms);
-}
-
-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, ¶ms); 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, §);
- if (f != NULL)
- filewrite(f, §, 1);
- if (xdebug)
- scg_prbytes("sec 0", (Uchar *)Sbuf, 16);
-
- sect = SECT_AUDIO;
- get_sectype(scgp, scgp->cap->c_baddr-4, §);
- if (f != NULL)
- filewrite(f, §, 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