diff options
581 files changed, 200577 insertions, 0 deletions
diff --git a/3rd-party/dirsplit/CMakeLists.txt b/3rd-party/dirsplit/CMakeLists.txt new file mode 100644 index 0000000..497774c --- /dev/null +++ b/3rd-party/dirsplit/CMakeLists.txt @@ -0,0 +1,3 @@ +PROJECT (DIRSPLIT C) +INSTALL(PROGRAMS dirsplit DESTINATION bin) +INSTALL(FILES dirsplit.1 DESTINATION share/man/man1) diff --git a/3rd-party/dirsplit/ChangeLog b/3rd-party/dirsplit/ChangeLog new file mode 100644 index 0000000..b5cd780 --- /dev/null +++ b/3rd-party/dirsplit/ChangeLog @@ -0,0 +1,27 @@ +*0.3.3: 2006/03 + +* code refactoring, much more readable now +* dropped the "du" exploration mode +* dropped the read-from-file mode and input "correct" cludge + * Use the new -T option to specify arbitrary input, and avoid dupes. + * Use the new option -F to follow symlinks +* option name fixes +* new option simple/stupid mode + * no space-efficiency optimisation, instead trying to store in alphabetic + order + +0.3.2: + +* cosmetic, correct usage and long help + +0.3.1: + +* proper fix for the = filenames + +0.3: + +* rewrite of some data input code, now using internal directory scanning +(exploration) go get data, not trusting du -a crap +* estimative calculation for filesystem overhead for directory entries +* workaround for = in filenames +* much, much more diff --git a/3rd-party/dirsplit/README b/3rd-party/dirsplit/README new file mode 100644 index 0000000..3867a12 --- /dev/null +++ b/3rd-party/dirsplit/README @@ -0,0 +1,7 @@ +Package: dirsplit +License: GPLv2 (until I change my mind) +Purpose: put files from a directory structure in subdirectories of specified +size or create catalogues for mkisofs so that generated volumes waste as few +space as possible +Algrorithm: randomising FirstFit or BestFit +Usage: Selfexplaining diff --git a/3rd-party/dirsplit/dirsplit b/3rd-party/dirsplit/dirsplit new file mode 100755 index 0000000..1348976 --- /dev/null +++ b/3rd-party/dirsplit/dirsplit @@ -0,0 +1,611 @@ +#!/usr/bin/perl +# -*- Mode: Perl -*- +# dirsplit --- +# Author : Eduard Bloch ( blade@debian.org ) +# Last Modified On : Sun, 06 Feb 2005 14:59:51 +0100 +# Status : Working, but use with caution! +# License: GPLv2 + +my $version="0.3.3"; + +require v5.8.1; +use strict; +use List::Util 'shuffle'; +use Getopt::Long qw(:config no_ignore_case bundling); +use File::Basename; +use File::Path; +use Cwd 'abs_path'; + +my $ret=0; +my $max="4488M"; +my $prefix="vol_"; +my $acc=20; +my $emode=1; +my $bsize=2048; +my $ofac =50; +my $opt_help; +my $opt_longhelp; +my $opt_sim; +my $opt_dir; +my $opt_flat; +my $opt_move; +my $opt_ver; +my $opt_sln; +my $opt_ln; +my $opt_filter; +my $opt_simple; +my $opt_follow; +my $get_ver; +my $opt_listfile; + + +my %options = ( + "h|help" => \$opt_help, + "d|dirhier" => \$opt_dir, + "flat" => \$opt_flat, + "f|filter=s" => \$opt_filter, + "F|follow" => \$opt_follow, + "e|expmode=i" => \$emode, + "o|overhead=i" => \$ofac, + "b|blksize=i" => \$bsize, + "n|no-act" => \$opt_sim, + "m|move" => \$opt_move, + "l|symlink" => \$opt_sln, + "L|hardlink" => \$opt_ln, + "v|verbose" => \$opt_ver, + "s|size=s" => \$max, + "S|simple" => \$opt_simple, + "T|input=s" => \$opt_listfile, + "p|prefix=s" => \$prefix, + "a|accuracy=i" => \$acc, + "H|longhelp" => \$opt_longhelp, + "version" => \$get_ver +); + +&show_help(1) unless ( GetOptions(%options)); +&show_help(1) if $opt_help; +&show_longhelp if $opt_longhelp; +if($get_ver) { + print $version; + exit 0; +} + +# ignore the old dirhier setting since it is default now and disable the flag when opt_flat is specified +$opt_dir = !$opt_flat; + +$opt_ver = 1 if $opt_sim; +$opt_move=1 if ($opt_sln || $opt_ln); + +# big list @sizes containing the "items" (object sizes) +# %names hash mapping "items" (size as key) to arrays with filenames/subarrays for coalesced files +my @sizes; +my %names; + +# result containts the calculated output. In simple mode, an +# array (bins) of atoms (files or filelists). Otherwise, sizes +# instead of atoms, to be resolved with %names. +my @result; + +my $inputdir; + +$max=fixnr($max); +# about 400kB for iso headers +$max-=420000; + +# init default value +my $globwaste=0; + + +if(-d $ARGV[0] || (-d readlink($ARGV[0]))) { + syswrite(STDOUT,"Building file list, please wait...\n"); + # save the absolut path before doing anyhting + $inputdir=Cwd::abs_path($ARGV[0]); + &explore($inputdir); +} +elsif($opt_listfile) { + if($opt_listfile eq "-") { + &parseListe(\*STDIN); + } + else { + open(my $in, "<", $opt_listfile) || die "Cannot open list file $opt_listfile\n"; + &parseListe($in); + } +} +else { + die "Error: please specify a directory\n"; +} + +# check for pointless requests +my $testsize=0; +for(@sizes) { + die "Too large object(s) ($_) for the given max size: @{$names{$_}} (maybe coalesced in arrays, check manually)\n" if($_>$max); + + $testsize+=$_; +} + +$acc=1 if ($testsize <= $max); # just generate a list, more trials are pointless +print "\nSumm: $testsize\n" if($opt_ver); +die "Nothing to do!\n" if($testsize<4096); # looks like just an empty dir + +if(!$opt_simple) { + syswrite(STDOUT, "Calculating, please wait...\n"); + my $starttime=time; + $globwaste=$max*@sizes; + for(1..$acc) { + syswrite(STDOUT,"."); + my @tmp; + #my $waste = bp_bestfit($max, \@in, \@tmp); + my $waste = bp_firstfit($max, \@sizes, \@tmp); + #print "D: waste - $waste\n"; + if($waste < $globwaste) { + $globwaste=$waste; + @result=@tmp; + } + if($starttime && time > $starttime+10) { + syswrite(STDOUT,"\nSpent already over 10s (for $_ iterations)\nHint: reduce accuracy to make it faster!\n"); + undef $starttime; + } + @sizes=shuffle(@sizes); + } + +} + +print "\nCalculated, using ".(scalar @result)." volumes.\n"; +print "Wasted: $globwaste Byte (estimated, check mkisofs -print-size ...)\n"; + +# and the real work +my $i=0; +my $inDirLen=length($inputdir); +for(@result) { + $i++; + my $o; + open($o, ">$prefix$i.list") if(! ($opt_move || $opt_sim)); + my $dirPrefix=dirname($prefix); + my $prefixBase=basename($prefix); + my $dirPrefixAbs=Cwd::abs_path($dirPrefix); + + for(@{$_}) { + my $stuffRef; + + # For simple mode, the files/atoms are already resolved, otherwise take + # the next with appropriate size. + my $item= $opt_simple ? $_ : shift(@{$names{$_}}); + + # make reference point to an array with our files, create a list if needed + if(ref($item) eq "ARRAY") { + $stuffRef=$item; + } + else { + $stuffRef=[$item]; + } + + for my $file (@$stuffRef) { + my $relFile=substr($file,$inDirLen+1); + my $base=basename($relFile); + if($opt_move) { + my $targetsubdir = $dirPrefixAbs."/$prefixBase$i"; + $targetsubdir .= "/".dirname($relFile) if($opt_dir); + print "$file -> $targetsubdir/$base\n" if($opt_ver); + if(!$opt_sim) { + mkpath $targetsubdir || die "Problems creating $targetsubdir\n"; + # last check + die "Could not create $targetsubdir?\n" if(!(-d $targetsubdir && -w $targetsubdir)); + if($opt_sln) { + symlink($file, "$targetsubdir/$base"); + } + elsif($opt_ln) { + if(-d $file && !-l $file) { + mkdir "$targetsubdir/$base"; + } + else { + link($file, "$targetsubdir/$base"); + } + } + else { + rename($file, "$targetsubdir/$base"); + } + } + } + else { + # escape = in mkisofs catalogs, they are used as separator + my $isoname = ($opt_dir?$relFile : $base); + $isoname=~s/=/\\=/g; + my $sourcefile=$file; + $sourcefile=~s/=/\\=/g; + print "$i: /$isoname=$sourcefile\n" if $opt_ver; + print $o "/$isoname=$sourcefile\n" if(!$opt_sim); + } + } + } + close($o) if($o); +} + +exit $ret; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# recursive function +# parameter: directory +# mode 1: descend as far as possible and index all non-directories +# mode 2++: +# put all files of a dir into coaleseced-object, then descend into each dir +sub explore { + (my $dir) = @_; + my @stuff; + my @dirs; + my @files; + + opendir(DIR, $dir) || die "Could not open $dir\n"; + @stuff=readdir(DIR); + + if($opt_simple) { + @stuff=sort { lc($a) cmp lc($b) } @stuff; + } + + foreach my $f (@stuff) { + next if ($f eq "." || $f eq ".."); + #print "\$f=$opt_filter;\n"; + + $f="$dir/$f" if($dir ne "."); + + if ($opt_filter) { + next unless (eval("\$f=~$opt_filter;")); + } + + if(-l $f && ! $opt_follow) { + push(@files, $f); + } + elsif(-d $f) { + push(@dirs, $f); + } + else { + push(@files, $f); + } + } + closedir(DIR); + + if( (@dirs + @files) == 0 ) { + # this one is empty, register for cosmetics reason + &insitem(getsize($dir), $dir); + return; + } + + # recurse on directories + &explore($_) for(@dirs); + + # and now process files + if($emode==1) { + &insitem(getsize($_), $_) for(@files); + } + else { + # handle coalesced objects - first some sanity checks and splitting if + # required + + my $filesum=0; + for(@files) { + my $tmp=getsize($_); + if($tmp>$max) { + # already too large, stop right here + die "Too large file ($_) for the given max size $max, aborting...\n"; + } + $filesum += $tmp; + }; + + # handle coal. objects becoming too large + if($filesum>$max) { + # too large coal. object... + if($emode==3) { + # don't coalesc in this mode, do like mode 1 above, leave them alone + &insitem(getsize($_), $_) for(@files); + return; + } + # a bit complicated, split file set while creating coal.objects + if($emode==4) { + my $partsum=0; + my @sorted=sort(@files); + my @tmpvol; + for(my $i=0;$i<=$#sorted;$i++) { +# print "D: i: $i, partsum: $partsum, file: $sorted[$i]\n"; + my $tmp=getsize($sorted[$i]); + $partsum+=$tmp; + if($partsum>$max) { + # undo the last step then build the coal.object + $partsum-=$tmp; + $i--; + + &insitem($partsum, \@tmpvol); + # reset temporaries + undef @tmpvol; + undef $partsum; + } + else { + push(@tmpvol, $sorted[$i]); + } + } + return; + } + } + + # ok, building a coalesced object for simple cases + if($filesum) { + &insitem($filesum, \@files); + } + } +} + +my $simplePos=0; +my @simpleBinSizes; + +# args: size, object (filename or list reference) +sub insitem { + my ($size, $object) = @_; + # normaly, put the items into the pool for calculation. In simple mode, calculate here + + push(@sizes, $size); + push(@{$names{$size}},$object); + + if($opt_simple) { + # now the simplest method to fill the bins, just take a new one when the + # object-to-be-added no longer fits + if($simpleBinSizes[$simplePos]+$size > $max) { + $globwaste += ( $max-$simpleBinSizes[$simplePos] ); + $simplePos++; + }; + $simpleBinSizes[$simplePos]+=$size; + push( @{$result[$simplePos]}, $object); + } + +} + +sub getsize { + (my $file) = @_; + my $size = ((stat($file))[7]); + my $rest = ($size % $bsize); + $size = ($size + $bsize - $rest) if ($rest); + return 1+int(200 + $ofac*length(basename($file)) + $size); +} + +sub parseListe { + my $fh=${$_[0]}; + while(<$fh>) { + if(/^(\w+)\s+(.+)/) { + &insitem(fixnr($1), $2); + } + } +} + +sub fixnr { + # args: + # Number + # optional: default multiplier + my $fac; + my $nr; + if($_[0]=~/(\d+)(\D)/) { + $nr=$1; + $fac=$2; + } + elsif(defined($_[1])) { + $nr=$_[0]; + $fac=$_[1]; + } + else { + return $_[0]; + } + return $nr*1000000000 if($fac eq "g"); + return $nr*1073741824 if($fac eq "G"); + return $nr*1000000 if($fac eq "m"); + return $nr*1048576 if($fac eq "M"); + return $nr*1000 if($fac eq "k"); + return $nr*1024 if($fac eq "K"); + return $nr if($fac eq "b"); + die "$fac is not a valid multiplier!"; +} + + +sub show_help { + print <<EOM +dirsplit [options] [advanced options] < directory > + + -H|--longhelp Show the long help message with more advanced options + -n|--no-act Only print the commands, no action (implies -v) + -s|--size NUMBER - Size of the medium (default: $max) + -e|--expmode NUMBER - directory exploration mode (recommended, see long help) + -m|--move Move files to target dirs (default: create mkisofs catalogs) + -p|--prefix STRING - first part of catalog/directory name (default: vol_) + -h|--help Show this option summary + -v|--verbose More verbosity + +The complete help can be displayed with the --longhelp (-H) option. +The default mode is creating file catalogs useable with: + mkisofs -D -r --joliet-long -graft-points -path-list CATALOG + +Example: +dirsplit -m -s 700M -e2 random_data_to_backup/ +EOM + ; + exit shift; +} + +sub show_longhelp { + my $msglong=" +dirsplit [options] [advanced options] < directory > + -n|--no-act Only print the commands, no action (implies -v) + -s|--size NUMBER - Size of the medium (default: $max) + -m|--move Move files to target dirs (default: create mkisofs catalogs) + -l|--symlink similar to -m but just creates symlinks in the target dirs + -L|--hardlink like -l but creates hardlinks + -p|--prefix STRING - first part of catalog/directory name (default: vol_) + -f|--filter EXPR - Filter expression, see examples below and perlre manpage + --flat Flat dir mode, don't recreate subdirectory structure (not recommended) + -e|--expmode NUMBER, special exploration modes, used with directory argument + + 1: (default) native exploration of the specified directory, but file sizes + are rounded up to 2048 blocks plus estimated overhead for + filenames (see -o option) + 2: like 1, but all files in directory are put together (as \"atom\") onto the + same medium. This does not apply to subdirectories, however. + 3: like 2, but don't coalesc files when the size of the \"atom\" becomes too + large for the medium size (currently $max) + 4: like 2, but the max. size of the atoms is limited to $max (storing the + rest on another medium) + + -F|--follow Follow symlinks. Use with care! + -b|--blksize NUMBER, block size of the target filesystem (currently $bsize). + -o|--overhead NUMBER, overhead caused by directory entries (as factor for the + filename length, default: 50, empiricaly found for Joliet+RR + with not-so-deep directory structure). Works in exploration + mode. + -a|--accuracy NUMBER (1=faster, large number=better efficiency, default: 500) + -S|--simple Simple/stupid/alphabetic mode + -T|--input FILENAME (or - for STDIN): List with sizes and paths, try: + find dir -type f -printf \"%s %p\n\" + to get an example. Avoid duplicates! Unit suffixes are allowed. + -h|--help Show this option summary + -v|--verbose More verbosity + +File sizes are expected to be in bytes, append modifier letters to multiply +with a factor, eg 200M (b,k,K,m,M,g,G for Bytes, Kb, KiB, Mb, MiB, Gb, GiB). +The default output mode is creating file catalogs useable with + mkisofs -D -r --joliet-long -graft-points -path-list CATALOG + +Examples: +dirsplit -m -s 120M -e4 largedirwithdata/ -p /zipmedia/backup_ #move stuff into splitted backup dirs +dirsplit -s 700M -e2 music/ # make mkisofs catalogs to burn all music to 700M CDRs, keep single files in each dir together +dirsplit -s 700M -e2 -f '/other\\/Soundtracks/' music/ # like above, only take files from other/Soundtracks +dirsplit -s 700M -e2 -f '!/Thumbs.db|Desktop.ini|\\.m3u\$/i' # like above, ignore some junk files and playlists, both letter cases + +Bugs: overhead trough blocksize alignment and directory entry storage varies, +heavily depends on the target filesystem and configuration (see -b and -o). + +You should compare the required size of the created catalogs, eg.: +for x in *list ; do mkisofs -quiet -D -r --joliet-long -graft-points \\ + -path-list \$x -print-size; done +(output in blocks of 2048 bytes) with the expected size (-s) and media data +(cdrecord -v -toc ...). +"; + print $msglong; + exit 0; +} + +# Parms: bin size (int), input array (arr reference), output array (arr reference) +# Returns: wasted space (int) +sub bp_bestfit { + my $max=$_[0]; + my @in = @{$_[1]}; + my $target = $_[2]; + my @out; + my @bel; + + my @tmp; + push(@tmp,$in[0]); + push(@out, \@tmp); + $bel[0] = $in[0]; + shift @in; + + for(@in) { + my $bestplace=$#out+1; + my $bestwert=$max; + for($i=0;$i<=$#out;$i++) { + my $rest; + $rest=$max-$bel[$i]-$_; + if($rest>0 && $rest < $bestwert) { + $bestplace=$i; + $bestwert=$rest; + }; + } + if($bestplace>$#out) { + my @bin; + $bel[$bestplace]=$_; + push(@bin, $_); + push(@out,\@bin); + } + else{ + $bel[$bestplace]+=$_; + push( @{$out[$bestplace]} , $_); + } + } + my $ret=0; + # count all rests but the last one + for($i=0;$i<$#out;$i++) { + $ret+=($max-$bel[$i]); + } + @{$target} = @out; + return $ret; +} + +# Parms: bin size (int), input array (arr reference), output array (arr reference) +# Returns: wasted space (int) +sub bp_firstfit { + my $max=$_[0]; + my @in = @{$_[1]}; + my $target = $_[2]; + my @out; + my @bel; + + piece: foreach my $obj (@in) { + # first fit, use the first bin with enough free space + # print "F: bin$i: $obj, @{$names{$obj}}\n"; + for($i=0;$i<=$#out;$i++) { + my $newsize=($bel[$i]+$obj); +# print "bel[i]: $bel[$i], new?: $newsize to max: $max\n"; + if( $newsize <= $max ) { +# print "F: bin$i: $bel[$i]+$obj=$newsize\n"; + #fits here + $bel[$i]=$newsize; + push( @{$out[$i]} , $obj); + next piece; # break + } + } + # neues Bin + my @bin; + $bel[$i]=$obj; +# print "N: bin$i: $bel[$i]=$obj\n"; + push(@bin, $obj); + push(@out,\@bin); + } + my $ret=0; + # sum up all rests except of the one from the last bin + for($i=0;$i<$#out;$i++) { +# print "hm, bel $i ist :".$bel[$i]." und res:".($max-$bel[$i])."\n"; + $ret+=($max-$bel[$i]); + } + @{$target} = @out; +# print "wtf, ".join(",", @{$out[0]})."\n"; + return $ret; +} diff --git a/3rd-party/dirsplit/dirsplit.1 b/3rd-party/dirsplit/dirsplit.1 new file mode 100644 index 0000000..76fdfa5 --- /dev/null +++ b/3rd-party/dirsplit/dirsplit.1 @@ -0,0 +1,27 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33. +.TH DIRSPLIT "1" "March 2004" "dirsplit 0.3" "User Commands" +.SH NAME +dirsplit \- splits directory into multiple with equal size +.SH SYNOPSIS +dirsplit \fB[options]\fR < directory | content-list-file > +.SH DESCRIPTION +displit is designed to for a simple purpose: convert a directory with +many multiple files (which are all smaller than a certain medium, eg. +DVD) and "splits" it into "volumes", looking for the optimal order to +get the best space/medium-number efficiency. +.P +The actual action is either adding the files to mkisofs catalogs or real +moving of files into new directories (or creating links/symlinks). +The method is not limited to files, whole directories can also be handled this +way (see various filesystem exploration modes). +.SH OPTIONS +.TP +Run dirsplit \fB\-h\fR to get the basic usage info. +.TP +Run dirsplit \fB\-H\fR to get the whole option overview and description. +.SH EXAMPLES +Run dirsplit \fB\-H\fR to see the commented examples. +.SH AUTHOR +\fBdirsplit\fR is created by Eduard Bloch (blade@debian.org) and is licensed +under the GPLv2. + diff --git a/3rd-party/geteltorito.1 b/3rd-party/geteltorito.1 new file mode 100644 index 0000000..978da17 --- /dev/null +++ b/3rd-party/geteltorito.1 @@ -0,0 +1,48 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH GETELTORITO 1 "Mai 6, 2007" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +geteltorito \- an El Torito boot image extractor +.SH SYNOPSIS +.B geteltorito +.RI < image | device > +.RB [ \-o +.IR outputfile ] +.br +.SH DESCRIPTION +.B geteltorito +is a Perl script which extracts the initial/default +.B El Torito +boot image from a CD if one exists. It will not extract any of other +boot images that are allowed by the El Torito standard. +.PP +The boot image file is written to +.B stdout +and all other information (e.g., image type and size) is written to +.BR stderr . +To write the image to a file instead of +.BR stdout , +specify the output filename using +.B \-o +.IR filename . + +.SH SEE ALSO +.BR genisoimage (1), +.BR isoinfo (1). +.br +.SH AUTHOR +geteltorito was written by Rainer Krienke <krienke@uni-koblenz.de>. +.PP +This manual page was written by Eduard Bloch <blade@debian.org> based on +README.geteltorito from geteltorito-0.4 package. diff --git a/3rd-party/geteltorito/README.geteltorito b/3rd-party/geteltorito/README.geteltorito new file mode 100644 index 0000000..383712f --- /dev/null +++ b/3rd-party/geteltorito/README.geteltorito @@ -0,0 +1,22 @@ +geteltorito +=========== + +Author: Rainer Krienke +Email: krienke@uni-koblenz.de +License: GPL +Version: 0.4 +Description: A El Torito boot image extractor + +call: geteltorito CD-image > toritoimagefile +example:geteltorito /dev/sr0 > /tmp/bootimage + +The perl-script will extract the initial/default boot image from a CD if +existant. It will not extract any of other possibly existing bootimages +that are allowed by the El Torito standard. +The imagedata are written to STDOUT all other information is written to +STDERR (eg type and size of image). +If you want to write the image to a file instead of STDOUT you can +secify the filename wanted on the commandline using option -o <filename> + +Rainer Krienke +krienke@uni-koblenz.de diff --git a/3rd-party/geteltorito/geteltorito.pl b/3rd-party/geteltorito/geteltorito.pl new file mode 100644 index 0000000..28cdbb3 --- /dev/null +++ b/3rd-party/geteltorito/geteltorito.pl @@ -0,0 +1,214 @@ +#!/usr/bin/perl + +use Getopt::Std; + +# +# geteltorito.pl: a bootimage extractor +# Script that will extract the first El Torito bootimage from a +# bootable CD image +# R. Krienke 08/2001 +# krienke@uni-koblenz.de +# License: GPL +# +# Get latest version from: +# http://www.uni-koblenz.de/~krienke/ftp/noarch/geteltorito +# +$utilVersion="0.4"; +# +# Version 0.4 +# 2007/02/01 +# A patch from Santiago Garcia <manty@debian.org> to use a virtual sector +# size (vSecSize) of 512 bytes, as defined on "El Torito" specs and change +# unpack of the sector count from n to v to get the correct sector count. +# Version 0.3 +# 2006/02/21 +# A patch from Ben Collins <bcollins@ubuntu.com> to make the +# utility work on PPC machines (change from 'L'-encoding in pack to 'V') +# Version 0.2 +# Several patches included from Nathan Stratton Treadway(nathant@ontko.com) +# to adjust the platform output as well as fixes for other minor bugs +# Version 0.1 +# Initial release +# +# For information on El Torito see +# http://wikipedia.org/ +# or try this link directly: +# http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/Platform+System+Software+Documents/default.htm + +$vSecSize=512; +$secSize=2048; +$ret=undef;$version=undef;$opt_h=undef;$loadSegment=undef;$systemType=undef; + +# +# Read a particular sector from a file +# sector counting starts at 0, not 1 +# +sub getSector{ + my ($secNum, $secCount, $file)=@_; + my ($sec, $count); + + open(FILE, $file) || die "Cannot open \"$file\" \n"; + + seek(FILE, $secNum*$secSize, 0); + $count=read(FILE, $sec, $vSecSize*$secCount, 0) ; + if( $count != $vSecSize*$secCount ){ + warn "Error reading from file \"$file\"\n"; + } + close(FILE); + + return($sec); +} + + +# +# Write eltorito data into a file +# +sub writeOutputFile{ + my($name)=shift; + my($value)=shift; + + open(OUT, ">".$name)|| die "$0: Cannot open outputfile \"$name\" for writing. Stop."; + print OUT $value; + close(OUT); +} + + +# +# Usage +# +sub usage{ + warn "\n$0 [-hv] [-o outputfilename] cd-image \n", + "Script will try to extract an El Torito image from a \n", + "bootable CD (or cd-image) given by <cd-image> and write \n", + "the data extracted to STDOUT or to a file.\n", + " -h: This help. \n", + " -v: Print version of script and exit.\n", + " -o <file>: Write extracted data to file <file> instead of STDOUT.\n", + "\n\n"; + exit 0; +} + + +# --------------------------------------------------------------------- +$ret=getopts('hvo:'); + +if( defined($opt_v) ){ + warn "Version: $utilVersion \n"; + exit 0; +} + +if( defined($opt_h) || $#ARGV <0 ){ + usage(0); +} + +if( defined($opt_o) ){ + $outputFilename="$opt_o"; +} + +$imageFile=$ARGV[0]; + +if( ! -r $imageFile ){ + die "Cannot read image/device \"$imageFile\". Aborting\n"; +} + +# +# Read Sector 17 from CD which should contain a Boot Record Volume +# descriptor. This descriptor contains at its start the text ($isoIdent) +# CD001 and ($toritoSpec) +# EL TORITO SPECIFICATION +# see http://www.cdpage.com/Compact_Disc_Variations/eltoritoi.html +# for details +# + +$sector=getSector(17, 1, $imageFile ); +($boot, $isoIdent, $version, $toritoSpec, + $unUsed, $bootP)= unpack( "Ca5CA32A32V", $sector ); + +if( $isoIdent ne "CD001" || $toritoSpec ne "EL TORITO SPECIFICATION" ){ + die "This data image does not seem to be a bootable CD-image\n"; +} + +# +# Now fetch the sector of the booting catalog +# +$sector=getSector($bootP, 1, $imageFile ); + +print STDERR "Booting catalog starts at sector: $bootP \n"; + +# The first 32 bytes of this sector contains the validation entry for a +# boot. The first byte has to be 01, the next byte determines the +# architecture the image is designed for, where 00 is i86, 01 is PowerPC +# and 02 is Mac. More data give info about manufacturer, etc. The +# final two bytes must contain 0x55 and 0xAA respectively (as +# defined by the El Torito standard). + +$validateEntry=substr($sector, 0, 32); + +($header, $platform, $unUsed, $manufact, $unUsed, $five, $aa)= + unpack( "CCvA24vCC", $validateEntry); + +if( $header != 1 || $five != 0x55 || $aa != 0xaa ){ + die "Invalid Validation Entry on image \n"; +} + +print STDERR "Manufacturer of CD: $manufact\n"; +print STDERR "Image architecture: "; +print STDERR "x86" if( $platform == 0 ); +print STDERR "PowerPC" if( $platform == 1 ); +print STDERR "Mac" if( $platform == 2 ); +print STDERR "unknown ($platform)" if( $platform > 2 ); +print STDERR "\n"; + +# +# Now we examine the initial/defaultentry which follows the validate +# entry and has a size of 32 bytes. + +$initialEntry=substr($sector, 32, 32); + +($boot, $media, $loadSegment, $systemType, $unUsed, + $sCount, $imgStart, $unUsed)=unpack( "CCvCCvVC", $initialEntry); + +if( $boot != 0x88 ){ + die "Boot indicator in Initial/Default-Entry is not 0x88. CD is not bootable. \n"; +} + +print STDERR "Boot media type is: "; +if( $media == 0 ){ + print STDERR "no emulation"; + $count=0; +} +if( $media == 1 ){ + print STDERR "1.2meg floppy"; + $count=1200*1024/$vSecSize; +} +if( $media == 2 ){ + print STDERR "1.44meg floppy"; + $count=1440*1024/$vSecSize; +} +if( $media == 3 ){ + print STDERR "2.88meg floppy"; + $count=2880*1024/$vSecSize; +} +if( $media == 4 ){ + print STDERR "harddisk"; + $count=0; +} +print STDERR "\n"; + +# Only use the internal sector counter if the real size is unknown +# ($count==0) +$cnt=$count==0?$sCount:$count; + +print STDERR "El Torito image starts at sector $imgStart and has $cnt sector(s) of $vSecSize Bytes\n"; + +# We are there: +# Now read the bootimage to stdout +$image=getSector($imgStart, $cnt, $imageFile); + +if( length($outputFilename) ){ + writeOutputFile($outputFilename, $image); + print STDERR "\nImage has been written to file \"$outputFilename\".\n"; +}else{ + print "$image"; + print STDERR "Image has been written to stdout ....\n"; +} diff --git a/3rd-party/zisofs_tools/CHANGES b/3rd-party/zisofs_tools/CHANGES new file mode 100644 index 0000000..5a6fee1 --- /dev/null +++ b/3rd-party/zisofs_tools/CHANGES @@ -0,0 +1,57 @@ +Changes in zisofs-tools-1.0.6: + + Further portability fixes; use subsecond resolution if available. + +Changes in zisofs-tools-1.0.5: + + Portability improvements. + +Changes in zisofs-tools-1.0.4: + + Update the documentation. + +Changes in zisofs-tools-1.0.3: + + Update cdrtools patch. + +Changes in zisofs-tools-1.0.2: + + Add "make install" target :) + +Changes in zisofs-tools-1.0.1: + + By default, abort if file modes, times and ownership cannot be + set. Since this isn't always possible, add new option + -s/--sloppy to suppress this error. + + Fix man page typo, and add a BUGS section. + + Remove problems with extremely long symlinks. + + Move all command line options into common "opt" structure. + + Fix bug in command line parsing: -z option not recognized. + + +Changes in zisofs-tools-1.0: + + Restructured code; now split into a number of modules. + + Use autoconf for configuration. + + Add support for long options if the platform has + getopt_long(). + + Support compiling on systems without lchown(). + + Support the following new options: + -x Don't descend into other filesystems + -X Same as -x, but don't create mount point directories + -l Don't descend into any subdirectories + -L Same as -l, but don't create stub directories + -F Allow compression or decompression of single files. + -V Explicitly set the verbosity. + -w Display program version. + + Update the mkisofs patch to warn if -z is specified without + -r/-R. diff --git a/3rd-party/zisofs_tools/CMakeLists.txt b/3rd-party/zisofs_tools/CMakeLists.txt new file mode 100644 index 0000000..75068bf --- /dev/null +++ b/3rd-party/zisofs_tools/CMakeLists.txt @@ -0,0 +1,8 @@ +PROJECT (ZISOFSTOOLS C) +ADD_DEFINITIONS(-Wall -W -Wpointer-arith -Wbad-function-cast -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wshadow -Wcast-align) +AUX_SOURCE_DIRECTORY(. MKZ_SRCS) +ADD_EXECUTABLE (mkzftree ${MKZ_SRCS}) +TARGET_LINK_LIBRARIES(mkzftree z) +SET_TARGET_PROPERTIES(mkzftree PROPERTIES SKIP_BUILD_RPATH TRUE) +INSTALL(TARGETS mkzftree DESTINATION bin) +INSTALL(FILES mkzftree.1 DESTINATION share/man/man1) diff --git a/3rd-party/zisofs_tools/COPYING b/3rd-party/zisofs_tools/COPYING new file mode 100644 index 0000000..d60c31a --- /dev/null +++ b/3rd-party/zisofs_tools/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/3rd-party/zisofs_tools/INSTALL b/3rd-party/zisofs_tools/INSTALL new file mode 100644 index 0000000..b42a17a --- /dev/null +++ b/3rd-party/zisofs_tools/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/3rd-party/zisofs_tools/MCONFIG.in b/3rd-party/zisofs_tools/MCONFIG.in new file mode 100644 index 0000000..1c0ba11 --- /dev/null +++ b/3rd-party/zisofs_tools/MCONFIG.in @@ -0,0 +1,38 @@ +# Prefixes +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +# Directory for user binaries +bindir = @bindir@ + +# Man page tree +mandir = @mandir@ + +# System binaries +sbindir = @sbindir@ + +# Install into chroot area +# Useful when making rpms and similar +INSTALLROOT = + +# Install program +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +# Compiler and compiler flags +CC = @CC@ +CFLAGS = @CFLAGS@ + +# Link flags +LDFLAGS = @LDFLAGS@ + +# Libraries +LIBS = @LIBS@ + +# Additional library we need to build +LIBOBJS = @LIBOBJS@ + +# ar and ranlib (for making libraries) +AR = ar cq +RANLIB = @RANLIB@ diff --git a/3rd-party/zisofs_tools/MRULES b/3rd-party/zisofs_tools/MRULES new file mode 100644 index 0000000..decd202 --- /dev/null +++ b/3rd-party/zisofs_tools/MRULES @@ -0,0 +1,22 @@ +# Standard compilation rules (don't use make builtins) + +.SUFFIXES: .c .cc .o .s .S .i + +.c.o: + $(CC) $(CFLAGS) -c $< + +.c.s: + $(CC) $(CFLAGS) -S -o $@ $< + +.c.i: + $(CC) $(CFLAGS) -E -o $@ $< + +.cc.o: + $(CXX) $(CXXFLAGS) -c $< + +.cc.s: + $(CXX) $(CXXFLAGS) -S -o $@ $< + +.cc.i: + $(CXX) $(CXXFLAGS) -E -o $@ $< + diff --git a/3rd-party/zisofs_tools/Makefile b/3rd-party/zisofs_tools/Makefile new file mode 100644 index 0000000..d70dec6 --- /dev/null +++ b/3rd-party/zisofs_tools/Makefile @@ -0,0 +1,96 @@ +## ----------------------------------------------------------------------- +## +## Copyright 2001 H. Peter Anvin - All Rights Reserved +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, +## USA; either version 2 of the License, or (at your option) any later +## version; incorporated herein by reference. +## +## ----------------------------------------------------------------------- + +## +## Makefile for mkzftree +## +## mkzftree mirrors a tree in a form suitable for "mkisofs -z". +## + +-include MCONFIG +include MRULES + +PROGS = mkzftree +MAN1PAGES = mkzftree.1 + +OBJS = mkzftree.o walk.o workers.o util.o hash.o iso9660.o copytime.o \ + compress.o uncompress.o + +all: $(PROGS) + +spec: zisofs-tools.spec + +clean: + rm -f *.o *.i *.s version.h $(PROGS) + +distclean: clean + rm -f MCONFIG config.status config.log config.h *~ \#* + rm -f core *.orig *.rej + rm -rf *.cache + +release: + $(MAKE) configure + $(MAKE) spec + $(MAKE) distclean + +mkzftree: $(OBJS) + $(CC) $(LDFLAGS) -o mkzftree $(OBJS) $(LIBS) + +spotless: distclean + rm -f configure config.h.in zisofs-tools.spec + +install: all + mkdir -p $(INSTALLROOT)$(bindir) + $(INSTALL_PROGRAM) $(PROGS) $(INSTALLROOT)$(bindir) + mkdir -p $(INSTALLROOT)$(mandir)/man1 + $(INSTALL_DATA) $(MAN1PAGES) $(INSTALLROOT)$(mandir)/man1 + +config: MCONFIG + +MCONFIG: configure MCONFIG.in config.h.in + ./configure + +config.h: MCONFIG + : Generated by side effect + +config.h.in: configure.in + rm -f config.h.in + autoheader + +configure: configure.in aclocal.m4 + autoconf + rm -f MCONFIG config.cache config.log config.status config.h + +# +# Version header +# +VERSION = $(shell cat version) + +version.h: version + echo "#define ZISOFS_TOOLS_VERSION \"$(VERSION)\"" > version.h + +zisofs-tools.spec: zisofs-tools.spec.in version + sed -e 's/@@VERSION@@/$(VERSION)/g' < zisofs-tools.spec.in > $@ + +# +# Dependencies +# +mkzftree.o: mkzftree.c mkzftree.h config.h version.h +workers.o: workers.c mkzftree.h config.h +compress.o: compress.c mkzftree.h config.h iso9660.h +copytime.o: copytime.c mkzftree.h config.h +hash.o: hash.c mkzftree.h config.h +iso9660.o: iso9660.c iso9660.h +uncompress.o: uncompress.c mkzftree.h config.h iso9660.h +util.o: util.c mkzftree.h config.h +walk.o: walk.c mkzftree.h config.h +workers.o: workers.c mkzftree.h config.h diff --git a/3rd-party/zisofs_tools/README b/3rd-party/zisofs_tools/README new file mode 100644 index 0000000..3bf8960 --- /dev/null +++ b/3rd-party/zisofs_tools/README @@ -0,0 +1,44 @@ + H. Peter Anvin <hpa@zytor.com> + June 13, 2004 + + +User tools for zisofs: + +The user tools for zisofs come in two parts: a utility "mkzftree" and +mkisofs, which is part of the cdrtools package. cdrtools 1.11a20 or +later is required. + +First create a directory tree containing compressed files: + + mkzftree input_dir compressed_dir + +mkzftree will not overwrite an existing directory; you may want to "rm +-rf" the directory tree if you are doing this from a script: + +Second, invoke the patched mkisofs with the -z option: + + mkisofs -z -R [other options] -o compressed.iso compressed_dir + +IMPORTANT: you *must* enable RockRidge (-R or -r) since this is an +extensions to the RockRidge specification. Without RockRidge, -z will +have no effect. + +Note that if there are files you do not want compressed (for example, +files involved in booting, or README files you want to be readable +under all circumstances) you can simply put them in a separate tree +and not run mkzftree on that tree. + +mkzftree will not compress files that end up larger when compressed; +if you want it to compress the files anyway, you can give the -f +option to mkzftree. + +mkzftree also accepts a -u option (uncompress), which can be used to +convert a compressed tree back to normal form. This can be used to +read a zisofs CD-ROM on a machine without zisofs kernel support. + +This version of mkzftree supports a -p option (parallelize.) +Specifying -p and a parallelism (e.g. -p4) allows files (up to the +number specified) to compress in parallel. Depending on your setup +and your data set size, this might speed things up if you are not +completely I/O bound. Use -p0 to completely disable parallel +execution; this is the default. diff --git a/3rd-party/zisofs_tools/aclocal.m4 b/3rd-party/zisofs_tools/aclocal.m4 new file mode 100644 index 0000000..a3d8427 --- /dev/null +++ b/3rd-party/zisofs_tools/aclocal.m4 @@ -0,0 +1,35 @@ +dnl -------------------------------------------------------------------------- +dnl PA_ADD_CFLAGS() +dnl +dnl Attempt to add the given option to CFLAGS, if it doesn't break compilation +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_ADD_CFLAGS, +[AC_MSG_CHECKING([if $CC accepts $1]) + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_TRY_LINK([#include <stdio.h>], + [printf("Hello, World!\n");], + AC_MSG_RESULT([yes]), + AC_MSG_RESULT([no]) + CFLAGS="$pa_add_cflags__old_cflags")]) + +dnl ------------------------------------------------------------------------ +dnl PA_WITH_BOOL +dnl +dnl PA_WITH_BOOL(option, default, help, enable, disable) +dnl +dnl Provides a more convenient way to specify --with-option and +dnl --without-option, with a default. default should be either 0 or 1. +dnl ------------------------------------------------------------------------ +AC_DEFUN(PA_WITH_BOOL, +[AC_ARG_WITH([$1], [$3], +if test ["$withval"] != no; then +[$4] +else +[$5] +fi, +if test [$2] -ne 0; then +[$4] +else +[$5] +fi)]) diff --git a/3rd-party/zisofs_tools/compress.c b/3rd-party/zisofs_tools/compress.c new file mode 100644 index 0000000..56f0af0 --- /dev/null +++ b/3rd-party/zisofs_tools/compress.c @@ -0,0 +1,155 @@ +/* + * 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. + * + */ + +/* $Id: compress.c,v 1.4 2006/07/04 04:57:42 hpa Exp $ */ +/* ----------------------------------------------------------------------- * + * + * Copyright 2001-2006 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <stdlib.h> +#include <stdio.h> +#include <utime.h> +#include <unistd.h> +#include <zlib.h> + +#include "iso9660.h" + + +int block_compress_file(FILE *input, FILE *output, off_t size) +{ + struct compressed_file_header hdr; + Bytef inbuf[CBLOCK_SIZE], outbuf[2*CBLOCK_SIZE]; + size_t bytes, pointer_bytes, nblocks, block; + uLong cbytes; /* uLong is a zlib datatype */ + char *pointer_block, *curptr; + off_t position; + int i; + int force_compress = opt.force; + int zerr; + int err = EX_SOFTWARE; + + if ( (sizeof hdr) & 3 ) { + fputs("INTERNAL ERROR: header is not a multiple of 4\n", stderr); + abort(); + } + + memset(&hdr, 0, sizeof hdr); + memcpy(&hdr.magic, zisofs_magic, sizeof zisofs_magic); + hdr.header_size = (sizeof hdr) >> 2; + hdr.block_size = CBLOCK_SIZE_LG2; + set_731(&hdr.uncompressed_len, size); + + if ( fwrite(&hdr, sizeof hdr, 1, output) != 1 ) + return EX_CANTCREAT; + + nblocks = (size+CBLOCK_SIZE-1) >> CBLOCK_SIZE_LG2; + pointer_bytes = 4*(nblocks+1); + pointer_block = xmalloc(pointer_bytes); + memset(pointer_block, 0, pointer_bytes); + + if ( fseek(output, pointer_bytes, SEEK_CUR) == -1 ) { + err = EX_CANTCREAT; + goto free_ptr_bail; + } + + curptr = pointer_block; + position = sizeof hdr + pointer_bytes; + + block = 0; + while ( (bytes = fread(inbuf, 1, CBLOCK_SIZE, input)) > 0 ) { + if ( bytes < CBLOCK_SIZE && block < nblocks-1 ) { + err = EX_IOERR; + goto free_ptr_bail; + } + + /* HACK: If the file has our magic number, always compress */ + if ( block == 0 && bytes >= sizeof zisofs_magic ) { + if ( !memcmp(inbuf, zisofs_magic, sizeof zisofs_magic) ) + force_compress = 1; + } + + set_731(curptr, position); curptr += 4; + + /* We have two special cases: a zero-length block is defined as all zero, + and a block the length of which is equal to the block size is unencoded. */ + + for ( i = 0 ; i < (int)CBLOCK_SIZE ; i++ ) { + if ( inbuf[i] ) break; + } + + if ( i == CBLOCK_SIZE ) { + /* All-zero block. No output */ + } else { + cbytes = 2*CBLOCK_SIZE; + if ( (zerr = compress2(outbuf, &cbytes, inbuf, bytes, opt.level)) + != Z_OK ) { + err = (zerr == Z_MEM_ERROR) ? EX_OSERR : EX_SOFTWARE; + goto free_ptr_bail; /* Compression failure */ + } + if ( fwrite(outbuf, 1, cbytes, output) != cbytes ) { + err = EX_CANTCREAT; + goto free_ptr_bail; + } + position += cbytes; + } + block++; + } + + /* Set pointer to the end of the final block */ + set_731(curptr, position); + + /* Now write the pointer table */ + if ( fseek(output, sizeof hdr, SEEK_SET) == -1 || + fwrite(pointer_block, 1, pointer_bytes, output) != pointer_bytes ) { + err = EX_CANTCREAT; + goto free_ptr_bail; + } + + free(pointer_block); + + /* Now make sure that this was actually the right thing to do */ + if ( !force_compress && position >= size ) { + /* Incompressible file, just copy it */ + rewind(input); + rewind(output); + + position = 0; + while ( (bytes = fread(inbuf, 1, CBLOCK_SIZE, input)) > 0 ) { + if ( fwrite(inbuf, 1, bytes, output) != bytes ) + return EX_CANTCREAT; + position += bytes; + } + + /* Truncate the file to the correct size */ + fflush(output); + ftruncate(fileno(output), position); + } + + /* If we get here, we're done! */ + return 0; + + /* Common bailout code */ + free_ptr_bail: + free(pointer_block); + return err; +} + diff --git a/3rd-party/zisofs_tools/config.h.in b/3rd-party/zisofs_tools/config.h.in new file mode 100644 index 0000000..c2103bb --- /dev/null +++ b/3rd-party/zisofs_tools/config.h.in @@ -0,0 +1,99 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the <endian.h> header file. */ +#undef HAVE_ENDIAN_H + +/* Define to 1 if you have the <getopt.h> header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the `getopt_long' function */ +#undef HAVE_GETOPT_LONG + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `lchown' function. */ +#undef HAVE_LCHOWN + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if `struct stat.st_[mca]tim' are struct timespec */ +#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + +/* Define to 1 if `struct stat.st_[mca]tim' are struct timeval */ +#undef HAVE_STRUCT_STAT_ST_MTIM_TV_USEC + +/* Define to 1 if you have the <sysexits.h> header file. */ +#undef HAVE_SYSEXITS_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `utimes' function. */ +#undef HAVE_UTIMES + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `signed long' if <sys/types.h> does not define. */ +#undef off_t + +/* Define to `unsigned long' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to `signed long' if <sys/types.h> does not define. */ +#undef ssize_t diff --git a/3rd-party/zisofs_tools/configure b/3rd-party/zisofs_tools/configure new file mode 100755 index 0000000..251af8c --- /dev/null +++ b/3rd-party/zisofs_tools/configure @@ -0,0 +1,7907 @@ +#! /bin/sh +# From configure.in Id: configure.in,v 1.7 2004/07/20 04:04:22 hpa Exp . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.60a. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" +else + as_executable_p=: +fi +rm -f conf$$.file + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="MCONFIG.in" +ac_default_prefix=/usr +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CPP +GREP +EGREP +RANLIB +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.60a + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.60a. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +cat >>confdefs.h <<\_ACEOF +#define _GNU_SOURCE 1 +_ACEOF + + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 +echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_largefile_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_largefile_CC=' -n32'; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 +echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_file_offset_bits+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + ac_cv_sys_file_offset_bits=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_file_offset_bits=64; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 +echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } +if test "$ac_cv_sys_file_offset_bits" != no; then + +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF + +fi +rm -f conftest* + { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 +echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_large_files+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + ac_cv_sys_large_files=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_large_files=1; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 +echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } +if test "$ac_cv_sys_large_files" != no; then + +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF + +fi +rm -f conftest* +fi + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + +{ echo "$as_me:$LINENO: checking if $CC accepts -Wall" >&5 +echo $ECHO_N "checking if $CC accepts -Wall... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wall" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -W" >&5 +echo $ECHO_N "checking if $CC accepts -W... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -W" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wpointer-arith" >&5 +echo $ECHO_N "checking if $CC accepts -Wpointer-arith... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wpointer-arith" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wbad-function-cast" >&5 +echo $ECHO_N "checking if $CC accepts -Wbad-function-cast... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wbad-function-cast" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wcast-equal" >&5 +echo $ECHO_N "checking if $CC accepts -Wcast-equal... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wcast-equal" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wstrict-prototypes" >&5 +echo $ECHO_N "checking if $CC accepts -Wstrict-prototypes... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wstrict-prototypes" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wmissing-prototypes" >&5 +echo $ECHO_N "checking if $CC accepts -Wmissing-prototypes... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wmissing-prototypes" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wmissing-declarations" >&5 +echo $ECHO_N "checking if $CC accepts -Wmissing-declarations... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wmissing-declarations" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wnested-externs" >&5 +echo $ECHO_N "checking if $CC accepts -Wnested-externs... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wnested-externs" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Winline" >&5 +echo $ECHO_N "checking if $CC accepts -Winline... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Winline" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wshadow" >&5 +echo $ECHO_N "checking if $CC accepts -Wshadow... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wshadow" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -Wcast-align" >&5 +echo $ECHO_N "checking if $CC accepts -Wcast-align... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wcast-align" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: checking if $CC accepts -pipe" >&5 +echo $ECHO_N "checking if $CC accepts -pipe... $ECHO_C" >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -pipe" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in inttypes.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sysexits.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in getopt.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in endian.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for off_t" >&5 +echo $ECHO_N "checking for off_t... $ECHO_C" >&6; } +if test "${ac_cv_type_off_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef off_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_off_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_off_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 +echo "${ECHO_T}$ac_cv_type_off_t" >&6; } +if test $ac_cv_type_off_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define off_t signed long +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned long +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for ssize_t" >&5 +echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6; } +if test "${ac_cv_type_ssize_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef ssize_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_ssize_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_ssize_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5 +echo "${ECHO_T}$ac_cv_type_ssize_t" >&6; } +if test $ac_cv_type_ssize_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t signed long +_ACEOF + +fi + + + +for ac_func in lchown +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in utimes +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +{ echo "$as_me:$LINENO: checking for struct stat.st_mtim.tv_usec" >&5 +echo $ECHO_N "checking for struct stat.st_mtim.tv_usec... $ECHO_C" >&6; } +if test "${ac_cv_member_struct_stat_st_mtim_tv_usec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/stat.h> + +int +main () +{ +static struct stat ac_aggr; +if (ac_aggr.st_mtim.tv_usec) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_mtim_tv_usec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/stat.h> + +int +main () +{ +static struct stat ac_aggr; +if (sizeof ac_aggr.st_mtim.tv_usec) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_mtim_tv_usec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_member_struct_stat_st_mtim_tv_usec=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_mtim_tv_usec" >&5 +echo "${ECHO_T}$ac_cv_member_struct_stat_st_mtim_tv_usec" >&6; } +if test $ac_cv_member_struct_stat_st_mtim_tv_usec = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIM_TV_USEC 1 +_ACEOF + + +fi + + + +{ echo "$as_me:$LINENO: checking for struct stat.st_mtim.tv_nsec" >&5 +echo $ECHO_N "checking for struct stat.st_mtim.tv_nsec... $ECHO_C" >&6; } +if test "${ac_cv_member_struct_stat_st_mtim_tv_nsec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/stat.h> + +int +main () +{ +static struct stat ac_aggr; +if (ac_aggr.st_mtim.tv_nsec) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_mtim_tv_nsec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/stat.h> + +int +main () +{ +static struct stat ac_aggr; +if (sizeof ac_aggr.st_mtim.tv_nsec) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_mtim_tv_nsec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_member_struct_stat_st_mtim_tv_nsec=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_mtim_tv_nsec" >&5 +echo "${ECHO_T}$ac_cv_member_struct_stat_st_mtim_tv_nsec" >&6; } +if test $ac_cv_member_struct_stat_st_mtim_tv_nsec = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 +_ACEOF + + +fi + + + + +{ echo "$as_me:$LINENO: checking for library containing compress2" >&5 +echo $ECHO_N "checking for library containing compress2... $ECHO_C" >&6; } +if test "${ac_cv_search_compress2+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char compress2 (); +int +main () +{ +return compress2 (); + ; + return 0; +} +_ACEOF +for ac_lib in '' z; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_compress2=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_compress2+set}" = set; then + break +fi +done +if test "${ac_cv_search_compress2+set}" = set; then + : +else + ac_cv_search_compress2=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_compress2" >&5 +echo "${ECHO_T}$ac_cv_search_compress2" >&6; } +ac_res=$ac_cv_search_compress2 +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + { { echo "$as_me:$LINENO: error: zlib not found" >&5 +echo "$as_me: error: zlib not found" >&2;} + { (exit cannot continue); exit cannot continue; }; } +fi + +{ echo "$as_me:$LINENO: checking for library containing getopt_long" >&5 +echo $ECHO_N "checking for library containing getopt_long... $ECHO_C" >&6; } +if test "${ac_cv_search_getopt_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getopt_long (); +int +main () +{ +return getopt_long (); + ; + return 0; +} +_ACEOF +for ac_lib in '' getopt getopt_long; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_getopt_long=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_getopt_long+set}" = set; then + break +fi +done +if test "${ac_cv_search_getopt_long+set}" = set; then + : +else + ac_cv_search_getopt_long=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_getopt_long" >&5 +echo "${ECHO_T}$ac_cv_search_getopt_long" >&6; } +ac_res=$ac_cv_search_getopt_long +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +for ac_func in getopt_long +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +ac_config_headers="$ac_config_headers config.h" + +ac_config_files="$ac_config_files MCONFIG" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" +else + as_executable_p=: +fi +rm -f conf$$.file + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.60a. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to <bug-autoconf@gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.60a, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "MCONFIG") CONFIG_FILES="$CONFIG_FILES MCONFIG" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +RANLIB!$RANLIB$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 53; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/3rd-party/zisofs_tools/configure.in b/3rd-party/zisofs_tools/configure.in new file mode 100644 index 0000000..4143ec5 --- /dev/null +++ b/3rd-party/zisofs_tools/configure.in @@ -0,0 +1,58 @@ +dnl +dnl autoconf input file to generate MCONFIG +dnl + +AC_PREREQ(2.57) +AC_REVISION([$Id: configure.in,v 1.7 2004/07/20 04:04:22 hpa Exp $]) +AC_INIT(MCONFIG.in) +AC_PREFIX_DEFAULT(/usr) + +AC_PROG_CC +AC_GNU_SOURCE +AC_SYS_LARGEFILE +AC_C_CONST +AC_C_INLINE + +PA_ADD_CFLAGS(-Wall) +PA_ADD_CFLAGS(-W) +PA_ADD_CFLAGS(-Wpointer-arith) +PA_ADD_CFLAGS(-Wbad-function-cast) +PA_ADD_CFLAGS(-Wcast-equal) +PA_ADD_CFLAGS(-Wstrict-prototypes) +PA_ADD_CFLAGS(-Wmissing-prototypes) +PA_ADD_CFLAGS(-Wmissing-declarations) +PA_ADD_CFLAGS(-Wnested-externs) +PA_ADD_CFLAGS(-Winline) +PA_ADD_CFLAGS(-Wshadow) +PA_ADD_CFLAGS(-Wcast-align) +PA_ADD_CFLAGS(-pipe) + +AC_CHECK_HEADERS(inttypes.h) +AC_CHECK_HEADERS(sysexits.h) +AC_CHECK_HEADERS(getopt.h) +AC_CHECK_HEADERS(endian.h) + +AC_CHECK_TYPE(off_t, signed long) +AC_CHECK_TYPE(size_t, unsigned long) +AC_CHECK_TYPE(ssize_t, signed long) + +AC_CHECK_FUNCS(lchown) +AC_CHECK_FUNCS(utimes) + +AC_CHECK_MEMBERS(struct stat.st_mtim.tv_usec, , , [#include <sys/stat.h>]) +AH_TEMPLATE([HAVE_STRUCT_STAT_ST_MTIM_TV_USEC], + [Define to 1 if `struct stat.st_[mca]tim' are struct timeval]) +AC_CHECK_MEMBERS(struct stat.st_mtim.tv_nsec, , , [#include <sys/stat.h>]) +AH_TEMPLATE([HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC], + [Define to 1 if `struct stat.st_[mca]tim' are struct timespec]) + +AC_SEARCH_LIBS(compress2, z, , [AC_MSG_ERROR(zlib not found, cannot continue)]) +AC_SEARCH_LIBS(getopt_long, [getopt getopt_long]) +AC_CHECK_FUNCS(getopt_long) +AH_TEMPLATE([HAVE_GETOPT_LONG], [Define to 1 if you have the `getopt_long' function]) + +AC_PROG_RANLIB +AC_PROG_INSTALL + +AC_CONFIG_HEADER(config.h) +AC_OUTPUT(MCONFIG) diff --git a/3rd-party/zisofs_tools/copytime.c b/3rd-party/zisofs_tools/copytime.c new file mode 100644 index 0000000..82cff7d --- /dev/null +++ b/3rd-party/zisofs_tools/copytime.c @@ -0,0 +1,66 @@ +/* + * 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. + * + */ + +/* $Id: copytime.c,v 1.2 2006/07/04 04:57:42 hpa Exp $ */ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Bostom MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * copytime.c + * + * Copy time(s) from a struct stat + */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <utime.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> + +int copytime(const char *filename, const struct stat *st) +{ +#if defined(HAVE_UTIMES) && (defined(HAVE_STRUCT_STAT_ST_MTIM_TV_USEC) || \ + defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)) + + struct timeval tv[2]; + +# ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_USEC + tv[0] = st->st_atim; + tv[1] = st->st_mtim; +# else + tv[0].tv_sec = st->st_atim.tv_sec; + tv[0].tv_usec = st->st_atim.tv_nsec / 1000; + tv[1].tv_sec = st->st_mtim.tv_sec; + tv[1].tv_usec = st->st_mtim.tv_nsec / 1000; +# endif + return utimes(filename, tv); + +#else + + struct utimbuf ut; + + ut.actime = st->st_atime; + ut.modtime = st->st_mtime; + return utime(filename, &ut); + +#endif +} diff --git a/3rd-party/zisofs_tools/hash.c b/3rd-party/zisofs_tools/hash.c new file mode 100644 index 0000000..6c906ea --- /dev/null +++ b/3rd-party/zisofs_tools/hash.c @@ -0,0 +1,79 @@ +/* + * 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. + * + */ + +#ident "$Id: hash.c,v 1.3 2006/07/04 04:57:42 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2001 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * hash.c + * + * Hash table used to find hard-linked files + */ + +#include "mkzftree.h" /* Must be included first! */ + +#define HASH_BUCKETS 2683 + +struct file_hash { + struct file_hash *next; + struct stat st; + const char *outfile_name; +}; + +static struct file_hash *hashp[HASH_BUCKETS]; + +const char *hash_find_file(struct stat *st) +{ + int bucket = (st->st_ino + st->st_dev) % HASH_BUCKETS; + struct file_hash *hp; + + for ( hp = hashp[bucket] ; hp ; hp = hp->next ) { + if ( hp->st.st_ino == st->st_ino && + hp->st.st_dev == st->st_dev && + hp->st.st_mode == st->st_mode && + hp->st.st_nlink == st->st_nlink && + hp->st.st_uid == st->st_uid && + hp->st.st_gid == st->st_gid && + hp->st.st_size == st->st_size && + hp->st.st_mtime == st->st_mtime ) { + /* Good enough, it's the same file */ + return hp->outfile_name; + } + } + return NULL; /* No match */ +} + +/* Note: the stat structure is the input file; the name + is the output file to link to */ +void hash_insert_file(struct stat *st, const char *outfile) +{ + int bucket = (st->st_ino + st->st_dev) % HASH_BUCKETS; + struct file_hash *hp = xmalloc(sizeof(struct file_hash)); + + hp->next = hashp[bucket]; + memcpy(&hp->st, st, sizeof(struct stat)); + hp->outfile_name = xstrdup(outfile); + + hashp[bucket] = hp; +} + + diff --git a/3rd-party/zisofs_tools/install-sh b/3rd-party/zisofs_tools/install-sh new file mode 100644 index 0000000..89fc9b0 --- /dev/null +++ b/3rd-party/zisofs_tools/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/3rd-party/zisofs_tools/iso9660.c b/3rd-party/zisofs_tools/iso9660.c new file mode 100644 index 0000000..c5b0abd --- /dev/null +++ b/3rd-party/zisofs_tools/iso9660.c @@ -0,0 +1,123 @@ +/* + * 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. + * + */ + +/* $Id: iso9660.c,v 1.1 2001/07/27 14:37:08 hpa Exp $ */ +/* ----------------------------------------------------------------------- * + * + * Copyright 2001 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include "iso9660.h" + +/* zisofs magic */ + +const unsigned char zisofs_magic[8] = { + 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 +}; + +/* iso9660 integer formats */ + +void +set_721(void *pnt, unsigned int i) +{ + unsigned char *p = (unsigned char *)pnt; + p[0] = i & 0xff; + p[1] = (i >> 8) & 0xff; +} + +unsigned int +get_721(void *pnt) +{ + unsigned char *p = (unsigned char *)pnt; + return ((unsigned int)p[0]) + ((unsigned int)p[1] << 8); +} + +void +set_722(void *pnt, unsigned int i) +{ + unsigned char *p = (unsigned char *)pnt; + p[0] = (i >> 8) & 0xff; + p[1] = i & 0xff; +} + +unsigned int +get_722(void *pnt) +{ + unsigned char *p = (unsigned char *)pnt; + return ((unsigned int)p[0] << 8) + ((unsigned int)p[1]); +} + +void +set_723(void *pnt, unsigned int i) +{ + unsigned char *p = (unsigned char *)pnt; + p[3] = p[0] = i & 0xff; + p[2] = p[1] = (i >> 8) & 0xff; +} + +#define get_723(x) get_721(x) + +void +set_731(void *pnt, unsigned int i) +{ + unsigned char *p = (unsigned char *)pnt; + p[0] = i & 0xff; + p[1] = (i >> 8) & 0xff; + p[2] = (i >> 16) & 0xff; + p[3] = (i >> 24) & 0xff; +} + +unsigned int +get_731(void *pnt) +{ + unsigned char *p = (unsigned char *)pnt; + return ((unsigned int)p[0]) + ((unsigned int)p[1] << 8) + + ((unsigned int)p[2] << 16) + ((unsigned int)p[3] << 24); +} + +void +set_732(void *pnt, unsigned int i) +{ + unsigned char *p = (unsigned char *)pnt; + p[3] = i & 0xff; + p[2] = (i >> 8) & 0xff; + p[1] = (i >> 16) & 0xff; + p[0] = (i >> 24) & 0xff; +} + +unsigned int +get_732(void *pnt) +{ + unsigned char *p = (unsigned char *)pnt; + return ((unsigned int)p[0] << 24) + ((unsigned int)p[1] << 16) + + ((unsigned int)p[2] << 8) + ((unsigned int)p[3]); +} + +void +set_733(void *pnt, unsigned int i) +{ + unsigned char *p = (unsigned char *)pnt; + p[7] = p[0] = i & 0xff; + p[6] = p[1] = (i >> 8) & 0xff; + p[5] = p[2] = (i >> 16) & 0xff; + p[4] = p[3] = (i >> 24) & 0xff; +} + +#define get_733(x) get_731(x) + diff --git a/3rd-party/zisofs_tools/iso9660.h b/3rd-party/zisofs_tools/iso9660.h new file mode 100644 index 0000000..20249b8 --- /dev/null +++ b/3rd-party/zisofs_tools/iso9660.h @@ -0,0 +1,62 @@ +/* + * 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. + * + */ + +#ident "$Id: iso9660.h,v 1.4 2006/07/04 04:57:42 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2001 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* zisofs definitions */ + +#ifndef ISO9660_H +#define ISO9660_H + +#ifndef CBLOCK_SIZE_LG2 +#define CBLOCK_SIZE_LG2 15 /* Compressed block size */ +#endif +#define CBLOCK_SIZE (1 << CBLOCK_SIZE_LG2) + +/* Compressed file magic */ +extern const unsigned char zisofs_magic[8]; + +/* VERY VERY VERY IMPORTANT: Must be a multiple of 4 bytes */ +struct compressed_file_header { + char magic[8]; + char uncompressed_len[4]; + unsigned char header_size; + unsigned char block_size; + char reserved[2]; /* Reserved for future use, MBZ */ +}; + +/* iso9660 integer formats */ +void set_721(void *, unsigned int); +unsigned int get_721(void *); +void set_722(void *, unsigned int); +unsigned int get_722(void *); +void set_723(void *, unsigned int); +void set_731(void *, unsigned int); +unsigned int get_731(void *); +void set_732(void *, unsigned int); +unsigned int get_732(void *); +void set_733(void *, unsigned int); +#define get_723(x) get_721(x) +#define get_733(x) get_731(x) + +#endif /* ISO9660_H */ diff --git a/3rd-party/zisofs_tools/mkzftree.1 b/3rd-party/zisofs_tools/mkzftree.1 new file mode 100644 index 0000000..fcd3d15 --- /dev/null +++ b/3rd-party/zisofs_tools/mkzftree.1 @@ -0,0 +1,120 @@ +.\" $Id: mkzftree.1,v 1.13 2004/07/20 04:03:53 hpa Exp $ +.\" ----------------------------------------------------------------------- +.\" +.\" Copyright 2001 H. Peter Anvin - All Rights Reserved +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, +.\" USA; either version 2 of the License, or (at your option) any later +.\" version; incorporated herein by reference. +.\" +.\" ----------------------------------------------------------------------- +.TH MKZFTREE "1" "30 July 2001" "zisofs-tools" "H. Peter Anvin" +.SH NAME +mkzftree \- Create a zisofs/RockRidge compressed file tree +.SH SYNOPSIS +.B mkzftree +[\fIOPTIONS\fR]... \fIINPUT\fR \fIOUTPUT\fR +.SH DESCRIPTION +.PP +Takes an input file tree (\fIINPUT\fR) and create a corresponding +compressed file tree (\fIOUTPUT\fR) that can be used with an +appropriately patched +.BR mkisofs (8) +to create a transparent-compression ISO 9660/Rock Ridge filesystem using +the "ZF" compression records. +.SH OPTIONS +.TP +\fB\-f\fP, \fB\-\-force\fP +Always compress all files, even if they get larger when compressed. +.TP +\fB\-z\fP \fIlevel\fP, \fB\-\-level\fP \fIlevel\fP +Select compression level (1-9, default is 9). Lower compression +levels are faster, but typically result in larger output. +.TP +\fB\-u\fP, \fB\-\-uncompress\fP +Uncompress an already compressed tree. This can be used to read a +compressed filesystem on a system which cannot read them natively. +.TP +\fB\-p\fP \fIparallelism\fP, \fB\-\-parallelism\fP \fIparallelism\fP +Compress in parallel. The +.I parallelism +value indicates how many compression threads are allowed to run. +.TP +\fB\-x\fP, \fB\-\-one-filesystem\fP +Do not cross filesystem boundaries, but create directory stubs at +mount points. +.TP +\fB\-X\fP, \fB\-\-strict-one-filesystem\fP +Do not cross filesystem boundaries, and do not create directory stubs +at mount points. +.TP +\fB\-C\fP \fIpath\fP, \fB\-\-crib-path\fP \fIpath\fP +Steal ("crib") files from another directory if it looks (based on +name, size, type and modification time) like they match entries in the +new filesystem. The "crib tree" is usually the compressed version of +an older version of the same workload; this thus allows for +"incremental rebuilds" of a compressed filesystem tree. The files are +hardlinked from the crib tree to the output tree, so if it is +desirable to keep the link count correct the crib path should be +deleted before running \fBmkisofs\fP. The crib tree must be on the +same filesystem as the output tree. +.TP +\fB\-l\fP, \fB\-\-local\fP +Do not recurse into subdirectories, but create the directories +themselves. +.TP +\fB\-L\fP, \fB\-\-strict-local\fP +Do not recurse into subdirectories, and do not create directories. +.TP +\fB\-F\fP, \fB\-\-file\fP +Indicates that \fIINPUT\fP may not necessarily be a directory; this +allows operation on a single file. Note especially that if \fI\-F\fP +is specified, and \fIINPUT\fP is a symlink, the symlink itself will be +copied rather than whatever it happens to point to. +.TP +\fB\-s\fP, \fB\-\-sloppy\fP +Treat file modes, times and ownership data as less than precious +information and don't abort if they cannot be set. This may be useful +if running +.B mkisofs +on an input tree you do not own. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Increase the program verbosity. +.TP +\fB\-V\fP \fIvalue\fP, \fB\-\-verbosity\fP \fIvalue\fP +Set the program verbosity to +.IR value . +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Issue no messages whatsoever, including error messages. This is the same +as specifying +.IR "\-V\ 0" . +.TP +\fB\-h\fP, \fB\-\-help\fP +Display a brief help message. +.TP +\fB\-w\fP, \fB\-\-version\fP +Display the release version. +.SH BUGS +Long options (beginning with \fI\-\-\fP) may not work on all systems. +See the message printed out by \fImkzftree\ \-h\fP to see if this +applies to your system. +.PP +Inode change times (ctimes) are not copied. This is a system +limitation and applies to all file copy programs. +.PP +If using the parallel option (\fI\-z\fP) the access times (atimes) on +directories may or may not be copied. If it is important that the +atimes on directories are copied exactly, avoid using \fI\-z\fP. +.SH AUTHOR +Written by H. Peter Anvin <hpa@zytor.com>. +.SH COPYRIGHT +Copyright \(co 2001-2002 H. Peter Anvin. +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +.BR mkisofs (8) diff --git a/3rd-party/zisofs_tools/mkzftree.c b/3rd-party/zisofs_tools/mkzftree.c new file mode 100644 index 0000000..3551180 --- /dev/null +++ b/3rd-party/zisofs_tools/mkzftree.c @@ -0,0 +1,294 @@ +/* + * 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. + * + */ + +/* $Id: mkzftree.c,v 1.18 2006/07/04 04:57:42 hpa Exp $ */ +/* ----------------------------------------------------------------------- * + * + * Copyright 2001 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * mkzffile.c + * + * - Generate block-compression of files for use with + * the "ZF" extension to the iso9660/RockRidge filesystem. + * + * The file compression technique used is the "deflate" + * algorithm used by the zlib library; each block must have a + * valid (12-byte) zlib header. In addition, the file itself + * has the following structure: + * + * Byte offset iso9660 type Contents + * 0 (8 bytes) Magic number (37 E4 53 96 C9 DB D6 07) + * 8 7.3.1 Uncompressed file size + * 12 7.1.1 header_size >> 2 (currently 4) + * 13 7.1.1 log2(block_size) + * 14 (2 bytes) Reserved, must be zero + * + * The header may get expanded in the future, at which point the + * header size field will be used to increase the space for the + * header. + * + * All implementations are required to support a block_size of 32K + * (byte 13 == 15). + * + * Note that bytes 12 and 13 and the uncompressed length are also + * present in the ZF record; THE TWO MUST BOTH BE CONSISTENT AND + * CORRECT. + * + * Given the uncompressed size, block_size, and header_size: + * + * Nblocks := ceil(size/block_size) + * + * After the header follow (nblock+1) 32-bit pointers, recorded as + * iso9660 7.3.1 (littleendian); each indicate the byte offset (from + * the start of the file) to one block and the first byte beyond the + * end of the previous block; the first pointer thus point to the + * start of the data area and the last pointer to the first byte + * beyond it: + * + * block_no := floor(byte_offset/block_size) + * + * block_start := read_pointer_731( (header_size+block_no)*4 ) + * block_end := read_pointer_731( (header_size+block_no+1)*4 ) + * + * The block data is compressed according to "zlib". + */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <limits.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> + +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#endif + +#include "version.h" + +/* Command line options */ +struct cmdline_options opt = { + 0, /* Force compression */ + 9, /* Compression level */ + 0, /* Parallelism (0 = strictly serial) */ + 0, /* One filesystem only */ + 0, /* One directory only */ + 1, /* Create stub directories */ + 0, /* Root may be a file */ + 0, /* Be paranoid about metadata */ + default_verbosity, /* Default verbosity */ + block_compress_file /* Default transformation function */ +}; + +/* Program name */ +const char *program; + +/* Long options */ +#define OPTSTRING "fz:up:xXC:lLFvqV:hw" +#ifdef HAVE_GETOPT_LONG +const struct option long_options[] = { + { "force", 0, 0, 'f' }, + { "level", 1, 0, 'z' }, + { "uncompress", 0, 0, 'u' }, + { "parallelism", 1, 0, 'p' }, + { "one-filesystem", 0, 0, 'x' }, + { "strict-one-filesystem", 0, 0, 'X' }, + { "crib-tree", 1, 0, 'C' }, + { "local", 0, 0, 'l' }, + { "strict-local", 0, 0, 'L' }, + { "file", 0, 0, 'F' }, + { "verbose", 0, 0, 'v' }, + { "quiet", 0, 0, 'q' }, + { "verbosity", 1, 0, 'V' }, + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'w' }, + { 0, 0, 0, 0 } +}; +#define LO(X) X +#else +#define getopt_long(C,V,O,L,I) getopt(C,V,O) +#define LO(X) +#endif + +static void usage(enum verbosity level, int err) +{ + message(level, + "zisofs-tools " ZISOFS_TOOLS_VERSION "\n" + "Usage: %s [options] intree outtree\n" + LO(" --force ")" -f Always compress, even if result is larger\n" + LO(" --level # ")" -z # Set compression level (1-9)\n" + LO(" --uncompress ")" -u Uncompress an already compressed tree\n" + LO(" --parallelism # ")" -p # Process up to # files in parallel\n" + LO(" --one-filesystem ")" -x Do not cross filesystem boundaries\n" + LO(" --strict-one-filesystem")" -X Same as -x, but don't create stubs dirs\n" + LO(" --crib-tree ")" -C Steal \"crib\" files from an old tree\n" + LO(" --local ")" -l Do not recurse into subdirectoires\n" + LO(" --strict-local ")" -L Same as -l, but don't create stubs dirs\n" + LO(" --file ")" -F Operate possibly on a single file\n" + LO(" --sloppy ")" -s Don't abort if metadata cannot be set\n" + LO(" --verbose ")" -v Increase message verbosity\n" + LO(" --verbosity # ")" -V # Set message verbosity to # (default = %d)\n" + LO(" --quiet ")" -q No messages, not even errors (-V 0)\n" + LO(" --help ")" -h Display this message\n" + LO(" --version ")" -w Display the program version\n" + ,program, (int)default_verbosity); + exit(err); +} + +static int opt_atoi(const char *str) +{ + char *endptr; + long out; + + out = strtol(str, &endptr, 10); + if ( *endptr ) + usage(vl_error, EX_USAGE); + + return (int)out; +} + + +int main(int argc, char *argv[]) +{ + const char *in, *out, *crib = NULL; + struct stat st; + int optch, err; + + program = argv[0]; + + while ( (optch = getopt_long(argc, argv, OPTSTRING, long_options, NULL)) + != EOF ) { + switch(optch) { + case 'f': + opt.force = 1; /* Always compress */ + break; + case 'z': + opt.level = opt_atoi(optarg); + if ( opt.level < 1 || opt.level > 9 ) { + message(vl_error, "%s: invalid compression level: %d\n", + program, optarg); + exit(EX_USAGE); + } + break; + case 'v': + opt.verbosity++; + break; + case 'V': + opt.verbosity = opt_atoi(optarg); + break; + case 'q': + opt.verbosity = vl_quiet; + break; + case 'u': + opt.munger = block_uncompress_file; + break; + case 'C': + crib = optarg; + break; + case 'p': + opt.parallel = opt_atoi(optarg); + break; + case 'x': + opt.onefs = 1; opt.do_mkdir = 1; + break; + case 'l': + opt.onedir = 1; opt.do_mkdir = 1; + break; + case 'X': + opt.onefs = 1; opt.do_mkdir = 0; + break; + case 'L': + opt.onedir = 1; opt.do_mkdir = 0; + break; + case 'F': + opt.file_root = 1; + break; + case 's': + opt.sloppy = 1; + break; + case 'h': + usage(vl_quiet, 0); + break; + case 'w': + message(vl_quiet, "zisofs-tools " ZISOFS_TOOLS_VERSION "\n"); + exit(0); + default: + usage(vl_error, EX_USAGE); + break; + } + } + + if ( (argc-optind) != 2 ) + usage(vl_error, EX_USAGE); + + in = argv[optind]; /* Input tree */ + out = argv[optind+1]; /* Output tree */ + + umask(077); + + if ( opt.file_root ) { + if ( lstat(in, &st) ) { + message(vl_error, "%s: %s: %s\n", program, in, strerror(errno)); + exit(EX_NOINPUT); + } + + err = munge_entry(in, out, crib, NULL); + } else { + /* Special case: we use stat() for the root, not lstat() */ + if ( stat(in, &st) ) { + message(vl_error, "%s: %s: %s\n", program, in, strerror(errno)); + exit(EX_NOINPUT); + } + if ( !S_ISDIR(st.st_mode) ) { + message(vl_error, "%s: %s: Not a directory\n", program, in); + exit(EX_DATAERR); + } + + err = munge_tree(in, out, crib); + } + + wait_for_all_workers(); + + if ( err ) + exit(err); + + if ( !opt.file_root ) { + if ( chown(out, st.st_uid, st.st_gid) && !opt.sloppy ) { + message(vl_error, "%s: %s: %s", program, out, strerror(errno)); + err = EX_CANTCREAT; + } + if ( chmod(out, st.st_mode) && !opt.sloppy && !err ) { + message(vl_error, "%s: %s: %s", program, out, strerror(errno)); + err = EX_CANTCREAT; + } + if ( copytime(out, &st) && !opt.sloppy && !err ) { + message(vl_error, "%s: %s: %s", program, out, strerror(errno)); + err = EX_CANTCREAT; + } + } + + return err; +} diff --git a/3rd-party/zisofs_tools/mkzftree.h b/3rd-party/zisofs_tools/mkzftree.h new file mode 100644 index 0000000..36e9358 --- /dev/null +++ b/3rd-party/zisofs_tools/mkzftree.h @@ -0,0 +1,115 @@ +/* + * 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. + * + */ + +#ident "$Id: mkzftree.h,v 1.7 2006/07/04 04:57:42 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2001-2006 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#ifndef MKZFTREE_H +#define MKZFTREE_H + +/* config.h should be included before any system headers!!!! */ +#include "config.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#endif + +#ifdef HAVE_SYSEXITS_H +#include <sysexits.h> +#else +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ +#endif + +/* File transformation functions */ +typedef int (*munger_func)(FILE *, FILE *, off_t); +int block_compress_file(FILE *, FILE *, off_t); +int block_uncompress_file(FILE *, FILE *, off_t); + +/* mkzftree.c */ +extern const char *program; /* Program name */ +enum verbosity { /* Message verbosity */ + vl_quiet, /* No messages */ + vl_error, /* Error messages only */ + vl_filename, /* Display filenames */ + vl_crib, /* Cribbing files */ +}; +#define default_verbosity vl_error +struct cmdline_options { + int force; /* Always compress */ + int level; /* Compression level */ + int parallel; /* Parallelism (0 = strictly serial) */ + int onefs; /* One filesystem only */ + int onedir; /* One directory only */ + int do_mkdir; /* Create stub directories */ + int file_root; /* The root may be a file */ + int sloppy; /* Don't make sure metadata is set correctly */ + enum verbosity verbosity; /* Message verbosity */ + munger_func munger; /* Default action */ +}; +extern struct cmdline_options opt; + +/* walk.c */ +int munge_tree(const char *, const char *, const char *); +int munge_entry(const char *, const char *, const char *, const struct stat *); + +/* workers.c */ +void wait_for_all_workers(void); +int spawn_worker(void); +void end_worker(int); + +/* util.c */ +void *xmalloc(size_t); +void *xrealloc(void *, size_t); +char *xstrdup(const char *); +void message(enum verbosity, const char *, ...); + +/* hash.c */ +const char *hash_find_file(struct stat *); +void hash_insert_file(struct stat *, const char *); + +/* copytime.h */ +int copytime(const char *, const struct stat *); + +#endif /* MKZFTREE_H */ diff --git a/3rd-party/zisofs_tools/uncompress.c b/3rd-party/zisofs_tools/uncompress.c new file mode 100644 index 0000000..c9ba6e4 --- /dev/null +++ b/3rd-party/zisofs_tools/uncompress.c @@ -0,0 +1,147 @@ +/* + * 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. + * + */ + +/* $Id: uncompress.c,v 1.3 2006/07/04 04:57:42 hpa Exp $ */ +/* ----------------------------------------------------------------------- * + * + * Copyright 2001-2006 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +#include "iso9660.h" + +int block_uncompress_file(FILE *input, FILE *output, off_t size) +{ + struct compressed_file_header hdr; + Bytef *inbuf, *outbuf; + int block_shift; + char *pointer_block, *pptr; + unsigned long nblocks; + unsigned long fullsize, block_size, block_size2; + size_t ptrblock_bytes; + unsigned long cstart, cend, csize; + uLong bytes; + int zerr; + int err = EX_SOFTWARE; + + if ( (bytes = fread(&hdr, 1, sizeof hdr, input)) != sizeof hdr ) { + if ( bytes == (size_t)size ) { + /* Very short file; not compressed */ + return ( fwrite(&hdr, 1, bytes, output) != bytes ) ? EX_CANTCREAT : 0; + } else { + return EX_IOERR; /* Read error */ + } + } + + if ( memcmp(&hdr.magic, zisofs_magic, sizeof zisofs_magic) ) { + inbuf = xmalloc(CBLOCK_SIZE); + /* Not compressed */ + memcpy(inbuf, &hdr, sizeof hdr); + bytes = sizeof hdr; + do { + if ( fwrite(inbuf, 1, bytes, output) != bytes ) + return EX_CANTCREAT; + } while ( (bytes = fread(inbuf, 1, CBLOCK_SIZE, input)) > 0 ); + free(inbuf); + return ferror(input) ? EX_IOERR : 0; + } + + /* Now we know the file must be compressed. Get the pointer table. */ + if ( fseek(input, hdr.header_size << 2, SEEK_SET) == -1 ) + return EX_IOERR; + + fullsize = get_731(hdr.uncompressed_len); + block_shift = hdr.block_size; + block_size = 1UL << block_shift; + block_size2 = block_size << 1; + inbuf = xmalloc(block_size2); + outbuf = xmalloc(block_size); + + nblocks = (fullsize + block_size - 1) >> block_shift; + + ptrblock_bytes = (nblocks+1) * 4; + pointer_block = xmalloc(ptrblock_bytes); + + if ( (bytes = fread(pointer_block, 1, ptrblock_bytes, input)) != ptrblock_bytes ) { + err = EX_IOERR; + goto free_ptr_bail; + } + + pptr = pointer_block; + while ( fullsize ) { + cstart = get_731(pptr); + pptr += 4; + cend = get_731(pptr); + + csize = cend-cstart; + + if ( csize == 0 ) { + memset(outbuf, 0, block_size); + bytes = block_size; + } else { + if ( csize > block_size2 ) { + err = EX_DATAERR; + goto free_ptr_bail; + } + + if ( fseek(input, cstart, SEEK_SET) == -1 || + (bytes = fread(inbuf, 1, csize, input)) != csize ) { + err = EX_IOERR; + goto free_ptr_bail; + } + + bytes = block_size; /* Max output buffer size */ + if ( (zerr = uncompress(outbuf, &bytes, inbuf, csize)) != Z_OK ) { + err = (zerr = Z_MEM_ERROR) ? EX_OSERR : EX_DATAERR; + goto free_ptr_bail; + } + } + + if ( ((fullsize > block_size) && (bytes != block_size)) + || ((fullsize <= block_size) && (bytes < fullsize)) ) { + err = EX_DATAERR; + goto free_ptr_bail; + } + + if ( bytes > fullsize ) + bytes = fullsize; + + if ( fwrite(outbuf, 1, bytes, output) != bytes ) { + err = EX_CANTCREAT; + goto free_ptr_bail; + } + + fullsize -= bytes; + } + + err = 0; + + free_ptr_bail: + free(pointer_block); + free(inbuf); + free(outbuf); + return err; +} + + diff --git a/3rd-party/zisofs_tools/util.c b/3rd-party/zisofs_tools/util.c new file mode 100644 index 0000000..1b45cdf --- /dev/null +++ b/3rd-party/zisofs_tools/util.c @@ -0,0 +1,68 @@ +/* + * 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. + * + */ + +/* $Id: util.c,v 1.3 2006/07/04 04:57:42 hpa Exp $ */ +/* ----------------------------------------------------------------------- * + * + * Copyright 2001-2006 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +/* Convenience functions */ +void *xmalloc(size_t size) +{ + void *p = malloc(size); + + if ( !p ) { + perror(program); + exit(EX_OSERR); + } + + return p; +} + +char *xstrdup(const char *str) +{ + char *s = strdup(str); + + if ( !s ) { + perror(program); + exit(EX_OSERR); + } + + return s; +} + +void message(enum verbosity level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + if ( opt.verbosity >= level ) + vfprintf(stderr, format, ap); + va_end(ap); +} + diff --git a/3rd-party/zisofs_tools/version b/3rd-party/zisofs_tools/version new file mode 100644 index 0000000..238d6e8 --- /dev/null +++ b/3rd-party/zisofs_tools/version @@ -0,0 +1 @@ +1.0.7 diff --git a/3rd-party/zisofs_tools/walk.c b/3rd-party/zisofs_tools/walk.c new file mode 100644 index 0000000..3b62f73 --- /dev/null +++ b/3rd-party/zisofs_tools/walk.c @@ -0,0 +1,323 @@ +/* + * 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. + * + */ + +#ident "$Id: walk.c,v 1.7 2006/07/04 04:57:42 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2001-2006 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * walk.c + * + * Functions to walk the file tree + */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <string.h> +#include <errno.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "iso9660.h" + +static int munge_file(const char *inpath, const char *outpath, + const char *cribpath, struct stat *st) +{ + FILE *in, *out; + int err = 0; + + if ( cribpath ) { + struct stat cst; + struct compressed_file_header cfh; + + /* Compare as much as we realistically can */ + if ( !stat(cribpath, &cst) && + st->st_mode == cst.st_mode && + st->st_uid == cst.st_uid && + st->st_gid == cst.st_gid && + st->st_mtime == cst.st_mtime ) { + if ( (in = fopen(cribpath, "rb")) ) { + int e = fread(&cfh, 1, sizeof cfh, in); + fclose(in); + /* Attempt to restore the atime */ + copytime(cribpath, &cst); + + if ( (e == sizeof cfh && + !memcmp(cfh.magic, zisofs_magic, sizeof zisofs_magic) && + (off_t)get_731(cfh.uncompressed_len) == st->st_size) || + (st->st_size == cst.st_size && + (e < (int)(sizeof zisofs_magic) || + memcmp(cfh.magic, zisofs_magic, sizeof zisofs_magic))) ) { + /* File is cribbable. Steal it. */ + if ( !link(cribpath, outpath) ) { + message(vl_crib, "crib: %s -> %s\n", cribpath, outpath); + copytime(outpath, st); /* Set the the atime */ + return 0; + } + } + } + } + } + + in = fopen(inpath, "rb"); + if ( !in ) + return EX_NOINPUT; + out = fopen(outpath, "wb"); + if ( !out ) { + fclose(in); + return EX_CANTCREAT; + } + + if ( spawn_worker() ) { + err = opt.munger(in, out, st->st_size); + fclose(in); + fclose(out); + + chown(outpath, st->st_uid, st->st_gid); + chmod(outpath, st->st_mode); + copytime(outpath, st); + + end_worker(err); + } else { + fclose(in); + fclose(out); + } + + return err; +} + +int munge_tree(const char *intree, const char *outtree, const char *cribtree) +{ + char *in_path, *out_path, *crib_path; + char *in_file, *out_file, *crib_file; + DIR *thisdir; + struct dirent *dirent; + struct stat dirst; + int err = 0; + + /* Construct buffers with the common filename prefix, and point to the end */ + + in_path = xmalloc(strlen(intree) + NAME_MAX + 2); + strcpy(in_path, intree); + in_file = strchr(in_path, '\0'); + *in_file++ = '/'; + + out_path = xmalloc(strlen(outtree) + NAME_MAX + 2); + strcpy(out_path, outtree); + out_file = strchr(out_path, '\0'); + *out_file++ = '/'; + + if ( cribtree ) { + crib_path = xmalloc(strlen(cribtree) + NAME_MAX + 2); + strcpy(crib_path, cribtree); + crib_file = strchr(crib_path, '\0'); + *crib_file++ = '/'; + } else { + crib_path = crib_file = NULL; + } + + /* Get directory information */ + if ( stat(intree, &dirst) ) { + message(vl_error, "%s: Failed to stat directory %s: %s\n", + program, intree, strerror(errno)); + return EX_NOINPUT; + } + + /* Open the directory */ + thisdir = opendir(intree); + if ( !thisdir ) { + message(vl_error, "%s: Failed to open directory %s: %s\n", + program, intree, strerror(errno)); + return EX_NOINPUT; + } + + /* Create output directory */ + if ( mkdir(outtree, 0700) ) { + message(vl_error, "%s: Cannot create output directory %s: %s\n", + program, outtree, strerror(errno)); + return EX_CANTCREAT; + } + + while ( (dirent = readdir(thisdir)) != NULL ) { + if ( !strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..") ) + continue; /* Ignore . and .. */ + + strcpy(in_file, dirent->d_name); + strcpy(out_file, dirent->d_name); + if ( crib_file ) + strcpy(crib_file, dirent->d_name); + + err = munge_entry(in_path, out_path, crib_path, &dirst); + if ( err ) + break; + } + closedir(thisdir); + + free(in_path); + free(out_path); + + return err; +} + + +int munge_entry(const char *in_path, const char *out_path, + const char *crib_path, const struct stat *dirst) +{ + struct stat st; + int err = 0; + + message(vl_filename, "%s -> %s\n", in_path, out_path); + + if ( lstat(in_path, &st) ) { + message(vl_error, "%s: Failed to stat file %s: %s\n", + program, in_path, strerror(errno)); + return EX_NOINPUT; + } + + if ( S_ISREG(st.st_mode) ) { + if ( st.st_nlink > 1 ) { + /* Hard link. */ + const char *linkname; + + if ( (linkname = hash_find_file(&st)) != NULL ) { + /* We've seen it before, hard link it */ + + if ( link(linkname, out_path) ) { + message(vl_error, "%s: hard link %s -> %s failed: %s\n", + program, out_path, linkname, strerror(errno)); + return EX_CANTCREAT; + } + } else { + /* First encounter, compress and enter into hash */ + if ( (err = munge_file(in_path, out_path, crib_path, &st)) != 0 ) { + message(vl_error, "%s: %s: %s", program, in_path, strerror(errno)); + return err; + } + hash_insert_file(&st, out_path); + } + } else { + /* Singleton file; no funnies */ + if ( (err = munge_file(in_path, out_path, crib_path, &st)) != 0 ) { + message(vl_error, "%s: %s: %s", program, in_path, strerror(errno)); + return err; + } + } + } else if ( S_ISDIR(st.st_mode) ) { + /* Recursion: see recursion */ + if ( !opt.onedir && + (!opt.onefs || (dirst && dirst->st_dev == st.st_dev)) ) { + if ( (err = munge_tree(in_path, out_path, crib_path)) != 0 ) + return err; + } else if ( opt.do_mkdir ) { + /* Create stub directories */ + if ( mkdir(out_path, st.st_mode) ) { + message(vl_error, "%s: %s: %s", program, out_path, strerror(errno)); + return EX_CANTCREAT; + } + } + } else if ( S_ISLNK(st.st_mode) ) { + int chars; +#ifdef PATH_MAX +#define BUFFER_SLACK PATH_MAX +#else +#define BUFFER_SLACK BUFSIZ +#endif + int buffer_len = st.st_size + BUFFER_SLACK + 1; + char *buffer = xmalloc(buffer_len); + if ( (chars = readlink(in_path, buffer, buffer_len)) < 0 ) { + message(vl_error, "%s: readlink failed for %s: %s\n", + program, in_path, strerror(errno)); + return EX_NOINPUT; + } + buffer[chars] = '\0'; + if ( symlink(buffer, out_path) ) { + message(vl_error, "%s: symlink %s -> %s failed: %s\n", + program, out_path, buffer, strerror(errno)); + return EX_CANTCREAT; + } + free(buffer); + } else { + if ( st.st_nlink > 1 ) { + /* Hard link. */ + const char *linkname; + + if ( (linkname = hash_find_file(&st)) != NULL ) { + /* We've seen it before, hard link it */ + + if ( link(linkname, out_path) ) { + message(vl_error, "%s: hard link %s -> %s failed: %s\n", + program, out_path, linkname, strerror(errno)); + return EX_CANTCREAT; + } + } else { + /* First encounter, create and enter into hash */ + if ( mknod(out_path, st.st_mode, st.st_rdev) ) { + message(vl_error, "%s: mknod failed for %s: %s\n", + program, out_path, strerror(errno)); + return EX_CANTCREAT; + } + hash_insert_file(&st, out_path); + } + } else { + /* Singleton node; no funnies */ + if ( mknod(out_path, st.st_mode, st.st_rdev) ) { + message(vl_error, "%s: mknod failed for %s: %s\n", + program, out_path, strerror(errno)); + return EX_CANTCREAT; + } + } + } + + /* This is done by munge_file() for files */ + if ( !S_ISREG(st.st_mode) ) { +#ifdef HAVE_LCHOWN + if ( lchown(out_path, st.st_uid, st.st_gid) && opt.sloppy && !err ) { + message(vl_error, "%s: %s: %s", program, out_path, strerror(errno)); + err = EX_CANTCREAT; + } +#endif + if ( !S_ISLNK(st.st_mode) ) { +#ifndef HAVE_LCHOWN + if ( chown(out_path, st.st_uid, st.st_gid) && !opt.sloppy && !err ) { + message(vl_error, "%s: %s: %s", program, out_path, strerror(errno)); + err = EX_CANTCREAT; + } +#endif + if ( chmod(out_path, st.st_mode) && !opt.sloppy && !err ) { + message(vl_error, "%s: %s: %s", program, out_path, strerror(errno)); + err = EX_CANTCREAT; + } + if ( copytime(out_path, &st) && !opt.sloppy && !err ) { + message(vl_error, "%s: %s: %s", program, out_path, strerror(errno)); + err = EX_CANTCREAT; + } + } + } + + return err; +} + diff --git a/3rd-party/zisofs_tools/workers.c b/3rd-party/zisofs_tools/workers.c new file mode 100644 index 0000000..df2fb29 --- /dev/null +++ b/3rd-party/zisofs_tools/workers.c @@ -0,0 +1,111 @@ +/* + * 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. + * + */ + +#ident "$Id: workers.c,v 1.3 2006/07/04 04:57:42 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2001-2006 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * workers.c + * + * Parallel job maintenance + */ + +#include "mkzftree.h" /* Must be included first! */ + +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <stdio.h> +#include <sys/wait.h> + +/* Global option */ +extern int parallel; /* Number of parallel jobs */ + +/* Functions related to parallel execution */ +static volatile int work_threads = 0; +static int is_worker = 0; + +/* This waits for one worker to finish */ +static void wait_for_one_worker(void) +{ + int status; + + if ( wait(&status) > 0 ) { + work_threads--; + + if ( WIFSIGNALED(status) ) { + kill(getpid(), WTERMSIG(status)); + exit(EX_SOFTWARE); + } else if ( WEXITSTATUS(status) ) { + exit(WEXITSTATUS(status)); + } + } +} + +/* This waits for *all* workers to finish */ +void wait_for_all_workers(void) +{ + while ( work_threads ) + wait_for_one_worker(); +} + +/* This returns 1 if the "job" at hand should be performed */ +int spawn_worker(void) +{ + pid_t f; + + if ( opt.parallel == 0 ) + return 1; + + fflush(NULL); + + /* Wait for a work slot */ + while ( work_threads >= opt.parallel ) + wait_for_one_worker(); + + /* Spawn worker process */ + work_threads++; /* Avoids race conditions */ + f = fork(); + if ( f == -1 ) { + work_threads--; + return 1; /* Do it ourselves */ + } + + if ( f == 0 ) { + /* Worker process */ + is_worker = 1; + return 1; + } else { + /* Control process */ + return 0; + } +} + +/* Routine to perform at the end of the job */ +void end_worker(int err) +{ + if ( is_worker ) { + exit(err); + } +} + diff --git a/3rd-party/zisofs_tools/zisofs-tools.spec b/3rd-party/zisofs_tools/zisofs-tools.spec new file mode 100644 index 0000000..d6bd234 --- /dev/null +++ b/3rd-party/zisofs_tools/zisofs-tools.spec @@ -0,0 +1,50 @@ +Summary: Utilities to create compressed CD-ROM filesystems. +Name: zisofs-tools +Version: 1.0.7 +Release: 1 +License: GPL +Group: Applications/System +URL: http://www.kernel.org/pub/linux/utils/fs/zisofs/ +Source: http://www.kernel.org/pub/linux/utils/fs/zisofs/zisofs-tools-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Epoch: 1 + +%description +Tools that, in combination with an appropriately patched version of +mkisofs, allow the creation of compressed CD-ROM filesystems. + +%prep +%setup -q + +%build +%configure +make + +%install +rm -rf $RPM_BUILD_ROOT +make install INSTALLROOT="$RPM_BUILD_ROOT" + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc README zisofs.magic +%{_bindir}/mkzftree +%{_mandir}/man1/mkzftree.1* + +%changelog +* Mon Jul 20 2004 H. Peter Anvin <hpa@zytor.com> 1.0.6-1 +- Generalize and include in 1.0.6 so rpmbuild -ta works. + +* Sat Jun 13 2004 H. Peter Anvin <hpa@zytor.com> 1.0.5-1 +- Revision update. + +* Wed Nov 6 2002 H. Peter Anvin <hpa@zytor.com> 1.0.4-1 +- Revision update. + +* Thu Nov 8 2001 H. Peter Anvin <hpa@zytor.com> 1.0.3-1 +- Revision update. + +* Mon Oct 29 2001 H. Peter Anvin <hpa@zytor.com> 1.0.2-1 +- Initial version. diff --git a/3rd-party/zisofs_tools/zisofs-tools.spec.in b/3rd-party/zisofs_tools/zisofs-tools.spec.in new file mode 100644 index 0000000..e5d7c13 --- /dev/null +++ b/3rd-party/zisofs_tools/zisofs-tools.spec.in @@ -0,0 +1,50 @@ +Summary: Utilities to create compressed CD-ROM filesystems. +Name: zisofs-tools +Version: @@VERSION@@ +Release: 1 +License: GPL +Group: Applications/System +URL: http://www.kernel.org/pub/linux/utils/fs/zisofs/ +Source: http://www.kernel.org/pub/linux/utils/fs/zisofs/zisofs-tools-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Epoch: 1 + +%description +Tools that, in combination with an appropriately patched version of +mkisofs, allow the creation of compressed CD-ROM filesystems. + +%prep +%setup -q + +%build +%configure +make + +%install +rm -rf $RPM_BUILD_ROOT +make install INSTALLROOT="$RPM_BUILD_ROOT" + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc README zisofs.magic +%{_bindir}/mkzftree +%{_mandir}/man1/mkzftree.1* + +%changelog +* Mon Jul 20 2004 H. Peter Anvin <hpa@zytor.com> 1.0.6-1 +- Generalize and include in 1.0.6 so rpmbuild -ta works. + +* Sat Jun 13 2004 H. Peter Anvin <hpa@zytor.com> 1.0.5-1 +- Revision update. + +* Wed Nov 6 2002 H. Peter Anvin <hpa@zytor.com> 1.0.4-1 +- Revision update. + +* Thu Nov 8 2001 H. Peter Anvin <hpa@zytor.com> 1.0.3-1 +- Revision update. + +* Mon Oct 29 2001 H. Peter Anvin <hpa@zytor.com> 1.0.2-1 +- Initial version. diff --git a/3rd-party/zisofs_tools/zisofs.magic b/3rd-party/zisofs_tools/zisofs.magic new file mode 100644 index 0000000..9aeb61e --- /dev/null +++ b/3rd-party/zisofs_tools/zisofs.magic @@ -0,0 +1,8 @@ + +#------------------------------------------------------------------------------ +# zisofs: file(1) magic for zisofs/RockRidge compressed files +# +# from H. Peter Anvin <hpa@zytor.com> May 4, 2001 +# +0 string \x37\xE4\x53\x96\xC9\xDB\xD6\x07 zisofs/Rockridge compressed file +>8 lelong x - %d bytes @@ -0,0 +1,60 @@ + +GENERAL NOTE: + +This package is heavily based on cdrtools (by Jörg +Schilling, see below), however he is not affiliated +with the debburn development project creating this package. + +Cdrtools (see http://cdrecord.berlios.de) 2.01.01a08 from May 2006 was +the version used as the starting code base for cdrkit. + +Jörg Schilling is not responsible for problems caused by the +use or distribution of this software. Please avoid bothering +him with issues that are out of his control. + +Kudos to the original authors, especially Jörg Schilling, but for +various reasons we decided that we can only continue to have a burning +suite without license incompatibilities. For more details about this +please read the file FORK. + + +This package contains the following software: + +- cdda2wav (an digital CD audio extraction program) + By Heiko Eißfeldt <heiko@hexco.de> + +- wodim (a CD recording program). Originaly based on + cdrecord by Jörg Schilling <schilling@fokus.fhg.de> but + developed independently now. + +- genisoimage (an ISO-9660 filesystem image creator) + By Eric Youngdale <eric@andante.org>, Jörg Schilling + <schilling@fokus.fhg.de>, James Pearson + <jcpearso@ge.ucl.ac.uk> and other contributors. + +- mkhybrid (an ISO-9660/HFS filesystem image creator) + Link to genisoimage + +- several diagnostic programs for ISO-9660, originaly from + cdrtools (by Jörg Schilling), + + - devdump dump a device or file in hex + + - isodump dump a device or file based on ISO-9660 + + - isoinfo analyze or list an ISO-9660 image + + - isovfy verify an ISO-9660 image + +- readcd (a stripped down version of usalskeleton) + By Jörg Schilling schilling@fokus.fhg.de and + may be used to read data CD's, to write to DVD-RAM + and to copy Solaris boot CD's + +- usalcheck (a program to validate the correct behavior + By Jörg Schilling schilling@fokus.fhg.de and + of the low level libusal code and the SCSI transport + code of the underlying OS). + +- libusal (a highly portable SCSI transport library) + By Jörg Schilling schilling@fokus.fhg.de diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..57edba6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ +PROJECT (cdrkit C) +SUBDIRS(include genisoimage wodim libedc libhfs_iso libparanoia icedax libusal librols libunls readom netscsid 3rd-party/dirsplit) + @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..b1aefc1 --- /dev/null +++ b/Changelog @@ -0,0 +1,8360 @@ +cdrkit (1.1.11) RELEASED; urgency=low + + [ Steve McIntyre ] + * genisoimage: Fix silly bug in MD5 output in template files. (Debian + bug #596681) + * genisoimage: Minor tweaks to the the genisoimage.1 man page. + * genisoimage: Update references to atterer.org (Debian bug #596860) + * genisoimage.1: Make the description of the md5-list format clearer. + + [ Mike Paul ] + * genisoimage: Use memmove() instead of strcpy() when cleaning + up graft points. + + -- Steve McIntyre <93sam@debian.org> Fri, 23 Apr 2010 00:30:18 +0100 + +cdrkit (1.1.10) RELEASED; urgency=low + + [ Steve McIntyre ] + * genisoimage: add support for sha256 and sha512 checksum generation + when making jigdo files. + * genisoimage: checksumming with lots of algorithms can be very + time-consuming, so split it out into multiple threads if possible. + * genisoimage: allow user to specify which checksum algorithms to run + on the command line. + * Fix FTBFS with missing xconfig.h. Thanks to Matt Kraai for the patch. + + [ Nikola Pajkovsky ] + * genisoimage: fix string overflow breakage when using the -root + option (https://bugzilla.redhat.com/show_bug.cgi?id=508449) + + [ Peter Samuelson ] + * librols: remove or rename several functions that clash with POSIX. + Fix up callers. + + -- Steve McIntyre <93sam@debian.org> Thu, 14 May 2009 00:28:48 +0100 + +cdrkit (1.1.9) RELEASED; urgency=low + + [ Steve McIntyre ] + * wodim: In -msinfo mode, only suggest dvd+rw-mediainfo in verbose mode. + Thanks to Michael Karcher <debian@mkarcher.dialup.fu-berlin.de> for the + patch. + * genisoimage: undo a mistake in the directory permissions change in + the last release. Fixes handling of deep directory structures. + + -- Steve McIntyre <93sam@debian.org> Sun, 26 Oct 2008 15:43:54 -0700 + +cdrkit (1.1.8) RELEASED; urgency=low + + [ Steve McIntyre ] + * genisoimage/joliet.c: Fix a potential memory corruption bug. + * genisoimage/md5.c: Trivial cleanup + * genisoimage/genisoimage.[c1]: Add command-line support for + -jigdo-template-compress + * genisoimage/sha1.h: Fix a type issue that broke sha1 support + on 64-bit arches. + * genisoimage/checksum.[ch]: Added test code; changed internal + layout slightly to make for easier debug. + * genisoimage: Applied patch from Roman Rakus <rrakus@redhat.com> to + preserve directory permissions. + * genisoimage: Add a patch from Ivan Shmakov. "-o -" will now write + to stdout, as typical for command line programs. And we will try + not to corrupt stdout by default if it's a terminal. + * genisoimage/genisoimage.1: Add a mention of -chrp-boot. + * genisoimage/mac_label.c: Fix an over-keen s/mkisofs/genisoimage. + + -- Steve McIntyre <93sam@debian.org> Mon, 25 May 2008 21:22:26 +0100 + +cdrkit (1.1.7.1) RELEASED; urgency=low + + [ Steve McIntyre ] + * Re-spin the 1.1.7 release with a few silly release process errors fixed. + + -- Steve McIntyre <93sam@debian.org> Mon, 17 Mar 2008 21:25:56 +0000 + +cdrkit (1.1.7) RELEASED; urgency=low + + [ Harald Hoyer ] + * lots of fixes to prevent gcc warnings + * Fix for Joliet directory length bug in genisoimage + + [ Peter Samuelson ] + * wodim.1: small fixes. + + [ Steve McIntyre ] + * genisoimage/jte.c: add support for bzip2-compressed templates + * genisoimage/jte.c: fix bzip2-compressed template data to be + compatible with jigdo. + * genisoimage/jte.c: fix exclude list handling. + * genisoimage/checksum.[ch]: Add a generic infrastructure for + checksums so we can use sha1/<whatever> as well as just + md5sum. Will make things much faster for generating sha1sums for + images and jigdos. + * genisoimage/sha1.[ch]: Add GPL-licensed SHA1 implementation. + * s/mkisofs/genisoimage/ in ABOUT + + -- Steve McIntyre <93sam@debian.org> Mon, 17 Mar 2008 20:07:58 +0000 + +cdrkit (1.1.6) RELEASED; urgency=low + + [ Vladimir Nadvornik ] + * genisoimage/eltorito.c: care about inhibit flags when preparing eltorito + boot catalog directory entry, avoiding possible crashes + + [ Eduard Bloch] + * ALL: customize the base manpage subdirectory below PREFIX using the new + MANSUBDIR variable + * make sure that the buffer is flushed and drive is ready before closing + session + * icedax: find libossaudio on OpenBSD and use it + * icedax: fixed bug with --devices (unnoticed segfault due to wrong + list_devices arguments) + * wodim/scsi_scan.h: moved Linux-specific recorder location guesser to an + extra method for automatic drive opening, and added an alternative + guessing method, using list_devices(...) picking up the first drive having + appropriate device type in the inquiry info. This generic method is also + used on Linux when the original guesser fails. + * wodim/wodim.c: count all track sizes when looking for an appropriate drive + + -- Eduard Bloch <blade@debian.org> Sun, 06 May 2007 16:39:08 +0200 + +cdrkit (1.1.5.1) RELEASED; urgency=low + + * resync with cosmetical last-minute changes from Peter Samuelson + * Makefile: "release" target extension to make the Debian related source + file creation more convinient + + -- Eduard Bloch <blade@debian.org> Sat, 21 Apr 2007 11:30:35 +0200 + +cdrkit (1.1.5) RELEASED; urgency=low + + * wodim: explicite warning and more grace time if user manually specifies a size + less than 301 sectors, which is likely to be a mistake from copy-pasting + of genisoimage -print-size output and omitting the block factor + * wodim: Native device name management directly in libusal now, the + rewritten device scan method uses it directly. If the backend driver does + not implement native names handling, the old-style IDs are displayed. + * libusal: native device name management, implemented on Linux and + Win32(SPT) for now + * libusal: ATA is now mapped directly into the b/t/l namespace, with some + workarounds to provide backward compatibility + * libusal: For SCSI devices, use only scd* on kernel 2.6 and sg* on kernel + 2.4 until proper locking scheme is established + * libusal: always return a known value in usal_sense_table(...), from a + patch from SUSE (cdrkit-dvd-fix.patch) + * genisoimage: customized the default APPID string in genisoimage + * genisoimage: restored support for iso9660 file sizes up to 4GB-1 + * genisoimage: forced MAGIC_ERROR definition for older version, thanks + to Thomas Schmidt + * genisoimage: avoid pointless warnings on filetype of <root directory>/.. + + -- Eduard Bloch <blade@debian.org> Sat, 21 Apr 2007 10:17:35 +0200 + +cdrkit (1.1.4) RELEASED; urgency=low + + [ Eduard Bloch ] + * On Linux, do device scanning on /dev/sr first and fallback to /dev/sg and + others only then, thus having better chances to use the same exclusive + lock as other programs when the user provided only the b/t/l + device specification, since the Linux kernel is not able to coordinate the + locking between the userspace interfaces + * some refactoring, moved new Linux specific extensions to scsi-linux-sg.c, + more relaxed device opening checks on scanning + * some more warnings about b/t/l syntax deprecation + + -- Eduard Bloch <blade@debian.org> Sun, 01 Apr 2007 21:49:03 +0200 + +cdrkit (1.1.3) RELEASED; urgency=medium + + [ Eduard Bloch ] + * Fixed fishing for transfer size in sysfs, now ready for + /dev/class/scsi_generic contents + * Fixed /dev/sg%d pattern scan in --devices, now iterating over modern style + device files. Thanks to Thomas Schmidt. + * Dealing with the last newline char when processing + /proc/sys/dev/cdrom/info contents + * print the track size in the info message when guessing + * added some missing or probably missing definitions in + wodim/CMakeLists.txt, restoring the reading from inf files + * passing through the real file size to the UDF generator. Creating + incorrect iso9660 but having it this way is better than no LFS at all. + * removed md5* parts and integration from icedax, patch by + Vladimir Nadvornik <nadvornik@suse.cz> + * various small bugfixes or cosmetic fixes picked from still GPLed parts of + cdrtools-2.01.01a24, excluding meta changes and big tree.c and mkisofs.c + refactoring. Stream file name option enabled now. + * wodim.1: "you have 4 seconds to abort ..." + * defaults.c: Correct fallback to CDR_FIFOSIZE and correct error message + on bad input. + * tell the user his device is busy on Linux because it's mounted, after + looking at /proc/mounts + + [ Peter Samuelson ] + * Clean up Linux-2.6 CD/DVD-R drive detection, clearer error messages. + + -- Eduard Bloch <blade@debian.org> Mon, 26 Mar 2007 17:35:10 +0200 + +cdrkit (1.1.2) RELEASED; urgency=low + + [ Stefan Huehner ] + * more Cstyle cleanups + + [ Eduard Bloch ] + * stop confusion and bailing out if burnfree/burnproof options have been + explicitely specified + * be move carefull with -dummy when the DVD media may not support it + * extracting drive's default speed in attach_mdvd() + * automatic recorder device guessing code, currently Linux-only + + [ Peter Samuelson ] + * Fix icedax cddb query, based on a patch from Heiko Schlenker + + -- Eduard Bloch <blade@debian.org> Sat, 13 Jan 2007 00:45:38 +0100 + +cdrkit (1.1.1) RELEASED; urgency=low + + * added geteltorito script from Rainer Krienke + + [ Eduard Bloch ] + * more verbose abort message if track is specified with some maintainance + command (#369677) + * Added more DVD related fixes from SuSE's wodim-1.0pre5cvs-6.src.rpm + * --devices option for wodim (modeled after cdrskin's output), working on + Linux and Cygwin + * Open-By-Device-Letter mode on Cygwin + * -msifile=... option to store -msinfo output reliably in a dedicated file + * clear profile names printing (using code from libburnia, thanks to Thomas + Schmidt) + * cleanup with unused embedded CVS revision strings from Schilling and + more gcc -Wall correctness + * reenabled -format functionality (bug in program function control flow) + * get maximum DMA buffer size from sysfs on Linux, where possible + * enable BURN-Free by default where possible + * setting argv[0] to wodim if someone is cheating and calls it as cdrecord. + Avoids confusion and printing of the wrong app name in the help output. + * more documentation updates WRT cdda2wav->icedax renaming, more table + formating fixes in icedax.1 + * genisoimage documentation updates, mkisofs name changes + + [ Thomas Schmidt ] + * workaround for older libmagic API + * code for clear profile name mapping + + [ Peter Samuelson ] + * expand where genisoimage looks for the config file - same places + mkisofs looks plus a few more. (We may wish to trim this back some.) + * major cleanups to genisoimage.1 manpage; split out the part about + .genisoimagerc to a new page genisoimagerc.5. + + [ Steve Langasek ] + * allow hppa and alpha boot code to coexist in one ISO image + + [ Arkadiusz Miskiewicz ] + * Fake prefix line in the version output of readom to keep compatibility + with frontends + + -- Eduard Bloch <blade@debian.org> Sat, 30 Dec 2006 16:45:40 +0100 + +cdrkit (1.1.0) RELEASED; urgency=medium + + [ Eduard Bloch ] + * replacement of libdeflt, config parser rewrite; more user-friendly, + more flexible/tolerant now + * config overhaul, much more dynamic checks, including fixes for SunOS and + AIX environment, including proper libiconv detection, and processing of + LDFLAGS provided by user. Also fixed confusing double-checks for some of + the variables in cdda2wav.c. + * mass renaming of applications and libraries, see FAQ + * dirsplit -S fix, oversized have been possible before + * consistent version display + * cleanup of libschily, removed unused/superfluous parts (assumed having a + modern POSIX compliant environment). Renamed to librols + (RemainsOfLibSchily). + * reenabled selection of the DVD driver, accidentaly disabled in 1.0, when + beeing in non-verbose mode + * made dirsplit work with file symlinks + * incorporated some OpenSUSE patches: + + cdrkit-HZ.patch (with initialized value, *sic*) + + cdrkit-dvd-fix.patch (return code tracking) + + cdrkit-gcc-workaround.patch + + cdrkit-mkisofs-fail-on-large-file.patch (don't just skip them) + + cdrkit-mkisofs-grow-check.patch (tolerate grown files) + + cdrkit-perms.patch (not breaking on missing device files) + + [ Christian Fromme ] + * big cleanup, phase I, getting rid from Cstyle function definitions in + applications + + [ Lorenz Minder ] + * user output junk filter in icedax/toc.c + * flexible ascii conversion buffer + + -- Eduard Bloch <blade@debian.org> Sat, 02 Dec 2006 18:43:14 +0100 + +cdrkit (1.0) RELEASED; urgency=low + + [ Eduard Bloch ] + * mapping of ATAPI: -> ATA: method on linux-2.6 and some code beautification + * added a atexit handler to stop the FIFO process more reliably, since + Schilling's constructs seem to terminate the application on too many + places + * print Burnfree state/preparation messages only with high verbosity + + [ Dennis Vshivkov ] + * sorted display of files when needed + + [ Joerg Jaspert] + * Remove all the printing of useless messages. This is based on GPLed + code, so we follow the letter of the GPL as it is interpreted by 99% + of the world, including its authors. Especially as Joerg was never able + to give us any clear explanation what other license he may think + cdrtools had, despite us asking multiple times. So we have no other + choice than to take whats written down, and thats GPL. + + -- Joerg Jaspert <joerg@debian.org> Mon, 20 Nov 2006 19:25:10 +0100 + +cdrkit (1.0pre5) RELEASED; urgency=low + + [ Eduard Bloch ] + * added better check for capability.h and FATAL_ERROR if it's missing on Linux + * wodim.1 updates, ie. moved suid howto to README.suidroot, Linux bashing to + README.linux, more notes about non-root usage + * more carefull description of the role of previous developer and his own + project + * fixed libmagic detection + * rewrote README.mkisofs, README.win32 + * better track numbers extraction command in cdda2ogg/cdda2mp3 + * reenabled (forgotten) support for libedc + * table formating fixes in cdda2wav.1, helps small terminals + * AIX 5l port + * killing FIFO process on ungraceful termination + * scsi-linux-sg.c: skipping unallowed devices, cleanup/consolidation of the + old workaround(s) for ATA now for SCSI too + * renamed error function to schily_error because it started to wreak random + havoc after harmless header moving (conflict with incompatible GNU version) + * restored scsi-remote.c compilation, moved to libscg sources, used instead + of rdummy.c + * added optional omiting of DMA speed tests + + [ Vladimir Nadvornik ] + * enabled CLONE feature in wodim's config + + [ Modestas Vainius ] + * dropped . from the include path and fixed mkisofs source to use the local + headers + + [ Lorenz Minder ] + * Fix of the joliet_strlen signature + * Code refactoring around *cvt* declarations to make the conditional + compilation more reliable, especially on BSD and AIX + * include/utypes.h: guard to preserve SIZE_T_MAX + + [ Christian Fromme ] + * detailed review and correction of author related data in manpages and + README files + + [ Peter Samuelson, Tollef Fog Heen ] + * typo and grammar fixes in mkisofs.8 + * Remove several instances of %r in printf-like statements, in + preparation for removing the libschily format-string implementation + + -- Eduard Bloch <blade@debian.org> Wed, 6 Sep 2006 22:05:30 +0200 + +cdrkit (1.0pre4) RELEASED; urgency=low + + [ Eduard Bloch ] + * Added checks for libcam to make (k)FreeBSD compilation work (untested) + * added clarifications about changes to all source files + * adapted initial message to display the copyright more clearly + * adapted copyright and contact information in scgcheck manpage + * adapted contact information in btcflash manpage, also added a reference to + its original author which has been missing + + [ Peter Samuelson ] + * Cleanups: unused macros/defines + * Unified and simplified the build-host data crawling methods + + [ Juergen Weigert ] + * Various documentation corrections, replaced cdrecord->wodim where it is + appropriate and legal on many visible locations + + -- Eduard Bloch <blade@debian.org> Mon, 4 Sep 2006 23:36:58 +0200 + +cdrkit (1.0pre3) unstable; urgency=low + + [ Eduard Bloch ] + * Added FAQ ("where wodim name comes from") + * Moved the NULL pointer check on cdr_t to a place before it is used for DVD + feature checks (otherwise it would crash when run on any pure CD-ROM + reader) + * Added test for WORDS_BIGENDIAN + * copied values from align.h to another set of sizeof-reflecting defines in + xconfig.h + * workarounds for almost all "you are not allowed to modify that {version + checking,quality assurance,other-important-looking-wording}" parts, + replacing the output of "schily" where the commend said that we are forced + to. One part in cdrecord.c still remains, the comment sounds too dangerous + to be touched. + * forced FIFO define, suggested by Peter + + [ Peter Samuelson ] + * Created cmake test and code snippet for HAVE_C_BITFIELDS + + [ Michael Ablassmeier ] + * Typo fixes in mkisofs messages and unified identical ones with a macro + + [Joerg Jaspert] + * Released as 1.0pre3 + + -- Eduard Bloch <blade@debian.org> Mon, 4 Sep 2006 09:56:38 +0200 + +cdrkit (1.0pre2) RELEASED; urgency=low + + * Took zisofs_tools out of the global build system and restored its original + Makefile. Its own build system works better. + + -- Eduard Bloch <blade@debian.org> Sun, 03 Sep 2006 22:14:31 +0200 + +cdrkit (1.0pre1) RELEASED; urgency=low + + [ See http://bugs.debian.org/$BUGNR for detailed explanations ] + * The Big Fork to an independent project called cdrkit + + using the last clearly stated GPLed versions of files from + cdrtools-2.01.01a08 (closes: #353403, 372486) + + we play the upstream role now, using our patches and we like them + (closes: #361450) + + renamed relevant works to avoid claims of "potential defamation" or + "damage of reputation" (closes: #350738) + + custom CMake based build system used instead of the original one, since + we understand it better (closes: #350739 and hopefully closes: #350254, + reopen if not). It seems to be portable among the platforms + supported by Debian, it needs a bit of work for porting to non-Linux + plattforms, though. + * removed most of the anti-linux2.6 program messages (unless being + in verbose mode). (closes: #377145) + * changed default config file location to /etc/wodim.conf + * added more meaningful error message on -dvd-video failure (closes: #324586) + * minor cdda2mp3/cdda2ogg scripts fixes suggested by Fabian Pietsch, plus + fixes for unreliable encoder detection (closes: #283794, #344443) plus + possible override of preset CDDA_DEVICE variable fixed. Made the list of + selected audiotracks modifiable, see manpage (closes: #344445) + * sync with 4:2.01+01a01-4ubuntu4: + + merged README.ATAPI.setup with README.ATAPI.setup.ubuntu. Kernel 2.6 part + now in the beginning and reflecting the reality (dev=/dev/drive syntax, + no SUID requirement, closes: #304230, 377736) + + 02_cdrecord_default_conf.dpatch: changed /dev/cdrom to /dev/cdrw which + is more likely to match the correct device on udev using systems + * 36_ATA_scanbus_ignore_locked.dpatch to ignore busy devices (eg. hda + harddisk) while scanning with dev=ATA + (closes: #310689, #309250, #317793, 360295, + * Included 37_clean_dvdsup.dpatch (closes: #312062) based on + cdrtools-2.01.01a04-dvd.patch.bz2 from + http://people.mandriva.com/~warly/files/cdrtools/ with few updates to work + with a08. Also implements a fallback to ATA: bus in the -scanbus operation + (closes: #310689, #278894). This patch is used instead of the old 07_.... + Enabled permanently, disabled the "cheatcode processing" in debian/rules. + Also eliminates some useability problems that have been pushed to our + users (closes: #325766, #271114, #312062, #353176). + * Updated dirsplit to version 0.3.3, zisofs-tools to 1.0.7 (with a custom + CMakeFile.txt for easier integration and config.h updated manually for + now) + * minor cdda2mp3/cdda2ogg scripts fixes suggested by Fabian Pietsch, plus + fixes for unreliable encoder detection (closes: #283794, #344443) plus + possible override of preset CDDA_DEVICE variable fixed + * added additional script manpages from Oleksandr Moskalenko (closes: #295438) + * changed -speed to speed= in cdrecord.1 for consistency (closes: #344214) + * Anti-Root-Requirements: + + 39_nonroot_skips_rezero_unit.dpatch - don't run rezero_unit() as root + which is a) most likely not needed (even admited in the comment) and b) + causes the whole scsi transport system to terminate + + 40_stop_setuid_games.dpatch - another workaround for problems introduced + in a03 - looks like Linux kernel does reject an application trying to + change the UID between ioctls + (closes: #335253, 374685, 330506, 329308, 374345, 377421) + * Ubuntu's 40_fix_bad_spelling.dpatch integrated (typo in wodim.dfl) + * increased hash size in mkisofs/hash.c (closes: #327270) + * more decent info message about locale detection + + -- Eduard Bloch <blade@debian.org> Sun, 03 Sep 2006 22:14:31 +0200 + +cdrkit (2.01.01a08+X.15) UNRELEASED; urgency=low + + * Removed cdrtools-2.01.01a05-ossdvd.patch.bz2 again (threw bogus error + messages in TAO mode), used 37_clean_dvdsup.dpatch (from Warly/Mandriva) + instead + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 15:03:46 +0200 + +cdrkit (2.01.01a08+X.15) UNRELEASED; urgency=low + + * Applied cdrtools-2.01.01a05-ossdvd.patch.bz2 slightly adapted to work with + a08. + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 15:03:46 +0200 + +cdrkit (2.01.01a08+X.14) UNRELEASED; urgency=low + + * 39_nonroot_skips_rezero_unit (don't try to run rezero_unit when not beeing + root) + * 40_stop_setuid_games (dont't try to cheat the kernel with delayed seteuid) + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 14:44:53 +0200 + +cdrkit (2.01.01a08+X.13) UNRELEASED; urgency=low + + * 34_JTE (Jigdo Template Extraction, by Steve) + * 36_ATA_scanbus_ignore_locked (skip busy devices when scaning, by myself) + * 38_script_manpages: added as readmult.1 and pitchplay.1, currently no + list_audio_tracks script there so moved to scrips/ + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 14:35:30 +0200 + +cdrkit (2.01.01a08+X.12) UNRELEASED; urgency=low + + * 31_gnu-kfreebsd.dpatch with minor adoptions (needs testing!) + * 33_extra_arch_boot_support (extra arches, by Steve) + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 14:29:32 +0200 + +cdrkit (2.01.01a08+X.11) UNRELEASED; urgency=low + + * 26_author_locale (ASCII transliteration of Jörg in the standard credits + message) + * 28_cdda2wav_interface (Linux friendly cdda2wav behaviour) + * 30_doc_typo_fixes (various documentation/message fixes) + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 14:23:03 +0200 + +cdrkit (2.01.01a08+X.10) UNRELEASED; urgency=low + + * Applied 23_o_excl (exclusive device opening) + * Applied 24_debug_tmpfile (more safe/secure log file location) + * 25_mkisofs_iconv_manpage (hints about extra charsets) + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 14:20:05 +0200 + +cdrkit (2.01.01a08+X.09) UNRELEASED; urgency=low + + * Applied 18_donotopen_hda.dpatch - don't insist on opening unrelated IDE + devices + * 20_rsh-bugfix.dpatch - make really sure that the program does seteuid + right or exit + * 22_linux_rawio_capability.dpatch: get Linux capabilities as needed + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 14:11:47 +0200 + +cdrkit (2.01.01a08+X.08) UNRELEASED; urgency=low + + * mkisofs iconv support with log message adapted, added to CMake build + system as appropriate + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:57:10 +0200 + +cdrkit (2.01.01a08+X.07) UNRELEASED; urgency=low + + * Applied patches: 07_noadvertising (strip adds for commercial + cdrecord-proDVD), 08_privacy (mkisofs revealing the exact command line) + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:54:54 +0200 + +cdrkit (2.01.01a08+X.06) UNRELEASED; urgency=low + + * Applied 06_dautipps - better hints about ATAPI usage howto and + -joliet-long workaround + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:52:50 +0200 + +cdrkit (2.01.01a08+X.05) UNRELEASED; urgency=low + + * Bits from 03_script.dpatch by Joerg Jaspert <joerg@debian.org> and Eduard + Bloch: Linux-friendly device location for cdda scripts and better encoder + selection + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:49:56 +0200 + +cdrkit (2.01.01a08+X.04) UNRELEASED; urgency=low + + * Added bits from 02_paths.dpatch by Joerg Jaspert <joerg@debian.org>: + /var/log directory location and SILO relevant paths + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:46:55 +0200 + +cdrkit (2.01.01a08+X.03) UNRELEASED; urgency=low + + * adapted cdrecord/cdrecord.dfl for modern Linux system, based on bits from + 02_cdrecord_default_conf.dpatch by Zack Cerza <zcerza@coe.neu.edu> + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:43:15 +0200 + +cdrkit (2.01.01a08+X.02) UNRELEASED; urgency=low + + * Converted to use a CMake based filesystem. Generating relevant things with + its mechanisms instead of inc/*. Dropped BUILD, INSTALL files, rewrote + COMPILE fall to reflect the new build method. + * Added GNUmakefile which has rules to bootstrap the CMake build system and + then pass the actuall call to it. GNUmakefile is the prefered script used + by gmake. Users with other make implementations should run cmake manually. + + -- Eduard Bloch <blade@debian.org> Wed, 23 Aug 2006 13:35:23 +0200 + +cdrkit (2.01.01a08+X.01) UNRELEASED; urgency=low + + * moved documentation around, READMEs/ directory contains a structure, moved + mkisofs docs from the source directory to it + + -- Eduard Bloch <blade@debian.org> Tue, 22 Aug 2006 12:40:05 +0200 + + +***** Version 2.01 ******** + +Wed Sep 8 20:26:34 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.297 + * readcd.c 1.74 + * cdrecord.c 1.296 + Version -> 2.01 + +Sat Sep 4 22:28:05 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.28 + * scsisense.h 2.18 + * scsicdb.h 2.19 + * scsireg.h 1.31 + * scgcmd.h 2.22 + Cstyle + +Wed Aug 25 13:28:57 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.295 + Warnung fuer Linux-2.6.8.1 neu + +Tue Aug 24 01:11:42 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.16 + Auch die euid auf pw->pw_uid setzen bevor exec(RSH gemacht wird + +Thu Aug 19 12:14:09 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.294 + Version -> 2.01a38 + +Thu Aug 19 12:08:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.293 + linuxcheck() im %I% verbessert ;-) + +Mon Aug 16 16:42:17 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.292 + Version -> 2.01a37 + SuSE Kommentar erweitert. + +Sun Aug 8 23:04:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.10 + struct features & struct profiles -> LOCAL + +Thu Aug 5 10:26:18 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.291 + Kommentar vor linuxcheck() erweitert + +Wed Aug 4 02:30:51 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.290 + Version -> 2.01a36 + max_dma ist nun 4/5 der DMA Speed statt 1/2 + Warnung wegen Linux-2.6 eingebaut + Warnung wegen SuSE Linux eingebaut + +Sat Jul 31 17:41:06 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.289 + Version -> 2.01a35 + Check auf dma_speed > 0, dma_speed Test nur wenn tracks > 0 + +Mon Jul 19 11:10:00 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.45 + SPTI nicht bei NT-4.0 als Default + +Sun Jul 18 01:26:08 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.288 + Version -> 2.01a34 + Mehr Tests auf Korektheit der Werte (sinnvoller Bereich in get_dmaspeed()) + dma_speed nur dann auswerten wenn > 0 + +Sun Jul 11 02:28:23 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.103 + CDR_FORCESPEED domumentiert + +Sun Jul 11 01:57:27 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * skel.c 1.3 + * readcd.c 1.73 + * xio.c 1.11 + -> NEED_O_BINARY + +Sun Jul 11 01:32:49 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.72 + * skel.c 1.2 + MINGW32 neu + +Sun Jul 11 01:30:12 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.10 + setmode() auch bei MINGW32 + +Fri Jul 9 00:05:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.287 + Version -> 2.01a33 + get_dmaspeed() neu + kein nice() bei __DJGPP__ + +Fri Jun 18 17:46:20 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.44 + if (isdigit(vers) -> if (isdigit(vers[0]) (bug korrigiert + +Fri Jun 18 01:17:54 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvdplus.c 1.15 + * drv_dvd.c 1.118 + long dvd_next_addr -> LOCAL long dvd_next_addr + +Thu Jun 17 23:20:27 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.29 + * scsitransp.c 1.91 + Bitfeld Typen fuer printf() auf int casten wegen IRIX cc + +Thu Jun 17 11:24:48 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.71 + Verbose Ausgabe fuer Fehlerkorrekturen nochmals angepasst + +Sun Jun 13 16:28:28 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.70 + maxtry neu + +Sun Jun 13 16:00:20 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.69 + Ausgabe der maximale Anzahl der Retries + +Sat Jun 12 15:14:49 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvdplus.c 1.14 + * drv_dvd.c 1.117 + RAW & TAO Schreibmodi nach check_writemodes() loeschen damit niemand cdrecord -raw fuer DVDs aufruft + +Sat Jun 12 13:48:12 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-ata.c 1.7 + Warntext geaendert + +Fri Jun 11 16:49:15 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.68 + Version -> 2.01a32 + -scanbus funktioniert nun auch wenn dev= nicht angegeben und /etc/default/cdrecord vorhanden + Auflistung der defekten Sektoren in allozierter Liste + +Thu Jun 10 10:58:19 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.102 + Schreibfehler + +Wed Jun 2 22:54:33 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.101 + -clone dokumentiert + +Tue May 25 17:33:15 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.67 + Vsersion -> 2.01a31 + +Tue May 25 17:32:29 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.66 + -scanbus neu + +Tue May 25 01:36:00 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.161 + * scsi_cdr.c 1.137 + * drv_mmc.c 1.157 + write_buffer() neu und write_buffer() in drv_mmc.c -> yamaha_write_buffer() + +Thu May 20 16:42:12 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.83 + Kommentar gegen die Debian patches fuer /dev/hd* + +Thu May 20 16:24:11 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-ata.c 1.6 + Bis zu 25 /dev/hd%c Files oeffnen + +Thu May 20 16:14:33 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.82 + Kommentare um dumme Leute von SuSE davon abzuhalten wichtige Warnungen wegzupatchen + +Thu May 20 15:50:38 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.100 + Kommentar zu benoetigten Root Rechten neu + +Thu May 20 15:35:52 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.286 + Bessere Kommentare gegen SuSE die cdrecord nicht als root laufen lasse wollen + +Wed May 19 00:54:29 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.285 + Make sure you are root. nur ausgeben wenn euid != 0 + +Wed May 19 00:47:48 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.284 + Version -> 2.01a29 + reload geht nun auch fuer Notebook Laufwerke wieder + +Wed May 19 00:45:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.160 + * scsi_mmc.c 1.9 + print_format_capacities() neu + +Wed May 19 00:27:28 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.99 + Bessere beschreibung der Hintergruende fuer eine gute Wahl der FIFO Groesse (fs=) + +Mon May 17 00:38:17 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.98 + Bessere Dokumentation fuer DVD + +Mon May 17 00:18:21 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsilog.c 1.17 + Besserer Kommentar + +Sun May 16 23:46:51 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.156 + bei OPC "Power calibration area almost full" nicht als Fehler auffassen + +Sun May 16 17:01:24 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.97 + Bessere Dokumentation der driver= Option + +Sun May 16 01:37:11 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.96 + Diverse kleinere Schreibfehler beseitigt + +Sun May 16 01:26:52 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.95 + Eißfeldt -> Ei\*sfeldt + µsec -> \*msec + +Sat May 15 23:14:18 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.19 + index Variable -> curindex wegen GCC Shadow Warnung + +Sun May 9 17:59:31 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * skel.c 1.1 + date and time created 04/05/09 16:59:31 by joerg + +Fri Apr 23 00:51:24 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.43 + Padding fuer ASPI CMD Struktur damit auch 32 Byte Sense Daten von SPTI gehen + +Wed Apr 21 01:48:32 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.42 + Support fuer SPTI & Kontroller mit mehr als einem SCSI Bus + Bei SPTI ist SENSE_LEN max nun 32 + +Sun Apr 18 13:26:43 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.81 + MAX-SCG -> 256 wegen Linux USB Implementierung + +Fri Apr 16 15:29:34 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.19 + Bis zu 256 Busse scannen. + +Thu Apr 15 16:35:46 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.283 + Version -> 2.01a28 + +Mon Apr 12 16:13:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.94 + Read Book -> Red Book + +Tue Apr 6 11:59:03 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.282 + Bessere Fehlermeldung bei fehlendem -pad/-shorttrack + +Mon Mar 15 01:59:49 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.281 + Kommentar fuer cuefile= & -raw + +Wed Mar 10 21:54:36 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.65 + * cdrecord.1 1.93 + * cdrecord.c 1.280 + ts= Doku besser + +Mon Mar 8 00:43:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.80 + Fehler if (sp->u_sense.cmd_sense != 0 -> if (sp->u_sense.cmd_sense[0] != 0 korrigiert + Wenn ASC/ASQ und auch alle zusaetzlichen Bits/Key in Byte 2 0 sind, dann loeschen wir CHECK CONDITION wieder + weil das ein Linux USB Problem ist wo z.B. wegen einem DMA Underrun REQUEST SENSE geschickt wurde + und das Laufwerk erwartungemaesz mit NO SENSE geantwortet hat + +Sun Mar 7 23:43:08 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.279 + Version -> 2.01a27 + +Thu Mar 4 09:24:11 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.278 + Bugfix: Nach Umstellung des Tests auf Schreibmodus Option ging nur noch TAO + +Wed Mar 3 01:27:14 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.115 + * cue.c 1.20 + * isosize.c 1.9 + * drv_simul.c 1.47 + * getnum.c 1.2 + * movesect.c 1.3 + Cstyle + +Tue Mar 2 21:02:42 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * misc.c 1.4 + * cue.c 1.19 + Copyright -> 2004 + +Tue Mar 2 02:53:06 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.25 + * fifo.c 1.47 + * drv_mmc.c 1.155 + * drv_sony.c 1.70 + * drv_dvdplus.c 1.13 + * drv_7501.c 1.15 + * diskid.c 1.37 + * defaults.c 1.11 + * crc16.c 1.6 + * cdr_drv.c 1.36 + * clone.c 1.7 + * drv_philips.c 1.68 + * readcd.c 1.64 + * scsi_cdr.c 1.136 + * scsi_scan.c 1.18 + * iso9660.h 1.5 + * xio.h 1.2 + * cdtext.h 1.5 + Cstyle + +Tue Mar 2 01:13:42 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_track.c 1.4 + Copyright -> 2004 + +Mon Mar 1 11:08:40 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.159 + * mmcvendor.h 1.3 + * scsilog.h 1.4 + * scsimmc.h 1.10 + * drv_jvc.c 1.80 + * scsi_mmc.c 1.8 + * cdtext.c 1.10 + * scsilog.c 1.16 + * auinfo.c 1.23 + * cdrecord.c 1.277 + * audiosize.c 1.19 + * sector.c 1.12 + * subchan.c 1.17 + * wm_packet.c 1.24 + * xio.c 1.8 + Cstyle + +Mon Mar 1 11:02:43 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.11 + * subchan.c 1.18 + * wm_packet.c 1.25 + * xio.c 1.9 + * sector.c 1.13 + Copyright -> 2004 + +Sun Feb 29 21:49:03 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.276 + Cstyle + +Sun Feb 29 18:19:58 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.275 + Version -> 2.01a26 + -tao/-sao neu + +Sun Feb 29 18:13:20 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.92 + -tao Option neu, -sao Option als Alias fuer -dao + +Sun Feb 22 16:41:57 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.91 + Schreibfehler + +Sun Feb 22 15:53:51 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.63 + * cdrecord.h 1.158 + * defaults.c 1.10 + cdr_defaults() Prototy -> neues defaults.h + +Sun Feb 22 15:53:00 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.1 + date and time created 04/02/22 15:53:00 by joerg + +Sun Feb 1 21:32:58 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * adip.h 1.1 + date and time created 04/02/01 21:32:58 by joerg + +Fri Jan 23 23:10:42 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.41 + dev=ATAPI:1,0 geht nun wieder + +Mon Jan 19 21:29:24 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.113 + * cdrecord.c 1.274 + * drv_dvdplus.c 1.12 + * wm_packet.c 1.23 + trackp[i].padsecs * secsize -> (Llong)trackp[i].padsecs * secsize, damit kein Integeroverflow mehr stattfindet + +Thu Jan 15 22:24:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.40 + w2k_or_newer() neu um bei NT-4.0 wegen DMA Problemen mit SPTI per Default mit ASPI zu betreiben + Debug prints fuer bessere Beurteilung der Funktionsweise + +Thu Jan 15 02:22:38 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.9 + memset sense 0 wieder eingebaut bis endgueltig geklaert ist wie es sein sollte + +Thu Jan 15 01:55:36 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-hpux.c 1.31 + * scsi-linux-pg.c 1.43 + * scsi-vms.c 1.33 + * scsi-os2.c 1.25 + * scsi-wnt.c 1.39 + * scsi-remote.c 1.15 + * scsi-unixware.c 1.36 + * scsi-qnx.c 1.3 + * scsi-osf.c 1.26 + * scsi-sgi.c 1.36 + * scsi-bsd.c 1.42 + * scsi-bsd-os.c 1.28 + * scsi-beos.c 1.22 + Umbau fuer Cstyle + +Thu Jan 15 01:05:25 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-openserver.c 1.31 + Aenderungen fuer Cstyle + +Thu Jan 15 00:50:11 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-next.c 1.32 + * scsi-linux-ata.c 1.5 + Umbau wegen Cstyle + +Wed Jan 14 20:05:52 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.112 + Unbenutzte Variablen beseitigt + +Wed Jan 14 20:04:33 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.82 + Aumbau fuer Cstyle + +Wed Jan 14 19:57:28 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.81 + Ueberfluessige Variable sb beseitigt + +Wed Jan 14 18:54:48 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-apollo.c 1.5 + * scsi-amigaos.c 1.6 + * scsi-aix.c 1.36 + * scsi-linux-sg.c 1.79 + * scsiopen.c 1.95 + * scsitransp.c 1.90 + * scgsettarget.c 1.2 + * scsihelp.c 1.4 + Umbau fuer cstyle + +Wed Jan 14 15:37:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.78 + LF_ATA Flag neu + +Wed Jan 14 01:14:27 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.8 + ux_errno wird nun korrekt gesetzt wenn ein Kommando schiefgeht + Die Sense Daten werden nicht mehr gelöscht + Author ist nun "schily", denn das Modul kommt nun teilweise dirch scgcheck + +Tue Jan 13 20:43:44 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.7 + Umbau fuer Cstyle + +Mon Jan 12 00:36:04 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.154 + Besserer Kommentar bei den Profilen in identify + +Mon Jan 12 00:33:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.35 + dp bei error() ueberpruefen um coredumps bei cdrecord -xd zu verhindern + +Sun Jan 11 18:42:14 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.77 + Versuch das /dev/hd* Interface von Linux-2.6 besser zu unterstützen. + +Sun Jan 11 16:18:48 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.76 + Kommentar verbessert + +Sun Jan 11 14:39:45 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.38 + w2kstyle_create() umgestellt und so repariert, dasy kein unzulaessiger Speicherzugriff mehr erfolgt + +Sun Jan 11 14:09:19 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.37 + loas_aspi() neu + +Sun Jan 11 13:28:56 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.36 + Aenderungen damit cdrecord -scanbus dev=ASPI geht + +Wed Jan 7 00:38:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.157 + * scsi_scan.c 1.17 + * scsi-mac-iokit.c 1.6 + * scsi-sun.c 1.80 + * scsi-wnt.c 1.34 + * scsitransp.c 1.89 + * cdrecord.c 1.273 + Copyright -> 2004 + +Wed Jan 7 00:20:32 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.35 + Anderer Version String fuer SPTI + +Wed Jan 7 00:03:55 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.272 + Version -> 2.01a24 + +Tue Jan 6 23:58:43 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.18 + Wenn FILE Anweisung im CUE Sheet keinen Slash (/) enthaelt, dann wird der Filename auch im Directory des CUE Sheets gesucht + +Tue Jan 6 23:52:52 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.88 + Version -> 0.8 + +Tue Jan 6 23:33:20 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.33 + Cstyle + +Tue Jan 6 23:21:14 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.32 + SPTI Unterdrueckung von nocht CD-ROM deaktiviert + +Tue Jan 6 23:10:18 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.31 + Erste Version mit SPTI Support + +Tue Jan 6 17:58:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.5 + scgo_havebus() korrigiert (war immer FALSE) damit pxupgrade funktioniert + +Tue Jan 6 01:01:59 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.153 + cmd_dummy statt init_mmc in den Treiberstrukturen fuer CD-ROM Leser + +Sun Jan 4 15:26:25 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.79 + Erste Version einer UID Verwaltung die fuer Solaris 9 USCSI gebraucht wird + +Fri Jan 2 16:05:57 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.78 + Erste Version die mit Volume Management arbeitet + +Fri Jan 2 16:05:21 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.271 + Version -> 2.01a23 + +Fri Jan 2 16:05:06 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.16 + Hack fuer fd == -1 -> Kein Zugriff auf LW -> '?' statt '*' + +Tue Dec 30 14:20:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.270 + Schreibfehler will not not Korrigiert + +Mon Dec 29 15:25:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.90 + Bessere Beschreibung und Beispiel fuer -setdropts driveropts= + +Wed Dec 24 11:51:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.152 + Hinweis auf RAW bei nicht funktionierendem CUE Sheet + +Tue Dec 23 13:48:33 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.269 + Version -> 2.01a21 + Hack fuer POSIX_PRIORITY_SCHEDULING Bug (wir brauchen root Rechte um die Pri zu verringern) + +Sun Dec 21 14:29:21 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.89 + Neuer Absatz ueber ATAPI auf erster Seite. + +Thu Dec 18 17:10:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.87 + Aehnlicher Text wie in cdrecord.c wenn !defined(IS_SCHILY_XCONFIG) + +Thu Dec 18 17:10:26 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.268 + Neuer Text fuer modifizierte Versionen ohne Support + +Thu Dec 18 17:09:41 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.88 + .sp verschoben auf Wunsch von Eric Raymond + +Tue Dec 16 00:42:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.267 + Security Test Ausgabe nun auch ohne Root Zugriff sichtbar + +Mon Dec 15 16:40:59 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.266 + Ausgabe des Resultats des Security Checks + +Mon Dec 15 09:19:24 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.151 + Copyright -> 2003 + +Mon Dec 15 09:18:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.150 + Ein DVD Brenner wird nun auch erkannt wenn er nur MMC-3 und nicht MMC-2 konform ist + Hinweis auf ftp://ftp.berlios.de/pub/cdrecord/ProDVD/ + +Mon Dec 15 07:32:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.265 + comexit(0); nach "erstem" -force blank unit entfernt damit auch mit dem Ricoh-5125 Medien erweckt werden koennen + +Thu Dec 11 12:59:54 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.30 + #ifdef __SCG_COMPAT_ zum enablen von info/ident/revision -> vendor_info/prod_ident/prod_revision + +Thu Dec 11 12:55:42 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.15 + * scsi_cdr.c 1.135 + info -> vendor_info, ident -> prod_ident, revision -> prod_revision + +Wed Dec 10 00:42:39 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.11 + Hinweis auf http://bootcd.narod.ru/ + +Wed Dec 10 00:40:49 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.264 + Hinweis auf ftp://ftp.berlios.de/pub/cdrecord/ProDVD/ + +Wed Dec 10 00:19:03 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.263 + Version -> 2.01a20 + FIFO Abschalten wenn fifosize < 2*bufsize + +Tue Dec 9 20:52:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.87 + ..sp -> .sp Schreibfehler + +Sun Nov 30 13:50:31 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.10 + schcgeck funktioniert nun, kein DMAresid und max sense_count 18 + +Sun Nov 30 00:00:01 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.7 + * readcd.c 1.62 + #include <io.h> auch fuer DJGPP + +Sat Nov 29 23:36:39 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.9 + Srb.Type.ExecSCSICmd.SenseLen = DEF_SENSE_LEN; -> Srb.Type.ExecSCSICmd.SenseLen = (SENSE_LEN+2); + +Sat Nov 29 23:11:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.61 + Version -> 2.01a20 + +Sat Nov 29 23:10:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.6 + setmode(fileno, O_BINARY) auch fuer DJGPP + +Sat Nov 29 23:10:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.60 + #include <io.h> fuer __CYGWIN32__/__EMX__ + setmode(fileno, O_BINARY) auch fuer DJGPP + +Sat Nov 29 23:03:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.8 + Sense_len & sense_count korrekt beachten + SS_ERR -> vor die invalid Device & Cannot Select Bus cases im switch in send_cmd() + +Sat Nov 29 22:28:57 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.7 + Schreibfehler is statt if beseitigt + +Sat Nov 29 19:11:41 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.24 + Return (0) statt -1 bei FATAL Error in send_cmd() wenn kein gueltiges Target gesetzt ist + +Sat Nov 29 19:10:48 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.6 + Neuer AspiLoaded Counter fuer mehrfaches Oeffnen + +Sat Nov 29 19:06:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.30 + Return (0) statt -1 bei FATAL Error in send_cmd() wenn kein gueltiges Target gesetzt ist + SS_ERR mit cp->SRB_TargStat != 0 ist nun SCG_NO_ERROR + AspiLoaded ist nun integer Counter damit mehrere open()s moeglich sind + +Sat Nov 29 19:04:36 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.5 + Return (0) statt -1 bei FATAL Error in send_cmd() wenn kein gueltiges Target gesetzt ist + SS_ERR mit Srb.Type.ExecSCSICmd.TargStat != 0 ist nun SCG_NO_ERROR + +Sat Nov 29 18:58:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.4 + Cstyle + +Sat Nov 29 18:30:44 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.3 + Umbau auf _go32_dpmi_allocate_real_mode_callback_retf() + +Fri Nov 28 10:25:15 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.2 + Callback Funktion neu + +Fri Nov 28 02:33:18 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.43 + scsi-dos.c neu + +Fri Nov 14 10:55:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-dos.c 1.1 + date and time created 03/11/14 10:55:14 by joerg + +Sun Nov 2 23:50:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.46 + fifo_percent() fragt nun (sp == NULL) ab um festzustellen of der FIFO aus ist + +Wed Oct 29 15:33:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.14 + strcatl()/concat()/*execl() casten nun NULL im letzten Arg nach (char *)NULL + +Wed Oct 1 00:39:23 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.156 + Kommentar ueber minimale FIFO Groesse + +Sun Aug 24 13:15:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.86 + driveropts in /Etc/default/cdrecord dokumentiert + +Tue Jul 22 21:43:08 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.262 + Version -> 2.01a17 + +Mon Jul 21 00:06:31 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.155 + * cdrecord.1 1.85 + * cdrecord.c 1.261 + Neue Option ts= + +Fri Jul 18 10:04:20 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.59 + Version -> 2.01a17 + Teilweise #ifndef EXTVERS -> #ifdef CLONE_WRITE fuer genauere Beschreibung des Kodes + +Fri Jul 18 10:03:04 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.134 + Kommentar Hinweis in cdr_underrun() + +Fri Jul 11 11:43:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.84 + Schreibfehler + +Sun Jul 6 00:04:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.23 + EIO statt EINVAL damit Scan fuer Targets > 7 klappt + +Sat Jun 21 21:42:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.77 + Workaround fuer Solaris 8 x86 Bug: DKIOCINFO liefert 256 kB DMAsize aber nur 68 kB geht bei ATAPI & DMA + +Sat Jun 21 19:42:26 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.58 + Neue Option -factor + +Fri Jun 20 22:47:08 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.57 + Neue Option ts= fuer Transfer size + +Fri Jun 20 22:32:59 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.56 + Residual count auswerten beim Lesen + +Fri Jun 20 22:21:33 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.55 + prstats_silent() Prototyp neu + Versuch damit klarzukommen dasz einige BS (UnixWare) nicht mit odd byte DMA bei ATAPI klarkommen (READ FULL TOC) + Ausgabe aller Lead out startzeiten bei -clone (READ FULL TOC) + Geschwindigkeitsangaben beziehen sich auf 1000 Byte == 1 kb + Hack to write empty disks geht mit end == 1 statt end == 0 + +Tue Jun 17 19:23:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.83 + Schreibfehler + +Tue Jun 17 19:18:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.22 + samples -> nsamples wegen samples() Makro und K&R C + +Sat May 31 21:58:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-amigaos.c 1.5 + Neue Version von Thomas Langer + +Sat May 31 19:41:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-amigaos.c 1.4 + Eingerueckt nach cstyle + +Sat May 31 18:34:37 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.260 + GPL Hinweise besser formuliert, Schreibfehler in usage() beseitigt + +Sat May 31 18:10:38 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.82 + Schreibfehler berichtigt & -format dokumentiert + +Sat May 31 18:09:46 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.21 + Fix fuer fehlerhafte Erkennung von *.inf Dateien die Meldung 'WARNING: Stdin is connected to a terminal.' verursacht + +Fri May 16 13:02:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.13 + js_snprintf(devname, sizeof(devname), device); -> js_snprintf(devname, sizeof(devname), "%s", device); + +Wed May 14 18:59:12 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.259 + CD-Text -text Aktivierung durch trackp[MAX_TRACK+1].flags |= TI_TEXT + Kein CD-text mehr wenn track[0].flags & TI_TEXT schon gesetzt (durch textfile=) + +Wed May 14 18:57:53 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.17 + CD-Text aus CDTEXTFILE nur noch wenn trackp[MAX_TRACK+1].flags & TI_TEXT + +Wed May 14 18:56:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.81 + Neue erweiterte CD-Text Behandlung beschrieben + +Wed May 14 02:24:17 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.258 + Version -> 2.01a15, Diverse Umstellungen damit tracks == 0 Abfragen bei cuefile=xxx korrekt behandelt werden + +Wed May 14 02:21:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.5 + while(pp) -> for (; pp; pp = pp->x_next) damit continue bei x_name == NULL nicht zur Endlosschleife wird + +Tue May 13 23:26:57 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.80 + speed= Behandlung besser erklaert und Schreibfehler + +Tue May 13 23:26:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.16 + TI_SWAB bei FILE ... WAVE setzen + +Tue May 13 13:07:03 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.4 + pp->x_name == NULL voer strcmp geaendert + +Tue May 13 13:05:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.3 + Neue Knoten korrekt in Liste ein und aushaengen + +Mon May 12 02:17:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.149 + Support fuer TM_QUADRO/TM_ALLOW_COPY neu + Hack fuer CUE Sheet Handling mit MODE2/CDI trackp[i].dbtype == DB_RAW + Fuer Lead-In/Lead-Out werden nun die Bits fuer Datengroesse wegmaskiert + +Mon May 12 01:39:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.257 + setleadinout() setzt nun trackp[tracks+1].tracktype aus trackp[tracks].tracktype + +Mon May 12 01:38:03 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.15 + Erste funktionierende Version + +Mon May 12 00:26:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvdplus.c 1.8 + Canot -> Cannot Schreibfehler beseitigt + +Mon May 12 00:25:29 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.154 + parsecue()/fparsecue() neu + +Mon May 12 00:22:57 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.256 + Version -> 2.01a14, Neue Option cuefile=, Kein Aufruf von checkdsize() wenn tracks == 0 (tsize == -150) + +Mon May 12 00:20:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.79 + einfache erste cuefile= Doku + +Sun May 11 21:47:29 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.153 + TI_QUADRO & is_quadro() neu + +Sun May 11 21:46:53 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.c 1.2 + Schutz gegen Coredump wenn pp->x_name == NULL + +Sat May 10 16:15:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.14 + Erster Ansatz fuer parse_file() + +Sat May 10 15:05:46 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.13 + struct state neu + cueopen()/neednextitem()/needword()/needitem()/checkextra()/cueabort() neu + +Fri May 9 10:10:42 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.12 + keyw_t Arrays -> LOCAL + +Fri May 9 10:08:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.11 + Parser Funktionen -> LOCAL + +Fri May 9 10:00:21 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.10 + Erster Ansatz zum weiteren parsieren der Keywort Zeilen mit den Funktionen parse_*() + +Fri May 9 09:58:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.9 + #include cdtext.h vor cdrecord.h wegen gettextptr() und den Typ textptr_t + +Fri May 9 09:57:08 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.20 + * cdrecord.h 1.152 + gettextptr() ist nun nicht mehr LOCAL + +Fri May 9 09:56:24 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.h 1.4 + #define CDTEXT_H fuer Erkennung dasz cdtext.h includiert wurde + +Thu May 8 20:13:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.9 + Umgestellt fuer mehr "Ordnung" + +Thu May 8 19:57:21 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.8 + Definitionen fuer alle Schluesselworte + +Thu May 8 19:44:42 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.7 + getlocal() beseitigt, parsecue()/fparsecue() neu + +Thu May 8 19:38:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsiopen.c 1.94 + js_snprintf(errs, slen, scgp->errstr) -> js_snprintf(errs, slen, "%s", scgp->errstr) + +Thu May 8 19:38:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.148 + get_speeds_plextor() geht nicht mit alten LW, daher Ausfuerung im silent Mode + +Thu May 8 00:45:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.6 + Reihenfolge der Keyworte Kommentar + +Wed May 7 23:46:01 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.151 + * wm_packet.c 1.22 + * fifo.c 1.45 + * cdrecord.c 1.255 + Umbau auf 'xio' + +Wed May 7 20:31:31 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * xio.h 1.1 + * xio.c 1.1 + date and time created 03/05/07 19:31:31 by joerg + +Tue May 6 23:57:09 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.150 + * cdrecord.1 1.78 + * cdrecord.c 1.254 + -abort Option neu + +Tue May 6 19:12:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.5 + Kommentar verbessert, lookup() mit table Parameter + +Tue May 6 00:35:47 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.4 + Kommentar verbessert + +Tue May 6 00:23:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cue.c 1.3 + Umbau auf Makefilesystem, ungetline()/getlocal() neu + +Sun May 4 18:41:33 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.77 + Beschreibung der Audio Kopie aus Pipe + +Sun May 4 18:36:46 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.253 + Version -> 2.01a13 + +Sun May 4 18:35:19 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.149 + * cdrecord.c 1.252 + * auinfo.c 1.19 + Neue Funktion auinfosize() fuer AudioCDs aus Pipe Brennen + +Sun May 4 15:46:38 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.251 + Neue Funktion opentracks() und Umstellung des Trackparsing + +Sun May 4 15:18:21 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.44 + STDIN wird nicht mehr geschossen damit Audio "On the Fly" moeglich wird + +Sun May 4 15:16:43 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.148 + Neues Track Flag TI_USEINFO, tracktype/dbtype nun Uchar + +Sun May 4 12:52:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.250 + setuid(getuid()) nachdem alle root Dinge erledigt sind (hoffentlich) + +Sat May 3 20:09:17 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.54 + * scsitransp.c 1.86 + scg_fprascii()/scg_prascii()/scg_sprascii() neu + +Sat May 3 19:39:32 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.249 + gracewait setzt nun didgrace auf TRUE um doppeltes Warten zu vermeiden + +Fri May 2 22:49:20 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.35 + Debug error() beseitigt + +Fri May 2 22:46:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.34 + xpopen() neu damit suid root Binaries gehen, denn /etc/scsi/pdiconfig geht nicht wenn euid != uid + +Tue Apr 29 22:59:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.248 + Version -> 2.01a11 + +Tue Apr 29 20:59:54 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.247 + * cdrecord.1 1.76 + Neue Optionen -xa/-xamix und -multi/-mode2/-xa1/-xa2/-cdi korrigiert + +Tue Apr 29 20:41:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.147 + Support fuer TAO -mode2 + +Tue Apr 29 20:40:26 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.147 + Definitionen fuer Daten Sektor Typen + +Tue Apr 29 00:27:20 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.146 + Bessere Ausgabe fuer formatierte RW Medien + +Tue Apr 29 00:26:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.7 + Ausgave des Current Profile auf separater Zeile + +Wed Apr 23 23:25:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvdplus.c 1.5 + Ungebrauchte Variablen beseitigt + +Wed Apr 23 23:20:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.133 + read_track_info() Bug gefixt (type Bits waren in cmd_cdb[2] statt cmd_cdb[1]) + +Wed Apr 23 23:19:24 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.246 + gracewait() umstrukturiert + +Wed Apr 23 23:18:13 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.6 + * drv_mmc.c 1.145 + * cdrecord.h 1.146 + print_profiles() neu + +Tue Apr 22 22:36:02 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.245 + Return Code von (*dp->cdr_init)(scgp, dp) auswerten + +Tue Apr 22 19:08:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.244 + raise_fdlim versucht nun nicht mehr z.B. ein Limit von 256 auf 109 zu "erhoehen". + +Tue Apr 22 17:47:29 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.144 + Fehlendes " ergaenzt + +Tue Apr 22 17:46:28 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.143 + Bessere Fehlermeldung fuer get next writable address auf formatierte CD-RW + +Tue Apr 22 17:42:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.243 + Mehr Fehlermeldungen wenn in der Hauptschleife Fehler auftreten. + +Tue Apr 22 01:08:46 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.242 + Version -> 2.01a11, gracewait() mit didgrace Parameter fuer Ausgabe ohne Warten + +Mon Apr 21 15:49:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.241 + Format Code mit #ifdef DRV_DVD auskommentiert + +Mon Apr 21 15:40:04 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.142 + CL_TYPE_* #defines neu fuer scsi_close_tr_session() + +Mon Apr 21 15:39:13 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.240 + -format & BOOL gracedone neu + +Mon Apr 21 15:23:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.145 + * scsi_cdr.c 1.132 + request_sense_b()/reserve_tr_rzone() neu + +Mon Apr 21 14:22:51 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.239 + Umbau auf gracewait() + +Sun Apr 20 16:26:57 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.5 + get_format_capacities() neu + +Sun Apr 20 16:22:26 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.141 + read_track_info() mit erweiterten Parametern (Type) -> TI_TYPE_TRACK + +Sun Apr 20 16:21:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.131 + read_track_info() mit erweiterten Parametern (Type), read_rzone_info() aus drv_dvd.c durch read_track_info() + +Sun Apr 20 16:20:40 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.144 + F_FORMAT neu, WM_FORMAT neu, DSF_DVD_PLUS_R/DSF_DVD_PLUS_RW/DSF_NEED_FORMAT neu + read_track_info() mit erweiterten Parametern (Type), read_rzone_info() aus drv_dvd.c durch read_track_info() + get_format_capacities()/read_format_capacities() neu + +Sun Apr 20 15:52:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.9 + struct disk_info um dbit & bg_format_stat erweitert + +Sun Apr 20 15:13:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.29 + struct scsi_format_header um immed/tryout/ipattern Bits erweitert + struct scsi_format_cap_header neu + struct scsi_format_cap_desc neu + struct scsi_cap_data neu + +Sun Apr 20 15:04:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsicdb.h 2.18 + NACA Bit im Control Byte neu + +Fri Apr 18 16:53:04 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.106 + * drv_mmc.c 1.140 + * cdrecord.h 1.143 + * scsi_cdr.c 1.130 + read_dvd_structure() nun mit addr und layer Parameter + +Fri Apr 18 16:51:11 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.4 + Unbenutze & Uninitialisierte Variablen beseitigt + +Thu Apr 17 23:13:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.34 + DVD+ Treiber neu + +Thu Apr 17 23:09:29 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.139 + Treibertexte besser eingerueckt + Umleitung auf DVD+ Treiber bei DVD+ Medium + Aufruf der dp->cdr_identify(scgp, dp, scgp->inq) Routine bei Weiterleitung auf DVD Treiber + +Thu Apr 17 09:45:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.69 + * drv_philips.c 1.67 + * cdr_drv.c 1.33 + * cdrecord.h 1.142 + * drv_simul.c 1.46 + * drv_dvd.c 1.105 + * drv_jvc.c 1.79 + * drv_7501.c 1.14 + * drv_mmc.c 1.138 + cdr_format() Funktion neu + +Thu Apr 17 02:32:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.137 + load_media() fuer get_curprofile() im Silent Mode, wenn es ein CD Brenner ist dann wird nicht der CD-ROM Treiber returniert + +Thu Apr 17 01:10:51 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.136 + SCSI-3/MMC-3 medien Tests neu um DVD+ zu erkennen + +Thu Apr 17 00:04:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.3 + Vermeiden von pname(profile) ohne #defne DRV_DVD + +Wed Apr 16 23:40:46 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.135 + mmc_getval() weiter nach hinten - nach Korrektur der Inquiry Daten fuer ATAPI + +Wed Apr 16 22:49:41 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.134 + Treiber ID Text (Kommentar) verbessert + +Wed Apr 16 22:42:59 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.68 + Cue sheet Option auf 3 setzen + +Wed Apr 16 22:40:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.75 + Hinweis auf mkisofs -print-size bei SAO/RAW + +Wed Apr 16 22:28:03 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.32 + SCSI-3/mmc-3 Support fuer DVD + DDCD Erkennung mit get_proflist() + +Wed Apr 16 22:25:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.8 + struct rzone_info um lra_v erweitert + struct mmc_performance_header / struct mmc_performance / struct mmc_exceptions / struct mmc_write_speed / struct mmc_streaming neu + +Wed Apr 16 22:01:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.141 + get_proflist()/get_wproflist() aus scsi_mmc.c neu + +Wed Apr 16 22:00:33 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.2 + get_conflen()/get_profiles()/get_proflist()/get_wproflist() neu + +Wed Apr 16 00:49:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.133 + get_speeds_plextor() komplett in die Statistik Funktion verlagert + +Wed Apr 16 00:28:09 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_mmc.c 1.1 + date and time created 03/04/15 23:28:09 by joerg + +Wed Apr 16 00:28:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.140 + scsi_mmc.c Definitionen neu + +Wed Apr 16 00:12:54 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.132 + Trebertabellen aufgeraeumt + +Tue Apr 15 18:57:54 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.139 + track_base(tp) Makro repariert (tp)->track statt (tp)->trackno + +Tue Apr 15 10:01:43 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.104 + TAO Fake beseitigt + +Sun Apr 13 21:54:15 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.67 + #include timedefs.h fehlte + +Sun Apr 13 18:54:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.66 + Erste SAO Implementierung (ohne MCN/ISRC/multi-session) + +Sun Apr 13 17:15:15 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.103 + * drv_simul.c 1.45 + * drv_jvc.c 1.78 + * drv_mmc.c 1.131 + * drv_7501.c 1.13 + * cdrecord.c 1.238 + * cdrecord.h 1.138 + * drv_philips.c 1.66 + cdr_abort_session() neu + +Sun Apr 13 17:10:44 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.130 + "Selected write speed:" -> "Last selected write speed:" + +Sun Apr 13 13:59:26 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.129 + Intelligenteres scsi_load() kennt nun CDR_CADDYLOAD + +Sun Apr 13 13:54:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.65 + Yamaha CDR-100 nun mit scsi_load() + +Sun Apr 13 13:36:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.237 + Version -> 2.01a10, Neue Funktion print_drflags() + +Sun Apr 13 13:35:26 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.137 + Kommentar verbessert + +Sun Apr 13 12:28:01 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.236 + * scsi_cdr.c 1.128 + scsi_load()/scsi_unload() nun mit korrektem Return Wert (int statt BOOL) und Auswertung des Return Wertes in load_media()/unload_media() + +Fri Apr 11 15:31:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.129 + * drv_7501.c 1.12 + (*dp->cdr_gen_cue)() Aufruf nun ueber Pointer + +Fri Apr 11 15:27:44 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.102 + * drv_simul.c 1.44 + * drv_mmc.c 1.128 + * cdr_drv.c 1.31 + * cdrecord.h 1.136 + * drv_7501.c 1.11 + (*dp->cdr_send_cue)() nun mit cdr_t * Parameter + +Fri Apr 11 15:18:57 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_7501.c 1.10 + * drv_simul.c 1.43 + * drv_philips.c 1.64 + * drv_dvd.c 1.101 + * drv_mmc.c 1.127 + * drv_sony.c 1.65 + * drv_jvc.c 1.77 + * cdrecord.h 1.135 + * cdrecord.c 1.235 + Neue Funktion (*cdr_gen_cue)() + +Fri Apr 11 01:25:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.126 + get_speeds_plextor() nun mit 3 int * Parametern, Ausgabe der Maximalen Brenngeschwindigkeit in stats_mmc() + +Fri Apr 11 00:53:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.234 + * cdrecord.h 1.134 + is_sao() & TI_SAO neu, checktsize() ueberprueft nun ob ein Track mit unbekannter Laenge in SAO/RAW mode vorhanden ist und bricht ab + +Thu Apr 10 21:18:42 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.63 + * drv_simul.c 1.42 + * drv_7501.c 1.9 + * cdr_drv.c 1.30 + * cdrecord.h 1.133 + * drv_jvc.c 1.76 + * drv_dvd.c 1.100 + * drv_sony.c 1.64 + * scsi_cdr.c 1.127 + * drv_mmc.c 1.125 + * cdrecord.c 1.233 + cdr_check_recovery()/cdr_recover()/cdr_close_session() nun mit cdr_t * Parameter + +Thu Apr 10 19:19:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.132 + Kommentar eingerueckt + +Thu Apr 10 19:15:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.232 + * cdrecord.h 1.131 + * drv_sony.c 1.63 + * drv_simul.c 1.41 + * drv_philips.c 1.62 + * drv_mmc.c 1.124 + * drv_7501.c 1.8 + * drv_jvc.c 1.75 + * drv_dvd.c 1.99 + cdr_init() neu, cdr_speed_select() nun ohne "dummy" Parameter + +Thu Apr 10 15:32:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.123 + get_speeds_plextor() neu + +Sun Apr 6 15:49:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.74 + Neue driveropts= speedread/singlesession/hidecdr + +Sun Apr 6 15:48:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.231 + (*dp->cdr_set_speed_dummy)() Aufruf bei -setdropts zwischen cdr_opt1() und cdr_opt2() + +Sun Apr 6 15:45:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.122 + Support fuer Plextor PowerRec, SpeedReeed, SongleSession, HideCDR + +Sun Apr 6 02:19:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.230 + * cdrecord.h 1.130 + #defines und Auswertung fuer CDR_SINGLESESS/CDR_HIDE_CDR/CDR_SPEEDREAD neu + +Sat Apr 5 22:35:50 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.129 + * cdrecord.c 1.229 + * cdrecord.1 1.73 + Neue Option -setdropts + +Sat Apr 5 20:51:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.121 + mmc_load/mmc_unload() auskommentiert + +Sat Apr 5 20:46:51 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.120 + opt2_mmc() neu und Kode aus open_session_mmc() dorthin bewegt + +Sat Apr 5 20:43:36 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.126 + * cdrecord.c 1.228 + Bessere Buffer underrun Erkennung und Beschreibung + +Sat Apr 5 15:49:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.62 + * drv_mmc.c 1.119 + * drv_simul.c 1.40 + * drv_7501.c 1.7 + * cdrecord.c 1.227 + * drv_philips.c 1.61 + * drv_jvc.c 1.74 + * cdrecord.h 1.128 + * drv_dvd.c 1.97 + (*dp->cdr_opt2)(scgp, dp) neu + +Sat Apr 5 15:37:12 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.226 + Buffer Underrun Vorhersage verbessert (kein loeschen am Trackanfang & zusaetzlicher Test auf leres RAM) + +Sat Apr 5 01:42:33 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.118 + Read Burn Proof Counter fuer Plextor + +Fri Apr 4 23:48:28 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.33 + Reset Support neu + +Fri Apr 4 00:44:59 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.225 + -packet impliziert nun nicht mehr TAO + +Fri Apr 4 00:35:13 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_7501.c 1.6 + cw7501__do_cue() nun korrekt LOCAL + +Fri Apr 4 00:30:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.18 + * subchan.c 1.16 + trackp->tracktype & TOC_MASK wegen TOCF_DUMMY/TOCF_MULTI + +Fri Apr 4 00:29:09 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.61 + * drv_simul.c 1.39 + * drv_7501.c 1.5 + * drv_philips.c 1.60 + * cdrecord.h 1.127 + * cdrecord.c 1.224 + * drv_mmc.c 1.117 + * drv_jvc.c 1.73 + * drv_dvd.c 1.96 + cdr_open_session()/cdr_fixate() ohne multi/dummy Parameter -> track[0].tracktype + +Thu Apr 3 22:49:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.72 + * drv_dvd.c 1.95 + * wm_packet.c 1.21 + * cdrecord.c 1.223 + Casting wegen Signed/Unsigned Arithmetik bei ANSI C + +Thu Apr 3 22:32:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.60 + * drv_7501.c 1.4 + * drv_simul.c 1.38 + * drv_dvd.c 1.94 + * drv_philips.c 1.59 + * drv_mmc.c 1.116 + * drv_jvc.c 1.71 + * cdrecord.c 1.222 + * cdrecord.h 1.126 + cdr_open_session()/cdr_fixate() Treiberinterface nun ohne toctype Parameter -> trackp[0]->tracktype + +Thu Apr 3 20:51:34 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.43 + int -> Uint wegen Ansi C Vergleich + +Thu Apr 3 20:46:46 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * clone.c 1.6 + first/last int -> Uint wegen Ansi C Vergleich + +Thu Apr 3 20:42:01 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.15 + j int -> Uint wegen Ansi C Vergleich + +Thu Apr 3 18:16:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.221 + Neue Option -lock + prtimediff() -> misc.c + Version -> 2.01a09 + +Thu Apr 3 18:15:00 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.72 + Neue Option -lock + +Thu Apr 3 18:14:43 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * misc.c 1.3 + prtimediff() aus cdrecord.c neu + +Thu Apr 3 18:14:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.115 + int/Uint Vergleiche gecastet + test auf tracksize < 0 vor do_cue() + Versuch zu erreichen dasz is_packet(trackp) nicht mehr is_tao(trackp) impliziert + +Thu Apr 3 18:11:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.125 + F_DLCK & prtimediff() neu + +Thu Apr 3 18:11:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_7501.c 1.3 + Support fuer SAO neu + +Sun Mar 30 22:16:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_7501.c 1.2 + Schreibsupport fuer TAO + +Sun Mar 30 13:50:02 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.220 + * drv_mmc.c 1.114 + Eingerueckt nach cstyle + +Sat Mar 29 20:27:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.32 + Auswertung von scbp->sc_comp_code und Setzten von sp->error + +Thu Mar 27 12:11:17 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.54 + meshpoints=# Option neu + +Thu Mar 27 01:15:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.219 + 2002 -> 2003 + +Thu Mar 27 01:03:48 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.29 + cw7501 neu + +Thu Mar 27 01:02:47 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_7501.c 1.1 + date and time created 03/03/27 01:02:47 by joerg + +Thu Mar 27 00:53:40 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.218 + Version -> 2.01a07, Unterdrueckung von "Warning: blockdesc secsize %d differs from cap secsize %d\n" wenn scgp->cap->c_bsize == 0 + +Thu Mar 27 00:45:34 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.124 + Eingerueckt nach cstyle + +Thu Mar 27 00:43:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.113 + mmc_load()/mmc_unload() mit 2. Parameter cdr_t * + +Tue Mar 25 18:48:41 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-qnx.c 1.2 + sccsid -> __sccsid + +Mon Mar 24 23:25:04 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.217 + Version -> 2.01a06, Handler fuer SGIHUP/SIGTERM, cdr_underrun() neu + +Mon Mar 24 23:23:38 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.125 + * cdrecord.h 1.123 + cdr_underrun() neu + +Mon Mar 24 13:01:28 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.31 + Beseitigung von fdesc[MAX_SCG][MAX_TGT][MAX_LUN] und Verkleinerung von sdidevs[scg][tgt][lun] + Nun kann wirklich scg_open() mehrmals aufgerufen werden. + +Sun Mar 23 21:10:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.30 + valid/atapi/initiator -> flags mit SDI_* Bit #defines + +Sun Mar 23 17:33:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.29 + Besseres Verhalten fuer scgcheck + +Sun Mar 23 15:14:23 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.28 + Eingerueckt wegen cstyle(1) + +Sun Mar 23 14:12:01 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.42 + Support fuer QNX neu + +Sun Mar 23 14:11:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-qnx.c 1.1 + date and time created 03/03/23 14:11:14 by joerg + +Thu Mar 6 16:39:42 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.42 + faio_wait_on_buffer() mit Prototype implementierung wegen SCO cc + +Thu Mar 6 16:27:52 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.71 + Beschreibung fuer -xa1 -xa2, ... berichtigt + +Fri Feb 7 12:34:37 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.70 + Schreibfehler beseitigt + +Sun Feb 2 14:13:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.12 + Umgestellt, damit es auch ohne rcmd() geht + +Tue Jan 28 01:19:39 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.112 + Workaround fuer LG TAO Audio Formware bug: audio_pause_len = 150 + +Tue Jan 7 14:09:28 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.124 + Ausgabe Save/Set Modepages auch auf stderr wie Rest der Zeile + +Tue Jan 7 14:08:43 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.111 + set_mode_params() ist BOOL, daher ist Abfrage auf < 0 falsch + +Tue Dec 24 16:28:38 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.69 + Version -> 2.0 + +Tue Dec 24 14:16:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.216 + Mail Adresse -> schilling@fokus.fhg.de + Vermeidung von "Cannot write CD's >= 100 minutes.\n" bei DVDs + +Mon Dec 16 22:26:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.68 + Mailing Lists geupdated, Hinweis auf cddb= bei den cdda2wav Beispielen + +*************** Release 2.0 ******************* + +Sat Nov 30 17:43:51 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * readcd.c 1.53 + * cdrecord.c 1.215 + Version -> 2.0 + +Sat Nov 30 16:11:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.214 + DVD-Pro Check for Tracksize-known only if ntracks > 0 + +Sat Nov 30 13:01:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.110 + Allow Medium removal after load Media for DVD/CD recognition as drecord -checkdrive would otherwise lock the tray if it has been open before + +Sat Nov 30 12:55:17 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-osf.c 1.25 + Debug output with SCSI Status Byte + +Fri Nov 22 17:55:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.67 + RSH= und RSCSI= documented for ssh(1) RSCSI + +Fri Nov 22 17:40:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.11 + Support for non-root rcmd() and ssh(2) + +Fri Nov 22 17:35:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.41 + AmigaOS Support with ix_vfork()/ix_vfork_resume() and separate var buf_idx_reader for vfork() + +Thu Nov 21 22:28:57 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.213 + New Option minbuf= + +Thu Nov 21 22:23:10 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.66 + minbuf= Option new + +Tue Nov 19 19:13:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsiopen.c 1.93 + Fix for Coredump with dev=/dev/rsr1c:@,0 + +Sun Nov 10 19:18:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.36 + Orange Forum Embargo Warning only if mp->msf_min == 97 for DVDs + +Mon Nov 4 18:12:16 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.40 + close(f) /dev/zero oly if /dev/zero has been opened + +Sun Nov 3 16:32:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.123 + * cdrecord.h 1.122 + write_xscsi()/seek_scsi()/seek_g0()/seek_g1() new + +Sat Nov 2 22:11:55 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.212 + Version -> 1.11a40, _POSIX_MEMLOCK/_POSIX_PRIORITY_SCHEDULING Test POSIX 2001 conformant + +Sun Oct 27 15:19:29 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.211 + New Wait Feature free the IDE Busses if Source&Destination are on the same cable (use -immed) + +Sun Oct 27 14:57:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.65 + New Wait (usleep) Feature for -immed documented + +Sun Oct 27 14:42:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.121 + New Flag RF_WR_WAIT to actively free the IDE Busses via usleep() + +Sun Oct 27 02:26:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.210 + * wm_packet.c 1.20 + * drv_jvc.c 1.70 + Change from trackp->padsize ->trackp->padsecs + +Sun Oct 27 02:02:38 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.120 + Change from trackp->padsize ->trackp->padsecs + New Sektor based Makros Sminutes(s)/Sseconds(s)/Shseconds(s)/Sframes(s) + +Sun Oct 27 01:20:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.64 + Better docukmentation for padsize= + +Sat Oct 26 23:13:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.122 + Text Generic mmc2 DVD -> Generic mmc2 DVD-R/DVD-RW + +Sat Oct 26 20:21:15 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.19 + Support printing the fill ratio of the drive buffer and the actual write speed + +Fri Oct 25 15:06:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.109 + ATIP printinf for speed better -> %2d (reserved val %2d) + +Fri Oct 25 15:05:21 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.209 + pad_track() now shows Drive buffer fill% and speed + Verbose prinrting for write_track_data() and pad_track() unified + +Fri Oct 25 00:49:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.208 + Warning for cdrecord blank=fast if drive does not like -> Try cdrecord blank=all + write_track_data() now computes trackp->isecsize from trackp->isecsize to trackp->secsize + +Fri Oct 25 00:18:19 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.108 + BURN-Free was not used -> BURN-Free was never needed + +Fri Oct 25 00:06:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.107 + Test for 0xFF:0xFF/0xFF with dsp->ds_maxblocks == 716730 -> dsp->ds_maxblocks == 1166730 because we now use forceposivive in msf_to_lba() + +Thu Oct 24 23:47:23 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.106 + di_to_dstat() now always sets dsp->ds_first_leadin to allow 2. setting for Yamaha AudioMaster + +Wed Oct 23 22:46:02 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.207 + Version -> 1.11a39, Only cdrecord dev=help calls scg_help() no automatic printing if scg_open() fails + +Wed Oct 23 22:40:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.63 + Many changes tp prepare for 2.0 + +Wed Oct 23 22:21:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-ata.c 1.4 + Workaround for Linux Kernel design bug: CDROM_SEND_PACKET stes errno to EINVAL if Sense Key is "Invalid Command" + +Mon Oct 21 19:20:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.75 + /dev/sg* read loop again with 1000 loops but only if 'f' is a RAW device + Typo fixed + +Sun Oct 20 15:28:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.74 + sg_clearnblock() new to alow to clear O_NONBLOCK directly after open(.., ...|O_NONBLOCK) + +Sat Oct 19 22:04:23 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.206 + Version -> 1.11a38, Support for libscg Help + +Sat Oct 19 21:28:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsiopen.c 1.92 + * scsihack.c 1.41 + scg_help() Funktion new + +Sat Oct 19 21:27:21 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.85 + Version -> 0.7 + +Sat Oct 19 21:26:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.29 + * scsi-vms.c 1.32 + * scsi-unixware.c 1.27 + * scsi-sun.c 1.76 + * scsi-sgi.c 1.35 + * scsi-remote.c 1.10 + * scsi-osf.c 1.24 + * scsi-os2.c 1.22 + * scsi-openserver.c 1.30 + * scsi-next.c 1.31 + * scsi-mac-iokit.c 1.4 + * scsi-linux-sg.c 1.73 + * scsi-linux-pg.c 1.42 + * scsi-linux-ata.c 1.3 + * scsi-hpux.c 1.30 + * scsi-bsd.c 1.41 + * scsi-bsd-os.c 1.27 + * scsi-beos.c 1.21 + * scsi-apollo.c 1.4 + * scsi-amigaos.c 1.3 + * scsi-aix.c 1.35 + scgo_help() Funktion new + +Sat Oct 19 19:14:05 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.53 + Parameter tcomment new in __scg_help() + +Sat Oct 19 14:02:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.52 + Help functions new + +Fri Oct 18 17:25:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.72 + Modified Cleanup read() loop in sg_initdev() by request from Linus Torvalds + +Fri Oct 18 17:20:00 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.75 + open Warnung von error() auf js_fprintf((FILE *)scgp->errfile umgestellt + +Fri Oct 18 17:16:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsiopen.c 1.91 + * scsi-linux-ata.c 1.2 + * scsi-sun.c 1.74 + Allow unified dev=ATAPI, dev=ATAPI:, dev=USCSI, dev=USCSI: + +Sun Oct 13 21:40:59 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.71 + open(name, 2) -> O_RDWR.... + sg_initdev() with better loop to read possible rests from driver (requested by Linus Torvalds) + +Sun Oct 13 21:23:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.73 + * scsi-linux-pg.c 1.41 + open(name, 2) -> O_RDWR.... + +Sat Oct 12 13:53:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.11 + Initialize Testsector in encspeed() to make resulting speed independent from junk on the stack + +Thu Oct 10 23:43:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.205 + Change wording from DAO -> SAO + +Wed Oct 9 19:36:09 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.28 + New device types for Inquiry + +Wed Oct 9 19:35:44 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.84 + scg_fprintdev() New device types for Inquiry + +Tue Oct 8 00:57:50 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.26 + Handle EBUSY for multiple opens + +Mon Oct 7 22:19:15 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.10 + * cdrecord.h 1.119 + * cdrecord.c 1.204 + Verbose printing of the LEC encoding speed -> encspeed() + +Sat Oct 5 22:07:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.203 + call cdr_buffer_cap() in Silent mode to make sure buggy drives (CW-7585) will not print constantly error messages + +Sat Oct 5 18:07:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-ata.c 1.1 + date and time created 02/10/05 17:07:46 by joerg + +Sat Oct 5 17:48:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.70 + Support for CDROM_SEND_PACKET in scsi-linux-ata.c new + SCSI Timeout now may be distinguished from SCSI selection Timeout by implementing a workarounf for a Linux kernel bug + +Sat Oct 5 00:02:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.72 + Do not open all /dev/scg* devices if not in SCAN mode + ENXIO for USCSI means selection Timeout + +Fri Oct 4 23:59:05 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.31 + Warn for missing Scanbus, up to 26 IDE Controller from Chip.Dancy@hp.com + +Wed Oct 2 21:44:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.202 + Version -> 1.11a36, #ifdef HAVE_LIB_EDC_ECC to allow compilation without libedc + +Wed Oct 2 02:22:32 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.39 + Allow again compilation with #undef FIFO + +Wed Oct 2 00:54:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsiopen.c 1.90 + replace comma by semikolon + +Wed Oct 2 00:48:49 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.30 + gk_chan is Unsigned but there was a comparison <= 0 + scsi status scsi_sts now correct for ATAPI + +Sat Sep 28 20:36:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.105 + deflt_writemodes_mmc() now with fallback to SAO if TAO is not supported + +Sat Sep 28 14:53:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.201 + -force Wirkung auf RAW Speed nur noch bis maximal das was eine CPU kann + Neue environment Variable "CDR_FORCERAWSPEED" + +Sat Sep 28 14:46:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.9 + EDC_SCRAMBLE_NOSWAP #define in old libedc new + +Fri Sep 27 17:39:00 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.200 + Limit gracetime to 999, Do not use \b with wait time because seconds may use more than one column + +Fri Sep 27 16:40:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.37 + DVD max speed -> 1000 + +Fri Sep 27 14:33:00 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.199 + Drive current speed/Drive default speed/Drive max speed printing now with lverbose > 1 + Hint to Heiko with Encoding speed printing + +Fri Sep 27 14:30:18 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.104 + Max Speed in struct from 370 -> 372, + mmc_opthelp()/hasdrvopt()/get_justlink_ricoh() now with EXPORT + Bug with dp->cdr_dstat->ds_dr_cur_wspeed fixed, + set dp->cdr_speeddef/dp->cdr_speedmax from drive values + +Fri Sep 27 14:28:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.89 + Change to use new driveropts= method from drv_mmc.c + +Fri Sep 27 14:25:18 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.36 + Max Speed for CD from 370 -> 372 + +Thu Sep 26 03:06:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.121 + scsi_load()scsi_unload() now may be called with cdr_t * 0 + +Wed Sep 25 18:05:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.103 + scsi_blank()/scsi_close_tr_session()/scsi_flush_cache() with immed Flag + +Wed Sep 25 16:12:10 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.117 + * cdrecord.c 1.198 + * drv_simul.c 1.35 + * drv_philips.c 1.58 + * scsi_cdr.c 1.120 + * drv_dvd.c 1.88 + start/stop, load/unload, flush_cache with immed Parameter + +Wed Sep 25 14:22:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.69 + * drv_dvd.c 1.87 + * drv_mmc.c 1.102 + * cdr_drv.c 1.28 + * cdrecord.c 1.197 + * cdrecord.h 1.116 + blank() driver function now weith cdr_t * parameter for F_IMMED + +Wed Sep 25 13:52:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.196 + -immed new + +Wed Sep 25 13:51:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.195 + F_DVD -> TI_DVD (was wrong) + +Wed Sep 25 13:13:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.115 + F_DVD -> TI_DVD (was wrong), F_IMMED new + +Wed Sep 25 00:38:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.194 + * cdrecord.h 1.114 + * drv_sony.c 1.59 + * drv_simul.c 1.34 + * drv_philips.c 1.57 + * drv_mmc.c 1.101 + * drv_jvc.c 1.68 + * drv_dvd.c 1.86 + close_track()/fixate() enhanced by cdr_t * Parameter + +Tue Sep 24 21:28:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.100 + mmc_set_speed() new to allow drives that don't like speed=1 + +Tue Sep 24 18:40:42 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.193 + Version -> 1.11a35, Do not print Zeit/speed Statistics if writing did not yet start + +Tue Sep 24 18:36:56 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.119 + Modify speed printing to include CD/DVD Speed + +Mon Sep 23 15:42:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.33 + Simulate Next Writable Address (for TAO) + +Mon Sep 23 15:39:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.192 + Move Comment out of #ifdef DRV_DVD + +Mon Sep 23 15:17:56 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.191 + Fix Pregap handling for DVD (no 150 Sektors per Track) + +Sun Sep 22 01:35:18 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.113 + F_DVD new + +Sun Sep 22 00:11:57 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.85 + Set DVD Flag in driverstructure because it is now used + +Sat Sep 21 23:59:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.32 + Set DVD Flags, calculate DVD speed correctly, + correct real time spend in usleep() + +Sat Sep 21 01:33:16 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.190 + Version -> 1.11a34, Late check for tracks == 0 only if -fix was not used + +Fri Sep 20 01:58:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.17 + -auinfo should be superceede -scms / -copy + +Thu Sep 12 17:16:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.189 + Statistics order new and better, + Print new statistics even on abort + +Thu Sep 12 17:03:42 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.112 + New Flags RF_DID_STAT/RF_DID_CDRSTAT + +Thu Sep 12 16:42:57 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.56 + Modified -> reload_media() + +Thu Sep 12 15:52:20 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.99 + cdr_dstat->ds_dr_max_rspeed/cdr_dstat->ds_dr_cur_rspeed neu + cdr_dstat->ds_dr_max_speed/cdr_dstat->ds_dr_cur_speed -> cdr_dstat->ds_dr_max_wspeed/cdr_dstat->ds_dr_cur_wspeed + scsi_set_speed() with MMC-3 rotctl Parameter + +Thu Sep 12 15:47:01 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.188 + Version -> 1.11a33, ds_dr_max_speed -> ds_dr_max_wspeed + +Thu Sep 12 15:43:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.84 + * scsi_cdr.c 1.118 + * cdrecord.h 1.111 + scsi_set_speed() mit MMC-3 rotctl Parameter + +Thu Sep 12 14:37:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.98 + dsp->ds_flags with DSF_HIGHSP_ERA / DSF_ULTRASP_ERA + New Speed Tabels for HS and UHS RW media + atip_printspeed() new + Print A1 ATIP Werte also in hex + Modify ATIP printout for UHS CD-RW + +Thu Sep 12 13:34:49 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.187 + Driveropts print MMC,MMC-2,MMC-3 + -force now allows to write faster data in -raw Data + Checks for Ultra High speed CD-RW for old writers + Do not print average write speed if data size is unknown + +Thu Sep 12 13:27:10 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.117 + Enhancements for MMC-2 & MMC-3 in -prcap (mode Page 2A) + +Wed Sep 11 21:23:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.27 + MMC-2 & MMC-3 enhancements for Mode Page 2A + +Wed Sep 11 20:47:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.110 + CDR_MMC/CDR_MMC2/CDR_MMC3 new + +Wed Sep 11 15:13:20 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.14 + end = 0 for useless GCC Warning 'end' might be uninitialized + +Wed Sep 11 15:01:55 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.109 + trackp->dataoff/tracks/track/trackno -> Uchar + DSF_HIGHSP_ERA & DSF_ULTRASP_ERA new + CDR_ALLOC without top Bit for GCC Warning + +Wed Sep 11 14:59:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.83 + * auinfo.c 1.16 + Cast for trackp->track* -> Uchar + +Wed Sep 11 14:59:07 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.58 + Constant 0xFFFFFFFF with #ifdef for K&R/ANSI + +Sun Sep 1 23:43:15 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.186 + Print minimal Drive Buffer fill ratio + +Sun Sep 1 23:42:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.97 + DiskT@2 Support new + +Sun Sep 1 23:33:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.108 + Several new ds_* Vars for better Statistics + +Sun Sep 1 21:27:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.185 + cdrstats() now guesses Buffer underruns and prints average write speed + +Sun Sep 1 17:42:59 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.96 + cdr_stats() Function new + speed_select_mmc() with 2nd Parameter dp for FORCESPEED + driveropts=foesecpeed new + driveropts=tattooinfo new + driveropts=tattoofile=name new + hasdrvopt() fixed: missing break nach past recognised Option + +Sun Sep 1 16:50:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.184 + Buffer Cap print every 1 MB + +Fri Aug 30 13:57:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.183 + Version -> 1.11a32, CDR_DISKTATTOO new, (*dp->cdr_stats)(scgp, dp); for Burn-Free Statistics + +Fri Aug 30 13:42:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.107 + New driverinterfacefunction cdr_stats() + CDR_DISKTATTOO new + +Fri Aug 30 13:41:21 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.57 + * drv_simul.c 1.31 + * drv_philips.c 1.55 + * drv_jvc.c 1.67 + * drv_dvd.c 1.82 + New driverinterfacefunction cdr_stats() + +Thu Aug 29 21:40:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.56 + * drv_simul.c 1.30 + * drv_philips.c 1.54 + * drv_jvc.c 1.66 + * drv_dvd.c 1.81 + * cdrecord.h 1.106 + * cdrecord.c 1.182 + New Parameter cdr_t *dp for cdr_set_speed_dummy() for "forcespeed" + +Thu Aug 29 17:12:40 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mmcvendor.h 1.2 + link_counter is [2]. + +Mon Aug 26 17:47:17 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.95 + Turning... messages -> stdout + +Mon Aug 26 01:56:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.94 + JustLink Support new + +Mon Aug 26 01:22:08 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mmcvendor.h 1.1 + date and time created 02/08/26 00:22:08 by joerg + +Tue Aug 20 01:11:19 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.93 + mmc_opt1() new + Yamaha Audio Master Support new + Be more careful with test_write (-dummy) in deflt_writemodes_mmc() + Check driveropts= already in attach_mmc() and turn into flags + +Tue Aug 20 00:06:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.181 + Call dp->cdr_opt1() _before_ set speed/dummy and before the first Size Check + +Mon Aug 19 02:30:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.180 + Do not clear ds_cdrflags after attach() + +Mon Aug 19 01:12:18 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.179 + driveropts=help new in short usage() + +Mon Aug 19 00:45:49 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.105 + * drv_dvd.c 1.80 + * drv_simul.c 1.29 + * drv_jvc.c 1.65 + * drv_sony.c 1.55 + * drv_philips.c 1.53 + cdr_t->cdr_opt1() new + +Mon Aug 19 00:40:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.178 + dataoff = 16 as Default in autoaudio to allow cdrecord -raw to work without -data + +Mon Aug 19 00:34:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.177 + Call (*dp->cdr_opt1)(scgp, dp) for Yamaha Audio Master, then 2. Check for size + +Sat Aug 17 01:13:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.92 + Yamaha Audio Master recognition, Varirec in driveropts=help, Varirec recognition + +Sat Aug 17 00:52:44 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.104 + Calling sequence comment new + +Sat Aug 17 00:04:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.8 + Max RAW speed in metering raised from 100x -> 1000x + +Fri Aug 16 02:39:01 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.176 + * cdrecord.h 1.103 + CDR_VARIREC / CDR_AUDIOMASTER / CDR_FORCESPEED new + +Wed Aug 14 23:43:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.175 + Version -> 1.11a30, Speed test for RAW data sectors + +Wed Aug 14 20:50:55 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.9 + Allow Space as separator in /etc/default/cdrecord + +Wed Aug 14 01:04:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.102 + * sector.c 1.7 + encspeed() new + +Tue Aug 13 23:45:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.6 + HAVE_LIB_EDC_ECC/HAVE_NEW_LIB_EDC/CLONE_WRITE new + +Tue Jul 30 00:22:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.174 + Version ->1.11a28, tracksize/secsize ->itracksize/isecsize for debug printf + +Mon Jul 29 22:22:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.101 + track_base() Macro new, typedef struct ofile ofile_t new + +Mon Jul 29 21:58:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.13 + Shift ISRC & MCN by one to the end if the are on an index change + +Sun Jul 28 23:19:55 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.28 + Flags with allen possible write modi and with CDR_TRAYLOAD to avoid + +Sun Jul 28 13:54:08 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.12 + better comment + +Thu Jul 25 03:25:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.11 + Support for ISRC/MCN in RAW Mode new (but witout index shift) + +Tue Jul 23 23:47:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.10 + First loop in fillsubch() removed because it is identical to second loop + +Tue Jul 23 23:32:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.9 + fillsubch() now coeerect for audio Pregap between Tracks korrekt with relative time counting downwards + +Sun Jul 21 18:21:24 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.91 + set dsp->{ds_disktype!ds_trfirst!ds_trlast!ds_trfirst_ls} from dip->* + Do not cast malloc() anymore + Check write_cdtext() Returncode + Prepare for just Link + +Sun Jul 21 18:13:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.79 + set CDR_BURNFREE Flag, + set dsp->{ds_disktype!ds_trfirst!ds_trlast!ds_trfirst_ls} from dip->* + +Sun Jul 21 18:07:21 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.173 + Version -> 1.11a27, + Define Warning that needs to be printed if Source has been changed, + Better messages for wrong DVD-RW write speed, reload_media() at end Ende of RAW Write + +Sun Jul 21 17:52:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.116 + * auinfo.c 1.15 + malloc() Cast removed + +Sun Jul 21 17:51:44 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.54 + dsp->ds_diskid now is UInt32_t + +Sun Jul 21 17:44:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.100 + struct disk_status with Typen from utypes.h + +Mon Jul 8 00:31:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_session.c 1.4 + * wm_packet.c 1.18 + * subchan.c 1.8 + * fifo.c 1.38 + * drv_mmc.c 1.90 + * drv_jvc.c 1.64 + * clone.c 1.5 + * cdrecord.h 1.99 + * cdrecord.c 1.172 + 'tracks' outside driver interface removed and replaced by trackp->tracks + +Sun Jul 7 22:30:24 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.63 + Better rebuild old driver interface in next_wr_address_jvc() + +Sun Jul 7 22:28:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.17 + * drv_mmc.c 1.89 + * cdr_drv.c 1.27 + * cdrecord.h 1.98 + * cdrecord.c 1.171 + * drv_sony.c 1.53 + * drv_simul.c 1.27 + * drv_philips.c 1.52 + * drv_jvc.c 1.62 + * drv_dvd.c 1.77 + trackno/tracks Parameter in driverinterface removed for new Struct Member + +Sat Jul 6 21:19:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.170 + * cdrecord.h 1.97 + track_t now with tracks and track for simplified driverinterface + +Sat Jul 6 18:20:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.96 + * cdrecord.c 1.169 + * drv_sony.c 1.52 + * drv_simul.c 1.26 + * drv_philips.c 1.51 + * drv_mmc.c 1.88 + * drv_jvc.c 1.61 + * drv_dvd.c 1.76 + cdr_speeddef/cdr_speedmax new and do not default to speed= 1 but to cdr_speeddef + +Fri Jul 5 23:11:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.168 + Version -> 1.11a26 + wm2name[] with better systematics + Bugfix for High Speed CD-RW that could not be written anymore at 10x speed + New test for too slow writing of a CD-RW + Modename for blank only now is "BLANK" + Text: write XXX mode -> real XXX mode + SAO & RAW start (leadin) Code -> drv_mmc.c + Correctly print the current DVD writespeed + +Fri Jul 5 21:36:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.95 + New driverfunction write_leadin, WM_ * Macros with better system, + new Macro wm_base(), + RF_LEADIN new + +Fri Jul 5 21:31:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.87 + New driverfunction write_leadin_mmc() with Code from cdrecord main function + +Fri Jul 5 21:26:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.51 + * drv_simul.c 1.25 + * drv_philips.c 1.50 + * drv_jvc.c 1.60 + * drv_dvd.c 1.75 + New driverfunction write_leadin as dummy + +Thu Jul 4 13:01:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.167 + Version -> 1.11a25 + Print Writemodes (new) + set_wrmode() new + restructuring: cdr_t->cdr_dstat is now used + dp->cdr_dstat->ds_cdrflags |= RF_PRATIP new + Check for ultra low speed media in High Speed writer + Check for high speed media in Low Speed writer + Avoid that cdrecord -- speed=8 causes speed=8 to be ignored as file type arg + +Thu Jul 4 12:55:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.94 + restructuring: cdr_t->cdr_dstat is now used + New Write Mode WM_* definitions + +Thu Jul 4 12:53:14 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.74 + * drv_mmc.c 1.86 + * drv_philips.c 1.49 + * drv_sony.c 1.50 + Check for dp->cdr_dstat->ds_cdrflags & RF_PRATIP + Fill dsp->ds_flags |= DSF_ERA and dsp->ds_at_*_speed + +Tue Jul 2 19:55:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.49 + * drv_simul.c 1.24 + * drv_philips.c 1.48 + * drv_jvc.c 1.59 + * cdr_drv.c 1.26 + * drv_mmc.c 1.85 + * drv_dvd.c 1.73 + dstat_t * now is a Member of cdr_t -> better handling of special funcs + +Tue Jul 2 15:18:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.84 + get_atip() now is always usable (not only if PRINT_ATIP has been defined) + +Sun Jun 16 15:58:37 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.115 + Comment -> mmc-2 + +Fri May 31 22:09:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.114 + wait_unit_ready() fast Abort even if k == SC_MEDIUM_ERROR + +Wed May 29 01:43:13 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.28 + Better printf() format strings for DWORD + +Wed May 29 01:02:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.h 1.3 + List of language codes enhanced + +Wed May 29 00:55:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.37 + palign() Macro with (UIntptr_t) Cast + +Wed May 29 00:54:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.166 + Version -> 1.11a24, gracetime= in usage(), printf() Format correkt for bmtime() + +Wed May 29 00:51:56 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.62 + gracetime= new + +Wed May 29 00:50:03 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.8 + Avoid Coredump if a single .inf File is missing and trackp[i].text is NULL -> ->textcodes does not work + +Mon May 20 17:08:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.34 + palign() -> with UIntptr_t cast + +Mon May 20 16:38:23 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.9 + avoid Integeroverflow with %.*s and 64 bit + +Mon May 20 14:28:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.71 + Cast (int)req.uscsi_buflen/(int)req.uscsi_resid forr 64 bit + +Mon May 13 02:02:09 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.165 + Version -> 1.11a23, + Flush Cache with exit() in Silent Mode to avoid problem with cdrecord -toc and CD-ROMs + +Mon May 13 02:00:49 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.36 + * drv_mmc.c 1.83 + * drv_jvc.c 1.58 + * drv_dvd.c 1.71 + * cdrecord.h 1.93 + New Typ tsize_t instead of off_t for Track size Vars > sizeof(long) on non-largefile OS + +Sat May 4 21:55:38 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.164 + Avoid that abort via ^C kills a running SCSI Command + +Sat May 4 21:42:56 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.83 + * scsitransp.h 1.51 + Callback Function at Ende of SCSI Command + +Sat May 4 18:10:05 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.163 + Version -> 1.11a22 + gracetime= Option new + Now use geterrno()/seterrno() + reload_media() reads from stdder if input is from stdin + +Sat May 4 16:00:13 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.162 + printf() Formats enhanced to get non jumping output with DVDs + +Sat May 4 15:36:45 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.70 + always set CDR_TAO|CDR_SAO in cdr_flags to allow speudo-DAO Mode + +Sat May 4 15:34:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.92 + MIN_GRACE_TIME new + +Sat Apr 20 22:29:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.35 + Now use geterrno()/seterrno() + +Tue Apr 16 19:20:40 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.28 + New Errorstrings from 29.5.2001 + +Tue Apr 9 22:48:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.35 + Embargo Message now better + +Tue Apr 9 22:41:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.91 + F_STDIN Flag new + +Sat Mar 30 12:26:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.69 + Make drecord -atip print useful things + +Wed Mar 27 23:36:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.68 + maxblocks computing corrected (now even works with Panasonic) + +Tue Mar 26 19:18:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.7 + create SCMS Bit + set COPY Bit in TOC and sub channels + +Tue Mar 26 19:10:32 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.161 + Version -> 1.11a19 + +Tue Mar 26 19:07:15 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.14 + Albumperformer= new + +Tue Mar 26 19:02:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.7 + textfile= not-existent caused a Coredump + +Sun Mar 24 23:39:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.160 + SCMS and Copy permitted printing new, Version -> 1.11a18 + +Sun Mar 24 23:38:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.13 + SCMS as new value for Copy_permitted= + +Sun Mar 10 00:24:19 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.159 + Print real write speed + +Sat Mar 9 23:21:05 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.82 + remiove typo in hasdrvopt() + +Sat Mar 9 23:03:00 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.81 + first VariRec Support + +Sat Mar 9 21:15:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.65 + Burn-PROOF Support new, try tp make Panasonic DVD-R working + +Sat Mar 9 20:20:16 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.158 + IS_SCHILY_XCONFIG new, Short Usage with susage() new + +Fri Mar 8 16:48:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.157 + Version print Lizens better, -cdi sets toctype + +Fri Mar 8 16:46:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.82 + Version -> 0.6 + +Tue Mar 5 23:34:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.8 + NULL Pointer for args is now OK to allow to be used with readcd + +Tue Mar 5 23:32:00 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.90 + getnum()/getllnum() from cdrecord.c -> getnum.c + +Tue Mar 5 23:26:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.156 + Version -> 1.11a17 + getnum()/getllnum() -> getnum.c + cdr_defaults() changed to allow to be used with readcd.c + +Tue Mar 5 23:20:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getnum.c 1.1 + date and time created 02/03/05 23:20:48 by joerg + +Mon Mar 4 23:42:43 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.34 + * drv_mmc.c 1.80 + * drv_dvd.c 1.64 + * scsi_cdr.c 1.113 + * drv_simul.c 1.23 + * fifo.c 1.34 + * crc16.c 1.5 + * crc16.h 1.3 + * cdrecord.h 1.89 + Copyright -> 2002 + +Mon Mar 4 23:32:08 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.h 1.2 + Comment for Text Language code now better + +Mon Mar 4 23:21:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.155 + better comment for Version printing for not working Branches + +Mon Mar 4 22:43:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.154 + Comments for Sector size + +Mon Mar 4 22:42:12 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.7 + Copyright -> 2002 + new Function open_cdrdefaults(), + Comment that states that "/etc/default/cdrecord" may not be changed + +Fri Mar 1 22:37:21 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.33 + Better Text for unknown ID Codes + +Thu Feb 28 23:04:45 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.12 + readtstr() now looks for rightmost ' from right to left, + readtag("CDINDEX_DISCID=") -> readtstr("CDINDEX_DISCID=") + +Sun Feb 24 15:44:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.153 + Copyright -> 2002 + +Sat Feb 23 22:00:51 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.6 + First Support for CD-Text Synthesis with new functions text_txt()/packtext()/anytext()/fillup_pack()/fillpack() + +Sat Feb 23 21:44:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.h 1.1 + date and time created 02/02/23 21:44:33 by joerg + +Sat Feb 23 21:21:10 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.61 + -text/textfile= Options documented + +Sat Feb 23 21:17:42 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.152 + Version -> 1.11a15, Option -text new, char * textfile not global anymore + +Sat Feb 23 21:10:53 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.11 + First CD-Text Support + +Sat Feb 23 17:24:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.88 + void *text new in struct track, packtext() Prototype new + +Sat Feb 23 16:01:50 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.79 + CD-Text Cue sheet for Lead-in does not depend anymore from char *textfile but from trackp[0].flags & TI_TEXT + +Wed Feb 20 19:39:39 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.112 + * drv_dvd.c 1.63 + * drv_simul.c 1.22 + * fifo.c 1.33 + #ifndef DEBUG around #define DEBUG + +Tue Feb 19 22:10:23 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.5 + setuptextdata() new + +Fri Feb 15 00:46:56 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * crc16.h 1.2 + * crc16.c 1.4 + flip_crc_error_cor() with bsize Parameter and EXPORT instead of LOCAL + cdtext_crc_ok() removed -> cdtext.c + +Fri Feb 15 00:42:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.4 + Flip error correction for Text CRC correction + Automatic Text Size Header recognition + +Sun Feb 10 12:43:07 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-openserver.c 1.29 + MAX-DMA -> 63kB, -scanbus contolled by env Vars + +Sat Feb 9 17:29:02 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.32 + Warning for guessed IDs + +Tue Jan 29 20:46:42 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.31 + Removed wrong (now superfluous) IDs + +Thu Jan 24 00:03:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.30 + "Advanced Digital Media", "Moser Baer India Limited", "NAN-YA Plastics Corporation", "SHENZEN SG&GAST DIGITAL OPTICAL DISCS" new from Plextools binary + m_grandadvance[] was superfluous (m_grandadv[]) + "WEALTH FAIR INVESTMENT LIMITE" typo fixed (D missing). + +Fri Jan 18 12:43:58 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.69 + do not try to use the PG driver if open(device) fails + +Fri Dec 7 22:40:31 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.111 + scsi_in_progress() with additional sense qualifier 0x04 for CyberDrive + +Sun Dec 2 15:42:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-beos.c 1.20 + Typo removed, Support for BeOS 5 + +Sun Dec 2 15:37:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-amigaos.c 1.2 + Reworked the error handling code + +Sun Dec 2 13:44:43 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-amigaos.c 1.1 + date and time created 01/12/02 13:44:43 by joerg + +Tue Nov 27 20:25:39 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.40 + Copyright + 2001 + +Tue Nov 27 20:24:18 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.39 + scsi-amigaos.c new + +Tue Nov 27 02:10:34 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.151 + NEED_SYS_SOCKET_H for BeOS new + Version -> 1.11a13 + cdr_buffer_cap() environment for Plasmon RF41xx better + +Tue Nov 27 02:08:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.47 + Comment for buffer_cap dummy function for the Plasmon RF41xx better + +Tue Nov 13 16:17:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.87 + * drv_dvd.c 1.62 + * cdrecord.c 1.150 + New Flag DSF_DVD, better overcapacity output for DVD + +Sun Nov 11 18:30:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.61 + Comment for ACARD TECH AEC-7720 ATAPI<->SCSI adaptor better + +Sun Nov 11 17:53:42 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.8 + Test HAVE_RCMD new + +Thu Nov 1 19:15:46 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.21 + Now using timedefs.h + +Wed Oct 31 19:29:35 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.110 + For ACARD TECH AEC-7720 ATAPI<->SCSI adaptor read Mode Page list only in debug mode + +Wed Oct 31 00:24:58 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.109 + sense_secsize() now calles mode_sense() first with 12 Bytes and again with 0xFE Bytes for Moge Page List + +Wed Oct 31 00:17:27 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.78 + check_writemodes_mmc() -> EXPORT, read_dvd_structure() now with mit 32 byte instead of 15 bytes len Parameter + +Wed Oct 31 00:06:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.86 + Prototyp for check_writemodes_mmc() + +Tue Oct 30 23:12:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.26 + cd_mode_page_05 intel byteorder link_size was wrong + +Tue Oct 30 21:36:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.147 + DVD Check code did code exit() for non MMC CD writers + version -> 1.11a10 + +Mon Oct 29 19:12:29 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.3 + Include Liste reworked + +Mon Oct 29 18:57:46 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.10 + * misc.c 1.2 + * modes.c 1.24 + * diskid.c 1.29 + * drv_simul.c 1.20 + * fifo.c 1.32 + * wm_track.c 1.3 + * wm_session.c 1.3 + * wm_packet.c 1.16 + avoid sys/types.h + +Sat Oct 27 02:56:16 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.7 + Test for HAVE_NETDB_H for rcmd() + +Sat Oct 27 02:55:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.27 + #include <unixstd.h> for size_t for snprintf() + +Sat Oct 27 02:53:49 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.31 + Test for HAVE_FORK new + +Sat Oct 27 02:53:18 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.3 + casts because sizeof() on MacOS X is long + +Thu Oct 25 16:19:08 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.2 + Unitnitialised Var dict, plugInResult format string ... GCC error removed + +Thu Oct 25 02:03:56 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.38 + Support for MaxOS X (Darwin-1.4) + +Thu Oct 25 02:03:11 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-mac-iokit.c 1.1 + date and time created 01/10/25 01:03:11 by joerg + +Wed Oct 17 19:40:22 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.146 + initialize scgp with NUL + brackets around if (p = senv_field(6)) + +Tue Oct 16 17:03:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.57 + * cdrecord.c 1.144 + * cdrecord.h 1.85 + * drv_simul.c 1.19 + * drv_sony.c 1.48 + * drv_philips.c 1.46 + * drv_mmc.c 1.77 + * drv_jvc.c 1.57 + New Structuremember cdr_cmdflags in cdr_t + +Tue Oct 16 15:57:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.143 + Better error messages for DVD Demo Mode > 1 GB + +Wed Oct 10 23:04:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.139 + number() corrected - had wrong if/then/else Structure for T/P/G Multiplyer + +Tue Oct 9 02:19:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.138 + sys/types.h & sys/stat.h -> statdefs.h, -> 1.11a09 + +Tue Oct 9 01:42:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.18 + * isosize.c 1.8 + sys/types.h & sys/stat.h -> statdefs.h + +Sun Oct 7 21:27:14 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.40 + * scsi-linux-sg.c 1.68 + Better error messages for Scanbus if /dev/sg* or /dev/pg* cannot be opened + +Sun Oct 7 21:03:23 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.76 + Modifications to allow recognition of CD/DVD writer + +Sun Oct 7 20:41:51 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.25 + xdebug for DVD/CD writer recognition + +Sun Oct 7 19:01:25 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.55 + read_dvd_structure() from drv_dvd.c -> scsi_cdr.c for Pioneer A03 DVD-R/CD-R + reload_media() only if writing later + +Sun Oct 7 13:35:21 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.108 + * cdrecord.h 1.84 + read_dvd_structure() from drv_dvd.c -> scsi_cdr.c for Pioneer A03 DVD-R/CD-R + +Thu Sep 27 19:01:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.27 + #undef DEV_UNKNOWN for True64 + +Thu Sep 13 19:10:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.107 + * cdr_drv.c 1.24 + * drv_dvd.c 1.54 + * cdrecord.h 1.83 + Modifications to allow recognition of CD/DVD writer + +Thu Sep 13 19:01:46 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.137 + cdrecord -version now may print cdrecord-Clone, + Modifications to allow recognition of CD/DVD writer + +Thu Sep 13 15:36:21 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.26 + DEV_MMC_DVD_WR new + +Thu Sep 13 14:31:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sun.c 1.70 + maxdma for USCSI to default if == -1 (e.g. for TAPE), Debug print the RQ Buffer. + +Tue Sep 11 14:04:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.106 + Open CD-Text File in Binary + +Tue Sep 11 03:06:31 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.67 + Timeout Workaround for ioctl() + +Tue Sep 4 14:04:25 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.136 + DEMO_SPEED new + +Thu Aug 9 16:38:21 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.82 + * cdrecord.c 1.135 + #define GRACE_TIME 9 new + +Fri Jul 20 13:17:21 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.75 + * cdrecord.c 1.134 + * cdrecord.h 1.81 + RF_BLANK new to avoid opening the tray before blanking + Version -> 1.11a07 + +Thu Jul 19 00:28:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.6 + Now using _niread()/_nixwrite() + +Thu Jul 12 23:40:28 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.25 + Taiyo Yuden EW-50 new + +Thu Jul 12 23:35:08 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.105 + * cdr_drv.c 1.23 + * drv_philips.c 1.45 + New driver for Taiyo Yuden EW-50 because it swabs audio bytes compared to Philips CDD-521 + +Thu Jul 12 23:33:28 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.30 + Better Debug messages for FIFO adresse/size + +Thu Jul 5 00:08:38 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.5 + Match new libedc + +Thu Jun 28 13:19:02 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.74 + Use -DSAO_RAW -DSAO_RAW_TEST for SAO RAW tests only + +Wed Jun 27 10:04:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * clone.c 1.4 + clone_cue() for Test + +Wed Jun 27 09:51:19 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.133 + CDR_SRAW16 removed + +Wed Jun 27 09:47:10 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.6 + * scsi_cdr.c 1.104 + struct ftrackdesc -> scsimmc.h + +Wed Jun 27 09:35:13 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.103 + struct tocheader definition removed because it is in scsimmc.h + +Sun Jun 24 22:35:23 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.73 + check_writemodes_mmc() now resety silent correctly, deflt_writemodes_mmc() new + +Sun Jun 24 19:55:02 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.80 + CDR_SRAW16 disabled, because SAO supports only RAW96x + +Fri Jun 22 08:42:55 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.5 + struct tocheader now with Uchar + +Wed Jun 20 21:53:55 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.6 + min Struktur member -> pmin + +Wed Jun 20 21:53:34 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.22 + #include <stdio.h> for printf() + +Wed Jun 20 21:53:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.132 + Changes for GCC-3.0 & Linux include file bugs for printf() (is a #define), 1.11a04 -> 1.11a05 + +Tue Jun 19 12:26:49 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.131 + Usage() with textfile=, 1.11a03 -> 1.11a04 + +Tue Jun 19 12:22:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.2 + Modifications for RAW CD-Text + +Tue Jun 19 11:39:08 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.79 + * subchan.c 1.5 + addrw() new for CD-Text Support in RAW mode + +Tue Jun 19 02:10:37 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.78 + * cdrecord.c 1.130 + BUF_SIZE -> CDR_BUF_SIZE & from cdrecord.c -> cdrecord.h + +Tue Jun 19 01:04:54 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.129 + Do not call exit() if interrupting during wait time via ^C + +Mon Jun 18 09:29:52 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdtext.c 1.1 + date and time created 01/06/18 08:29:52 by joerg + +Mon Jun 18 08:55:07 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.72 + * cdrecord.c 1.128 + * cdrecord.h 1.77 + First CD-Text Support + +Sat Jun 16 19:20:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.127 + trackp->dataoff new, call on_comerr() earlier + +Sat Jun 16 18:16:51 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.76 + Dataoffset in struct track new, is_text() new + +Sat Jun 16 18:15:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.71 + Forgotten if (xdebug) + +Tue Jun 12 22:57:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.126 + -clone new, write mode for -xa1 -xa2, RAW data bug removed + +Tue Jun 12 22:42:25 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.4 + recodesectors() -> subrecodesecs()/sunchan.c, scrsectors() without return for AUDIO + +Tue Jun 12 22:41:37 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.4 + subrecodesecs() from sector.c & scrsectors() dummy + +Tue Jun 12 22:40:59 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.75 + recodesectors() -> subrecodesecs() + +Tue Jun 12 01:51:49 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.74 + Modifications for clone.c + +Tue Jun 12 01:50:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * clone.c 1.1 + date and time created 01/06/12 00:50:53 by joerg + +Tue Jun 12 01:07:06 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.3 + subq/nsubh -> _subq/_nsubh + +Tue Jun 12 01:05:54 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.2 + Changes for clone writing, qwto16() new for clone 16/96 Writing + +Tue Jun 12 00:12:42 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.3 + removed unused Vars + +Mon Jun 11 23:31:00 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.73 + Enhancements for clone writing + +Mon Jun 11 23:29:50 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.2 + scrsectors()/recodesectors() fuer clone writing neu + +Mon Jun 11 23:12:41 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.70 + Checking write modes Message only with xdebug + +Mon Jun 11 23:11:55 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * movesect.c 1.2 + Make it more general to allow compress and expand + +Mon Jun 11 23:09:58 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.10 + Comment for ISRC + +Sat Jun 9 20:13:35 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.125 + -copy/-nocopy new, Prevent data sectors only in RAW Mode (without libedc_ecc) + +Sat Jun 9 20:05:59 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.60 + New Options -raw, -raw96r, -raw96p, -raw16, -copy, -nocopy + +Wed Jun 6 00:09:58 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.124 + Any positive startsector for RAW is wriong -> Philips Firmware bug fixed + +Mon Jun 4 19:28:17 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.123 + Modifications for RAW Mode + cdr_t *dp now allocated + BURNFREE printput with Driver Flags + OPC also for -blank + write_secs() new for all writes on ATAPI + print_wrmodes()/check_wrmode() new + reload_media() new + +Mon Jun 4 17:45:49 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.72 + * drv_dvd.c 1.53 + * drv_mmc.c 1.69 + New Function reload_media() + +Mon Jun 4 17:08:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.71 + * wm_packet.c 1.15 + Modifications for RAW Mode + +Mon Jun 4 17:06:21 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * subchan.c 1.1 + date and time created 01/06/04 16:06:21 by joerg + +Mon Jun 4 16:52:34 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * crc16.c 1.3 + Now correct Code with Inverted CRC Bits + +Mon Jun 4 16:49:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.9 + SECT_AUDIO_NPRE -> SECT_AUDIO_NOPRE + +Mon Jun 4 16:06:15 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * crc16.c 1.2 + Now using Uint*_t + +Mon Jun 4 16:02:17 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * crc16.h 1.1 + date and time created 01/06/04 15:02:17 by joerg + +Mon Jun 4 13:33:19 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.68 + Now using CDR_SRAW*, botchexit Abort removed + +Mon Jun 4 12:53:18 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sector.c 1.1 + date and time created 01/06/04 11:53:18 by joerg + +Sun Jun 3 20:51:22 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.8 + Modifications for RAW Mode + +Sun Jun 3 14:48:57 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.122 + Use comexit()/comerr() instead of exscsi() + New Function do_opc() now also called before blank, -force avoids this + +Sat Jun 2 21:24:52 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * movesect.h 1.1 + * movesect.c 1.1 + date and time created 01/06/02 20:24:52 by joerg + +Fri Jun 1 07:54:04 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.59 + burnproof -> burnfree + +Fri Jun 1 07:46:01 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.102 + BURN-Proof (Sanyo) -> Buffer-Underrun-Free recording + +Fri Jun 1 07:44:39 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.29 + call fill_buf() instead of read_buf() and trackp/secno Parameter for Subcode Generator + +Fri Jun 1 02:08:55 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.67 + BURN-Proof -> BURN-Free + +Thu May 31 23:31:44 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.25 + BURN Free & link size new + +Thu May 31 03:21:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.66 + check_writemodes_mmc() new, is_raw() set write modes + +Mon May 28 00:51:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.9 + sec_to_msf() new + +Sun May 27 14:01:28 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.17 + Better comment + +Thu May 24 19:10:28 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.7 + No exit() if -debug & nindex > 1 + +Thu May 24 19:09:39 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.23 + Warning using default data only if not in Silent mode + +Thu May 24 19:07:13 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.52 + * drv_jvc.c 1.56 + * drv_simul.c 1.18 + * drv_philips.c 1.44 + * drv_sony.c 1.47 + CDR_DAO -> CDR_SAO, SAO no more predefined - it either does not work or is tested automatically (MMC) + +Sun May 20 21:23:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.46 + * drv_philips.c 1.43 + mask sectype with ST_MASK because of new mode bits + +Sun May 20 18:51:41 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.17 + CDR_SIMUL Flag new + +Fri May 18 21:07:58 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.70 + F_OVERBURN new, F_RAW / is_raw() new, CDR_SIMUL new + +Fri May 18 19:30:02 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.121 + trackp[0].dbtype is set with Data type from Track 1 + +Fri May 18 19:22:50 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.65 + In open_session() wird nun schon der Datenblocktyp fuer den ersten track eingestellt + +Mon May 14 23:36:07 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.120 + -overburn new + Bracket bug with > 90 min Warning removed + > 90 Min Warning only if offizial capacity is exceeded (for DVD-R) + -pad implied for next Track with -isosize + Win32 Priorities are non contiguous (fix in rt_raisepri()) + +Mon May 14 22:54:17 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.69 + F_OVERBURN (-overburn) new + +Mon May 14 22:53:33 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.58 + -overburn new, -isosize better documented + +Sat Apr 28 23:34:12 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-remote.c 1.5 + Read char with buffer for cygwin + +Fri Apr 20 11:38:03 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.81 + scg_svhead() is silent if non verbose + +Fri Apr 20 11:34:41 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.66 + Hack for ide-scsi bug, although there is sense data, SCSI Status is 0 + +Thu Apr 19 21:52:41 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.64 + removed superfluous scgp->silent--; in fixate_mmx(). silent did become negative + +Thu Apr 19 21:51:26 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.119 + Enhance wait time in wait_unit_ready() after blank to 240 s for Mitsumi + +Tue Apr 17 00:58:57 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.57 + Hint for mailman interface + +*************** Release 1.10 ******************* + +Fri Apr 13 20:41:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.118 + Version -> 1.10 final + +Fri Apr 13 20:40:58 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.117 + Backwardcounter corrected + +Fri Apr 13 20:39:09 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.56 + New Support mail Adresses + +Wed Apr 11 01:22:18 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.101 + * cdrecord.h 1.68 + print_capacity() new with FILE * Parameter + +Sun Apr 8 02:03:49 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.22 + scgp->silent--; was oat wrong place + +Sun Apr 1 14:39:01 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.55 + Typo + +Sat Mar 31 23:02:28 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.21 + unit_ready() before each mode_sense()/mode_select() + +Sat Mar 31 22:46:28 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.63 + Comment for IOMEGA DMA overrun modified (Philips removed) + +Sun Mar 18 19:39:48 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.54 + REMOTE SCSI description and new unified SCSI Options + +Sun Mar 18 19:31:31 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.116 + Unified SCSI Options + +Sun Mar 18 19:27:02 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.80 + Fixed bug that printed SCSI timing without verbose + +Sun Mar 18 18:37:45 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.79 + New Functions: scg_svhead()/scg_svtail()/scg__sprinterr() + Comments for Functions + Print SCSI timing for earch failed SCSI Command + +Sun Mar 18 18:28:17 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.50 + New Funstions: scg_svhead()/scg_svtail()/scg__sprinterr() + +Sun Mar 18 15:37:09 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.78 + Print Timing without Verbose + +Sun Mar 18 15:10:18 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.27 + * scsi-vms.c 1.29 + * scsi-unixware.c 1.25 + * scsi-sgi.c 1.34 + * scsi-osf.c 1.23 + * scsi-next.c 1.30 + * scsi-linux-sg.c 1.65 + * scsi-hpux.c 1.29 + * scsi-linux-pg.c 1.39 + * scsi-bsd.c 1.40 + * scsi-bsd-os.c 1.26 + * scsi-beos.c 1.19 + * scsi-aix.c 1.33 + if (scgp->debug) -> if (scgp->debug > 0) + +Wed Mar 14 00:42:40 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.49 + * scsitransp.c 1.77 + scg_verbose() -> scg_vsetup() + +Mon Mar 12 23:09:38 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.115 + Version -> 1.10a17, select_target() uses FILE * + +Mon Mar 12 23:08:46 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.h 1.3 + * scsi_scan.c 1.14 + comerrno() removed + select_target() with FILE * + select_target() returns number of Targets + +Mon Mar 12 23:06:50 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.67 + * scsi_cdr.c 1.100 + printinq() new + +Mon Mar 12 22:06:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.64 + Better differentiation SCG_RETRYABLE/SCG_NO_ERROR + Set ux_errno if Sense Data present + +Sun Mar 11 17:10:12 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.38 + SCG_RETRYABLE for DMA overrun + CHECK CONDITION == SCG_NO_ERROR + +Sun Mar 11 17:07:48 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.76 + Remove unused Variables + +Sun Mar 11 16:56:24 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.48 + scg_vhead()/scg_vtail()/scg_verbose() & scg_errfflush() new + +Sun Mar 11 16:55:55 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.75 + scg_vhead()/scg_vtail()/scg_verbose() & scg_errfflush() new + Version -> 0.5 + +Sat Mar 10 17:53:45 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.47 + scgp->bufptr new + SCG_KVERSION new + +Sat Mar 10 17:52:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.74 + scgp->bufptr new + scgp->scmd->resid < 0 == DMA overrun + +Sat Mar 10 16:24:00 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.63 + SCG_KVERSION new + +Mon Feb 26 22:20:32 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.24 + New formatting + +Mon Feb 26 22:18:39 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.23 + Environment "LIBSCG_SCAN_ALL" controls scanning of Harddisks because of system crash + +Mon Feb 26 16:05:41 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.114 + Warning if DVD-R code is missing and we found a DVD-R drive + +Sun Feb 25 13:02:42 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.27 + Now using mmapdefs.h + +Fri Feb 23 17:32:38 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.24 + ccs() Makro -> is_ccs() + +Fri Feb 23 00:24:02 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.26 + Support for mmap() on Apollo Domain/OS with mmap(0, &size, ...) + +Thu Feb 22 16:13:27 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.16 + Fixed bug in Prototyp (result from long -> off_t) + +Thu Feb 22 16:11:07 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.66 + * wm_packet.c 1.14 + * cdrecord.c 1.113 + * drv_mmc.c 1.62 + * drv_jvc.c 1.54 + * drv_dvd.c 1.51 + Large File support + +Thu Feb 22 16:10:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.55 + padsize Parameter for pad_track() casted to Llong + +Thu Feb 22 00:57:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.21 + mconfig.h/unixstd.h for Large Files + +Thu Feb 22 00:55:35 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.13 + #include <mconfig.h> for Large Files + +Thu Feb 22 00:54:26 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.25 + Large File support + Casts for sizeof() [long] on MaxOS X + +Wed Feb 21 23:32:51 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.6 + #include unixstd.h for Large Files + +Wed Feb 21 23:27:48 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.6 + * isosize.c 1.7 + * audiosize.c 1.15 + Large File support + +Tue Feb 20 23:56:44 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.45 + * drv_philips.c 1.42 + unixstd.h for sys/types.h for off_t in cdrecord.h + +Thu Feb 15 23:09:12 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.37 + Test for HAVE_BSD_DEV_SCSIREG_H for new MacOSX + +Fri Feb 9 00:35:50 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.41 + Fixes for Plasmon RF 4100 + +Tue Jan 23 12:20:32 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.20 + Cast for singed/unsigned cmparison + +Mon Jan 15 01:09:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.24 + %x -> %p Format + +Sun Jan 7 19:46:42 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.36 + scsi-apollo.c new + +Sun Jan 7 19:39:40 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.73 + * scsi-vms.c 1.28 + * scsi-unixware.c 1.22 + * scsi-linux-pg.c 1.37 + * scsi-aix.c 1.32 + sense_len check -> scsitransp.c + +Tue Jan 2 00:09:45 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.72 + sccsid[] is always used -> without #ifdef lint + +Fri Dec 29 00:06:35 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.112 + Lint, 1.10a10, rlimit cast to Llong for SGI + +Thu Dec 28 23:19:23 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.99 + Modified for Lint + +Wed Dec 20 18:26:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.33 + Cast to caddr_t for SENSEBUF(dsp) + +Wed Dec 13 20:22:52 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.36 + Cast s_cmd.addr = (caddr_t)sp->u_sense.cmd_sense; + +Tue Dec 12 15:20:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.46 + struct scsi -> struct scg_scsi for AIX + +Sat Dec 9 22:52:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.62 + Recognise ENOTTY as errno for failed ioctl() + +Sat Dec 9 18:20:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.19 + * scsilog.c 1.13 + * drv_sony.c 1.44 + * drv_philips.c 1.40 + * drv_mmc.c 1.61 + * drv_jvc.c 1.53 + * drv_dvd.c 1.50 + u_char -> Uchar + +Wed Dec 6 12:43:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.111 + atoll() -> libschily + +Wed Nov 29 17:22:15 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.27 + Indented + +Wed Nov 29 17:18:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.26 + ATAPI Support and changed for new libscg Interface + +Fri Nov 24 11:00:58 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.110 + Workaround for ACER drive that does not return from -dummy + Typo in online Help + +Wed Nov 8 00:06:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.45 + * scsireg.h 1.24 + * scsidefs.h 1.23 + * scgio.h 2.16 + #ifdef __cplusplus extern "C" { + +Sat Nov 4 15:00:50 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.23 + * cdrecord.c 1.109 + Printf-like Formats cleaned up + +Sat Nov 4 14:56:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.98 + PIONEER CD-WO DR-R504X -> DEV_PIONEER_DW_S114X + +Sat Nov 4 14:52:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.65 + DEFAULT_FIFOSIZE -> Long Constant + +Tue Oct 31 15:58:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.108 + Cygwin-1.x Compatibility + +Sun Oct 22 13:37:15 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.31 + Type in sizeof(devname removed + +Tue Oct 17 10:35:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.53 + SEE ALSO enhanced + +Fri Oct 13 11:28:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.61 + use pg_version() only for PP + +Wed Sep 20 00:59:38 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.18 + Code reordered so DMA overrun messages only appears once + +Sun Sep 17 17:15:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.64 + #define sample -> #define msample for Win32 + +Fri Sep 8 03:04:50 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.17 + Warning for Philips DMA overrun + +Wed Sep 6 23:41:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.97 + unit_ready() made better + +Wed Sep 6 09:59:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.71 + * scsitransp.h 1.44 + scg_cmderr() -> scg_cmd_err(), scg_cmd_status() new + +Tue Sep 5 03:32:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.70 + Default printing to stderr + +Tue Sep 5 03:06:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.69 + scg__open() returns -1 when SCGO_OPEN fails, to avoid calling scg_fileno() + +Tue Sep 5 02:30:41 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.96 + allow_atapi() calls unit_ready() before mode_sense() to make it work past a reset + +Tue Sep 5 02:28:03 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.16 + Minimal transfer sizeof(struct scsi_mode_header) after DMA overrun + +Tue Sep 5 02:22:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.60 + read_toc()/read_disk_info() reads minimal 4 bytes for Philips ATAPI drives + +Mon Sep 4 20:24:52 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.52 + Typo removed + +Sat Sep 2 21:16:00 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.43 + Drive flags new in SCSI * + +Sat Sep 2 21:03:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.26 + * scsi-vms.c 1.25 + * scsi-unixware.c 1.21 + * scsi-sgi.c 1.32 + * scsi-osf.c 1.22 + * scsi-os2.c 1.21 + * scsi-next.c 1.29 + * scsi-linux-sg.c 1.60 + * scsi-linux-pg.c 1.35 + * scsi-hpux.c 1.28 + * scsi-bsd.c 1.39 + * scsi-bsd-os.c 1.25 + * scsi-aix.c 1.30 + * scsi-beos.c 1.18 + All debug printing to stderr (scgp->errfile) + +Tue Aug 29 23:44:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-next.c 1.28 + * scsi-bsd-os.c 1.24 + error codes & return harmonised + +Tue Aug 29 02:36:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.59 + set curspeed only if > 0 (SCSI-3 floating point exception in waitfix) + +Tue Aug 29 02:35:04 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.12 + call scg_settarget() in scanbus, to make sure SCSI address for scg_initator_id() is OK + +Sat Aug 26 10:20:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.58 + OPC Hack for strange drive that returns from OPC with "UNIT ATTENTION/operator selected write permit" + +Sat Aug 26 10:15:03 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.107 + Enhancements for remote SCSI, scg_reset() with what Parameter + +Sat Aug 26 00:53:10 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.35 + * scsitransp.c 1.68 + scsibus/target/lun acess now only with scg_scsibus()/scsi_target()/scg_lun() and scg_settarget() + do not initialize target in struct scg_cmd because this is now done in SCG lowlevel code + scg__open() from scsihack.c -> scsitransp.c, scg_settarget() -> scgsettarget.c + dummy code it now always present + +Sat Aug 26 00:22:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.42 + scg_settarget() -> scgsettarget.c + +Fri Aug 25 23:17:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.25 + * scsi-vms.c 1.24 + * scsi-unixware.c 1.20 + * scsi-sgi.c 1.31 + * scsi-osf.c 1.21 + * scsi-os2.c 1.20 + * scsi-next.c 1.27 + * scsi-linux-sg.c 1.59 + * scsi-linux-pg.c 1.34 + * scsi-hpux.c 1.27 + * scsi-bsd.c 1.38 + * scsi-bsd-os.c 1.23 + * scsi-beos.c 1.17 + * scsi-aix.c 1.29 + scsibus/target/lun acess now only with scg_scsibus()/scsi_target()/scg_lun() and scg_settarget() + do not initialize target in struct scg_cmd because this is now done in SCG lowlevel code + +Thu Aug 24 00:52:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.41 + scg Address Stucture new + scg__open() without bus/target/lun Parameter + scg_remote() new + +Wed Aug 23 22:44:26 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.11 + * scsilog.c 1.12 + * drv_dvd.c 1.49 + * drv_jvc.c 1.52 + * drv_philips.c 1.39 + * drv_sony.c 1.43 + * scsi_cdr.c 1.95 + scsibus/target/lun acess now only with scg_scsibus()/scsi_target()/scg_lun() and scg_settarget() + do not initialize target in struct scg_cmd because this is now done in SCG lowlevel code + +Sun Aug 20 20:57:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.40 + * scsitransp.c 1.67 + * scsihack.c 1.34 + * scsi-linux-sg.c 1.58 + * scsi-linux-pg.c 1.33 + * scsi-sgi.c 1.30 + * scsi-next.c 1.26 + * scsi-hpux.c 1.26 + * scsi-bsd.c 1.37 + * scsi-aix.c 1.28 + * scsi_scan.c 1.10 + Now using scg_settarget() + +Sat Aug 19 23:24:03 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.66 + * scsihack.c 1.33 + * scsi-wnt.c 1.24 + * scsi-vms.c 1.23 + * scsi-unixware.c 1.19 + * scsi-sgi.c 1.29 + * scsi-osf.c 1.20 + * scsi-os2.c 1.19 + * scsi-next.c 1.25 + * scsi-linux-sg.c 1.57 + * scsi-linux-pg.c 1.32 + * scsi-hpux.c 1.25 + * scsi-bsd.c 1.36 + * scsi-beos.c 1.16 + * scsi-bsd-os.c 1.22 + * scsi-aix.c 1.27 + * scsitransp.h 1.38 + scg_reset() with Function code Parameter + +Sat Aug 19 22:37:30 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.63 + * scsitransp.h 1.39 + #ifdef's modified for new #define _SCG_*_H + +Sat Aug 19 21:57:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.23 + * scsidefs.h 1.22 + * scgio.h 2.15 + Correctly made multi include safe with #ifdef _SCG_* + +Sat Aug 19 21:05:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.65 + sys/param.h removed + +Sat Aug 19 20:52:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.37 + Now using scg_ops + Remote Version #defines, scg__version() removed + +Sat Aug 19 20:23:20 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.28 + * scsi-osf.c 1.19 + * scsierrs.c 2.26 + * scsitransp.c 1.64 + * scsireg.h 1.22 + u_char -> Uchar + +Sat Aug 19 19:13:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.63 + * scsihack.c 1.32 + scsitransp.c and scsihack.c separated + +Sat Aug 19 17:30:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.21 + Status & Sense Definitions from scsireg.h + +Fri Aug 18 10:40:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.22 + * scsi-wnt.c 1.23 + * scsi-unixware.c 1.18 + * scsi-sgi.c 1.27 + * scsi-osf.c 1.18 + * scsi-os2.c 1.18 + * scsi-next.c 1.24 + * scsi-linux-sg.c 1.56 + * scsi-linux-pg.c 1.31 + * scsi-hpux.c 1.24 + * scsi-bsd.c 1.35 + * scsi-bsd-os.c 1.21 + * scsi-beos.c 1.15 + * scsihack.c 1.31 + * scsi-aix.c 1.26 + * scsitransp.c 1.62 + Now uses scg_ops Structure and calling via pointers + +Thu Aug 17 22:50:53 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.61 + Bracketing typo in scg_sprintresult() removed (printed junk) + +Wed Aug 16 10:11:08 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.22 + * scsi-vms.c 1.21 + * scsi-unixware.c 1.17 + * scsi-sgi.c 1.26 + * scsi-os2.c 1.17 + * scsi-osf.c 1.17 + * scsi-next.c 1.23 + * scsi-linux-sg.c 1.55 + * scsi-hpux.c 1.23 + * scsi-linux-pg.c 1.30 + * scsi-bsd.c 1.34 + * scsi-beos.c 1.14 + * scsi-bsd-os.c 1.20 + * scsi-aix.c 1.25 + * scsihack.c 1.30 + * scsitransp.c 1.60 + scg_send() now only with scgp* Parameter + +Sun Aug 13 23:31:37 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.59 + Buggy braketing corrected (printed 4-5 null Bytes to error output even in silent mode) + +Fri Aug 4 01:26:24 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.36 + * scsitransp.c 1.58 + Komplett umgebaut damit die Fehlerausgabe in einen String erfolgt + +Tue Aug 1 00:03:45 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.35 + * scsitransp.c 1.57 + * scsierrs.c 2.25 + * scsi-wnt.c 1.21 + * scsi-vms.c 1.20 + * scsi-unixware.c 1.16 + * scsi-sgi.c 1.25 + * scsi-osf.c 1.16 + * scsi-os2.c 1.16 + * scsi-next.c 1.22 + * scsi-linux-sg.c 1.54 + * scsi-linux-pg.c 1.29 + * scsi-hpux.c 1.22 + * scsi-bsd.c 1.33 + * scsi-bsd-os.c 1.19 + * scsi-beos.c 1.13 + * scsi-aix.c 1.24 + All printf()'s -> js_printf(), sprintf() -> snprintf() + +Sun Jul 30 15:15:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.56 + * scsitransp.h 1.34 + scg_prbytes()/scg_prsense() & scg_printdev() INterface restructured + +Sun Jul 30 13:52:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.13 + * scsi_scan.c 1.9 + * scsilog.c 1.11 + * cdrecord.c 1.106 + * scsi_cdr.c 1.94 + * modes.c 1.15 + * drv_sony.c 1.42 + * drv_simul.c 1.16 + * drv_philips.c 1.38 + * drv_mmc.c 1.57 + * drv_jvc.c 1.51 + * drv_dvd.c 1.48 + Restructured for new libscg with scg_*() + +Thu Jul 27 01:17:47 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.55 + scg_prbytes()/scg_printdev() now using FILE * Parameter + scg__errmsg() restructured to be similar to snprintf() + +Thu Jul 27 01:15:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.24 + Made similar to snprintf() + +Thu Jul 27 01:15:02 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.33 + scg_prbytes()/scg_printdev() now using FILE * Parameter + scg__errmsg() restructured to be similar to snprintf() + +Sun Jul 23 18:01:12 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.23 + * scsihack.c 1.29 + * scsitransp.c 1.54 + * scsi-wnt.c 1.20 + * scsi-vms.c 1.19 + * scsi-unixware.c 1.15 + * scsi-osf.c 1.15 + * scsi-sgi.c 1.24 + * scsi-os2.c 1.15 + * scsi-next.c 1.21 + * scsi-linux-sg.c 1.53 + * scsi-linux-pg.c 1.28 + * scsi-hpux.c 1.21 + * scsi-bsd.c 1.32 + * scsi-beos.c 1.12 + * scsi-bsd-os.c 1.18 + * scsi-aix.c 1.23 + * scsitransp.h 1.32 + restructured to use scg_ basieed Function names + +Sun Jul 23 00:28:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.31 + open_scsi()/close_scsi()/... -> scg_open()/scg_close/... + +Thu Jul 20 20:12:42 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.51 + Note for Volmgt & Solaris/USCSI + +*************** Release 1.9 ******************* + +Thu Jul 20 19:49:20 2000 joerg + * diskid.c 1.28 + New Manufacturer: "Grand Advance Technology LTD." + +Thu Jul 20 19:12:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.105 + Version -> 1.9 + 99 Minute check better + +Mon Jul 3 01:19:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.52 + Type fixed in !scglocal(scgp)->drvers < 0 + +Mon Jul 3 00:11:20 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.93 + * drv_sony.c 1.41 + * drv_dvd.c 1.47 + * drv_mmc.c 1.56 + * cdrecord.h 1.62 + * cd_misc.c 1.8 + msf_to_lba() with force_positive Flag for 99 Minute CD's + +Sun Jul 2 23:22:00 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.51 + scsi_raisedma() only for Kernel-2.2.10 and newer + +Sat Jul 1 13:40:49 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.50 + New allocated copy buffer in SCSI * -> local for raisedma + +Sat Jul 1 13:22:49 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.53 + * scsi-wnt.c 1.19 + * scsi-vms.c 1.18 + * scsi-unixware.c 1.14 + * scsi-sgi.c 1.23 + * scsi-osf.c 1.14 + * scsi-os2.c 1.14 + * scsi-next.c 1.20 + * scsi-linux-sg.c 1.49 + * scsi-linux-pg.c 1.27 + * scsi-hpux.c 1.20 + * scsi-bsd.c 1.31 + * scsi-bsd-os.c 1.17 + * scsi-beos.c 1.11 + * scsi-aix.c 1.22 + maxdma/maxbuf new in SCSI * + scsi_getbuf() now calls scsi_bufsize() to init new members + +Sat Jul 1 13:09:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.30 + maxdma/maxbuf new in SCSI * + +Fri Jun 30 18:43:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.48 + scsi_raisedma() now called with correct DMA Buffersize + +Fri Jun 30 18:38:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.52 + * scsihack.c 1.28 + * scsi-wnt.c 1.18 + * scsi-vms.c 1.17 + * scsi-unixware.c 1.13 + * scsi-sgi.c 1.22 + * scsi-sco.c 1.14 + * scsi-osf.c 1.13 + * scsi-os2.c 1.13 + * scsi-next.c 1.19 + * scsi-linux-sg.c 1.47 + * scsi-hpux.c 1.19 + * scsi-linux-pg.c 1.26 + * scsi-bsd.c 1.30 + * scsi-beos.c 1.10 + * scsi-bsd-os.c 1.16 + * scsi-aix.c 1.21 + scsi_maxdma() now with 2nd Parameter "amt" for Linux sg driver + +Tue Jun 27 19:29:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.55 + Disk Subtype decoder for High Speed RW + +Tue Jun 27 19:19:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.104 + Support for 99 Minute CD's + +Tue Jun 27 19:17:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.27 + 99 Minute media in table + +Mon Jun 26 22:40:39 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.26 + Bestdisc Technology Corporation new + +Mon Jun 26 22:29:17 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.29 + * scsi-bsd-os.c 1.15 + * scsi-sgi.c 1.21 + * scsi-linux-sg.c 1.46 + * scsi-linux-pg.c 1.25 + * scsi-next.c 1.18 + better error messages into scgp->errstr + +Fri Jun 23 23:52:39 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.45 + pvers && isold -> scglocal + +Fri Jun 23 23:23:33 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.44 + Variable pvers only conditional for unused... warning + +Fri Jun 23 23:19:00 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.43 + Support for SG_IO ioctl() + +Fri Jun 23 21:40:38 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.29 + overbose new + +Thu Jun 22 15:20:18 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.42 + SG_SCSI_RESET & SG_SET_RESERVED_SIZE new + +Wed Jun 21 10:34:52 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.24 + Test with ATAPI SCSI status code + +Wed Jun 21 10:33:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.51 + scsitransp.c split into scsitransp.c & scsi-sun.c + +Wed Jun 21 10:27:11 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.27 + scsi-sun.c new + +Tue Jun 20 07:20:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.28 + secured _SCGIO_H -> _SCG_SCSISENSE_H + +Tue Jun 20 06:09:57 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.28 + ATAPI Support for OpenBSD + +Sun Jun 4 00:55:02 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.103 + #include <sys/select.h> for select() (autoconf Test for AIX), version -> 1.9a02 + +Sat Jun 3 17:31:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.102 + New Option -shorttrack/-noshorttrack + +Fri Jun 2 22:37:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.61 + New Flag TI_SHORT_TRACK & is_shorttrk() macro + +Fri Jun 2 22:32:59 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.50 + New Optionen -shorttrack & -noshorttrack + +Fri Jun 2 21:44:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.5 + Prevent a buffer overrrun with dev= option + +Fri Jun 2 21:43:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.5 + Check for buffer ovverun + +Fri Jun 2 00:03:13 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.54 + Set Pregapsize to 1 if the drive does not support 0 + free(cue) if cuep == NULL + +Tue May 30 02:46:22 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.25 + Restructured + +Tue May 30 01:06:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.24 + New manufacturers: "WEALTH FAIR INVESTMENT LIMITE", "General Magnetics Ld", "MPO" + +Tue May 30 00:59:12 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.27 + debug Parameter -> odebug + +Mon May 29 19:07:56 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-next.c 1.17 + Typo corrected max_scsibus -> scglocal(scgp)->max_scsibus + +Mon May 29 00:31:18 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.20 + Mode page 2A pw_in_lead_in & side_change new + +Mon May 29 00:13:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.92 + More Page 2A bits for cdrecord -prcap + +Sun May 28 18:52:11 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.16 + scsi_close() now works + +Sun May 28 18:40:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.49 + -fix hint for CDR-50 & CDR-55 specified + +Sun May 7 16:52:20 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.91 + * scsilog.c 1.10 + * scsi_scan.c 1.8 + * auinfo.c 1.4 + * cd_misc.c 1.7 + * audiosize.c 1.14 + * cdr_drv.c 1.20 + * fifo.c 1.22 + * defaults.c 1.4 + * wm_packet.c 1.12 + * modes.c 1.14 + * cdrecord.c 1.101 + * drv_sony.c 1.40 + * drv_simul.c 1.15 + * drv_philips.c 1.37 + * drv_mmc.c 1.53 + * drv_jvc.c 1.50 + * drv_dvd.c 1.46 + * scsierrs.c 2.22 + * scsitransp.c 1.50 + #include <schily.h> + +Sun May 7 16:46:39 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.90 + New DVD recognition, to allow Ricoh 9060 + +Sun May 7 16:11:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.26 + Support for new Mac OS X + +Mon May 1 20:06:37 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.49 + scsi_maxmdma() cleaned up + +Thu Apr 27 15:06:42 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.48 + Examples for cdda2wav + +Thu Apr 27 14:22:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.52 + No more error message forSony & long write in progress when Fixating + +Thu Apr 27 14:17:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.23 + Better message for illegal ID (CD-RW) + all old CD-R's now print ILLEGAL OLD CODE + +Wed Apr 26 11:50:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.100 + * cdrecord.h 1.60 + * scsi_cdr.c 1.89 + * drv_jvc.c 1.49 + * drv_dvd.c 1.45 + scsi_close_tr_session()/scsi_blank() with immed Parameter + +*************** Release 1.8.1 ******************* + +Thu Apr 27 14:22:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.52 + No error message for Sony & long write in progress while fixating + +Thu Apr 27 14:17:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.23 + Better printout with illegal ID for CD-RW, all old CD-R's now give ILLEGAL OLD CODE + +Wed Apr 26 11:50:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.100 + * cdrecord.h 1.60 + * scsi_cdr.c 1.89 + * drv_jvc.c 1.49 + * drv_dvd.c 1.45 + scsi_close_tr_session()/scsi_blank() with immed Parameter + +Mon Apr 24 12:32:14 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.99 + Version -> 1.8.1 final, exitcode == 0 only if fixating in Dummy Mode fails + +Sat Apr 22 15:37:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.22 + New manufacturer "VICTOR COMPANY OF JAPAN, LIMITED", "VIVASTAR AG" + +Sun Apr 16 17:07:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.47 + BURN-Proof Option for Sanyo + +Sun Apr 16 17:07:11 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.51 + BURN-Proof Support for Sanyo + +Sun Apr 16 17:06:30 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.98 + New Option driveropts= + better -dao usage + +Sun Apr 16 03:11:26 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.88 + display BURN-Proof for cdrecord -prcap + +Sun Apr 16 03:08:58 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.3 + * cdrecord.dfl 1.2 + driveropts new + +Sun Apr 16 02:16:29 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.39 + * cdrecord.h 1.59 + * drv_simul.c 1.14 + * drv_philips.c 1.36 + * drv_jvc.c 1.48 + * drv_dvd.c 1.44 + open_session() now with cdr_t * Parameter for BURN-Proof + +Mon Apr 3 21:05:37 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.23 + #include <string.h> for strlen() + +Sat Apr 1 21:59:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.21 + New manufaturer: "TAROKO INTERNATIONAL CO.,LTD.", "UNIDISC TECHNOLOGY CO.,LTD", "Hong Kong Digital Technology Co., Ltd.", "VIVA MAGNETICS LIMITED" + +Sat Mar 11 12:31:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.87 + Sanyo CRD-R24S -> Philips CDD 521 + +Sat Mar 11 12:30:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.50 + send_opc_mmc() now calls send_opc() and suppresses ILLEGAL_REQUEST + +Sat Mar 11 12:26:37 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.46 + WeB address changed + +Sun Feb 20 21:54:33 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.58 + * cdrecord.c 1.97 + * cdrecord.1 1.45 + New Option -waiti for multi session from Pipe from mkisofs + +Sun Feb 20 20:56:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.96 + scsi_in_progress() Test and usleep(100000) if Long Write in Progress + +Sun Feb 20 20:54:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.49 + scsi_in_progress() test for scsi_flush_cache() in fixate, send_cue() -> LOCAL + +Sun Feb 20 20:52:49 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.57 + scsi_in_progress() new, send_cue() removed + +Sun Feb 20 20:52:15 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.86 + scsi_in_progress() new + +Sat Feb 19 00:38:35 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.95 + read Sectorsize from read_capacity too, for drivs without Blockdescriptor, dp->cdr_opc() new + +Sat Feb 19 00:33:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.85 + send_opc() new + +Sat Feb 19 00:24:37 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.56 + * drv_sony.c 1.38 + * drv_simul.c 1.13 + * drv_philips.c 1.35 + * drv_mmc.c 1.48 + * drv_jvc.c 1.47 + * drv_dvd.c 1.43 + Separate OPC code in driver interface + +Sun Feb 6 08:27:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.20 + * scsi-openserver.c 1.17 + * scsi-linux-sg.c 1.41 + * scsi-aix.c 1.20 + * scsi-bsd-os.c 1.14 + * scsi-hpux.c 1.18 + * scsi-linux-pg.c 1.22 + * scsi-bsd.c 1.27 + added missing brackets in scsi_close() to make sure that scsi_close() really closes files + +Sun Feb 6 08:25:14 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.40 + Maxdma now is correcteven if only a prallel port is present + +*************** Release 1.8 ******************* + +Fri Jan 28 10:01:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.47 + * drv_dvd.c 1.42 + load_media() with new doexit Parameter + Reload now does not make problems with notebook type drives + +Fri Jan 28 09:51:26 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.34 + * cdrecord.h 1.55 + * cdrecord.c 1.94 + load_media() with new doexit Parameter + +Fri Jan 28 09:50:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.84 + wait_unit_ready() does not print error message if scgp->silent >= 1 + +Wed Jan 26 11:48:08 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.7 + Initiator-ID test past havebus() + +Sun Jan 23 16:39:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.93 + Better error message for open_scsi() + +Sun Jan 23 16:07:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.9 + New code from SCO, -scanbus now works + +Sun Jan 23 00:44:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.25 + scsi-sco.c -> scsi-openserver.c + +Tue Jan 18 00:02:33 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.92 + Version -> 1.8, mlockall()/setpri() problems do not cause abort + Note to -pad option for audio Files with wrong length + #include <sys/procset.h> for SCO Openserver + +Thu Jan 13 01:32:35 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.20 + Problems with m_digitalstor (97:27/01) in table docuented + +Thu Jan 13 01:11:45 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.2 + CDR_DEVICE now superseedes /etc/default/cdrecord + +Tue Jan 11 01:46:47 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-hpux.c 1.17 + sprintf(.../dev/rscsi...) now uses hex digits for tgt 0..15 + +Sat Jan 8 23:42:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.83 + scsi_read() now looks for is_atapi to allow mkisofs & ATAPI to do multi-session + +Fri Jan 7 02:24:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.24 + Dummyfunctions fuor new Interface + +Fri Jan 7 02:22:36 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.19 + set_cdrcmds() now calls return() past exit() for lint's sake + +Wed Dec 29 14:01:03 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.91 + exargs Strukt new + Setting to 2048 bytes/sector earlier for -msinfo + new function exscsi() + exfifo() -> excdr() + +Wed Dec 29 02:14:11 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.54 + * fifo.c 1.21 + wait_faio() new + +Wed Dec 29 00:38:52 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.19 + New manufacturer: "Hile Optical Disc Technology Corp." + "Friendly CD-Tek Co." + "Sound Sound Multi-Media Development Limited" + "kdg mediatech AG" + +Wed Dec 29 00:34:39 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.44 + better dociumentation for SUID Installation + +Fri Dec 24 01:59:35 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.20 + sp null pointer Problem in fifo_stats() fixed + input-buffer -> input buffer + +Tue Dec 7 01:07:24 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.43 + added missing .TP + +Sun Dec 5 13:37:16 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.19 + kill_fifo() now kil only if faio_pid > 0 + +Sat Dec 4 21:36:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.18 + New manufacturer: EXIMPO & Seantram Technology Inc. + Seantram has been guessed before + +Sat Dec 4 14:15:16 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.90 + intfifo()/exfifo() new + kill FIFO on comerr() and signals + +Sat Dec 4 14:12:41 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.41 + isgui as with drv_mmc.c added + +Tue Nov 30 14:48:12 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.23 + * scsi-linux-pg.c 1.21 + pg.h now locally available + +Sat Nov 27 21:38:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.12 + SRB in scsi_send() and scsi_reset() -> static to prevent core dump + +Sat Nov 20 17:49:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.11 + scgfiles array removed + set_error() new + added some ux_errno = EIO + wait_post() now calls DosResetEventSem() in any case + +Sat Nov 20 14:21:09 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.10 + DEBUG2/SCANDEBUG code removed + +Sat Nov 20 07:23:59 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.17 + New manufacturer: Customer Pressing Oosterhout + Harmonic Hall Optical Disc Ltd. + DELPHI TECHNOLOGY INC. + +Sat Nov 20 06:45:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.89 + Version -> 1.8a32 + 5 missing set_secsize(.. oldsize) added + +Sat Nov 20 06:44:02 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.18 + Kodak PDC-600 in driver recognition + +Sat Nov 20 06:43:12 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.46 + next_wr_addr() in driver struct for CD-ROM -> cmd_ill() + +Sat Nov 20 06:41:39 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.18 + fixed typo for HAVE_DOSALLOCSHAREDMEM + +Fri Nov 12 10:00:19 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.48 + scsi_yes() now global + +Fri Nov 12 09:59:49 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.26 + scsi_yes() new + +Mon Oct 18 02:38:11 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.88 + always set TAO mode on startup to make checkdsize() working + +Mon Oct 18 01:34:34 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsilog.c 1.9 + * scsi_cdr.c 1.82 + i_to_short() -> i_to_2_byte() + +Mon Oct 18 01:15:21 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsilog.c 1.8 + * scsi_cdr.c 1.81 + * drv_dvd.c 1.40 + * drv_mmc.c 1.45 + * drv_philips.c 1.33 + * iso9660.h 1.4 + a_to_u_short() -> a_to_u_2_byte() + +Mon Oct 18 01:04:17 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isosize.c 1.6 + utypes.h wegen intcvt.h + +Mon Oct 18 00:38:01 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.80 + * drv_sony.c 1.37 + * drv_jvc.c 1.46 + * drv_dvd.c 1.39 + a_to_3_byte() -> a_to_u_3_byte() + +Mon Oct 18 00:10:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.38 + * drv_sony.c 1.36 + * drv_jvc.c 1.45 + * drv_philips.c 1.32 + i_to_long() -> i_to_4_byte() + +Mon Oct 18 00:04:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.79 + * isosize.c 1.5 + * drv_dvd.c 1.37 + * drv_mmc.c 1.44 + * drv_jvc.c 1.44 + * drv_sony.c 1.35 + * drv_philips.c 1.31 + * audiosize.c 1.13 + * cdrecord.c 1.87 + modified to use intcvt.h and a_to_4_byte() + +Sun Oct 17 23:21:40 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.3 + removed i_to_* and a_to_* macros -> intcvt.h + +Sun Oct 17 22:51:51 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.19 + struct scsi_capacity modified to use Int32_t + +Sat Oct 16 13:52:29 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.78 + * drv_mmc.c 1.43 + * auinfo.c 1.3 + * drv_sony.c 1.34 + malloc() casts for K&R C + +Fri Oct 15 20:28:25 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.53 + * cdr_drv.c 1.17 + * cdrecord.c 1.86 + set_cdrmds() if 2. Parameter is NULL returns BOOL + for cdrecord to check for dvd driver or not + +Fri Oct 15 20:19:36 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.77 + Optima Dis Covery 650 CD-R Inquiry recognition new + +Fri Oct 15 20:17:17 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-beos.c 1.9 + * scsi-osf.c 1.12 + typos removed + +Thu Oct 7 15:33:17 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd-os.c 1.13 + * scsi-aix.c 1.19 + mising bracket in scsi_open() fixed + +Fri Sep 17 17:59:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.85 + Version -> 1.8a29 + libscg version check + #incude <vadefs.h> for win32 realtime pri Code + +Fri Sep 17 17:56:57 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.76 + endless lookp in mmc_cap() removed: no medium (wait_unit_ready()) + +Fri Sep 17 15:48:09 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.47 + HAVE_SCG #define earlier + +Fri Sep 17 15:42:39 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.20 + duplicates with scsi-linux-sg.c fuer scg__version() removed + +Fri Sep 17 15:36:55 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.46 + #ifdef HAVE_SCG for _scg_trans_version[] + +Fri Sep 17 15:09:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.17 + * scsi-vms.c 1.15 + * scsi-unixware.c 1.8 + * scsi-sgi.c 1.19 + * scsi-osf.c 1.11 + * scsi-sco.c 1.13 + * scsi-os2.c 1.9 + * scsi-next.c 1.16 + * scsi-linux-sg.c 1.39 + * scsi-linux-pg.c 1.19 + * scsi-hpux.c 1.16 + * scsi-bsd.c 1.26 + * scsi-bsd-os.c 1.12 + * scsi-beos.c 1.8 + * scsi-aix.c 1.18 + * scsitransp.c 1.45 + * scsitransp.h 1.25 + scg_version() new + +Fri Sep 17 14:55:17 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.22 + Comment changed + +Tue Sep 14 10:57:29 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.38 + scgfile variable in max_dma corrected from scgfile -> scglocal(scgp)->scgfile + +Fri Sep 10 14:06:19 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.16 + Better text for Disk Typ (e.g. Long strategy type) + +Thu Sep 9 12:30:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.2 + isrc_illchar() Prorotype new + +Wed Sep 8 17:57:45 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.15 + New manufacturer: Guann Yinn Co. Ltd. + Opti.Me.S. S.p.A. + Nacar Media srl + +Wed Sep 8 12:45:37 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.16 + missing bracket at malloc(amt) + +Tue Sep 7 17:13:09 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.15 + * scsi-unixware.c 1.7 + * scsi-vms.c 1.14 + * scsi-sgi.c 1.18 + * scsi-sco.c 1.12 + * scsi-osf.c 1.10 + * scsi-next.c 1.15 + * scsi-os2.c 1.8 + * scsi-linux-sg.c 1.37 + * scsi-linux-pg.c 1.18 + * scsi-hpux.c 1.15 + * scsi-bsd.c 1.25 + * scsi-beos.c 1.7 + * scsi-bsd-os.c 1.11 + * scsi-aix.c 1.17 + * scsitransp.c 1.44 + First error messages past scgp->errstr + less calls to comerr() + +Tue Sep 7 17:07:55 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.24 + errstr & errptr new in SCSI * + open_scsi() with errs Parameter + +Tue Sep 7 16:47:21 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.84 + Now using new open_scsi() + added some calls to flush() + +Tue Sep 7 16:46:04 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.42 + 1.6 -> 1.8 + +Tue Sep 7 00:21:08 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.42 + * drv_jvc.c 1.43 + * drv_dvd.c 1.36 + flush() for Blanking new + +Fri Sep 3 11:57:35 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.36 + * scsi-linux-pg.c 1.17 + scsi_initiator_id() in scsi-linux-pg.c -> pg_initiator_id() + +Thu Sep 2 18:57:59 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.83 + 1.8a24 -> 1.8a26 + Ricoh DAO Bug (fwa != -150) workaround + Realtimepri for Win32 + +Thu Sep 2 14:42:14 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.6 + scsi_initiator_id() new + Now prints bus,tgt,lun before selektor + +Thu Sep 2 13:32:57 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.23 + * scsi-wnt.c 1.14 + * scsi-vms.c 1.13 + * scsi-unixware.c 1.6 + * scsi-sco.c 1.11 + * scsi-sgi.c 1.17 + * scsi-osf.c 1.9 + * scsi-os2.c 1.7 + * scsi-next.c 1.14 + * scsi-linux-sg.c 1.35 + * scsi-hpux.c 1.14 + * scsi-linux-pg.c 1.16 + * scsi-bsd.c 1.24 + * scsi-bsd-os.c 1.10 + * scsi-aix.c 1.16 + * scsi-beos.c 1.6 + * scsitransp.c 1.43 + scsi_initiator_id() new + +Mon Aug 30 13:36:17 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.42 + * drv_simul.c 1.12 + * fifo.c 1.17 + #include libport.h new + +Sun Aug 29 01:42:10 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.16 + shared memory for OS/2 + +Sun Aug 29 00:52:56 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.15 + Typo fixed (\f instead of \n) + +Tue Aug 10 21:34:03 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.41 + * scsi-wnt.c 1.13 + * scsi-vms.c 1.12 + * scsi-unixware.c 1.5 + * scsi-sco.c 1.10 + * scsi-sgi.c 1.16 + * scsi-osf.c 1.8 + * scsi-os2.c 1.6 + * scsi-next.c 1.13 + * scsi-linux-sg.c 1.34 + * scsi-linux-pg.c 1.15 + * scsi-hpux.c 1.13 + * scsi-bsd.c 1.23 + * scsi-bsd-os.c 1.9 + * scsi-beos.c 1.5 + * scsi-aix.c 1.15 + Static locale variable removed + Test for openbydev + scsi_freebuf() new + +Mon Aug 9 00:39:37 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.22 + SCSI *->bufbase & scsi_freebuf() new + +Sat Aug 7 22:24:46 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.21 + running/curcmdname/local new in SCSI * + +Sat Aug 7 22:22:36 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.40 + * scsi-wnt.c 1.12 + * scsi-vms.c 1.11 + * scsi-unixware.c 1.4 + * scsi-sgi.c 1.15 + * scsi-sco.c 1.9 + * scsi-osf.c 1.7 + * scsi-os2.c 1.5 + * scsi-next.c 1.12 + * scsi-linux-sg.c 1.33 + * scsi-linux-pg.c 1.14 + * scsi-hpux.c 1.12 + * scsi-bsd.c 1.22 + * scsi-bsd-os.c 1.8 + * scsi-beos.c 1.4 + * scsi-aix.c 1.14 + scg_maxdma removed + scsi_running/scsi_command -> SCSI * struct + +Sat Aug 7 21:05:51 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.10 + scsi_close() new + +Sun Aug 1 22:08:46 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.14 + WRITER_MAXWAIT & READER_MAXWAIT -> 240s for SAO SCSI Timeout + usleep() debug code + +Sun Aug 1 17:14:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.41 + Better documentation for -multi Option (DAO mode) + +Sun Aug 1 17:05:30 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.82 + -msinfo now works even if drive is in DAO mode + Now corrects trackstart values for second session in DAO Mode + +Sun Aug 1 16:51:35 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.33 + * drv_simul.c 1.11 + * drv_philips.c 1.30 + * drv_mmc.c 1.41 + * drv_jvc.c 1.42 + * drv_dvd.c 1.35 + speedp == 0 allowed if speed should remain as is + +Sun Aug 1 16:10:40 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.32 + * drv_simul.c 1.10 + * drv_mmc.c 1.40 + * drv_jvc.c 1.41 + * drv_dvd.c 1.34 + recovery_needed()/recover()/reserve_track() References to Philips driver removed + +Sun Aug 1 16:02:03 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.29 + * scsi_cdr.c 1.75 + * cdr_drv.c 1.16 + * cdrecord.h 1.52 + Several functions scsi_cdr.c -> drv_philips.c + new function cmd_ill() + +Sun Aug 1 13:25:42 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.33 + phys_end in dvd_structure_00 may be 0 for empty session + +Sun Jul 25 13:52:02 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.39 + scsi_close() new + __scgp removed + +Sun Jul 25 13:36:47 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.11 + * scsi-unixware.c 1.3 + * scsi-sgi.c 1.14 + * scsi-osf.c 1.6 + * scsi-sco.c 1.8 + * scsi-os2.c 1.4 + * scsi-next.c 1.11 + * scsi-linux-sg.c 1.32 + * scsi-linux-pg.c 1.13 + * scsi-hpux.c 1.11 + * scsi-bsd.c 1.21 + * scsi-bsd-os.c 1.7 + * scsi-beos.c 1.3 + * scsi-aix.c 1.13 + scsi_close() new + +Sun Jul 25 00:50:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.20 + close_scsi() and scsi_smalloc()/scsi_sfree() new + +Sat Jul 24 22:26:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.19 + scsi_close() new + +Sat Jul 24 22:25:39 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.9 + last changes fro Mr. Heuser + Max Timeout corrected + +Sat Jul 24 22:22:44 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-next.c 1.10 + Kernel Driver is in undefined state if SCSI Bus is not valid -> bugfix & debug prints + +Sat Jul 24 20:43:47 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.39 + from BCD converson (debug) for Ricoh test + Trying to suppress error messages for newer MITSUMI ATAPI drives + +Sat Jul 24 19:27:06 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.40 + Better documentation for -pad/padsize= + +Sat Jul 24 19:25:34 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.14 + New manufacturer: OPTROM + AUDIO DISTRIBUTORS + Acer Media Technology + +Sat Jul 24 19:23:49 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.81 + -> 1.8a24 & write_buf() Test Code + +Sat Jul 24 19:19:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.80 + Check HAVE_SETPRIORITY and HAVE_NICE + +Sat Jul 24 19:17:30 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.79 + Version -> 1.8a23 + Signalhandler for wait time before burning + O_BINARY define for win32 + setmode(TDIN, O_BINARY) for win32 + track[] Array now MAX_TRACKS+2 + Print Drive Buffer size and FIFO size + -force Flag to blank problematic CD-RW's + set sector size to 2k before burning for Plextor + set_speed...() now with speedp Parameter to allow MMC to send back actual values + DAO for MMC + new Options -atip/-useinfo/-force/-dao/mcn=text/isrc=text/index=list + first Test for continuous Drive buffer cap printouts + set_secsize() new (for Plextor & DAO) + EMX Wildcard expansion for OS/2 + Timeout for DAO -> minimal 200s + print_toc() \ removed for K&R C + print_toc() with CD-Text + DosSetPriority() now korrectly doing delta + setpregaps() sets values for lead-in/out + checktsize() checks for DAO + +Sun Jul 18 14:39:31 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.51 + * scsi_cdr.c 1.74 + open_scsi() -> libscg + +Sat Jul 17 15:54:11 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.38 + MAX DMA for Solaris x86 from 32k -> 56k + scsierr() checks for sense[0] != 0 + scsi_sense_{key!code!qual} return 0 if scsierr() == FALSE + +Sat Jul 17 15:37:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.18 + open_scsi() for scsiopen.c new + +Mon Jun 28 01:11:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.12 + set CDB to 0 past cdb_len + +Sun Jun 6 19:41:11 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.28 + CDR_SWABAUDIO for pioneer_dws114x + +Sun Jun 6 19:40:29 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.13 + get_mode_params() now return FALSE if has_mode_page() returns FALSE + +Sun Jun 6 19:39:02 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.73 + Hack for NT-4.0 ASPI ISE inquiry fake (bug in add_len) + workaround for Ricoh NOT_READY key in get Mode page 2A + +Thu May 13 16:55:13 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.10 + #define for format to avoid hiding messages + Now uses dlopen() + ha_inquiry() new + better paraeters in scsi_open() + SRB_HaID/SRB_HaId unified + +Thu May 13 15:07:36 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.72 + check scsi_open() return code for < 0 + +Thu May 13 15:00:48 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.12 + Cast for ANSI C comparison + +Thu May 13 15:00:07 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.31 + Cast for ANSI C + fixed typo in error texts + +Thu May 13 14:31:50 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.40 + mods for ANSI C comparison + +Thu May 13 14:31:12 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.39 + New Options -atip and index= + +Thu May 13 12:00:58 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.21 + field_ptr now correctly used for progress printing on NOT_READY + +Wed May 12 01:42:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.3 + -scanbus support + +Wed May 12 01:01:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.27 + * scsi_cdr.c 1.71 + * cdr_drv.c 1.15 + * scsidefs.h 1.21 + DEV_RICOH_RO_1060C new (preliminary) + +Mon May 3 01:30:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.9 + changed names and indented + WBOOL definition to distinguish BOOL from Windows.h and BOOL from standard.h + busses new + compare busno with busses + Debug File removed + EventStatus as result of WaitForSingleObject() + set_error() new for correct error codes + scsiabort() new + +Tue Apr 27 23:11:59 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.8 + Debug File removed + +Tue Apr 27 21:06:48 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.7 + -scanbus now works + file matrix removed + check for nuber of SCSI Busses + +Mon Apr 26 22:37:40 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.6 + Try to implement -scanbus + +Mon Apr 26 22:36:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.5 + sp->u_scb.cmd_scb[0] = s.SRB_Status -> sp->u_scb.cmd_scb[0] = s.SRB_TargStat + error code SCG_FATAL -> SCG_RETRYABLE + +Mon Apr 26 22:35:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.4 + Indented II + +Mon Apr 26 22:34:15 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.3 + Indented + +Mon Apr 26 22:33:41 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.2 + Better comment + +Mon Apr 26 22:32:32 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-wnt.c 1.1 + date and time created 99/04/26 21:32:32 by joerg + +Sun Apr 25 09:48:05 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.50 + is_copy()/is_scms() new + TI_COPY/TI_SCMS new + read_subchannel() new + pr_manufacturer()/disk_rcap() with rw/audio Parameters + +Sun Apr 25 09:46:03 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.38 + clear -dummy status by clearin -dummy state + COPY & SCMS handling + +Sat Apr 24 14:10:19 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.13 + * drv_mmc.c 1.37 + pr_manufacturer()/disk_rcap() now using rw and audio Parameter + +Sat Apr 24 14:05:48 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.26 + pr_manufacturer()/disk_rcap() now using rw and audio Parameter + Printing of ATIP "restricted" + +Sat Apr 24 14:04:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.30 + pr_manufacturer()/disk_rcap() now using rw and audio Parameter + printf() Format (%l..) + +Sat Apr 24 14:02:11 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.70 + read_subchannel() new + +Sat Apr 24 13:03:56 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.21 + scsi-wnt.c new + +Sun Apr 18 21:04:15 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.c 1.1 + date and time created 99/04/18 20:04:15 by joerg + +Sun Apr 18 19:56:45 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.29 + * drv_simul.c 1.9 + * drv_philips.c 1.25 + * drv_mmc.c 1.36 + * drv_jvc.c 1.39 + * cdr_drv.c 1.14 + * drv_dvd.c 1.32 + * cdrecord.h 1.49 + New driver function cdr_send_cue + +Sun Apr 18 19:28:03 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.38 + g6 & g7 test functions + +Sun Apr 18 18:40:56 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.48 + index= Option new + +Sun Apr 18 18:40:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.35 + index= Option new + +Sun Apr 18 00:42:59 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.47 + New Flags F_SAO/F_WRITE/F_PREGAP/F_FORCE + isrc in struct track + is_tao()/is_pregap() new + ds_cdrflags in struct disk_status + cdr_buffer_cap in struct cdr_cmd + cdr_set_speed_dummy with *speedp - to allow mmc to return value + Functions for auinfo.c + +Sun Apr 18 00:18:30 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.31 + MAX_SCG & MAX_TGT -> 16 + Debug function for printing buscookies[] and scgfiles[][][] + sg_mapbus() now with Bus Parameter and spcial handling for holes in buscookies[] + sg_setup() doing range check + better handling of Status byte in extended Code for mk2 Interface + +Sun Apr 18 00:09:52 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.11 + Search slot for PP Bus backwards, as buscookies[] may have holes + +Sat Apr 17 22:12:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.37 + New Function in Driver table to read Buffer capacity + buf_cap_teac(), read_peak_buffer_cap_teac (), buffer_inquiry_teac(), check_buffer_teac() new + +Sat Apr 17 19:32:41 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_scan.c 1.5 + Enhancements for 16 SCSI busses and 17 Targets/Bus + +Sat Apr 17 19:29:25 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.13 + buf_dummy() new + New Function in Driver table to read Buffer capacity + +Sat Apr 17 19:28:27 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.28 + * drv_mmc.c 1.34 + * drv_philips.c 1.24 + * drv_simul.c 1.8 + * drv_dvd.c 1.31 + New Function in Driver table to read Buffer capacity + +Sat Apr 17 19:25:47 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.27 + Workaround for CDU 620 (can not read lead-in Start time) + +Sat Apr 17 18:57:36 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.37 + MAX_SCG & MAX_TGT -> 16 + Workaround for /dev/scg if Target > 7 + +Sat Apr 17 18:55:26 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd-os.c 1.6 + * scsi-vms.c 1.8 + * scsi-unixware.c 1.2 + * scsi-sgi.c 1.13 + * scsi-sco.c 1.7 + * scsi-osf.c 1.5 + * scsi-os2.c 1.2 + * scsi-next.c 1.9 + * scsi-hpux.c 1.10 + * scsi-bsd.c 1.20 + * scsi-aix.c 1.12 + MAX_SCG & MAX_TGT -> 16 + +Sat Apr 17 18:47:39 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-next.c 1.8 + scsi_setup() & scsi_havebus() with scgp Pointer (bug) + +Sat Apr 17 17:09:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.36 + limit SunOS 4.x maxdma to 64k-1 + +Sat Apr 17 13:14:24 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.38 + -force flag and -useinfo new + +Tue Apr 13 01:29:14 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.12 + m_seantram Index 28 (typo) -> 83 + +Tue Apr 13 01:06:45 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.11 + Test in has_mode_page() if desired page is really available for JVC 2080 FW Bug + +Fri Apr 9 20:49:08 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.36 + speed -> *speedp Parameter in speed_select() + +Fri Apr 9 01:03:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.69 + * drv_dvd.c 1.30 + * audiosize.c 1.12 + Signed/unsiged comparisons with cast + +Fri Apr 9 00:46:07 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsilog.c 1.7 + cast for comparing unsigned > int + +Fri Apr 9 00:33:17 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.68 + read_buff_cap() Ulong -> int + +Fri Apr 9 00:32:35 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.11 + New manufacturer: "Woongjin Media corp" + "INFODISC Technology Co., Ltd." + "UNITECH JAPAN INC." + "AMS Technology Inc." + +Tue Apr 6 22:08:31 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.33 + speed -> *speedp Parameter in speed_select() + Read write speed Auslesen and set *speedp + Test for dsp->ds_cdrflags & RF_WRITE + first DAO enhancements + +Tue Apr 6 22:05:25 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.67 + speed -> *speedp Parameter IN speed_select() + read_buffer() WITH mode Parameter + scsi_get_speed() new + read_buff_cap() prints Data if sp && fp == NULL and avoids division by 0 + read_cdtext() new + Workaround for Philips CDD-522 cannot do read TOC MSN + +Tue Apr 6 01:15:52 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.23 + speed -> *speedp Parameter in speed_select() + Test for dsp->ds_cdrflags & RF_WRITE + +Tue Apr 6 01:13:14 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.26 + ATIP Support + +Fri Apr 2 16:06:31 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.10 + "Seantram Technology Inc." new (guess) + +Fri Apr 2 15:50:28 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.25 + * drv_simul.c 1.7 + * drv_dvd.c 1.29 + speed -> *speedp Parameter in speed_select() + +Sun Mar 28 15:31:56 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.4 + struct mmc_cue new + +Sun Mar 28 15:29:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.37 + -dao and -audio default for .au & .wav + +Fri Mar 12 02:05:58 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auinfo.c 1.1 + date and time created 99/03/12 02:05:58 by joerg + +Sun Mar 7 22:30:42 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.13 + roundup(bufsize, pagesize) to make each Segment page aligned + +Wed Mar 3 23:45:20 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.9 + New manufacturers: vanguard, grandadv, taeil, kingpro, digitalstor + +Wed Mar 3 22:58:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.8 + New RCAP Liste + +Sat Feb 20 00:00:44 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.66 + read_buffer() new + timeout for read_toc_philips() -> 240s for TEAC + read_master_cue() new + send_cue_sheet() new + read_buff_cap() new + +Sun Jan 31 22:37:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.11 + * cdrecord.c 1.78 + carriage Return to beginning of Track... Strings to make error message not overwrite position + +Sun Jan 31 19:50:01 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.77 + ignore dev= values from /etc/default/cdrecord for -scanbus + +Sun Jan 31 19:23:53 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.65 + Suport for ACER CR-4020C + +Sun Jan 31 19:23:05 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.22 + scgp->inq->ansi_version = 1; -> scgp->inq->data_format = 1; to make Plasmon RF-4100 work again + +Sun Jan 31 18:55:45 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.36 + Hint for SVr4 and POSIX Realtime scheduler + +Sun Jan 31 18:49:06 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.19 + scsi_maxdma() from MAXPHYS -> DFLTPHYS + +Sat Dec 12 12:36:09 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-beos.c 1.2 + sccsid[] -> __sccsid[] + +Sun Dec 6 13:16:25 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-beos.c 1.1 + date and time created 98/12/06 13:16:25 by joerg + +Sun Dec 6 12:41:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.20 + BeOS new + +Sun Dec 6 12:41:30 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.7 + New Version past phone call with vaxinf@CHCLU.CHEMIE.UNI-KONSTANZ.DE + +Sun Dec 6 12:10:54 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.35 + FreeBSD device name bug + New address for Mailing List + Documentation of /etc/default/cdrecord + +Sat Dec 5 13:46:27 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.76 + HAVE_SYS_RESOURCE_H new (BeOS) + 1.8a13 -> 1.8a14 + cdr_defaults() new + +Sat Dec 5 13:38:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.46 + default.c/cdr_defaults() new + +Sun Nov 29 19:40:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sco.c 1.6 + cleaned up and permission to use /dev/xxx:target,lun + +Sun Nov 29 19:27:55 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.20 + fused + +Sun Nov 29 19:25:54 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.14 + Splitted into scgcmd.h and scgio.h + +Sun Nov 29 19:23:33 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-unixware.c 1.1 + date and time created 98/11/29 19:23:33 by joerg + +Sun Nov 29 19:22:45 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.19 + UNIXWARE new + +Sun Nov 29 19:15:04 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.75 + scgio.h -> scgcmd.h/scgio.h, scgio.h scgcmd.h scsidefs.h scsireg.h scsitransp.h -> include/scg, 1.8a11 -> 1.8a13 + +Sun Nov 29 19:14:20 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.20 + * scsitransp.c 1.35 + * cdr_drv.c 1.12 + * modes.c 1.10 + * scsilog.c 1.6 + * wm_packet.c 1.10 + * scsi_scan.c 1.4 + * scsi_cdr.c 1.64 + * audiosize.c 1.11 + * drv_sony.c 1.24 + * drv_simul.c 1.6 + * drv_philips.c 1.21 + * drv_mmc.c 1.32 + * drv_jvc.c 1.35 + * drv_dvd.c 1.28 + scgio.h -> scgcmd.h/scgio.h, scgio.h scgcmd.h scsidefs.h scsireg.h scsitransp.h -> include/scg + +Sun Nov 29 00:39:42 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sco.c 1.5 + Correctly return Sense Data, EIO if errno == 0 + +Sat Nov 28 12:32:00 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.19 + asc <= 80 -> asc < 80 for invalid sense code + +Sat Nov 28 00:49:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.18 + Missing NULL as terminator for sd_ccs_error_str[] added + +Wed Nov 25 22:23:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.10 + pg_send() Prototyp new + +Wed Nov 25 22:22:46 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.34 + HAVE_PARAM_H -> HAVE_SYS_PARAM_H (Typo) + +Sun Nov 22 15:50:37 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.74 + 1.8a9 -> 1.8a11, DosSetPriority() new + +Sun Nov 22 15:26:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isosize.c 1.4 + * audiosize.c 1.10 + Now using statdefs.h + +Sat Nov 21 23:41:31 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.33 + #ifdef HAVE_PARAM_H for VMS + +Sat Nov 21 21:38:31 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.63 + unsigned int cast for char Parameter in i_to_short() + +Sat Nov 7 22:21:28 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.73 + 1.8a8 -> 1.8a9 + +Fri Nov 6 23:49:59 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.30 + Typo in scsi_send() header + +Mon Nov 2 22:22:23 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.18 + Typ bus -> busno for CAM removed + +Mon Nov 2 14:55:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-os2.c 1.1 + date and time created 98/11/02 14:55:22 by joerg + +Mon Nov 2 13:24:30 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.18 + Now completely using SCSI *scgp as Function parameter + scsi-os2.c new + +Mon Nov 2 14:27:10 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.6 + * scsi-sgi.c 1.12 + * scsi-sco.c 1.4 + * scsi-osf.c 1.4 + * scsi-next.c 1.7 + * scsi-linux-sg.c 1.29 + * scsi-linux-pg.c 1.9 + * scsi-hpux.c 1.9 + * scsi-bsd.c 1.17 + * scsi-bsd-os.c 1.5 + * scsi-aix.c 1.11 + * scsierrs.c 2.17 + * scsitransp.c 1.32 + * scsitransp.h 1.17 + * cdrecord.c 1.72 + * cdrecord.h 1.45 + * cdr_drv.c 1.11 + * drv_mmc.c 1.31 + * drv_philips.c 1.20 + * drv_jvc.c 1.34 + * drv_dvd.c 1.27 + * drv_simul.c 1.5 + * drv_sony.c 1.23 + * scsi_cdr.c 1.62 + * modes.c 1.9 + * scsi_scan.h 1.2 + * scsi_scan.c 1.3 + * scsilog.c 1.5 + * wm_packet.c 1.9 + Now completely using SCSI *scgp as Function parameter + +Thu Oct 29 15:59:52 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.17 + * scsitransp.h 1.16 + * scsitransp.c 1.31 + * scsi-sgi.c 1.11 + * scsi-vms.c 1.5 + * scsi-sco.c 1.3 + * scsi-osf.c 1.3 + * scsi-next.c 1.6 + * scsi-linux-pg.c 1.8 + * scsi-linux-sg.c 1.28 + * scsi-hpux.c 1.8 + * scsi-bsd.c 1.16 + * scsi-bsd-os.c 1.4 + * scsi-aix.c 1.10 + Globale Variables removed and replaced by SCSI *scgp + +Thu Oct 29 15:45:38 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sco.c 1.2 + Indented and scsi_isatapi() new + +Thu Oct 29 15:30:53 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sco.c 1.1 + date and time created 98/10/29 15:30:53 by joerg + +Thu Oct 29 15:21:52 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.70 + Lowlevel SCSI transport Routines now have scgp Parameter, 1.8a6 -> 1.8a7 + +Thu Oct 29 15:21:09 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.61 + * drv_sony.c 1.22 + * modes.c 1.8 + * scsilog.c 1.4 + * drv_philips.c 1.19 + * drv_mmc.c 1.30 + * drv_jvc.c 1.33 + * drv_dvd.c 1.26 + Lowlevel SCSI transport Routines now have scgp Parameter + +Wed Oct 28 22:20:25 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.9 + dev=device:b,t,l Syntax new + +Mon Oct 26 03:18:37 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.7 + manufacturer_id() new + mi_num new in struct disk_man + +Mon Oct 26 03:17:34 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.44 + manufacturer_id() new + +Mon Oct 26 00:27:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.6 + New manufacturer: Xcitec Inc. + Doremi Media Co., Ltd. + Matsushita Electric Industrial Co.,Ltd. + CDA Datenträger Albrechts GmbH. + +Sun Oct 25 13:00:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.71 + #ifdef HAVE_SYS_MMAN_H new + +Sat Oct 24 01:41:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.4 + * scsi-osf.c 1.2 + * scsi-sgi.c 1.10 + * scsi-next.c 1.5 + * scsi-hpux.c 1.7 + * scsi-bsd.c 1.15 + * scsi-bsd-os.c 1.3 + * scsi-aix.c 1.8 + Blind changes for 1st stage of SCSI lib: Globale Variables removed and replaced by SCSI *scgp + +Sat Oct 24 00:22:01 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.69 + * scsi_cdr.c 1.60 + open_scsi(dev, timeout, verboseopen) -> open_scsi(dev, debug, verboseopen) + +Fri Oct 23 23:46:23 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.8 + * scsi_cdr.c 1.59 + scsi_settimeout() -> do not divide by 100 + +Fri Oct 23 15:53:37 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.68 + XXX scgp->cap->c_bsize = 2048; XXX Hack init !!! + +Fri Oct 23 03:14:46 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.16 + scsi-sco.c new + +Fri Oct 23 16:01:44 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.27 + * scsi-linux-pg.c 1.7 + * scsitransp.c 1.30 + * scsitransp.h 1.15 + * scsierrs.c 2.16 + * scsi_cdr.c 1.58 + * scsidefs.h 1.19 + * cdrecord.c 1.67 + * drv_dvd.c 1.25 + * drv_philips.c 1.18 + * drv_sony.c 1.21 + * drv_jvc.c 1.32 + * cdr_drv.c 1.10 + * drv_mmc.c 1.29 + * modes.c 1.7 + * scsi_scan.c 1.2 + * scsilog.c 1.3 + Globale Variables removed and replaced by SCSI *scgp + +Thu Oct 22 18:49:06 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-next.c 1.4 + Now using scsi_open(device, busno, tgt, tlun) Interface + +Tue Oct 20 18:31:25 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.57 + CDD521/02 (Kodak PCD-200) + +Sun Oct 18 14:54:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.66 + 1.6.1 -> 1.7.1 + +*************** Release 1.6.1 ******************* + +Sun Oct 18 14:47:55 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.65 + O_BINARY for Tracks + Restore old sector size on exit() + Better handling for lba (512/2048) in read_toc() + +Sun Oct 18 14:40:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.56 + * cdrecord.h 1.43 + sense_secsize() new + +Sat Oct 17 16:39:41 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.12 + #ifdef SHM_LOCK to allow compilation of SysV shm on AIX + +Fri Oct 9 14:21:38 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.14 + sp->ux_errno = EIO; for old Transport Interface + +Fri Oct 9 22:19:30 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.24 + * cd_misc.c 1.6 + * fifo.c 1.11 + * diskid.c 1.5 + * port.c 1.8 + #include <utypes.h> new + +Fri Oct 9 14:21:38 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.5 + * wm_packet.c 1.7 + * wm_session.c 1.2 + * wm_track.c 1.2 + #include <sys/types.h> & #include <utypes.h> new + +Thu Oct 8 15:43:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.42 + u_char -> Uchar + +Wed Oct 7 18:08:46 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.64 + 1.7a2 -> 1.7, -fix -eject corrected + wait_unit_ready(120); after a load + +Wed Oct 7 18:07:41 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.55 + IMMED hack in close track/session added + +Wed Oct 7 18:06:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.28 + new function waitfix_mmc() + -dummy error hiding better + +Wed Oct 7 17:54:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.6 + EIO on SCG_RETRYABLE + +Tue Oct 6 12:53:11 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.3 + next version from vaxinf@CHCLU.CHEMIE.UNI-KONSTANZ.DE and my remarks + +Tue Oct 6 12:21:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.2 + next version from vaxinf@CHCLU.CHEMIE.UNI-KONSTANZ.DE + +Tue Oct 6 02:09:14 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.5 + * scsi-linux-sg.c 1.26 + * scsi-bsd-os.c 1.2 + New device:@ Syntax + +Tue Oct 6 02:04:46 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.54 + New device:@ Syntax + sscanf() -> scsi_scandev() + +Tue Oct 6 01:50:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.34 + new dev= Syntax (dev=device:@ / dev=device:@,lun) inserted + +Tue Oct 6 01:05:29 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.13 + modified to use -lcam & cam_open_btl(busno, tgt, tlun, O_RDWR, NULL); + +Thu Oct 1 01:15:57 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.12 + Mods for dev=devname:@,l + +Mon Sep 21 01:24:45 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.25 + scsi_settimeout() -> sg_settimeout() + +Sat Sep 19 21:49:11 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-osf.c 1.1 + date and time created 98/09/19 20:49:11 by joerg + +Tue Sep 15 02:55:28 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.17 + capacity_philips() with Philips CDD-2600 Support new + *_attach() now uses cdr_t * Parameter + cdr_kodak_pcd600 new + Pioneer DW-S114X from open_track_yamaha -> open_track_oldphilips + +Tue Sep 15 02:39:44 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.11 + #ifndef BSD_CAM -> #ifndef HAVE_CAMLIB_H + +Tue Sep 15 02:37:58 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.63 + Now uses: fctldefs.h, strdefs.h + SECURITY new + 1.7a1 -> 1.7a2 + open_scsi() check return value and print error message + Blanking time print + #ifdef _SC_PRIORITY_SCHEDULING around sysconf() + #ifdef PRIO_PROCESS around setpriority() for WNT + +Tue Sep 15 02:31:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.31 + Now uses: fctldefs.h, strdefs.h + blank_jvc() new + +Tue Sep 15 02:30:11 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.20 + Now uses: fctldefs.h, strdefs.h + +Tue Sep 15 02:22:12 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.41 + struct index -> struct tindex to allow #define index strchr + +Tue Sep 15 02:21:24 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.27 + Now uses: fctldefs.h, strdefs.h, timdefs.h + Sony 928 Support new + For drives that don't support read ATIP use data from read_diskinfo + Try to handle "early Return" fixating syndrom from Mitsumi drives + no error messages when fixating using -dummy + +Tue Sep 15 02:13:49 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.53 + Now uses: fctldefs.h, strdefs.h + +Tue Sep 8 01:32:08 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.15 + Conditional compilation for Linux pg driver to support old Linux releases + +Mon Sep 7 02:30:15 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.10 + Typo in scsi_fileno() fixed + +Sun Sep 6 18:47:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.9 + first FreeBSD CAM Support + +Sun Sep 6 18:22:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.8 + Enhancements for NetBSD & ATAPI + +Sun Sep 6 01:39:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.9 + cdr_mmc_sony new + +Sun Sep 6 00:43:43 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.4 + * drv_dvd.c 1.24 + Now uses: strdefs.h + +Sat Sep 5 23:23:31 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.29 + Now uses: timedefs.h fctldefs.h + +Mon Aug 31 01:50:12 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.4 + pgbus init from -1 -> -2 + +Mon Aug 31 01:39:52 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.24 + /dev/sga... to /dev/sgz instead of /dev/sgy now checked + return nopen to allow recognition of bad dev= parameters + +Mon Aug 31 01:38:08 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.3 + Debug print for pgbus + if scsibus >= 0 ist do nothing if busno is wrong + +Mon Aug 31 01:03:17 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.52 + write_xg5() new + +Mon Aug 31 01:02:00 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.51 + open_scsi() now checks dev=devicename:b,t,l + read_trackinfo() now don't prints Cannot read TOC Meldung in silent mode + +Mon Aug 31 00:43:31 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.28 + scsiprintresult() new + +Mon Aug 31 00:40:32 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.14 + scsiprintcdb()/scsiprintwdata()/scsiprintrdata()/scsiprintresult() new + +Sun Aug 30 12:55:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.23 + g5_cdbaddr()/g5_cdblen() -> scgio.h + +Sun Aug 30 12:54:37 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.14 + USE_PG -> USE_PG_ONLY + +Sun Aug 30 12:54:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.13 + g0_cdblen()/g5_cdblen() & g5_cdbaddr() new + +Sun Aug 30 12:53:06 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.40 + write_xg5() new + +Sat Aug 29 22:15:37 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.4 + pr_manufacturer() reference removed from print_min_atip() + +Sat Aug 29 21:57:01 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.33 + PP tranport documented, -scanbus doc corrected + +Sat Aug 29 21:01:59 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.2 + #include <linux/pg.h> statt "pg.h" + support for integrated parallel Port Adapter & SCSI + timeout code corrected + DMA overrun now recognized + +Sat Aug 29 20:48:28 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.23 + Support for integrated parallel Port Adapter & SCSI + +Sat Aug 29 20:22:10 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.3 + * cdrecord.h 1.39 + print_min_atip() new in cd_misc.c + +Tue Aug 25 20:23:20 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.13 + scsi_isatapi() defined, for default SCSI code + +Sun Aug 23 13:42:44 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.22 + Fix for misaligned integer access in sg_header for Linux/sparc if valloc() DMA Buffer is used + +Thu Aug 20 10:05:14 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.7 + errno == Reference removed + +Thu Aug 20 01:24:33 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.32 + dev=devicename:target,lun documented + +Tue Aug 18 04:41:56 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.12 + scsi-next.c & scsi-vms.c new + +Mon Aug 17 23:08:36 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-vms.c 1.1 + date and time created 98/08/17 22:08:36 by joerg + +Mon Aug 17 22:35:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.11 + scsi-linux-pg.c new use with USE_PG + +Mon Aug 17 22:34:55 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-pg.c 1.1 + * scsi-bsd-os.c 1.1 + date and time created 98/08/17 21:24:24 by joerg + +Mon Aug 17 22:22:04 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.21 + MAX_SCG -> 8 + search /dev/sg0... before /dev/sfg... + +Mon Aug 17 21:47:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.20 + Support new sg driverinterface + scgfile new to use with global ioctl's + MAX_DMA_LINUX -> 4k if SG_BIG_BUFF undefined + SG_MAX_SENSE -> 16 if not declared + SG_GET_BUFSIZE ioctl new + scsi_isatapi() new + +Sun Aug 16 23:47:48 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * misc.c 1.1 + date and time created 98/08/16 22:47:48 by joerg + +Sun Aug 16 23:47:06 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.38 + misc.c: timevaldiff() new + +Sun Aug 16 23:34:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.7 + scsi_isatapi() new + /dev/scgx may be replaced by dev=/dev/xxx:0,0 + +Sun Aug 16 23:32:42 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.13 + * scsitransp.c 1.27 + * scsi-sgi.c 1.9 + * scsi-aix.c 1.6 + * scsi-hpux.c 1.6 + scsi_isatapi() new + +Fri Jul 17 03:44:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.10 + BSDI new -> scsi-bsd-os.c + +Fri Jun 19 19:59:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.12 + * scsitransp.c 1.26 + * scsihack.c 1.9 + * scsi-sgi.c 1.8 + * scsi-hpux.c 1.5 + * scsi-bsd.c 1.6 + * scsi-aix.c 1.5 + * scsi-linux-sg.c 1.19 + Use scsi_open(device, busno, tgt, tlun) with parameters + +Tue Jun 9 01:44:46 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.22 + korrekte Indizierung bei tracksize virtual tracklist + +Sat Jun 6 00:16:40 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * port.c 1.7 + #include <time.h> -> #include <timedefs.h> wegen sys/time.h + +Wed Jun 3 02:20:27 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.31 + bytes= Option removed + Introduced Mailing List + +Wed Jun 3 02:18:47 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.21 + Treshold for printing the Virtual Trackliste corrected + Abort if first virt Track is not a multiple of the sectorsize + +Wed Jun 3 01:35:24 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.4 + disk_rcap List new + +Wed Jun 3 01:04:49 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.62 + CD -> CD/DVD + +Wed Jun 3 01:01:53 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.61 + #if defined(_POSIX_PRIORITY_SCHEDULING) -> #if defined(_POSIX_PRIORITY_SCHEDULING) && !defined(HAVE_SYS_PRIOCNTL_H) bei LOCAL declaration + +Tue Jun 2 00:41:37 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.20 + attach_???() new now implementing the side effects from identify_???() + +Tue Jun 2 00:41:36 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.26 + attach_???() neu mit den Nebeneffekten aus identify_???() + +Mon Jun 1 23:34:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.50 + Cast for malloc(): not every malloc() is void * + +Mon Jun 1 23:33:21 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.19 + * drv_jvc.c 1.30 + * cdr_drv.c 1.8 + * cdrecord.h 1.37 + * cdrecord.c 1.60 + attach Routine now uses cdr_t * Parameter + +Mon Jun 1 22:24:42 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.19 + * scsilog.c 1.2 + Superfluous & in a_to_u_short() removed + +Sun May 31 21:38:00 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.8 + OSF1 new + +Sun May 31 01:45:04 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.25 + void * cast for valloc() return + +Sun May 31 00:39:54 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.59 + Casts for tracksize & padsize + +Sat May 30 23:12:56 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.3 + Verbose Message for islast + +Sat May 30 00:35:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.58 + tracksize & padsize -> LLong + +Fri May 29 00:32:30 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.57 + astoll() & getllnum() new + number() -> LLong + +Fri May 29 00:05:29 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.30 + waw in .wav Typo + +Fri May 29 00:03:32 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.18 + Better comment and housekeeping + +Thu May 28 01:08:06 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.17 + next_wr_addr_dvd() now correct with read_rzone_info() + +Thu May 28 00:02:01 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.16 + Verbose level documented + set ds_maxblocks from rzone_info + rzone_size() new + phys size computation corrected + +Tue May 26 04:16:55 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.15 + Speed code removed + +Tue May 26 04:03:55 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.14 + Removed lines that have been commented out + +Tue May 26 04:01:03 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.13 + dvd check in identify_dvd() later + +Tue May 26 03:58:57 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.12 + fcntl.h + errno.h + sys/file.h removed + +Tue May 26 03:56:48 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.11 + scsiprbytes() with lverbose > 1 + multi Track Hack indented + +Tue May 26 03:49:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.10 + Superfluous Debugs in SCSI routines removed + +Tue May 26 00:02:51 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.56 + checktsize() with Llong for total Tracksize in Bytes + checkdsize() now computed the remaining rest capacity + +Mon May 25 04:40:51 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.9 + Computations of the track split code -> long long + MAX tracks -> 99 + +Mon May 25 04:35:54 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.8 + close_Xtrack_dvd() code -> fixate_dvd() + +Mon May 25 04:30:05 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.7 + send_dvd_structure() & send_dvd0F() new + +Mon May 25 03:46:30 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.6 + print_laserlog() new + print_logpages() new + +Mon May 25 03:42:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.5 + przone() new + print_dvd00()/print_dvd01()print_dvd04()/print_dvd05()/print_dvd0D()/print_dvd0E()print_dvd0F() new + now reads 4096 Bytes DVD structure + +Mon May 25 03:17:14 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.4 + print_dvd_info() new + +Mon May 25 02:31:56 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsilog.c 1.1 + date and time created 98/05/25 01:31:56 by joerg + +Mon May 25 02:05:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.3 + rzone_info new + dvd_structure_XX new + +Sat May 23 22:41:54 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.2 + #include unixstd.h new + +Sat May 23 21:32:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.49 + New Mode Page 2A Heuristic (min length 0x14 -> 0x10): ATAPI LITEON only gives 0x12: No Write Speed. + +Wed May 20 23:49:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.55 + islast bug (|| instead of &&) fixed + bytes= Option removed + +Tue May 19 04:11:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.3 + struct disk_info & struct track_info -> scsimmc.h + scsilog.h new + +Sat May 16 13:15:21 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.2 + u_char -> Uchar + +Sun May 10 00:12:04 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsimmc.h 1.1 + date and time created 98/05/09 23:12:04 by joerg + +Sun May 10 00:04:17 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auheader.h 1.2 + generic Copyright comment + +Sun May 10 00:02:27 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.25 + Strukturdefinitionen -> scsimmc.h + +Thu May 7 22:43:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.48 + strindex() -> strbeg() + vendor_info / prod_ident / prod_revision new because of array index problems + Kodak PCD-600 new + +Thu May 7 21:38:58 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.36 + getnum() now extern + is_mmc() with DVD recognition + disk_rcap() new + +Thu May 7 21:38:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.7 + DRV_DVD new + cdr_kodak_pcd600 / cdr_cdr_simul / cdr_dvd_simul new + DEV_PIONEER_DVDR_S101 new + DVD recognition in is_mmc() nee + +Thu May 7 21:15:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.54 + 1.6 -> 1.7a1 + getnum() LOCAL -> EXPORT + test_unit_ready() before load Medium + Allow Medium removal if not ready on load_media() + +Thu May 7 10:43:00 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.3 + Vendor list actualalized + +Wed May 6 02:52:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.29 + simulation driver documented + +Wed May 6 02:41:33 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.9 + .wav files that are smaller than expected are handled correctly + +Mon May 4 02:09:55 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.2 + Function names *_mmc -> *_dvd + ds_maxblock -> ds_maxblocks + getdisktype_dvd() now includes more tests + write_type -> WT_SAO + Hack for virtual track list + +Sun May 3 19:37:17 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.47 + mode_select_sg0()/mode_sense_sg0() cnt usage corrected + mode_sense_sg0() movebytes() count corrected + +Sat May 2 00:46:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_simul.c 1.1 + date and time created 98/05/01 23:46:07 by joerg + +Fri May 1 19:26:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.46 + DEV_PCD_600 new + is_mmc() now uses dvdp Arg + +Fri May 1 19:08:34 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.18 + PCD_600 new + +*************** Release 1.6 ******************* + +Fri Apr 17 12:53:59 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.45 + & before ibuf removed because it is an array + +Fri Apr 17 12:45:38 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.44 + min/sec/frame -> amin/asec/aframe because of min() Macro + +Thu Apr 16 01:43:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.26 + -ignsize new + web page for cdrecord added + +Thu Apr 16 00:55:39 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.2 + Print if Manufacturer is in none of the tables + +Thu Apr 16 00:52:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.24 + ds_maxblock -> ds_maxblocks + do get_atip() always, but print if lverbose is set + +Thu Apr 16 00:32:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.35 + * cdrecord.c 1.53 + ds_maxblock -> ds_maxblocks + new Option -ignsize + +Thu Apr 16 00:31:32 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.29 + * drv_philips.c 1.16 + ds_maxblock -> ds_maxblocks + +Sun Apr 12 16:14:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.43 + Smart & Friendly CD-R4012 (TEAC CDR-55S) new + +Sun Apr 12 02:15:15 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.24 + scsiprintcdb()/scsiprintwdata()/scsiprintrdata() new + print scsiprintcdb() on errors + +Sun Apr 12 01:58:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.34 + * cdrecord.c 1.52 + Real Blocks new + 1.6a14 -> 1.6 + +Wed Apr 1 03:28:36 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.51 + checkgui() now has verbose print + +Wed Apr 1 01:36:59 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.28 + lberbose > 1 for all subcode Messages + teac_wr_pma()/teac_rd_pma() new + JVC Errorcodes new + check for cdrecord -fix without Parameter + hide Illegal Command errorcode for next_wr_addr_teac() + +Wed Apr 1 01:29:49 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.23 + * scsi_cdr.c 1.42 + * drv_mmc.c 1.23 + GCC Warnings removed: printf format errors + +Tue Mar 31 20:58:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.50 + ->1.6a14, LOAD & EJECT works for CD-ROM too + GUI test on STDERR + first Trackno -> track[0] as Hack + +Tue Mar 31 20:56:43 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.25 + CREDITS + better Documentation for tsize= & TEAC + +Sun Mar 29 15:31:08 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.24 + -vv/-VV mods + -fix: not for TEAC + -load new + timeout= Option + tsize= description because of tracksize and TEAC + nice/SunOS -> nice/others + +Sun Mar 29 15:26:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.15 + open_session() with tracks & trackp Parameters + Philips CDD-521 old/dumb new + Pioneer DW-S114X new + +Sun Mar 29 15:22:29 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.22 + open_session() with tracks & trackp Parameters + Check for zeroed ATIP Info + wait_unit_ready() for ATAPI - sorry not working + +Sat Mar 28 23:43:07 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.49 + check_recovery() now uses flags for unload_media() + call unload_media() on input buffer, wait error, and for blank media error + open_session() now usees tracks & trackp Parameters for Sizecheck + Printing of is_swab() with audio fixed + +Sat Mar 28 23:22:30 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.27 + teac_open_session() checks tracksize ( <= 0 is not possible) + +Sat Mar 28 23:21:08 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.41 + wait_unit_ready() now handles BUSY + mode_sense_sg0() movebytes() count handling corrected (amt-4) + better (komplete) Inquiry printing with -V + JVC XR-W2001 / Plilips CDD521/00 / Traxdata CDR4120 / Pioneer CD-WO DW-S114X / Pinnacle RCD-1000 new + +Sat Mar 28 23:06:05 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.18 + SCSI Status codes + +Fri Mar 27 01:04:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.18 + * cdrecord.h 1.33 + open_session() with tracks & trackp parameters + +Thu Mar 26 22:42:29 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.6 + Pioneer DW-S 114, old Philips, dumb Philips new + +Tue Mar 24 21:30:08 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.32 + is_*() Macros now clearer: != 0 + +Tue Mar 24 21:29:18 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.17 + DEV_CDD_521_OLD new + +Mon Mar 16 00:48:34 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_dvd.c 1.1 + date and time created 98/04/20 00:48:34 by joerg + +Sat Mar 14 17:49:09 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.5 + MAX_DMA_BSD 64k -> 60k + +Thu Mar 12 23:48:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.26 + set ds_maxblock + next_wr_addr_jvc() uses read_B0() if track == 0 + use trackp[i].trackno for TOC + Lead-out Start time now uses frames + teac_calibrate() inits lba_addr from read_B0() + next_wr_addr_teac() with Parameters + +Thu Mar 12 23:42:09 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.48 + use real Track nubmers + -v/-V now Inc type Flag + print remaining capacity + Pregapsize || bug fixed + Trackno in struct track + wait_unit_ready() new + +Thu Mar 12 23:35:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.14 + Print computed ATIP only for empty Disk + ATIP printout now prints Lead-out start time too + compute Disk capacity + +Thu Mar 12 22:33:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.17 + close_track_sony() -> track = 0 ! + mode_sense() -> get_mode_params() + +Thu Mar 12 22:24:10 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.31 + Strukt track now includes trackno + CDR_DVD new + from_bcd()/to_bcd() new + wait_unit_ready() new + read_B0() new + +Thu Mar 12 22:20:40 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.40 + unit_ready() now checks for UNIT_ATTENTION + wait_unit_ready() new + toc struktures char -> Uchar + read_tochdr()/read_trackinfo() may have NULL Pointer Args + read_B0() new + +Thu Mar 12 22:12:16 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.22 + Print data if verbose > 1 + +Thu Mar 12 01:21:58 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.2 + from_bcd()/to_bcd() new + +Tue Mar 10 00:07:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.47 + * drv_mmc.c 1.21 + checkgui() & isgui new + +Mon Mar 9 23:29:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.20 + Read ATIP non-fatal + warnung in fixation with correct lverbose flag + +Sun Mar 8 15:02:13 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.39 + SAF CD-R2006PRO CD-R2006, JVC R2626 new + +Sun Mar 8 14:59:31 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.46 + Default Timeout -> 40s + flags int -> long + new Option -load + Print Lead-out start + 90 Min value corrected + +Sun Mar 8 14:56:53 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.30 + fsamples()/frames() new + +Fri Mar 6 01:11:56 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.21 + print SCSI command names before ABORT + +Thu Mar 5 01:15:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.15 + referres -> refers + +Thu Mar 5 01:15:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.11 + * scsitransp.c 1.20 + scsi_sense_qual() new + +Mon Mar 2 22:50:12 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.19 + msf_to_lba()/lba_to_msf() -> cd_misc.c + len += 2 to correct length for TOC & disk Info + failed read ATIP is no fatal error + better print_atip() + +Mon Mar 2 22:45:53 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cd_misc.c 1.1 + date and time created 98/03/02 22:45:53 by joerg + +Mon Mar 2 22:39:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.29 + F_LOAD new + All Flags sorted + msf_to_lba()/lba_to_msf() new + +Mon Mar 2 22:36:10 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.13 + philips_getlilo() new + print disk manufacturer new + +Mon Mar 2 21:56:53 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.38 + Pinnacle RCD 4X4, SAF CD-RW226 new + +Mon Feb 23 22:32:27 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.37 + read_toc_philips() same parameters as read_toc() (ses -> fmt) + +Mon Feb 23 22:30:57 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.18 + msf_to_lba() corrected (+-150 bug) + lba_to_msf() new + Check for Complete Disk: 0xFF:0xFF/0xFF + pr_manufacturer() new with lverbose + different Formatting + +Mon Feb 23 21:54:28 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.45 + 80 Minute limit -> 90 Minutes + +Mon Feb 23 21:51:56 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskid.c 1.1 + date and time created 98/02/23 21:51:56 by joerg + +Sun Feb 22 23:23:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.10 + fifo_percent() with Parameter + FIFO Bug (duoubling of a segment at end of writing) fixed + +Sun Feb 22 22:54:46 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.44 + fifo_percent() with Parameter + unit_ready() for UNLOAD removed + print Disk capacity + +Sun Feb 22 22:52:53 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.6 + fifo_percent() with Parameter + +Sun Feb 22 22:47:51 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.28 + fifo_percent() with Parameter + msf_t typedef + pr_manufacturer() new + +Sun Feb 15 21:01:03 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.8 + getWavShort() & getWavLong() Definitions removed + +Tue Feb 10 01:00:48 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.43 + New option timeout=# + +Mon Feb 9 12:44:40 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.18 + timeout from 1/100 sec -> 1/HZ sec + +Sun Feb 8 21:56:01 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.17 + Missing bracket at read() inserted + +Sun Feb 8 18:45:19 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.36 + Tayo Yuden CD-WO EW-50 better Inquiry + +Sun Feb 8 15:52:15 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.9 + fifo_percent() returns -1 if buflen == 0 + dummy fifo_percent() always -1 + +Sun Feb 8 15:50:43 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.5 + * cdrecord.c 1.42 + Copyright -> 1998 + fs Reference in fifo_percent() removed + fifo_percent() in wm_packet new + +Sun Feb 8 13:54:25 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.23 + fs= - administrative part + .au & .wav description + better -swab description + +Sun Feb 8 13:30:33 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.16 + Fix for sendcommand() befor scsi_getbuf() call + read() < 0 now handled + +Sun Feb 8 13:28:38 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.7 + Definitions for WAVE better + better WAV recognition from Dave + +Sat Feb 7 23:20:14 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.25 + close_track_teac() fixed only audio uses no run-out blocks + +Sat Feb 7 23:18:43 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.41 + rezero_unit() now silent not supported by all drives + +Sat Feb 7 23:14:03 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.35 + Kodak CDR-240 new + +Sun Feb 1 23:17:33 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.8 + HAVE_SHM -> HAVE_USGSHM was a typo + +Sun Feb 1 21:20:48 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.34 + DVD enhancements in mmv_getval() & print_capabilities() + +Sun Feb 1 20:35:06 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.17 + DVD Definitions in Mode Page 2A + +Sun Feb 1 19:56:10 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.15 + scsi_getbuf() hat nun char *ret wegen pointer Aritmetik + sizeof() cast comparison to int + scsi_send(): superfluous ; before scsi_settimeout() removed + +Sun Feb 1 19:45:21 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.40 + filename new in struct track + Errorcode and exit() in audio*size() + +Sun Feb 1 19:44:08 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * auheader.h 1.1 + date and time created 98/02/01 19:44:08 by joerg + +Sun Feb 1 19:44:00 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.6 + auheader.h new + Errorcodes + +Sun Feb 1 19:43:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.27 + filename new in struct track + cd_mode_page_2A *cdr_cdcap new in struct cdr_cmd + +Sun Feb 1 19:42:28 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.12 + * drv_sony.c 1.16 + * drv_mmc.c 1.17 + * drv_jvc.c 1.24 + cd_mode_page_2A *cdr_cdcap new in struct cdr_cmd + +Sun Feb 1 16:03:29 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.16 + ATIP Enhanced + +Sun Feb 1 15:56:31 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.15 + mmv_check() -> mmc_cap()/mmc_getval() + Handle non-trayload drives + warning for dummy/verbose while fixating + +Sun Feb 1 15:49:17 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.16 + DEV_MMC_DVD, DEV_PIONEER_DVDR_S101 new + +Sun Feb 1 15:46:50 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.33 + mmc_getval() & mmv_check() with dvdp + DEV_MMC_DVD new + Pioneer DVD-R S101, TEAC CD-R55S new + allow_atapi() in print_capabilities() + heuristic with speed >= 176 according to mmc2 + +Sun Feb 1 15:46:17 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.39 + better CD-Recorder warning + +Sun Feb 1 14:53:02 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.38 + Honour file sizes + better usage() Output + .au & .wav Filesize recognition + early recognition of "incompatible medium" + sched_setscheduler() error code (< 0) is correct + +Sun Feb 1 14:39:27 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.26 + mmc_getval() & mmv_check() with dvdp + TI_WAV & is_wav() removed + +Sun Feb 1 14:33:39 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.5 + Complete recognition of a Wavheader (with Hilfe from Heiko) + +Mon Jan 26 01:56:21 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.4 + valloc() re-implemented (not available in AIX libc) + scsi sense handling ready + +Mon Jan 26 01:51:58 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.32 + mmc_cap(), mmc_getval() new + Strings for printcap() static for K&R + +Mon Jan 26 01:07:27 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.4 + Filesize - header for Sun .au Files, data_size is not always correct + +Sun Jan 25 23:08:00 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.3 + Sun .au Header new + +Sun Jan 25 22:58:58 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.25 + TI_NOWAV -> TI_NOAUHDR, is_auname() & ausize() new + +Sun Jan 25 18:10:47 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.24 + TI_NOWAV, mmc_cap() & mmg_getval(), is_wavname() new + +Sun Jan 25 16:16:23 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.2 + is_wavname() new + +Sun Jan 25 16:02:26 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * audiosize.c 1.1 + date and time created 98/01/25 16:02:26 by joerg + +Sun Jan 25 13:38:40 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.23 + Errortexts for CD-R55S + +Sat Jan 24 17:52:52 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_packet.c 1.4 + * fifo.c 1.7 + Honour file sizes + +Fri Jan 23 02:08:22 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.14 + scsi_initdev() new to allow concurrent cdrecord's + +Fri Jan 23 02:04:01 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.22 + * drv_mmc.c 1.14 + * drv_sony.c 1.15 + * scsireg.h 1.16 + * scgio.h 2.12 + Uint for Bitfields -> Ucbit + +Sun Jan 18 14:25:01 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.19 + flush() calls to correctly mix stderr/stdout + +Sun Jan 18 14:23:33 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.23 + TI_WAV, is_wav(), wavsize() nee + +Sat Jan 17 22:07:03 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.22 + * cdrecord.c 1.37 + -reset Option new + +Sat Jan 17 21:53:58 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.22 + F_RESET, F_PRATIP, F_PRDINFO, SES_UNDEF new + Definitios for disk status and session status + dstat_t enhanced + CDR_NOLOLIMIT & CDR_ALLOC new + fifo_percent(), allow_atapi(), mode_sense_??()/mode_select_??() new + +Sat Jan 17 21:35:54 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.6 + undef FIFO if no shared mamory + SHM_LOCK for Linux + Stat buffer for fifosize + removed sp->cont because it is not secure (use diff) + fifo_percent() new + +Sat Jan 17 21:20:57 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.36 + -reset new + fifo_percent() printing for -v + +Sat Jan 17 21:09:24 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.21 + Better description of dev= and -scanbus + +Tue Dec 23 01:26:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.31 + Plextor PX-R24CS + S&F CD-R2006PLUS + Wearns CDR-632P new + +Tue Dec 23 01:23:34 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.30 + Uint in Bitfields -> Ucbit + +Thu Dec 11 19:30:31 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.18 + Print command execution time for each failed (non-silent) command + +Sun Nov 9 18:33:48 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.13 + Remove get Page 0x2A for Matsushita CW-7502 + has_mode_page() checks "current" instead of "default" + +Sat Nov 8 16:11:51 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.35 + Disk size check -> checkdsize() : new + +Fri Nov 7 00:02:20 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.3 + timeout counts in seconds + +Fri Nov 7 00:04:11 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.15 + * scgio.h 2.11 + * scsi_cdr.c 1.29 + * drv_sony.c 1.14 + * drv_mmc.c 1.12 + * drv_jvc.c 1.21 + u_char in Bitfields -> Uint + +Thu Nov 6 20:27:08 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.7 + Typo __AIX -> defined(_IBMR2) || defined(_AIX) + +Thu Nov 6 20:26:23 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.2 + sccsid[] -> __sccsid[], fd -> f Typo, #include <malloc.h> + +Thu Nov 6 20:22:14 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.20 + Typo corrected + +Thu Nov 6 20:19:26 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.17 + * scsierrs.c 2.14 + * scsi_cdr.c 1.28 + * scsi.c 1.4 + * drv_sony.c 1.13 + * drv_philips.c 1.11 + * drv_mmc.c 1.11 + * drv_jvc.c 1.20 + #include <mconfig.h> for AIX + +Thu Nov 6 20:18:25 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.34 + #ifdef RLIMIT_NOFILE fuer AIX + +Wed Nov 5 18:01:32 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.19 + Better doc for fs= + +Wed Nov 5 17:57:50 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.10 + msf_to_lba() new, get_diskinfo() new, di_to_dstat() new, getdisktype_mmc() new, additions for Matsushita CW-7502 + +Wed Nov 5 17:43:41 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.5 + switch -> if then else + +Wed Nov 5 17:15:45 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.33 + init struct disk_status, better aritmetic for disk size + +Wed Nov 5 17:14:29 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.4 + print FIFO min fill in percent + +Tue Nov 4 11:20:22 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.26 + return (mode_select_g0(dp, cnt, smp, pf)) was missing in mode_select() + +Tue Nov 4 10:35:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.13 + Check for NULL at return of valloc() + +Tue Nov 4 00:13:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.19 + New flag CDR_NO_LOLIMIT + +Sun Nov 2 16:17:10 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.25 + SCSI mode(6/10) conversion for ATAPI, distinguish between S&F 2006PLUS / S&F 2006PLUS + +Sun Nov 2 14:57:57 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.16 + Print finish time + +Sun Nov 2 14:54:50 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.10 + i_to_4_byte new + +Thu Oct 23 19:21:19 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.6 + AIX Support + +Thu Oct 23 19:20:25 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-aix.c 1.1 + date and time created 97/10/23 18:20:25 by joerg + +Thu Oct 23 19:12:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.9 + Enhancements for packet writing + +Thu Oct 23 01:35:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.18 + New options -prcap, -packet, pktsize =#, -noclose + +Wed Oct 22 23:50:44 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.18 + * wm_packet.c 1.3 + * cdrecord.c 1.32 + fflush(stdout) -> flush(), flush() after Fixating... + +Wed Oct 22 23:49:12 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.24 + scsi_close-session() -> scsi_close_tr_session() + +Wed Oct 22 23:49:11 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.21 + scsi_close-session() -> scsi_close_tr_session() + +Sun Oct 19 15:41:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.23 + * cdrecord.c 1.31 + Prevent medium removal problems fixed (read TOC) & Matsushita CD-750? + +Sun Oct 19 15:40:32 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.15 + Matsushita CW-7501 & CW-7502 + +Sun Oct 19 02:08:53 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.12 + * drv_philips.c 1.10 + * drv_jvc.c 1.17 + * wm_packet.c 1.2 + * cdrecord.h 1.20 + * cdrecord.c 1.30 + next_wr_address() has track_t * added + +Sun Oct 19 01:37:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.16 + read_disk_info() -> read_disk_info_teac(), zero pre-gap audio support, opt_power_judge() timeout -> 60 sec + +Sun Oct 19 01:33:21 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.22 + read_disk_info() new, print_capabilities() new + +Sun Oct 19 00:40:36 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.29 + * cdrecord.h 1.19 + get_buf() new, -prcap & print_capabilities() new, -packet new, pktsize=# new + +Sun Oct 19 00:36:32 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * wm_track.c 1.1 + * wm_session.c 1.1 + * wm_packet.c 1.1 + date and time created 97/10/18 23:36:31 by joerg + +Sat Oct 18 19:14:05 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.3 + stdlib.h -> stdxlib.h, unistd.h -> unixstd.h + +Sat Oct 18 01:34:19 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * modes.c 1.3 + Ausgabe der Mode Parameter wenn mode_select() nicht klappt & return FALSE + +**** 1.6a3 *** + +Sun Oct 12 20:00:21 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.17 + * cdrecord.c 1.28 + New options pregap= defpregap= + +Sun Oct 12 19:30:45 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.18 + is_first() & is_last() new + +Sat Oct 11 18:01:28 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.27 + islast debug printf deleted + +Sat Oct 11 17:57:43 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.21 + * drv_sony.c 1.11 + * drv_philips.c 1.9 + * drv_mmc.c 1.8 + * drv_jvc.c 1.15 + * cdrecord.h 1.17 + * cdrecord.c 1.26 + islast for TEAC & no run-out blocks for disksize computing + +Sat Oct 11 14:54:03 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.14 + OLD_CLOSE_TRACK re-aktiviert, clear_subcode() in open_track(), set_limits() in open_track() for audio without run-out, dummy sector -> static to be zeroed + +Thu Oct 9 14:14:24 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.13 + Audio Tracks have no link&run-in + +Thu Oct 9 02:01:23 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.12 + SWABAUDIO Flag new + +Wed Oct 8 17:24:40 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.20 + * drv_sony.c 1.10 + * drv_philips.c 1.8 + * drv_mmc.c 1.7 + * cdrecord.h 1.16 + * cdrecord.c 1.25 + Modification of data structures for JVC/TEAC + +Wed Oct 8 17:23:41 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.3 + WRITER_MAXWAIT 20 -> 120 s + +Wed Oct 8 17:14:04 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.11 + Enhancements for audio and multi track disks + +Wed Oct 8 14:48:06 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.16 + Better doc for padsize & fs= + +Mon Oct 6 20:37:39 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.10 + Modified to use pad_track() + +Mon Oct 6 20:32:11 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.24 + In pad_track(): if (bytesp != 0) check was missing ->coredump + +Mon Oct 6 20:29:22 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.19 + SMART&FRIENDLY CD-R2006 + +Sun Oct 5 16:53:45 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.6 + verbose printing modified + +Sun Oct 5 16:53:09 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.23 + Check for bytesp != 0 in pad_track() + +Sat Oct 4 01:09:56 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.22 + realtime raisepri Problem for HP-UX fixed (function present bot not working) + +Fri Oct 3 21:33:13 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.18 + * drv_sony.c 1.9 + * drv_philips.c 1.7 + * drv_mmc.c 1.5 + * drv_jvc.c 1.9 + * cdrecord.h 1.15 + * cdrecord.c 1.21 + * cdrecord.1 1.15 + * cdr_drv.c 1.5 + new option blank=type for CD-RW + +Fri Oct 3 16:23:00 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.20 + pad_track() new, await_faio() new & init_faio() befor wait loop, always pad to 300 sectors , padsize= option new, DEFAULT_FIFOSIZE new + +Thu Oct 2 02:02:10 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.2 + MIN_BUFFERS -> 3, await_faio() new, kill_faio() new, stdin EOF check, Messages only for debug + +Thu Oct 2 01:38:39 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.14 + padsize Option new, nice --18 bug, 's' & 'f' mult for getnum() + +Thu Oct 2 01:31:28 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.8 + sleep()'s added to cure fixating problems ??? + +Thu Oct 2 01:19:46 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.14 + DEFAULT_FIFOSIZE, roundup(), tracksize & padsize -> long, pad_track() new, await_fifo() & kill_fifo() new, minutes() cast to int + +Wed Sep 24 00:02:39 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.19 + Fifo & tracksize Option + +Tue Sep 23 23:46:27 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.7 + Bug with resid != 0 fixed + +Sun Sep 21 23:20:15 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.13 + fs= Option, tsize= Option, mkisofs | cdrecord with fs= EXAMPLE + +Sun Sep 21 22:58:34 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fifo.c 1.1 + date and time created 97/09/21 21:58:34 by joerg + +Sun Sep 21 22:45:08 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.13 + faio_get_buf() & fifo_stats() + +Sun Sep 21 01:12:43 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.12 + fifo code + +Wed Sep 17 13:55:57 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.7 + Typo in cdr_write_teac() EXPORT -> LOCAL + +Wed Sep 17 13:55:06 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.18 + raisepri() has Parameter (n below Max), _POSIX_PRIORITY_SCHEDULING, _POSIX_MEMLOCK + +*************** Release 1.5 ******************* + +Mon Sep 15 16:46:16 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README 1.9 + Anpassungen fuer release 1.5 + +Wed Sep 10 18:40:49 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.17 + Print always Copyright except for -msinfo + +Wed Sep 10 18:12:59 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.17 + Inquiry debug data indented + Mode Parameters only for verbose + +Wed Sep 10 17:57:32 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.16 + Flags defs von cdrecord.c -> cdrecord.h + load_media() new + load/unload_madia() global + Track verbose output after inquiry + Test errorcodes while burning + Dummy blocks added for close_track() is not an error + -nofix Flag activated + Exit code for burning errors: -2 + Swabaudio automatic + +Wed Sep 10 17:43:12 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.11 + Flag defs from cdrecord.c + getdisktype() with cdr_t * + load_media() new + load/unload_madia() global + +Wed Sep 10 17:42:13 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.4 + * drv_jvc.c 1.6 + getdisktype() with cdr_t * + +Wed Sep 10 17:41:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.6 + philips_getdisktype() new for automatic eject on "Command Sequence Error" + +Wed Sep 10 16:50:56 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.12 + Scsibus , typo removed + +Wed Sep 10 15:10:03 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.11 + 1.4 -> 1.5 + +Wed Sep 10 15:04:26 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.8 + new_track_sony() return valoe corrected + +Wed Sep 10 15:03:36 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.10 + Changes for cdrecord-1.5 + +Thu Sep 4 19:26:00 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.12 + Use channel on multi channel controlers + +Thu Sep 4 19:09:10 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.5 + * drv_sony.c 1.7 + * scsi_cdr.c 1.16 + inq.ansi_version -> inq.data_format for all mode_select() calls + for Philips CDD-522 (version == 1 , format == 2) + +Wed Sep 3 02:00:33 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.11 + scsi_mapbus() new + better timeout handling + copy Struct now automatic Variable + Sense Data error = SCG_RETRYABLE + +Mon Sep 1 01:25:16 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.6 + * scsi-linux-sg.c 1.10 + * scsi-hpux.c 1.4 + * scsi-bsd.c 1.4 + Last tuning make all implementations equal + Open only one file if possible. + Better bound checking + +Sun Aug 31 23:21:06 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-hpux.c 1.3 + Array again has 8 Luns + havebus tests bounds + +Sun Aug 31 23:18:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.5 + MAX_* introduced, open max 1 lun (for now) + +Sun Aug 31 20:14:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-hpux.c 1.2 + MAX_LUN now 1 + +Sun Aug 31 20:10:25 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-hpux.c 1.1 + date and time created 97/08/31 19:10:25 by joerg + +Sun Aug 31 18:00:16 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.5 + HP-UX added + +Tue Aug 26 19:37:15 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.15 + init dp in main now correctly + +Tue Aug 26 17:50:20 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.4 + Support complete without using -lds + +Tue Aug 26 17:47:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.15 + scsibus/target/lun now now -1 if bus is scanned + to make sure that not ony one target can be opened. + +Tue Aug 26 17:46:22 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.14 + test_unit_ready() after select_target() (SCANBUS) + +Tue Aug 26 01:47:41 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.3 + unused includes removed + +Mon Aug 25 22:02:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.9 + * scsitransp.c 1.15 + * scsi-sgi.c 1.2 + * scsi-linux-sg.c 1.9 + * scsi-bsd.c 1.3 + errno -> ux_errno in scg_cmd for POSIX multithread + +Mon Aug 25 21:27:55 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-sgi.c 1.1 + date and time created 97/08/25 20:27:55 by joerg + +Mon Aug 25 18:10:12 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.13 + raisepri() not always done + +Sun Aug 24 22:58:37 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.4 + First pre-aplha makes one data track only + +Sun Aug 24 17:03:05 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.12 + New options: driver=name -checkdrive -inq -scanbus -nofix + set_trsizes() later + get_cdr_cmds() new + first simple sizecheck + "swap" output from print_data_track() removed + +Sun Aug 24 16:54:31 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.10 + struct disk_status new + is_unknown_dev() new + is_mmc() new + mmc_check() new + set_cdrcmds() new + +Sun Aug 24 16:53:09 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.14 + is_unknown_dev() new + is_mmc() new + mmc_check() new + open_scsi() modified for scsi_scan() + Device recognition new for CD-R + scsi_load() now correct + +Sun Aug 24 16:22:22 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.9 + -nofix new + driver=name new + -checkdrive new + -inq new + -scanbus new + Sense Output uses new form + +Sun Aug 24 16:19:42 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.4 + CDR_SWABAUDIO new + cd_mode* pages -> scsireg.h + identify_mmc() uses mmc_check() + +Sun Aug 24 16:18:00 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.3 + set_cdrcmds() new + get_cdrcmds() enhanced + +Sun Aug 24 15:47:30 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.6 + * drv_philips.c 1.5 + CDR_SWABAUDIO Flag new + +Sun Aug 24 14:51:43 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.14 + CDD-2000 & CDD-2600 new + MMC Definitionen new + +Sun Aug 24 14:18:47 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.14 + CD mode pages 05 & 2A + +Sun Aug 10 19:29:38 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.4 + * drv_sony.c 1.5 + * drv_mmc.c 1.3 + * cdrecord.h 1.9 + * cdrecord.c 1.11 + cdr_driver -> cdr_drname + cdr_drtext + open_track() with track_info * instead of many arguments + +Sun Aug 10 18:10:14 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.13 + LOAD (A6) command now uses correct SCSI definition + +Sun Aug 10 17:43:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.8 + Buffer overflow in sg_rq corrected + timeout corrected (semicolon past if) + 12 Byte Hack now OK + +Sun Aug 10 17:42:06 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.8 + SCSI g5 command struct now ansi compliant + +Sun Aug 10 17:40:30 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.4 + SGI include + +Fri Jul 18 13:41:46 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.12 + read_capacity() new + scsi_load_unload() new + scsi_set_sped() new + write_xg1() new + read_toc() for SCSI-3 new + read_toc_philips() from old name + read_track_info() -> read_track_info_philips() + read_track_info() new + scsi_close_session() new + first_writable_address() with address Pointer + read_tochdr() with cdr_t * ???? + read_session_offset() with offset Pointer + Version for SCSI-3 + is_cdrecorder() removed, Taiyo Yuden new + +Fri Jul 18 12:35:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.7 + with new ioctl() SCSI_IOCTL_GET_BUS_NUMBER more SCSI busses + +Fri Jul 18 02:49:46 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.8 + -version + better -isosize Doku + -multi warning removed + +Fri Jul 18 02:44:11 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.10 + fix_it now past open_session() + next_writable_address() and read_session_offset() now with adress Pointer + -version usage() + superfluous argument removed with lout + +Fri Jul 18 02:31:23 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.8 + * drv_mmc.c 1.2 + SCSI-3/mmc first implementation + +Fri Jul 18 02:25:10 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.3 + * drv_philips.c 1.3 + * drv_sony.c 1.4 + next_writable_address now has adress pointer + read_session_offset_philips() extracted + +Thu Jul 17 18:12:43 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.2 + ifdef for BSD SENSE bug + +Thu Jul 17 17:43:10 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isosize.c 1.3 + filedescriptor sense (seek) test. + +Tue Jul 15 21:27:29 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isosize.c 1.2 + & before vd.vd_type deleted + +Tue Jul 15 21:26:57 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.3 + & before mode deleted + +Tue Jul 15 21:16:46 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.9 + version string + write_track_data() with startsec parameter + cd_recorder/drive recognition now uses cdr_t + print_toc() with cdr_t parameter + open_session() with multi parameter + Progress printing in write_track_data() now uses correct rounding + dbtype with -multi corrected + read_session_offset() with cdr_t parameter + print_toc() prints sector numbers correctly and 'lout' for 0xAA + +Tue Jul 15 13:34:04 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.2 + drive_identify may modify cdr_t struct pointer + Yamaha CDR-400 correct with cdr_mmc + +Tue Jul 15 13:24:49 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.2 + * drv_jvc.c 1.2 + * drv_sony.c 1.2 + open_track() with dbtyp arg + open_session() with multi arg + struct cdr_t driver flags filled in + driver type string + +Tue Jul 8 19:42:42 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.6 + /dev/sg0 ... tested too + +Tue Jul 8 18:00:39 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-bsd.c 1.1 + date and time created 97/07/08 17:00:39 by joerg + +Tue Jul 8 17:59:20 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.3 + New Implementation for *BSD + +Sun Jun 22 19:58:40 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.11 + Smart & Friendly Support + +*************** Release 1.4 ******************* + +Sat Mai 21 19:58:42 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.7 + Updates for release 1.4 + +Sat Mai 21 18:11:25 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.2 + scsireg.h Include + +Sat Mai 21 00:52:33 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_sony.c 1.1 + date and time created 97/05/20 23:52:33 by joerg + +Sat Mai 21 00:27:56 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_philips.c 1.1 + date and time created 97/05/20 23:27:56 by joerg + +Sat Mai 21 00:27:50 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_mmc.c 1.1 + date and time created 97/05/20 23:27:50 by joerg + +Sat Mai 21 00:27:43 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * drv_jvc.c 1.1 + date and time created 97/05/20 23:27:43 by joerg + +Sat Mai 21 00:27:14 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.10 + mode_select() uses inq.ansi_version >= 2 + +Sat Mai 21 00:26:42 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.7 + attach_unknown() new + +Sat Mai 21 00:26:05 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdr_drv.c 1.1 + date and time created 97/05/20 23:26:05 by joerg + +Thu Mai 19 23:46:54 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.8 + Struct track -> cdrecord.h + DB_XXX Data block types + cdr_cmd Struct as Drive Abstraction Layer + -eject Flag + checktsize() new + CDR_SPEED & CDR_DEVICE + +Thu Mai 19 16:59:44 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.6 + struct track from cdrecord.c + DB_XXX Data block types + cdr_cmd Struct as Drive Abstraction Layer + +Thu Mai 19 15:42:53 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.9 + Prototypes lokal too + scsi_load_unload() -> load_unload_philips() + start_stop_unit() now with eject + close_track_philips() new + recover with track parameter + mode_sense() new + speed_select splitted + inquiry news new drives + scsi_cdr_write() + +Mon Mai 16 15:46:48 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * config.h 1.1 + date and time created 97/05/16 14:46:48 by joerg + +Mon Mai 16 15:46:48 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.1 + date and time created 97/05/16 14:46:48 by joerg + +Fri May 23 22:09:21 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.14 + bad 2. Parameter in gettimeofday -> struct timezone * + +Fri Apr 23 22:08:16 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.13 + missing %s in Formatstring added + +Wed Apr 14 00:54:03 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.13 + new scsi device types + +Wed Apr 14 00:53:28 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.13 + scsireset() into hack part + scsi_setnonstderrs() new, scsierrmsg() chganges + new scsi devicetype codes, Solaris x86 dmasize without gethostid() + +Wed Apr 14 00:46:27 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.10 + Changes for scsierrs.c enhancements + +Wed Apr 14 00:45:26 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.12 + Enhancements for SCSI-2 & SCSI-3 + +Tue Apr 6 17:15:43 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.13 + Different order & Yamaha CDR-400, Sony CDU-924, Ricoh RO-1420, Teac CD-R50 new + +Tue Apr 6 16:36:38 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.7 + Enhancements for SCSI-2 & SCSI-3 + +Tue Apr 6 14:10:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.5 + CCD-> CCS Typo + +Tue Apr 6 13:59:16 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.2 + scsireset() -> transport specific part + +Tue Apr 6 13:59:16 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.4 + scsireset() -> transport specific part + +*************** Release 1.3 ******************* + +Fri Mar 4 19:48:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README 1.6 + Changes for Release 1.3 + +Fri Mar 4 18:57:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.6 + release 1.3 + +Fri Mar 4 18:46:37 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.5 + Changes for Release 1.3 + +Fri Mar 4 11:55:28 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.3 + scsihack.c & scsi-linux-sg.c splitted + +Fri Mar 4 11:53:59 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsihack.c 1.1 + date and time created 97/03/04 10:53:59 by joerg + +Fri Mar 4 11:52:42 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.2 + Quick hack for ANSI C + +Wed Mar 2 17:16:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.8 + open_scsi() with verbose arg + write_track() & write_track_info() isaudio/preemp -> sectype + read_toc() new, read_header() new, read_track_info() new + first_writable_addr() now working + read_tochdr() new, read_trackinfo() new, read_session_offset() new + is_cddrive() new read_scsi() now korrekt with G0_MAXADDR & cnt < 256 + HACK XXX scsi_capacity to 2048 bytes Sectorsize initialized for mkisofs-1.10 + +Wed Mar 2 16:51:24 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.12 + BAD -> EX_BAD, BOOL scsi_havebus() new + scsi_fileno(bus, tgt, lun) new with 3 Parameters, MAX_DMA_SUN386 new + +Wed Mar 2 16:46:44 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.2 + better Kommentar + +Wed Mar 2 16:35:04 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.9 + BOOL scsi_havebus() new, scsi_fileno(bus, tgt, lun) new with 3 Parameters + +Wed Mar 2 16:33:18 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.6 + intriduced _SCGIO_H & bei __STDC__ 0xFF000000UL + +Wed Mar 2 16:14:35 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsidefs.h 1.12 + BAD -> EX_BAD + +Wed Mar 2 16:14:04 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * port.c 1.6 + include fmt.h only if #ifdef FMT + +Wed Mar 2 16:07:53 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi-linux-sg.c 1.1 + date and time created 97/03/02 15:07:53 by joerg + +Wed Mar 2 15:49:56 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.1 + date and time created 97/03/02 14:49:56 by joerg + +Wed Mar 2 15:48:55 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isosize.c 1.1 + date and time created 97/03/02 14:48:55 by joerg + +Wed Mar 2 15:40:32 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.7 + toctname[] * sectname[] new + ldebug -> debug, HAVE_MLOCKALL, -msinfo new, -toc new + -audio/-mode2/-xa1/-xa2/-cdi new, -isosize new + better Check for options, print_msinfo() new, print_toc() new + HAVE_SYS_PRIOCNTL_H new + +Wed Mar 2 15:30:26 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.h 1.5 + BAD -> EX_BAD in standard.h, TOC_* defines, ST_* defines, struct msf + several Interface changes for Prototypes + +Wed Jan 19 00:23:11 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.6 + Changed to use scsi_buf_size() & scsi_getbuf(), better gcc Kompat. + +Wed Jan 12 23:11:18 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.11 + Sbufsize -> long, scsi_maxdma() new + +Wed Jan 12 22:10:33 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.8 + Sbufsize -> long + +Fri Jan 7 21:10:26 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * port.c 1.5 + ANSI C & printf %ld + +Thu Jan 6 22:45:03 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.7 + scsi_sense_key() & scsi_sense_code() from fmt.c + +Thu Jan 6 22:45:02 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.10 + scsi_sense_key() & scsi_sense_code() from fmt.c + +Mon Jan 3 14:47:53 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.h 1.6 + scsi_bufsize() & scsi_getbuf() new + +Mon Jan 3 14:47:52 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.9 + scsi_bufsize() & scsi_getbuf() new + +Fri Dec 31 17:16:13 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsireg.h 1.12 + Defekt List: length & list_block -> char[] for Byteorder + +Tue Dec 28 20:51:42 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.5 + #error beseitigt for SunOS cc + +Tue Dec 28 14:28:01 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsitransp.c 1.8 + debug -> kdebug + +Tue Dec 28 14:19:16 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scgio.h 2.4 + debug -> kdebug + +Sun Dec 19 16:18:18 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.7 + Mitsumi + +Sun Dec 19 16:14:12 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README 1.5 + Performance X86 & Mitsumi + +Sat Dec 18 12:37:38 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.11 + param.h, sys/buf.h, sun/dklabel.h, sun/dkio.h eliminated + +Sat Dec 18 03:26:04 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README 1.4 + Changes for Release 1.2 + +Sat Dec 18 03:24:14 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.1 1.4 + Changes for Release 1.2 + +Sat Dec 18 03:13:41 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * cdrecord.c 1.5 + -swab new + LOCAL functions + timings, new timeout for fixating + countdown timer before Start + write_track_info() disabled + -pad for audio, pad to 2352 bytes. + +Sun Dec 12 21:09:24 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi_cdr.c 1.6 + Flush cache & Fixation with big Timeout. + +Thu Nov 26 10:54:18 1996 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsierrs.c 2.10 + New Codes for CDD-2000 & Support for Yamaha CDR-100 + +Mon Dec 16 16:19:54 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Added -swab option to support Yamaha audio + Thanks to (Fred) vecoven@montefiore.ulg.ac.be + for the hint. + * Added counter for quit time (9 seconds) + +Wed Dec 12 21:09:24 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Flush cache & Fixation with separate bigger timeout, + other timeout reduced to 20sec. + +Mo Dec 3 13:03:30 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Set sector size on all drive types before writing, + * Omwith the write_track_info Mode Select before write_track + even for Philips drives (this is currently not needed because + we don't support ISRC codes at this time). + +Tue Nov 26 10:54:18 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * New error codes for CDD-2000 & error code support for Yamaha CDR-100 + +Sun Nov 3 22:58:21 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * scsireset() aded to scsitransport.[hc] + * Timings for Track and Fixation + +Fri Oct 4 11:45:13 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Version 1.1 released. + +Mon Aug 19 22:25:18 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Read access test to allow cdrecord to run savely suid root + +Sun Aug 18 12:11:20 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * bit ordering problems solved + Thanks to Gert Poletiek <gert@fwi.uva.nl> for testing + +Tue Jun 18 21:38:51 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * several changes in scgio.h + +Sun Jun 16 15:56:35 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Ansi C Protytypes + * priocntl added for Solaris + Thanks to Anders Lundgren <al@irfu.se> + +Sun Feb 4 19:14:46 1996 J. Schilling <joerg@schily.isdn.cs.tu-berlin.de> + + * Initial release 1.0 @@ -0,0 +1,33 @@ +Frequently Asked Questions about cdrkit +======================================= + +Q: What does "wodim" stand for? +A: It is not a forest troll and not a winner of the inpronounceability + contest. It was simply the next alternative to wom (Writes Optical Media) + which was unfortunately already used by other software products. + +Q: What this name of ... mean? +A: Terminology: some names are based on pure imagination, some on + abbreviations, some on permutations of chars in descriptions. + + genisoimage: Generate ISO IMAGEs + icedax: InCrEdible Audio eXtractor + librols: LIB Remains Of LibSchily + libusal: LIB Unified/Universal Scsi Access Layer + netscsid: NET SCSI Daemon + readom: READ Optical Media (see also wodim) + wodim: see above + +Q: Are there additional depedencies, compared to cdrtools? +A: Yes. Libcap is required on Linux plattform. Libmagic is needed to support + content-based creator/type tables with HFS (optional). Libiconv is needed to + support iconv-based filename converstion, eg. from UTF-8 ins Joliet's UCS-2 + unicode (optional, on plattform where iconv is not already included in the libc + system library). + +Q: Burning dies with (logical unit communication crc error (ultra-dma/32)). + Reason? Solutions? +A: Try enabling DMA for your device. Some CDROM readers/writters seem to send + non-critical UDMA control/error codes without beeing in DMA mode and so + those messages are not interpreted by the kernel but delivered to the + applications instead. @@ -0,0 +1,63 @@ +Forking cdrtools as cdrkit +-------------------------- + + +So, why the fork? CD/DVD burning is a complicated business that needs a +lot of knowledge, so forking such a big collection isn't a step to be +taken lightly. It requires a lot of development effort that could be put to +better use elsewhere. + +In the past, we, the Debian maintainers of cdrtools, had a good and +mutually cooperative relationship with Jörg Schilling. He even +commented on Debian bug reports, which is one of the best things an +upstream maintainer can do. Naturally, there were occasionally +disagreements, but this is normal. + + +Unfortunately Sun then developed the CDDL[1] and Jörg Schilling +released parts of recent versions of cdrtools under this license. +The CDDL is incompatible with the GPL. The FSF itself says that this +is the case as do people who helped draft the CDDL. One current and +one former Sun employee visited the annual Debian conference in Mexico +in 2006. Danese Cooper clearly stated there that the CDDL was +intentionally modelled on the MPL in order to make it GPL- +incompatible. For everyone who wants to hear this first-hand, we have +video from that talk available at [2]. + +You can read the FSF position about the CDDL at [3]. The thread behind +[4] contains statements on the issue made by Debian people; for more +context also see the other mails in that thread. +In short - the CDDL has extra restrictions, which the GPL does not +allow. Jörg has a different opinion about this and has repeatedly +stated that the CDDL is not incompatible, interpreting a facial +expression in the above-mentioned video, calling us liars and generally +appearing unwilling to consider our concerns (he never replied to the +parts where we explained why it is incompatible). As he has basically +ignored what we have said, we have no choice but to fork. While the CDDL +*may* be a free license, we never questioned if it is free or not, as it +is not our place to decide this as the Debian cdrtools +maintainers. However, having been approved by OSI doesn't mean it's ok +for any usage, as Jörg unfortunately seems to assume. There are several +OSI-approved licenses that are GPL-incompatible and CDDL is one of +them. That is and always was our point. + + +For our fork we used the last GPL-licensed version of the program code +from Cdrtools [5] and killed the incompatibly licensed build system. It +is now replaced by a cmake system, and the whole source we distribute +should be free of other incompatibilities, as to the best of our current +knowledge. + + +Anyone who wants to help with this fork, particularly developers of +other distributions, is welcome to join our efforts. You can contact us +on IRC, server irc.oftc.net, channel #debburn, or via mail at +debburn-devel@lists.alioth.debian.org. Our svn repository is +http://svn.debian.org/wsvn/debburn. + + +[1] http://www.opensource.org/licenses/cddl1.php +[2] http://meetings-archive.debian.net/pub/debian-meetings/2006/debconf6/theora-small/2006-05-14/tower/OpenSolaris_Java_and_Debian-Simon_Phipps__Alvaro_Lopez_Ortega.ogg +[3] http://www.gnu.org/licenses/license-list.html +[4] http://lists.debian.org/debian-devel/2006/08/msg00552.html +[5] Cdrtools 2.01.01a08 from May 2006, http://cdrecord.berlios.de @@ -0,0 +1,66 @@ + +Short overview for those who don't read manuals: + +This software is compiled to binary form using a build system based on the +CMake framework. Therefore, the requirements to build this package are: + + - cmake 2.4.3 or newer (available from http://www.cmake.org or maybe as a + package in your Linux distribution) + - GNU make + - working GCC compiler environment + - maybe additional requirements for your operating system, see + doc/platforms/... and FAQ. + Recommended: glibc (Linux standard) or GNU libiconv + +COMPILATION: + +Run: make + +INSTALLATION: + +Run: make install + +To customize the target paths, some variables can be appended to this line: +PREFIX=/opt/cdrkit/latest (default: CMake preset, e.g. /usr/local) +MANSUBDIR=man (default: share/man) + +TROUBLESHOOTING: + +Problem: Linking error. +Solution: Look for missing dependencies. If you installed additional libraries +in non-system paths, they may have a conflict with the system libraries which +are already installed. Make sure that the linker gets the right ones, those +that belong to the headers. For example, if you installed libmagic and libiconv +into /usr/local/{include,lib} and your compiler or linker have different +defaults (eg. they use /usr/lib, /usr/include or intermix them), then you can +set CFLAGS and LDFLAGS vars to override the system defaults, assumed by cmake. +Example: +(AIX5l, /usr/lib is default lib dir but /usr/local/include is preferred by gcc +for headers), command: + make clean + make CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib +(cleaning is important to rerun tests. Alternatively, remove build/CMakeCache*) + +Problem: Library not found +Solution: Install the library and its development files. Depending on the +system distribution they can be shipped in different packages. Install them +all and make sure that the development files match the version of the main +library package. + +Problem: Library not found during configuration though it's installed +Solution: Install the development files, see above for details. + +Problem: Library not found though it's installed with dev files +Solution: Install the development files, see above for details. If you use +non-standard paths not known/searched by Cmake and/or your compiler, pass the +location of the headers in CFLAGS and the libraries via LDFLAGS. See examples +above. + +Problem: None of those hints helps +Solution: Examine the following files: + build/CMakeFiles/CMakeFiles/CMakeOutput.log + build/CMakeFiles/CMakeOutput.log +and look for failed commands. Some checks are expected to fail if the platform +does not provide a certain feature, others must not fail. Look the failing +check and use THE FORCE to find related problems and solutions. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6b24226 --- /dev/null +++ b/Makefile @@ -0,0 +1,72 @@ +ifneq ($(CFLAGS),) +CMAKETWEAKS += ( cd build ; cmake .. -DCMAKE_C_FLAGS="$(CFLAGS)" ) || exit 1; +endif + +ifneq ($(LDFLAGS),) +CMAKETWEAKS += (cd build ; cmake .. -DCMAKE_EXE_LINKER_FLAGS:STRING="$(LDFLAGS)" -DCMAKE_MODULE_LINKER_FLAGS:STRING="$(LDFLAGS)" -DCMAKE_SHARED_LINKER_FLAGS:STRING="$(LDFLAGS)" ) || exit 1; +endif + +ifneq ($(PREFIX),) +CMAKETWEAKS += ( cd build ; cmake .. -DCMAKE_INSTALL_PREFIX="$(PREFIX)") || exit 1; +endif + +ifneq ($(MANSUBDIR),) +CMAKETWEAKS += ( cd build ; cmake .. -DMANSUBDIR="$(MANSUBDIR)" ) || exit 1; +endif + +default_target: all + +DISTNAME=cdrkit-$(shell cat VERSION) +DEBSRCNAME=cdrkit_$(shell cat VERSION | sed -e "s,pre,~pre,").orig.tar.gz + +build/Makefile: + @-mkdir build 2>/dev/null + cd build && cmake .. + +cmakepurge: + rm -rf install_manifest.txt progress.make CMakeFiles CMakeCache.txt cmake_install.cmake + rm -rf */install_manifest.txt */progress.make */CMakeFiles */CMakeCache.txt */cmake_install.cmake + rm -rf */*/install_manifest.txt */*/progress.make */*/CMakeFiles */*/CMakeCache.txt */*/cmake_install.cmake + rm */Makefile */*/Makefile + +clean: + rm -rf build + +tarball: +# if test "$(shell svn status | grep -v -i make)" ; then echo Uncommited files found. Run \"svn status\" to display them. ; exit 1 ; fi + @if test -f ../$(DISTNAME).tar.gz ; then echo ../$(DISTNAME).tar.gz exists, not overwritting ; exit 1; fi + -svn up + rm -rf tmp + mkdir tmp + svn export . tmp/$(DISTNAME) + rm -rf tmp/$(DISTNAME)/debian + tar -f - -c -C tmp $(DISTNAME) | gzip -9 > ../$(DISTNAME).tar.gz + rm -rf tmp + test -e /etc/debian_version && ln -f ../$(DISTNAME).tar.gz ../$(DEBSRCNAME) || true + test -e ../tarballs && ln -f ../$(DISTNAME).tar.gz ../tarballs/$(DEBSRCNAME) || true + +tarball-remove: + rm -f ../$(DISTNAME).tar.gz ../tarballs/$(DEBSRCNAME) ../$(DEBSRCNAME) + +SVNBASE=$(shell svn info | grep URL: | cut -f2 -d' ' | xargs dirname) +release: tarball + svn ci + svn cp $(SVNBASE)/trunk $(SVNBASE)/tags/release_$(shell cat VERSION) + +#%:: +# $(MAKE) $(MAKE_FLAGS) build/Makefile +# $(CMAKETWEAKS) +# $(MAKE) -C build $(MAKE_FLAGS) $@ + +# needs to be explicite, for PHONY and install (AKA INSTALL) file on cygwin +install: build/Makefile + $(CMAKETWEAKS) + $(MAKE) -C build $(MAKE_FLAGS) $@ + +all: build/Makefile + $(CMAKETWEAKS) + $(MAKE) -C build $(MAKE_FLAGS) $@ + +.PHONY: install all + + @@ -0,0 +1,2 @@ +build/mkisofs/mkisofs -r -J -o /tmp/cd.iso . +build/wodim/wodim -dummy -v speed=24 dev=/dev/cdrw /tmp/cd.iso @@ -0,0 +1,50 @@ + + - on various places in drv_dvd.c, check for the correct answer ("long write in + progress" and friends) instead of using the dumb wait_unit_ready method. + + - (for consideration) similar got natname management in libusal, add a method + to check whether the device can be opened without side effects (for safety) + and then get the device capabilities to select the best drive for the input + size. Kind of generic implementation of the Linux specific guessing code. + + - look for alternative ways to find the maximum DMA transfer size, Schilling + wrote something about SKGETSIZE ioctl being fixed in recent Linux kernel + versions + + - wrong buffer size displayed with MMC5 DVD recorders, works with -prcap + though. Find a way to get the real one when printing status. + + - check OpenBSD issues with OSS libs + + - fix the multi-file in cuefile support at all. First idea: + import libcuefile from on cuetools-1.3.1/src/lib (after generating the + parser with its build system), add CMakeLists.txt, drop cue.c and make wodim + make use of the parsed CUE data if available. + But be warned, JS said something about bugs in cuetools code, a proper test + suite is required. I doubt he will share his test cases. + + Maybe even do it properly and create a track writting strategy preprocessor + module which could be feeded from cue/toc or from CLI options. + But OTOH this is similar to what libburnia is going to make real, spare time + is better invested there. + + - Scale the command timeout with the recommended WRITE command minimum wait + time? See Pioneer specs from DVR-111 for details. + + - check the REMOTE method, especially with real device names and ssh. + Something is going wrong. + OR + Stop supporting it, add a warning to libusal (scsi-remote.c or so) to not + use it, add an appropriate comment to a BUGS file + - check libparanoia, we may link dynamicaly with it. Quality? Portability? + - check notes in help output, drop advisories, notes about future plans... + - find out why spawn.c breaks in WAIT_H while the WAIT_UNION check works quite + well on sys/wait.h. See include/CMakeLists.txt comments. + - wodim -audio wavefile thesamewavefile thesamewavefile fails with obscure + symptoms. Why? See .cue file problems above for that topic. + - make some deflt.h functions inline, use a define wrapper INLINE which is set + empty if the compiler does not support it + - review the sort/uniq code in dvd_file.c, see comments there + - implement -stream-file-name properly. Then close #157962 + + @@ -0,0 +1 @@ +1.1.11 diff --git a/doc/ANNOUNCEMENTs/AN-2.0 b/doc/ANNOUNCEMENTs/AN-2.0 new file mode 100644 index 0000000..c504298 --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.0 @@ -0,0 +1,1607 @@ +NEW features of cdrtools-2.0: + +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +All: + +- Now using the "Slottable Source" feature of the makefile system. + This is the fist modular reusable portable makefile standard + in the open source world. + + To see a new feature call: "make tinfo" + +- config.sub now recognises "parisc-unknown-linux-gnu" + +- Circumvent some problems with GCC-3.0 on Linux + +- Removed printf() definitions from schily.h to avoid type clashes + +- Support for SCO (Caldera) OpenUNIX (aka. UnixWare 8) + +- Better support for Darwin-1.3 and 1.4 + + This is: + + - enhanced makefile system + + - type casts needed for unusual types used on Darwin + (e.g. sizeof() returns long!) + +- Schily support includefiles rearranged to make portability even + easier. + +- mconfig.h now defines IS_SCHILY to signal users of the + Schily makefilesystem, that the Schily portability environment + is being used. + +- now includes the forgotten mkdep-sco.sh that helps to better + work around the SCO C-compiler. + +- timedefs.h modified. Now the last schily portability support include + file hast been reworked to make portability even much easier. + +- schily.h & standard.h have been modified to hopefully finally solve + all type clash problems with size_t & spawn*() + +- Compile support for QNX Neutrino + +- Now we hopefully have floating point support for _all_ platforms + even those without *cvt() and without __dtoa(). Thanks to a hint + from Thomas Langer <Langer.Thomas@gmx.net> we now use strtod.c + to gert a fallback __dtoa() + +- Added an autoconf test for rcmd() so cdrtools now should compile + again on BeOS and AmigaOS where no rcmd() is present. + +- fixed fexec.c to make it compile ion QNX + +- Now the complete libschily is included although it it not needed + for cdrtools. There are two reasons for doing this: + + - Cdrtools is _the_ program that is heavily tested on + many different platforms, so I will get reports for + compile problems this way. + + - cdrtools becomes a base docking platform for the SSPM + system this way. Now any of the Schily tools may be included + and compiled inside the base portability platform 'cdrtools'. + +- New supported architctures: + s390-linux-cc.rul parisc-linux-cc.rul parisc64-linux-cc.rul + +- Large File support for IRIX-6.2 (added autoconf test for -n32 cc option) + +- Large File support for IRIX-6.5 now everything works correctly if the + OS supports Large Files by default in 32 bit mode (uses fseeko()/ftello() + if present. This could only be done by massively changing the autoconf code + stolen from GNUtar. + +- Support for SGI IRIX platform ip17-irix + +- Support for SGI IRIX-6.5 + +- Try to support recent BeOS (again) + + - Workaround in libschily/comerr.c for the nonstandard + big negative errno values on BeOS + +- libschily now includes floating point printf() for BeOS + +- fileluopen.c from libschily now compiles on BeOS (without O_NDELAY) + +- workaround for the nonstandard negative errno values on BeOS + +- Schily makefile RULES for AmigaOS added + +- getpagesize() emulation for BeOS to make cdda2wav compile on BeOS + +- New rule allows automatic fallback to GCC if the configured + default compiler could not be found. + +- statdefs.h enhanced + +- Many corrections to give less warnings on SCO Openserver + +- Support for NT-5.1 (WIN XP) added os-cygwin_nt-5.1.id + +- VMS script build_all.com now includes astoll.c so compilation + on VMS should work again. + +- New macros for max/min values of int*_t in utypes.h + +- Limit the different handling of packed bitfields for AIX to AIX CC. + +- Unfortunately fragementation of cdrecord has begun. + I noticed this fact recently when people started to ask me + senseless things which turned out to be a result of + a modified cdrtools source that I have not ben aware of. + + One main goal of cdrtools is to provide a platform indepenant + user interface which cannot be achieved if people change important + parts os the user interface. + For this reason, I changed the license in hope that this will + help at least to keep the user interface the same on all + platforms and on all distributions. + + Please keep in mind that fragmentation in many cases increases + my workload. There is no real reason for a modification, + and (even worse) the people who create modifications do not help + to keep my workload low in order to help me (and Heiko and James) + with the cdrtools project. People should rather contribute to + the project. Cdrtools should be free and actively mantained + in future. With increasing workload, I don't know how to do this. + + +- Add hints that compiling on unknown platforms wil only work if + "smake" is used. + +- Autoconf code for Large file support now handles Linux system include + file bugs that prevented correct behavior on 64 Bit Linux systems. + + +- Better autoconf code for the problems with mlock() & HP-UX-10.20 + +- Better autocheck code for available C-compilers on HP-UX + Now even a fallback from GCC to CC works. + +- Some changes to make compilation on 64 bit systems more correct + +- Added support for GNU Hurd to the Schily Makefilesystem + +- Cast pointerdiffs to int for printf() %.*s format and/or include + workarounds for 64 bit problems in this area. + +- Several modifications to make OS/2 work again + (e.g. -lsocket added) + +- fexec.c now uses a configurable PATH environment separator + to allow PATH lookup on OS/2 + +- A 20 year old extension has been removed from format.c + This caused printf() to interpret %X as %lX. This caused noticable + problems on IA-64. It should have created problems on True64 + and on 64 bit Sparc programs too but was not directly visible + due to a different stack content. + +- remove #elif to avoid a GCC-3.x warning + +- config.sub now knows about IA64 architecture + +- Makefilesystem now spports compiler specific optimization flags + +- Align_test.c now creates a better include file (using more () to + make sure the compiler created correct code). + +- Makefilesystem changed $(MAKE) to "$(MAKE)" to allow spaces + in pathnames + +- Correct autoconf test for broken OS like MAC OS X that do not + allow local malloc() implementations due to linker bugs. + +- Add autoconf test for strange clock_t definition method on Linux + +- README.ATAPI enhanced for all platforms + +- README.ATAPI now contains a hint on how to use ATAPI drives on HP-UX-11.x + +- Support for FreeBSD on Ultrasparc added to the makefile system + +- *roff'd man pages in .../doc dir re-created + +- Try to work around a bug in OpenBSD. + OpenBSD defines EOF in ctype.h but POSIX only mentions an EOF definition + for stdio.h. If we include ctype.h bfore schily.h on OpenBSD while + stdio.h has not been included, this will fail. + +/*--------------------------------------------------------------------------*/ + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +- The paranoia code from cdparanoia (written by Monty xiphmont@mit.edu) + has been converted into a portable library. + +/*--------------------------------------------------------------------------*/ + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +- Changed to allow compilation on K&R compilers too + +- Speedup by 300% + The speedup is nearly processor independant. + + Pentium-233 2443 sectors/s 32x + 333Mhz-UltraSparc-IIi 6402 sectors/s 85x + 900Mhz-UltraSparc-III+ 22813 sectors/s 304x + Athlon-1000 24378 sectors/s 325x + Athlon-1700 40168 sectors/s 535x + + Depending on the speed of gettimeofday(), these numbers may be up to 5% + too low. + +- Code is now put under GPL. + +/*--------------------------------------------------------------------------*/ + +Libscg: + +- Trying to add a workaround for just another bug in the + sg driver in the Linux kernel. If a TIMEOUT occurs, + the error code does not indicate a TIMEOUT. + +- Better scg_open() error messages when trying to do scanbus on Linux + and no /dev/sg* or /dev/pg* could be opened. + +- Output Request Sense buffer with -debug when the USCSI interface is + used on Solaris. + +- First attempt for support for the new IOKit SCSI interface on MaxOS X + Darwin-1.4 and newer with much much help from + Constantine Sapuntzakis <csapuntz@Stanford.EDU> + + Unfortunately there is not yet support for SCSI devices nor + is there support for standard Bus,Target,Lun device namings. + I hope that bot may be added in the future. + + Volunteers who like to help with the libscg interface stuff + for Darwin-1.4 are welcome. + +- Try to make scsi-beos.c compile on new BeOS version 5 + +- First attempt to integrate the AmigaOS SCSI transport interface code + from Thomas Langer <Langer.Thomas@gmx.net> + +- Massive modicifation of the support code for SCO OpenServer 5.x + + As the kernel implementation contains several bugs, + the new code will by default not check for hard disks in scan mode. + + The code checks the following environment variables: + + "LIBSCG_SCAN_ALL" To force scanning for all SCSI targets. + "LIBSCG_SCSIUSERCMD" use old SCSIUSERCMD ioctl() + "LIBSCG_MAX_DMA" override MAX_DMA value, value must be number in kB + "LIBSCG_ENABLE_USB" enable access of USB devices + +- Version -> 0.6 + +- Adding support for the CDROM_SEND_PACKET ioctl() from cdrom.c + + Thanks to Alexander Kern <alex.kern@gmx.de> for the idea and first + code fragments for supporting the CDROM_SEND_PACKET ioctl() from + the cdrom.c kernel driver. Please note that this interface in principle + is completely unneeded but the Linux kernel is just a cluster of + code and does not support planned orthogonal interface systems. + For this reason we need CDROM_SEND_PACKET in order to work around a + bug in the linux kernel that prevents to use PCATA drives because + the kernel panics if you try to put ide-scsi on top of the PCATA + driver. + + The code is currently in "status nascendi" but usable with some trade offs. + + To use: call e.g. + + cdrecord -scanbus dev=ATAPI: + + cdrecord -dao -v speed=24 dev=ATAPI:0,0 .... + + Be careful! This code is only needed in order to be able to use + PCATA CD-writers on notebooks because there is a severe kernel bug. + Unfortunately, this bug causes the kernel to hang (and force you + to reboot) if you try to call: + + cdrecord -scanbus + + without the dev=ATAPI: option. + + In this case cdrecord will hang infintely and unkillable + in open("/dev/sg1", 2) => you need to reboot :-( + + Repeat by: Insert a PCATA CD-Writer in a Sony VAIO notebook and run + cdrecord -scanbus. + +- Enhanced list of SCSI Error texts from SCSI standard from 29.5.2001 + +- New callback function to allow execption handling to be done after + the current SCSI command did finish. + +- scsi-aix.c now uses UIntptr_t in alignement macro. + +- Some 64 bit casts in the USCSI code from scsi-sun.c + + For hints on the Linux Packet code in ide-cdrom.c read README.ATAPI + +- Introduce a workaround for a conceptional Bug in the Linux kernel + SCSI implementation. + + Linux is unable to distinct between a target selection timeut (e.g. switched + off target) and a command timeout (e.g. command needs more time than expected). + + If the detected command time is < 1 second, libscg will now assume a dead target. + +- Fix a bug with ATAPI in scsi-vms.c - now the SCSI status byte is OK + Thanks To Eberhard Heuser + +- Allow up to 26 IDE controlers in scsi-vms.c - Thanks to Chip Dancy + +- Do not open all /dev/scg* devices on Solaris if not in Scanbus mode + +- Handle ENXIO in Solaris USCSI interface code as indicator for a + switched off device. + +- Max DMA size for Linux ATAPI Packet interface code corrected. + Max DMA is 128k-1 and not 128k. + +- Support for recently defined new SCSI target types found in SCSI + standard. + +- New help system that lists all SCSI low level transports for a specific + platform together with their properties. + +- Allow consistent usage of alternate SCSI transport layers. + + Now the Solaris USCSI implementation and the (SuSE) Linux ATA implementation + behave similar and both allow dev=<Transport> as well as dev=<Transport>: + for -scanbus, e.g. + + cdrecord dev=USCSI -scanbus + cdrecord dev=USCSI: -scanbus + cdrecord dev=ATAPI -scanbus + cdrecord dev=ATAPI: -scanbus + + all work the same way. + +- Small change for Linux device initialization by request of Linus Torvalds + + The purpose of this change is to support a new SCSI transport interface + for ATAPI in Linux that came up with the latest developer Linux kernels + (e.g. Linux-2.5.43). This interface allows to send SCSI commands directly + to ATAPI drives without using ide-scsi and sg, but it has several pitfalls. + + While Linux allows to use DMA when using ide-scsi and sg if the + sector size is 2048 and the transfer buffer starts page aligned, the new + direct interface never uses DMA (acording to Linus Torvalds). So if you + write audio CDs or data CDs in RAW mode, there is no difference. If you + write data CDs in TAO or DAO mode, using ide-scsi and sg allows much + higher write speed. Note that this may change in future.... + + Notes for use: + + - You need to specify something like dev=/dev/hdc + Note that this is unsupported by libscg. + + - As long as there is no safe way for libscg to find out early that + this new interface is used, libscg may hang a bit on open. + This is caused by the fact that libscg is forced to read + from the open filedscriptor to clean up old Linux sg driver + interfaces. This was never a problem with /dev/sg*, but + when doing the same thing, this causes libscg to read content + from /dev/hd* + + - There is (currently) no way for cdrecord to scan for ATAPI + devices when using this interface. + + As long as this is true, you may want to prefer to use + + cdrecord dev=ATAPI: -scanbus + and + cdrecord dev=ATAPI:0,0 ... + instead. + +- Fix scsi-unixware.c to allow multiple opens. + +- Fixed several typo's. + +- Avoid to read from the media (when using the new experimental + Linux ATAPI transport) while trying to clear old sg driver status. + +- Woraround for Linux kernel design bug: CDROM_SEND_PACKET sets errno + to EINVAL in case SCSI sense key is "Invalid command". + +/*--------------------------------------------------------------------------*/ + +Rscsi: + +- RSCSI now works if the target is a Win32 system. + This is not done by changing rscsi.c but by fixing a bug + in Cygwin! + + The fix to Cygwin's rshd is posted in + + http://sources.redhat.com/ml/cygwin-apps/2001-05/msg00000.html + + Thanks to egor duda <deo@logos-m.ru> + + NOTE that in a few weeks this patch will be integrated into Cygwin + and cdrecord/RSCSI will work out of the box on a recent Cygwin release. + +- Now prints user ID & user Name into DEBUG file + +- Now using signal safe read/write functions. + +- Code now checks for HAVE_NETDB_H (added by request of + "Thomas" <Langer.Thomas@gmx.de> to help with AmigaOS port) + This should indicate whether there is support for rcmd() + in the OS. + +- Make it compile on BeOS + +- changed because GNU Hurd has no MAXHOSTNAMELEN + +- Return "PIPE" for hostname comparison if called from e.g. 'sshd'. + +/*--------------------------------------------------------------------------*/ + +Cdrecord: + +- New option -overburn + + This option has been added as many people seem to be unabe to understand + that they are going to write more than the official disk capacity from + reading cdrecord's output. Oveburnung now is no more done by default! + + NOTE that there even are some drives that prevent you from writing + exactly the official size and stop several hundreds of sectors before. + +- Do not print a warning for writing more than 90 minutes if the media is + a DVD + +- Fix for a problem with setting high priority on Win32 systems. + Thanks to egor duda <deo@logos-m.ru> + +- Sony MMC drives now work in -multi session mode. + There was a bug in cdrecord that was accepted by all other drives. + The bug did cause a temporary bad setup to the drive. + +- I hope that the 90 minute CD capacity warning now will finally + disappear for DVD writers. + +- Old test code removed that prevented cdrecord from being able + to write manually configured indices. Note that the index lists + from the *.inf files with using the -useinfo option alway worked. + +- -force will force cdrecord to ingnore any failed forced OPC. + currently this is only done if the drive does not support + forced OPC. + +- Do forced OPC before blanking a CD-RW + +- Driveropts "burnproof" renamed to "burnfree". + This has been done as this technology now appears in the MMC standard. + +- Cdrecord now shows whether BURN-Free is active. This makes + sense as Ricoh's "Just-Link" is enabled by default. + Unfortunately, the way "Just-link" is implemented is not compliant + with the MMC standard. We will have to wait until I get the needed + information from Ricoh. + +- Support for MMC RAW mode writing. + + This allows to do disk at once recording on Philips drives that + do not support SAO. + + You may write audio tracks in RAW mode. There are some new + and most likely transient options: + + -raw16 Write 2352 Bytes sectors + P+Q Subchannel + + -raw96r Write 2352 Bytes sectors + P+W Subchannel (R-W in raw mode) + + -raw96p Write 2352 Bytes sectors + P+W Subchannel (R-W in packed mode) + + Indices are fully supported in RAW mode. + + MCN & ISRC are not yet suported in RAW mode, they are silently discarded. + + I know that cdrecord currently does not work in RAW/R96P mode. + It is not clear whether this is a bug in cdrecord or in the Plextor + firmware as I did not yet found another drive that claimes to support + RAW7R96P. + + If you find other problems in RAW mode or if you find + new bugs introduced in old write modes, please send a bug report. + +- Cdrecord now checks the properties of the writer. If a specific write + mode is not supported by the writer, cdrecord warns you and makes + a suggestion for a similar alternate write mode. + + With the curent structure of cdrecord, it is not possible to silently + e.g. change the write mode from -dao to -raw96r + +- MMC compliant drives are automatically scanned for supported write modes. + This should help to make cdrecord work without manual static configuration. + My hope is still to have no need to know all drive properties in + advance, so new drives will continue to work as long as they + are standard comliant enough for cdrecord. + + NOTE for GUI implementors: + + the line starting with the text: + + "Checking possible write modes:" + + will go away in the near future. + + The line starting with: + + "Supported modes:" + + will remain and should be checked for possible write modes. + +- Fixed a bug in the option checking that prevented to write + data CD's at all. + + Now only "RAW data" CD's are flagged as expected. + +- Fixed a bug in the Firmware bug recognition system. + This bug did prevent cdrecord to work with Philips drives + when writing in RAW mode. + +- New options -copy & -nocopy to allow to modify the 'copy' bit + in audio subchannel data. + +- -scms option added to the man page and online help. + +- New model to compute SCSI transfersizes + +- -xa1 -xa2 sector typedefinitions changed. + +- Debug messages while checking possible write modes of MMC + compliant made optional. + +- RAW writing scatter sector function made more general + +- New functions to convert between 2448 and 2368 byte sectors + + NOTE: Read README.raw + +- add a forgotten if (xdebug) in drv_mmc.c. + This caused a superfluous write mode debug message to be printed + +- do installation of exit handlers (to reset SCSI state) earlier + +- Cdrecord now does not exit with 0 anymore when interrupted with ^C + during the waittime before starting to write. + +- First CD-Text support (can only copy CD-Text information from master + disk) + + Writing of CD-Text is supported for all drives that support + CD-Text in SAO write mode and for all drives that support + to write in RAW/RAW96R mode (use -raw96r in this case). + + NOTE: Read README.cdtext + +- Circumvent a bug in the system include files from Linux that + makes printf() a macro and prevented compilation with GCC-3.0 + +- Added some #include <stdio.h> to substitute missing printf() definitions + +- SAO/R16 mode removed from tests, it may never occur. + +- Changed some .min defines in structs to .pmin to avoid K&R complier + problems + +- better FIFO debug messages + +- New driver config table for Taiyo Yuden EW-50. + This dive is like a Philips CDD-521 but has been reported to + swab audio data. + +- rscsi client code now uses buffered read to speed up on Cygwin + +- rscsi client code now uses signal safe read/write functions + +- Cdrecod now does not open/close the tray anymore if the disk + is going to be erased. + +- modify -version output if Clone writing support is present + +- A new driver has been added that first checks the media if the drive + supports to write CD & DVD. + +- Behaviour of the function that reads fs= tsize= and similar + corrected. + +- Modified driver interface for better DVD support + +- FIFO Code now checks for HAVE_FORK (added by request of + "Thomas" <Langer.Thomas@gmx.de> to help with AmigaOS port) + +- Better messages when trying to write more than the amount of data + that fits on a DVD. + +- The DVD driver now reports a DVD media back to the high level code. + +- correctly use the buffer capacity code from the driver instead + of the MMC-2 read buffer cap code directly + +- Support for the unusual not ready error code of the CyberDrive CW038D + +- CD-Text Code now also accepts Text File without 4 byte Size header + +- CD-Text file read code now is able to do CRC error correction + Note that only songle bit errors per 18 byte pack. + +- CD-text Autoring support: + + CD-text may now be based on fields found in the *.inf files + created by cdda2wav. + + To create a CD with CD-Text based on information from freedb.org + call: + + 1) cdda2wav -B -v255 -L + 2) cdrecord {-dao!-raw96r} -v -useinfo -text *.wav + + CD-text TODO: + + - Check whether the *.inf files are all from the same CD + and clear some CD-text fields that are only valid if + they relate to one CD only. + + - Add some more fields (mainly a dficiency of cdda2wav) + + - Support multi language text + + - Support character coding other than ISO-9959-1 + + CD-text may be based on fields found in the *.inf files + created by cdda2wav. + + NOTE: Read README.cdtext + +- better messages for CD manufacturer codes that are not in the + latest free Orange forum table. + +- Default usage code is now only 6 lines so the error message + does no longer scroll out the screen. If yu like to get the old + long usage information, call cdrecord -help + +- move 'dd' like number conversion stuff into getnum.c + +- Allow the /etc/default/cdrecord parsing code to be used by + readcd too (as documented in the man page) + +- First support for Plextor's VariRec feature in the PX-W4012 + I am not sure about the final user interface. + For now, call e.g. cdrecord speed=4 driveropts=varirec=-1 + for all audio CDs. Allowed varirec parameters are -2, -1, 0, 1, 2 + VariRec only works at write speed 4. + +- Print the actual current write speed in verbose mode. + +- DVD-R code (undisclosed) now supports: + Vendor_info : 'MATSHITA' + Identifikation : 'DVD-RAM LF-D310 ' + Revision : 'A116' + +- Support for SCMS from *.inf files + Note that you need to use cdda2wav/cdrecord that have fitting versions + because of this change. Otherwise cdrecord may add SCMS copy + protection. + +- RAW mode now honors COPY bit and SCMS coding. + +- Avoid coredump with "cdrecord textfile= non/existant ..." + +- Corrected printf() formats for verbose printing to hold enough + space for media > 1 GB (DVD) + +- Corrected printf() formats to make the write speed non-jumping. + +- If called from a GUI, cdrecord now reads from "stderr" if + the CD-input-data is from "stdin". + If it turns out that stderr is not open for reading, cdrecord + waits to receive a SIGUSR1 + +- Better printouts for the DISC-ids covered by the orange forum embargo. + +- DVD structure structure definition enhanced to reflect + current standard. + +- new option gracetime= + +- Try to abort DAO recording with a flush_buffer() if ^C is hit. + +- Try to make cdrecord behave more polite for platforms (like Cygwin) + that don't support large files when the DVD data to be written + is read from stdin. + + mkisofs ... | cdrecord ... - + + will now work for DVDs on non large file OS + +- Call flush buffer in silent mode to avoid error messages with + cdrecord -toc called on a CD-ROM drive. + +- Avoid core dump is a single .inf file is missing and -text + option is used. + +- Data structures modified to allow new features in the future. + +- Fixed a bug that caused cdrecord to ignore escaped file type + args if they looked like a valid option (e.g.): + + cdrecord dev=0,0 -dao -v -- speed=8 + + "speed=8" should be handled as if it was a filename but was + skipped. + +- Print write mode when starting to write. + I hope that this helps me to understand incorrect "bug reports" + from lazy people who do not include their cdrecord command line. + +- Printing ATIP information is now caused by a separate (internal) flag + and not ny a hack. + +- Do not allow to write to ultra low speed RW media if the drive + is not able to write at 2x or 1x. This may be circumvented + with -force. + +- Do not allow to write to high speed RW media if the drive is not + a high speed RW drive. This may be circumvented with -force. + +- Data structures modified to allow new features in the future. + + Trying to make driver interface simpler and cleaner. This resulted + in a major rewrite of the driver interface. + + - please test if multi session with TEAC CDR-50/CDR-55 + still works. + + As a lot has been changed in the driver interface, please test + if bugs have been introduced! + +- New test that prevents to write CD-RW media too slow + +- Display of current DVD write speed now correct and no more based on + single speed CD but on single speed DVD. + +- Moving SAO/RAW start code from cdrecord.c into drv_mmc.c + allows clean DVD-R/RW driver interface code. + Now cdrecord -dao will work correctly (as expected) even for DVDs + +- speed= option no longer defaults to speed=1 + Each driver now includes a default speed and a maximum speed. + If the maximum speed in the driver is wrong, use -force to overwrite. + + Please send feedback if my assumptions on write speed are wrong: + + - No drive using the Philips CDD-521 command set is faster + or slower than 2x + + - No drive using the Yamaha CDR-100 driver is faster than 4x + No drive using the Yamaha CDR-100 driver is slower than 2x + + - The Tayo Yuden CW-50 is 2x + + - The Kodak PCD-600 is 6x + +- Abort when the last track # of a multi session disk would be > 99 + +- Data structures modified to allow new features in the future. + +- Better bessages for CD-RW where the speed ofthe media does not match + the properties of the writer. + +- Avoid to reload media in -dummy RAW mode. + +- Correctly abort if there was a problem when writing CD-Text in the LEAD-IN. + +- Again: Data structures modified to allow new features in the future. + + This release uses the new data structurec to allow to write ISRC/MCN + in RAW mode. + +- Fixed a bug that caused cdrecord to write a wrong relative time + into the subchannel data when writing audio CDs in RAW mode. + This affected the pregap sectors if pregap size was != 0. + +- Allow cdrecord to write ISRC & MCN even in RAW mode. + +- Allow Simulation driver cdr_simul and dvd_simul to simulate any write + mode. + +- Simulation driver cdr_simul and dvd_simul changed so no reload on the + real background drive occurs. + +- Since last release , the new data structures allow to write + ISRC/MCN in RAW mode. This now makes RAW mode fully usable for + audio CDs. NOTE: if you find any problems with CDs written in SAO + mode, first try to write the same CD in RAW mode if your + drive supports to write in RAW mode. Tere are a lot of drives + that have rotten firmware and create broken CDs in DAO mode. + +- Support for Yahama Audio Master Quality Recording. + + This support is switched on via driveropts=audiomaster + + I am sorry, but I had to do major changes in the MMC + driver in order to be able to support Audio Master. + This may have affected all other driveropts= + too. Please test and keep in mind that I like to have + the mext major release in a few weeks. + + When audiomaster has been specified, BURN-Free recording + is disabled and - as the visible size of the medium + decreases - a second disk size check is done after + Audio Master has been turned on. + +- man page enhanced according to new features + +- Short Usage funtion now includes a hint on how to + obtain the list of possible driveropts= parameters + +- Include the tags + + "VARIREC ", "AUDIOMASTER ", "FORCESPEED " + + In the "Driver flags" line that is visible with + + cdrecord -checkdrive. + +- cdrecord driveropts=help now includes + + "varirec=" and "audiomaster" + + +- Support for writing data sectors in RAW mode has been added + to the GPL#ed version of cdrecord. + Note that writing data sectors in RAW mode is a highly CPU + intense task. For this reason, cdrecord first checks whether + it would be possible to do the requested job reliably. + If it is questionable whether the job could be done in the + desired speed, cdrecord aborts with a related message. + + The max theoretical speed (not including the writing load) + is printed in a new line starting with: "Encoding speed :". + Cdrecord allows half of this speed. + +- Allow RAW writing of data sectors to work correctly without + the need of specifying -data + +- Allow spaces as delimiters between different tags in a single + line in the file /etc/default/cdrecord + +- Support for Ricoh (and others) Just Link + + This support is switched on via driveropts=burnfree + + Note that Just Link is by default swichted on in the drive + but as Just Link may create CDs that are no 100% OK, + cdrecord now by default switches it off. Now you definitely + need to specify driveropts=burnfree to switch Just Link on + again. + + If you call cdrecord dev=... -checkdrive you will see + the TAG "BURNFREE" as a hint that either Burn-Proof or + Just Link is supported. + +- "Turning .... " messages for drive special functiions are + now printed to stdout + +- Limited display (once every 1 MB) of the drives internal buffer + RAM fill ratio. + +- Display the minimal drive buffer fill ratio a the end of the write + process. + +- Display number of predicted drive buffer underruns based on the + fill ratio of the drive buffer (incremented if fill ratio is < 5%). + +- Display average write speed at the end of the write process. + In dao mode, this includes the time needed to write the lead in and + thus is not 100& correct (value is too low). + +- Display of the number of times the Buffer underrun protection + has been active for drives where the manufacturer send me the needed + information (Ricoh, Yamaha, Aopen). It may work for other drives too + but there is no guarantee. + +- Fixed a bug in the driveropts= parsing routine. + +- New driveropts= option "forcespeed". Use with extreme care as this + will force several drives ((Ricoh, Yamaha, Aopen, ...) to write with + the selected high speed although the mediaum is too bad for this + operation. + +- New driveropts= option "tattooinfo". Use together with -checkrive + to retrieve the information about the picture size that will fit. + + The result will be someting like: + + DiskT@2 inner r: 265 + DiskT@2 outer r: 583 + DiskT@2 image size: 3744 x 318 pixel. + +- New driveropts= option "tattoofile=". Use together with -checkrive + to write an image of the right size to disk. + + Read README.DiskT@2 + +- Rearrange the order of the new statistics printing + +- Allow several of the new statistics to be printed even if cdrecord + aborts due to an error. + +- Let the old Philips drive use the common CD media 'reload' function. + +- Try to find out if a drive is MMC, MMC-2 or MMC-3 compliant. + - see cdrecord -checkdrive + +- Suppress printing oof the average write speed if the size of the + tracks is not known prior to start CD writing + +- ATIP printing (cdrecord -atip) enhanced to support Ultra high speed + CD-RW media. + +- Check whether somebody likes to write a Ultra high speed CD-RW on + an improper writer + +- Print MMC conformance level of the drive based on content of + SCSI mode page 2A. + +- Print more information for MMC-2 & MMC-3 drives with cdrecord -prcap + +- The new true CAV Plexwriter 482448 is now supported. + + Please note that it is not easy to write at 48x. You definitely need + a correct DMA setup to optimal values. + + Also note switching on Burn-Proof will reduce the max speed to 40x + so it may be that you don't need Burn-Proof if you simply reduce speed + to 40x manually + +- make sure that using both -copy and -useinfo will not result in unclear state + Instead the content of the *.inf files will be used + +- Simulation driver (cdr_simul / dvd_simul) now uses correct speed ratio + for DVDs + +- Simulation driver now supports fake "Next writable address" function. + +- On Linux usleep() is very unacurate, meter the real sleep time + and cumulate a correction value. This allows the simulation driver + to simulate the correct write speed. + +- Added a note to Heiko Eißfeldt's libedc when printing RAW encoding speed + +- Limit gracetime to 999 seconds and make output correct even for + times > 9 seconds. + +- Corrected a bug in the MMC driver that caused cdrecord to use the + wrong place for current speed when doing MMC/MMC-3 dependant stuff + +- cdrecord -prcap will now use the same format for MMC & MMC-3 drives + rsulting in a better readability. + +- Don't print write time statistics if writing did not yet start + +- Try to handle drives that don't support to write at speed 1 but + will fail if you try to call cdrecord speed=1 ... + +- New option -immed tells cdrecord to set the SCSI "IMMED" flag in certain + commands. + + This option is not needed if your PC has been configured correctly. + However, ATAPI drives usually cannnot do disconnect/reconnect. + As a result, the PC may hang with long lasting commands if the CD-writer + has been connected to the same IDE cable as the harddisk. A correct + solution would be to set up a correct cabling but there seem to be + notebooks around that have been set up the wrong way by the manufacturer. + As it is impossible to fix this problem in notebooks, -immed has been + added. Use this option with care and do not expect cdrecord to work + correctly if it has been called with -immed. + +- -force will not completely removeany speed restrictions for writing in RAW + mode. Instead, only the speed that a single CPU allows will be permitted + by cdrecord. This still has a high potential for a buffer underrun. + By default cdrecord still is limited to half the encoding speed that + a single CPU allows. Even this may result in a buffer underrun on Linux + as Linux does not use DMA for IDE when the sector size is != 2048 bytes + which is true in RAW write mode. + +- If the environment variable "CDR_FORCERAWSPEED" is set, this will have + the same results for RAW speed as using -force. However, -force has more + general effects and should be avoided. + +- Fixed a bug in fifo.c introduced with the driver interface change. + Now cdrecord compiles again on VMS (without FIFO). + Thanks to Eberhard Heuser. + +- Allow cdrecord to compile without libedc + Thanks to Eberhard Heuser. + +- Run read buffer capacity in silent mode. + This is needed because drives with buggy firmware like the CW-7585 + did cause hundreds of "command sequence erorrs" to be emmited when + trying to read the current drive buffer fill ratio. + +- Fixed man page to correctly call SAO mode SAO and not DAO. + +- Encoding speed is contend dependant. Initalize test buffer + before doing a libedc speed test to make the result independant + from grabage on the stack. + +- Support for libscg help system + +- Warn to use cdrecord blank=all if a drive rejects cdrecord blank=fast + +- Fixed a bug that became obvious with Yamaha AudioMaster mode and CD-Text + The problem was caused by the fact that cdrecord did not allow to overwrite + the lead in start time in cdrecord's internal data structures. + +- Fixed a bug with recognition of complete disks that came up after cdrecord + did allow to deal with >= 90 minute CD's. + +- Changed Text "BURN-Free was not used" to "BURN-Free was never needed" because + people did believe that the old text means that Burn-Proof has been disabled. + +- Man page now includes a hint that padsize is always using 2048 as sector size. + +- Fixed a bug with padsize=xxx if sector size was not 2048 bytes. + Cdrecord in this case did just divide the number of pad bytes by the + number of bytes in an output sized sector (e.g. 2448 or 2352 bytes). + This did result in a too low number of padding sectors. + The fix caused a complete rewrite of the pad size handling. + +- Treat packet mode similar to normal writing: Print Drive buffer fill ratio + and current write speed. + +- Treat padding similar to normal writing: Print Drive buffer fill ratio and + current write speed. + +- Make verbose printing consistent and non-jumping + +- A new experimental feature of the -immed flag is to + tell cdrecord to try to wait short times wile writing + to the media. This is expected to free the IDE bus if + the CD/DVD writer and the data source are connected to + the same IDE cable. In this case, the CD/DVD writer + would otherwise usually block the IDE bus for nearly + all the time making it impossible to fetch data from + the source drive. + + As this is an experimental feature, I would like to get feedback. + + +- #ifdef _POSIX_MEMLOCK/_POSIX_PRIORITY_SCHEDULING Tests now + POSIX 2001 compliant + +- Do not try to close fd if running on an OS that does not use an fd + to mmap() chared memory from anonymous pages. + +- Print Orange Forum embargo warning only if ATIP minutes == 97 + because some DVD writer return junk with read ATIP + +- New option minbuf= to choose the mininum drive buffer fill ratio + for the ATAPI wait option that is intended to forcibly free the + IDE bus to avoid buffer underruns with bad HW configurations. + The permitted range is 25..95 for 25%..95% buffer fill ratio. + +- minbuf= may switch on the ATAPI wait option without enabling + the SCSI Immed option. + +- Forcibly switch on -v for now if the ATAPI wait option has been + selected. This is needed because due to a bug, this option will + not work without -v + +- Make FIFO code work on AmigaOS + + +For Yamaha Disk Tatoo features read README.DiskT@2 + +/*--------------------------------------------------------------------------*/ + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +- Changes to make cdda2wav compile better on Alpha/True64 + +- Restructured to better use the schily makefile portability structures. + +- Changed handling of Table of contents. Now the more informative + methods of Read full toc are being used in favor to the old SCSI readtoc + command. For Sony methods, the fallback is the old method. + The new methods are available on MMC drives and modern drives with + Sony command sets. It should enhance access to very weird multi session + cds. + + ************** + NOTE: If your drive still has problems to copy such non-CD's, there + is a simple hack to allow the disk to be copied on all drives: + + Use a (black) whiteboard pen (non-permanent) and paint on the + space directly outside the visible ring that is in the middle + of the non-CD. This is the space where the broken TOC from the + second session is located. + + After doing the copy please return the disk to the dealer and + tell the dealer that this is broken goods. This is the only way + to stop the big groups to defraud the customers. + ************* + +- Temporary hack to fix a bug in the ISRC code that caused the ISRC + string to be shortened by one character. + +- fixed ioctl handling of toc entries + +- checked ISRC retrieval (MMC + Plextor) + +- more checking for weird CDs with wrong track types + +- bugfix in setuid.c + +- read full toc method extended to a data track in the second + session for cd-extra/enhanced cd recognition + +- if the tracks in the TOC are labelled as data, this is checked + and corrected if untrue + +- show cd text disc identification, if one exist + +- a new perl script to generate a binary cdtext file for use with + cdrecord. This is currently very simple, but it enables you to + create cd-text enriched copies from non cd-text originals. + For a hint how to use the new perl script see the CD-text usage + notes above. + + +- New option -L to ask freedb.freedb.org for CDDB information. + This alllows to automatically create CD-Text CDs. + +- correct TOC endianess for FreeBSD ioctl interface. + +- Fixed a bug that caused cdda2wav to dump core with certain + CD-Text data. + +- new option -L changed. Now a numerical parameter (0 or 1) + defines the handling of multiple cddbp entries. + 0 enters user interactive mode. + 1 take the first entry unconditionally. + I still need a reasonable way for gui interaction in this case! + Proposals are welcome. + +- made cddbp handling for mixed mode cds more robust. + It is unclear yet, if data tracks have to be included in the + query. Anybody knows the definitive answer? + +- Better TOC ADDR/CRTL (red book) handling + +- Better method to scan for indices. + +- Support for SCMS in *.inf files + +- Better SUID/SGID handling + +- new script cddda2ogg + +- bugfix deemphasizing (thanks to Klaus Wolterec) + +- bugfix rounding error (creation of info files) + +- added AlbumPerformer entry in info files + +- integration of Monty's libparanoia + +- switch to Jörgs getargs option handling + +- Fix some bugs with option parsing introduced with the new option + parsing using getargs() + +- New option -version to make cdrtools behave similar + +- New option paraopts=opts for paranoia options. + +- Print Paranoia statistics result at end of every track. + +- prepare for better recording of discs with illegal TOCs + +- prepare for non-english cd_text languages + +- rewrite of the TOC handling code (now multisession capable + and much more robust) + +- add a fallback method (shmat()) for failed mmap() + +- linux bug workaround: open() sound device does block when device is busy. + +- several code cleanups, some 64-bit portability bugfixes + +- Fixed shell script 'cdda2mp3.new' to correctly use "#!/bin/sh" + +- Fixed a bug (introduced while converting to getargs()) that caused + cdda2wav to dump core on OS that implement read only text + correctly like Solaris does) if compled with gcc or Sun CC COPTX=-xstrconst + +- Remove old unused getopt() code. + +- Check DMA residual count + +- FreeBSD cooked ioctl() Byte swapping now finally OK? + +- Fixed a bug that caused cdda2wav to return wrong byteorder + on Big endian machines if -paranoia has been specified + +- fix several CDDB query bugs +- support CDDBP protocol 5 + +- customizable CDDBP server and port settings. + +- Fixed a bug in the paranoia calling code that caused + cdda2wav to try to access one sector too far on the media + if in paranoia mode. + +- Allow again compilation on FreeBSD + +- bugfix for CD Extra, when copyright messages were present + +- patch from Kyle to make CD extra handling more robust + +- bugfix for wrong warning message 'no generation of info files' + due to incomplete length + +- new verbose suboptions. Strings will finally replace the + tedious binary masks. For script compatibility the special + form of -v255 will be recognized for some releases. + -vhelp will show the new strings. +- reworked the toc display code to make it more orthogonal. + +- changed option 'speed-select' to 'speed' for better interoperability + +- Temporary added -v<number> for compatibility with old GUI programs. + Note: -v<number> is outdated and will be removed soon. + +- Implement a temporary compatibility bug for the -v option. + +- Support for libscg help system + +- Man page fixed + +- Fix for an uninitialized variable + +- New exit codes for xcdroast + +- Fix for a CDDB bug: need to use lead out start for play time + +- Fix for a CDDB bug: Allow whitepsace in Genre + +- Fix for a CDDB bug: need to count data tracks too + +/*--------------------------------------------------------------------------*/ + +Readcd: + +- better error recovery with -noerror + +- error handling increased + +- Handle signals and other aborts by restoring old drive state + +- Set PF bit with mode select. + +- New option -quiet to suppress primary SCSI error messages + in read CD error handling + This are the messages that are printed before entering the + retry mode. + +- Secondary SCSI error messages are now suppressed by default, + they may be turned on again with -verbose + This are the messages that are printed in -noerror + retry mode. + +- Better handling of C2 scans on unreadable data disks. + +- use comerrno() instead of comerr() if the drive is not ready + as errno is not valid after that test. + +- Enhanced output for C2 error scan. + +- Now use /etc/default/cdrecord as documented in the man page. + +- Better behavior with extreme badly readable media. + +- List number of completely unreadable sectors in addition to + the C2 error count. + +- Man page updated to contain all options + +- New option speed= to allow reading at slower speed and avoid read error + caused by vibrations of the media. + +- added new option -overhead to meter SCSI command execution overhead. + +/*--------------------------------------------------------------------------*/ + +Scgcheck: + +- Fixed Makefile so scgcheck now compiles on FreeBSD + +/*--------------------------------------------------------------------------*/ + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +- Man page updated and corrected. + +- Try to avoid the C-compiler warnings for getopt.c that are caused + by the non-confirming way of hacking used by FSF people + +- isoinfo now corectly displays file with filesize > 1 GB + +- isoinfo now implements a new option -s that displays the size + of the files in multiples of the sector size (2048 Bytes) + +- libhfs_iso reworked to use timedefs.h from schily portability support. + +- Better error messages for ISO and Rock Ridge directory sort problems + +- Preserves HFS file dates for AppleDouble, AppleSingle and NetaTalk files + +- Fixed a problem from an uninitialized variable in desktop.c + that caused random effects in Apple CD's + +- better documentation for README.sort/README.hide from James Pearson + +- Fixed a bug in sort code that caused the compare function to behave + symmetric when called c(a,b) vs. c(b,a) + +- First UDF support via -udf option - thanks to Ben Rudiak-Gould. + + Note that the UDF support is not what you might indend. It is currently + wired to the Joliet tree which is a bad idea. It also does not yet + support Symbolic Links, user ID's and similar. + +- Write messages with more correct size names for the floppy eltorito + boot images + +- Added a missing prototype in getopt.c + +- isodump.c isoinfo.c isovfy.c: + Correctly handle symlinks + use offsetof(struct iso_directory_record, name[0]) instead of + sizeof(struct iso_directory_record) - sizeof(idr->name) + +- Fixed a check in the Apple HFS code that used strcmp for + data that could contain null bytes. + +- Introduced many casts to enhance portability. + This was needed for GNU fnmatch.c and the HFS support lib libhfs_iso + +- Use Protoyped function definitions for hash.c to allow old UNIX variants + where sizeof(dev_t) is < sizeof(int) + +- Fixed a check in the Apple HFS code that used strcmp for + data that could contain null bytes. + +- Introduced many casts to enhance portability. + This was needed for GNU fnmatch.c and the HFS support lib libhfs_iso + +- Use Protoyped function definitions for hash.c to allow old UNIX variants + where sizeof(dev_t) is < sizeof(int) + +- Support generic boot code if session does not start at sector 0. + +- Fixed a minor bug with HFS labels & multi-session + Thanks to James Pearson + +- Only print a short Usage if mkisofs detected a usage error. + +- -z option now working to create CDs in a format with Linux proprietary + Rock Ridge extensions for transparent compression. + + This is a patch from H.P. Anvin. It makes only sense with Linux-2.4.14 + or later. + +- New option -debug + +- Correctly use stat()/lstat() with graft points + +- Fixed a bug with escape character handling in graft point handling. + +- Make the graft point a directory if the file it should point to + is a directory. + +- Correctly handle non-canonical filenames with graft points. + + .////././///test=OBJ/sparc-sunos5-cc/ will now work correctly + and not result in a corrupted ISO-Filesystem. + +- Canonicalize graft points so commands like: + + mkisofs -graft-points /a/b/././//=some_dir + and + mkisofs -graft-points /a/b/../c/=some_dir + + will not cause broken ISO images anymore. + +- Avoid unwanted information in debug information on disk. + +- Allow the -sort option to work with the Eltorito Boot Catalogue + +- Allow '-' to be part of the ISO-9660 filename if -no-iso-translate + has been specified. + Thanks for this hint from Georgy Salnikov (sge@nmr.nioch.nsc.ru) + from Novosibirsk, Russia. + +- Try to avoid an integer overflow with the -C option and DVDs + +- Try to fix (very old) rotten code in various files that did cause + integer overflows for files > 2 GB - 2kB. + + Inconsistent use of (always diferent) hand crufted code using + 2048, 2047, ... instead of SECTOR_SIZE, ISO_ROUND_UP(), ... + + Note that this is not only of interest for DVDs as mkisofs could + believe that > 2 GB of data would fit on a CD. + +- New code to print file type names. + +- Some more changes to reduce the probability of integer overflows + in size computations. + +- Fixed a bug in the code that removes sensitive information from + the command line. + +- Add text strings with descritpive text to the output_fragment structures + +- verbose > 1 (use -v) writes debug info for output fragments. + This uses the new strings introduced with the last version. + +- isoinfo now uses getargs() and includes -version and -help + options. + +- isoinfo now is able to find out that Joliet information is + present if the disk contains illegal Joliet UNICODE escape code. + This seem to happen with disks written with Adaptecs programs. + +- isoinfo has new option -debug that prints more information + from the Primary volume descriptor. + +- Support for Apple HFS on Mac OS X Thanks to James Pearson. + +- Support for more then 65535 directories as only the parent entries + need to fit into the path tables. + +- Full DVD-Video support thanks to Olaf Beck - olaf_sc@yahoo.com + +- Avoid a C-compler warning caused by mkisofs.h + +- Fixed a bug in the DEBUG code from the DVD-Video enhancements + +- Allow symlink targets to be up to 1024 bytes + +- devdump/isodump/isovfy now use getallargs() and implement -help/-version + +- If UDF but no Joliet is used, UDF filenames may be 255 chars long. + Note that this is still hack. + +- From James: New option -joliet-long to allow 103 UNICODE characters with + Joliet. This is not Joliet compliant but several other programs + also create long Joliet names. + +- Fixed a minor C non-compliance in ifo_read.c + +- Allow symlink targets to be up to 1024 bytes + +- devdump/isodump/isovfy now use getallargs() and implement -help/-version + +- If UDF but no Joliet is used, UDF filenames may be 255 chars long. + Note that this is still hack. + +- From James: New option -joliet-long to allow 103 UNICODE characters with + Joliet. This is not Joliet compliant but several other programs + also create long Joliet names. + +- Correct a minor problem with K&R compilers for the programs + in mkisofs/diag/ + +- Make fire PATH_MAX is defined in isoinfo.c too. + +- Make sure UDF directory permissions include 'execute permission'. + +- A patch from James that make mkisofs able to create a HFS volume < 4 GB. + +- Support for MS code page 1250 (Slavic/Central Europe) added. + Thanks to Petr Balas petr@balas.cz + +- A patch from James that make mkisofs able to create a HFS volume > 4 GB. + +- A new option -hfs-parms for better HFS support for HFS volumes > 4 GB + from James Pearson + +- Fixed several typos in the man page and the source + +- Belly based speudo fix for a problem with mkisofs -f (follow) + and symlinks to directories where directory content was + missing with the old version. The new version is most likely better + and we (James and I) could not find problems with the new version. + +- Make "HFS_TYPE" and "HFS_CREATOR" work as documented in ~/.mkisofsrc + +- Fixed a small typo in isofinfo.c + +- As mkisofs -f has bugs that cannot be fixed for this release, I decided + to mark the '-f' Option as non-functional. People who use it will be warned + that it does not work correctly. + +- Sort VIDEO_TS.IFO to be the first entry in VIDEO_TS/ woth -dvd-video + +- Disable Joliet if -dvd-video has been specified. This needs to be done to + allow the change above. + +- Correctly handle files > 1GB on the UDF filesystem. + Thanks to Wei DING <ding@memory-tech.co.jp> for the patch. + +- Add support for Code Page 1251 + +- Koi8-u added to libunls + +- Fix a nasty bug in the UDF handling part that caused mkisofs to + create completely broken filesystem images if directories have been + nested deeper than 8 and -D has not been specified. + +- Include a new piece of code that causes mkisofs to abort with an + error message if it turns out that the block numbers estimated + during the sizing phase do not match the block numbers in the + write phase. + +- Enabled a piece of code that has been introduced 2 years ago and that + causes mkisofs to prevent deep directory relocation if Rock Ridge + has not been spacified. + + If you like mkisofs not to omit the part of the directory tree that + is nested too deep, specify either -R, -r or -D. + + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task: + Peter Berendi <berendi2@webdesign.hu> announced that he likes + to be the volounteer for this task. + + Unfortunately, I did no hear again from him, but I got + a proposal from + "Krisztian Gede" <nameless@mail.datanet.hu> + who also likes to do the job. + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - implement Yellow book compliant XA extended dir attributes + + - add libecc/edc for CDI and similar. + This may not be needed if we ise VCDimager and recent + cdrecord versions. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% ansi compatible. Solaris 2.x tar and GNU + tar may get some minor trouble. + +WARNING: Do not use 'mc' to extract the tar file! + All mc versions before 4.0.14 cannot extract symbolic links correctly. + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01 b/doc/ANNOUNCEMENTs/AN-2.01 new file mode 100644 index 0000000..3268bbb --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01 @@ -0,0 +1,1496 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01: + + +All: + +- Support for the ELF format in BSDi 4.x + +- Allow floating point printing on OS/2. This has been possible + since 11/2001 but OS/2 has been forgotten. + +- Correct OS/2 ranlib handling + +- New architecture 9000-831-hp + +- Include +DAportable in HP-UX cc options + +- README.hpux enhanced to include hints on how to compile 64 bit + binaries. + +- Support for NetBSD on PPC (macppc-netbsd-cc) + +- portable getdomainname() replacement now supports to get the domainname + from /etc/resolv.conf. This allows usage even on OS/2 + +- Typo in DEFAULTS files fixed + +- New generic target for symlinks + +- New file rename.c for portability part of libschily + +- Better Next STep support: + + - Some workarounds for broken unistd.h + + - -lkvm removed from Next Step config. + + - waitdefs.h fixed for very old BSD based systems (~ 1980) + like Next STep + + - strdup() moved into portability part of libschily + + - fixed typo in fctldefs.h R_RDONLY -> O_RDONLY + + - New file ttydefs.h includes portability phrases from ved and bsh. + + - Added an autoconf test for buggy termios.h in Next Step. + Next STep provides fully functional termios.h but tcgetattt(), ... + is missing in libc. + + - Test for clock_t changed to deal with a bug in Next STep. + Next Step illegally needs sys/time.h for clock_t + + +- Make recently introduced symlink install use relative symlinks instead + of absolute symlinks. + +- Change autoconf/statdefs.h to support nanosecond support for SCO + UnixWare and FreeBSD + +- Call conf/mkdep-sco.sh via sh to be independent from 'x' bit. + +- libschily/rename.c fixed for SCO Openserver fo avoid warning + for redefinition of MAXPATHNAME + +- libschily/usleep.c fixed to avoid SCO Openserver warning about + non matchin prototype in system include files + +- Better Portability for SCO UnixWare + + - New platforms i486, i586, Pentium III, Pentium Pro + + - Let strdefs.h also include strings.h for strcasecmp() + + - Support for missing struct sockaddr_storage + + - Support for broken wait3() (returns wrong timings) + + - Changed broken portability Prototype support in libfile + to use 'makefiles / prototype.h' based system + + - Changed fileopen() and filereopen() to avoid fdopen() + provlems (does not accept mode string that does not + match fd flags) + +- Catch the case where somebody tries to compile on Solaris with + /usr/ucb in PATH before /opt/SUNWspro/bin and when calling 'cc' + results in: + /usr/ucb/cc: language optional software package not installed + +- Trying to make the source get accepted by 'cstyle'. + +- Changes in the general topic 'Stack Scanning' and the software signal + system handlecond()/raisecond() that make the software signal system + now usable on all platforms. + +- Trying to support DOS with the DJGPP compilation environment + Thanks to Alex Kopylov <reanimatolog@yandex.ru> for the first version + of the port and further helping. + + Note that in order to compile cdrtools on DOS/DJGPP you need smake-1.2a20 or newer. + GNU make does not seem to work for a DOS compilation. + +- New File README.msdos + +- New RULES for DOS/DJGPP + +- Make some vars in align_test.c static because Mac OS X creates unneeded + name space pollution. + +- DJGPP has no SIGBUS, use #ifdef in avoffset.c and align_test.c + +- Several changes with casting Null pointer constants to Null Pointers + if they are used as parameters in var arg lists (see below). + +- New gethostname() fallback emulation using uname(2). + +- Better rename(2) emulation for Platforms that don't have rename(). + +- niread()/niwrite()/nixread()/nixwrite() in libschily now resets errno + to the old value in case EINTR did occur. + +- README.msdos has been corrected according to a hint from Alex Kopylov + +- New macros to platform independently set up integers in little endian + format. This is needed to e.g. write PC disk labels from big endian + platforms. + +- Rules extended to support volume management libs + +- The install-sh script not takes care about UNIX variants like SCO UnixWare + and SCO OpenServer that allow to give away files via chown. + + If this works and /tmp has the sticky bit set, the root test was unable + to remove the test files later. For this reason, now a subdirectory + in /tmp is used. + + +- Support for the special .PHONY: target ---> needs smake-1.2a21 or newer + + This helps to deal with files like INSTALL operating systems + like Win32 and Mac OS that don't honor file name case and prevents + the file named INSTALL to get into trouble with 'make install' + + +- 'make install' now works on operating systems that require a '.exe' + suffix for executable binaries + +- Updated the file README.ATAPI + + Updated information for Linux, SCO-OpenServer, SCO-UnixWare, Win32 + and DOS + +- mconfig.h now supports make COPTX=-DNO_FORK & COPTX=-DNO_VFORK + +- snprintf() from libschily now correctly follows POSIX.1-2001 for maxlength == 0 + +- Workaround for a bug in the C-compiler from SCO-OpenServer. It + is not very probable that this causes problems with cdrecord. The + function getfp() did not return the correct Frame Pointer when called + as first function in another function as the compiler sdoes set up the + new stack frame after getfp() has been called. + +- New function filemopen(char *name, char *omode, mode_t mode) with additional + mode_t parameter. + +- update recent getargs() version from repository. This has been forgotten. + +- Add a workaround for a SCO OpenServer C-compiler bug. + The bug causes the first function in a function to be called + before the new stack frame has been established and did cause + scanning the stack frame to fail. + +- Make snprintf() POSIX compliant. + +- Many typos in the READMEs fixed, thanks to a hint from Stefano Allrath + +- New global method to handle PATH environment delimiters (":" on + POSIX systems and ";" on DOS). + +- New README.msdos reflecting new features of smake-1.2a23 on DOS/DJGPP + +- Some minor enhancements to the makefilesystem + +- Some minor changes for better compilation in SGI IRIX + +- Trying to start adding support for Win32/Mingw32 + +- New global #define NEED_O_BINARY to make using setmode() easier + +- New autoconf test for struct stat.st_fstype + +- New autoconf test for fnmatch() + +- New autoconf test for blksize_t/blkcnt_t + +- libscgily/stdio/io.h renamed to schilyio.h to avoid conflicts with + DOS. + +- Added a Note to README.linux: + + NOTE for all Linux 2.5.x versions and all Linux versions before 2.6.8: + + Linux did ship with defective kernel include files starting + with 2.5.x. These defective kernel include files did prevent + compilation. If you have problems compiling software and see + error messages related to include/scsi/scsi.h & include/scsi/sg.h + either upgrade to Linux-2.6.8 or newer or remove /usr/src/linux + +- Support added to the makefile system that allows compilation on + AMD x86_64 using non automake aware make programs like GNU make. + Note that smake ftp://ftp.berlios.de/pub/smake/alpha/ is able to compile + things even on unknown platforms as it includes auto make features. + + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +- Included a bug fix from the libparanoia Author. + Correctly allocate some arrays. Note: on 32 Bit machines, this patch does + not result in a different binary but the code is now really correct. + +- New indentation is better conforming to 'cstyle' + +- Fixed a bug in libparanoia that prevented the statistics to show up + the number of 'skips' (the number of exhausted read retries) when + SKIP verification has been turned off. + +- modified to avoid GCCs shadowed variable warnings. + +- Try to use page aligned transfer buffers if possible. + +- Avoid buffer size problems wit non page aligned transfers on FreeBSD. + +- Avoid freeing pointers that are not from malloc() by copying the data + to a second allocated chunk of free()able space. This has been a bug + introduced while trying to handle buffer size problems with non page aligned + transfers on FreeBSD. + + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + + +Libscg: + +- Reordered and restructured scsi-remote.c code to allow compilation on OS/2 + and hopefully other OS like BeOS + +- First attempt to support QNX. + Note that the sourcecode comes from QNX and it looks as if it + is buggy for commands that cause SCSI commands that result in + a Check Condition status. From looking at the source, the stack + gets overwritten in this case. + +- SCSI adaptation layer for SCO UnixWare rewritten to support + multiple opens and to better follow the libscg interface standard. + +- Second attempt to support QNX. + Make it compile + +- Check kernel level error return codes on SCO-UnixWare + +- Starting to support SCSI reset on SCO-UnixWare + +- Extensions to libscg related include files to support DVD+RW formatting + +- Make libscg work on SCO UnixWare if an application like cdrecord + has been installed suid root. + + Before, the called administration programs did not work if euid!=uid + +- Fixed a problem with possible garbage in the SCSI error string. + Thanks to Stefano Di Paola <stefano.dipaola1@tin.it> for reporting. + +- Fixed another printf buffer vulnerability in scsi-remote.c + +- New version of scsi-amigaos.c from Thomas Langer + +- Added a work around for a Solaris 9 x86 bug: + DKIOCINFO returns a max DMA size of 256 kB but only 68 kB will work. + Check max DMA size for a IDE disk to get a correct value.... + + For more information read the updated file README.solaris and the + new files README.solaris-x86-ata-DMA and README.solaris-x86-ATAPI-DMA + +- Changed scsi-os2.c to allow 'cdrecord -scanbus' to find targets with + target ids > 7. + +- Librscg now uses correct casting to a Null Pointer for execlp() as + NULL is a Null Pointer Constant but no Null Pointer. This could + make problems with some 64 bit architectures. + +- New driver scsi-dos.c acting as 16 bit DOS ASPI interface + Thanks to Alex Kopylov <reanimatolog@yandex.ru> for the first version + of the driver. + + Check his Web Page: http://bootcd.narod.ru/index_e.htm + it contains precompiled DOS binaries. + +- The driver scsi-dos.c has already been verified with 'scgcheck'. + +- scsi-os2.c and scsi-wnt.c now correctly return 0 from scg_send() if + the target is not valid. + +- scsi-wnt.c does now support multiple SCSI opens. + +- scsi-wnt.c does now correctly return SCG_NO_ERROR in case a SCSI command + returned CHECK CONDITION. + +- scg__open() now prints a warning if it has not compiled with the results + from a certified autoconf environment. + +- Introduced a fix to avoid the need for a #define ident prod_ident + for SCSI Inquiry data. This #define did cause problems with the + latest Sun Studio 8, C compilers + +- First attempt to support running cdrecord while the volume management is + active. + +- Increased version number to 0.8 + +- First attempt to work around the problems for suid programs introduced by + Sun with Solaris 9. Programs that like to issue a USCSI ioctl() need to be + root or get EPERM. Cdrecord did does up root privilleges eraly to avoid + security problems. + + libscg now selectively runs the USCSI ioctl() as root if the program is installed + suid root. + +- Fixed a bug in scsi-mac-iokit.c in scgo_havebus() that caused pxupgrade not + to work on MacOS X. + +- First attempt to support the SPTI Ioctl interface on Windows NT. + see also http://www.ste-home.de/cdrtools-spti/ + Thanks to Richard Stemmer, Jay A. Key and thomas podkanski + + This allows to use cdrtools on NT without the need to install ASPI in case + you are administrator when yu run a program. + + Please note that the use of SPTI is default. If you like to force using + ASPI, use dev=ASPI:b,t,l or dev=ASPI (in the -scanbus case). + If you like to force STPI, use dev=SPTI:b,t,l or dev=SPTI. + + Currently, the interface does not yet fully matches the scg interface standard. + +- Try to support the half hearted and badly designed /dev/hd* interface + from Linux-2.6 in a more usable way. + + The only reason for adding this kind of support is that the Linux kernel + hackers reject to fix the known DMA bugs in the already existing SCSI + transport interfaces in the Linux kernel. Using /dev/hd* is unfortunately + the only way to get DMA with sector size being 2352, 2448 or similar. + + Use cdrecord -scanbus dev=ATA and + cdrecord dev=ATA:1,0,0 + + Note: The Bus mapping function inside the kernel for this interface is + a dummy. For this reason, we need to do the mapping ourselves. + Busnumber is ("/dev/hd*"[7] - 'a') / 2 + Target is ("/dev/hd*"[7] - 'a') % 2 + + Also note that creating this interface in the Linux kernel was a waste of + time. It did need a lot of effort to be created. Instead of first adding + a new interface with a new broken DMA implementation and later fixing + the DMA bugs, it would have been better to just fix the DMA bugs + in ide-scsi.c + + Adding SCSI transport to something like /dev/hd* on an OS that includes + a generic SCSI transport driver is disregarding SCSI protocol layering. + A clean way to implement ATAPI on Linux would be to rather introduce a + SCSI hostadaptor driver that sends the SCSI commands via the + ATA hardware. + + Linux users should think about buying a CD writer for Linus Torvalds. + Maybe this could help to get better SCSI support in the Linux. Currently + Linus doesn't know anything about the CD-writing problems on Linux and + his contributions to CD-writing related issues in discussions are just + guesses that are not related to own experiences and understanding for + the matter :-( + + It seems that the Linux way of dealing with bugs is to implement a new + incompatible interface instead of fixing the known bugs from + old interfaces :-( + +- Allow cdrecord -scanbus dev=ASPI and cdrecord -scanbus dev=SPTI to work + on win32. + +- Correct a bug in the Win32 version analyze function that is needed to + use the correct SPTI interface. Unfortunately, the interface did + change with a NT-4.0 service pack. It is unclear whether the currently + used interface type is correct for all possible NT-4.0 variants. + +- For Win32, default to STPI only if on NT-5.x as there is a bug in some + UDMA implementations that causes blue screens. + +- The Mac OS X SCSI low level transport now roughly meets the interface standard. + For this reason, the file scsi-mac-iokit.c now is marked with Author "schily" + +- Indented according to the cstyle standard. + +- For win32, dev=ASPI:1,0 and dev=SPTI:1,0 work again + +- Trying to add a workaround for the Linux problem with USB where the + kernel issues a request sense even when there was only a DMA underrun + and the drive replies as expected with no-sense. Our problem in this + case is that we needed to ad another workaround because sometimes + Linux clears the status byte and we did assume a CHECK CONDITION in case + sense[0] was != 0. + +- Enhanced max # of SCSI busses to 256 for the Linux sg driver. + This was needed because of the (compared to Solaris) suboptimal + way of dealing with instance numbers on Linuux. + + While Solaris keeps a data base with instance numbers, disconnecting and + reconnecting a USB drive results in the USB device getting the same + SCSI address as before. + + As Linux does not have such a data base, disconnecting/reconnecting + a USB device has the unfortunate side effect of assigning a new and + different SCSI address with every USB connect. This also creates problems + when software likes to manage access rights to devices for non-root + users. + +- Win32 SPTI interface now also supports controllers with more than one + SCSI Bus. Thanks to Richard Stemmer + +- Fixed a bug in the Win32 SPTI/ASPI interface introduced with 2.01a28 + that caused core dumps because it did try to access data behind the end of the + sense data array in the ASPI cmd structure. + +- Scan /dev/hda../dev/hdz instead of /dev/hda../dev/hdt for dev=ATAPI on Linux. + +- Trying to write a better warning message for the dev=ATAPI: interface + on Linux (the related kernel interface is unmaintained and does + not support DMA at all). + +- Fixed a bug in Win-NT Version string handling in scsi-wnt.c + Thanks to Alex Kopylov <reanimatolog@yandex.ru> + This caused that libscg did not properly recognize NT-4.x with service pack 4 + to be equivalent to NT-5.0 (Win2k). + +- Trying to avoid using the WinNT-SPTI interface for NT-4.0 + +- Fixed a security bug in scsi-remote.c (the RSCSI client). + + +Rscsi: + +- Support for IPv6 + +- Workaround for missing struct sockaddr_storage on SCO UnixWare + +- Security update. Forbid to write arbitrary debug files, only allow + a debug file name that has been configured in /etc/rscsi.conf. + Writing arbitrary files with a siud root program could be used to become + root on a local machine if you are already logged into that local machine. + +- README.rscsi typo's corrected. + + +Cdrecord: + +- Use correct set_mode_params() return value in deflt_writemodes_mmc() + +- Correct a debug printing to go to stderr instead of stdout. + +- Workaround for broken Firmware for LG (Lucky Goldstar) drives. + These drives have been unable to write Audio in TAO mode because + they have an illegal audio pause length default. + + Thanks to a hint from: Mark Vytlacil <markvyt@comcast.net> + +- Man page now correctly describes the data formats used with -xa1 & -xa2 + +- Use Prototypes for functions with enum parameter in fifo.c to avoid + warnings on SCO UnixWare + +- Trying to catch SIGHUP to avoid hung recorders after people + close X windows by accident (This in most cases happens because + some newer GUIs try try copy bad ideas from Microsoft like the 'x' + button on the top bar in the window. + +- Trying to print hints if the SCSI error core looks like a buffer + underrun occurred. + +- First (still mostly empty) driver for the Matsushita CW-7501 + +- First TAO writing support for the Matsushita CW-7501 + +- New option -setdropts to allow cdrecord to set driver specific + parameters and exit. + +- Added support to disable/enable the Plextor PowerRec feature. + Use driveropts=forcespeed + Be very careful as this will cause in badly readable disks. + The only senseful reason to use this feature is to run tests in + -dummy mode to check whether the system would be able to record + fast enough and to later buy High-Speed Media. + Note that documentation for the related SCSI command is not + oficially available and thus the information has been "guessed". + +- Added support to enable/disable the Plextor SpeedRead feature. + Use driveropts=speedread + to allow the drive to read CDs faster than 40x. + Be very careful as this may cause the media to break in the drive + while reading, resulting in a destroyed media and drive! + Note that documentation for the related SCSI command is not + oficially available and thus the information has been "guessed". + +- Added support to enable/disable the Plextor SingleSession feature. + Use driveropts=singlesession + This allows to read defective (illegal) media with extremely + non-standard additional TOC entries. You need to enable Single Session + mode before you insert the defective disk! + Note that documentation for the related SCSI command is not + oficially available and thus the information has been "guessed". + +- Added support to enable/disable the Plextor Hide CD-R feature. + Use driveropts=hidecdr + This allows to make CD-Rs look like CD-ROMs and applications believe + that the media in the drive is not a CD-R. + Note that documentation for the related SCSI command is not + oficially available and thus the information has been "guessed". + +- Added reading out "real" Burn-Proof counter for Plextor drives. + Note that documentation for the related SCSI command is not + oficially available and thus the information has been "guessed". + +- Try to do a more correct job when doing Buffer Underrun estimation + counts. + +- Make the explicit Buffer underrun error checking work for + Plextor drives too. + +- Fixed the command line parser for driveropts= parameters. + Before the fix, driveropts=noburnfree,hidecdr would result + in assuming: driveropts=noburnfree,nohidecdr + +- Now also supporting SAO/DAO write mode for the CW-7501 + +- New option -lock (similar to -load) that loads the media but leaves + the drive in locked status. + +- New driver interface to allow SAO recording for the CW-7501 + Simplified: "dummy" and "multi" Parameter information has been + moved into the track structure. + +- Removed the internal implication that -packet is a TAO write mode. + Please test! It may be that this did introduce bugs. + +- Try to avoid ANSI C arithmetic conformance change warnings from + SCO C-compiler by introducing proper casting. + +- Driver interface restructured to support aborting SAO recording + with the Sony CDU-948 + +- "Driver flags" printing corrected + +- Better behavior with CADDY drives and -load option + +- Fixed a bug that caused cdrecord not to abort if Tracks with unknown + length are present in RAW write mode. + +- Print extended Power Rec Speed information for Plextor drives. + +- CUE Sheet handling generalized to allow to implement SAO writing + for more drives. + +- Start supporting the Sony CDU-948 in SAO mode. Currently not yet working: + + - Multi-session + + - MCN/ISRC + +- Grace time handling restructured. The grate time waiting is now done + even before the forced blanking and it is made sure that the waiting + is done only once. + +- Several changes in the open source part are visible as a result of the + new DVD+RW / DVD+R support. + +- cdrecord-ProDVD now includes first DVD+RW and DVD+R support. + Check ftp://ftp.berlios.de/pub/cdrecord/ProDVD/ + on Thursday 24.4.2002 for the first binaries + +- Do not try to lower the possible number of open files in raise_fdlim() + anymore. + +- Check return code of driver's init function. + +- Better error messages from main write loop. + +- Write a hint that a user may have used a "preformatted" CD-RW if + read_next_writable_address fails for the "invisible" track + and tell him to run cdrecord blank=.... + +- Fixed a bug that caused cdrecord to prevent a 3rd session on a + multi session disk. This bug was introduced with the driver + restructuring a few releases before. + +- Better driver text strings for the driver IDs in the CD MMC drivers. + +- Move Plextor PowerRec speed info completely to the statistics _past_ + the recording activities. + +- Allow more nonstandard Cue sheets to be accepted by the Sony CDU-924 + and CDU-948. + +- Implement MMC-3 DVD+ Drive/Media recognition to avoid that cdrecord starts + to treat a DVD+ as a CD-R because the DVD+ drive identifies as CD-R/RW + DVD-ROM + with "no DVD media installed" from a MMC-2 viewpoint. + +- Added a note to the cdrecord man page how to use mkisofs + to allow cdrecord to knoe about track sizes in SAO or RAW mode. + +- Fixed a multi session bug that has been introduced with the DVD+R/RW + restructuring with cdrecord-2.01a11. This bug caused cdrecord to be unable + to start a track from a sector number != 0 in TAO mode. + +- Fixed a problem with cdrecord -msinfo introduced with the the DVD+R/RW + restructuring with cdrecord-2.01a11. The unwanted verbose printing has been + removed with this version. + +- New option -xa to create CD-ROM XA mode 2 form 1 sectors with 2048 bytes + of user data + +- New option -xamix to create mixed CD-ROM XA mode 2 form 1/2 sectors + with 2332 bytes of user supplied data. + +- Restructured sector types to make them usable: + + -mode2 CD-ROM data mode 2 - 2336 bytes + -xa CD-ROM XA mode 2 form 1 - 2048 bytes + -xa1 CD-ROM XA mode 2 form 1 - 2056 bytes + -xa2 CD-ROM XA mode 2 form 2 - 2324 bytes + -xamix CD-ROM XA mode 2 form 1/2 - 2332 bytes + + To write conforming CD-ROM XA multisession disks use cdrecord -multi -xa1 + together with mkisofs -XA -sectype xa1 + +- -cdi is now implemented how it should be: as a flat to change + the TOC type of a CD and not as a sector mode. + +- Track parsing completely restructured to allow new features. + One of the features is to write audio CDs from a pipe, + other features will follow. + +- Cdrecord now resets euid to the uid of the caller (if called suid root) + before it opens data files. + +- Fixed a bug that caused cdrecord to insert two grace wait periods + if a disk was blanked and rewritten in one call. + +- Allow cdrecord to copy audio CDs from a pipe from cdda2wav + without using an intermediate file on disk. + + To copy an audio CD from a pipe (without intermediate + files), first run + + cdda2wav dev=1,0 -vall cddb=0 -info-only + + and then run + + cdda2wav dev=1,0 -no-infofile -B -Oraw - | \ + cdrecord dev=2,0 -v -dao -audio -useinfo -text *.inf + + This will get all information (including track size info) + from the *.inf files and then read the audio data from + stdin. + + If you like to write from stdin, make sure that cdrecord + is called with a large enough fifo size (e.g. fs=128m), + reduce the write speed to a value below the read speed of + the source drive (e.g. speed=12), and switch the burn- + free option for the recording drive on by adding + driveropts=burnfree. + +- New option -abort allows you to send a write abort sequence to a drive. + This may help if other software did leave the drive in an unusable + condition. + +- New 'xio' module allows to open a file virtually more than once to + support CDRWIN CUE sheets in cdrecord. + +- Run Plextor Speedinfo SCSI command in silent mode as old Plextor drives + do not support this command. + +- Workaround for a Plextor (Premium only???) firmware bug that may result + in a B0 pointer A5:A5:A5 instead of FF:FF:FF. + + This made it impossible to blank a freshly written CD-RW witout reloading + the media. Now cdrecord does not check the disk size anymore if the number + of tracks to be written is 0. + +- First CDRWIN CUE sheet support. + + Cdrecord currently supports what is in the CUE sheet description in + the CDRWIN documentation (with a few exceptions). Note that the + examples in the rest of the CDRWIN man page are mostly illegal + if you compare them against the CDRWIN CUE sheet syntax documentation. + + These exceptions are currently in effect: + + - Only one FILE Line per CUE sheet file (This is compliant to the + CUE shet format documentation although the examples show CUE + files with more than one FILE line). NOTE that the CUE syntax has + been ill defined so that it would not make sense to e.g. use + more than one FILE line for audio CDs. + + - The AIFF File type is not implemented (because I have no documentation + for this audio file format). + + - The MP3 File type is not yet implemented. + + - The CDG data type keyword will not yet work + + - The CDI data type keyword will not yet work + + - Only a sector size of 2048 will work with MODE1 + + - Sectors with sector size 2336 will not yet work + + - POSTGAP will not yet work. + + Note that the CDRWIN CUE documentation is bad and it is unclear how + formless (non XA) MODE 2 sectors should be made. + + CDI is not a sector/track property but a disk property. + + The File type BINARY vs. MOTOROLA is unclear. + + To use the cue sheet feature call: + + cdrecord dev=.... -v -dao cuefile=xx.cue + + The main reason for implementing CUE sheet support was to allow to + write VCD/SVCD with cdrecord. It has currently tested with the + test SVCD from ftp://ftp.vcdimager.org/pub/vcdimager/examples/test_svcd/ + + Cdrecord should allow to write audio type CUE sheet based CDs also. + + +- Modified the notes close to the Copyright printing code in cdrecord.c + to make clear that this note is not a deviation from the GPL but just + a memorandum on how to understand the GPL. + +- Fixed a bug in file descriptor handling that caused cdrecord not + to continue at offset xxx in the file after a new track did start. + +- Added a forgotten feature in the CUE Sheet parser so it will now know that + WAVE files use swapped (intel) byte order. + +- Restructured the main program of cdrecord so that cdrecord overall + behaves similar to before when cue sheets are used. + e.g. cdrecord -eject cuefile=xxx did only eject the disk instead of + first writing and then ejecting. + +- Added some hints to the man page to make speed= handling clearer + +- Fixed some typos in the man page + +- Added the -format option to the man page + +- CD-Text handling reworked: + + CD-Text from textfile= or from CUE CDTEXTFILE wins over CD-Text + from *.inf files and over CUE SONGRITER. + +- CD-Text from CUE file (either CDTEXTFILE or SONGRITER) now needs + -text in addition in order to be not ignored. + +- Fixed a bug in the recognition for cdda2wav | cdrecord *.inf + that caused a message + WARNING: Stdin is connected to a terminal. + if not writing from a pipe. + +- Small fix in auinfo.c to again allow compilation on K&R systems + +- Typo fixes for the cdrecord man page + +- The clone write code is now part of the GPL'd source + Note that this part of the code is now more than 2 years old but previously + has been excluded from the publically visible part of the source. + + To understand how to use the clone mode read README.clone + +- New option ts= to set the SCSI transfer buffer size + +- Man page corrected to correctly mention current format for /etc/default/cdrecord + +- call setmode(fileno, O_BINARY) for DOS/DJGPP also + +- Better check if we use the FIFO to avoid core dumps with too small FIFO sizes. + +- Switch off FIFO of fifo size is < 2 * SCSI transferbuffer + +- Fixed a small bug in the man page (..sp instead of .sp). Thanks to Eric Raymond + for reporting! + +- Work around for a problem in the Plextor 708 firmware (at least 1.01..1.02) + that caused cdrecord to be unable to recognize that a DVD medium is present instead + of a CD medium. + +- Changed the GPL clarifications text in a way so Debian people still + agree with me that cdrecord is free software. The clarifications are + needed in order to tell people/companies (like Mr. Rosenkranzer, + RedHat & SuSE) who create broken branches from cdrecord that they are + not legally publishing their branches because they violate the + GPL § 2 Paragraph c) and GPL Preamble Section 6). + + If would be better if the named persons/companies would rather stay + in contact to the Authors, discuss things and contribute to the + community instead of creating useless/broken changes and in case + of SuSE Linux even creating hacks that introduce security risks. + + Note that now, RedHat Linux (enterprise server) or the SuSE Linux + are even more expensive than e.g. Solaris x86, see: + + http://www.osnews.com/story.php?news_id=5416&page=5 + Small Correction to this web page: Solaris x86 is free again for + personal use. + +- Extended the man page to make it more clear that all CD/DVD-writers + ever made use only SCSI commands. + +- Another change to the man page according to a hint from + Eric Raimond in order to get better compliance for troff -> "*ml" + converters. + +- Allow people who cannot provide an e-mail address or who + don't like to support their modifications to modify cdrecord + +- Some CUE sheet modifications in drv_mmc.c now made it into + the official SCCS history file. + +- Several fixes to avoid the need for a #define ident prod_ident + for SCSI Inquiry data. This #define did cause problems with the + latest Sun Studio 8, C compilers + +- Hack to work around a POSIX real time priotity design bug that + causes us to become root again on e.g. Linux in order to be able + to lower the priority of the FIFO background process. + +- Better documentation and EXAMPLE for -setdropts driveropts= + in the man page. + +- print a help message to direct the user to use -raw96r in case + the drive does not accept the cue sheet with -dao. + +- Mark all drives that cannot be accessed because the volume management is + running and no media is in the drive with '?' instead of '*', so they + may be distinct from non existing drives. + + Read README.volmgt for more information + +- Now works again suid root on Solaris 9 + +- Fixed a bug introduced in 2.01alpha by a source consolidation. + cdrecord -toc did not work anymore for CD-ROM readers + +- Updated README.audio + +- Make the CUE Sheet handling search for a file name from a FILE statement + also in the directory where the CUE sheet is found (in case there is no + slash (/) in the file name from 'FILE'). + +- Avoid coredumps when cdrecord is called with -xd and there is no known + driver for the current drive. + +- New option -tao is now needed if you like to write in TAO mode. + Cdrecord now does no longer writes if no write mode has been specified. + +- New option -sao as alias for -dao. As the official name for the write mode + is SAO, -sao is more correct than -dao. + +- Fixes for minor typos in cdrecord.1 + +- Fixed a bug with pad=xxx and pad sizes > 2 GB. + +- Trying to fix a bug introduced lately with the check for specified + write mode options. As a result, only TAO mode writing did work. + +- Better man page & online help for the ts= option. + +- Fixed a typo in the man page. + +- Better error messages when audio size is < 300 Sectors or needs padding. + Thanks to a hint from Stefano Allrath + +- cdrecord -scanbus now checks for 256 SCSI busses + +- cdrecord -scanbus now checks for 256 SCSI busses + This has already been announced for 2.01a28 but forgotten to include + +- Some Man Page Fixes trying to avoid coding problems for non 7-bit ACSII + +- Several typos in the man page fixed + +- Man page enhanced to include a better documentation for the driver= + option. + +- Several other enhancements to the man page + +- modified to avoid GCCs shadowed variable warnings. + +- Cdrecord now tolerates the OPC "error code" "Power calibration area almost full" + to not a real error. + +- Fix for a bug that caused cdrecord to be unable + to reload the media for some drives. + The fix helps with the following problem: + + Trying to clear drive status. + cdrecord: Drive needs to reload the media to return to proper status. + cdrecord: Cannot load media with this drive! + cdrecord: Try to load media by hand. + cdrecord: Cannot load media. + +- man page enhanced + +- Print the "Make sure you are root" only if root privilleges are missing. + +- Avoid warning for not working nice() on DOS + Thanks to Alex Kopylov <reanimatolog@yandex.ru> + +- -clone option documented in the man page. This has been forgotten before. + +- Several typos in the man page fixed + +- Do not try to call nice() on DOS/DJGPP + +- cdrecord now tries to check the DMA speed if the drive supports to read the + drive buffer. If the DMA speed is not sufficient, then cdrecord requires + that burnfree is activated. If the environment variable "CDR_FORCESPEED" + is set or -force has been specified, then cdrecord does not try to enforce + that the available DMA speed is 2x the expected write speed. + +- Make some symbols static to avoid problem with a badly designed libc on + OpenBSD that violates POSIX by pulluting the namespace with symbols + like 'pl'. + + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +- fixed typo in cdda2ogg.1 + +- Do not use uname() but gethostname() for portability. + +- include unistd.h for abs() + +- old Toshiba's usable again + +- Multisession Non-CD-Extra disks now work again + Now also a lot more broken disks are readable again. + +- not using ioctl in signalhandler any more + +- trying to support sound on Win32 + +- Several changes (mostly OS/2 related) for more ask Heiko + +- bugfix add cdda2ogg manpage,and script and makefile install target + +- support BeOS shared memory and FIFO + +- support soundcard output under QNX + +- windows-users! Cygwin has fixed the bug introduced with 1.3.18. Please + upgrade to the new 1.5.3-1 release. + +- call setmode(fileno, O_BINARY) for DOS/DJGPP also + +- Now using the major() macro for some Linux duties. + + WARNING to creators of Linux distributions: + + It has _always_ been wrong to compile software only once for different + kernel versions (e.g. for compile Linux-2.4 and later install a + 2.2 kernel on the so created system). + + Now that Linux-2.6 introduces incompatible changes to kernel/user + interfaces, the resulting binaries will not work correctly anymore. + +- Made CD-Text handling reentrant to overcome a problem triggered by XCDRoast + +- Now works again suid root on Solaris 9 + +- Fix for a Bug that prevents paranoia statistics from being printed + because the paranoia statistics for the forked version has not been + inside the shared memory. + +- New paranoia sub option paraopts=overlap=xx + + This is mainly a bug fix for cdda2wav. Cdda2wav previously _always_ did + completely deactivate the dynamic overlapping from libparanoia. Instead, + it did set the overlapping to the statical value 0. + + If you omit paraopts=overlap=xx, cdda2wav will now use dynamic overlapping + with -paranoia. + + If you like the old behavior, use: paraopts=overlap=0 + +- New paranoia sub option paraopts=minoverlap=xx + This sets the minimum dynamic overlap + +- New paranoia sub option paraopts=maxoverlap=xx + This sets the maximum dynamic overlap + +- Better paranoia statistics output + +- Fixed a Problem with some Linux sound card drivers that caused cdda2wav to be + unable to output to the soundcard. + +- cdda2wav now checks /etc/default/cdrecord and accepts dev=plextor as + cdrecord does. + +- Trying to add verbose output that estimates the read quality with -paranoia + +- Trying to convert non-ascii characters in user & host names into '_' + for better cddb compatibility. + +- Some Man Page Fixes trying to avoid coding problems for non 7-bit ACSII + +- New option -scanbus + +- Removed some "historical junk" that caused cdda2wav to define a + compile time default input device. This conflicts with cdda2wav -scanbus + and is superfluous and contra productive since cdda2wav reads + /etc/default/cdrecord + +- cdda2wav has signed bitfields of size 1 :-( + +- Fixed a typo in cdda2ogg.1 + +- Bug fix from Heiko for index lists that contain offset values of -1 in the middle + +- Trying to handle interface setup more carefully if SCSI Generic is not + used. + +- Better Debug Code in setuid.c + +- Trying to fix a bug in UID handling on FreeBSD + Thanks to the bugs reports and help from Fabian Keil <fk@fabiankeil.de> + +- Try to workaround a bug in GCC that caused incorrect warnings + for "strict-aliasing rules" + + +Readcd: + +- First (hacky) implementation of a way to meter the read speed + as a function of the disk location modeled after a idea from + Markus Plail <cdrecord@gitteundmarkus.de> + + Call: + readcd dev=b,t,l meshpoints=1000 > outfile + then + gnuplot + gnuplot> plot "outfile" w l + + or + + gnuplot> replot "outfile" w l + + if you like to overlay graphs. + +- New option fs=# (same syntax as with cdrecord fs=#) to allow the + user to set the maximum transfer size even in non-interactive mode. + This may help is the OS (as it has been the case for Solaris 9 x86) + reports a wrong maximum DMA size or there is a bug in libscg. + +- Speed printing with meshpoints=# now is based on 1000 bytes == 1 kb + as documented in the SCSI standard. + +- Stop reading if the OS replies with a DMA residual count != 0 + +- New option -factor will cause the read speed values to be printed + be based on the single speed of the current medium. This is only + possible if readcd is able to find out the current medium type. + +- The clone read code is now part of the GPL'd source + Note that this part of the code is now more than 2 years old but previously + has been excluded from the publically visible part of the source. + + Clone writing has been designed to allow to copy complex structured media + like e.g. SVCDs without the need to first do a sector by sector analysis + on the source media. + + To understand how to use the clone mode read README.clone + +- New option ts= to set the SCSI transfer buffer size + +- call setmode(fileno, O_BINARY) for DOS/DJGPP also + +- Now works again suid root on Solaris 9 + +- Better man page & online help for the ts= option. + +- New option -scanbus + +- Fixed a bug with -scanbus (did not work correctly if /etc/default/cdrecord + exists). + +- Added an allocated list of defective sectors, that is printed to the end of + a read operation. + + +Scgcheck: + +- Trying to check if multiple scg_open() requests result in + usable interfaces. + +- Send more outout to stdout instead of stderr. + +- More correct test for max sense count. + +- Eject CD _after_ asking for it. + +- Abor further DMA residual tests if a basic DMA residual test fails. + +- Second open test enhanced. + +- A small fix to prevent a core dump caused by a problem on Mac OS X. + + +Scgskeleton: + +- New Skeleton program as sample and template for programs that like to + use libscg. + + This template has been included to help people like the Author of the + BTC firmware flash program to write simple portable applications that + send arbitrary SCSI commands to arbitrary drives. + + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +- First attempt to support ISO-9660:1999 (Version 2) via -iso-level 4 + This allows 207 chars in filenames if Rock Ridge is not used + ans 197 207 chars in filenames if Rock Ridge is used. + + Note that this as an absolutely nontrivial change. Problems may + even occur when not using -iso-level 4. Please test and report + problems. + + It is not clear whether mkisofs should characters in the range + outside 7-Bit ASCII. Currently, mkisofs allows any 7-Bit ASCII + character except '\0' and '/'. + +- Second attempt to support ISO-9660:1999 (Version 2) via -iso-level 4 + This allows 207 chars in filenames if Rock Ridge is not used + and 197 207 chars in filenames if Rock Ridge is used. + + In version 2.01a01 the extended VD used the wrong signature 1. + This has been corrected. + +- isoinfo is now able to recognize ISO-9660:1999 + +- Enhanced the filename length for graft points to 2x PATH_MAX + +- Abort with a warning message if the total size of the image data + created by mkisofs would differ from the size printed by -print-size + +- udf.c indented according to hints from the program 'cstyle' + +- UDF now uses the same 'now' timestamp as the ISO-9660 part of the FS. + +- New Stream File feature and new options: + + -stream-file-name + -stream-media-size + + This feature has been implemented after an idea from M.H. Voase. + Mkisofs had to be heavily modified to allow this feature. + + A typical usage would look like this: + + star -c . | mkisofs -stream-media-size 333000 | cdrecord dev=b,t,l -dao tsize=333000s - + + The maximum size of the tar archive is 332800 sectors. + Note that only plain vanilla ISO-9660 is possible in this mode. + + +- The final padding that is added by default is now 150 sectors + which is the required size of the track post gap on a CD. + +- Inter partition padding is now only chosen to make the next partition + start on a sector number that is a multiple of 16. + +- isoinfo now also prints root directory extent # in debug mode + +- First step to allow mkisofs to support Kodak Photo CD and + Kodak Picture CD format: + + Try to correctly support associated files in multi-session mode. + + +- Diagnostic programs modified to use ttydefs.h and to have better + portability for the built in "stty" features. + +- isoinfo now prints the ISO-9660 directory flags. + +- Make mkhybrid a symlink to mkisofs instead of a hardlink + + +- getopt.h/fnmatch.h changed to use 'makefiles / prototype.h' based + system instead FSD junk system + +- Removed FSF junk from getopt.c that either created problems + with SCO Unixware or did not compile on AIX + +- Prototype for DVDOpenFile() to avoid warning on SCO UnixWare + related to enum function parameter + +- Fixed a bug with split symbolic links found by Klaus Kopper + with the new debug messages introduced with mkisofs-2.01a04 + +- Changed #if __STDC__ to #ifdef PROTOTYPES for better portability + +- Now using character code translation for 8 Bit characters that + are used with -iso-level 4 (ISO-9660-1999). + +- Fixed a typo in the on-line Usage information for isoinfo + +- New options -XA & -xa + + -XA Generate XA iso-directory attributes with original owner + and mode information. + + -xa Generate XA iso-directory attributes with rationalized owner + and mode information (user/group == 0). + + In the first phase of the implementation you need to specify -R in + addition. + +- Try to support files >= 2 GB. + Note that mkisofs is not yet written cleanly so there may be problems + if files >= are used. In such a case, please report. + +- Create XA "CD-XA001" signature in PVD with -XA or -xa + + In the first phase of the implementation you need to specify -R in + addition to -XA or -xa or no XA signatures will be written. + +- Removed a debug statement that has been introduced to implement + support for filees >= 2GB. + +- This version of mkisofs allows to create sectors with 2056 bytes if the + option -XA or -xa has been used together with -sectype xa1. + This is 2048 bytes + sub-header. + +- -apple does no longer include -R or -r. + If you like to use -apple, you need to use -R/-r or -XA/-xa in addition. + +- New option -sectype SECTYPE / -s SECTYPE + + Possible parameters are: + + data 2048 bytes per sector - the old and current default + + xa1 2056 bytes per sector - this is what you need for a conforming + CD-ROM XA multi session CD. Use -sectype xa1 together with -XA + +- Fixed a bug in the Rock Ridge symlink handling with Continuation records + triggered by '/../' filename components. + Thanks to jmmikkel@bbn.com (Joanne M Mikkelson) + for the fix. + +- man page corrected + +- Moved Eltorito PVD before ISO-9660:1999 enhanced PCD to allow + bootable CD with ISO-9660:1999 + +- -sort file handling fixed: mkisofs now looks for SPACE/TAB whatever + comes last (as documented in the man page). + +- Better error message in case of a stat(2) buffer overflow (too long + filename). This release now prints the file name that caused the problem. + +- call setmode(fileno, O_BINARY) for DOS/DJGPP also + +- Added a NOTE regarding the SILO boot program for Linux sparc to the + man page. + +- Added support for Solaris x86 boot CDs. + This includes the following new options: + + - -sunx86-boot to create a fdisk & SVr4 partition table + + - -sunx86-label to set the "disk label" name for the + SVr4 partition table. + +- New file README.sunx86boot + +- The file README.sunx86boot has been reworked to make it more correct + and contain less typos. + +- Fixed a Rock-Ridge length handling bug in update_nlink()/increment_nlink() (tree.c) + that may have caused an endless loop. + +- "Total extents including sparc boot" Message is now correctly + "Total extents including %s boot" sparc/sunx86 + +- mkisofs now checks /etc/default/cdrecord and allows e.g. + "mkisofs -C 0,1234 dev=plextor ...." as cdrecord does + +- Unclean message ....extents written (%d Mb) changed to + ....extents written (%d MB) to avoid "MegaBit" confusion. + +- Minor change for old UNIX versions like SCO OpenServer to get + smooth compilation on system where mode_t is a short. + +- Fix for a bug in RockRidge name handling for long file names + that need to be split into more than one sector. + Thanks to Patrick Ohly <Patrick.Ohly@gmx.de> + +- Trying to fix a bug in the multi session time stamp comparing + functions. CE records have not been handled correctly here. + +- Support for PowerPC CHRP Boot added, thanks to + "Leigh Brown" <leigh@solinno.co.uk> + +- Support for -uid/-gid for UDF Filesystems added + +- isoinfo now is able to list ElTorito Boot information with -d + +- isoinfo now correctly shows long RR filenames from CE Extension records. + +- Fixed a bug in the PowerPC CHRP Boot, thanks to + "Leigh Brown" <leigh@solinno.co.uk> + +- New options -root & -old-root from Patrick Ohly + This allows mkisofs to be used for "incremental backups" where + each backup is put into a separate directory tree on the CD. + +- Default to System ID "UNIX" for unknown platforms instead of + uning LINUX. + +- Support System ID "SCO-OPENSERVER" and "SCO-UNIXWARE" + +- Better error message when a user tries to create a multi session image + out of a multi-volume image. + +- When doing malloc(), include Null Byte at end of TRANS_TBL data to + avoid memory size conflicts. + +- Fix for a core dump caused by a double free() when doing: + echo bar >/tmp/bar + echo foo/bar=/tmp/bar > /tmp/pathlist + env LD_PRELOAD=libumem.so.1 UMEM_DEBUG=default UMEM_LOGGING=transaction \ + mkisofs -hfs -graft-points -o /tmp/foo.raw -path-list=/tmp/pathlist + + Thanks to Jürgen Keil jk@tools.de + +- Fixed a typo in write.c "Padbock" -> "Padblock" + Thanks to Richard Dawe <rich@phekda.gotadsl.co.uk> + +- Trying to fix a problem with comparing relaxed ISO-9660 file names + that contain a ';' which normally is a separator for the ISO-9660 + version number. The fix is in hash.c, please test! + +- Avoid GCCs shadowed variable warnings. + +- Added a comment is in hope to prevent silly people from + e.g. SuSE (who did not yet learn C but believe that + they need to patch other peoples code) from changing a + valid cast into an illegal lhs cast expression. + The cast in the unodified version of write.c is the correct way to + handle the problem. + + It would save a lot of time if people from companies like SuSE + would remember the Open Source software development model and + contact the Author for help rather than introducing proprietary + changes that result in worse and incompatible software variants. + + The way, companies like SuSE deal with Open Source software just + proves that Jonathan Schwartz from Sun is not wrong when he calls + SuSE and RedHat proprietary software companies. Users from Open Source + software expect that companies like SuSE and RedHat are in close + contact with the software developers but they unfortunately are not. + They prefer to create proprietary variants that are usually much + worse than the original software. The only explanation I have for this + behaviour is that SuSE likes to deviate from RedHat and RedHat likes + to deviate from SuSE in hope to get customer retention this way. + While the last 150 years did prove that this proprietary method to + tie up customers works for a limited time, it did always fail after + some time. + +- Removed verbose output for Eltorito boot method when called with -quiet + +- The Eltorito boot catalog and the Eltorito boot files are now by default + sorted to the beginning of the filesystem image as sime BIOS versions don't + boot from locations beyond 512 MB. + +- All programs from mkisofs/diag now support libscg so you may now + use e.g. isoinfo to list end extract from CDs directly on platforms + that do not support a usual driver interface (like on Win32). + +- Set default SYSID to "DOS" for DJGPP + Thanks to Alex Kopylov <reanimatolog@yandex.ru> + +- devdump isodebug isodump isoinfo isovfy + now include libscg and allow to use SCSI devices as input + +- devdump isodebug isodump isoinfo isovfy + now implement a new option dev= to force to use the SCSI + interface from libscg. + +- isoinfo now correctly sets the filemode of stdout to O_BINARY + on DOS alike Platforms like Win32 & DJGPP + This affects the '-x pathname' option + Thanks to Alex Kopylov <reanimatolog@yandex.ru> + +- The options -H/-L/-P from mkisofs have been marked "outdated" + as they are reserved by POSIX.1-2001 for other purposes. + + Mkisofs-2.02 will start to implement the POSIX.1-2001 semantics for + these options. + +- The max. length for the strings in the Primary volume descriptor + is now also documented in the options section of the man page. + +- Speed up by 30% in the case that a directory contains many (> 5000) + pathological file name entries (that _all_ do not differ in 8.3). + +- A minor speed up in devdump & isodump was made by no longer calling + strlen() in the end condition of a for loop (this still was old + code from Eric). + +- fixed a bug with -dvd-video + The bug caused mkisofs not to find the IFO file when VIDEO_TS was not + the first entry in the unsorted source directory. + Thanks to a hint from Johan Borg borg@morth.org + +- The option -volset-size does no longer accept numbers > 1 + + This change was needed because Eric Youngdale did completely + missunderstand the ISO-9660 standard with respect to Volume Set + Sizes. + + A Volume Set is not a numbered set of CDs but a set of CDs that + contains a coherent directory tree that would not fit on a single + volume. + +- Fixed a typo in the mkisofs man page + +- man page enhanced to make clear that the options + -no-split-symlink-fields & -no-split-symlink-components + are most likely not needed as they have been introduced by Eric Youngdale + when serious bugs have been in mkisofs. + +- Changelog updated + +- Try to workaround a bug in GCC that caused incorrect warnings + for "strict-aliasing rules" + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volunteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a01 b/doc/ANNOUNCEMENTs/AN-2.01.01a01 new file mode 100644 index 0000000..2d3a1eb --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a01 @@ -0,0 +1,91 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a01: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +- Better lint make rules + +- Better autoconf rrules for ACLs + +- Better support for Linux on IBM-390 + +- Better support for Linux on AMD x86-64 + +- Better conforming to lint warnings. + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +- Modified the remote SCSI library stuff that has been changed due + to a security problem on order to make it compile again on HP-UX. + +Rscsi: + +Cdrecord: + +- Support for the Plextor GigaRec feature. + Use driveropts=gigarec=1.2 to increase CD capacity by 20%. + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +Readcd: + +Scgcheck: + +Scgskeleton: + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a03 b/doc/ANNOUNCEMENTs/AN-2.01.01a03 new file mode 100644 index 0000000..e7819a2 --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a03 @@ -0,0 +1,150 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a02: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +- Now using "makefiles-1.5" + +- Compilation on OS/ should work again (-Zexe -> -o xxx.$(EXEEXT) + +- Sleeptime to allow reading Gmake warning reduced to 2 seconds. + I am still waiting for GNU make to fix the bugs I did report in 1999. + +- Support for 'make DESTDIR=xxx install' added + +- Workaround for a Shell Bug on BSDi + +- Install workaround for the fact that BSDI has chown(1) in /usr/sbin/ + +- cc-config shell script reworked + +- Better configure tests for procfs include files + +- Configure tests for fchown, chmod, fchmod, lchmod, futimes, lutimes + +- Configure tests for fdopendir + +- Configure tests for broken ext2fs includes files in Linux kernel + +- Better SRCROOT search function in makefiles shell scripts + +- libunls reworked + +- New autoconf tests for broken <linux/ext2_fs.h>, <scsi/scsi.h> & <scsi/sg.h> + on various Linux systems + + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +- Trying to introduce a workaround for broken <scsi/scsi.h> & <scsi/sg.h> + on various Linux systems. + +- Trying to introduce a workaround for the changed SCSI generic Linux + Kernel interface from Linux-2.6.8.1 and newer. + + Be very careful with testing. The Linux adption layer for libscg + is already full of workarounds for bugs, unstable interfaces and + unwillingness of the Linux Kernel maintainers to give access to the + needed information for libscg. I am not sure whether this workaround + will not have problems. It has been tested on a Pegasus PPC running + Linux-2.6.8.1 + +Rscsi: + +Cdrecord: + +- Allow the -shorttrack option for RAW mode, thanks to a report + from Sebastian Trueg + +- Enhance the minimal grace time from 2 to 3 seconds to make sure + that cdrecord will not get out of sync with locks from the + Volume management system. + +- Better checks and better error messages for /etc/default/cdrecord + +- Correct verbose print mode for old pre-MMC TEAC drives. + +- Added support for Ultra speed+ CD-RW media recognition and a check + whether the drive supports Ultra speed+ CD-RW media. + (Thanks to Alexander Noé). + + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +Readcd: + +Scgcheck: + +Scgskeleton: + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +- Better error messages with wrong Eltorito boot options + +- Man page is now more explicit about requirements for DVD-video + directory trees. + +- Better warning text for missing Rock Ridge in multi.c + +- Bugs in README.sunx86boot corrected + +- Multi Volume code for reading old image now gives different + error messages on read errors and short reads. + +- Diagnostic programs isodump, isoinfo, ... no longer dump core + when called with dev=<SCSI addr> parameters. + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a04 b/doc/ANNOUNCEMENTs/AN-2.01.01a04 new file mode 100644 index 0000000..7acaf29 --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a04 @@ -0,0 +1,164 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a04: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +- astoull*() new in schily.h + +- utypes.h now has MAX_ and MIN_ value definitions for all basic + system types. + +- Using Makefiles-1.5a02 + +- Support added to compile in 64 bit mode on Solaris Sparc. + Use: smake CCOM=cc64 + +- Support added to compile shared libraries with version + numbers for interface levels and make inofficial "interfaces" + static + +- Prevent gmake to go into an enless loop on Solaris + in case that /usr/ucb/tr is before /usr/bin/tr in PATH + +- Better autoconf error message ion case that the expected + C-compiler could not be found. + +- Mac OS X now installs files as root:wheel + +- Supply linker mapfiles for all libraries. This allows cdrtools + to be compiles using shared libraries only and to properly + hide inofficial interfaces on Solaris (using ls) + Note that this feature is not available with GNU ld + + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +- Autoconf test for broken Linux sg.h headers added + +- if libscg is compiles on newer Solaris systems, the warning: + + "Warning: Volume management is running, medialess managed drives are invisible.\n" + + is no longer printed. + + Since Solaris 11 Build 21, vold no longer hides empty drives + that are under volume management. This now allows cdrecord to be even + used to close the tray while vold is running. + + The criteria used to decide whether Solaris is "recent enough" is + #ifndef SEEK_HOLE + The definition SEEK_HOLE has been added with Solaris 11 Build 14 + while the fixed vold appears in Solaris 11 Build 21. + +- Support for root-less cdrecord using fine-grained privileges. + Remote SCSI not tests for PRIV_NET_PRIVADDR instead of (geteuid() == 0) + + If you like all users to be able to call cdrecord root-less, you need + Solaris 10 or newer. + + Edit the file /etc/security/exec_attr and add: + + All:solaris:cmd:::/opt/schily/bin/cdrecord: privs=file_dac_read,sys_devices,proc_lock_memory,proc_priocntl,net_privaddr + All:solaris:cmd:::/opt/schily/bin/readcd: privs=file_dac_read,sys_devices,net_privaddr + All:solaris:cmd:::/opt/schily/bin/cdda2wav: privs=file_dac_read,sys_devices,net_privaddr + + If you like to allow only specific user to use cdrecord, + use something like: + + CD RW:solaris:cmd:::/opt/schily/bin/cdrecord: privs=file_dac_read,sys_devices,proc_lock_memory,proc_priocntl,net_privaddr + + instead and make the users members of the profile "CD RW" + by adding a line like: + + joerg::::profiles=CD RW + + into /etc/user_attr + + Note that you either need to call cdrecord via "pfexec cdrecord ....." + or by using a profile aware shell (e.g. /usr/bin/pfksh) + +Rscsi: + +Cdrecord: + +- Correctly evaluate the write speeds for Ultra speed+ CD-RW media. + This prevents wrong warnings that the "drive does not support Ultra speed+" + +- Fixed a typo in the driveropts=help messages + + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +- Added a workaround for the _POSIX_PRIORITY_SCHEDULING behavior + on MacosX: defined but not supported# + Thanks to: Emanuele Giaquinta <e.giaquinta@glauco.it> + +- Bugfix: cdda2wav did previously chose to ignore the result of realloc(3) + This prevents core-dumps. + +Readcd: + +Scgcheck: + +Scgskeleton: + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +- mkisofs now detects if a file grows or shrinks while being + read by mkisofs. + + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a05 b/doc/ANNOUNCEMENTs/AN-2.01.01a05 new file mode 100644 index 0000000..f52ab26 --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a05 @@ -0,0 +1,143 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a05: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +- Support for DragonFly BSD added, thanks to joerg@britannica.bec.de + +- Default Cygwin install uid/group adapted to use available ids. + +- Updated the (forgotten) autoconf to include the tests needed for Solaris + fine grained privileges. + +- New program btcflash added. Thanks to David Huang <khym@azeotrope.org> + +- + If you like all users to be able to call cdrecord root-less, you need + Solaris 10 or newer. + + Edit the file /etc/security/exec_attr and add: + + All:solaris:cmd:::/opt/schily/bin/cdrecord: privs=file_dac_read,sys_devices,proc_lock_memory,proc_priocntl,net_privaddr + All:solaris:cmd:::/opt/schily/bin/readcd: privs=file_dac_read,sys_devices,net_privaddr + All:solaris:cmd:::/opt/schily/bin/cdda2wav: privs=file_dac_read,sys_devices,proc_priocntl,net_privaddr + + If you like to allow only specific user to use cdrecord, + use something like: + + CD RW:solaris:cmd:::/opt/schily/bin/cdrecord: privs=file_dac_read,sys_devices,proc_lock_memory,proc_priocntl,net_privaddr + + instead and make the users members of the profile "CD RW" + by adding a line like: + + joerg::::profiles=CD RW + + into /etc/user_attr + + Note that you either need to call cdrecord via "pfexec cdrecord ....." + or by using a profile aware shell (e.g. /usr/bin/pfksh) + + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +- Support for root-less cdrecord using fine-grained privileges. + Remote SCSI not tests for PRIV_NET_PRIVADDR instead of (geteuid() == 0) + This is now active since the needed autoconf code is out. + +Rscsi: + +Cdrecord: + +- Trying to work around a noncompliance (modified interface) present on newer + Linux kernels that causes cdrecord to be unable to allocate a SCSI transfer + buffer. + + Newer Linux kernels do not honor a contract from mlockall(MCL_FUTURE) + after cdrecord turned off euid == 0 from a suid root installation. + Instead of honoring mlockall(MCL_FUTURE), Linux checks each mmap() + and compares against getrlimit(RLIMIT_MEMLOCK + +- Explicit fine grained privileges support for Solaris. + Cdrecord now switches off all privs that are no longer needed. + + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +- Explicit fine grained privileges support for Solaris. + Cdda2wav now switches off all privs that are no longer needed. + +Readcd: + +- Allow readcd to work correctly in -scanbus mode + Thanks to Fabian Keil <fk@fabiankeil.de> for reporting. + +- Explicit fine grained privileges support for Solaris. + readcd now switches off all privs that are no longer needed. + +Scgcheck: + +Scgskeleton: + +- Allow readcd to work correctly in -scanbus mode + Thanks to Fabian Keil <fk@fabiankeil.de> for reporting. + +- Explicit fine grained privileges support for Solaris. + Scgskeleton now switches off all privs that are no longer needed. + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a06 b/doc/ANNOUNCEMENTs/AN-2.01.01a06 new file mode 100644 index 0000000..8a4f3e6 --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a06 @@ -0,0 +1,141 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a06: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +- Better support for BeOS/Zeta in the makefile system + +- Support for armv5teb-linux-cc was added to the makefile system + +- + If you like all users to be able to call cdrecord root-less, you need + Solaris 10 or newer. + + Edit the file /etc/security/exec_attr and add: + + All:solaris:cmd:::/opt/schily/bin/cdrecord: privs=file_dac_read,sys_devices,proc_lock_memory,proc_priocntl,net_privaddr + All:solaris:cmd:::/opt/schily/bin/readcd: privs=file_dac_read,sys_devices,net_privaddr + All:solaris:cmd:::/opt/schily/bin/cdda2wav: privs=file_dac_read,sys_devices,proc_priocntl,net_privaddr + + If you like to allow only specific user to use cdrecord, + use something like: + + CD RW:solaris:cmd:::/opt/schily/bin/cdrecord: privs=file_dac_read,sys_devices,proc_lock_memory,proc_priocntl,net_privaddr + + Also edit /etc/security/prof_attr + + CD RW:::CD-R/RW Recording Authorizations:auths=solaris.device.cdrw + + instead and make the users members of the profile "CD RW" + by adding a line like: + + joerg::::profiles=CD RW + + into /etc/user_attr + + Note that you either need to call cdrecord via "pfexec cdrecord ....." + or by using a profile aware shell (e.g. /usr/bin/pfksh) + + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +- BeOS/Zeta libscg low level adoption code fixed. + The code now is passing a "scgcheck" test. + +Rscsi: + +Cdrecord: + +- Adjust some timeouts to prevent that the drive buffer of + newer Pioneer DVD writers empties when writing high speed DVD + media. + +- Support for BeOS/Zeta shared memory was added + +- New tag CDR_MAXFIFOSIZE= in /etc/default/cdrecord allows to + limit the size of the FIFO cdrecord is using. This helps the + sysadmin to prevent other people from locking up the system. + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +Readcd: + +- Support for BeOS/Zeta shared memory was added + +- -scanbus behavior corrected + +Scgcheck: + +- Fixed DMA overrun test. BeOS/Zeta did pass the test but + scgcheck did complain before. + +Scgskeleton: + +- -scanbus behavior corrected + +Btcflash: + +- -scanbus behavior corrected + +- man page added + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +- try to work around a GCC trigraph problem + +- man pages for diag commands added + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a07 b/doc/ANNOUNCEMENTs/AN-2.01.01a07 new file mode 100644 index 0000000..2bac2f6 --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a07 @@ -0,0 +1,96 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a07: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +- Autoconf script added to 'conf' directory + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +Rscsi: + +Cdrecord: + +- Fixed a bug caused by an uninitalized variable when handling + CDR_MAXFIFOSIZE= and no file /etc/default/cdrecord exists + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +- Write correct error info in case that BeOS/Zeta *_area() calls + fail. + +- As Heiko did not work on cdda2wav during the past 2.5 years, + Heiko did hand over the SCCS history for cdda2wav. + +- Autoconf test for <sys/cdio.h> added (FreeBSD) + +- Some FreeBSD related changes from Heiko done in 2004 + + IMPORTANT: I need testers for FreeBSD and DragonFly BSD as + a result of the merge with the complex changes + from Heiko. + +Readcd: + +Scgcheck: + +Scgskeleton: + +Btcflash: + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/ANNOUNCEMENTs/AN-2.01.01a08 b/doc/ANNOUNCEMENTs/AN-2.01.01a08 new file mode 100644 index 0000000..b45988c --- /dev/null +++ b/doc/ANNOUNCEMENTs/AN-2.01.01a08 @@ -0,0 +1,96 @@ +Please have a look at the German open Source Center BerliOS at www.berlios.de +BerliOS will continue to support free hosting of cryptography projects even +when US laws change and don't allow to host cryptography projects in the USA. +Also look at sourcewell.berlios.de, the first Open Source announcement service +that itself is implemented as Open Source project. + +***************** Important news **************************** + +For the 'Slottable Source Plugin Module' SSPM Features read README.SSPM + +***************** Please Test ********************************* + +NEW features of cdrtools-2.01.01a08: + +******* +NOTE: this is _not_ a release that starts a new aplha/beta series of dirtibutions. + The only reason is to add certain new CD/DVD features that are important. + + So _please_ do not send any patches except when you like to fix extreme bugs. + I am currently mainly working on stable incremental restore featurs for star-1.5-final. + Once star-1.5-final is out, cdrtools will start a new developent cycle. +******* + +All: + +Libparanoia (Ported by Jörg Schilling, originated by Monty xiphmont@mit.edu): + +Libedc (Optimized by Jörg Schilling, originated by Heiko Eißfeldt heiko@hexco.de): + +Libscg: + +Rscsi: + +Cdrecord: + +Cdda2wav (By Heiko Eißfeldt heiko@hexco.de): + +- Started to make cdda2wav Cstyle compliant. + +- Avoid to shutdown the whole system when kill(getppid(), SKGINT) + would result in kill -INT 1 because the parent cdda2wav is + dead and the child is orphaned and cdda2wav has been called by root. + +- __FreeBSD_version >= 600021 have devmajor == 0 for all devices. + Thanks to Marius Strobl <marius@alchemy.franken.de> for reporting. + +- General #ifdef structure related to FreeBSD in mycdrom.h now + corrected, thanks to Marius Strobl. + +- Try to fix some FreeBSD/DragonFly related problems that have been + introduced with a06 when Heiko's changes from 2004 have been integrated + + IMPORTANT: I need testers for FreeBSD and DragonFly BSD as + a result of the merge with the complex changes + from Heiko. + +Readcd: + +Scgcheck: + +Scgskeleton: + +Btcflash: + +Mkisofs (By Jörg Schilling and James Pearson j.pearson@ge.ucl.ac.uk): + +TODO: + - read Joliet filenames with multi-session if no TRANS.TBL + or RR is present. I am looking for a volouteer for this task! + + Note that this can never be 100% correct as there is no relation + between the names on the master (UNIX) filesystem, the ISO-9660 + names and the Joliet names. Only the Rock Ridge names are + untranslated with respect to the original files on the + master (UNIX) filesystem. + + - add libecc/edc for CDI and similar. + + +CYGWIN NT-4.0 NOTES: + +To compile on Cygwin32, get Cygwin and install it. +For more information read README.win32 + +The files are located on: + +ftp://ftp.berlios.de/pub/cdrecord/alpha ... + +NOTE: These tar archives are 100% POSIX compatible. GNU tar may get some + minor trouble. If you like a 100% POSIX compliant tar, get star from + ftp://ftp.berlios.de/pub/star/ + +WARNING: Do not use 'winzip' to extract the tar file! + Winzip cannot extract symbolic links correctly. + +Joerg diff --git a/doc/DOC-OVERVIEW b/doc/DOC-OVERVIEW new file mode 100644 index 0000000..d40ff6c --- /dev/null +++ b/doc/DOC-OVERVIEW @@ -0,0 +1,35 @@ +This is the documentation collection of the cdrkit package + +It has been derived from the cdrtools package maintained by +Joerg Schilling. However, other maintainers work on this +spinoff of the documentation. + +Keep in mind that cdrkit is not cdrtools when you read the +documentation. Some details may be void in context of +cdrkit. + +Contents: + +ANNOUNCEMENTs : directory containing AN* files with release + notes from old cdrtools releases + +READMEs : contains HOWTOs and instructions relevant to + various tasks, especially such where multiple + programs are involved + +wodim : contains README files relevant for the work with the + wodim application (writing data) and details specific + to its usage + +genisoimage : documentation for work with genisoimage program, a + ISO9660 filesystem creator. See genisoimage/README for + details. + +icedax : contains documentation for the CD audio + extraction utility icedax. See icedax/README for + details. + +platforms : contains notes about portability to different + platforms + + diff --git a/doc/PORTABILITY b/doc/PORTABILITY new file mode 100644 index 0000000..c694a22 --- /dev/null +++ b/doc/PORTABILITY @@ -0,0 +1,34 @@ +You may have heard from a certain person that cdrkit is not portable and you +may need some help to decide whether you shall believe him/her or not. It is, +as usual, recommended to make your own opinion before adopting someone elses +which may be biased. + +What is portability? Portability is the ability for being compiled and +deployed on a platform that an application supports. It is obvious that nobody +can promise the unlimited portability especially not to operating systems to do +not exist yet or that are long dead (dead like in: unsupported, unmaintained for +many years, needing hardware which is not available in stores for many years). +And there could always undocumented bugs which means that real life tests +should be done on the target platform(s) again and again. + +Therefore, unlimited portability is pure utopia. It is required to define a +certain degree of portability to meet the needs of the target user base. + +How does that work in scope of cdrkit? Main target are mainstream platforms. +Currently, it supports Linux, FreeBSD, Cygwin (Win32), SunOS and AIX5l. This +set should cover the majority of general purpose computer systems in the wild. + +Cdrkit sets some requirements on the targeted operating systems. However, most +modern unix-like OS should be able to fullfill them. Those requirements +include: + + - an ANSI-C compiler, or a GCC port + - GNU make port + - Large File Support + - sane libc library + - some prerequisites to bootstrap CMake + +This cuts off support for really old operating systems, but... do you care? Do +you need it? Or do you want to believe the tales of superiority through (just +claimed) portability? + diff --git a/doc/READMEs/README.ATAPI b/doc/READMEs/README.ATAPI new file mode 100644 index 0000000..8b2e601 --- /dev/null +++ b/doc/READMEs/README.ATAPI @@ -0,0 +1,589 @@ + +The file attached below provides a short explanation about the nature of ATAPI +and the support for it on various platforms. However, it was written for an +old version of cdrtools by Joerg Schilling and completed with even older guides +supplied by other authors, therefore parts of the content are no longer true or +are not applicable anymore. Read and interpret with care! + +See README.ATAPI.setup for a quick setup guide for Linux. + +Eduard Bloch, 2006 + +# @(#)README.ATAPI 1.3 04/05/20 Copyright 1997-2004 J. Schilling + +People (with a Linux only background) often ask me why do you depend on +"ATAPI-SCSI emulation", why don't you support generic IDE? + + Well first a statement: There is no single IDE burner out! + Even a CD-ROM cannot be used decently if you use only IDE commands. + Opening/closing the door, playing audio and similar things + cannot be done using vanilla IDE commands - you will need SCSI commands + to do this. But how do we do this with a drive that uses an IDE + interface? + + ATAPI stands for ATA Packet Interface + + The ATAPI standard describes method of sending SCSI commands over IDE + transport with some small limitations to the "real" SCSI standard. + SCSI commands are send via IDE transport using the 'ATA packet' + command. There is no SCSI emulation - ATAPI drives include native + SCSI command support. For this reason, sending SCSI commands to ATAPI + drives is the native method of supporting ATAPI devices. Just imagine + that IDE is one of many SCSI low level transport mechanisms. + + This is a list of some known SCSI transports: + + - Good old Parallel SCSI 50/68 pin (what most people call SCSI) + - SCSI over fiber optics (e.g. FACL - there are others too) + - SCSI over a copper variant of FCAL (used in modern servers) + - SCSI over IEEE 1394 (Fire Wire) + - SCSI over USB + - SCSI over IDE (ATAPI) + + As you now see, the use of the naming convention "ATAPI-SCSI emulation" + is a little bit misleading. It should rather be called: + "IDE-SCSI host adapter emulation" + +Some naming explanations: + + ATA Attachment Adapter + IDE Integrated Drive Electronics (A Drive that includes ATA) + ATAPI ATA Packet Interface + +When wodim has problems with ATAPI drives on Linux this usually is a Linux +kernel problem. The Linux kernel maintainers unfortunately refuse to correct +their current IDE driver system setup which does not support ATAPI by default. +ATAPI _is_ SCSI over IDE transport. It is hard to understand why Linux still +uses a default driver setup that is designed for IDE CD-ROM drives made +before 1994 (using a IDE compat mode that only allows to use the drive +read-only) and does not handle to send SCSI commands to ATAPI drives by +default. This makes it hard for people who just started with Linux to do +CD-writing on Linux if they own an ATAPI drive. Both Linus Torvalds and +Alan Cox admit that they don't own a CD/DVD writer, how should they know about +the problems? + +There are bugs with the DMA implementation that are known for many years +but they don't get fixed. + +/*--------------------------------------------------------------------------*/ +Which Operating systems support ATAPI + +- AIX: Status unknown! Please report your experience... + +- Apple Mac OS X (Darwin): Supported + +- BeOS (libscg maps ATAPI to SCSI bus # >= 8 + +- BSD/OS: Status unknown! Please report your experience... + +- FreeBSD: + - YES for the latest default kernel. + It includes finally ATAPI-Cam + + - NO for the older kernels. + Yes, if you install a kernel patch from + Thomas Quinot <thomas@cuivre.fr.eu.org> + See http://www.cuivre.fr.eu.org/~thomas/atapicam/ + and README.FreeBSD + +- HP-UX: It looks like ATAPI does not work correctly due to kernel bugs. + + New information: + HP supports a HP A7853A B/C class machine (s700_800) with HP-UX-11.x + You need to install a patch: + + Patch Name: PHKL_27224 Patch Description: s700_800 11.00 IDE/ATAPI + cumulative patch + + +- Linux (unfortunately not in the default configuration) + + - It works more or less if you include ide-scsi + + - Linux-2.4.xx includes a CDROM Packet interface in the + IDE CD driver. For this driver libscg now includes + support in pre-alpha status. Use wodim dev=ATAPI -scanbus + to check for drives and e.g. wodim dev=ATAPI:0,0 .... + for writing. Note that this interface is not integrated into + the standard libscg device naming scheme. Support for + this interface has been included because it is the only + way to use a PCCARD/PCMCIA writer - trying to use ide-scsi + on a PCATA interface will cause a Linux kernel panic + or will block all ATAPI drives. + + - Starting with Linux-2.5.45, there is a new experimental + ATAPI interface initiated by Linus Torvalds. Unfortunately, + this interface does not fit well into the rest of the Linux + SCSI kernel transport naming scheme. Wodim allows to + use this interface by calling e.g. wodim dev=ATA:1,0,0 ... + + All Linux ATAPI transport implementations do not support DMA. + Current exceptions are: + + - ide-scsi with block size 2048 and if DMA has been enabled + + - The new experimental ATAPI interface starting with Linux-2.5.45 + allows DMA if DMA has been enabled and the sector size is a + multiple of 4. This allows to use DMA for audio CDs and + when writing any type of CD in RAW mode. + + Note that is a bad idea to first implement a new kernel + interface that also implements the named DMA implementation + bugs and later fix the DMA bug _only_ for this new + interface. It looks like the Linux kernel folks are not + very cooperative :-( + + RAW mode is needed for many new and cheap drives that have bugs when + writing in cooked mode. If there is no DMA, you cannot write faster + than approx 16x. + + +- NetBSD (releases 1.3 and newer) + +- NeXT: Status unknown! Please report your experience... + +- OpenBSD: (release 2.6 and newer) + +- OS/2 (you need to fetch and install ATAPI support first) + see: http://www.leo.org/pub/comp/os/os2/leo/drivers/dasd/daniatapi.zip/ + +- OSF-1 / True64 Status unknown! Please report your experience... + +- SCO-OpenServer: Supported with 5.0.6 and non-public patch or with + 5.0.7. I don't know whether you need a patch for 5.0.7 + +- SCO-UnixWare: partial support with UnixWare 7.1.3 - some SCSI commands + that are needed for cdda2wav and DVD writing are blocked. + 7.1.4 will have full ATAPI support. + +- SGI/IRIX: Status unknown! Please report your experience... + +- Solaris (you may need to use the USCSI transport interface to address + ATAPI if the IDE hostadapter idriver implementation does not follow + Sun's internal standards). + + ATAPI works fine on Solaris 7 sparc and on Solaris 7/8 intel. + + On Solaris 8 (intel) and newer, the ATAPI/SCSI subsystem is integrated + correctly according to Sun's SCSA white paper, so the 'scg' driver works. + This is not true for Solaris on sparc where the ATAPI driver do not conform + to Sun's internal structuring rules. You need to use the USCSI interface + on for ATAPI drives on Solaris sparc for this reason. + + Solaris 8 sparc has a ATA DMA bug that prevents wodim from working at all. + There is a fix from Sun available: the patch 108974-16 + Solaris 9 sparc works again, it has the fix for the ATA DMA bug included. + + Newer versions of Solaris 9 disable DMA for CD-ROM drives on IDE. + Read README.solaris-x86-ATAPI-DMA to learn how this may be circumvented. + +- VMS: works on recent versions! + +- Win32 using a recent ASPI Layer supports ATAPI + You nay need to exclude mini port drivers (see README.win32). + + Newer wodim versions also support the SPTI (SCSI Pass through ioctl). + Libscg uses SPTI by default if you are running NT-5.x or newer and are + administrator. With NT-4.x it may be possible to run wodim dev=SPTI:1,0.0 ... + But there are reports for blue screens (kernel crashes). + +- DOS DOS-7 from win98 includes a ATAPI aware aspi + For other versions have a look at README.msdos and use e.g. "oakaspi". + +/*--------------------------------------------------------------------------*/ +General hints: + +*********************** +NOTE: IDE/ATAPI doesn't have disconnect/reconnect! you cannot expect the needed + performance for CD-writing if you connect source and destination drive + to the same IDE cable. +*********************** + +If you never like to directly write a CD from CD-ROM source, this configuration +seems to be the best: + +IDE 0 MSTR -> HD1 +IDE 0 SLAV -> HD2 + +IDE 1 MSTR -> CD-writer +IDE 1 SLAV -> CD-ROM + +If you like to write from both HD source and CD-ROM source, you should have +the following configuration: + +IDE 0 MSTR -> HD1 (does _not_ hold CD mastering data) +IDE 0 SLAV -> CD-Writer + +IDE 1 MSTR -> HD2 (holds CD mastering data) +IDE 1 SLAV -> CD-ROM + +If cou cannot set up a decent cabling (e.g. because you use a notebook) +you may try to use wodim -immed ... +It runs slow commands in quick (immediate) return background mode and +tries to wait between the write commands to allow to free the IDE cable +so the wodim read process may fill the FIFO from the other drive +on the same IDE cable. + +/*--------------------------------------------------------------------------*/ +The rest of this file is only valid for Linux! + +This was taken out of mails from From: Dave Cohen <dcohen@richmond.infi.net> +and From: Gadi Oxman <gadio@netvision.net.il> +(slightly modified marked ***JS *** except typo corrects) + +As all current Linux versions have ATAPI support for wodim, +I removed the patch section. If you are running a Linux version +that does not support ATAPI<->SCSI command transport, please upgrade. + +The basic driver design in Solaris would also allow to use ATAPI +drives but unfortunately, Sun made a mistake in the mid-level design. +If you want to use ATAPI drives with Solaris, ask Sun why they don't +support SCSI passthrough to IDE although they are using a common driver +concept. + +Please use cdrecord-1.6 final or later (if available), it includes the +modifications needed for ATAPI drives and is still working with other +SCSI drives. Older revisions of cdrecord do not support ATAPI drives. + +If you are using Linux Kernel version prior to 2.1.73 or prior to +2.0.35, please upgrade before you try to compile and use wodim. + +In any case, you need to configure a kernel with ATAPI/SCSI hostadapter +emulation. Read carefully the following instructions: + +In any case, you need to disable generic IDE/ATAPI CDROM support in +order to make ATAPI SCSI emulation working. + +Many people ask why I use ATAPI-SCSI emulation. + + The use of the naming convention "ATAPI-SCSI emulation" is a + little bit misleading. It should rather be called: + "SCSI host adapter emulation" + + The ATAPI standard describes method of sending SCSI commands over IDE + with some small limitations to the "real" SCSI standard. + For this reason ATAPI-SCSI emulation is the native method of + supporting ATAPI devices. + +If you have problems to talk to the device when it is jumpered as "slave" +try to use it as "master". If you connect a hard disk to the same IDE +cable as the CD writer or if you try to read/write data from another drive +that is connected to the same IDE cable as the CD writer you may get +problems too. + +NOTICE: + +With the newer 2.1.x or 2.2.x kernels it seems to be possible to run +SCSI/ATAPI hostadapter emulation and generic IDE at the same time by +selectively telling the kernel what to use for which drive. However, +this would not be needed if the Linux SCSI CD-ROM driver would be more +up to date and supports standard conforming drives. + +Jörg Schilling <schilling@fokus.fhg.de> + +-------------------------------------------------- +Here is a hint from Alan Brown <alanb@manawatu.gen.nz>: + +To allow ATAPI cd and ide-scsi support on the same machine, add +`hd<x>=ide-scsi` to the lilo.conf append entry, or use +`hd<x>=ide-scsi` at the bootup lilo prompt. + +I have my HP-7200 RW drive as the primary drive on the second IDE +bus, so the statement used is "hdc=ide-scsi" + +-------------------------------------------------- + +Hope that the following is helpful to you. + +I recently purchased a HP-7110i CD-RW, which is the U.S. only version of +what you have. The HP 7100 and 7110 CD rewritables use the ATAPI +standard. Originally, the drives were not supported under Linux (due to +some inconsistencies with SCSI translations between the kernel and the +CD), but that problem has just recently been fixed. There are some kernel +and wodim patches that have been made to support this device that have +yet to be officially incorporated into cdwrite and the kernel. In order to +get your drive supported under Linux, you will have to do the following: + +1. Get the proper version of cdrecord. + +As of this writing, I am just getting ready to test Joerg's new cdrecord. +I am currently operational on cdrecord-1.5, so I know that works, and I +have attached patches for that version. + +If you are in a hurry, you can download ver. 1.5, apply patches, and +rock-n-roll. You may want to wait, though. Up to you ;). The version with +ATAPI support is cdrecord-1.6alpha5. I'm not sure if the current kernel +patches are valid for this version, but i'll know soon enough. +**** They are valid **** JS + +BTW, the new version of xcdroast now supports cdrecord - this version +is in beta testing, too (currently uses cdrecord-1.5 but cdrecord-1.6a5 +should work with the current xcdroast too). + +2. Upgrade to kernel version 2.0.31 + +IDE/SCSI translation was first added in this kernel. Because your CD-RW is +an ATAPI device, it will support SCSI command sets. The translation +allows you to map the device as a SCSI generic device. This will allow +cdrecord to recognize it as a SCSI device. +**** 2.0.31 still needs patches, get 2.0.35 or later **** JS + +3. Get the patches and apply them + +Attached find kernel patches for kernel sources ide.h and ide-scsi.c, and +cdrecord source scsi_cdr.c (version 1.5 only). +**** Get cdrecord-1.6 or later **** JS + +3. Recompile kernel with SCSI emulation support + +If you do a "make menuconfig" or "make xconfig", select SCSI emulation +under the category "Floppy, IDE, and other block devices". + +WARNING: +Do not install SCSI support as a module - there is a bug in the makefile +structure that will cause the compile to fail. Compile directly into the +kernel. + +4. WARNING: Disable generic IDE/ATAPI CDROM support *** JS *** + +If you don't do this, the SCSI emulation will not work *** JS *** + +5. This is important too: +You also need to enable SCSI and SCSI generic support *** JS *** + +6. Make sure that /dev/sg* exists. +If they are missing, create them. + +Dave Cohen +dcohen@richmond.infi.net +(Patch instructions below) + +----------------------------------------------------------------- +From: Danilo Fiorenzano <shade@juliet.gppsd.ab.ca> + +Anyway, here's what I did, using kernel version 2.0.33 I believe this +is the proper way to get an HP-7100i to work (and as far as I can tell, +any other IDE CD-writer unit): + +1) patch the kernel as described by README.ATAPI + +2) save your current kernel config to an alternate file, then run + "make mrproper" + +3) run 'make menuconfig' or 'make xconfig', then choose "load config + from alternate file" to restore the original configuration + +4) In "Floppy, IDE and other block devices", disable "IDE/ATAPI CD-ROM + support" and enable instead "scsi emulation" + +5) in "SCSI support" enable "SCSI support", "SCSI CD-ROM support" and + "SCSI generic support", everything directly in the kernel. + +6) compile, install kernel/modules, reboot. Now, if everything went + fine, your CDROM units should show up with a message like: + "hdb: HP CD-Writer+ 7100, ATAPI CDROM drive - enabling SCSI emulation" + +7) run "wodim -scanbus" to make sure wodim can see the unit and + talk to it. The end. + +Don't forget that now -all- of your CD drives are seen as -SCSI- units +by all programs (/dev/scd0 etc.), so you might want to relink +/dev/cdrom to the proper scd<n> in order to get xcdplay or whatever to +work again. + + +------------------------------------------------------------------------------- +NOTE: + +1) Current wodim releases support ATAPI + +2) Linux 2.0.35 or Linux 2.1.73 or later include ATAPI support +------------------------------------------------------------------------------- +From whampton@staffnet.com Fri Jan 14 05:21:34 2000 +From: "W. Wade, Hampton IV" <whampton@staffnet.com> + +You may wish to include/append these notes to your ATAPI notes.... + +I have my 4X Acer CD-R/RW ATAPI drive working with Linux. My platform +is +RedHat 6.1 with kernel 2.2.14. My first ATAPI CD device is a DVD with +the second +the CD-R. I made the following changes: + +Steps: + +1. Identify which device is the CD-R -- in my case the fourth ATAPI +device, /dev/hdd. + +2. Compile the kernel to include ATAPI CDROM and SCSI emulation: + + Under the block devices menu: + Y or M Include IDE/ATAPI CDROM support + Y or M SCSI emulation + +3. Build and install the upgraded kernel. + +4. If you selected modules, add them to the /etc/conf.modules file. + +5. In the /etc/lilo.conf file add an append line for ide-scsi, in my +case: + append = "hdc=ide-scsi hdd=ide-scsi" + +6. Reboot to the new kernel and make sure the ide-scsi module is loaded + + /sbin/lsmod | grep ide-scsi + +7. Make a link from the proper SCSI device to a symbolic, e.g., +/dev/cdrom: + In my case the DVD is the first CD, hence appears as /dev/scd0 to +scd7 + (cat /proc/scsi/scsi to get a full list of devices -- the first +CD-ROM will + appear as scd0, etc.) With the current ATAPI-SCSI module, each CD + + device appears as 8 SCSI devices (different logical units). If +you have + two devices, like I do, you may have to make a node for the second +device. + In my case I had to make scd8: + + cd /dev + mknod scd8 b 11 8 + + Then make links, in my case: + + ln -s scd0 cdrom + ln -s scd8 cdr + + Note, many CD-ROM player programs expect the audio CD drive to + be located at /dev/cdrom (xplaycd, etc.), hence this link is +recommended. + + If you try to use /dev/hdc (or wherever your CD or CD-R is) +after loading + the ide-scsi module, you may not be able to mount CD's or play +audio + discs -- you have to use the new SCSI names for the device. + +8. Fix your /etc/fstab file to mount the /dev/cdrom and /dev/cdr + + +/*--------------------------------------------------------------------------*/ +From: Eduard Bloch <edi@gmx.de> + +Situation: + Linux: Kernel 2.2.15 (Debian package kernel-image-2.2.15) + Distribution: Debian Potato (deep freeze), i386 + Devices: one CDRW-Writer, one CDROM-drive, both ATAPI + +1. Become root, try "grep hd.: /var/log/kern.log" to find out where your + ATAPI-devices are connected to (hd?-names). +2. Edit your boot configuration file, eg. /etc/lilo.conf if you use + lilo or the batch-file if you boot via loadlin. +3. Find a line where you can append additional kernel parameters, eg. + "append=" in lilo.conf or the loadlin-line in the batch file. +4. Append sth. like this: "hdb=ide-scsi hdc=ide-scsi max_scsi_luns=1" + The hdX-parameters defines devices that should be mapped to SCSI + latter. You may do it with non-writers too, since the emulation layer + is almost complete, or let them out so the devices will use their + native drivers. +5. Save the file, reinstall the bootloader (ie. running "/sbin/lilo") +6. Call "modconf", load "sg" and "ide-scsi" from the SCSI-section +7. Reboot Debian, watch while booting, you should see a line like this + "Detected scsi CD-ROM sr0 at scsi0, channel 0, id 0, lun 0". + Your old ATAPI devices virtually don't exist any longer, use the + SCSI equivalents instead. +8. Become root, setup devices: + cd /dev + MAKEDEV sg scd + ln -s scd0 cdrom # NOTE: or cdrw, first check which drive is here + ln -s scd1 cdrw # NOTE: see above, maybe cdrom + Check the new SCSI settings: + wodim -scanbus + Setup wodim's environment - edit /etc/wodim.conf: + CDR_DEVICE=cdrw + cdrw=1,0,0 4 8m + cdrom=1,2,0 0 0m + Input the right values, the fields are described in the manpage + of wodim. Alternatively, you may use this values as + wodim-parameter or take a frontend with an own configuration + scheme, then you don't need to modify /etc/wodim.conf. +9. It's done! Insert a CD and try "wodim -v -toc" +/*--------------------------------------------------------------------------*/ +He had constant buffer underrun problems: + +From: "Trenton D. Adams" <trenton.adams@telusplanet.net> + +I enabled DMA, and 32-bit mode on the CD-Writer using "hdparm". +This fixed the writing problem. + +/*--------------------------------------------------------------------------*/ +From: "Mario Moder" <clay-man@freenet.de> +----- +TEAC CD-W54E + +I recently installed a TEAC CD-W54E (an ATAPI CD-RW-Recorder) and I had +problems with buffer underruns and other errors when burning a CD (with +Linux and Windows 2000). My system has an old ASUS P/I-P55T2P4 Pentium +mainboard with Intel PCI-Bus-Master-IDE (I think the chipset is an Intel +430HX and the IDE controller is an 82371SB). The harddisk is the master on +the primary IDE channel, and the CD-Recorder is the master on the secondary +IDE channel. + +After turning off DMA for the CD-Recorder AND the harddisk, the drive had no +longer problems with burning a CD. You can try the following things to make +it work, if you have similar problems with a similar hardware configuration: + +For Linux (Kernel 2.2.19): +Turn off "Enable DMA by default" in the kernel (and then compile a new +kernel), if you had it turned on or use "hdparm" to turn of DMA for both the +CD-Recorder and the harddisk + +For Windows 2000: +In the Device Manager go to "IDE ATA/ATAPI-Controller" and open the +properties for the first and second IDE channel. There you change the mode +of the devices from DMA to PIO. +----- + +/*--------------------------------------------------------------------------*/ + +Hints for the Linux Packet code in ide-cdrom.c: + + WARNING! It seems that this driver does not allow to send all + SCSI commands. A command that definitely fails is READ FULL TOC. + For this reason, you cannot read those 'defective' audio CDs + with broken TOC when you use this interface. + + Thanks to Alexander Kern <alex.kern@gmx.de> for the idea and first + code fragments for supporting the CDROM_SEND_PACKET ioctl() from + the cdrom.c kernel driver. Please note that this interface in principle + is completely unneeded but the Linux kernel is just a cluster of + code and does not support planned orthogonal interface systems. + For this reason we need CDROM_SEND_PACKET in order to work around a + bug in the linux kernel that prevents to use PCATA drives because + the kernel panics if you try to put ide-scsi on top of the PCATA + driver. + + The code is currently in "status nascendi" but usable with some trade offs. + + To use: call e.g. + + wodim -scanbus dev=ATAPI: + + wodim -dao -v speed=24 dev=ATAPI:0,0 .... + + Be careful! This code is only needed in order to be able to use + PCATA CD-writers on notebooks because there is a severe kernel bug. + Unfortunately, this bug causes the kernel to hang (and force you + to reboot) if you try to call: + + wodim -scanbus + + without the dev=ATAPI: option. + + In this case wodim will hang infintely and unkillable + in open("/dev/sg1", 2) => you need to reboot :-( + + Repeat by: Insert a PCATA CD-Writer in a Sony VAIO notebook and run + wodim -scanbus. + diff --git a/doc/READMEs/README.ATAPI.setup b/doc/READMEs/README.ATAPI.setup new file mode 100644 index 0000000..e283342 --- /dev/null +++ b/doc/READMEs/README.ATAPI.setup @@ -0,0 +1,87 @@ +Howto setup an ATAPI CD-RW/DVD+-RW recorder on Debian/Ubuntu +============================================================ + +This guide should be applicable to most kernel 2.6 using distributions of +GNU/Linux. For installations with kernel 2.4, continue reading below. + +Kernel 2.6.* +============ + +If you have just one CD writer in your computer, CD-writing should work out of +the box. There should be a symbolic link /dev/cdrw which points to your actual +CD-Writer's device (e. g. /dev/hdb). If the link is not present (eg. the +system is not using udev/devfs) or if you want to use a different device as +default, you can configure the device in /etc/wodim.conf: + + CDR_DEVICE=/dev/hdd + +would configure the default device to be /dev/hdd, i. e. the slave +device on the secondary IDE bus. + +You can always override this default setting with wodim's "dev" +option: + + wodim dev=/dev/hdc ... + +Only users part of the system group "cdrom" are able to write CDs. +If you wish to allow non-root users to write CDs then add your users to the +cdrom group ("adduser user cdrom") and let the user completely logout and +re-login. +Note: with certain kernel versions wodim can fail with this message: +"wodim: Operation not permitted. Cannot send SCSI cmd via ioctl" +In this case it still does need the suid bit - please send patches if you have +identified the reason of that problem. + +Kernel 2.4.* (for 2.5/2.6, see above) +===================================== + +Where we start: + Linux: Kernel 2.4.20-bf2.4 (Debian package kernel-image-2.4.20-bf2.4) + Distribution: Debian Woody 3.0r2, i386 + Devices: one CDRW-Writer, one CDROM-drive, both ATAPI + +1. Become root, try "grep hd.: /var/log/kern.log" to find out where your + ATAPI-devices are connected to (hd?-names). +2. Edit your boot configuration file, eg. /etc/lilo.conf if you use + lilo or the batch-file if you boot via loadlin. +3. Find a line where you can append additional kernel parameters, eg. + "append=" in lilo.conf or the loadlin-line in the batch file. +4. Append sth. like this: "hdb=ide-scsi hdc=ide-scsi max_scsi_luns=1" + The hdX-parameters defines devices that should be mapped to SCSI + latter. You may do it with non-writers too, since the emulation layer + is almost complete. Or omit some so the devices will use their + native drivers (eg. ide-cd). +5. Save the file, reinstall the bootloader (ie. running "/sbin/lilo") +6. Call "modconf" in a console or xterm, enter the section + "kernel/drivers/scsi", load "sg" and "ide-scsi" +7. Reboot Debian, watch while booting, you should see a line like this: + "Detected scsi CD-ROM sr0 at scsi0, channel 0, id 0, lun 0". + Your old ATAPI devices virtually don't exist any longer, you cannot refer to + /dev/hd* as CDROM drives. Use the SCSI equivalents instead, /dev/sr*. +8. Become root, setup devices: + cd /dev + MAKEDEV sg scd + ln -s scd0 cdrom # NOTE: or cdrw, first check which drive is here + ln -s scd1 cdrw # NOTE: see above, maybe cdrom + Check the new SCSI settings: + wodim -scanbus + Setup wodim's environment - edit /etc/wodim.conf: + CDR_DEVICE=cdrw + cdrw=1,0,0 4 8m + cdrom=1,2,0 0 0m + Insert the right values, the fields are described in the manpage + of wodim. Alternatively, you may use these values as + wodim-parameter or take a frontend with an own configuration + scheme, then you don't need to modify /etc/wodim.conf. + The columns must be separated by tabs. +9. It's done! Insert a CD and try "wodim -v -toc". To create your first CD-ROM, try: + + mkisofs -v -r -J /directory/to/be/written | wodim -v -dummy - + + (read wodim(1), "man 1 wodim", for details) + +10. If you wish to allow non-root users to write CDs, you must give them + permissions to do so. Set suid-root permissions on the executable, + then add your users to the cdrom group ("adduser user cdrom") and + let the user completely logout and re-login. + diff --git a/doc/READMEs/README.audio b/doc/READMEs/README.audio new file mode 100644 index 0000000..7e2d7c9 --- /dev/null +++ b/doc/READMEs/README.audio @@ -0,0 +1,50 @@ +Why do I hear only noise from my first audio CD? + +You may have a byte swapping problem, try wodim -swab +but note that is is most unlikely that you need to use the -swab +option from wodim unless your input files are broken. +It makes more sense to find out why the inout files are not OK. + +wodim assumes Motorola/Network byte order (big-endian) on input +regardless of the byte order of the CD-Recorder. If wodim +encounters a .wav file, byte order is corrected to match the byte order +of the .wav file. + +wodim by default uses Track at once. This always gives 2 seconds +pause between two audio tracks and loweres the audio quality. + +For best audio CD quality, use wodim -dao (to write in Session At Once) +ot wodim -raw (to write in RAW mode). Note that there are a lot of drives +notably from Lite-ON that have defective firmware and will write defective +CDs if you use either TAO or SAO mode. In RAW mode, wodim has the +full control over the complete CD and the chance that the CD is OK +is much higher. + +The 2 seconds pause between two audio tracks is the CD ***standard*** + +The standard says: + Each track starts with 2 seconds of silence + followed by at least 4 seconds of audio data. + +For that reason the 2 second pause is generated by the CD-R drive in +Track at once (TAO) mode. + +CD's that have no pause between two tracks are illegal (compared to RED BOOK). +These illegal disks may be made with Disk At Once (DAO) only. +In DAO mode the writing software needs to send the 2 seconds pause as +binary zeroes and therefore is able to create illegal disks by +sending audio data instead. + +Some drives don't accept to write illegal disks even in SAO mode. +In this case, use the RAW mode. In RAW mode, the drive does not even +"know" what is going on and thus cannot prevent you from writing such +a disk. + +This audio data (the last two seconds of a track in this case) +however are part of the next track from viewing the TOC of the disk. +Digital Audio Extraction programs that work correctly (as intended by the +CD standard) split the content of a CD into files by including the +pre-gap (usually holding 2 seconds of pause) at the end of the previous +track. + +Eduard Bloch, based on documentation from Joerg Schilling diff --git a/doc/READMEs/README.cdplus b/doc/READMEs/README.cdplus new file mode 100644 index 0000000..24deb0d --- /dev/null +++ b/doc/READMEs/README.cdplus @@ -0,0 +1,85 @@ +Wodim and genisoimage allow you to create multi-session CD's with all +supported drives. + +According to www.cd-info.com, a CD+ is a CD with two sessions. +The first session is an audio session, the second session a data +session. + +Creating a CD+ is first writing an audio session in +multi session mode and then writing a data session. + +If you like to append a filesystem to a audio CD, first extract the +CD by calling: + + icedax -B -vall + +This first audio session may be written in TAO mode with the command + + wodim -multi -audio file1 .... + +or in DAO mode with the command + + wodim -dao -multi -useinfo -audio file1 .... + +To add the second session that contains the data track, you need +to create an ISO-9660 file system that starts not at sector 0. + +With the current genisoimage, you must use the following method: + +- First call wodim -msinfo for your prepared multi-session audio CD. + + you will get something like 0,12345 + +- Now call genisoimage: + + genisoimage -o fs.raw -C 0,12345 root_directory_for_new_cd + + replace 0,12345 with your actual wodim -msinfo output. + +the image in fs.raw may now be written with wodim as second session. + +See my README.multi for more info on how to create multi session CD's + + +The procedure again in short form: + + icedax -vall -B + + wodim -multi -audio audio_tracks .... +or + wodim -dao -useinfo -multi -audio audio_tracks .... + + wodim -msinfo .... + (output is e.g. 0,12345) + + genisoimage -R -o cd_plus.raw -C 0,12345 root_dir_of_fs + + wodim -data cd_plus.raw +or + wodim -multi cd_plus.raw + + +Note: If you want to create an HFS hybrid as the data track, then you must +use the '-part' option to genisoimage. Otherwise, the data track will be mounted +as an ISO9660/Joliet CD when used on a Mac. + +Jörg + +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch + +This describes the programs as shipped with cdrkit, a spinoff from the +cdrtools project. However, the cdrtools developers are no longer +involved in the development of this spinoff and therefore shall not +be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original authors. + +If you have support questions, send them to + +debburn-devel@lists.alioth.debian.org + +If you have definitely found a bug, send a mail to this list or to + +submit@bugs.debian.org + +writing at least a short description into the Subject and "Package: cdrkit" +into the first line of the mail body. diff --git a/doc/READMEs/README.cdtext b/doc/READMEs/README.cdtext new file mode 100644 index 0000000..33df110 --- /dev/null +++ b/doc/READMEs/README.cdtext @@ -0,0 +1,65 @@ +CD-Text Usage (to copy CD-Text from master CD): + + icedax -D 6,0 -vall -B # To extract audio information + wodim dev=6,0 -vv -toc # To extract CD-Text information + + and then + + wodim dev=6,0 -v -dao textfile=cdtext.dat -useinfo *.wav + or + wodim dev=6,0 -v -raw96r textfile=cdtext.dat -useinfo *.wav + + If the CD-Text information contains more CRC errors than + wodim can correct, you need to reload the CD and to + re-read the CD-Text information from the master disk. + + Writing of CD-Text is supported for all drives that support + CD-Text in SAO write mode and for all drives that support + to write in RAW/RAW96R mode (use -raw96r in this case). + + NOTE: not all writers that support MMC SAO mode support + to write CD-Text in this write mode. + If you have a drive that does not support CD-Text + but supports RAW/RAW96R mode use this mode as + in RAW/RAW96R mode the drive does not need to know + about CD-Text. This way even old drives like the + Plextor PX-R 412C will write CD-Text. + + NOTE that icedax will read CD-Text and fill in the + CD-Text fields in the *.inf files if vou use -vall. + + The new icedax option cddb= allows you to tell icedax to + retrieve CDDB information from freedb.freedb.org. + cddb=0 means ask if ambiguous, cddb=1 means take first entry. + The information in this case is filled into the fields + in the *.inf files. + +Creating a CD with CD-Text based on CDDB information from freedb.freedb.org: + + Tell icedax to fetch data from freedb.freedb.org, call + + icedax -D 6,0 -vall -B cddb=1 # To extract audio information/fetch CDDB data + + and then call + + wodim dev=6,0 -v -dao -text -useinfo *.wav + or + wodim dev=6,0 -v -raw96r -text -useinfo *.wav + + +If you like to create your own CD-text data for a CD use the +following method: + + First extract all tracks with icedax -vall (see above), + + then edit the *.inf Files and add album and song titles. + + Now call wodim as if the *.nf files contain CD-Text + information. + + Note that it is recommended to use less that 160 characters + for a single string. + +Source: README.cdtext from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch + diff --git a/doc/READMEs/README.copy b/doc/READMEs/README.copy new file mode 100644 index 0000000..dc78169 --- /dev/null +++ b/doc/READMEs/README.copy @@ -0,0 +1,53 @@ +Ho to copy CD's and CD-R/CD-RW's + +Copying audio CD's: + +If you want to copy audio CD's, look for 'icedax'. + +Copying data CD's: + +The best way to copy a data disk is to copy the raw data on the master CD. +This may be done by reading the data from the raw device by using 'readom'. + + +NOTE: All CD-R's written in Track At Once mode end in two unreadable + run-out sectors. If the disk has been written with a Yamaha CD-R100 + or with a Yamaha CD-R102, there are even more run-out sectors. + +For this reason, you will not be able to read such a CD correctly with 'dd'. + +I recommend to write all disks in Disk at Once mode if your drive +is supported in DAO mode with wodim. In addition, you may wish to +add padding (see wodim / genisoimage man pages). + +If you want to copy such a CD directly with wodim, you may call: + + wodim -v dev=... -isosize /dev/cdrw + +But this may fail if the master gives read errors. To copy such a CD to a file +you may use the program 'readom' from this package + +Call 'readom [target] [lun] [scsibusno]' and select function 11. +Or call readom -help to get alternate usage. +To prevent readom from reading the run-out sectors, reduce the +number of sectors to copy by 2. + +Recent readom versions may be called: readom dev=b,t,l f=outfile +To reduce the numbers of sectors to copy you may use the sectors= option. + +If the master disk is made of several partitions (like a Solaris boot CD), +the best way to copy a CD is to use the program 'readom'. It ignores +the partition info and does raw SCSI reads. + +If you like to copy audio CD's in a way that preserves as much accuracy as +possible, use: + +icedax -vall -D... -B +wodim -v dev=... -dao -useinfo *.wav + +This will preserve pre-gap sizes, indices ... + + +Source: README.copy from cdrtools package, version 2.01.01a08 +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch <blade@debian.org> + diff --git a/doc/READMEs/README.multi b/doc/READMEs/README.multi new file mode 100644 index 0000000..d7d3457 --- /dev/null +++ b/doc/READMEs/README.multi @@ -0,0 +1,209 @@ +Creating multi-session CDs/DVDs Mini Howto FAQ + +Multi-session filesystems are a trick that comes from the Kodak photo CD. +The OS mounts the last session that contains the sum of the current session +and all previous sessions. + +To test (with Linux): + + - create a iso-9660 filesystem image with genisoimage. + - genisoimage is included in the cdrkit release. + - use the -R flag to add Rock Ridge extensions (this is important). + +Assuming that the CD-R drive is connected to target 2 on the SCSI bus. + +Write the first session with: + +wodim -v speed=2 dev=2,0 -eject -multi isoimage.raw + +Note that all Sony drives do no support XA2 disks in firmware - read README.sony +for more information. + +This must be a iso9660 image with Rock Ridge extensions (see above) + +Note the number of sectors written and check the disk, it should be mountable. + +Next step is to check if wodim is able to retrieve the following data: + + 1) The first block (sector) number in the first track of the last session + This must be '0' in our case. + + 2) The next writable address in the unwritten session following the current. + This should be the number of sectors written in the first + run + ~ 11400 sectors for about 22MB lead out/in + + For the first additional session this is 11250 sectors lead-out/lead-in + overhead + 150 sectors for the pre-gap of the first track after the + lead-in = 11400 sectors. + + For all further session this is 6750 sectors lead-out/lead-in + overhead + 150 sectors for the pre-gap of the first track after the + lead-in = 6900 sectors. + +To get this information type: + +wodim -msinfo dev=2,0 + +The output should be two numbers separated by a comma. + + e.g.: 0,204562 + +The first number is (1), the second number is (2). + +2nd session: +You should create a directory that contains a second directory with data in it +for this purpose. + + e.g.: + first_dir/ + second_dir/ + file_1 + file_2 + ... + +call: + +On Linux: +genisoimage -o isoimage_2.raw -R -C xx,yy -M /dev/cdwriter_blk_dev first_dir + +On SunOS: +genisoimage -o isoimage_2.raw -R -C xx,yy -M target,lun first_dir + +Note that the name "first_dir" is not important. + +If you still keep the old raw image of the first session and there is only +one previous session on the CD you may also call: + +genisoimage -o isoimage_2.raw -R -C xx,yy -M isoimage.raw first_dir + + +The argument of -C is the output of wodim -msinfo +- On Linux, the argument of -M is a device that would allow you to mount + the current CD in the CD-writer +- On SunOS, target and lun refer to the SCSI target and lun of the + CD-R device with the same notation as for wodim dev=xxx,yyy . + +Note that you can also use the -msifile=... option of wodim to store this data +in a reliable way. This is usefull for scripting. + +If you want to check, whether genisoimage make everything right, you should create +another image by using the following command line. + +On Linux: +genisoimage -o isoimage_2.raw -R -C xx,0 -M /dev/cdwriter_blk_dev first_dir + +On SunOS: +genisoimage -o isoimage_2.raw -R -C xx,0 -M target,lun first_dir + +Where xx is the first number of the pair returned by wodim -msinfo + +You may check ***this** image by mounting it with my "fbk" on Solaris +or the loopback driver on Linux. + +On Linux type: + mount isoimage_2.raw -r -t iso9660 -o loop /mnt + +On SunOS type: + mount -r -F fbk -o type=hsfs /dev/fbk0:isoimage_3.raw /mnt + +For Solaris 8 and later you may also use the Sun lofi driver (see README.sun-lofi) + +If you list /mnt, you should see all directories that have been in the first +session and the directory "second_dir". If you try to read a file from the +first session, you will get an I/O error or bad data (depending on the +block address), don't worry about that. If you try to read a file from +the second session, you will see everything correctly. + +To write the second session to CD, call: + +wodim -v speed=2 dev=2,0 -eject -multi isoimage_2.raw + +If you mount this CD, you should see the first session and the second directory +from 2nd session added to the root directory of the CD. + + +Additional check: + +call: + +wodim -msinfo dev=2,0 + +The first number should be the first writable address which was retrieved by the +first call to wodim -msinfo after creating the first session. +The second number should be the first number + number of sectors of the second session ++ ~ 11400 sectors. + +Note: The first lead-out is 1:30 (6750 sectors) the lead-in is 1:00 (4500 sectors) +All following sessions need only 0:30 for lead-out (2250 sectors), the lead-in +is also 1:00. So in theory, the can be 44 sessions on s 74 minute disk if you +take into account that the minimum track size is 4 seconds. + +The total amount of the overhead is 11250 + 150 sectors for the first additional +session and 6750 + 150 sectors for all subsequent sessions. +The 150 additional sectors are the pre-gap sectors for the first track after +the current session. + +Some notes on multi-session CD's that contain only Joliet but no Rock Ridge: + +Joliet is a really bad idea in general: + +- There is no way to find a relation between a ISO-9660 name and a Joliet + name. If the file has a size, you may try to match the starting sector # + but if the size in 0 it's impossible. + + +- Joliet does not allow long filenames (it limits names to 64 chars). + +- Joliet does not allow all (usually used) characters in filenames. + + All code points between (00)(00) and (00)(1F), inclusive. (Control Characters) + (00)(2A) '*'(Asterisk) + (00)(2F) '/' (Forward Slash) + (00)(3A) ':' (Colon) + (00)(3B) ';' (Semicolon) + (00)(3F) '?' (Question Mark) + (00)(5C) '\' (Backslash) + + While '/' is not a real problem ;-) other characters may cause trouble. + +All notes above prevent you from doing reliable multi-session if the CD does +only contain Joliet but des not contain Rock Ridge attributes. + +In addition, please read README.joliet in the genisoimage directory. + +This is the answer to a commonly asked question is why can't I continue a +multisession CD that has been started on a Microsoft system using genisoimage. + + +Note: It is not possible to create a multi-session HFS CD. If you create +a multi-session CD using any of the HFS options, then each new HFS +session will ignore HFS files from any previous sessions. A warning will +be printed if you attempt this. However, if you use the '-part' option to +genisoimage for each session you create, then each session will appear as +separate volumes when mounted on a Mac. In this case, it is worth using the +'-V' or '-hfs-volid' option to give each session a unique volume name, +otherwise each "volume" will appear on the Desktop with the same name. + + +Joerg Schilling + +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch + + +This describes the programs as shipped with cdrkit, a spinoff from the +cdrtools project. However, the cdrtools developers are no longer +involved in the development of this spinoff and therefore shall not +be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original authors. + +If you have support questions, send them to + +debburn-devel@lists.alioth.debian.org + +If you have definitely found a bug, send a mail to this list or to + +submit@bugs.debian.org + +writing at least a short description into the Subject and "Package: cdrkit" + + diff --git a/doc/READMEs/README.netscsid b/doc/READMEs/README.netscsid new file mode 100644 index 0000000..07c3672 --- /dev/null +++ b/doc/READMEs/README.netscsid @@ -0,0 +1,145 @@ +The Remote-SCSI protocol gives you SCSI-Anywhere features. + +The protocol used by netscsid is based on rscsi from the cdrtools, developed by +Joerg Schilling. However, no guarantee for the compatibility or reliability can +be made. This documentation is based on rscsi documentation from Joerg +Schilling, but is not identical to the original. + +There are three possible ways to control access to the remote users: + + - Let the remote scsi lib log in as a standard user. + In this case netscsid will be called via sh -c netscsid /usr/sbin/netscsid + NOTE: In this case, netscsid must be installed suid root. + --- This would need to allow any valid local user to access SCSI ---- + It could be a security problem. + + - Log in as root and call netscsid via sh -c netscsid + NOTE that this will fore you to allow remote logins as root + which is considered to be a security hole. + + - Create one or more special user(s) that have netscsid + as login shell with their own home directory. + You then may create special .rhosts files for each user. + NOTE: In this case, netscsid must be installed suid root. + **** This is the preferred method **** + +To enable remote SCSI via the login shell method you should do the following: + + - Install netscsid into /usr/sbin. It can be set suid-root if neccessary, see + security section below. + + - Install a file /etc/netscsid.conf and define access rights. + Without this file, netscsid will not work at all. + The template for this file is: netscsid/netscsid.dfl + + - For the special user method, create a user account. This can be done with a + frontend like adduser or useradd, if available. The user should have /usr/sbin/netscsid as the login shell. + If there is no frontend tool, try this: + + + Add an entry to /etc/passwd in the form: + + netscsid:x:1999:1000:Tape:/home/netscsid:/usr/sbin/netscsid + + (modify this according to your OS). And don't forget to + modify /etc/shadow the way it needs to be on your OS. + + + Create the home directory for this user, adapt the user/group ownership + on this directory. + + - if you use SSH as the login shell (via appropriate RSH environment variable + or a symlink to "rsh" which is the case for many Linux distribution), + consult the ssh documentation for details. + Note that SSH requires sufficiently powered client/server systems to + encrypt/decrypt data in realtime. + + - if you use traditional rsh, add a .rhosts file to this directory to allow + access to all users you like (see rsh documentation) + +NETSCSID Security: + +- When netscsid starts, it checks if /etc/netscsid.conf exists. + If not, it dies. + +- If netscsid is not called by a user listed in /etc/netscsid.conf + it dies. + +- To access a SCSI target there must be an entry that lists the user + rcsi hast been started from, the hostname and the SCSI target. + + netscsid compares the hostname field in /etc/netscsid.conf + to the peername retrived from STDIN: + + - legal host name IP connection + - "ILLEGAL_SOCKET" Not an IP socket + - "NOT_IP" Not a socket + +NETSCSID Security hints: + +- Do not generally allow other users to see your boot disk via NETSCSID. + All people who see this disk may edit your passwd file. This especially + applies to suid-root usage. For non-suid-root, check the access permissions. + +- If you are in doubt, only export CD-ROM drives, scanners and similar + devices that are not directly security sensitive. + +If anybody sees a security hole in my security precautions, please send me a mail! + +NETSCSID usage: + +- To use remote SCSI devices you need to know how to access a specific remote + SCSI target. + + - dev=REMOTE:host: or dev=REMOTE:host + will allow you to do SCSI bus scanning while you log in as yourself + + - dev=REMOTE:user@host: or dev=REMOTE:user@host + will allow you to do SCSI bus scanning while you log in as "user" + + If you use the setup described above, you should use: + + dev=REMOTE:netscsid@babbel: + + to do SCSI Bus scanning on host babbel + + - To access a specific SCSI device, you must specify + dev=REMOTE:host:<target spec> or dev=REMOTE:user@host:<target spec> + <target spec> is the SCSI target specification as it is needed + on the remote host + + dev=REMOTE:netscsid@babbel:1,3,0 + + Will let you log in as netscsid on host babbel and open Target 3 lun 0 + on SCSI bus #1 + + - If you use wodim -vv ...., wodim will on startup print some + information about the remote libscg version used for the connection. + +- To be able to use the remote SCSI client code from win32 you need to create + a file /etc/passwd with a correct entry for the user you are on win32. + Call 'id' to get the right user id. + Note that remote SCSI has not yet been tested on Win32. + +NETSCSID speed: + +- On a Ultra-10 running Solaris 8, the command overhead time is 400 usec. + You may achieve up to 9900 kB/s via a 100MB/s ethernet connection + between two of such machines. + +- With 100 MB/s, 12x recording should be no problem. + +- With 10 MB/s, 4x recording is the maximum. Do tests before! + +- Logging into a remote machine and running wodim on the remote machine + causes the buffer cache on that machine to be trashed. The main user + is disturbed. + +- Doing cdrecording via Remote SCSI causes only the netscsid command with less + than 200kB to be needed on the remote machine hosting the CD recorder. + The main user on that machine is not disturbed. + The buffer cache of the machine running wodim is trashed. + +- It is desirable to use a Burn-Proof recorder to make sure that network + load will not cause buffer underruns. + + +- USER= test and test for hostname are using a pattern matcher. diff --git a/doc/READMEs/README.sony b/doc/READMEs/README.sony new file mode 100644 index 0000000..3ee6da6 --- /dev/null +++ b/doc/READMEs/README.sony @@ -0,0 +1,31 @@ +The Sony CDU-924 was the first drive that has no hardware support +for CDROM XA2 mode 1. If you want to create a multi session disk, +you need to switch back to -data (plain CD-ROM) + +If you have a Sony drive that gives you problems with multi session disks, +please always check the following: + + For some Sony drives you may need to call wodim -multi -data + if you like to create multi-session CD's. + + Some Sony drives do not allow to write XA2 tracks with + hardware support of the drive. + +There is currently a bug in the Sony code (for _old_ non MMC drives) +of wodim that does not allow you to have different track types +in one session. + +All Sony drives that have CDUxxx type names are _old_ non MMC drives. + Here I expect that no XA support is in the firmware. + +All Sony drives that have CRXxxx type names are MMC compliant. + These drives should support XA-mode2-form1 as it is mandatory with MMC. + +NOTE: many HP CD-writers are nased on Sony OEM drives. + + +NOTE: As for 18.5.2001, a fix was introduced that prevented wodim + to do multi session with new MMC compliant Sony drives. + +--- +Eduard Bloch, based on documentation from Joerg Schilling, cdrtools package 2.01.01a08 diff --git a/doc/READMEs/README.suidroot b/doc/READMEs/README.suidroot new file mode 100644 index 0000000..b1198d6 --- /dev/null +++ b/doc/READMEs/README.suidroot @@ -0,0 +1,29 @@ + +This is an example of how to install wodim and other cdrkit applications to get +the root permissions in a safer way. + +Usually it is not a good idea to run the applications as root or to +give users the means to run wodim as root. This gives them an easy way +to fetch sensitive data by writing it to the disk, or pass arbitrary +SCSI commands, e.g. formatting a SCSI disk. + +This also applies to root-mode wrappers like sudo, they should be used with +the most possible care. + +The alternative way is installing wodim as suid-root application. In this +mode, wodim checks permission of the device access by comparing the ownership +of the device node user/group attributes for the real UID/GID of the calling +user. + +To give all user access to use wodim, enter: + + chown root /usr/local/bin/wodim + chmod 4711 /usr/local/bin/wodim + +To give a restricted group of users access to wodim, add a group +"cdburners" to your system and add the trusted users to this group. +Then enter: + + chown root:cdburners /usr/local/bin/wodim + chmod 4710 /usr/local/bin/wodim + diff --git a/doc/READMEs/README.verify b/doc/READMEs/README.verify new file mode 100644 index 0000000..28227b7 --- /dev/null +++ b/doc/READMEs/README.verify @@ -0,0 +1,75 @@ +Mini-Howto for verifying a selfmade CD + +1) verifying the data layer + + To verify if all data on the disk can be read, + use SCSI verify. This can be done with the + sformat utility. + + use: sformat -verify [target] [lun] [scsibus] + + If the CD-R device is connected to target 2 on SCSI bus 0 + sformat -verify 2 0 + + sformat can be found on ftp://ftp.berlios.de/pub/sformat + + NOTE: Not all CD-ROm drives support verifying + NOTE: All TAO tracks end in 2 unreadable run-out sectors + +2) verifying the filesystem layer + + A quick check is to mount the CD and to use star to read + all files on the filesystem. + + mount -r /dev/cdrom /cdrom (modify for your OS) + cd /cdrom + star -cPM . >/dev/null + + If no errors can be found, all files are readable. + + star can be found on ftp://ftp.berlios.de/pub/star + + + You also may want to compare the filesystem on the CD + with the original data. This can be done with star too. + + + (cd /master_for_cd; star -cPM .)|(cd /cdrom; star -diff -v) + +2a) verifying the iso image before creating the CD + + You may check the filesystem image by mounting it with my + "fbk" on Solaris or the loopback driver on Linux. + + On Linux type: + mount isoimage.raw -r -t iso9660 -o loop /mnt + + On SunOS type: + mount -r -F fbk -o type=hsfs /dev/fbk0:isoimage.raw /mnt + +For Solaris 8 and later you may also use the Sun lofi driver (see README.sun-lofi) + + The check the filesystem with: + + (cd /master_for_cd; star -cPM .)|(cd /mnt; star -diff -v) + + +Solaris has a bug with hardlinks. It generates different inode numbers +for the hardlinks to a file. This makes it impossible for star to +check hard links. Use + +(cd /master_for_cd; star -cPM .)|(cd /cdrom; star -diff -v diffopts=!hardlink) + +in this case. + +NOTE: Some operating systems have a read ahead bug that causes I/O errors for +the last file(s) on a CD. This seems at least to be true for all Linux versions +and for Solaris 7 FCS. For Solaris 7 there is a patch (107465-02) that you should +install. This I/O error problem does not occur with DAO disks and with TAO disks +that have been written with wodim -pad. + +Joerg Schilling + +Source: README.verify from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch + @@ -0,0 +1,26 @@ +Why cdrkit? Why wodim? Why genisoimage? Because: + + - it won't tell you that you have no /dev/pg* device file thing foo, that you + have never seen and you will never need + + - it won't require to be executed as root, fail with obscure messages without + such permissions + + - it won't force you to wait 3 seconds every time you want to start, no matter + what you specify as gracetime= + + - it won't kill another burning process when you do -scanbus in another shell + + - it will let you specify your device directly in the way you know it, rather + than forcing some weird TARGET,BUS,LUN syntax with weird numbers + + - it will not wreak random havoc if you used spaces and not tabs in the config file + + - genisoimage won't stop accepting the well known option -L in the near future + + - genisoimage will stop on 2.1GiB large files rather than just "forgetting" + them and let you burn crap + + - users are respected and not used as pinballs between us and the OS kernel + developers + diff --git a/doc/genisoimage/README b/doc/genisoimage/README new file mode 100644 index 0000000..708bae5 --- /dev/null +++ b/doc/genisoimage/README @@ -0,0 +1,26 @@ +Cdrkit carries a fork of the mkisofs program called genisoimage. + +The acompanying documentation consists of the manual page genisoimage.8 and +README files found in the following locations (shell globing used): + +doc/: + +README.multi: documentation and examples for creating + multi-session CDs and DVDs + +README.cdplus: documentation and examples for creating + CD-plus (aka CD-extra) disks + +doc/genisoimage: + +README.releasenotes: release notes for old mkisofs releases + +README.*boot: documentation for various boot loader related + extensions for different architectures + +README.hfs*: hints and usage for HFS related features + +README.*: additional docs for special features + +Eduard Bloch -- Mon, 11 Sep 2006 23:05:29 +0200 + diff --git a/doc/genisoimage/README.alphaboot b/doc/genisoimage/README.alphaboot new file mode 100644 index 0000000..4bd10e1 --- /dev/null +++ b/doc/genisoimage/README.alphaboot @@ -0,0 +1,28 @@ +# README.alphaboot Steve McIntyre <steve@einval.com> 2004/07/19 + +The alpha boot support allows you to create a bootable CD which will +work with DEC/Compaq/HP Alpha machines, for example bootable +installation media. + +The method used for this is the same as in aboot, the bootloader for +Linux on Alpha, and works with SRM firmware. See the SRM Firmware +HOWTO at http://www.alphalinux.org/faq/SRM-HOWTO/ for more details +about SRM. + +In common with many Unix systems, the SRM code reads the first +512-byte "sector" off a disk and parses information in that +sector. The information in question is the location (start "sector") +and length of the first stage boot loader. On a Linux system, this +file will normally be called bootlx. + +SRM will load and execute the first stage boot loader, and from that +point the system should be able to find the normal OS kernel and start +up fully. + +To use the Alpha boot support code in genisoimage, simply specify the +location of the first stage boot loader (relative to the CD root) +using the -alpha-boot command line switch: + +genisoimage ... -alpha-boot boot/bootlx -o alpha.iso files + + diff --git a/doc/genisoimage/README.compression b/doc/genisoimage/README.compression new file mode 100644 index 0000000..4c8d425 --- /dev/null +++ b/doc/genisoimage/README.compression @@ -0,0 +1,17 @@ +Transparent decompression (-z option) is available on Linux kernels +using kernel version 2.4.14 or 2.4.9-ac14 or later. + +You also need the zisofs-tools package, containing the mkzftree +utility, to create the compressed files; this package is available at: + +ftp://ftp.kernel.org/pub/linux/utils/fs/zisofs/ + +The mkzftree utility can also be used to read compressed CD-ROMs on +systems which do not support transparent decompression. + +The use of a separate utility allows compression to be controlled on a +per-file basis. A file which is not compressed can be read on any +system. + +Transparent decompression is implemented as an extension to Rock +Ridge, so Rock Ridge needs to be enabled (-R or -r options.) diff --git a/doc/genisoimage/README.eltorito b/doc/genisoimage/README.eltorito new file mode 100644 index 0000000..5c94cdc --- /dev/null +++ b/doc/genisoimage/README.eltorito @@ -0,0 +1,101 @@ + +What is El Torito? +------------------ +Simply put, El Torito is a specification that says how a cdrom should +be formatted such that you can directly boot from it. + +The "El Torito" spec says that ANY cdrom drive should work (scsi/eide) +as long as the BIOS supports El Torito. So far this has only been +tested with EIDE drives because none of the scsi controllers that has +been tested so far appears to support El Torito. The motherboard +definately has to support El Torito. The ones that do let you choose +booting from HD, Floppy, Network or CDROM. + +How To Make Bootable CDs +------------------------ + +For the x86 platform, many BIOS's have begun to support bootable CDs. +The standard my patches for genisoimage is based on is called "El Torito". + +The "El Torito" standard works by making the CD drive appear, through BIOS +calls, to be a normal floppy drive. This way you simply put an floppy +size image (exactly 1440k for a 1.44 meg floppy) somewhere in the +iso fs. In the headers of the iso fs you place a pointer to this image. +The BIOS will then grab this image from the CD and for all purposes it +acts as if it were booting from the floppy drive. This allows a working +LILO boot disk, for example, to simply be used as is. + +It is simple then to make a bootable CD. First create a file, say "boot.img" +which is an exact image of the boot floppu currently in use. There is +at least one HOWTO on making bootable floppies. If you have a bootable +floppy handy, you can make a boot image with the command + +dd if=/dev/fd0 of=boot.img bs=10k count=144 + +assuming the floppy is in the A: drive. + +Place this image somewhere in the hierarchy which will be the source +for the iso9660 filesystem. It is a good idea to put all boot related +files in their own directory ("boot/" under the root of the iso9660 fs, +for example), but this is not necessary. + +One caveat - Your boot floppy MUST load any initial ramdisk via LILO, +not the kernel ramdisk driver! This is because once the linux kernel +starts up, the BIOS emulation of the CD as a floppy disk is circumvented +and will fail miserably. LILO will load the initial ramdisk using BIOS +disk calls, so the emulation works as designed. + +The "El Torito" specification requires a "boot catalog" to be created as +ll. +This is a 2048 byte file which is of no interest except it is required. +My patches to genisoimage will cause it to automatically create the +boot catalog. You must specify where the boot catalog will go in the +iso9660 filesystem. Usually it is a good idea to put it the same place +as the boot image, and a name like "boot.catalog" seems appropriate. + + +So we have our boot image in the file "boot.image", and we are going to +put it in the directory "boot/" under the root of the iso9660 filesystem. +We will have the boot catalog go in the same directory with the name +"boot.catalog". The command to create the iso9660 fs in the file +bootcd.iso is then + +genisoimage -b boot/boot.img -c boot/boot.catalog -o bootcd.iso . + +The -b option specifies the boot image to be used (note the path is +relative to the root of the iso9660 disc), and the -c option is +for the boot catalog file. + +Now burn the CD and its ready to boot! + +CAVEATS +------- + +I don't think this will work with multisession CDs. + +If your bootable floppy image needs to access the boot floppy, it has +to do so through BIOS calls. This is because if your O/S tries to talk to +the floppy directly it will bypass the "floppy emulation" the El Torito spec +creates through BIOS. For example, under Linux it is possible to +have an initial RAM disk loaded when the kernel starts up. If you let the +kernel try to read in the initial RAM disk from floppy, it will fail +miserably because Linux is not using BIOS calls to access the floppy drive. +Instead of seeing the floppy image on the CD, Linux will be looking at +the actually floppy drive. + +The solution is to have the initial boot loader, called LILO, load your +initial RAM disk for you. LILO uses BIOS calls entirely for these +operations, so it can grab it from the emulated floppy image. + +I don't think making a CD bootable renders it unreadable by non-El Torito +machines. The El Torito spec uses parts of the iso9660 filesystem which +were reserved for future use, so no existing code should care what it does. + +Genisoimage currently stores identification records in the iso9660 filesystem +saying that the system is a x86 system. The El Torito spec also allows +one to write PowerPC or Mac id's instead. If you look at the code in write.c +you could figure out how to change what is written. + +/* @(#)README.eltorito 1.2 00/03/18 eric */ +/* Edited for name change by Eduard Bloch, mkisofs -> genisoimage */ + diff --git a/doc/genisoimage/README.graft_dirs b/doc/genisoimage/README.graft_dirs new file mode 100644 index 0000000..da05e29 --- /dev/null +++ b/doc/genisoimage/README.graft_dirs @@ -0,0 +1,151 @@ +This is from "Eduardo M. A. M. Mendes" <mendes@mgconecta.com.br> + +Creating multi-session CD's with dir=/ feature Micro Howto + +This mini-howto was written as guide to help me to create multi-session CD's +with the possibility of determining the location of files. I hope +that this guide helps you too. + +In order to use wodim it is first necessary to define to which scsi bus +the cd-writer is connected. In my case the setup is dev=0,3,0. It is also +interesting to have a separate directory in which all image files can +be dumped: /home/cdsource is the directory I chose for dumping the images. + +The best way to understand how to create multi-session cds is to read +README.multi. Most of what is going to be said here is based on that +README file and on the help of several wodim users. + +This Micro Howto is divided into two parts as follows: + +Example a) A dir/=/dir1/dir2 example + +Example b) A dir1/dir2/=/dir3/dir4 and dir1/dir2a=/dir5/dir6 example + + +We are now ready to start. + +Example a) An dir/=/dir1/dir2 example + +A simple example will demonstrate that we can create multi-session cds +with the dir_feature of the type dir/=/dir1/dir2 + +Objetive: Saving root directories of Redhat 6.1 and Col 2.3 on a single CD. + +Observation: Redhat installation is mounted on COL 2.3 at /mnt/redhat + +First image - RedHat 6.1 - /mnt/redhat/root + +genisoimage -D -l -r -f -m core -L -o image1.raw redhat/=/mnt/redhat/root + +This will create a redhat directory on the cd. The option -D should be +used with care. The other options used in the above command are just +to demonstrate the use of genisoimage. Please +refer to man genisoimage if you want to know more. + + +To see if the image is created as expected, we need to mount image1.raw using +the option -o loop (Linux only! for information on Solaris read README.verify) +as follows: + +mount -t iso9660 image1.raw /mnt/image -o loop + +To see the contents type: + +ls -l /mnt/image/redhat + +Does it look ok? Great! Unmount /mnt/image. Now the burning process itself: + +wodim -v -dev=0,3,0 -multi -eject image1.raw + +To check the burned image we need to mount the cd; something like + +mount -t iso9660 /dev/scd0 /mnt/cdroms + +/mnt/cdroms is the device file for the cdrom I use. + + +Second image - Caldera 2.3 - /root + + +To create the second image on our cd, we need get information +about sectors related to the first track. To do that, issue the command + +wodim -v -dev=0,3,0 -msinfo + +wodim returns the following number + +0,135563 + +This number is the format XX,YY discussed on README.multi. XX would be used +for testing the images as well as burning the new track. + +genisoimage -D -l -r -f -m core -L -C 0,135563 -M /dev/scd0 -o image2.raw caldera/=/root + +Now we need to check of image2.raw is ok. The following command creates exactly what we +need. Plese note that -C option. Only the first number changes in this case. The second one +is always zero. In our case the first number is zero due to wodim -msinfo. When +more tracks are added to the cd this number will change. + +genisoimage -D -l -r -f -m core -L -C 0,0 -M /dev/scd0 -o image2_test.raw caldera/=/root + +mount -t iso9660 image2_test.raw /mnt/image -o loop + +ls -l /mnt/image shows that there are two directories: redhat and caldera, just the way +we wanted. + +Now let us burn image2.raw (not image2_test.raw) + +wodim -v -dev=0,3,0 -multi -eject image2.raw + +We can mount the CD again to see that the two directories are there. We can carry on +doing this until we decide to close the CD. If this is the case, don't use -multi when +burning the last session. + +b) A dir1/dir2/=/dir3/dir4 and dir1/dir2a=/dir5/dir6 example + +The above example seems a bit silly, one could argue. Why did I create a single directory +called root and within two sub-directories: redhat and caldera? + +Using the procedure described above we would do as follows: + +genisoimage -D -l -r -f -m core -L -o image1.raw etc/redhat/=/mnt/redhat/etc + +wodim -v -dev=0,3,0 -multi -eject image1.raw + +To check the burned image we need to mount the cd; something like + +mount -t iso9660 /dev/scd0 /mnt/cdroms + +wodim -v -dev0,3,0 -msinfo + +wodim returns the following number + +0,14391 + +The second image can be created using + +genisoimage -l -r -f -m core -L -C 0,14391 -M /dev/scd0 -o image2.raw etc/caldera/=/etc + +Creating a test image2 + +genisoimage -l -r -f -m core -L -C 0,0 -M /dev/scd0 -o image2_test.raw etc/caldera/=/etc + +mount -t iso9660 image2_test.raw /mnt/image1 -o loop + +It works!! That is great!!! + +Now the burning process itself. + +wodim -v -dev=0,3,0 -multi -eject image2.raw + +and we're done !!!! + +To add more tracks just do as indicated above. + +Good luxk!!! + +Eduardo Mendes - 11/23/99 + +Source: README.graft_dirs from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch + diff --git a/doc/genisoimage/README.hfs_boot b/doc/genisoimage/README.hfs_boot new file mode 100644 index 0000000..378bb95 --- /dev/null +++ b/doc/genisoimage/README.hfs_boot @@ -0,0 +1,76 @@ +Making HFS bootable CDs + +******* +The HFS boot code in genisoimage/mkhybrid is now very out of date ... +it does not support booting from IDE CDROMS, and probably won't work on +"newer" Macs. + +The HFS boot code will be updated at some point in the future +******* + +It *may* be possible to make the hybrid CD bootable on a Mac. As I do not +have easy access to a CD-R (nor a Mac) at the moment, I have not actually +created and written a bootable hybrid to CD - however, I *think* it will work! + +A bootable HFS CD requires an Apple CD-ROM (or compatible) driver, a bootable +HFS partition and the necessary System, Finder, etc. files. + +A driver can be obtained from any other Mac bootable CD-ROM using the +"apple_driver" utility (to make, type "make apple_driver"). This file can +then be used with the -boot-hfs-file option. See below for usage. + +The HFS partition (i.e. the hybrid disk in our case) must contain a +suitable System Folder, again from another CD-ROM or disk. + +For a partition to be bootable, it must have it's "boot block" set. The boot +block is in the first two blocks of a partition. For a non-bootable partition +the boot block is full of zeros. Normally, when a System file is copied to +partition on a Mac disk, the boot block is filled with a number of required +settings - unfortunately I don't know the full spec for the boot block ... + +I'm guessing that this will work OK ... + +Therefore, the utility "apple_driver" also extracts the boot block from the +first HFS partition it finds on the given CD-ROM and this is used for the +HFS partition created by mkhybrid. + +To extract the driver and boot block: + +apple_driver CDROM_device > HFS_driver_file + +where CDROM_device is the device name used by the CD-ROM (e.g. /dev/cdrom) + +The format of the HFS driver file is: + + HFS CD Label Block 512 bytes + Driver Partition Map (for 2048 byte blocks) 512 bytes + Driver Partition Map (for 512 byte blocks) 512 bytes + Empty 512 bytes + Driver Partition N x 2048 bytes + HFS Partition Boot Block 1024 bytes + +The Perl script "hdisk.pl" can be used to give a listing of what's on +a Mac CD. hdisk.pl is part of hfsutils. + +A hybrid CD is made using the option "-boot-hfs-file" e.g. + +mkhybrid -boot-hfs-file HFS_driver_file -o hfs.raw src_files/ + +The -boot-hfs-file implies the -hfs option. + +PLEASE NOTE: + +By using a driver from an Apple CD and copying Apple software to your CD, +you become liable to obey Apple Computer, Inc. Software License Agreements. + +The driver code (both extracting the driver and creating partitions etc. +is based on code from "mkisofs 1.05 PLUS" by Andy Polyakov +<appro@fy.chalmers.se> (see http://fy.chalmers.se/~appro/mkisofs_plus.html) + + +Any comments, bug reports/fixes to the address below + +James Pearson (j.pearson@ge.ucl.ac.uk) +19-Jul-2000 + +Edited for program name change by Eduard Bloch, 2006 diff --git a/doc/genisoimage/README.hfs_magic b/doc/genisoimage/README.hfs_magic new file mode 100644 index 0000000..814d59e --- /dev/null +++ b/doc/genisoimage/README.hfs_magic @@ -0,0 +1,69 @@ + +Find file types by using a modified "magic" file + +Based on file v3.22 by Ian F. Darwin (see libfile/LEGAL.NOTICE and +libfile/README.dist - File v3.22 can be found at many archive sites) + +For each entry in the magic file, the "message" for the initial offset MUST +be 4 characters for the CREATOR and 4 characters for the TYPE - white space is +optional between them. Any other characters on this line are ignored. +Continuation lines (starting with a '>') are also ignored i.e. only the initial +offset lines are used. + +e.g magic entry for a GIF file: + +# off type test message +# +# GIF image +0 string GIF8 8BIM GIFf +>4 string 7a \b, version 8%s, +>4 string 9a \b, version 8%s, +>6 leshort >0 %hd x +>8 leshort >0 %hd, +#>10 byte &0x80 color mapped, +#>10 byte&0x07 =0x00 2 colors +#>10 byte&0x07 =0x01 4 colors +#>10 byte&0x07 =0x02 8 colors +#>10 byte&0x07 =0x03 16 colors +#>10 byte&0x07 =0x04 32 colors +#>10 byte&0x07 =0x05 64 colors +#>10 byte&0x07 =0x06 128 colors +#>10 byte&0x07 =0x07 256 colors + +Just the "8BIM" "GIFf" will be used whatever the type of GIF file it is. +The continuation lines are used by the "file" command, but ignored by +mkhybrid. They could be left out completely. + +The complete format of the magic file is given in the magic man page (magic.5). + +See the file "magic" for other examples + +Use with the -magic magic_file option, where magic_file is a file +described above. + +The magic file can be used with the mapping file (option -map) - the order +these options appear on the command line is important. mkhybrid will try to +detect if the file is one of the Unix/Mac files (e.g. a CAP or Netatalk +file) first. If that fails, it will then use the magic and/or mapping +file e.g: + +mkhybrid -o output.raw -map mapping -magic magic src_dir + +The above will check filename extensions first, if that fails to set the +CREATOR/TYPE, the magic file will be used. To check the magic file +before the filename extensions, use: + +mkhybrid -o output.raw -magic magic -map mapping src_dir + + +Using just a magic file - filename extensions will not be checked e.g: + +mkhybrid -o output.raw -magic magic src_dir + +For the magic method to work, each file must be opened and read twice +(once to find it's CREATOR/TYPE, and a second time to actually copy the +file to the CD image). Therefore the -magic option may significantly +increase processing time. + +If a file's CREATOR/TYPE is not set via the magic and mapping matches, +then the file is given the default CREATOR/TYPE. diff --git a/doc/genisoimage/README.hide b/doc/genisoimage/README.hide new file mode 100644 index 0000000..ae8521b --- /dev/null +++ b/doc/genisoimage/README.hide @@ -0,0 +1,208 @@ +Hiding files on a CD +===================== + +This document attempts to show how to hide files from being seen by an +operating system accessing a CD as an ISO9660/Rock Ridge, Joliet or HFS +CD. It also highlights some of the limitations ... + +Note: this document is about the various -hide options - not be confused with +the -hidden options. + +The -hidden options set the 'EXISTENCE' bit in the directory entry which +means the file or directory will be invisible - unless some special option +is used to mount or view the CD - Linux has the 'unhide' mount option to +make these files visible. i.e. the directory entry exists on the CD. + +With hindsight, to avoid confusion with the -hidden option, it would have +been better to chose an option name like '-omit' instead of '-hide'... + +The various -hide options actually exclude the relevant directory entry +from the directory tree. Therefore, it is not possible to access a file +or directory that has be hidden with the -hide option when the ISO9600/Rock +Ridge directory is mounted - because the directory entry does not exist on the +CD (but the file data does). You would probably be able to access this file +or directory when mounted as a Joliet or HFS CD (depending on other options +used). Similarly, a directory entry hidden with the -hide-joliet option +will not be accessible when mounted as an Joliet CD. Similarly for -hide-hfs +etc. + +If you don't want a file or directory to appear on the CD at all, then use the +-exclude options, not the -hide options (genisoimage completely ignores any +file/directory excluded with the -exclude options). + + +Using the hide options +====================== + +There are 6 hide options: + +-hide Hide a file/directory from the ISO9660/Rock Ridge directory +-hide-list As above, but read file names from a file +-hide-joliet Hide a file/directory from the Joliet directory +-hide-joliet-list As above, but read file names from a file +-hide-hfs Hide a file/directory from the HFS directory +-hide-hfs-list As above, but read file names from a file + +You can use the -hide, -hide-joliet and/or -hide-hfs options as many times +as you like on the command line, but if you have many files to hide, then +it may be better to put your file names in a file (one per line) and use +the corresponding 'list' option. You can also use the three -hide-list options +as many times as you want. + +The arguments to the -hide options are either the 'basename' or the 'whole +path name' of a file. That is, if you use the option: + +% genisoimage -hide ABC [-other-options] CD_directory + +then any file with the name ABC will be hidden. If you want to be more +specific, then use the whole name - as seen by genisoimage e.g.: + +% genisoimage -hide CD_directory/XYZ/ABC [-other-options] CD_directory + +will hide just the file 'CD_directory/XYZ/ABC' - not any other file called +'ABC' that might exist under 'CD_directory'. However, if your command line +is like: + +% genisoimage -hide CD_directory/XYZ/ABC [-other-options] ./CD_directory + +Then the file 'CD_directory/XYZ/ABC' will not be hidden because as far as +genisoimage is concerned. Its whole path is actually './CD_directory/XYZ/ABC'. + +You can use wild cards in the -hide arguments. + +If the file name to be hidden is a directory, then the directory and all +its contents are hidden. + +The main use of the hide options is on a multi platform (hybrid CD) to hide +various files/directories that are operating system specific from been seen +on the CD when mounted on another OS. i.e. You may want to hide Macintosh +executables from being seen when the CD is mounted as a Joliet CD on a PC etc. + +For example, say we want to create a ISO9660/Rock Ridge, Joliet, HFS hybrid +CD from files/directories in the directory called 'cd_dir' - which are: + +MAC/ +MAC/app +MAC/data/ +MAC/data/file1 +PC/ +PC/app +PC/data/ +PC/data/file1 +UNIX/ +UNIX/app +UNIX/data +UNIX/data/file1 +COMMON/ +COMMON/some_files + +We could use the command line: + +% genisoimage -r -J -hfs -hide MAC -hide PC -hide-joliet MAC \ + -hide-joliet UNIX -hide-hfs PC -hide-hfs UNIX -o cd.iso cd_dir + +This will give a CD that when mounted as a Rock Ridge CD, you will only +see the directories UNIX and COMMON, as a Joliet CD the directories +PC and COMMON, and as an HFS CD the directories MAC and COMMON. + +If you also had the three files in the current directory called README.hfs, +README.joliet and README.unix - but you wanted to have each of these +files appear as just 'README' when mounted, then you could use the above +command line with the following: + +% genisoimage -r -J -hfs -graft-points -hide MAC -hide PC -hide-joliet MAC \ + -hide-joliet UNIX -hide-hfs PC -hide-hfs UNIX \ + -hide README.hfs -hide README.joliet -hide-joliet README.hfs \ + -hide-joliet README.uni -hide-hfs README.joliet -hide-hfs README.unix \ + README=README.hfs README=README.joliet README=README.unix \ + -o cd.iso cd_dir + +Note: we've used the -graft-points option as we're using the '=' syntax +to insert the files called README.hfs, README.joliet and README.unix as +'README' + +The resulting CD when mounted as a Rock Ridge CD, will have the directories +UNIX and COMMON - with the file called README - which was originally +called README.unix. + +However, in most circumstances, it would be better to have the contents +of each of the OS specific directories (plus the contents of the COMMON +directory) to appear at the top level of the CD. i.e. when the CD is mounted +(as ISO9660/Rock Ridge, Joliet or HFS) it has the contents: + +README +app +data/file1 +some_files + +Unfortunately, this is not as straight forward as it may seem - i.e. doing +the following may seem OK, but it won't work - for reasons I'll explain +later: + +It gets a bit messy using the -graft-points syntax above, so we'll assume +each of the MAC, UNIX and PC directories contain the correct README, We'll +also change to the 'cd_dir' directory and use the command: + +genisoimage -r -J -hfs -hide MAC -hide PC -hide-joliet MAC \ + -hide-joliet UNIX -hide-hfs PC -hide-hfs UNIX \ + -o cd.iso MAC PC UNIX COMMON + +You will get errors like: + +genisoimage: Error: UNIX/README and MAC/README have the same Rock Ridge name +... +genisoimage: Unable to sort directory + +This is because you can not hide "pathspecs" that are directories ("pathspecs" +are file names given on the command line, or in a path-list file). This a +"feature" of genisoimage. In this case nothing is actually hidden at all. + +So you might think that the following may work: + +genisoimage -r -J -hfs -hide "MAC/*" -hide "PC/*" -hide-joliet "MAC/*" \ + -hide-joliet "UNIX/*" -hide-hfs "PC/*" -hide-hfs "UNIX/*" \ + -o cd.iso MAC PC UNIX COMMON + +which may appear to work - but when the CD is mounted as an ISO9660/Rock Ridge +or Joliet CD, then the directory "data" is missing. + +Again this is a feature of genisoimage - the directories PC/data and UNIX/data +are mapped by genisoimage to the same output directory called "/data" - the +various "hide" flags are stored with this directory info - in this case as +the output directory "/data" is first hidden from the ISO9660/Rock Ridge and +then the Joliet directory, the net result is that "/data" gets hidden from +both directories ... the way genisoimage hides HFS directories is slightly +different, so in this case the directory "data" exists on the HFS volume +and contains the correct contents. + +However, it is possible to obtain the required result, but we have to be +careful about hiding multiple input directories that map to a single output +directory. + +To do this we have to hide just the files in these directories (or more +accurately, all the non-directories). This is best done by using lists of +files to hide for example: + +find PC -type f -print > pc.list +find UNIX -type f -print > unix.list +find MAC -type f -print > mac.list + +genisoimage -r -J -hfs -hide-list pc.list -hide-list mac.list \ + -hide-joliet-list unix.list -hide-joliet-list mac.list \ + -hide-hfs-list pc.list -hide-hfs-list unix.list \ + -o cd.iso MAC PC UNIX COMMON + +i.e. instead of trying to hide a directory and letting genisoimage hide its +contents, we explicitly hide all the files in the directory, but not the +directory and any of its sub-directories. + +This will work for the above input files, but if your directory trees contain +symbolic links and/or directories that will not get merged, then the hide lists +will have to be tailored to get the required result. + + +James Pearson 22-Nov-2001 + +Any comments/problems to j.pearson@ge.ucl.ac.uk + +Modified for cdrkit/genisoimage by Eduard Bloch, Wed, 27 Dec 2006 diff --git a/doc/genisoimage/README.hppaboot b/doc/genisoimage/README.hppaboot new file mode 100644 index 0000000..a7a7549 --- /dev/null +++ b/doc/genisoimage/README.hppaboot @@ -0,0 +1,38 @@ +# README.hppaboot Steve McIntyre <steve@einval.com> 2004/07/19 + +The hppa boot support allows you to create a bootable CD which will +work with HP PA/RISC machines, for example bootable installation +media. + +The method used for this is the same as in palo, the bootloader for +Linux on hppa. See the palo README for more details about supported +hardware etc. + +The HPPA firmware reads the first 2048-byte sector off a disk and +parses information in that sector. The information in question is the +location (start sector) and length of various files: + + * a 32-bit kernel image + * a 64-bit kernel image + * first stage bootloader (iplboot) + * (optional) ramdisk + +and also the system command line to use, e.g. + + "5/vmlinux HOME=/ TERM=linux console=tty" + +The firmware will load and execute the first stage boot loader, and +that should be able to find the (32- or 64-bit) kernel and boot +normally. Whether you need a 32- or 64-bit kernel depends on your +hardware; some will even support both. + +To use the hppa boot support code in genisoimage, simply specify the boot +command line and file locations (relative to the CD root) as follows: + +genisoimage ... -hppa-cmdline <cmdline, parts separated by spaces or commas> \ + -hppa-kernel-32 <32-bit kernel> \ + -hppa-kernel-64 <64-bit kernel> \ + -hppa-bootloader <bootloader> \ + -hppa-ramdisk <ramdisk file> \ + -o hppa.iso hppa-files + diff --git a/doc/genisoimage/README.joliet b/doc/genisoimage/README.joliet new file mode 100644 index 0000000..ab9bf5d --- /dev/null +++ b/doc/genisoimage/README.joliet @@ -0,0 +1,53 @@ +Some thoughts on Joliet - why it is a dumb idea to have a CD +with Joliet enhancements but without Rock Ridge. +It also helps you to understand why it it not possible to append +a new session to a multi-session Joliet CD when Rock Ridge is +missing. + +- Joliet is not an accepted independant international standard + like ISO-9660 or Rock Ridge (IEEE-P1282). + Joliet has been created in 1995 - Rock Ridge in 1990. + Rock Ridge became a IEEE standard around 1992. + +Joliet is an unjustified addition to ISO-9660. + +- The Joliet tree has no relation to the + ISO-9660 tree. Files from the ISO-9660 tree and from the + Joliet tree only share content. In general, it is not + possible to find the ISO-9660 name from a Joliet name + and vice versa if you check both trees on a CD. + + Rock Ridge extensions are located at the end of each + ISO-9660 directory record. This makes the Rock Ridge + tree closely coupled to the ISO-9660 tree. + +- Joliet does not allow all characters too, so the + Joliet filenames are not identical to the filenames + on disk. + + As the ISO-9660 tree is the standard reference tree + on a CD and the ISO-9660 filenames don't allow all + characters and there is a length limitation, the + ISO-9660 names cannot be mapped to the filenames on the + OS reference tree on disk for doing multi-session. + + Due to different limitations, the short ISO-9660 name + is in most cases not equal to the Joliet name or the + Rock Ridge name. + +- Joliet has a filename length limitation of 64 chars (independent + from the character coding and type e.g. European vs. Japanese) + This is annoying as modern filesystems all allow 255 chars + per path name component. + + Joliet uses UTF-16 coding while Rock Ridge uses ISO-8859 or + UTF-16 based chars and allows 255 octets. Using UTF-8, + Rock Ridge allows 85 Japanese characers or 255 US-ASCII chars. + +Other than slightly longer filenames, Joliet offers no new properties +over plain ISO 9660. Rock Ridge is an open extendable standard and +there is no filesystem property on Win32 that could not be implemented +using Rock Ridge. + +Except Linux and FreeBSD, there is no POSIX-like like OS that supports +Joliet. Never create Joliet only CD's for that reason. diff --git a/doc/genisoimage/README.macosx b/doc/genisoimage/README.macosx new file mode 100644 index 0000000..e082bfc --- /dev/null +++ b/doc/genisoimage/README.macosx @@ -0,0 +1,43 @@ +Notes on using the --osx-hfs option when running genisoimage on MacOS X + +genisoimage does not use any of the MacOS APIs to access files - it uses +standard (POSIX style) library calls. Under normal circumstances, all +genisoimage will 'see' is the data fork of files on an HFS (or HFS+) file system. + +However, Apple have provided a way for POSIX style applications to +access the resource fork - using the following syntax: + +If a file exists on an HFS volume with the name 'foo', then the resource fork +can be accessed using the file name 'foo/rsrc' or foo/..namedfork/rsrc' +(the data fork can also be accessed using 'foo/..namedfork/data'). + +These 'pseudo' file names are not normally visible in a directory - unless +you access them directly (e.g. 'ls -l */rsrc etc). + +To access the finder information, Apple have provided an undocumented library +function called getattrlist(). Fortunately there are example of its usage +in the Darwin (MacOS kernel) source code. + + +Although MacOS X can use HFS(+) as its file system, Apple have decided to +move away from using HFS to store finder info and resource data - for +example, the TYPE of a file may be based on its file name extension and the +TYPE field in the finder info empty. + +genisoimage knows nothing about these file name extension mappings, so if the +--osx-hfs option is used and the source files are on MacOS X HFS(+) volumes, +by the fact that they are HFS files, they will get identified as 'MacOS X HFS' +and the resulting file on the output CD image will have empty TYPE and CREATOR +fields. + +Therefore, if the input finderinfo is blank and the the resource fork is +empty, genisoimage will assume the input file is not a 'real' HFS file - which +means the TYPE and CREATOR may then be set using the file's magic number or +genisoimage' file name extension mapping. + +The only real benefit of using the --osx-hfs option is when the source files +are on an OS9 or earlier HFS or HFS+ volume e.g. an existing HFS CD. + +James Pearson 3-Jul-2002 +Edited for program name change by Eduard Bloch, 2006 + diff --git a/doc/genisoimage/README.mipsboot b/doc/genisoimage/README.mipsboot new file mode 100644 index 0000000..1e5227a --- /dev/null +++ b/doc/genisoimage/README.mipsboot @@ -0,0 +1,26 @@ +# README.mipsboot Steve McIntyre <steve@einval.com> 2004/07/19 + +The mips/SGI boot support allows you to create a bootable CD which +will work with big-endian mips SGI machines, for example bootable +installation media. + +The method used for this is the same as in genisovh, a tool to make +CDs bootable for Linux on SGI. + +The SGI firmware reads the first 512-byte "sector" off a disk and +parses information from a volume descriptor header in that sector. The +information in question is the location (start sector) and length of +bootable kernel images; up to 15 are supported. + +The firmware will load and execute kernels listed. (I'm not sure what +it will do if more than one kernel is listed - it may display a boot +menu). + +To use the SGI boot support code in genisoimage, simply specify the kernel +file locations (relative to the CD root) as follows: + +genisoimage ... -mips-boot <kernel file #1> \ + ... + -mips-boot <kernel file #n> \ + -o mips.iso mips-files + diff --git a/doc/genisoimage/README.mipselboot b/doc/genisoimage/README.mipselboot new file mode 100644 index 0000000..af3979b --- /dev/null +++ b/doc/genisoimage/README.mipselboot @@ -0,0 +1,29 @@ +# README.mipselboot Steve McIntyre <steve@einval.com> 2004/07/19 + +The mips/DEC boot support allows you to create a bootable CD which +will work with little-endian mips DEC machines (e.g. older +DECstations), for example bootable installation media. + +The method used for this is the same as in delo, the Linux-on-mipsel +bootloader. See the delo README for more information about how to +configure the DECstation's firmware to find and boot the CDROM. + +The DEC firmware reads the first 512-byte "sector" off a disk and +parses information from that sector. The information in question is +the location (start sector) and length of the first stage boot +loader. + +(On Linux, this boot loader is in ELF format and the firmware does not +know how to deal with ELF directly, we have to parse the ELF headers +and find the raw binary data needed inside it. Pointers to the start +and length of that raw binary are what is stored in the boot sector.) + +The firmware will load and execute the first stage boot loader, and +from that point the system should be able to find the normal OS kernel +and start up fully. + +To use the DEC boot support code in genisoimage, simply specify the kernel +file location (relative to the CD root) as follows: + +genisoimage ... -mipsel-boot <kernel file> -o mipsel.iso mipsel-files + diff --git a/doc/genisoimage/README.mkhybrid b/doc/genisoimage/README.mkhybrid new file mode 100644 index 0000000..49036a1 --- /dev/null +++ b/doc/genisoimage/README.mkhybrid @@ -0,0 +1,145 @@ + +mkhybrid v1.13 has merged with mkisofs which was forked to genisoimage later + +HFS hybrid code Copyright (C) James Pearson 1997, 1998, 1999, 2000 +libhfs code Copyright (C) 1996, 1997 Robert Leslie +libfile code Copyright (c) Ian F. Darwin 1986, 1987, 1989, + 1990, 1991, 1992, 1994, 1995 +mkisofs code Copyright 1993 Yggdrasil Computing, Incorporated + +*** NEWS *** + +Macs can now read Joliet CDs - see http://www.tempel.org/joliet/ + +*** + +*** IMPORTANT *** + +The meaning of some of the HFS command line options has changed since +version 1.12b5.2. This change is to make the way genisoimage decodes the +various Apple/Unix file formats (CAP, AppleDouble, MacBinary etc.) less +confusing and more logical. To decode one or more of the Apple/Unix files, +then the corresponding "double dash" option must be given (i.e. --cap, +--double, --macbin etc.) genisoimage can search for all known Apple/Unix files +by using the -probe option. + +The options that have changed are: + +Option old meaning new meaning +====== =========== =========== + +-hfs Create an HFS hybrid CD Create an HFS hybrid CD. + and attempt to decode all Any Apple/Unix file is only + Apple/Unix files (except decoded if one or more of + MacBinary and AppleSingle) the "double dash" options are + given + +-apple Create an ISO9660 with Create an ISO9660 with + Apple extensions CD and Apple extensions CD. Any + attempt to decode all Apple/Unix file is only decoded + Apple/Unix files (except if one or more of the + MacBinary and AppleSingle) "double dash" options are given + +-no-mac-files Do not attempt to decode No longer used + any Apple/Unix file + +-probe Attempt to decode Attempt to decode all + MacBinary and AppleSingle Apple/Unix files + as well as the other + Apple/Unix files + +*** + +Most of the HFS features work fine, however, some are not fully tested. +These are marked as "Alpha" in the man page. + +See "ChangeLog.mkhybrid" for any minor changes/bug fixes + +If you are using SunOS 4.1.[34], then you need the following patches +to read CDs with associated files: + +SunOS 4.1.3: Patch 101832-05 +SunOS 4.1.3_U1: Patch 101833-02 +SunOS 4.1.4: Patch 102583-02 + + +EXAMPLES + +To create a HFS hybrid CD with the Joliet and Rock Ridge extensions of +the source directory cd_dir: + +% genisoimage -o cd.iso -r -J -hfs cd_dir + +To create a HFS hybrid CD from the source directory cd_dir that contains +Netatalk Apple/Unix files: + +% genisoimage -o cd.iso --netatalk cd_dir + +To create a HFS hybrid CD from the source directory cd_dir, giving all files +CREATOR and TYPES based on just their filename extensions listed in the file +"mapping".: + +% genisoimage -o cd.iso -map mapping cd_dir + +To create a CD with the 'Apple Extensions to ISO9660', from the source +direcories cd_dir and another_dir. Files in all the known Apple/Unix format +are decoded and any other files are given CREATOR and TYPE based on their +magic number given in the file "magic": + +% genisoimage -o cd.iso -apple -magic magic -probe cd_dir another_dir + +The following example puts different files on the CD that all have +the name README, but have different contents when seen as a +ISO9660/RockRidge, Joliet or HFS CD. + +Current directory contains: + +% ls -F +README.hfs README.joliet README.unix cd_dir/ + +The following command puts the contents of the directory "cd_dir" on the +CD along with the three README files - but only one will be seen from +each of the three filesystems: + +% genisoimage -o cd.iso -hfs -J -r \ + -hide README.hfs -hide README.joliet \ + -hide-joliet README.hfs -hide-joliet README.unix \ + -hide-hfs README.joliet -hide-hfs README.unix \ + README=README.hfs README=README.joliet README=README.unix \ + cd_dir + +i.e. the file README.hfs will be seen as README on the HFS CD and the +other two README files will be hidden. Similarly for the Joliet and +ISO9660/RockRidge CD. + +There are probably all sorts of stange results possible with +combinations of the hide options ... + + +Any comments, bug reports/fixes about the HFS parts of genisoimage to the +address below. + +Please state the version, platform and command line used when submitting +a bug report - the output from "-log-file -v" would help. + +Original author: James Pearson (j.pearson@ge.ucl.ac.uk) + +This describes the program as shipped with cdrkit, a spinoff from the +cdrtools project. However, the cdrtools developers are no longer +involved in the development of this spinoff and therefore shall not +be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original authors. + +If you have support questions, send them to + +debburn-devel@lists.alioth.debian.org + +If you have definitely found a bug, send a mail to this list or to + +submit@bugs.debian.org + +writing at least a short description into the Subject and "Package: cdrkit" + +Source: README.mkhybrid from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> and Eduard Bloch + diff --git a/doc/genisoimage/README.prep_boot b/doc/genisoimage/README.prep_boot new file mode 100644 index 0000000..f406735 --- /dev/null +++ b/doc/genisoimage/README.prep_boot @@ -0,0 +1,45 @@ +I have extended mkhybrid to create a CD that is bootable via PPCbug +on a PowerPC Reference Platform compliant machine (referred to as +PReP). + +This includes a number of IBM RS-6000 clones, along with most of +Motorola's embedded PowerPC boards, such as the MTX and MVME +boards. (The motorola boards are sometimes referred to as PowerPlus) + +To build a bootable CD, you will first need a kernel image for your +machine. Put the image somewhere in the filesystem you want +to generate and ISO9660 image from. + +The '-B' or '-prep-boot' flags are used to specify the image file +to use. The path must be relative to the root of the CD filesytem, +NOT from the current directory. + +For example: to make an image of /tmp/cd and use the image file +/tmp/cd/zImage, (with rock ridge extensions) use: + +mkhybrid -r -B zImage /tmp/cd -o cd.img + +Since there are four entries for bootable 'partitions', I have +allowed up to 4 different images to be used. This might be +usefull if one has need of different kernel images for different +machines on the same CD. + +The first image will be in the first partition entry, so if one +uses: + +mkhybrid -r -B zImage1 -B zImage2 -B zImage3 -B zImage4 /tmp/cd + +This will result in 4 bootable images. To boot off the first image +from PPCbug, use 'pboot 0 41' from the ppcbug> prompt. +(assuming the CDROM is at SCSI ID 4.. replace the 4 with the SCSI +ID of the CDROM if not.) The second image is at 'pboot 0 42', etc. + +There should not be any conflicts with any of the HFS or hybrid +functions, since the space used by the PReP partition maps is +unused by anything else. If fact, the goal is to make a CD +bootable on both Mac's and PReP machines ;) + +For any questions contact me at one of the following addresses: +troy@microux.com +troy@blacklablinux.com +hozer@drgw.net diff --git a/doc/genisoimage/README.releasenotes b/doc/genisoimage/README.releasenotes new file mode 100644 index 0000000..d4f3898 --- /dev/null +++ b/doc/genisoimage/README.releasenotes @@ -0,0 +1,154 @@ +# @(#)README 1.7 99/11/23 joerg +# 06/09/11 christian + +This describes the program as shipped with cdrkit, a spinoff from the +cdrtools project. However, the cdrtools developers are no longer +involved in the development of this spinoff and therefore shall not +be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original authors. + +Note: + + This program requires a lot of virtual memory to run since it +builds all of the directories in memory. The exact requirements +depend upon a lot of things, but for Rock Ridge discs 12Mb would not +be unreasonable. Without RockRidge and without the translation +tables, the requirements would be considerably less. + + +***************************** +Notes for version 1.12 + + Joliet support is now complete. See the -J option. + + The file scanning code is much improved - mkisofs can use multiple + sources of input files and merge them together to form the output + image. In addition, each source can be grafted at any point in the + iso9660 image. + + The image writing code has been cleaned up to make it much easier + to add custom extensions. + + The ADD_FILES feature has been removed as it didn't work well, +and it was hard to figure out. The recent rearrangements in the +file scanning code would tend to solve these issues. + +***************************** +Notes for version 1.11 + + There is a feature which can be optionally compiled into +mkisofs that allows you to merge arbitrary directory trees into the +image you are creating. You need to compile with -DADD_FILES for my +changes to take effect. Thanks to Ross Biro biro@yggdrasil.com. + +***************************** +Notes for version 1.10b1 + + Big news is that multi-session capability is very close to being + done. There is still a missing interface to cdwrite that is + used to determine the next writable address and the sector number + of the last existing session. Until we get the interface to cdwrite + done, this is a beta version. + + Bug involving DST fixed (dates are always calculated, since some + files may be DST and other ones would not be). + + Unfortunately the notes on some of the small patches got lost. + +***************************** +Notes for version 1.06 + + Jan-Piet Mens <jpm@mens.de> added support for the '-m' switch. This + allows exclusion of shell-style globs from the CDROM. + See manual mkisofs.8 for more information. + +***************************** +Notes for version 1.05 + + Added support for '-r' switch. This is very similar to -R for +Rock Ridge, but echos of the development environment are removed +(i.e. uid/gid set to 0, and permissions of the files are canonicalized). +Useful in applications where a distribution medium is being produced. + +***************************** +Notes for version 1.04 + + No notes for 1.04. + +***************************** +Notes for version 1.03 + + No notes for 1.03. + +***************************** +Notes for version 1.02. + + Minor bugfixes here and there. Support for compiled in +defaults for many of the text fields in the volume header are now +present, and there is also support for a file ".mkisofsrc" that can +also read settings for these parameters. + + A short script "Configure" was added to allow us to set up special +compile options that depend upon the system that we are running on. +This should help stamp out the sphaghetti-isms that were starting to grow +up in various places in the code. + + You should get more meaningful error messages if you run out of +memory. + +***************************** +Notes for version 1.1. + + The big news is that SUSP CE entries are now generated for +extremely long filenames and symlink names. This virtually guarantees +that there is no limit (OK, well, about 600Mb) for file name lengths. +I have tested this as well as I can, and it seems to work with linux. +This would only be used very rarely I suspect. + + Also, I believe that support for VMS is done. You must be +careful, because only Stream-LF and FIxed length record files can be +recorded. The rest are rejected with error messages. Perhaps I am +being too severe here. + + There is a bugfix in the sorting of entries on the disc - we +need to stop comparing once we reach the ';' character. + + There are four new options -z -d -D -l -V. Some of these tell +mkisofs to relax some of the iso9660 restrictions, and many systems +apparently do not really seem to mind. Use these with caution. + + Some diagnostic programs to scan disc images are in the diag +directory. These are not as portable as mkisofs, and may have some +bugs. Still they are useful because they can check for bugs that I might +have introduced as I add new features. + +***************************** +Notes for version 1.0. + + In version 1.0, the date fields in the TF fields were fixed - +previously I was storing st_ctime as the file creation time instead of +the file attribute change time. Thanks to Peter van der Veen for +pointing this out. I have one slight concern with this change, +however. The Young Minds software is definitely supplying 3 dates +(creation, modification and access), and I would strongly suspect that +they are incorrectly putting the file attribute change time in the +file creation slot. I would be curious to see how the different RRIP +filesystems treat this. Anyway, this is something to keep in the back +of your mind. + + The symlink handling was not quite correct in 0.99 - this is +now fixed. Only some systems seemed to have been affected by this bug. + + A command line option is now present to allow you to +specifically exclude certain files from the distribution. + + The case where you do not have permissions to read a directory +is now handled better by mkisofs. The directory that cannot be opened +is converted into a zero-length file, and processing continues normally. + + A few portability things have been fixed (hopefully). + + +Source: README from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/doc/genisoimage/README.rootinfo b/doc/genisoimage/README.rootinfo new file mode 100644 index 0000000..b3bc447 --- /dev/null +++ b/doc/genisoimage/README.rootinfo @@ -0,0 +1,90 @@ +The -icon-position option will attempt to preserve folder window positions, +scroll bars, views etc. for Apple/Unix file formats that support this +information (see below for which Apple/Unix encoding are supported). + +This information is stored in the 'FinderInfo' part of a Apple/Unix directory. +For example, in a CAP directory structure a directory called 'dirA' will +have the necessary FinderInfo stored in file '.finderinfo/dirA'. This file +stores information including, the folder's location and size on screen, +its scroll positions, folder View (view as Icons, Small Icons, etc.). + +However, the similar FinderInfo data for the 'root' folder is a special case. +For example, if a directory called '/some/dir/macfiles' is a CAP volume that +is mounted on a Mac as 'macfiles', then the FinderInfo for this directory +is stored in the file '/some/dir/.finderinfo/macfiles' - which is outside +the CAP directory structure. + +To get round this, an extra option, '-root-info' is used that takes as its +argument the name of the file that stores the root folder's FinderInfo. + +Using the above example, the command file options will be something like: + +% mkhybrid --cap -root-info /some/dir/.finderinfo/macfiles /some/dir/macfiles + +The format of the root FinderInfo file must be the same as the 'double-dash' +option(s) given on the command line. + +The Apple/Unix encodings that mkhybrid can decode the root FinderInfo are: + +CAP: + CAP directory: /some/dir/macfiles + Root FinderInfo file: /some/dir/.finderinfo/macfiles + +Netatalk: + Netatalk directory: /some/dir/macfiles + Root FinderInfo file: /some/dir/.AppleDouble/RootInfo + +EtherShare: + EtherShare directory: /some/dir/macfiles + Root FinderInfo file: /some/dir/.rsrc/macfiles + +If an HFS disk is mounted on a Linux platform, then the root FinderInfo +files are: + +Option 'fork=cap': + Root FinderInfo file: /mountpoint/.rootinfo + +Option 'fork=double': + Root FinderInfo file: /mountpoint/%RootInfo + +Option 'fork=netatalk': + Root FinderInfo file: /mountpoint/.AppleDouble/RootInfo + + +The '-root-info' option implies the '-icon-position' option. Future releases +of mkhybrid may automatically find the root FinderInfo file. + +The volume name is not set from the root FinderInfo file. Use the -V or +-hfs-volid options to set the volume name. + +Currently UShare, SGI/XINET, PC Exchange and SFM Apple/Unix root FinderInfo +files are not supported by mkhybrid - more information about these formats +is required in order to supoort them. + +AppleSingle and MacBinary are file only formats - they don't support folders +or volumes. + +Using this option, it is now possible to make a nearly true representation +of a Mac folder layout on a Unix/Linux platform. + +Original author: James Pearson 26-Apr-2000 + +This describes the program as shipped with cdrkit, a spinoff from the +cdrtools project. However, the cdrtools developers are no longer +involved in the development of this spinoff and therefore shall not +be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original authors. + +If you have support questions, send them to + +debburn-devel@lists.alioth.debian.org + +If you have definitely found a bug, send a mail to this list or to + +submit@bugs.debian.org + +writing at least a short description into the Subject and "Package: cdrkit" + +Source: README.rootinfo from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/doc/genisoimage/README.session b/doc/genisoimage/README.session new file mode 100644 index 0000000..a4126fb --- /dev/null +++ b/doc/genisoimage/README.session @@ -0,0 +1,53 @@ +/* @(#)README.session 1.3 99/03/02 eric */ + + This release of genisoimage has basic support completed for +multiple sessions. However, we still need some interaction +between wodim and genisoimage for this to work correctly. This is needed as +only wodim knows the different ways to gather these numbers for all +different drives. It may be that future versions of genisoimage will include +the needed support for MMC compliant drives. + + There are a few new options to genisoimage to allow for this. +The first one is "-M /dev/scd0", and is used so that genisoimage can examine +the entirety of the previous image so that it can figure out what additional +files need to be written in the new session. Note that there are operating +systems that don't allow to read from CD drives with a sector size +of 2048 bytes per sector. To use genisoimage on such an operating system, you +will need a version of genisoimage that includes the SCSI transport library +from wodim. Simply use the dev= syntax from wodim with -M in +such a case. It will tell genisoimage to use the SCSI transport library to +read from the CD instead of using the standard read() OS interface. + + There is also a temporary hack in genisoimage in the form of a '-C' option. +The -C option takes two numbers as input, which are delimited by commas. +For example, you could specify "-C 1000,1020", but you should never just +make up numbers to use here. These numbers are determined from wodim. + + Note that if you use -C and omit -M, it effectively means that +you are writing a new session, starting at a non-zero block number, +and you are effectively ignoring all of the previous session contents. +When this session is sent to the writer, the new session effectively +"erases" the previous session. + + In practice you should be able to do something like: + +genisoimage [other options] -C `wodim dev=b,t,l -msinfo` \ + -M /dev/cdblkdev + +Replace 'b,t,l' by the aproriate numbers for SCSIbus, target and lun +of your drive. + +Note: As of the 1.12b5 release, the multi-session technology has +matured quite significantly. It is entirely possible that bugs +exists, or that further tweaks will be required somewhere along the +way to get things working correctly. The data gathering mode of +wodim has been tested, and I believe it works correctly. Caveat +Emptor. + +[Mar 1, 1999]. + + +Source: README.session from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> and +Eduard Bloch <blade@debian.org> + diff --git a/doc/genisoimage/README.sort b/doc/genisoimage/README.sort new file mode 100644 index 0000000..1e377bc --- /dev/null +++ b/doc/genisoimage/README.sort @@ -0,0 +1,102 @@ +Sort the order of file data on the CD +===================================== + +Note: this option does not sort the order of the file names that appear +in the ISO9660 directory. It sorts the order in which the file data is +written to the CD image. + +This option is useful in order to optimize the data layout on a CD. + +To use, type something like: + +genisoimage -o cdimage.iso -sort sort_file [other_options] cd_dir + +The file 'sort_file' contains two columns of: + +filename weight + +where filename is the whole name of a file/directory as genisoimage will see it +and weight is a whole number between +/- 2147483647 + +The files will be sorted with the highest weights first and lowest last. +The default weight is zero. + +If the filename is a directory name, then all the files in that directory (and +sub-directories) will use its weight as their default weight. + +e.g. + +If the directory 'cd_dir' contains two directories called 'dir1' and 'dir2' +with files 'A', 'B' and 'C' in dir1 and 'X', 'Y' and 'Z', the the file +'sort_file' could look something like: + +cd_dir/dir2 1000 +cd_dir/dir2/Y 2000 +cd_dir/dir1/B -2000 +cd_dir/dir1/A -8000 + +Note: There must be only one space or tab character between the filename and +the weight and the weight must be the last characters on a line. The filename +is taken to include all the characters from the first in a line, up to, but +not including the last space or tab character on a line. This is to allow +for space characters to be in, or at the end of a filename. + + +The command: + +genisoimage -o cdimage.iso -sort sort_file cd_dir + +will sort the above file data as: + +cd_dir/dir2/Y +cd_dir/dir2/X +cd_dir/dir2/Z +cd_dir/dir1/C +cd_dir/dir1/B +cd_dir/dir1/A + +Note: files 'X' and 'Z' both have the weight 1000 - their sort order will then +be the normal ISO9660 sort order (i.e. alphabetical in this case). + +File C will have the default weight of 0 + +Warning: the filenames in the sort list MUST match the whole path as seen by +genisoimage. i.e. in the above case, if the command line was: + +genisoimage -o cdimage.iso -sort sort_file ./cd_dir + +then the sort_file filename will have to changed as accordingly. + +Notes +===== + +CDs are written from the middle outwards. High weighted files will be nearer +the inside of the CD. + +Wildcards in the filename list should work. + +If a file appears more than once in the source directory tree, then the file +is only added once to the CD image - i.e. a hard linked file, or symbolic +link if using the -f option. The file will be sorted according to the +highest weighting given to any of the linked files. + +Zero length files are not sorted - the 'start extent' *may* appear to be in +the middle of another file after sorting. This is because zero length files +are given the start extent after the last file added to the CD at that time. +This address is not changed by the sorting, so it may appear that the file +address is in another file - however as they are zero length, this will +not matter! + +Directories are not sorted by this flag - directories HAVE to be in the +ISO9660 sort order - however, the files the directory entry points to, can be +anywhere on the CD. + +Existing files from any previous sessions will not be sorted - they already +exist on the CD and can not be moved! + +I have no idea if this is really useful ... + + +James Pearson 22-Nov-2001 + +Any comments/problems to j.pearson@ge.ucl.ac.uk diff --git a/doc/genisoimage/README.sparcboot b/doc/genisoimage/README.sparcboot new file mode 100644 index 0000000..b9bcbf2 --- /dev/null +++ b/doc/genisoimage/README.sparcboot @@ -0,0 +1,77 @@ +# @(#)README.sparcboot 1.1 99/12/12 joerg +# Edited for program name change by Eduard Bloch, 2006 + +The sparc boot feature does allow you to create your own Sun sparc boot disk. +This will allow you to create modified Solaris install disks or to create +installation CD's for other OS that run on sparc systems. + +A CD that is bootable on a Sun sparc system has a Sun disk label on sector 0 +and some Sun sparc disk partitions behind the ISO-9660 filesystem image. + +The layout of a sparc boot CD: + +---------------------------------------------------------------------------------------------------- +|Sun disk label| Iso 9660 filesystem |Generic sun4 boot|sun4c boot|sun4m boot|sun4d boot|sun4e boot| +---------------------------------------------------------------------------------------------------- + +On older system CD's all boot partition contain a full UFS miniroot filesystem. +On newer CD's the images on slice 2 and above only contain boot redirects to +slice 1. + +To create a CD that is bootable on Sun sparc systems you need to have the +boot images for the apropriate sparc architecture. + +A boot image file usually is a UFS filesystem image that contains the +primary boot image at byte offset 512 ... 8191. + +You may get such boot images by extracting partitions 1..5 from a Sun Solaris install CD, +but any bootable image should work. + +Here is an expample how to do this with the Solaris 7 install CD. + +dd if=/vol/dev/dsk/c0t6/sol_7_sparc_sun_srvr/s1 of=sun4 +dd if=/vol/dev/dsk/c0t6/sol_7_sparc_sun_srvr/s2 of=sun4c +dd if=/vol/dev/dsk/c0t6/sol_7_sparc_sun_srvr/s3 of=sun4m +dd if=/vol/dev/dsk/c0t6/sol_7_sparc_sun_srvr/s4 of=sun4d +dd if=/vol/dev/dsk/c0t6/sol_7_sparc_sun_srvr/s5 of=sun4e + + +genisoimage -R -sparc-boot sun4,sun4c,sun4m,sun4d,sun4e -o boot.img /mnt/install + +Will create the bootable image in boot.img. + +If you like to make the boot images smaller, you may call 'fstyp -v' +on the images and use the 'size' value to get the needed minimal +boot image size in kB. + +The result for the S7 boot CD is: + +ufs +magic 11954 format dynamic time Wed Oct 7 00:00:30 1998 +sblkno 8 cblkno 12 iblkno 16 dblkno 252 +sbsize 2048 cgsize 2048 cgoffset 20 cgmask 0xfffffff0 +ncg 7 size 25704 blocks 23987 + ^^^^^ + This is the number of interest. +bsize 8192 shift 13 mask 0xffffe000 +fsize 2048 shift 11 mask 0xfffff800 +frag 4 shift 2 fsbtodb 2 +minfree 10% maxbpg 2048 optim time +maxcontig 256 rotdelay 0ms rps 90 +csaddr 252 cssize 2048 shift 9 mask 0xfffffe00 +ntrak 14 nsect 72 spc 1008 ncyl 102 +cpg 16 bpg 1008 fpg 4032 ipg 3776 +nindir 2048 inopb 64 nspf 4 +nbfree 1768 ndir 667 nifree 24329 nffree 9 +cgrotor 2 fmod 0 ronly 0 + +So you should call: + +dd if=/vol/dev/dsk/c0t6/sol_7_sparc_sun_srvr/s1 of=sun4 bs=1k count=25704 + +To modify this filesystem, you can mount it using the fbk driver: + +chmod +t ./sun4 # Need to do this to avoid vm cache aliasing problems + +mount -F fbk -o rw,type=ufs /dev/fbk0:sun4 /mnt + diff --git a/doc/genisoimage/README.sunx86boot b/doc/genisoimage/README.sunx86boot new file mode 100644 index 0000000..2286a57 --- /dev/null +++ b/doc/genisoimage/README.sunx86boot @@ -0,0 +1,77 @@ +# @(#)README.sunx86boot 1.3 05/02/25 Copyright 2003 J. Schilling +# Edited for program name change by Eduard Bloch, 2006 + +A Solaris x86 Boot CD looks the like this: + +- A PC type fdisk partition map is in CD sector 0 at offset 0 + This fdisk partition map contains a single Solaris 0x82 type + partition starting at CD sector 0 at offset 512. + +- A SVr4 disk partition label is at CD sector 0 at offset 1024. + This equates the usual 512 byte offset to the primary partition + used by SVr4. + + This SVr4 partition label defines: + + - Partition 0 to contain a usually UFS type boot filesystem + + - Partition 1 to map the ISO-9660 filesystem. + + This seems to be a conceptual bug from Sun, as it is + impossible to mount this partition because this partition + would point outside the primary fdisk partition type 0x82 + + - Partition 2 maps the whole CD. + + +A boot CD created by Sun contains a master boot record in CD sector 0 offset 0. +The size if this MBR is 0x1BE (446 decimal) as usual on PCs. + +At CD sector 0 offset 512, there is a "primary boot sector". The MBR assumes +that is always gets loaded together with the ""primary boot sector". + +The El-Torito map for this CD defines a "no-emulation" boot sitting at CD sector 0 +and being 4 512 byte sectors in size. This covers the 1024 bytes of above +boot code. Note that genisoimage will not put the no-emulation boot at sector 0 +as it keeps the boot inside the area used for other file content data. + +At CD sector 1..15, there is a secondary boot code that understands UFS and tries +to boot from UFS slice 0. If you like to boot from different filesystem types, +you need to replace this boot code. The real size used by the secondary boot +is 31 x 512 bytes == 15872 bytes. + +To get hold of the three boot files, do the following with e.g. a Solaris 10 +boot CD: + +readcd dev=1,0 f=CD.out sectors=0-32 + +Replace dev=1,0 with the apropriate values for your system (see readcd -scanbus). + +sdd if=CD.out bs=446 count=1 of=mboot +sdd if=CD.out count=1 iseek=512 of=pboot +sdd if=CD.out count=60 iseek=2048 of=bootblk + +To create the needed files for the misofs command line example below, do the +following: + +sdd if=mboot -fill of=eltoritoboot +cat pboot >> eltoritoboot + +sdd -inull bs=2k count=1 of=genboot +cat bootblk >> genboot + +If you like the CD to look more similar to the original Sun CDs, use: + +cp eltoritoboot genboot +sdd -inull bs=1k count=1 >> genboot +cat bootblk >> genboot + +If you like to create a CD similar to the Solaris 10 boot CD, do the following: + +mkdir isodir +star -cPM -C /vol/dev/dsk/c1t1d0/multi_icd_sol_10_x86/s2 . | star -xp -xdot -C isodir +cp eltoritoboot isodir/.bootimage + +genisoimage -G genboot -no-emul-boot -b .bootimage -c .catalog -R -o bootcd.iso -sunx86-boot /vol/dev/dsk/c1t1d0/multi_icd_sol_10_x86/s0 isodir/ + + diff --git a/doc/icedax/FAQ b/doc/icedax/FAQ new file mode 100644 index 0000000..815f579 --- /dev/null +++ b/doc/icedax/FAQ @@ -0,0 +1,296 @@ +Frequently Asked Questions + +Status +====== + + +Q: What is the copyright status of icedax? + +A: icedax is software copyrighted by Heiko Eissfeldt and others, and + released under the General Public License from the Free Software + Foundation (see file GPL). + +Compilation +=========== + + +Q: What are the requirements to run icedax? + +A: All operating systems that are supported by wodim should also be able to + run icedax. Currently DOS and Windows are not covered. + Requirements of previous versions of icedax have been cut down for the + sake of portability. Features like fork(), realtime scheduling, or shared + memory are all optional now. You need Cmake and its dependencies, an + ANSI C compiler and a C library to build icedax + on a supported operating system. To run icedax, a SCSI transport + implementation for the os, a cdrom or cd burner device to read from, and + at least say 65K of memory for buffers are needed. + + +Q: Why does it not compile under Linux, although I am using the newest kernel? + +A: There have been changes in the generic driver by Douglas Gilbert, that are + in its first release not compatible with the scsi library from Joerg + Schilling. We are working on this problem... + In the meantime better do not use this variant, use the older one instead. + + +Q: Why does it not compile using standard make? + +A: Like wodim, icedax uses the cmake system, which requires a + sophisticated make program like GNU make. + Pure posix make functionality is not enough. + +Setting Up (for now Linux only) +=============================== + + +Q: Should I use scsi emulation or the eide driver for my ATAPI cdrom drive? + +A: Scsi emulation is preferred, since it enables icedax to use more commands + and is often the only way to get special information like track titles with + cd-text. The emulation module is called ide-scsi, the eide module is called + ide-cd. + + +Q: How can I use my parallel-port-connected cdrom with icedax? + +A: Under Linux there is a driver, that makes this device under SCSI + emulation available. For more information see the wodim documentation. + + +Q: How do I check, if the current Linux kernel does support generic SCSI? + +A: run 'cat /proc/devices | grep "21 sg"' and see, if a line with 'sg' appears. + If it does not appear, the current kernel is not able to use the generic_scsi + interface. If you have generic SCSI support compiled as a module, see next + question, otherwise you need to recompile the kernel and enable generic SCSI. + You might try to use the 'cooked_ioctl' interface as a last resort, but then + you need to supply a cdrom device with -D (like -D/dev/cdrom). In this case + icedax completely relies on the cdda reading methods from the kernel + driver, so it might not work (due to unsupported). + + +Q: How do I load the generic SCSI module by hand? + +A: run 'insmod sg' and check the result (see above). + + +Q: How do I find the device setting for my drive? + +A: Under Linux use the script scan_scsi.Linux. It prints the available devices + and their respective device option to be used. + Be aware of the fact that the generic device naming may change whenever the + devices on the SCSI bus change (present or not present). + +General usage (sampling) +======================== + + +Q: How do I record the whole cd, each track in a seperate file? + +A: Use the '-B' option. This will automagically create a file for each track. + + +Q: How do I record the whole cd into one file? + +A: Just extend the default recording time from one track to a big enough + time in seconds to cover the whole cd (like -d99999). + + +Q: How do I record successive tracks (a track range) into seperate files? + +A: Use the '-B' option and -t<first tracknumber>+<last track number>. + + +Q: How do I record successive tracks (a track range) into one file? + +A: Use -t<first tracknumber>+<last track number>. + + +Q: How do I record different tracks into seperate files with individual file + names? + +A: Use the supplied script 'readmult'. For usage see the comments at the + beginning of the script. + + +Q: How can I get the highest speed out of icedax? + +A: See the file README. There is a section about performance and what is + influencing it. + + +Q: How can I burn audio cds with icedax and wodim on-the-fly? + +A: This has not been tested very well, so caveat emptor. It is possible to + use icedax and wodim with pipes, _but_ there are several issues. + 1.: The cd drive may become too slow to keep wodim's buffer happy, when + a scratch on the audio cd is encountered, and several retries take place. + 2.: Currently there is no way to carry individual track information from + icedax to wodim. Several information bits are available very late + but are needed in advance from wodim. + 3.: Some operating systems have limitations in multiple SCSI accesses and + other resources (shared memory). icedax and wodim may block each + other, or might fight over limited resources. + For these reasons it is not recommended to burn on-the-fly with icedax. + +Frontends +========= + + +Q: Which frontends for icedax are available? + +A: See the file 'Frontends'. There are command line and graphical frontends. + +Album and track titles +====================== + + +Q: Does icedax support titles from cd extra (aka cd plus aka enhanced cd)? + +A: In general, yes. In order to get this information, icedax needs to read + a data sector from the second session of the cd. This requires multisession + support and the capability to read XA sectors. The titles are printed on the + screen and written into the inf files, then. + + +Q: Does icedax support titles from cd-text? + +A: Newer versions support the most important features of cd-text like titles + and creators. Non-supported are currently 16-bit characters, so asian + titles etc. are currently not available. + + +Q: Does icedax support CDDB ids? + +A: Yes, while it does not make CDDB lookups itself, it supplies an cddb file + with the table of contents and the cddb id. For cddb lookups see the + perl script tracknames.pl and tracknames.txt. If the titles are known to + icedax, it fills the titles itself in the cddb file. + + +Q: What is the MCN? + +A: The media catalog number is an unique id for the audio cd release. It is + similar to the ISBN for books, but unfortunately it is included only on + some audio cds. + + +Q: What is the ISRC? + +A: The International Standard Record Code is an unique id for a track. Like the + MCN (see above) it is an optional item. + +MP3 coding +========== + + +Q: Does icedax support on-the-fly mp3-coding? + +A: Yes. As of version 1.9alpha I integrated the LAME encoding engine as a new + output format. + To support external encoders, I added two scripts. The trick + is to avoid big temporary files. There are three versions (cdda2mp3.file, + cdda2mp3.pipe, and cdda2mp3.fifo), the first using files, the second uses + pipes, and the last uses a named pipe (also called fifo). The examples + use the Fraunhofer encoder 'l3enc', which is a commercial product and has + to be purchased seperately. Other encoders should be usable in a similar way. + +Conversions +=========== + + +Q: How do I create a file suitable for cd burning? + +A: If you are using wodim, you can produce cdr or wav files. To select + cdr files, use -Ocdr, to select wav files use -Owav (the default). + Audio files that have been recorded with a length not a multiple of the + audio sector size 2352 bytes, should be used with wodim's -pad option. + + +Q: How do I convert a wav file into a cdr file (my other cd burning program + does not accept wav format)? + +A: Use 'dd if=wavfile of=cdrfile conv=swab ibs=44 skip=1 obs=2352' + + +Q: How to convert cdr to wav? + +A: Use sox, the sound utility. It supports other formats as well. + +Specials +======== + + +Q: Does icedax support the pre-emphasis bit? + +A: If the table of contents marks a track as pre-emphasized, the corresponding + inf file will have this information, too. That enables a cd burning program + to retain the state of the track. + + +Q: Can icedax undo the pre-emphasis effect in the samples? + +A: Yes, if the -T option is given (and cd quality is selected), + icedax filters the samples with the reverse emphasis on-the-fly. This has + been checked with a sine sweep from a pre-emphasized test cd. + + +Q: My cdrom delivers the stereo channels swapped. How can I undo this? + +A: Use the -cs option. + + +Q: Does icedax support indices? + +A: Yes, but since there are positioning problems with a lot of drives, + information might be inaccurate. A start index can be specified with the + -i option. To get all indices, use the -v7 option. + + +Q: Can icedax avoid including the pre-gap region at the end of the track? + +A: Currently not. This might be added later, but is not easily done. + + +Q: How can I get all information about the cd without writing files? + +A: Use the -J option, which switches analysis to the max, and aborts after + the report. + + +Q: Can icedax display/save the graphics on my CD+graphics disc? + +A: No, this is not planned. A seperate X11 program could do that probably + better. + + +Q: Can icedax read the audio portion from my CD-I/Video-CD/DVD mpeg streams? + +A: No, these are special formats, which require much more effort. + +User support/feedback +===================== + + +Q: icedax is great. How can I support you to encourage further development? + +A: Look into the file NEEDED. Also constructive criticism and feedback is + appreciated. + + +Q: I want to port cdrkit (wodim/genisoimage/icedax) to a new platform (like + DJGPP,cygwin,os/2). How should I proceed? + +A: It would be convenient to have a unix like environment (like cygwin provides) + A shell, and a make program would be needed to first create smake (in order + to make the makefile system working). Another critical component is autoconf. + Once that is running, os dependent interfaces and the SCSI library should be + adjusted. For the makefile system and the scsi library please contact Joerg + Schilling. + + +Q: icedax sucks. Are there other alternatives available? + +A: Yes, for Linux you might try 'cdparanoia' from Monty (see README file). diff --git a/doc/icedax/Frontends b/doc/icedax/Frontends new file mode 100644 index 0000000..779af6e --- /dev/null +++ b/doc/icedax/Frontends @@ -0,0 +1,34 @@ +This file lists additional free frontend software to be combined with icedax: + +graphical frontends +=================== + +BurnIT (http://sunsite.auc.dk/BurnIT/) + by Jesper Petersen + a Java based frontend for cdrecord and icedax/cdparanoia + +Grip (http://www.ling.ed.ac.uk/~oliphant/grip) + by Mike Oliphant + a GTK+ Frontend for audio extraction and MPEG 1 Layer 3 conversion + (incl. CDDB support) + requires libcdaudio (also by Mike Oliphant) + +Krabber (http://members.tripod.com/~fehlfarben/download.html) + by Adrian Schroeter + a KDE frontend for cdparanoia and MPEG 1 Layer 3 conversion + (incl. CDDB support) + +script frontends +================ + +Cdr Create/Duplicate/Rip (ftp://ftp.burdell.org/pub/) + by David Cantrell + a ncurses based Perl script for CDDA to MPEG 1 Layer 3 conversion + (incl. CDDB support) + requires xmcd + +Ripenc rip encoder (http://www.asde.com/~mjparme/index.htm) + by Michael J. Parmeley + a shell script frontend for CDDA extraction and MPEG 1 Layer 3 + conversion + (incl. CDDB support) diff --git a/doc/icedax/HOWTOUSE b/doc/icedax/HOWTOUSE new file mode 100644 index 0000000..1ab9d77 --- /dev/null +++ b/doc/icedax/HOWTOUSE @@ -0,0 +1,101 @@ +Icedax User guide +================= + +NOTE: expressions in angle braces have to be substituted with + the corresponding numerical values. + For example: <delay in seconds> has to be substituted + with the numerical value to be used. + +Common tasks +============ +NOTE: The examples used here depend on proper default settings for interface +method and devices as specified in the Makefile. They can be overriden with +command line parameters, but here I choose to focus on simple examples. + +Copy complete audio CDs + +1. Copy an audio CD into wav files one per track. + + icedax -B + + will produce the sample wav files (one per track) + audio_01.wav + audio_02.wav + ... + + and the corresponding description files + audio_01.inf + audio_02.inf + ... + +2. Same as above but include MD-5 type signatures + + icedax -B -M<length> + + +3. Same as above but use other file name ('party_cd.wav') + + icedax -B -M<length> party_cd.wav + + +Copy single tracks + +1. Copy one track (eg track 6) into a wav file. + + icedax -t6 + + will produce a wav file including track 6 + + audio.wav + + and + + audio.inf + + +Copy parts of tracks + +1. Copy from given start time to end of track + + icedax -t6 -o<delay in 1/75 seconds> + + will record track 6 starting at track time <delay>/75 seconds + from track beginning upto the end of track. + +2. Copy from given start time and record for a given time + + icedax -t6 -o<delay in 1/75 seconds> -d<time to record in seconds> + + will record track 6 starting at track time <delay>/75 seconds + from track beginning for <time to record in seconds> seconds. + + + +Copy tracks into a pipe + + icedax -t6 -Oraw - | audio_compressor + + will feed the audio samples (in big endian format) of track 6 + into a secondary program audio_compressor. +(See also script cdda2mp3(.new) for a suggestion, how to process all tracks of +an audio cd with a MPEG-Layer3 encoder (not included here).) + + +Miscellaneous + +1. Use icedax as a cd player + + icedax -eN -t6 + + will copy the audio samples into a sound card (if sound card support + is compiled in) and will not write any file. + + + +2. Get complete information on the cd + + icedax -v63 -Nd0.01 + + will try to find out a media catalog number and track related + information (ISRCs) in addition to indices. For CD-Extra discs + limited support exists to retrieve additional information. diff --git a/doc/icedax/NEEDED b/doc/icedax/NEEDED new file mode 100644 index 0000000..361cc29 --- /dev/null +++ b/doc/icedax/NEEDED @@ -0,0 +1,10 @@ +Here I list some things, which would be very helpful for the further +development of cdrtools/icedax, but I currently have no access to. +User support for the acquisition of these items is appreciated :-) + +Access to all 'coloured books' from Philips/Sony +(Red/Yellow/Green/Orange/White/Blue,...). + +CD-extra discs with a lot of features/entries in the data sectors (SUB_INFO*). + +CD-text discs with a lot of features/entries. diff --git a/doc/icedax/OtherProgs b/doc/icedax/OtherProgs new file mode 100644 index 0000000..8c6fa41 --- /dev/null +++ b/doc/icedax/OtherProgs @@ -0,0 +1,2 @@ +dagrab works with ioctls, includes cddb lookups +cdparanoia has sophisticated jitter correction diff --git a/doc/icedax/README b/doc/icedax/README new file mode 100644 index 0000000..4b65532 --- /dev/null +++ b/doc/icedax/README @@ -0,0 +1,549 @@ +Hi dear cdrom drive users, + +This README describes hardware related matters as well as the installation of +icedax, the sampling utility. + +This icedax utility comes with the Cdrkit project. Cdrkit is a spinoff from +cdrtools. However, the cdrtools developers are not involved in the +development of this spinoff and therefore shall not be made responsible for +any problem caused by it. Please do not try to get support for this program by +contacting the original authors. + +Requirements +============ + +For SCSI cdroms and CD-writers, as well as SCSI-emulated ATAPIS and parallel + port drives +1s. kernel support for SCSI, the host adapter, SCSI cdroms and the + generic SCSI interface (if under Linux). You need to have the proper device + descriptors (get them under Linux with the MAKEDEV script from /dev). + +For ATAPI cdroms under Linux +1a. kernel support for the ATAPI cdrom driver or alternatively ide-scsi + emulation. You need to have the proper device descriptors (get them + with the MAKEDEV script from /dev). + +For parallel port cdroms under Linux + With newer kernels icedax uses the same parallel port access + as does wodim. Please refer additionally to the wodim documentation. + There are generally two drivers to access the cdrom through the parallel + port: the ATAPI cd emulation (called pcd), and the SCSI device emulation + (called pg). The pcd driver does NOT support cdda reading (kernel 2.2.12), + while the pg driver has no restriction. So you have to use pg for that. + + +For cdrom drives with proprietary busses under Linux +1p. Please check the CDROM-HOWTO for features of the respective + drivers. The sbpcd driver is very demanding due to the lack of + interrupts. + +optionally currently for Solaris and all platforms running 4fronts +OpenSoundSystems: +2. kernel sound card support. + + +Recommendations for higher throughput on Linux SCSI systems +=========================================================== + +Higher throughput will give better chances for non-interrupted +sampling. This should avoid typical interruption errors (cracklings +at buffer boundaries). + +1. Increase SG_BIG_BUFF to (128*1024) in /usr/src/linux/include/scsi/sg.h + (and recompile your kernel and boot it :-). +NOTE: Some kernel configurations will lead to 'out of kernel memory' errors. + If you encounter this message regularly, better leave SG_BIG_BUFF at + 32768. + +1a.There is a patch for multiple sg device access under Linux. It uses + up to 128 K buffer for each device. See here: +ftp://ftp.fokus.gmd.de/pub/unix/cdrecord/alpha/sg* + +2. Ensure your harddisk has write cache enabled (For SCSI hard disks I + switched it on with the scsiinfo program from tsx-11.mit.edu), but + enable this only if it is correctly working ;-) + +This has boosted the throughput of icedax considerably. + + +Supported interfaces +==================== + +Non SCSI drives (Linux only): + ATAPI: + The greatest group nowadays are ATAPI (EIDE) cdrom drives. + Support is only limited by the drive. Kernel and icedax + are ready for them (unless the drive uses a very uncommon method). + + Newer kernels can do an scsi emulation for ATAPI devices. + This interface is supported. + + Parallel port interface: + There is a driver that maps the parallel port driver to an generic + scsi like driver. Should work with newer kernels. + + Proprietary interfaces: + Older drives with proprietary interfaces are supported only + if the kernel driver allows reading cdda audio data via ioctl(). + Currently only Eberhard Moenkeberg's sbpcd and Corey Minyard's + cdu31a driver do allow this. The sbpcd driver of kernels earlier than + 2.0.30 and 2.1.57 needs a patch before satisfying output can be + obtained (see README.sbpcd). + +SCSI drives: + For these drives the SCSI library from Joerg Schilling is used. + Thus we need kernel support (compiled-in or as a module) for it. + The generic SCSI interface allows multi sector transfers (max. 128 KB) + which lowers cpu load considerably. + + ** NEW ** + I added a script 'scsi_scan.linux' to find the generic devices for all + SCSI CDROM- or WORM-type drives. + +Configuration +============= + +There are some adjustable parameters in the beginning of the Makefile +(which is called local.cnf.in) . They describe default settings of icedax: + +INTERFACE: How the cdrom is accessed. Choose one method for INTERFACE. +DEVICE: The default cdrom device is set in DEF_DEVICE. + +SOUND FILE FORMAT DEFAULTS: +The default format can be 'wav', 'sun pcm au', 'aiff', 'aifc', or +'raw bigendian samples'. +It is determined by the Makefile variable DEF_TYPE. + +AUDIO FILENAME: +The default filename is given by DEF_FILE. Unless 'cdr' format is being used, +this name is appended with '.wav', '.au', '.aiff' or '.aifc'. + +RATE: the default rate is given by setting DEF_UNDERSAMPLING to the divisor +for the audio cd sampling frequency (44100 Hz). + + RATE = 44100 Hz / DEF_UNDERSAMPLING + +DEF_UNDERSAMPLING can be any multiple of a half greater than one half. + +DYNAMIC: The default dynamic range of one sample in one channel is defined in +DEF_BITS which can be one of 8, 12 or 16. + +CHANNELS: set DEF_CHANNELS to 1 for mono and 2 for stereo. + +RECORDING TIME: set DEF_TIME to the amount of seconds to record (or 0 for +the whole track). + +SOUND DEVICE: set SOUND_DEVICE to the device name of your sound card. + The line containing HAVESOUND should be + uncommented also, if you want the option to hear + what you record. + +All of those values can be overridden by command line parameters. + + +Compiling icedax +================== + +Adjust the Makefile (named local.cnf.in) for your cdrom interface and +device setting first. + +Then type + make +and as root + make install + +This will compile icedax and copy the binary to /usr/local/bin and the +man page to /usr/local/man/man1 (defaults). + + +Privileges +========== + +You can setgid the binary, if you want to allow access to a CDROM's +scsi_generic interface for icedax but not for arbitrary programs. +Giving away permissions to send SCSI commands directly to a device is +not something you want to do lightly on a multi-user server system. +The setgid privileges will only be used to access the scsi generic +interface; for cooked_ioctl, the setgid privileges are not necessary +and they are simply dropped. + +Previous versions of icedax had to be setuid to root. Such privileges +are no longer necessary and will be dropped if present. + +Select device +============= + +By default icedax uses the generic SCSI interface and a device tripel for +SCSI bus, id, and lun. +This setting can be overridden by specifying '-Iinterface' and +'-D cdromdevice'. +The following command line example uses the generic_scsi interface and the +SCSI device with bus 1, id 2 and lun 3: +icedax -Igeneric_scsi -D1,2,3 + +The shell script 'scan_scsi.linux' will report the generic devices for +all SCSI cdrom drives. + +If you need to use another interface, check the device setting also as they +need to fit together. +Here is an example for an ATAPI cdrom using the cooked_ioctl interface and +the cdrom device /dev/hdb: +icedax -Icooked_ioctl -D/dev/hdb + + +Features +======== + +I added an optional on-the-fly correction for pre-emphasized samples +(available for original CDDA format only). +If the -T option is given, the samples will be filtered before they +are written to disk. The samples then have a linear frequency response again. + +When recording in mono, both channels are summed with halved amplitude. + +Undersampling is done by summing several samples with reduced amplitude to +prevent overflows. This damps higher freqencies as well. Compared to +exact resampling icedax does not use a very sophisticated (expensive) +filter algorithm. It currently uses quadratic interpolation for +noninteger subsampling factors. + +Sampling can be aborted by pressing the Interrupt-Key (eg control-C) +at anytime. Unless streaming to a pipe, the wav header will be updated +to contain the actual length of the sample. The same will happen, if +disk space becomes exhausted. + +Fast options +============ + +The options can also influence the performance greatly. +The fastest case is given when the samples don't need to be changed from +their original form or analysed, that is the output format uses the same +parameters as the drive: 16-bit samples, stereo at 44100 Hz sample rate +AND with the same endianess (-Cbig and -Ebig, or -Clittle and -Elittle). +To be sure all parameters can be given explicitly on the command line. +This avoids an analysis of icedax. + +icedax -P0 -q -S<maximum speed> +run as root will read with maximum speed and copy its output into the +wav file, taking advantage of realtime scheduling as well. + +For throughput testing the additional option -N can be used. Write +operations will be suppressed then. + +Options that slow down initially +================================ +-v<level> needs some time for analysis before the actual sampling starts + +Options that slow down during sampling +====================================== +-P1 causes overlap reading, the slowdown depends on the amount of jitter +-e synchronous output to a sound card slows down to onefold speed + +Options that need more cpu power +================================ +-p<rate> resamples the output send to the sound card +-M<count> calculates checksums +-T on-the-fly preemphasis filtering +-F checking for extremal samples +-G checking for differences in both channels +-C<endianess> if a conversion is required (see below) +-E<endianess> if a conversion is required (see below) +-Oaudiotype if a conversion is required (see below) +-c 1 +-c s +-m +-b 8 +-b 12 +-a <not 1> +-r <not 44100> + +When are one or two endianess (byte order) conversions required? +================================================================ +There are three stages where the endianess matters: +1.) on the input side the cd drive can deliver in two flavors (called F1). + When the flavor is unknown, icedax needs to find out the endianess. + A simple voting method is used. Successive samples are compared in both + flavors and the flavor with the statistically smaller changes is taken. + The flavor can be defined with the -C option, avoiding the analysis. +2.) For any calculation with samples (and echoing to the sound card), + the samples are needed in the byte order of the machine (in this case + I set 'need_host_order' to yes). The flavor of the machine endianess + is called F2. +3.) Finally, there are two flavors of output sound formats (called F3): + wav uses little endian samples + cdr and au use big endian samples + If the samples currently in memory have the wrong endianess a + (possibly second) conversion is required. + +This gives the following table: +F1 F2 need_host_order F3 conversions +little little no little 0 +little little yes little 0 +little little no big 1 +little little yes big 1 +little big no little 0 +little big yes little 2 +little big no big 1 +little big yes big 1 +big little no little 1 +big little yes little 1 +big little no big 0 +big little yes big 2 +big big no little 1 +big big yes little 1 +big big no big 0 +big big yes big 0 + + +Known problems +============== + +1. Sound quality + +Audible errors caused by hesitations: + +When recording the same audio track twice, recordings can slightly differ. +Furthermore depending on the firmware in the cdrom drive, positioning +errors can be so severe that they cannot be easily corrected by icedax. +This will unfortunately lead to audible errors. + +In this case some overlap or even underlap between successive portions +is introduced from the cdrom drive. +Here is this case demonstrated graphically: + +Sec 1 ... Sec n +|----------------------| first read delivered + |------------------------| second read wanted + |------------------------| second read delivered + |-| extra bogus bytes + |-| missing bytes + +This is due to synchronisation problems between sectors inside the cdrom +drive. When the drive has been forced to wait, these problems arise. + +Audio cds are lacking sector headers, so it's a difficult job to do the +positioning right (in the firmware). The frequency of these errors is +reduced when the reading process can continue undisturbed for longer periods. +So, a high throughput is essential. + +You may want to fine-tune your update daemon to use shorter intervals +(see 'man 8 update'). Shorter intervals are better because the update +interruptions are shorter when not so much write requests can pile up. + +The plextor 4plexplus drive (PX-4XCE) and newer models, newer pioneer +models as well as CD-writers with large buffers don't suffer from this +errors. Here the default is to switch off overlap reading. + +If you cannot get good samples from your drives you might consider an +alternative program. Monty's cdparanoia program goes to great lengths +in order to seperate the good bits from the bad ones. + +2. The index scanner has caused timeouts on my toshiba 3401 due to fast + random accesses. + +3. Retrieval of media catalog numbers and International Standard Recording + Codes may fail due to firmware bugs. + +Audio Format Conversion +======================= +Currently wav, sun (au-pcm), Apple/SGI aiff/aifc, and raw formats are supported. + +I try to write correct wav files (little endian samples), but some +cd-writers might swap them, which would result in sort of white noise +instead of the original sounds. icedax has an endianness detector +for these cases, but as for all automatics, it might fail on bizarre samples. + +Hint: icedax can be forced to use a given input endianness with the +-C option (arguments are 'little', 'big' or 'guess'). + +The sun format is a pcm variant, and uses big endian samples. +The other more common sun format with logarithmically scaled samples (au) +is not supported but can be obtained from sox's conversion. + +The raw format is like the sun format except it has no header. I +changed the endianness to big endian samples in order to comply +with popular cd burning software like the wodim program. + +The sound converter 'sox' can be used to obtain other sound formats. +(Note however, that the current sox player and a newer sound driver do not +harmonize well, use the player from the wavplay package instead (available +at sunsite)). + + +Feedback +======== + +Tested patches, any hardware information regarding drives as well as success/ +failure reports are always welcome at heiko@colossus.escape.de. + + +known cdda capable drives +========================= +Check out these web pages for uptodate information: + +<http://www.tardis.ed.ac.uk/~psyche/pc/cdrom/CDDA.html> + +and + +<http://www.anime.net/~goemon/linux-cd/cdda-list.html> + +From a news posting from Björn Wiberg + +> The following table was generated using the CDROM.CFG file from Nero +> v3.0.4.2. +> +> It shows different CD-ROM models and what speeds they can do DAE at. I +> guess the values are "safe ones"; i.e. the speeds at which each drive +> can perform DAE reliably. +> +> A value of "0x" means the drive doesn't support DAE. +> +> For your convenience, the maximum data transfer speed of the drives +> (for reading conventional files and data from the CD-ROM) are also +> included. +> +> Hopefully, this will help some of you who are looking for a good +> CD-ROM drive to choose a model which seems fast enough both for data +> and DAE. +> +> The models which support DAE: +> (Sorted by DAE speed, data speed and model) +> +> CD-ROM model DAE Data Interface +> --------------------------------------------------------- +> PLEXTOR CD-ROM PX-32TS 16x 16x SCSI +> TEAC CD-524E 14x 24x IDE +> CREATIVE CD620E 12x 5x IDE +> MITSUMI CD-ROM FX320S !B 12x 32x IDE +> TEAC CD-532E 12x 32x IDE +> HITACHI CDR-8335 12x 24x IDE +> PIONEER CD-ROM DR-A02S 12x 24x IDE +> TEAC CD-ROM CD-532S 12x 14x SCSI +> PIONEER CD-ROM DR-A12X 12x 12x IDE +> PIONEER CD-ROM DR-U06S 12x 12x SCSI +> PLEXTOR CD-ROM PX-20TS 12x 12x SCSI +> MITSUMI CD-ROM FX120T !B 11x 12x IDE +> PIONEER CD-ROM DR-A04S 11x 32x IDE +> PIONEER CD-ROM DR-U12X 10x 12x SCSI +> HITACHI CDR-8330 9x 24x IDE +> SONY CD-ROM CDU711 9x 14x IDE +> MATSHITA CD-ROM CR-584 9x 12x IDE +> MATSHITA CD-ROM CR-586 8x 32x IDE +> CDM-T531 Ver1.041 8x 18x IDE +> TEAC CD-516E 8x 16x IDE +> TOSHIBA CD-ROM XM-6201TA 8x 16x SCSI +> PLEXTOR CD-ROM PX-12CS 8x 12x SCSI +> PLEXTOR CD-ROM PX-12TS 8x 12x SCSI +> PIONEER CD-ROM DR-U10X 8x 10x SCSI +> SONY CD-ROM CDU611 8x 10x IDE +> FUNAI E285X 8x 8x IDE +> MITSUMI CD-ROM FX810T4!B 8x 8x IDE +> SONY CD-ROM CDU511 8x 8x IDE +> SONY CD-ROM CDU571-Q 8x 8x IDE +> TEAC CD-C68E 8x 8x IDE +> MITSUMI CD-ROM FX400E !B 8x 4x IDE +> HITACHI CDR-8130 7x 16x IDE +> MATSHITA CD-ROM CR-585 6x 24x IDE +> CREATIVE CD2422E MC102 6x 12x IDE +> MATSHITA CD-ROM CR-508 6x 12x SCSI +> IBM PD-1 LF-1195 6x 6x IDE +> PLEXTOR CD-ROM PX-6XCS 6x 6x SCSI +> LITEON CD-ROM LTN301 5x 32x IDE +> LITEON CD-ROM LTN242F 5x 24x IDE +> HITACHI CDR-7930 5x 8x IDE +> ASUS CD-S340 4x 34x IDE +> E-IDE CD-ROM 32X/AKU 4x 32x IDE +> ATAPI CDROM 4x 24x IDE +> LITEON CD-ROM LTN244 4x 24x IDE +> PHILIPS PCA248CD 4x 24x IDE +> TEAC CD-524EA 4x 24x IDE +> LITEON CD-ROM LTN202 4x 21x IDE +> ATAPI CD-ROM DRIVE-24X 4x 20x IDE +> CREATIVE CD2423E NC101 4x 20x IDE +> SAMSUNG CD-ROM SCR-2431 4x 20x IDE +> TAE IL CD-ROM CDD-7240J 4x 20x IDE +> TEAC CD-220E 4x 20x IDE +> CREATIVE CD1620E SL970404 4x 16x IDE +> LITEON CD-ROM LTN262 4x 16x IDE +> TEAC CD-ROM CD-516S 4x 16x SCSI +> ATAPI CD-ROM DRIVE 4x 15x IDE +> BCD 16XA CD-ROM 4x 10x IDE +> MATSHITA CD-ROM CR-506 4x 8x SCSI +> SONY CD-ROM CDU311 4x 8x IDE +> MATSHITA CD-ROM CR-504-J 4x 4x SCSI +> MITSBISH CDRW226 4x 4x SCSI +> SONY CD-ROM CDU625-S 4x 4x SCSI +> SONY CD-ROM CDU-76S 4x 4x SCSI +> SONY CD-ROM CDU77E 4x 4x IDE +> PLEXTOR CD-ROM PX-4XCE 4x 4x SCSI +> SONY CD-ROM CDU55E 4x 2x IDE +> PIONEER CD-ROM DR-U24X 3x 24x SCSI +> LITEON CD-ROM LTN204 3x 21x IDE +> PIONEER CD-ROM DR-A01S 3x 20x IDE +> PIONEER CD-ROM DR-A24X 3x 20x IDE +> FUNAI E295X 3x 16x IDE +> PIONEER CD-ROM DR-U03S 3x 12x SCSI +> BTC 24X CD-ROM SLL24 3x 10x IDE +> PLEXTOR CD-ROM PX-8XCS 3x 4x SCSI +> CyberDrv CD-ROM TW240S 3x 3x SCSI +> COMPAQ CRD-8320B 2x 32x IDE +> LG CD-ROM CRD-8320B 2x 32x IDE +> TOSHIBA CD-ROM XM-6202B 2x 32x IDE +> CREATIVE DVD-ROM DVD2240E 2x 24x IDE +> TOSHIBA CD-ROM XM-6102D 2x 24x IDE +> BTC 16X CD-ROM SLL16 1x 10x IDE +> NEC CD-ROM DRIVE:282 2x 8x IDE +> HITACHI GD-2000 2x 4x IDE +> MATSHITA CD-ROM CR-581 2x 4x IDE +> NEC CD-ROM DRIVE:222 2x 4x SCSI +> MATSHITA CD-ROM CR-8004 2x 2x SCSI +> GoldStar CD-ROM CRD-8240B 1x 24x IDE +> TOSHIBA CD-ROM XM-6102B 1x 24x IDE +> CyberDrv IDE CD-ROM 120D 1x 12x IDE +> I DE CD-ROM TW120D 1x 12x IDE +> NEC CD-ROM DRIVE:464 1x 12x SCSI +> TORiSAN CD-ROM CDR_U112 1x 12x IDE +> TOSHIBA CD-ROM XM-5701TA 1x 12x SCSI +> TOSHIBA CD-ROM XM-5702B 1x 12x IDE +> CyberDrv SCSI CD-ROM 120S 1x 10x IDE +> NEC CD-ROM DRIVE:463 1x 10x SCSI +> COMPAQ DVD-ROM SD-M1002 1x 8x IDE +> MATSHITA CD-ROM CR-583 1x 8x IDE +> NEC CD-ROM DRIVE:462 1x 8x SCSI +> TEAC CD-58E 1x 8x IDE +> OPTICS_S 8622 SCSI 1x 8x SCSI +> TOSHIBA CD-ROM XM-5602B 1x 8x IDE +> TOSHIBA CD-ROM XM-3801TA 1x 7x SCSI +> NEC CD-ROM DRIVE:461 1x 6x SCSI +> IBM CDRM00203 1x 6x SCSI +> TEAC CD-46E 1x 6x IDE +> TEAC CD-56E 1x 6x IDE +> TEAC CD-ROM CD-56S 1x 6x SCSI +> TOSHIBA CD-ROM XM-5502TA 1x 6x IDE +> TOSHIBA CD-ROM XM-3701TA 1x 6x SCSI +> NEC CD-ROM DRIVE:502 1x 4x SCSI +> TOSHIBA CD-ROM XM-1502BN 1x 4x IDE +> TOSHIBA CD-ROM XM-5302TA 1x 4x IDE +> TOSHIBA CD-ROM XM-5401TA 1x 4x SCSI +> TOSHIBA CD-ROM XM-5402TA 1x 4x IDE +> TOSHIBA CD-ROM XM-1502B 1x 4x IDE +> TOSHIBA CD-ROM XM-3501TA 1x 4x SCSI +> TOSHIBA CD-ROM XM-5301TA 1x 4x SCSI +> TOSHIBA CD-ROM XM-5201TA 1x 2x SCSI + +known cdda uncapable drives +=========================== + +Pioneer DRM-602X, DRM-604X +Teac CD-55A (panasonic bus) +Philips CM206/10 serial RS-422 + CM207 + CM226/10 serial RS-422 + CDD462/01 serial RS-422 +Orchid CDS3110 + +Additions to the tables above are welcome. + +and now catch your sounds, +Heiko heiko@colossus.escape.de (Original author) +Changes for the Cdrkit project by Christian Fromme <kaner@strace.org>, Eduard Bloch diff --git a/doc/icedax/THANKS b/doc/icedax/THANKS new file mode 100644 index 0000000..801f7df --- /dev/null +++ b/doc/icedax/THANKS @@ -0,0 +1,36 @@ +Cdda2wav development has been funded by + +Project MODE +http://www.mode.net/ + +and + +Fraunhofer Institut für integrierte Schaltungen (FhG-IIS) +http://www.iis.fhg.de/ + +Code for extraction of ISRC and MCN codes as well as MD5 signatures +has been made possible by their contributions, thanks very much. + +Thanks to Rik Swusten of Plextor Europe for supplying a cd burner +for development. + +Thanks to Ricoh for supplying a cd burner for development. + +Thanks to Sanyo for supplying a Burn-Proof cd burner with documentaion +for development. + +More thanks goto +Joerg Schilling (helped a lot to integrate his SCSI library) +Aaron Newsome (which created an account on his machine for me to do testing) +Christopher Montgomery (aka Monty, for his work on jitter correction) +Zygo Blaxell (a lot of code improvements) +Thomas Niederreiter (extensions for cd-writers) +Piercarlo Grandi (rewrote of cdda2wav's man page) +Stewart Addison (suggestions and a fine web page on cdda) +Leland Olds (the cdda2wav debian maintainer) +Francesco Chemolli (getopt_long patches) + +Thanks to all testers and finally Jim McLaughlin for supplying +the first cdda-reader source code (that got me started). + +Heiko Eißfeldt diff --git a/doc/icedax/TODO b/doc/icedax/TODO new file mode 100644 index 0000000..5fb1fdd --- /dev/null +++ b/doc/icedax/TODO @@ -0,0 +1,41 @@ +improved Indexscan without playing sectors +use C2 pointers to reduce speed +Solaris handling with volumed +SunOS/Solaris and 512 byte sectors?? +setuid.c group ids on WinXP?? + +stabilization: +check all exit codes (exit with error if sync failed) +new ioctl support for Solaris, FreeBSD-3.x, FreeBSD-4.x +find cause of ringbuffer assertions (resource temporarily unavailable) + +new features: +enable hidden (audio) track recording +thread support +more sound support +CDIndex, CDDB lookups +prepare for MP3 inclusion (lame) +cut off silence at start and end of track +interpolation for massive read errors + +internal: +get cache setting/set cache to zero/reset cache size at the end... +maybe add something for pioneer cd drives (spin up problems) +develop a new transport to read cdda sectors with complete subchannels +use index0 optionally to cut off the pregap portion +detect type of hidden track (data/audio) +implement capability to add a global shift +enhance cd text: + increase buffer size + add tab semantics + support 16-bit characters + try fallback read text info from program area + +structural: +plug-in infrastructure + +BeOS: cddbp support, sound support +QNX: realtime support RR-scheduler message, sound support in lconfig Makefiles +OS/2: sound support +cygwin: sound support + diff --git a/doc/icedax/cdda_links b/doc/icedax/cdda_links new file mode 100644 index 0000000..0371896 --- /dev/null +++ b/doc/icedax/cdda_links @@ -0,0 +1,4 @@ +http://www.escape.de/icedax/icedax.html +http://www.geocities.com/SiliconValley/Bay/6893/multi.htm +http://www.mp3.com/cdrom.html +http://www.emi.u-bordeaux.fr/~morel/ diff --git a/doc/icedax/tracknames.pl b/doc/icedax/tracknames.pl new file mode 100755 index 0000000..09f0fcf --- /dev/null +++ b/doc/icedax/tracknames.pl @@ -0,0 +1,245 @@ +#!/usr/local/bin/perl +# A quick perl hack to get rename files pulled in with icedax. +# by billo@billo.com +# +use Socket; +use IO::Handle; +use Env qw(USER); +use strict; +no strict 'subs'; # can't get it to stop complaining about SOCK + +my $state = "header"; + +my $global_album = "Artist / Title"; +my $global_title = "Title"; +my $global_artist = "Artist"; +my @global_tracks = ("") x 100; +my $global_ntracks = 0; + +my @track_offsets = (); +my $disc_id = 0; +my $disc_time = 0; + + +if ($#ARGV != 1) +{ + print "usage: cddbhack.pl CDDBHOST PORT < audio.cddb\n"; + exit 0; +} + +while (<STDIN>) +{ + if ($state eq "header") + { + if (/#\s[\s]*(\d[\d]*)$/) + { + push @track_offsets, $1; + } elsif (/#\s[\s]*Disc length:\s(\d[\d]*)/) { + $disc_time = $1; + $state = "discid"; + } + } elsif ($state eq "discid") + { + if (/DISCID=(\w[\w]*)/) + { + $disc_id = $1; + last; + } + } +} + +my $query_string = "cddb query $disc_id " . ($#track_offsets + 1); +foreach my $offset (@track_offsets) +{ + $query_string .= " $offset"; +} +$query_string .= " $disc_time"; + +print "$query_string\n"; + +my $host = $ARGV[0]; +my $port = $ARGV[1]; + +my $iaddr = inet_aton($host); +my $paddr = sockaddr_in($port, $iaddr); + + +socket(SOCK, AF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "socket: $!"; + +connect(SOCK, $paddr) or die "connect: $!"; + +autoflush SOCK 1; + +print "Connected.\n"; + +my ($status, $result) = &resp(\*SOCK); + +if (int($status) != 201) +{ + print "Unexpected status.\n"; + close(\*SOCK); + exit 0; +} + +$host = `hostname`; + +$host =~ s/\n//g; + +&cmd(\*SOCK, "cddb hello $USER $host billo-scan 0.1"); +($status, $result) = &resp(\*SOCK); +if (int($status) != 200) +{ + print "Unexpected status.\n"; + close(\*SOCK); + exit 0; +} + +&cmd(\*SOCK, "$query_string"); +($status, $result) = &resp(\*SOCK); +if (int($status) != 200) +{ + print "Unexpected status.\n"; + close(\*SOCK); + exit 0; +} + +my ($ignore, $cat, $id, @rest) = split (" ", $result); + + + +my $read_string = "cddb read $cat $id"; + +&cmd(\*SOCK, $read_string); +&resp(\*SOCK); +while (<SOCK>) +{ + if (/^\./) + { + # print $_; + # print "last line\n"; + last; + } else { + &process($_); + # print $_; + } +} + +&cmd(\*SOCK, "quit"); +&resp(\*SOCK); + +close(\*SOCK); + +&rename; + +exit 0; + +sub cmd +{ + my ($S, $cmd) = @_; + + print "$cmd\n"; + print $S "$cmd\r\n"; +} + +sub resp +{ + my ($S) = @_; + my ($code, $message); + while (<$S>) + { + if (/^(\d[\d]*)\s.*/) + { + # print "\n$1\n"; + print "$_\n"; + $code = $1; + $message = $_; + last; + } + sleep(1); + } + my @return_array = ($code, $message); + return @return_array; +} + +sub process +{ + my ($line) = @_; + + $_ = $line; + if (/^DTITLE=(.*)$/) + { + $global_album = $1; + $_ = $global_album; + if (m/([^\/][^\/]*)\s\/\s([^\/][^\/\n\r]*)/) + { + $global_artist = $1; + $global_title = $2; + } + print "$global_album\n"; + print "$global_title\n"; + print "$global_artist\n"; + return; + } + if (/^TTITLE(\d[\d]*)=(.*)$/) + { + my $track = $1 + 1; + if ($track > $global_ntracks) + { + $global_ntracks = $track; + } + $global_tracks[$track] = sprintf ("%s-%02d-%s", $global_title, + $track, $2); + $global_tracks[$track] =~ s/\s$//g; + $global_tracks[$track] =~ s/'//g; + $global_tracks[$track] =~ s/\s/_/g; + $global_tracks[$track] =~ s/:/_/g; + $global_tracks[$track] =~ s/\?//g; + $global_tracks[$track] =~ s/\*//g; + $global_tracks[$track] =~ s/\\/_/g; + $global_tracks[$track] =~ s/\s/_/g; + $global_tracks[$track] =~ s/\//_/g; + print "Track match " . $global_tracks[$track] . "\n"; + } +} + +sub rename +{ + my $i = 1; + + for ($i = 1; $i <= $global_ntracks; $i++) + { + my $track_name = $global_tracks[$i]; + if ($track_name ne "") + { + my $file_name = sprintf("audio_%02d.wav", $i); + my $new_file_name = sprintf("$track_name.wav", $i); + + my $mv_cmd = "mv '" . $file_name . "' '" + . $new_file_name . "'"; + print "$mv_cmd\n"; + `echo $mv_cmd >> rename.sh`; + } + } +} + +sub unrename +{ + my $i = 1; + + for ($i = 1; $i <= $global_ntracks; $i++) + { + my $track_name = $global_tracks[$i]; + if ($track_name ne "") + { + my $file_name = sprintf("$track_name.wav", $i); + my $new_file_name = sprintf("audio_%02d.wav", $i); + + my $mv_cmd = "mv '" . $file_name . "' '" + . $new_file_name . "'"; + print "$mv_cmd\n"; + `echo $mv_cmd >> unrename.sh`; + } + } +} + + diff --git a/doc/icedax/tracknames.txt b/doc/icedax/tracknames.txt new file mode 100644 index 0000000..9a94e66 --- /dev/null +++ b/doc/icedax/tracknames.txt @@ -0,0 +1,34 @@ +Date: Fri, 2 Oct 1998 16:58:15 -0400 +From: Bill O'Donnell <billo@billo.com> +To: heiko@colossus.escape.de +Subject: CDDB/icedax quick lookup utility + + +Hello, I just started using icedax to capture CD audio on Linux. +It's working great on my 2.0.22 kernel with NEC CD-ROM DRIVE:273 (ATAPI). + +Anyway, I noticed that you're dumping out cddb query info, but not +doing the query yet, so I hacked a quick perl program to do it. + +If you run with a default extraction like this: + + icedax -B -D /dev/hda + +then run the program included something like this: + + cddbhack.pl ma.us.cddb.com 8880 < audio.cddb + +It looks up the names, and creates a file "rename.sh" which can be +used to rename all the audio_XX.wav files to a nice name. + +Anyway, thought you might find it useful, feel free to include in your +next beta distribution or not. Sorry if I made any stupid perl +mistakes, I only just learned it last week. I would have done it in C +or python but I need to learn perl for another job... + +Cheers, + +-billo + +Bill O'Donnell Independent Software Developer +billo@billo.com http://www.billo.com diff --git a/doc/plattforms/README.aix5l b/doc/plattforms/README.aix5l new file mode 100644 index 0000000..8c697d7 --- /dev/null +++ b/doc/plattforms/README.aix5l @@ -0,0 +1,16 @@ +Cdrkit can be built on AIX 5 using the following instructions. Note that the +SCSI transport has not been tested yet because of missing hardware. + + - install cmake either from source or from binaries downloadable on cmake.org. + Make sure the cmake is in your PATH and it can find its modules. + - GCC compiler (available on gcc.org) is recommended, however the native xlc + compiler should work as well. + +Follow instructions from the INSTALL file. + +If you installed a local version of GNU libiconv and ld is confused and spews +linking errors related to .libiconv, check the linker paths with +"cmake -LA build | grep lib". Probably your local path is not listed there and +you may need to set LDFLAGS make variable. See INSTALL file for details. + + -- Eduard Bloch -- Sun, 26 Nov 2006 23:06:25 +0100 diff --git a/doc/plattforms/README.freebsd b/doc/plattforms/README.freebsd new file mode 100644 index 0000000..6e51a30 --- /dev/null +++ b/doc/plattforms/README.freebsd @@ -0,0 +1,31 @@ +These instructions have been tested with FreeBSD 6.2-PRERELEASE, but +should work on any 6.x release. If you're having trouble (with any +release, not just 6.x), please let us know. + +Building +======== + +You need to have cmake installed. It is available in the ports +collection or from cmake.org. You also need GNU make. It is also in the +ports collection, and can be alternatively obtained from gnu.org. + +Most users have libiconv installed under /usr/local. If you wish to add +support for it (used by genisoimage, and recommended), build with + + gmake CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib + +instead of just plain + + gmake + +Short note on using wodim +========================= + +If you want to use wodim with ATAPI drives, make sure you load the +atapicam module before using wodim. Not even "wodim -scanbus" works +usually if this is not done. The command for loading the atapicam +module is (for root) + + /sbin/kldload atapicam + + -- Lorenz Minder -- Mon Nov 27 23:23:01 CET 2006 diff --git a/doc/plattforms/README.linux b/doc/plattforms/README.linux new file mode 100644 index 0000000..da8f759 --- /dev/null +++ b/doc/plattforms/README.linux @@ -0,0 +1,46 @@ + +Requirements of cdrkit on Linux: + + - Linux kernel 2.4 or newer + - Glibc 2.2 or newer + - libcap library package is required, with development files (headers) + - kernel headers useable with the combination of glibc and kernel, as approved + by the distribution. Do not blindly use random kernel headers, do not + symlink them to /usr/include/linux or /usr/include/asm*. + +Notes about support on Linux: + + - Linux kernel versions between 2.6.8 and 2.6.11 are known to have invasive + SCSI command filtering which makes the use of wodim almost inpossible or + complicated for non-root users. Avoid those kernel versions, unless they + have been patched to disable that filtering. + + - support of generic scsi was limited on 2.4, ie. not available directly with + IDE/ATAPI devices. The ide-scsi driver could be used map ATAPI devices to + SCSI ids, however this driver had other problems. See README.ATAPI for + details. Note that there also the ATAPI:... device access method which uses + deprecated funtionality of kernel 2.4. Don't use it unless it is really + neccessary. The support for it may be removed in future versions of cdrkit. + + - the DMA transfer size is limited with some device controllers and the Linux + kernel 2.6.x (2.6.19 currently) provides no method to retrieve it for + exactly one device. Wodim scans sysfs to retrieve this information, but it + needs to be mounted. Use the ts= option of wodim to limit the transfer size + on problems. + + +Additional comments moved from the wodim.1 manpage (originaly cdrecord.1): + +The sg driver on Linux has several severe bugs: + + - It cannot see if a SCSI command could not be sent at all. + - It cannot get the SCSI status byte. wodim for that reason cannot report + failing SCSI commands in some situations. + - It cannot get real DMA count of transfer. wodim cannot tell you if there is + an DMA residual count. + - It cannot get number of bytes valid in auto sense data. wodim cannot tell + you if device transfers no sense data at all. + - It fetches too few data in auto request sense (CCS/SCSI-2/SCSI-3 needs + >= 18). + + -- Reviewed by Eduard Bloch -- 12/2006 diff --git a/doc/plattforms/README.parallel b/doc/plattforms/README.parallel new file mode 100644 index 0000000..22b9e09 --- /dev/null +++ b/doc/plattforms/README.parallel @@ -0,0 +1,59 @@ +This file is intended to help with ATAPI <-> Parallel Port devices on Linux + +Before you start, read + + http://www.torque.net/parport/paride.html + +Make sure that your parallel port device is set up to EPP mode +from within the BIOS. In many cases it is best to set the PP delay to 0. + +Here is a short explanation how to make the FreeCom Traveller work +in 4x speed on a notebook: + +1.) Set BIOS for parallel port to 'EPP'. + +2.) Load drivers in default mode: + + # modprobe paride + # modprobe <driver for parallel port adaptor> + # modprobe pg + +in case of a FreeCom Traveller this is: + + # modprobe paride + # modprobe friq + # modprobe pg + +3.) Check kernel log for paride messages: + + # dmesg + ... + paride: version 1.04 installed + paride: friq registered as protocol 0 + ... + parport0: PC-style at 0x378 [SPP,PS2,EPP] + parport0: no IEEE-1284 device present. + ... + pg: pg version 1.02, major 97 + pg0: Sharing parport0 at 0x378 + pg0: friq 1.01, Freecom IQ ASIC-2 adapter at 0x378, mode 4 (EPP-32), delay 1 + pg0: CD-R/RW RW8040A, master + ... + +4.) load module again but use different parameters: + 'drive0=IO-Port,Protocol,Unit,Mode,Master/Slave,Delay drive1=...' + if you have only one drive at the parallel port + 'drive0=IO-Port,0,0,-1,-1,Delay' e.g. for Delay = 0: + + # modprobe -r pg + # modprobe pg drive0=0x378,0,0,-1,-1,0 + +5.) Check for optimum delay using for maximum speed using wodim -dummy + +6.) Use the file rc.pp and modify for your needs + +7.) Your CD drive now appears as /dev/pcd? + +Source: README.cdtext from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/doc/plattforms/README.sunos b/doc/plattforms/README.sunos new file mode 100644 index 0000000..6fc3a0d --- /dev/null +++ b/doc/plattforms/README.sunos @@ -0,0 +1,10 @@ + +Cdrkit have been built and partially tested on SunOS 5.8. + +To compile, run "gmake". CMake must be installed (with its modules), the cmake +binary must available in your path. Installing GNU libiconv is also recommended. + +On linking problems with 3rd-party libraries involved, make sure that you have +matching configuration of CFLAGS and LDFLAGS vars. + + -- Eduard Bloch -- Tue, 28 Nov 2006 00:01:47 +0100 diff --git a/doc/plattforms/README.win32 b/doc/plattforms/README.win32 new file mode 100644 index 0000000..1714ed6 --- /dev/null +++ b/doc/plattforms/README.win32 @@ -0,0 +1,31 @@ + +Cdrkit suite can be compiled on Windows XP (Service Pack 2) using cygwin +environment and tools set, available on: + + http://sources.redhat.com/cygwin/ + +and many mirrors. + +To compile on Cygwin, execute setup.exe to install it. You will need to select +cmake, make, libiconv and gcc compiler in the package selection. Also choose +subversion if you wish to fetch the latest development version. + +When done, you can start the Cygwin Shell by the new icon in the Start menu or +on the desktop. Visit cdrkit.org and download a tarball of a recent version and store it under <cygwin_directory>\home\your_user_name. + +Untar the package with tar -z -x -f <tarball>, go into this directory and run +"make", followed by "make install". Ignore messages about clock skew etc. + +NOTE: with some versions of Cygwin or cmake shipped with it, the installation +fails for unknown reason. In this case, you can browse trough the build/ +directory, pick up the .exe files there and read the manpage files in +application directories with the man command ("man wodim/wodim.1"). + +Windows drives are available in paths like /cygdrive/c/, /cygdrive/d/. The +drive IDs can be detected using "wodim -scanbus". See wodim's manpage for +details. + +STANDARD WARNING: test in dummy mode before you really write data to the disks. +Report trouble to Cdrkit maintainers. + + -- Eduard Bloch <blade@debian.org> -- Tue, 12 Sep 2006 10:06:34 +0200 diff --git a/doc/wodim/README.DiskT@2 b/doc/wodim/README.DiskT@2 new file mode 100644 index 0000000..f94e124 --- /dev/null +++ b/doc/wodim/README.DiskT@2 @@ -0,0 +1,67 @@ +New driveropts= option "tattoofile=". Use together with -checkdrive +to write an image of the right size to disk. + + DiskT@2 hints: + + In order to have "DISKTATTOO" listed in the "Driver flags", + the disk currently inserted must be usable for the DiskT@2 feature. + This means that there needs to be enough space on it. + + You need an B&W image with 3744 pixels per line + + Best start with a 3744 x 320 pixel image. + The correct size may be retrieved with + wodim driveropts=tattooinfo -checkdrive + + To get RAW image data: + + - Take 'xv' and save the image in PBM/PGM/PPM (raw) mode + + - use a binary aware (must support unlimited linelength) + editor such as 'ved' and remove the header lines. + These lines look like: + + P5 + # CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) + # CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) + 3744 144 + 255 + + Now you should have (in case of the file above) a file that + has exactly 539136 Bytes. + + - Note that the tattoo image must be left to right flipped + (a mirror image). + +From a hint from "E. Robert Bogusta" <rob23@tmr.com>: + +Take an image, and do: + + djpeg myface.jpg | ppmtopgm | pnmflip -lr | + pnmscale -xsi 3744 -ysi 320 | sed '1,/255/d' >myface.tattoo + +So: + djpeg extracts ppm from a jpeg. Use your favorite other way of getting +this far is you wish. + + ppmtopgm changes color to grey scale + + pnmflip -lr flips left to right, the small image is faster + + pnmscale makes it 3644x320 regardless of starting size. This may make it +look really odd on the CD if it doesn't start off the right size. More on +this after I try it. + + sed strips from the first line to the line containing 255, which is the +last header line. + +Note that it would be better to use the actual height of the applicable image instead +of the maximum value of 320 and it would be even more correct to create an +image that has the right width/height ratio for the target on CD in order +get an undistorted view of the image on CD. + +For best visibility, use black text on light background. + +Source: README.cdtext from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/doc/wodim/README.WORM b/doc/wodim/README.WORM new file mode 100644 index 0000000..d3e2ace --- /dev/null +++ b/doc/wodim/README.WORM @@ -0,0 +1,10 @@ +CD-R drives are anything but WORM drives, but older drives identify themselves +as WORM drives. +A Worm drive is able to write each sector once at any time without preparation. +A CD-R drives is not and never will be able to do this. +However some old drives identify as WORM drives. + +For this reason the SCSI-3 standard tells CD-R drives simply CD drives +with multi media extensions. + + diff --git a/doc/wodim/README.cdrw b/doc/wodim/README.cdrw new file mode 100644 index 0000000..cda86e9 --- /dev/null +++ b/doc/wodim/README.cdrw @@ -0,0 +1,17 @@ +Using CD-RW media Mini Howto FAQ + +CD-RW drives usually support packet writing, but as there +is currently no usable UDF filesystem support you may only use +the simple wodim approach. + +wodim writes to CD-RW media in exactly the same way as it +does with CD-R. + +You may erase a complete disk in preparation to reuse it. +Check the man page entry for the blank= option of wodim. +Not all drives support all blanking modes. Usually +blank=fast or blank=full are working. + +Source: README.cdtext from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/doc/wodim/README.clone b/doc/wodim/README.clone new file mode 100644 index 0000000..4964730 --- /dev/null +++ b/doc/wodim/README.clone @@ -0,0 +1,27 @@ +Hints for how to copy a CD using the clone method: + +Step 1 (read master CD): + + Call "readcd dev=b,t,l -clone f=somefile" and the files + + somefile + and + somefile.toc + + will be generated. + + If the disk contains many sectors that are unreadable by intention, + call "readcd dev=b,t,l -clone -nocorr f=somefile" + + +Step 2 (write copy): + + Call "wodim dev=b,t,l -raw96r -clone -v somefile" + +If wodim complains that your drive does not support -raw96r, but the +drive is able to do clone writing at all, then wodim will propose you +a different write mode that works with the drive. + +Source: README.clone from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/doc/wodim/README.raw b/doc/wodim/README.raw new file mode 100644 index 0000000..4629f66 --- /dev/null +++ b/doc/wodim/README.raw @@ -0,0 +1,71 @@ +Tips for MMC RAW mode writing. + + This allows to do disk at once recording on Philips drives that + do not support SAO. + + You may write audio tracks in RAW mode. There are some new + and most likely transient options: + + -raw16 Write 2352 Bytes sectors + P+Q Subchannel + + -raw96r Write 2352 Bytes sectors + P+W Subchannel (R-W in raw mode) + + -raw96p Write 2352 Bytes sectors + P+W Subchannel (R-W in packed mode) + + NOTE that the MMC standard does not allow -dummy in RAW mode. + There may be drives which allow it but don't bother if it does not work. + + Indices are fully supported in RAW mode. + + MCN & ISRC are not yet supported in RAW mode, they are silently discarded. + + If you find other problems in RAW mode or if you find + new bugs introduced in old write modes, please send a bug report. + + wodim now checks the properties of the writer. If a specific write + mode is not supported by the writer, wodim warns you and makes + a suggestion for a similar alternate write mode. + + With the curent structure of wodim, it is not possible to silently + e.g. change the write mode from -dao to -raw96r + + MMC compliant drives are automatically scanned for supported write modes. + This should help to make wodim work without manual static configuration. + My hope is still to have no need to know all drive properties in + advance, so new drives will continue to work as long as they + are standard compliant enough for wodim. + +EXAMPLES: + + wodim dev=1,0 -v -raw96r *.wav + + will write a audio CD in raw mode using (computed) 2448 byte sectors + with raw P-W subchannels. This works e.g. with Plextor drives. + + + wodim dev=1,0 -v -raw16 *.wav + + will write a audio CD in raw mode using (computed) 2368 byte sectors + with raw P+Q subchannels. This works e.g. with Philips drives. + + + NOTE: The input sector size always is 2352 bytes for audio. + +IMPORTANT: + + - if the drive supports RAW/R96R among with other raw write modes, + use -raw96r + + - if the drive does _only_ supports RAW/R16, use -raw16 + + - ... else if the drive supports RAW/R96P, use -raw96p + + The packed raw mode (RAW/R96P) is buggy in Plextor drives and + the RAW/R16 mode is buggy in TEAC drives. Plextor creates + unreadable disks and TEAC hangs the drive. + + For this reason, it is important to select the raw writing + mode accoding to the notes above. + +Source: README.raw from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> diff --git a/genisoimage/CMakeLists.txt b/genisoimage/CMakeLists.txt new file mode 100644 index 0000000..303ba4d --- /dev/null +++ b/genisoimage/CMakeLists.txt @@ -0,0 +1,70 @@ +PROJECT (MKISOFS C) + +INCLUDE(../include/AddScgBits.cmake) +INCLUDE(../include/AddSchilyBits.cmake) + +INCLUDE_DIRECTORIES(../include ../libhfs_iso ../wodim ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) + +INCLUDE(CheckIncludeFiles) +CHECK_INCLUDE_FILES("magic.h" USE_MAGIC) +IF(USE_MAGIC) + ADD_DEFINITIONS(-DUSE_MAGIC) + SET(MAGICLIBS magic) +ENDIF(USE_MAGIC) + +CHECK_INCLUDE_FILES("pthread.h" USE_PTHREAD) +IF(USE_PTHREAD) + ADD_DEFINITIONS(-DTHREADED_CHECKSUMS) + LIST(APPEND EXTRA_LIBS "pthread") +ENDIF(USE_PTHREAD) + + IF(HAVE_ICONV_H) + ADD_DEFINITIONS(-DUSE_ICONV) + #INCLUDE(CheckLibraryExists) +# CHECK_LIBRARY_EXISTS (iconv "iconv_open(argv[0],argv[0])" "" USE_LIBICONV) +IF(USE_LIBICONV) + LIST(APPEND EXTRA_LIBS "iconv") +ELSE(USE_LIBICONV) +# MESSAGE("No additional libiconv found, maybe not required. If required, change linker flags, see TROUBLESHOOTING in the INSTALL file") +ENDIF(USE_LIBICONV) +ENDIF(HAVE_ICONV_H) + +ADD_DEFINITIONS(-DUSE_LARGEFILES -DABORT_DEEP_ISO_ONLY -DAPPLE_HYB -DUDF -DDVD_VIDEO -DSORTING -DHAVE_CONFIG_H -DUSE_LIBSCHILY -DUSE_SCG -DJIGDO_TEMPLATE) + +SET(MKISOFS_MOST_SRCS apple.c boot.c desktop.c dvd_file.c dvd_reader.c eltorito.c exclude.c files.c fnmatch.c hash.c ifo_read.c joliet.c mac_label.c match.c multi.c name.c rock.c scsi.c stream.c tree.c udf.c vms.c volume.c write.c boot-alpha.c boot-hppa.c boot-mips.c md5.c jte.c rsync.c boot-mipsel.c endian.c sha1.c sha256.c sha512.c checksum.c ) + +INCLUDE(CheckFunctionExists) +SET(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) +CHECK_FUNCTION_EXISTS("getopt_long" HAVE_GETOPT_LONG) +IF(NOT HAVE_GETOPT_LONG) + LIST ( APPEND MKISOFS_MOST_SRCS getopt.c getopt1.c ) +ENDIF(NOT HAVE_GETOPT_LONG) + + +#SET_SOURCE_FILES_PROPERTIES(${MKISOFS_MOST_SRCS} PROPERTIES ) +LINK_DIRECTORIES(../libhfs_iso ../librols ../libusal ../libunls ../wodim) + +ADD_EXECUTABLE (genisoimage genisoimage.c ${MKISOFS_MOST_SRCS}) +TARGET_LINK_LIBRARIES(genisoimage wodimstuff hfs_iso ${MAGICLIBS} c unls z bz2 ${EXTRA_LIBICONV} ${EXTRA_LIBS}) + +# common lib set and genisoimage source parts for the rest +LINK_LIBRARIES(wodimstuff ${EXTRA_LIBS} unls ${EXTRA_LIBICONV} ) +ADD_EXECUTABLE(devdump diag/dump.c scsi.c) +ADD_EXECUTABLE(isodebug diag/isodebug.c scsi.c) +ADD_EXECUTABLE(isodump diag/isodump.c scsi.c) +ADD_EXECUTABLE(isoinfo diag/isoinfo.c scsi.c) +ADD_EXECUTABLE(isovfy diag/isovfy.c scsi.c) + + +SET_TARGET_PROPERTIES(genisoimage devdump isodebug isodump isoinfo isovfy PROPERTIES SKIP_BUILD_RPATH TRUE) + +INSTALL(TARGETS genisoimage devdump isodebug isodump isoinfo isovfy DESTINATION bin) +INSTALL(FILES +genisoimage.1 +diag/devdump.1 +diag/isodebug.1 +diag/isodump.1 +diag/isoinfo.1 +diag/isovfy.1 +DESTINATION ${MANSUBDIR}/man1) +INSTALL(FILES genisoimagerc.5 DESTINATION "${MANSUBDIR}/man5") diff --git a/genisoimage/COPYING b/genisoimage/COPYING new file mode 100644 index 0000000..946cb19 --- /dev/null +++ b/genisoimage/COPYING @@ -0,0 +1,345 @@ + The GPL below is copyrighted by the Free Software + Foundation, but the instance of code that it refers to (the mkisofs + utility is copyrighted by Yggdrasil Computing, Incorporated). + +---------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/genisoimage/ChangeLog b/genisoimage/ChangeLog new file mode 100644 index 0000000..681a6ce --- /dev/null +++ b/genisoimage/ChangeLog @@ -0,0 +1,3866 @@ +****** Version 2.01 ****** + +Wed Sep 8 20:28:58 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.47 + * isovfy.c 1.23 + * dump.c 1.21 + * isodebug.c 1.9 + * isodump.c 1.24 + * mkisofs.c 1.161 + Version -> 2.01 + +Thu Sep 2 13:05:11 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.108 + -D Hinweis auf ISO9660:1999 + +Mon Aug 30 12:24:17 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.107 + ISO-9690 -> ISO-9660 + +Tue Aug 24 19:21:54 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.85 + Intermediate Cast auf (void *) damit GCC nicht wegen "strict-aliasing rules" meckert + +Tue Aug 3 21:21:54 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.106 + Hinweis auf Bugfix fuer -no-split-symlink-components / -no-split-symlink-fields + +Sat Jul 31 17:11:30 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.105 + Schreibfehler beseitigt + +Sat Jul 17 23:42:14 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.104 + * mkisofs.c 1.160 + Version -> 2.01a34 + -volset-size ist nun auf 1 begrenzt + +Sun Jul 11 18:30:27 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.159 + Fehlermeldung bei -L/-H/-P weis nun korrekt auf 2.02 hin + +Sun Jul 11 02:03:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.158 + -> NEED_O_BINARY + +Fri Jul 9 17:34:41 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.157 + Version -> 2.01a33 + +Fri Jul 9 16:06:36 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.14 + * write.c 1.84 + static -> LOCAL + EXPORT + +Fri Jul 9 15:32:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.83 + 'VIDEO_TS' wird jetzt immer gefunden und mkisofs bricht ab wenn es nicht gefunden werden konnte und -dvd-video + +Fri Jun 18 11:17:08 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.18 + Nachdenken ueber Speedup + +Thu Jun 17 12:25:43 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.156 + Version -> 2.01a32 + +Thu Jun 17 11:22:11 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dump.c 1.20 + * isodump.c 1.23 + For Schleife ohne strlen() in Ende Bedingung + +Sat Jun 12 16:15:16 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.82 + sprintf() zur besseren Geschwindigkeit beim Erzeugen von 8.3 Filenamen in sort_n_finish() vermeiden + +Mon Jun 7 13:02:01 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.103 + Dokumentation der maximalen Stringlaenge der Eintraege im PVD nun auch bei den Optionen + +Sat Jun 5 16:48:02 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.102 + * mkisofs.c 1.155 + Optionen -H/-L/-P sind veraltet und werden mit 2.02 POSIX.1-2001 konform + +Tue Jun 1 18:27:04 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.154 + Version -> 2.01a31 + +Tue Jun 1 16:53:24 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.81 + Bei DJGPP auch alle Files eXecutable machen. + +Tue Jun 1 16:52:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.153 + load_nls("cp437") per Default auch fuer DJGPP + +Tue Jun 1 16:51:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.18 + SYSTEM_ID -> DOS fuer DJGPP + +Tue Jun 1 16:50:58 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.46 + setmode(fileno(stdout), O_BINARY) beim Extrahieren von Dateien nach STDOUT + +Tue Jun 1 14:07:06 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isodebug.c 1.8 + Funktionen moeglichst LOCAL + +Tue Jun 1 13:50:50 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dump.mk 1.4 + * dump.c 1.19 + * isoinfo.8 1.7 + * isodump.c 1.22 + * isoinfo.mk 1.5 + * isodump.mk 1.4 + * isovfy.mk 1.4 + * isovfy.c 1.22 + * isodebug.mk 1.2 + * isodebug.c 1.7 + Umstellung auf libusal + +Sat May 29 17:46:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.45 + cdr_defaults() nur mit libusal rufen + +Sat May 29 16:55:08 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isodebug.c 1.6 + Version -> 2.01a31 + Cstyle + +Fri May 28 13:51:13 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.44 + Support fuer cdr_defaults() (/etc/default/cdrecord) neu + +Fri May 28 13:39:35 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.43 + Cstyle + +Fri May 28 13:37:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.42 + Version -> 2.01a31 + Umbau auf libusal + +Fri May 28 13:36:25 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isodump.c 1.21 + * isovfy.c 1.21 + Version -> 2.01a31 + Cstyle + +Fri May 28 01:09:55 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dump.c 1.18 + Version -> 2.01a31 + Cstyle + +Thu May 27 01:54:59 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.94 + scsi.c Prototypen -> scsi.h + +Thu May 27 01:54:31 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.h 1.1 + date and time created 04/05/27 00:54:31 by joerg + +Sun May 23 23:46:05 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.32 + Debug Messages beseitigt + +Sun May 23 23:23:27 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.101 + * tree.c 1.80 + * eltorito.c 1.31 + * match.h 1.9 + * mkisofs.c 1.152 + * match.c 1.18 + Version -> 2.01a30 + Eltorito Boot Images per Default nach Vorne Sortieren + +Thu May 20 13:38:31 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.30 + Copyright J. Schilling neu + +Thu May 20 13:33:59 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.29 + Keine Ausgabe der Bootmethode bei mkisofs -quiet + +Sat May 15 22:25:17 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.151 + Version -> 2.01a29 + Hinweis auf unerwuenschte SILO Optionen + +Sat May 15 21:48:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.82 + Neuer Kommentar damit SuSE keine sinnlosen Patches anbringt + +Sat May 15 21:05:49 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.41 + Version -> 2.01a29 + +Sat May 15 19:59:40 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.66 + * mkisofs.c 1.150 + * isoinfo.c 1.40 + GCC shadowed Variblen beseitigt + +Thu Apr 15 16:33:41 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.149 + Version -> 2.01a28 + +Thu Apr 15 16:30:40 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.17 + isoname_endsok() neu zum besseren Vergleich von ISO-9660 namen + +Thu Apr 15 14:51:22 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.16 + * udf.c 1.14 + Cstyle + +Wed Apr 14 12:55:56 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.81 + Schreibfehler beseitigt (Initial Padbock) + +Tue Apr 6 12:30:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.79 + Fix fuer doppeltes Free von Juergen Keil + Absturz durch: + echo bar >/tmp/bar + echo foo/bar=/tmp/bar > /tmp/pathlist + env LD_PRELOAD=libumem.so.1 UMEM_DEBUG=default UMEM_LOGGING=transaction mkisofs -hfs -graft-points -o /tmp/foo.raw -path-list=/tmp/pathlist + +Tue Apr 6 11:57:30 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.78 + beruecksichtigung des Null Bytes beim malloc() fuer die Datei TRANS_TBL + +Sun Apr 4 20:24:38 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.65 + Bessere Fehlermeldung bei multi Session mit volset size > 1 + +Mon Mar 15 15:43:58 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.17 + "SCO-OPENSERVER"/"SCO-UNIXWARE", Default ist nun "UNIX" statt "LINUX" + +Fri Mar 5 00:22:28 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.148 + Version -> 2.01a27 + +Fri Mar 5 00:12:50 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.9 + * match.c 1.17 + * name.c 1.28 + * scsi.c 1.19 + * stream.c 1.3 + * files.c 1.12 + * exclude.c 1.9 + * dvd_reader.c 1.3 + * eltorito.c 1.28 + * ifo_read.c 1.5 + * dvd_file.c 1.3 + * desktop.c 1.6 + * apple_driver.c 1.6 + * vms.c 1.9 + * volume.c 1.13 + Cstyle + +Thu Mar 4 22:47:39 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.64 + * mkisofs.h 1.93 + * mkisofs.c 1.147 + * mkisofs.8 1.100 + Neue Optionen -root & -old-root von Patrik Ohly + +Thu Mar 4 22:40:24 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.8 + Korrektur fuer PREP/CHRP Erweiterung + +Tue Mar 2 00:54:16 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fnmatch.h 1.4 + * exclude.h 1.3 + * diskmbr.h 1.2 + * defaults.h 1.16 + * bootinfo.h 1.3 + * apple.h 1.7 + * apple.c 1.19 + * ifo_read.h 1.2 + * ifo_types.h 1.2 + * iso9660.h 1.19 + * mac_label.h 1.3 + * mactypes.h 1.3 + * match.h 1.8 + Cstyle + +Tue Mar 2 00:50:27 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dvd_reader.h 1.2 + Cstyle + +Mon Mar 1 12:05:40 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * vms.h 1.3 + * udf.h 1.2 + * udf_fs.h 1.2 + Cstyle + +Sun Feb 29 17:53:16 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.39 + Eltorito Boot mit -d anzeigen + Extension Records fuer lange RR Namen korrekt anzeigen + +Sun Feb 29 17:20:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.h 1.2 + * write.c 1.80 + * mkisofs.c 1.146 + * mkisofs.h 1.92 + * mac_label.c 1.7 + CHRP Support von "Leigh Brown" <leigh@solinno.co.uk> + +Sun Feb 29 16:49:18 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.42 + * multi.c 1.63 + }; in Funktionen -> } + +Sun Feb 29 16:43:37 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.62 + Korrekte Behandlung von CE Extension Records fuer RR NM & fue rTime Stamps + +Wed Feb 25 00:16:47 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.13 + Support fuer rationalize_uid/rationalize_gid + +Sun Feb 22 16:27:28 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.145 + Version -> 2.01a26 + Mb -> MB + +Sun Feb 22 16:26:26 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.41 + gen_xa_attr(mode_t attr) ANSI C Variante wegen aelteren UNIX Versionen mit mode_t == short + +Sun Feb 22 16:25:09 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * boot.c 1.13 + Total extents including sparc boot -> Total extents including %s boot + +Sun Feb 22 16:13:43 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.18 + cdr_defaults() wird nun fuer das SCSI dev= gerufen (/etc/default/cdrecord) + +Wed Jan 7 00:23:46 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.144 + Copyright -> 2004 + +Tue Jan 6 23:53:42 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.143 + Version -> 2.01a24 + +Tue Jan 6 22:37:55 2004 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.77 + Rock Ridge Laengenbehandlung in update_nlink()/increment_nlink() korrigiert (Bugfix) + +Mon Dec 29 14:46:02 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.142 + * boot.c 1.12 + Cstyle Anpassungen + +Mon Dec 29 14:36:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * boot.c 1.11 + Neue Optionen -sunx86-boot & -sunx86-label + +Mon Dec 29 14:35:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.141 + Version -> 2.01a22 + Neue Optionen -sunx86-boot & -sunx86-label + +Mon Dec 29 14:34:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.99 + Neue Optionen -sunx86-boot & -sunx86-label + -sparc-label war vergessen - nun dokumentiert + +Mon Dec 29 13:31:28 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.98 + Kommentar zu SILO in den NOTES + Fehlende backslashes for diversen - Zeichen eingefuegt + +Sun Dec 28 14:46:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sunlabel.h 1.5 + Cstyle Aenderungen + +Sun Dec 28 14:44:50 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sunlabel.h 1.4 + Erweiterungen fuer Solaris x86 Disk Label und fdisk + +Sun Dec 28 14:38:51 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.91 + Cstyle Anpassungen + +Sun Dec 28 14:37:09 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.90 + make_sunx86_label()/scan_sunx86_boot()/sunx86_boot_label() neu + +Sat Nov 29 23:58:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.140 + #include <io.h> fuer setmode(fileno, OBINARY) + #include <io.h> auch fuer DJGPP + +Sat Nov 29 23:11:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.139 + Version -> 2.01a20 + setmode(fileno, O_BINARY) auch fuer DJGPP + +Sun Jul 13 15:42:15 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.79 + * mkisofs.h 1.89 + * mkisofs.c 1.138 + secsize -> osecsize, Version -> 2.01a17 + +Fri Jul 11 11:42:32 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.97 + Schreibfehler + +Thu Jul 10 01:26:47 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.76 + Bessere Meldung bei Stat Buffer Overflow + +Sat Jun 21 14:28:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.137 + Eltorito PVD muss vor direkt nach dem Primaeren PVD kommen -> also vor Enhanced PVD + +Sat Jun 21 14:16:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.16 + Wenn ein TAB nach einem Space im Sort File kommt, dann wird dieses genommen + +Sat Jun 21 14:11:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.96 + Schreibfehler und Formulierungen korrigiert + +Sat Jun 21 14:10:13 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.27 + Schreibfehler bei 'is not the an allowable size' beseitigt + +Tue May 6 19:04:03 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.40 + Fix fuer defekte CE Signaturen bei ../../../ in Symlinks + +Wed Apr 30 01:19:33 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.136 + no_rr nur dann automatisch setzen wenn keine XA Signaturen gefunden wurden + +Wed Apr 30 01:18:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.61 + find_rr() nun mit XA Flag + +Wed Apr 30 01:15:59 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.88 + Rock Ridge Defines neu + +Tue Apr 29 21:22:52 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.78 + Variable secsize neu, struct xa_subhdr neu + +Tue Apr 29 21:20:40 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.87 + Neue Variable secsize + +Tue Apr 29 21:19:13 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.135 + Neue Option -sectype + +Tue Apr 29 01:39:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.134 + -apple bedeutet nicht mehr -r + +Tue Apr 29 01:17:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.75 + insert_file_entry() erzeugt auch XA oder RockRidge Signaturen fuer rsrc Files + +Tue Apr 29 01:06:32 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.77 + Umbau von xfwrite() fuer XA subheader + +Mon Apr 28 01:44:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.95 + Hinwies, dasz -apple nicht mehr -R beinhaltet + +Mon Apr 28 01:36:07 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.37 + * eltorito.c 1.26 + * boot.c 1.10 + * stream.c 1.2 + * udf.c 1.12 + * mkisofs.h 1.86 + Umbau von xfwrite() fuer XA subheader + +Mon Apr 28 01:06:38 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.18 + XA Sektor Subheader Definitionen neu + +Sun Apr 27 15:46:18 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.74 + * eltorito.c 1.25 + generate_rock_ridge_attributes() -> generate_xa_rr_attributes(), if (use_RockRidge) -> if (use_XA || use_RockRidge) + +Sun Apr 27 15:38:59 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.39 + generate_rock_ridge_attributes() -> generate_xa_rr_attributes(), if (!use_RockRidge) goto xa_only; + +Sun Apr 27 15:36:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.85 + generate_rock_ridge_attributes() -> generate_xa_rr_attributes() + +Sun Apr 27 15:35:49 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.133 + Version -> 2.01a12 + +Sun Apr 27 14:09:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * TODO 1.6 + 13.4.2003 HFS > 2 GB + +Tue Apr 15 18:47:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.76 + CD-XA001 Signatur hinzufuegen + +Sun Apr 13 19:05:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.38 + Version -> 2.01a10 + st_size ist unsigned bei ISO-9660, map auf Llong + +Sun Apr 13 01:36:22 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.75 + * tree.c 1.73 + * mkisofs.h 1.84 + Erster Versuch Files bis zu 4 GB zu unterstuetzen + +Sun Apr 13 01:32:15 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * vms.h 1.2 + * vms.c 1.8 + vms_write_one_file() mit off_t size + +Fri Apr 11 19:19:24 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.38 + gen_xa()/gen_xa_attr() neu + +Thu Apr 10 15:38:04 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.17 + Kommentar fuer XA Flags korrigiert + +Thu Apr 10 15:37:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.132 + Version -> 2.01a10, Optionen -XA/-xa neu, Schreibfehler bei -iso-level beseitigt + +Thu Apr 10 15:36:03 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.83 + use_XA neu + +Thu Apr 10 15:34:30 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.74 + Skip XA Record neu + +Sat Apr 5 13:39:51 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.37 + Usage Schreibfehler beseitigt + +Fri Apr 4 23:42:02 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.27 + conv_charset() bei -iso-level 4 fuer 8 Bit Zeichen + +Fri Apr 4 23:41:05 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.37 + statis -> LOCAL, unsigned char -> Uchar + +Fri Apr 4 23:40:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ifo_read.c 1.4 + Umbau um ANSI C Warnungen zu vermeiden + +Sat Mar 29 13:01:43 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.11 + Hinweis auf VIDEO_TS in joliet.c + +Sat Mar 29 12:59:14 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.36 + * write.c 1.73 + #ifdef __STDC__ -> PROTOTYPES, Eingerueckt nach cstyle + +Sat Mar 29 12:43:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.60 + * rock.c 1.36 + #ifdef __STDC__ -> PROTOTYPES + +Thu Mar 27 00:19:50 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.35 + Anpassungen fuer cstyle + +Thu Mar 27 00:05:17 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.34 + Bessere Debug Ausgaben fuer add_CE_entry & Bug Fix fuer Split Symplinks (2 Byte Offsetfehler) + +Tue Mar 25 21:31:29 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * bswap.h 1.2 + * mkisofs.h 1.82 + Eingerueckt nach cstyle + +Tue Mar 25 20:51:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.59 + Eingerückt nach cstyle + +Tue Mar 25 20:48:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.131 + Version -> 2.01a07, Eingerueckt nach cstyle + +Sun Mar 9 13:38:18 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.c 1.6 + FSF Junk Code (#define _NO_PROTO) beseitigt der #include strings.h verhinderte; stattdessen #define getopt __nothing_ + +Thu Mar 6 22:11:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.h 1.3 + * fnmatch.h 1.3 + mconfig.h statt (internem) protoyp.h + +Thu Mar 6 22:03:51 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.h 1.2 + * fnmatch.h 1.2 + Umbau auf prototyp.h & PROTOTYPES statt __STDC__ damit Prototypen korrekt auch bei SCO Unixware gehen + +Thu Mar 6 22:01:40 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dvd_reader.c 1.2 + DVDOpenFile() mit Prototype implementierung wegen SCO cc (enum) + +Sun Mar 2 17:33:16 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.72 + strdup() -> libport + +Sat Mar 1 21:19:56 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.15 + #include match.h nach #include libport.h wegen MAX define in param.h bei Linux + +Sat Mar 1 19:25:08 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.14 + #includ <libport.h> fuer strdup() + +Sat Mar 1 18:56:35 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.58 + *nent -> *nentp & nent + +Sat Mar 1 18:41:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.57 + pnt->assoc schon direkt nach dem Einlesen der direcory zuweisen damit es zuverlaessig funktioniert + +Sat Mar 1 13:00:37 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.36 + Ausgabe der ISO-9660 directory flags + +Sat Mar 1 12:54:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.16 + Definitionen fuer XA attributes neu + +Fri Feb 28 01:32:10 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.72 + * vms.c 1.7 + * mkisofs.c 1.130 + * mkisofs.h 1.81 + strdup() -> libport.h + +Fri Feb 28 01:23:34 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isodump.c 1.20 + * dump.c 1.17 + Umbau auf ttydefs.h und Portabilitaet fuer alte UNIX Versionen ohne termio* + +Sun Feb 23 19:34:23 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.71 + LOCAL statt static & Umbau wegen cstyle + +Sun Feb 23 14:25:55 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.56 + * mkisofs.h 1.80 + Einige Funktionen in multi.c -> LOCAL, Eingerueckt nach cstyle + +Sat Feb 22 21:57:34 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.35 + sort_goof -> jsort_goof + +Sun Feb 16 01:17:25 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple_driver.c 1.5 + Unsinniger Parameter aus comerr() Aufruf beseitigt + +Sat Feb 15 22:05:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.35 + Bei -debug wird nun auch der root directory extent ausgegeben + +Sat Feb 15 22:03:43 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.94 + Padding neu beschrieben (150 Sektoren) + +Sat Feb 15 22:00:28 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.71 + Interpad rundet nur noch auf ein Vielfaches von 16 Sektoren auf + +Sat Feb 15 21:50:27 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * stream.c 1.1 + date and time created 03/02/15 21:50:27 by joerg + +Sat Feb 15 21:01:49 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.79 + * mkisofs.c 1.129 + * udf.c 1.10 + * write.c 1.70 + Umbau auf 150 Sektoren Padding am Ende des FS Images + +Sat Feb 15 13:59:11 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.93 + * mkisofs.c 1.128 + Neue Option -stream-media-size + +Thu Feb 13 09:37:52 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.69 + time_t begun -> EXTERN Freigeben fuer UDF & Stream.c + +Thu Feb 13 09:34:41 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.78 + Definitionen fuer stream.c + +Thu Feb 13 09:33:19 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.9 + Externe time_t begun aus write.c uebernehmen fuer: PDV, LVDESC, File Set Desc, Main Seq + +Mon Feb 10 01:47:19 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.34 + Eingerueckt nach cstyle + +Sun Feb 9 21:49:45 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.8 + Umformatier fuer cstyle + +Fri Feb 7 11:15:06 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.127 + Version -> 2.01a03, Graft-point nodename ist nun [2*PATH_MAX + 1 + 1] grosz + +Tue Jan 28 01:28:37 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * isoinfo.c 1.33 + Erkennung von ISO-9660:1999 + +Tue Jan 28 01:27:23 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.126 + Version -> 2.01a02 + +Tue Jan 28 01:25:58 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.125 + ISO-9660:1998 -> ISO-9660:1999, Schreibfehler bei -pad help beseitigt + +Tue Jan 28 01:25:04 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.68 + Bei ISO-9660:1999 ist der 2. VD ein ISO_VD_SUPPLEMENTARY (war vorher wie PVD) + +Tue Jan 28 01:24:09 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.92 + * iso9660.h 1.15 + ISO-9660:1998 -> ISO-9660:1999 + +Sun Jan 19 20:18:08 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.91 + Warnung vor Suns Eltorito Patch bei -iso-level 4 + +Sun Jan 19 16:19:29 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.26 + Bei relaxed Filenames wird '/' verboten. + +Sun Jan 19 16:00:57 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.90 + * iso9660.h 1.14 + * mkisofs.h 1.77 + * rock.c 1.33 + * mkisofs.c 1.124 + * multi.c 1.55 + * write.c 1.67 + Version -> 2.01a01, Erweiterungen fuer ISO-9660:1998 + +Sun Jan 19 15:55:18 2003 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.70 + Bessere RR overflow Meldung + +Wed Dec 25 15:16:49 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.25 + * files.c 1.11 + * multi.c 1.54 + ctype.h nach schily.h wegen OpenBSD #define EOF Bug + +Tue Dec 24 16:39:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.89 + * isoinfo.8 1.6 + Version -> 2.0 + +Mon Dec 23 18:25:55 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dvd_file.c 1.2 + Support fuer 0 Byte VIDEO_TS/VTS_xx_0.VOB Files + +Mon Dec 16 22:37:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.88 + Umbau auf Berlios & fhg.de + +Sun Dec 15 02:03:20 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.66 + DVD-Video Pad Ausgaben auch ohne DEBUG + +Sat Dec 14 19:03:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ChangeLog 1.22 + -> Version 2.0 + +Sat Dec 14 19:03:09 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * TODO 1.5 + Hints for ISO 9660:1988 + +Thu Dec 12 01:25:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.65 + Consistency check for DVD-Video Pad (<0) + +Thu Dec 12 01:25:01 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ifo_read.c 1.3 + open() with O_BINARY + +Sat Dec 7 21:40:44 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.69 + in #ifdef ABORT_DEEP_ISO_ONLY print a hint for -R/-r and -D + +Sat Dec 7 21:14:50 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.7 + write_udf_file_entries() now ignores de->de_flags & RELOCATED_DIRECTORY + and does not create a broken FS if RR_MOVED exists + +Sat Dec 7 21:02:08 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.64 + * mkisofs.h 1.76 + * mkisofs.c 1.123 + opnt->of_start_extent new for Constistency Check + +Sat Dec 7 20:41:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.87 + Better Documentation for -split-output + +Sat Dec 7 19:37:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.122 + Cast to int forr name_end-name (parameter in %.*s) + +Sat Nov 30 17:10:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.121 + Version -> 2.0 + +Sun Nov 24 12:54:45 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * TODO 1.4 + Open Problems for time past 2.0 + +Sun Nov 24 01:17:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.6 + Patch from Wei DING <ding@memory-tech.co.jp> for UDF Files > 1 GB + +Fri Nov 22 17:32:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.68 + Another attempt to fix mkisofs -f + +Fri Nov 22 17:16:43 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.120 + Disable Joliet for -dvd-video (because of Sort in joliet.c) + -s/-S Warning disabled until 2.1alpha + +Fri Nov 22 17:15:34 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.34 + Make VIDEO_TS.IFO 1st dir entry with -dvd-video + +Sun Nov 17 15:42:19 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.119 + Mark -s/-S as reserved options + +Sat Nov 2 21:41:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.118 + Version -> 1.15a40, Tags in ~/.mkisofsrc have '_' in HFS_* + +Thu Oct 24 22:12:30 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.67 + scan_directory_tree() with new Flag DIR_WAS_SCANNED to avoid double scan + scan_directory_tree() more stable by setting errno = 0 before readdir() + no_scandir = 1 commented out to make mkisofs -f not to omit dir content with symlinks to dies + +Thu Oct 24 22:03:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.75 + #define DIR_WAS_SCANNED new + +Mon Oct 21 19:29:14 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.86 + * tree.c 1.66 + Typo removed + +Mon Oct 21 19:28:25 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.117 + Typo efective -> effective uid + +Sat Oct 5 00:38:01 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.63 + * volume.c 1.12 + * mkisofs.8 1.85 + * mkisofs.c 1.116 + * mkisofs.h 1.74 + Version -> 1.15a36, New Option -hfs-parms for better HFS > 4 GB Support from James Pearson + +Sat Oct 5 00:17:22 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.115 + Version -> 1.15a35, Warning for -L/-P/-H Options in POSIX.1-2001 + +Tue Oct 1 01:13:40 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.62 + * volume.c 1.11 + * mkisofs.8 1.84 + * desktop.c 1.5 + Patch from James for HSFS > 4 GB + +Sat Sep 28 16:55:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.83 + * mkisofs.h 1.73 + * write.c 1.61 + * volume.c 1.10 + Fix from James for 4 GB HFS Support + +Tue Sep 24 15:41:27 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.60 + * volume.c 1.9 + Patches from James to aboert on HFS volume size > 2 GB + +Sun Sep 1 23:59:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.5 + Make sure directories have execute permission in default permissions. + +Sat Aug 10 23:33:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.114 + UDF Filenames may be 255 chars if not using Joliet + +Thu Aug 8 23:48:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.32 + * tree.c 1.65 + Symlink buffer size -> PATH_MAX to avoid Overflow + +Thu Aug 8 23:25:14 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ifo_read.c 1.2 + Comment around Tag past #endif + +Thu Aug 8 23:24:37 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.33 + * mkisofs.8 1.82 + * mkisofs.c 1.113 + * mkisofs.h 1.72 + New Option -joliet-long + +Sun Jul 28 01:29:19 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.71 + Tag past #endif now as comment + +Sun Jul 28 01:28:29 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.59 + Defect Debug printf() with newline in String fixed + +Sun Jul 21 17:36:20 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.81 + -dvd-video Option new + +Sun Jul 21 17:00:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.32 + * write.c 1.58 + * mkisofs.h 1.70 + Pathtable now works wth more than 65535 Dires if all Parent indices are <= 65535 + +Sun Jul 21 16:42:36 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dvd_reader.c 1.1 + date and time created 02/07/21 15:42:36 by joerg + +Sun Jul 21 16:40:43 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ifo_read.c 1.1 + date and time created 02/07/21 15:40:43 by joerg + +Sun Jul 21 16:23:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.18 + * multi.c 1.53 + malloc() -> e_malloc() + +Sun Jul 21 15:51:54 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dvd_file.c 1.1 + date and time created 02/07/21 14:51:54 by joerg + +Sun Jul 21 15:18:47 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * dvd_file.h 1.1 + date and time created 02/07/21 14:18:47 by joerg + +Sun Jul 21 15:16:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.57 + Support for DVD-Video -dvd-video + +Sun Jul 21 14:59:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.112 + * multi.c 1.52 + * tree.c 1.64 + * files.c 1.10 + 1024 -> PATH_MAX + +Sun Jul 21 14:21:02 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.31 + Hack against wrong GCC warning + +Sat Jul 20 17:57:49 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.17 + Function perr() now uses comerr() + +Sat Jul 20 17:54:57 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ifo_types.h 1.1 + * dvd_reader.h 1.1 + date and time created 02/07/20 16:54:57 by joerg + +Sat Jul 20 17:54:56 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ifo_read.h 1.1 + date and time created 02/07/20 16:54:56 by joerg + +Sat Jul 20 17:37:32 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.69 + Enhancements for DVD-Video -dvd-video + +Sat Jul 20 17:28:10 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * bswap.h 1.1 + date and time created 02/07/20 16:28:10 by joerg + +Sat Jul 20 01:17:52 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.4 + DVD-Video comment new + +Sat Jul 20 01:15:19 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.111 + Version -> 1.15a27, Option -dvd-video new + +Sat Jul 20 01:13:31 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.63 + Sort Video Files only with -dvd-video + +Tue Jul 16 21:32:42 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.62 + * mkisofs.c 1.110 + * mactypes.h 1.2 + * mkisofs.8 1.80 + * apple.h 1.6 + * apple.c 1.16 + Support for Apple files on MacOS X + +Thu Jul 4 12:31:42 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.109 + Version -> 1.15a25, verbose > 1 writes debug info for output fragments. + +Thu May 30 01:48:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.3 + * write.c 1.56 + * joliet.c 1.31 + * eltorito.c 1.24 + * boot.c 1.9 + * mkisofs.h 1.68 + of_name in struct output_fragment new + +Mon May 20 13:58:11 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.6 + ISO_ROUND_UP(mac_boot->size) / SECTOR_SIZE -> ISO_BLOCKS(mac_boot->size) + +Mon May 20 13:55:53 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.55 + Unused Var in graftcp() removed + +Mon May 20 13:51:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.67 + HFS_BLOCKS() new + +Tue May 14 21:13:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.54 + graftcp() Bug fixed (simple Filenames as Arg not shortened) + +Mon May 13 00:45:28 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf.c 1.2 + Now using ISO_ROUND_UP()/ISO_BLOCKS()/SEC_SIZE + +Mon May 13 00:40:04 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.53 + * joliet.c 1.30 + Now using ISO_ROUND_UP()/ISO_BLOCKS() + +Mon May 13 00:24:43 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.51 + Now using ISO_ROUND_UP() + +Mon May 13 00:22:40 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.108 + Version -> 1.15a23, Now using ISO_ROUND_UP()/ISO_BLOCKS() + +Mon May 13 00:08:55 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.23 + Now using ISO_BLOCKS() + +Sun May 12 14:42:18 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.66 + Comment for ISO_ROUND_UP(X)/ISO_BLOCKS(X) + +Sun May 12 14:10:20 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.61 + Function filetype() better + +Sun May 12 00:32:18 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.65 + ISO_BLOCKS() new + +Sat May 4 15:31:00 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.50 + file_addr now based on sectors not on bytes to avoid overflow with DVDs + +Fri May 3 01:17:51 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.24 + * mkisofs.c 1.107 + -no-iso-translate now also using '-' + +Sun Apr 28 14:50:15 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.79 + Remove outdated hint that at least one "pathspec" is needed + (even for File from list List) + +Sun Apr 28 14:48:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.106 + Version -> 1.15a22, susage() Bugfix (program_name missing) + +Tue Apr 16 19:19:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.22 + make boot.catalog sortable via -sort + +Sun Apr 14 22:53:26 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.52 + * mkisofs.h 1.64 + * mkisofs.c 1.105 + Avoid to put unwanted information into the version info + +Thu Apr 11 23:53:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.104 + Support for xxx/../yyy in graft-points + +Thu Apr 11 19:27:13 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.60 + * mkisofs.c 1.103 + Fix -graft-points /a/b//.///=some_dir bug (doubled / Dir), Version -> 1.15a21 + +Thu Apr 11 18:55:48 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.78 + UTF comment corrected + +Thu Apr 11 18:55:23 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.63 + debug new + +Wed Apr 3 19:47:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.102 + Version -> 1.15a20 + +Wed Apr 3 19:42:41 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.101 + Corrected file type recognition for graft points + +Wed Apr 3 19:00:32 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.30 + * mkisofs.c 1.100 + * mkisofs.8 1.77 + Transparent compression (-z) from H.P. Anvin integrated + +Wed Apr 3 18:12:07 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.99 + escstrcpy() corrected for multiple '//', new option -debug + +Tue Apr 2 00:57:38 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.98 + short usage added + +Fri Mar 8 16:44:37 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.76 + Hint for multisession on MAC -> -part + +Fri Mar 8 16:43:46 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.5 + Mac Label mpm[mpc].start = session_start + ... -> mpm[mpc].start = hce->hfs_map_size ... + +Tue Feb 26 22:39:16 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * boot.c 1.8 + Support generic boot for CD-extra (session_start != 0 Dreamcast) + +Sun Feb 10 20:18:32 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.15 + use Prototyped function definition if we have dev_t arg because it may be < int + +Sun Feb 10 16:13:16 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fnmatch.c 1.4 + Now using utypes.h, >=/<= compare with Uchar cast + +Sun Feb 10 15:56:51 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.15 + cast info->nlen to int for comparison + +Sat Feb 9 22:21:33 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.14 + strcmp() -> memcmp() for sfm_magic/sfm_version + +Fri Jan 18 12:48:35 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.75 + Write correct size info (1440 kB instead of 1.44 meg) for boot floppy sizes, correct .R typo (used instead of .B) at -magic + +Fri Jan 18 12:47:51 2002 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.21 + Write correct size info (1440 kB instead of 1.44 meg) for boot floppy sizes + +Mon Dec 10 01:05:06 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.74 + -udf option documented + +Mon Dec 10 01:04:38 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.c 1.5 + prototype for my_index() + +Sun Nov 25 12:53:17 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.73 + long unreadable option list removed from sysnopsis line + +Thu Nov 22 22:34:18 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.97 + Version -> 1.15a12 + +Thu Nov 22 22:24:38 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * udf_fs.h 1.1 + * udf.c 1.1 + * udf.h 1.1 + date and time created 01/11/22 22:24:38 by joerg + +Thu Nov 22 16:42:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.10 + * Makefile 1.10 + * mkisofs.c 1.96 + * mkisofs.h 1.62 + Enhancements for UDF support + +Thu Nov 22 16:41:13 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.59 + add sort criteria for UDF VIDEO_TS and AUDIO_TS files. + +Thu Nov 22 16:40:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.29 + make convert_to_unicode()/joliet_strlen() global if UDF support is compiled in + +Thu Nov 22 15:24:44 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.72 + better documentation for README.sort/README.hide from James Pearson + +Thu Nov 22 00:42:31 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.51 + compare_sort() now behaves correctly if the parameters are exchanged so qsort() may sort correctly + +Tue Nov 20 00:55:44 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.71 + better documentation for -print-size, use \& if '.' is at beginning of line + +Tue Nov 20 00:54:35 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.50 + avoid #if defined(sun) || defined(_AUX_SOURCE), better error messages + +Fri Nov 16 18:15:42 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * desktop.c 1.4 + nitialize the whole struct hfsdirent in make_desktop() + +Sun Nov 11 20:38:20 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.h 1.5 + d_dtoutime() Prototype new + +Sun Nov 11 20:28:56 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.h 1.4 + * apple.c 1.13 + Preserves HFS file dates for AppleDouble, AppleSingle and NetaTalk files + +Sun Nov 11 13:38:45 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.29 + QNX Neutrino has no st_ftime + +Sun Oct 21 01:01:23 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.c 1.4 + Try to compensate FSF rubish code and supress warnings by always including standard include files + +Sun Oct 21 01:00:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.95 + Always use local getopt.h, version -> 1.15a09 + +Tue Oct 9 01:27:16 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.61 + sys/types.h & sys/stat.h -> statdefs.h + +Thu May 31 10:56:32 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.70 + -split-output description new, -hard-disk-boot/-no-emul-boot/-no-boot hint added to -b + +Sun Apr 22 11:34:46 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.94 + Comment for memset() in e_malloc() + +Fri Apr 20 23:53:40 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ChangeLog 1.21 + Late changes for 1.14 + +Fri Apr 20 18:46:36 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.49 + Initalize more data from struct directory_record + +Fri Apr 20 18:45:47 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.93 + Always clear allocated memory to avoid uninitialized data. + +Tue Apr 17 00:57:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.69 + Hint to mailman + +Fri Apr 13 23:31:42 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ChangeLog 1.20 + updated to release 1.14 + +Fri Apr 13 20:42:30 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.92 + Version -> 1.14 final + +Fri Apr 13 20:12:50 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.68 + New Support mail Adresses + +Thu Apr 12 19:36:39 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.91 + make insert_file_entry() failure non fatal in mkisofs main code + +Sat Apr 7 17:31:44 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.48 + starting to implement associated files in multi-session + +Sat Apr 7 14:47:49 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.58 + * mkisofs.c 1.90 + No exit() for warnings + +Tue Apr 3 23:33:26 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.9 + * defaults.h 1.15 + APPID_DEFAULT now includes Copyright messages + +Mon Apr 2 23:17:05 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.47 + unused vars removed + +Mon Apr 2 20:09:22 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.89 + Fixed -check-session handling for -C0,0 default, Search for SUSP RR record in '.' of root + +Mon Apr 2 20:05:48 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.67 + New option -force-rr + +Mon Apr 2 20:05:25 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.46 + rr_flags()/parse_rrflags()/find_rr() new, get_session_start() handling for -check-session fixed + +Mon Apr 2 20:04:34 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.60 + rr_flags()/parse_rrflags()/find_rr() new + +Sun Apr 1 21:51:43 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.66 + -check-session new + +Sun Apr 1 21:51:11 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.88 + Parameter for -check-session added to usage + +Sun Apr 1 21:49:56 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.59 + -check-session neu + +Sun Apr 1 19:13:37 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.87 + * multi.c 1.45 + Need to handle -C (cdrecord_data) special if -check-session is set + +Sun Apr 1 17:46:59 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.23 + Back up to last '.' found if trying to find a better '.' did not work + +Sun Apr 1 17:45:17 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.86 + New option -check-session + +Tue Mar 20 01:09:27 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.8 + * mkisofs.h 1.58 + * mkisofs.c 1.85 + * mkisofs.8 1.65 + New options for writable HFS files from James Pearson + +Sun Mar 4 15:13:00 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.64 + Better documentation for -no-cache-inodes + +Sun Mar 4 00:53:59 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.84 + Fix a bug with '-- filename' + +Sun Mar 4 00:52:29 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.63 + * hash.c 1.14 + * mkisofs.h 1.57 + * mkisofs.c 1.83 + new options -no-cache-inodes/-cache-inodes as a workaround for non unique inodes on Cygwin + +Fri Feb 23 21:58:52 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.62 + Einfo for RR_MOVED dir added + +Fri Feb 23 17:33:54 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.12 + set_Dinfo(hfs_info->finderinfo, hfs_ent); -> set_Finfo(hfs_info->finderinfo, hfs_ent); according to James Pearson to make --xinet option work + +Thu Feb 15 23:04:00 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.49 + output_fraagment now copied to allocated space to allow a desc to be used more than once + +Thu Feb 15 23:02:53 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.82 + version -> 1.14a14 + +Thu Jan 25 23:28:32 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.8 + * eltorito.c 1.20 + * apple.c 1.11 + * mkisofs.h 1.56 + * tree.c 1.57 + * write.c 1.48 + changes to support large files + +Tue Jan 23 13:27:44 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.56 + * mkisofs.c 1.81 + * mkisofs.h 1.55 + * write.c 1.47 + * apple.c 1.10 + * rock.c 1.28 + * eltorito.c 1.19 + * joliet.c 1.28 + Avoid gcc -W warnings (e.g. signed/unsigned) + +Sat Jan 20 23:17:37 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.46 + * mkisofs.8 1.61 + * mkisofs.c 1.80 + -quiet make mkisofs really quiet + +Sat Jan 20 23:03:26 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.79 + Modified to allow EBCDIC + +Sat Jan 20 22:46:10 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.60 + * mkisofs.h 1.54 + * mkisofs.c 1.78 + * rock.c 1.27 + * joliet.c 1.27 + * apple.c 1.9 + Better charset tables for Apple + +Fri Jan 19 19:26:19 2001 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.55 + * mkisofs.c 1.77 + * mkisofs.8 1.59 + * mkisofs.h 1.53 + better rationalized uid/gid/modes + +Sat Dec 9 19:55:17 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.8 + u_short -> Ushort, u_int -> Uint + +Sat Dec 9 19:36:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.26 + u_char -> Uchar + +Tue Dec 5 15:25:02 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.7 + * write.c 1.45 + * vms.c 1.6 + * tree.c 1.54 + * rock.c 1.26 + * name.c 1.22 + * multi.c 1.44 + * mkisofs.h 1.52 + * mkisofs.c 1.76 + * match.c 1.13 + * match.h 1.7 + * mac_label.c 1.4 + * joliet.c 1.25 + * hash.c 1.13 + * files.c 1.9 + * exclude.c 1.8 + * eltorito.c 1.18 + * desktop.c 1.3 + * apple_driver.c 1.4 + * boot.c 1.7 + * apple.c 1.7 + Completed conversion to Schily SING autoconfiguration + +Mon Dec 4 12:56:49 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.51 + Now first includes mconfig.h then stdio.h (for largefiles), now uses strdefs.h, standard.h for const abstraction, stdxlib.h instead of stdlib.h + +Mon Dec 4 12:53:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.43 + * scsi.c 1.17 + lseek now using SEEK_* macros + +Mon Dec 4 12:53:11 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.3 + * apple_driver.c 1.3 + * apple.c 1.6 + fseek now using SEEK_* macros + +Fri Dec 1 14:14:23 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.42 + Now working without usal_prbytes() from libusal + +Fri Nov 24 10:49:58 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.75 + -print-size now also prints an easy to parse string to stdout + +Fri Nov 24 10:49:29 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.58 + New -print-size behavior documented + +Sun Nov 19 16:34:56 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.74 + New option -no-pad, -pad now default, support for Cygwin-1.x + +Sun Nov 19 16:33:13 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.7 + Umbau fuer mkhybrid + +Sun Nov 19 16:32:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile.man 1.3 + INSMODE= beseitigt + +Sun Nov 19 13:03:18 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.21 + Special handling for '#' and '~' disabled because the code created infinite dir tree loops + +Sat Nov 4 17:59:36 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.57 + New option -no-pad, -pad now default + +Sat Oct 14 15:33:50 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.56 + hint for CD-Extra usage (-M/-C), note for -graft-points option in examples that need -graft-points + +Fri Sep 8 02:49:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.16 + Call to usal_remote() + +Fri Sep 8 02:49:00 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.73 + Warning for using Joliet without Rock Ridge + +Fri Aug 25 15:31:13 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.12 + * mkisofs.c 1.72 + new-line discarded only if really present + +Mon Aug 14 01:36:38 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.71 + Graft-points repariert fuer esacped = + +Sun Jul 30 14:08:38 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.41 + * scsi.c 1.15 + Modified for new libusal with usal_*() + +Thu Jul 20 19:29:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.70 + Version -> 1.13 + +Thu Jul 20 19:27:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.2 + Size arithmetic fix for HFS vol size + +Thu Jul 20 19:27:12 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.55 + Small typo fixes + +Tue Jun 27 19:12:02 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.69 + * mkisofs.8 1.54 + New option -graft-points + +Tue Jun 27 01:38:35 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.68 + 1.13a02 -> 1.13a03 + +Tue Jun 27 01:31:27 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.67 + allow -path-list option to work without a command line arg, graft pointer escapes haf way ready + +Tue Jun 27 01:20:27 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.11 + better parser for -sort option, avoid buffer overflows by not using fscanf + +Tue Jun 27 01:18:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.53 + Better doc for -sort option + +Mon Jun 26 23:50:33 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple_driver.c 1.2 + Converted for Schily SING makefile system, made portable + +Mon Jun 5 03:19:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.44 + percent output now even works with NO_FLOATINGPOINT + +Sat Jun 3 14:24:26 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.43 + buffer[] -> static in write_one_file() for sake of the silly Metrowerks C found on BeOS/PPC + +Sun May 28 17:41:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.66 + version -> 1.13a02 + +Sun May 28 17:03:48 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.17 + * mkisofs.8 1.52 + * mkisofs.h 1.50 + * mkisofs.c 1.65 + New option -eltorito-alt-boot + +Sun May 28 16:28:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.51 + Integration of mkisofs/mkhybrid to one single application + +Sun May 28 13:21:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.40 + Check for reloc_dir != NULL in match_cl_re_entries() + +Sun May 7 17:23:57 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.10 + * scsi.c 1.14 + * boot.c 1.6 + * eltorito.c 1.16 + * name.c 1.20 + * joliet.c 1.24 + * multi.c 1.39 + * rock.c 1.25 + * hash.c 1.12 + * write.c 1.42 + * tree.c 1.53 + * mkisofs.c 1.64 + #include <schily.h> + +Sun May 7 17:14:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.63 + Release -> 1.13a01, removed comment for associated files as it has been wrong + +Thu Apr 27 14:11:30 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * RELEASE 1.31 + Release 1.12.1 + +Thu Apr 27 14:06:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.50 + New Opton -root-info, typo's corrected + +Thu Apr 27 13:54:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.5 + cast for correct char * / unsigned char * handling + +Thu Apr 27 13:36:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.6 + * apple.h 1.3 + * desktop.c 1.2 + * apple.c 1.4 + Major changes to implement new HFS option -root-info and -jcharset mac-roman + +Thu Apr 27 12:47:26 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.6 + New file place sorting option activated with -DSORTING + +Thu Apr 27 12:46:35 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * ChangeLog 1.19 + updated to release 1.12.1 + +**************** Release 1.12.1 ******************* + +Thu Apr 27 12:44:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.52 + * rock.c 1.24 + * mkisofs.h 1.49 + * mkisofs.c 1.62 + New HFS option -root-info + +Fri Apr 21 22:11:17 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.41 + better double conversion for estimation time computation + +Fri Apr 21 22:04:56 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.19 + Name trucation warning removed because it does not work. + +Fri Apr 21 18:37:36 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.18 + * mkisofs.h 1.48 + * mkisofs.c 1.61 + * mkisofs.8 1.49 + -max-iso0660-filenames + +Fri Apr 21 18:09:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.51 + Creating unique filenames now works even if we are creating 37 char names + +Thu Apr 20 22:14:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.50 + Make TRANS.TBL wider to allow 37 char iso names, avoid hard coded values + +Thu Apr 20 21:44:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.38 + Parsing of TRANS.TBL now adaptive instead of using hard coded numbers + +Wed Apr 19 23:59:22 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.49 + * multi.c 1.37 + * iso9660.h 1.13 + MAX_ISONAME fom 38 -> 37 + +Tue Apr 18 16:22:56 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.5 + Use HFS_FNDR_ISINVISIBLE for dirs too + +Tue Apr 18 16:20:03 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.17 + * tree.c 1.48 + * multi.c 1.36 + * mkisofs.h 1.47 + * mkisofs.c 1.60 + * mkisofs.8 1.48 + Removed Option -all-files, New options -iso-level, -allow-lowercase, -allow-multidot, -relaxed-filenames, -use-fileversion, name.c completely rewritten + +Sun Apr 16 16:30:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.47 + * name.c 1.16 + * mkisofs.h 1.46 + * mkisofs.c 1.59 + New Option -no-iso-translate + +Sun Apr 16 16:26:37 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.46 + New Options -sort & -ucs-level + +Sun Apr 16 15:24:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.14 + * mkisofs.h 1.45 + * multi.c 1.35 + Copyright Schilling added + +Sun Apr 16 15:22:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.12 + struct iso_ext_attr_record new + +Sun Apr 16 14:47:53 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.23 + * mkisofs.h 1.44 + * mkisofs.c 1.58 + New Option -ucs-level + +Sun Apr 16 14:12:24 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.43 + * mkisofs.c 1.57 + * tree.c 1.47 + * hash.c 1.11 + * write.c 1.40 + New sort code from James Pearson + +Sun Apr 16 13:39:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.h 1.6 + * match.c 1.9 + Converted to unified match code, new sort match code + +Sat Apr 15 21:59:15 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.4 + Apply ISO Hidden flag to files on HFS volume too + +Sat Apr 15 20:57:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.15 + Handle '.' and '..' entries corretly in iso9660_check() + +Wed Apr 12 23:56:56 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.45 + New option -check-oldnames + +Wed Apr 12 23:44:18 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.3 + strcasecmp() local implementation + +Wed Apr 12 23:24:10 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.5 + HFILES added to get better ctags + +Wed Apr 12 23:23:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.34 + * name.c 1.14 + * mkisofs.h 1.42 + * mkisofs.c 1.56 + New Option -check-oldnames, new function iso9660_check() to check/repair filenames from old session, better error messages for bad RR attributes, avoid coredump with calling memset with negative count. + +Tue Apr 11 10:50:04 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.11 + * tree.c 1.46 + iso_directory_record now uses MAX_ISONAME (38) old was 34 + +Sun Apr 9 22:04:42 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.33 + Better error messages for bad XA disks. + +Sun Apr 9 17:06:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.55 + Version -> 1.12.1a06, corrected help for -l (30 chars!) + +Sun Apr 9 17:05:47 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.45 + Put number to make names unique before the dot to retain the suffix + +Sun Apr 9 14:28:01 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.44 + some more curly brackets.... + +Sat Apr 8 23:51:20 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.54 + removed duplicate OPTION_H_LIST + +Sat Apr 8 23:44:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.44 + * tree.c 1.43 + * mkisofs.c 1.53 + * match.c 1.8 + * mkisofs.h 1.41 + * match.h 1.5 + New option -hidden & -hidden-list to implement hidden (ISO existence flag) files + +Sat Apr 8 23:32:45 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.43 + better padding documentation (-pad) + +Sat Apr 8 20:55:49 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.42 + added description for mkhybrid + +Sat Apr 8 20:50:47 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.41 + add \ before some - signs and mark some mkisofs places with \& to prevent repleacement with sed script + +Sat Apr 8 19:40:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.40 + typo correction and preparation towards unified manual (mkisofs/mkhybrid) + +Sat Apr 8 16:05:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.3 + * write.c 1.39 + * tree.c 1.42 + * multi.c 1.32 + * joliet.c 1.22 + * eltorito.c 1.15 + * iso9660.h 1.10 + * mkisofs.h 1.40 + Now using iso directory flag definition from iso9660.h + +Mon Apr 3 23:59:05 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.31 + Minor clean up, Message about XA records + +Mon Apr 3 23:40:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.39 + * match.c 1.7 + * exclude.c 1.7 + indented + +Mon Apr 3 21:06:04 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.14 + insert_boot_cat() prototype + +Mon Apr 3 02:22:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.41 + * write.c 1.38 + * mkisofs.c 1.52 + * rock.c 1.23 + * name.c 1.13 + * joliet.c 1.21 + * hash.c 1.10 + * files.c 1.8 + * eltorito.c 1.13 + * vms.c 1.4 + indented + +Mon Apr 3 00:38:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.40 + * multi.c 1.30 + parse_xa() new to skip XA extended directory attributes + +Sun Apr 2 22:24:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.38 + * write.c 1.37 + version_desc new + +Sun Apr 2 21:15:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.51 + version desc new + +Sun Apr 2 20:28:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * vms.c 1.5 + eric -> joerg + +Sun Apr 2 19:10:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.9 + struct iso_xa_dir_record new + +Sun Apr 2 19:01:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.20 + stdlib.h -> stdxlib.h, rtmp, ltmp (short -> char[2]) for correct byteorder handling + +Sun Apr 2 18:14:35 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * files.c 1.7 + Typo correction + +Sat Apr 1 22:29:29 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.8 + Indented + +Fri Mar 31 18:50:41 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.2 + New function set_cusstom_icon() + +Fri Mar 31 18:48:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.h 1.2 + * apple.c 1.2 + sys/param.h removed, MAXPATHLEN -> PATH_MAX for portability + +Fri Mar 31 18:44:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.19 + Now sort joliet tree according to Unicode order + +Fri Mar 31 18:38:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.39 + * write.c 1.36 + * mkisofs.h 1.37 + * mkisofs.c 1.50 + New option -pad + +Fri Mar 31 12:59:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.38 + -jcharset implies -J + +Fri Mar 31 12:55:30 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.49 + hfs_ct var new, -hfs-creator typo in option parsing fixed + +Thu Mar 30 02:47:14 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.48 + 1.8.1a04 -> 1.8.1a05, -icon-position option needs no argument, -jcharset now implies -J + +Thu Mar 30 02:43:18 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.36 + #include limits.h for NAME_MAX, PATH_MAX definition new + +Wed Mar 29 10:33:45 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c.bak 1.1 + date and time created 00/03/29 09:33:45 by joerg + +Sun Mar 26 18:44:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.37 + Better doc for -jcharset + +Sun Mar 26 18:40:23 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.47 + Unicode mapping now defaults to iso8859-1 resp. cp437 + +Sun Mar 26 18:31:24 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.46 + * defaults.h 1.13 + defined(__CYGWIN__) added for Cygwin recognition + +Sat Mar 25 17:10:43 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.36 + * joliet.c 1.18 + * Makefile 1.4 + * mkisofs.c 1.45 + Joliet character translation using different character sets (-jcharset) + +Sun Mar 19 20:08:24 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * boot.c 1.5 + -B ... zum Duplizieren der letzten Partition bis zum Ende der Partitions Map + +Sun Mar 19 20:02:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.35 + New usage for -B option: ... means replicate previous boot partition + +Sun Mar 19 19:19:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.12 + Mac OS X definition new + +Sun Mar 19 16:46:31 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.39 + * multi.c 1.29 + * mkisofs.c 1.44 + * mkisofs.h 1.35 + RR deep directory relocation fixes for multi-session from: "Artem Hodyush" <artem@duma.gov.ru> + +Sun Mar 19 16:15:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.28 + made conform to schily programming rules + +Sun Mar 19 16:02:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.27 + indented + +Sat Mar 18 23:59:42 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README.eltorito 1.2 + typo corrected + +Sat Mar 18 22:43:10 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.43 + * tree.c 1.38 + added code for APPLE_HYBRID + +Sat Mar 18 19:39:14 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.34 + removed superfluous spaces + +Sat Mar 18 19:24:34 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.h 1.1 + date and time created 00/03/18 19:24:34 by joerg + +Sat Mar 18 19:24:13 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.h 1.1 + date and time created 00/03/18 19:24:13 by joerg + +Sat Mar 18 19:23:54 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mactypes.h 1.1 + date and time created 00/03/18 19:23:54 by joerg + +Sat Mar 18 19:18:36 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * desktop.c 1.1 + date and time created 00/03/18 19:18:36 by joerg + +Sat Mar 18 19:18:09 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mac_label.c 1.1 + date and time created 00/03/18 19:18:09 by joerg + +Sat Mar 18 19:16:33 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * volume.c 1.1 + date and time created 00/03/18 19:16:33 by joerg + +Sat Mar 18 17:56:59 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * apple.c 1.1 + date and time created 00/03/18 17:56:59 by joerg + +Sat Mar 18 13:52:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.35 + * mkisofs.h 1.34 + added code for APPLE_HYBRID, ROUND_UP() -> ISO_ROUND_UP() + +Sat Mar 18 13:44:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.11 + Use better recognition code for Rhapsody + +Sat Mar 18 13:41:24 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.17 + ROUND_UP() -> ISO_ROUND_UP() + +Sat Mar 18 13:02:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * boot.c 1.4 + 2048 -> SECTOR_SIZE + +Sat Mar 18 13:00:02 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.12 + csum_buffer[2048] -> csum_buffer[SECTOR_SIZE] + +Sun Mar 12 20:50:51 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.16 + * rock.c 1.22 + added code for APPLE_HYBRID + +Sat Mar 11 14:00:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.6 + added match code for APPLE_HYBRID, better error messages + +Sat Mar 11 13:38:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.9 + New function flush_hash() for APPLE_HYBRID + +Sat Mar 11 13:21:13 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.h 1.4 + Added definitions for APPLE_HYBRID + +Sat Mar 11 13:19:07 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.10 + Defaults for HFS (mkhybrid), SYSTEM_ID_DEAULT for Rhapsody + +Sun Mar 5 18:08:30 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.15 + Always sort root dir to be first in path table + +Sun Mar 5 14:28:41 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.33 + correction for boot.catalog description, -table-name documented + +Sun Mar 5 14:27:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.12 + replace forgotten but illegal chars by '_' + +Sat Mar 4 16:33:38 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.42 + close_merge_image() call from multi.c, do not close merge image a second time + +Sat Mar 4 16:32:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.33 + * multi.c 1.26 + new function clode_merge_image(), close_merge_image() -> mkisofs.c + +Thu Feb 17 00:10:46 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sunlabel.h 1.3 + * boot.c 1.3 + splitted into boot.c and sunlabel.h + +Wed Feb 16 17:55:06 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.c 1.3 + Prototypes for exchange() & _getopt_initialize() + +Wed Feb 16 17:08:57 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.32 + prototype for scsidev_close() + +Wed Feb 16 17:08:36 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.25 + merge_previous_session() now calls scsidev_close() to allow mkisofs | cdrecord with multi session + +Mon Feb 14 15:58:26 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * bootinfo.h 1.2 + comment added + +Thu Feb 10 01:10:21 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.13 + scsidev_close() neu + +**************** Release 1.12 ******************* + +Mon Jan 17 23:53:16 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * RELEASE 1.30 + * mkisofs.c 1.41 + * mkisofs.8 1.32 + Release 1.12 + +Fri Jan 14 02:26:40 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.31 + -no-rr new, Bugs section + +Wed Jan 12 16:19:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README.graft_dirs 1.1 + date and time created 00/01/12 16:19:55 by joerg + +Tue Jan 11 13:17:32 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.14 + allow odd to buffer sizes when converting to unicode + +Mon Jan 10 23:17:25 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.37 + * rock.c 1.21 + now using device.h + +Mon Jan 10 02:26:07 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.40 + -no-rr new + +Mon Jan 10 01:45:07 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.24 + * mkisofs.h 1.31 + no_rr new + +Sat Jan 8 23:42:24 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.12 + scsi_read() beachtet nun is_atapi damit mkisofs auch mit ATAPI multi-session kann + +Fri Jan 7 20:51:10 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.36 + print file typee, better error messages, no_scandir added + +Fri Jan 7 20:42:00 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.20 + * exclude.c 1.6 + better error messages + +Fri Jan 7 20:41:04 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.39 + new -U flag, -F flag removed, new list match code + +Fri Jan 7 20:32:22 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.5 + new list match code + +Fri Jan 7 19:26:08 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.30 + new hide options, -F removed -U new + +Fri Jan 7 18:58:12 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.34 + make TRANS.TBL a variable, gui code gives faster verbose message + +Fri Jan 7 18:55:19 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.23 + make TRANS.TML name a variable + +Fri Jan 7 18:52:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.30 + -U new, new match list code + +Fri Jan 7 18:07:38 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.h 1.3 + new match list code + +Wed Jan 5 20:06:55 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.11 + -U flag new + +Sun Jan 2 00:37:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.38 + Version js-a38 + +Sat Jan 1 23:05:28 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.33 + using offsetof() to get around odd structure length, better error messages + +Sat Jan 1 23:03:42 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.13 + * multi.c 1.22 + * tree.c 1.35 + using offsetof() to get around odd structure length + +Sat Jan 1 20:31:59 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.7 + Note for odd length added + +Sat Jan 1 20:31:53 2000 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.29 + offsetof() macro new + +Wed Dec 29 14:38:31 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.29 + * mkisofs.h 1.28 + * mkisofs.c 1.37 + New options -hide-rr-moved & -hide-joliet-trans-tbl + +Wed Dec 29 14:21:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.34 + New options -hide-rr-moved & -hide-joliet-trans-tbl, better error messages + +Tue Dec 28 18:23:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.21 + better error messages, free more structures, check for bad RR Version, fix direactory handling code for graft pointers + +Tue Dec 28 16:32:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.c 1.2 + fixed uninitialized variable + +Tue Dec 28 15:12:05 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.8 + * files.c 1.6 + * write.c 1.32 + better error messages + +Tue Dec 28 15:07:29 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.11 + better error messages, make boot file/ boot catalog hidable + +Tue Dec 28 14:21:26 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.12 + Error message made different from others + +Mon Dec 27 15:34:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.6 + indented + +Mon Dec 20 00:14:20 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.33 + config.h must be first, boot catalog becomes MEMORY FILE + +Sun Dec 19 22:31:42 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.36 + hard disk boot, no emulation boot + +Sun Dec 19 21:29:59 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.10 + better autoconf, hd boot, no emulation boot, boot catalog as memory file + +Sun Dec 19 21:06:46 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.10 + fix with file priority + +Sun Dec 19 21:01:37 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.27 + hard disk boot/ no emulation boot new, MEMORY FILE new + +Sun Dec 19 20:58:32 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.31 + config.h must be first get_731()/get_732() new + +Sun Dec 19 20:57:02 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.19 + * multi.c 1.20 + config.h must be first + +Sun Dec 19 20:55:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * hash.c 1.7 + include stdlib.h past config.h + +Sun Dec 19 20:33:49 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * diskmbr.h 1.1 + date and time created 99/12/19 20:33:49 by joerg + +Sun Dec 19 19:54:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * iso9660.h 1.5 + changes for NOEMUL BOOT + +Sun Dec 19 18:16:10 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * bootinfo.h 1.1 + date and time created 99/12/19 18:16:10 by joerg + +Sun Dec 19 16:38:04 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.28 + hard disk boot and no emulation boot + +Sun Dec 19 16:13:21 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sunlabel.h 1.2 + * boot.c 1.2 + Ueberfluessige Variablen beseitigt, Prototypen fuer geboot_*() + +Sat Dec 18 01:11:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile.in 1.16 + Erics final changes + +Wed Dec 15 01:24:58 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.35 + sparc boot new, -nomak new, suid mode now safe + +Sun Dec 12 22:01:32 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README.sparcboot 1.1 + date and time created 99/12/12 22:01:32 by joerg + +Sun Dec 12 19:26:57 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.30 + * mkisofs.8 1.27 + * mkisofs.h 1.26 + sparc boot new + +Sun Dec 12 18:28:09 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.3 + boot.c new + +Sun Dec 12 18:03:39 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * sunlabel.h 1.1 + * boot.c 1.1 + date and time created 99/12/12 18:03:39 by joerg + +Sat Dec 11 16:26:54 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.32 + rstr() new to check for .bak files + +Fri Dec 10 01:58:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.19 + Check first if -M file exists before trying to use scsidev_open() + +Tue Dec 7 00:33:13 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.29 + new sort_dir code checks for is_rr_dir + +Tue Dec 7 00:21:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.31 + Do not make directory loop fatal, new sort_directory code + +Tue Dec 7 00:19:32 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.25 + sort directory prototyp modified + +Mon Dec 6 23:40:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.11 + use comerr() + +Mon Dec 6 22:46:07 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.34 + Version js-a34 + +Sat Dec 4 20:56:21 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.18 + Allow RR Version 2 for Mac, memcmp() returns != null for misscompare of date!!! + +Sat Dec 4 20:48:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.28 + Allow the same name in rr_moved + +Tue Nov 30 17:16:47 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.10 + strncmp() for max of 64 chars in Joliet dirs + +Sat Nov 27 22:05:15 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.30 + Force graft dirs to be at least SECTOR_SIZE, dup missing whole_name + +Thu Nov 25 10:44:05 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.9 + Various new system definitions + +Thu Nov 25 00:25:08 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.33 + -version new + +Tue Nov 23 00:11:24 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.26 + Hint to new maintainer Joerg Schilling + +Tue Nov 23 00:05:30 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.32 + Version js-a32, -cdwrite-params -> -cdrecord-params + +Tue Nov 23 00:03:15 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README 1.7 + cdwrite hint removed + +Tue Nov 23 00:01:13 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.17 + TRANS.TBL handling corrected + +Mon Nov 22 23:47:21 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.11 + Abbruch bei Lesefehlern in readsecs() + +Mon Nov 22 21:41:38 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.18 + #ifdef corrected for BLK/CHR devices + +Fri Nov 19 23:01:59 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.29 + S_IFBLK checked for OS/2 + +Fri Nov 12 11:55:44 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * eltorito.c 1.9 + clean castings + +Fri Nov 12 11:53:07 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.27 + clean casting + +Fri Nov 12 11:45:03 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.24 + #include statdefs.h + +Wed Nov 3 23:56:49 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.31 + Release js-a31 + +Mon Nov 1 22:29:15 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile.man 1.2 + INSMODE new + +Sat Oct 16 18:52:16 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.30 + Release 1.12b5-js-a30, removed & before array + +Fri Oct 15 22:01:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.16 + Removed & before array + +Fri Oct 8 19:54:24 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * match.c 1.4 + make it work correctly on 64 bit systems + +Mon Sep 13 12:10:13 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.29 + Version to 1.12b5-js-28 + +Tue Sep 7 16:45:13 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.10 + Umbau auf neues open_scsi(), commerr() statt fprintf(stderr) + +Tue Sep 7 14:52:25 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * rock.c 1.17 + HAVE_READLINK test, use comerr() + +Tue Sep 7 14:50:50 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.9 + * hash.c 1.6 + * files.c 1.5 + * eltorito.c 1.8 + * multi.c 1.15 + * write.c 1.26 + use comerr() + +Tue Sep 7 14:32:27 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.28 + use comerr(), HAVE_READLINK test + +Tue Sep 7 14:13:12 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.28 + use comerr()/save_args() + +Tue Sep 7 14:10:48 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.2 + USE_LIBSCHILY new + +Sun Aug 29 01:59:22 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.23 + HAVE_LSTAT test new + +Sun Aug 1 22:50:12 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * defaults.h 1.8 + SYSTEM ID DEFAULT for OS/2 + +Sun Jul 11 19:32:42 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * multi.c 1.14 + <translation table> -> TRTANS.TBL for Joliet, round up to SECSIZE for reading TRANS.TBL + +Sun Jul 11 19:30:08 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * tree.c 1.27 + <translation table> -> TRTANS.TBL for Joliet, ignore-loops new + +Mon Jun 21 11:46:40 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * write.c 1.25 + Check for Rock Ridge files with same name + +Thu Jun 17 16:31:43 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.9 + cleaned up + +Thu Jun 17 16:30:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.8 1.25 + Better words, -F option new + +Thu Jun 17 16:17:18 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.27 + wildcard for EMX, ignore loops, no-split-symlink-fields/no-split-symlink-components now work + +Tue May 25 21:09:44 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.h 1.22 + ignore-loops new + +Wed May 19 16:41:02 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * joliet.c 1.8 + debug print for joliet files wirh same name + +Wed Apr 28 16:58:37 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * name.c 1.8 + Better handling for chars > 128 + +Sat Apr 24 18:39:19 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.9 + Wegen OS/2 wird nun scsi_getbuf() aufgerufen, wait_inut_ready() neu, read_capacity() neu, Schleife ueber read_scsi, falls der transfer groeszer als der SCSI Puffer ist. + +Sat Apr 24 18:25:00 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * mkisofs.c 1.26 + #ifdef for EMX (OS/2) + +**************** Release 1.12b5 ******************* + +Mon Mar 8 01:32:05 1999 Eric Youngdale <eric@andante.org> + * RELEASE 1.29 + Release1.12b5 + +Mon Mar 8 01:31:05 1999 Eric Youngdale <eric@andante.org> + * mkisofs.8 1.24 + many new options from Joerg Schilling, Release 1.12b5 + +Sun Mar 7 22:48:49 1999 Eric Youngdale <eric@andante.org> + * mkisofs.c 1.25 + several new options, binary open for Win32 + +Sun Mar 7 18:41:19 1999 Eric Youngdale <eric@andante.org> + * write.c 1.24 + split-output new, binary open for Win32, avoid incorrect sorting for ./.. with -L, ISO hide code + +Sun Mar 7 18:41:19 1999 Eric Youngdale <eric@andante.org> + * tree.c 1.26 + Inhibit code, sprintf() now correct, varoius other fixes + +Sun Mar 7 18:41:19 1999 Eric Youngdale <eric@andante.org> + * joliet.c 1.7 + Let all iso8859-1 chars be unicode, Joliet hide code + +Tue Mar 2 05:16:41 1999 Eric Youngdale <eric@andante.org> + * multi.c 1.13 + Prototypes and other various bug fixes + +Tue Mar 2 05:16:41 1999 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.21 + better prototypes, INHIBIT_ISO9660_entry new, volume_set_size/volume_sequence_number + +Tue Mar 2 05:16:40 1999 Eric Youngdale <eric@andante.org> + * Makefile.in 1.15 + Release 1.12b5 + +Tue Mar 2 05:16:40 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * README.session 1.3 + Modified for cdrecord + +Tue Mar 2 04:41:26 1999 Eric Youngdale <eric@andante.org> + * rock.c 1.16 + Binary open for Win32, some other fixes + +Tue Mar 2 04:41:26 1999 Eric Youngdale <eric@andante.org> + * name.c 1.7 + casts for unsigned char * + +Tue Mar 2 04:41:25 1999 Eric Youngdale <eric@andante.org> + * match.h 1.2 + * match.c 1.3 + Joliet/ISO hide code new + +Tue Mar 2 04:41:25 1999 Eric Youngdale <eric@andante.org> + * defaults.h 1.7 + APPID_DEFAULT new + +Tue Mar 2 04:41:25 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * exclude.h 1.2 + __PR() macros + +Tue Mar 2 04:41:25 1999 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * fnmatch.c 1.3 + some casts for unsigned char * + +Tue Mar 2 04:41:25 1999 Eric Youngdale <eric@andante.org> + * eltorito.c 1.7 + small bug fixes + +Sun Nov 29 19:13:43 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.8 + usalio.h -> usalcmd.h/usalio.h, usalio.h usalcmd.h scsidefs.h scsireg.h scsitransp.h -> include/usal + +Sun Nov 29 18:30:41 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile 1.1 + date and time created 98/11/29 18:30:41 by joerg + +Sat Nov 14 04:20:05 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * Makefile.man 1.1 + date and time created 98/11/14 04:20:05 by joerg + +Fri Oct 30 02:06:35 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.7 + open_scsi() returniert nun SCSI *usalp, wird auch fuer read_scsi() verwendet + +Sat Oct 24 01:29:24 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.6 + open_scsi(dev, timeout, verboseopen) -> open_scsi(dev, debug, verboseopen) + +**************** Release 1.12b4 ******************* + +Tue Jun 2 06:44:45 1998 Eric Youngdale <eric@andante.org> + * RELEASE 1.28 + Release 1.12b4 + +Tue Jun 2 06:43:45 1998 Eric Youngdale <eric@andante.org> + * mkisofs.c 1.24 + New options -print-size & -split-output, put Joliet & ElTorite PVD in right order + +Tue Jun 2 06:43:44 1998 Eric Youngdale <eric@andante.org> + * mkisofs.8 1.23 + -print-size/-split-output new, Release 1.12b4 + +Tue Jun 2 06:14:58 1998 Eric Youngdale <eric@andante.org> + * tree.c 1.25 + Win32 changes, do not use sprintf result, some other fixes + +Tue Jun 2 05:40:39 1998 Eric Youngdale <eric@andante.org> + * write.c 1.23 + -split-output, several fixes + +Tue Jun 2 05:40:38 1998 Eric Youngdale <eric@andante.org> + * multi.c 1.12 + Some fixes with DOT/DODOT, create whole_name by strdup + +Tue Jun 2 05:40:38 1998 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.20 + Win32, -print-size, -split-output + +Tue Jun 2 05:40:38 1998 Eric Youngdale <eric@andante.org> + * name.c 1.6 + No version number if it is part of the filename + +Tue Jun 2 05:40:37 1998 Eric Youngdale <eric@andante.org> + * eltorito.c 1.6 + O_BINARY for Win32 + +Tue Jun 2 05:40:37 1998 Eric Youngdale <eric@andante.org> + * joliet.c 1.6 + bug fix for ce_bytes and chars > 128 + +Tue Jun 2 05:40:37 1998 Eric Youngdale <eric@andante.org> + * defaults.h 1.6 + Defaults for Win32 + +Tue Jun 2 05:40:36 1998 Eric Youngdale <eric@andante.org> + * Makefile.in 1.14 + CFLAGS new + +Fri Apr 17 12:39:39 1998 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.5 + Prototypen entfernt fuer K&R C + +**************** Release 1.12b3 ******************* + +Wed Feb 18 05:51:47 1998 Eric Youngdale <eric@andante.org> + * RELEASE 1.27 + * mkisofs.c 1.23 + * mkisofs.8 1.22 + Release 1.12b3 + +Wed Feb 18 05:48:24 1998 Eric Youngdale <eric@andante.org> + * tree.c 1.24 + check for relocated dirs + +Wed Feb 18 05:48:23 1998 Eric Youngdale <eric@andante.org> + * rock.c 1.15 + check strlen of symlink buffer + +**************** Release 1.12b2 ******************* + +Mon Feb 16 18:57:56 1998 Eric Youngdale <eric@andante.org> + * RELEASE 1.26 + * mkisofs.c 1.22 + * mkisofs.8 1.21 + Release 1.12b2 + +Mon Feb 16 18:56:56 1998 Eric Youngdale <eric@andante.org> + * tree.c 1.23 + small bug fixes, Ingoring file message + +Mon Feb 16 18:56:56 1998 Eric Youngdale <eric@andante.org> + * write.c 1.22 + bug fix.... + +Mon Feb 16 18:56:55 1998 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.19 + better autoconf, better prototypes + +Mon Feb 16 18:56:55 1998 Eric Youngdale <eric@andante.org> + * joliet.c 1.5 + several casts to unsigned char * + +**************** Release 1.12b1 ******************* + +Mon Dec 15 13:48:59 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.25 + * mkisofs.c 1.21 + * mkisofs.8 1.20 + Release 1.12b1 + +Mon Dec 15 13:47:59 1997 Eric Youngdale <eric@andante.org> + * rock.c 1.14 + mkdev() autoconf corrected + +Mon Dec 15 13:47:59 1997 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.18 + string.h/strings.h autoconf + +Mon Dec 15 13:47:59 1997 Eric Youngdale <eric@andante.org> + * tree.c 1.22 + set isorec.size later + +Mon Dec 15 13:47:58 1997 Eric Youngdale <eric@andante.org> + * eltorito.c 1.5 + some printf's moved to stderr to avoid problems + +Mon Dec 15 13:47:57 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * configure.in 1.4 + several new tests + +**************** Release 120697 ******************* + +Sat Dec 6 22:06:07 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.24 + * ChangeLog 1.18 + Release 120697 + +Sat Dec 6 22:05:07 1997 Eric Youngdale <eric@andante.org> + * write.c 1.21 + * tree.c 1.21 + * rock.c 1.13 + Fix uninitialized memory usage that screwed up lots of stupid things. Add support for non-split symlinks. + +Sat Dec 6 22:05:05 1997 Eric Youngdale <eric@andante.org> + * multi.c 1.11 + init struct directory to null + +Sat Dec 6 22:05:05 1997 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.17 + readdir include handling new, *split_SL* new + +Sat Dec 6 22:05:05 1997 Eric Youngdale <eric@andante.org> + * mkisofs.c 1.20 + * mkisofs.8 1.19 + new option -no-split-symlink-fields/-no-split-symlink-components + +Sat Dec 6 22:05:03 1997 Eric Youngdale <eric@andante.org> + * defaults.h 1.5 + SunOS/Solaris switch + +**************** Release 112597 ******************* + +Tue Nov 25 14:09:37 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.23 + Release 112597 + +Tue Nov 25 14:08:37 1997 Eric Youngdale <eric@andante.org> + * mkisofs.8 1.18 + Release 112597, -quiet option new + +Tue Nov 25 14:08:37 1997 Eric Youngdale <eric@andante.org> + * mkisofs.c 1.19 + verbose levels, -quiet + +Tue Nov 25 14:06:43 1997 Eric Youngdale <eric@andante.org> + * write.c 1.20 + vervose levels + +Tue Nov 25 14:06:42 1997 Eric Youngdale <eric@andante.org> + * joliet.c 1.4 + some bug fixes, handling of reloc dir + +Tue Nov 25 14:06:42 1997 Eric Youngdale <eric@andante.org> + * tree.c 1.20 + * hash.c 1.5 + verbose levels + +**************** Release 112397 ******************* + +Mon Nov 24 03:52:49 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.22 + Release 112397 + +Mon Nov 24 03:51:49 1997 Eric Youngdale <eric@andante.org> + * multi.c 1.10 + print error messages to stderr + +Mon Nov 24 03:51:49 1997 Eric Youngdale <eric@andante.org> + * joliet.c 1.3 + fixed some bugs that prevented images working on NT, convert to unicode new + +Mon Nov 24 03:51:49 1997 Eric Youngdale <eric@andante.org> + * tree.c 1.19 + put error/debug messages to stderr, INHIBIT_JOLIET_ENTRY new + +Thu Nov 13 06:01:42 1997 Eric Youngdale <eric@andante.org> + * name.c 1.5 + typo fix + +Mon Nov 10 04:27:17 1997 Eric Youngdale <eric@andante.org> + * write.c 1.19 + casting to unsigned char * + +**************** Release 110997 ******************* + +Sun Nov 9 19:56:51 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.21 + 110997 + +Sun Nov 9 19:55:51 1997 Eric Youngdale <eric@andante.org> + * mkisofs.c 1.18 + getopt_long() codem, graft pointers, struct output_fragment new + +Sun Nov 9 19:55:44 1997 Eric Youngdale <eric@andante.org> + * mkisofs.8 1.17 + Joliet new, Graft pointers new + +Sun Nov 9 19:54:58 1997 Eric Youngdale <eric@andante.org> + * tree.c 1.18 + Joliet handling and graft pointer handling + +Sun Nov 9 19:54:45 1997 Eric Youngdale <eric@andante.org> + * write.c 1.18 + struct output_fragment new, sort goof check new, free unused space, better statistics + +Sun Nov 9 19:54:27 1997 Eric Youngdale <eric@andante.org> + * multi.c 1.9 + correct line length for TRANS.TBL, graft pointer merging code new + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.16 + struct output_fragment new, some defines for the tree + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * iso9660.h 1.4 + defines for unicode level, PVD ID for Joliet + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * joliet.c 1.2 + first code added + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * Makefile.in 1.13 + joliet.c, getopt*.c new + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * name.c 1.4 + mapping chars > 128 + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * eltorito.c 1.4 + error messages to stderr, struct output_fragement new + +Sun Nov 9 19:43:36 1997 Eric Youngdale <eric@andante.org> + * README 1.6 + Notes for Release 1.12 added + +Thu Nov 6 20:19:25 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.4 + #include <mconfig.h> fuer AIX + +Tue Nov 4 03:27:44 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt.h 1.1 + date and time created 97/11/04 03:27:44 by joerg + +Tue Nov 4 03:27:39 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * getopt1.c 1.1 + date and time created 97/11/04 03:27:39 by joerg + +Tue Nov 4 03:27:32 1997 Eric Youngdale <eric@andante.org> + * getopt.c 1.1 + date and time created 97/11/04 03:27:32 by eric + +Sat Oct 18 19:14:05 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.3 + stdlib.h -> stdxlib.h, unistd.h -> unixstd.h + +Wed Oct 15 07:25:15 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * TODO 1.3 + New list for 1.12 + +**************** Release 1.11.1 ******************* + +Mon Oct 13 05:56:49 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.20 + * mkisofs.8 1.16 + Release 1.11.1 + +Mon Oct 13 05:55:49 1997 Eric Youngdale <eric@andante.org> + * mkisofs.c 1.17 + Release 1.11.1, let path_table start on correct sector # depending on El Torito or not + +Mon Oct 13 05:46:46 1997 Eric Youngdale <eric@andante.org> + * multi.c 1.8 + better checking for null pointers, USE_SCG code included, type casts for unsigned char * + +Mon Oct 13 05:46:01 1997 Eric Youngdale <eric@andante.org> + * write.c 1.17 + Make local time a structure rahte than a pointer so data will not overwritten, add Joliet support + +Mon Oct 13 05:41:16 1997 Eric Youngdale <eric@andante.org> + * tree.c 1.17 + file renaming code corrected, iso9660_file_length() called correctly (not dir!) for TRANS.TBL + +Mon Oct 13 05:32:57 1997 Eric Youngdale <eric@andante.org> + * mkisofs.h 1.15 + prototypes for readsecs() and scsidev_open() + +Mon Oct 13 05:30:51 1997 Eric Youngdale <eric@andante.org> + * name.c 1.3 + seen_dot new, include '%' to illegal characters + +Mon Oct 13 05:30:21 1997 Eric Youngdale <eric@andante.org> + * rock.c 1.12 + major() autoconf changed + +Mon Oct 13 05:29:40 1997 Eric Youngdale <eric@andante.org> + * eltorito.c 1.3 + Limit publisher ID to 23 chars + +Wed May 21 18:11:25 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * scsi.c 1.2 + scsireg.h Include + +Sat May 17 18:49:03 1997 Eric Youngdale <eric@andante.org> + * joliet.c 1.1 + date and time created 97/05/17 17:49:03 by eric + +Fri May 16 15:46:48 1997 Joerg Schilling <joerg@schily.isdn.cs.tu-berlin.de> + * config.h 1.1 + * scsi.c 1.1 + date and time created 97/05/16 14:46:48 by joerg + +**************** Release 1.11 ******************* + +Thu Apr 10 06:46:21 1997 Eric Youngdale <eric@andante.org> + * RELEASE 1.19 + * RELEASE 1.18 + * mkisofs.8 1.15 + Release 1.11 + +Thu Apr 10 06:43:02 1997 Eric Youngdale <eric@andante.org> + * write.c 1.16 + Check for . and .. entries in dir + +Thu Apr 10 06:41:49 1997 Eric Youngdale <eric@andante.org> + * tree.c 1.16 + Strip off non-significant part of filename + +/*--------------------------------------------------------------------------*/ +The text below is not autogenerated from SCCS comments: + +Wed Nov 5 10:46:29 1997 Andreas Buschmann US/EC4 60/1F/110 #40409 <buschman@lts.sel.alcatel.de> + + Circumvent a bug in the SunOS / Solaris CD-ROM driver (and maybe HP/UX, too). + + * mkisofs.8 (-S): Document switch. + * mkisofs.c (split_SL_field): new Variable, new switch -S. + * mkisofs.h (split_SL_field): new Variable. + * rock.c (generate_rock_ridge_attributes): only split SL field, + when split_SL_field is set. + +Tue Jun 3 15:32:21 1997 Andreas Buschmann <buschman@lts.sel.alcatel.de> + + Circumvent a bug in the SunOS CD-ROM driver (and maybee HP/UX, too). + + * mkisofs.8 (-s): Document switch. + * mkisofs.c (split_SL_component): new Variable, new switch -s. + * mkisofs.h (split_SL_component): new Variable. + * rock.c (generate_rock_ridge_attributes): only split SL + components, when split_SL_component is set. + + * defaults.h: Added SunOS string. + + +Wed Mar 19 16:50:17 1997 Fred Fish <fnf@ninemoons.com> + + * Makefile.in (CFLAGS): Let configure set basic flags. Move + compilation option -c to actual CC commands. + (LDFLAGS): Let configure set basic flags. + (Makefile): Depends upon config.status, not configure. + Regenerate if necessary from Makefile.in using config.status. + (configure): Cd to srcdir before running autoconf. + * acconfig.h: New file to hold nonstandard entries used in + config.h.in. Used by autoheader to generate config.h.in. + * config.h.in: Regenerated with autoheader. + * configure.in: Check for existance of sbrk() function. + * configure: Regenerated with autoconf 2.12. + * fnmatch.c (FMN_FILE_NAME): Define if not already defined. + (FNM_LEADING_DIR): Ditto. + (FNM_CASEFOLD): Ditto. + * mkisofs.c (main): Only use sbrk() if system supports it. + +Fri Mar 14 21:54:37 1997 Eric Youngdale <eric@andante.jic.com> + + * Bump version number to 1.10, public release. + + * Put entire thing under RCS. History is buried there now. + + * Fix bug involving empty directories, translation tables and + malloc(0). + +Mon Feb 17 12:44:03 1997 Eric Youngdale <eric@andante.jic.com> + + * Bump version number to 1.10b7. + + * Makefile.in, configure.in, config.in: Change to use GNU autoconf. + + * Configure: Delete old configuration script. + + * tree.c: Fix bug where we had a rename limit of 1000 files + instead of 0x1000. + + * mkisofs.c: Fix sign of timezone offset. Linux iso filesystem + also need to be fixed, unfortunately. + +Tue Dec 3 22:21:21 1996 Eric Youngdale <eric@sub2317.jic.com> + + Fixed a couple of multi-session bugs. Discs now seem to + work on both Solaris and Windows-NT. + + * Bump version number to 1.10b6. + +Tue Dec 3 22:21:21 1996 Eric Youngdale <eric@sub2317.jic.com> + + Multi-session stuff *almost* there. Discs seem to work + under Linux without any problem, but under DOS only + the first session is seen. The patch to write.c + inspired by disc written by Windows generated multi-session + disc, which will hopefully make the discs usable under + DOS as well. + + * Bump version number to 1.10b5. + + * write.c: use size of new session, not total of all sessions + in volume_space_size field. + + * mkisofs.8: Update with current location of cdwrite. + +Mon Nov 4 23:45:01 1996 Eric Youngdale <eric@sub2317.jic.com> + + * Bump version number to 1.10b4. + + * Add cdwrite.c.diff file, which provides a very crude, minimal + interface between mkisofs and cdwrite. It should be enough to + generate a multi-session disc, but it hasn't been tested yet. + +Thu Oct 17 00:39:52 1996 Eric Youngdale <eric@sub2317.jic.com> + + * Bump version number to 1.10b3. + +Wed Oct 16 23:40:44 1996 Michael Fulbright <msf@redhat.com> + + Add support for 'El Torito' specification which allows for bootable + cdroms. + + * Makefile.in: Add eltorito.[c,o]. + + * defaults.h: Add default settings for El Torito related things. + + * iso9660.h: Add structure definitions for El Torito. + + * mkisofs.8: Document new options. + + * mkisofs.c: Add support for new options related to El Torito. + + * mkisofs.h: Add definitions, prototypes as required. + + * tree.c: Add search_tree_file function to search for a specified + file. + + * write.c: Add support for writing special records for El Torito. + + * eltorito.c: New file. + + +Wed Oct 16 23:40:44 1996 Eric Youngdale <eric@sub2317.jic.com> + + * rock.c: Fix bug whereby we made assumptions about how + dev_t was split into major/minor. Use major() and minor() + macros to do this for us, since each system should + do this correctly. + + * write.c: Fix bug whereby abstract, copyright and appid + strings were not properly filled if application ID weren't + in use. + +Sun Sep 29 10:05:10 1996 Eric Youngdale <eric@sub2317.jic.com> + + * Bump version number to 1.10b2. Minor bug fixes here + and there. + +Sun Sep 15 18:54:05 1996 Eric Youngdale <eric@sub2317.jic.com> + + * Bump version number to 1.10b1. Major new functionality is + support for multi-session. Still a bit preliminary, but + most of the pieces are there now. + +Wed Dec 20 16:44:44 1995 Eric Youngdale (eric@andante.aib.com) + + * mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.05. + + * rock.c: Bugfix for cases where sizeof(int) == 4 and + sizeof(dev_t) > 4. + + * rock.c: Bugfix for long symbolic links ('/' characters were + being dropped). + + Patches from Peter Miller <pmiller@agso.gov.au>: + + * mkisofs.8: Documentation fix (some versions of nroff don't + like '.' in column 1 if it is not a nroff command). + + * mkisofs.c: Add support for 'rationalize' option. + Similar to rock ridge, except echos of development environment + are removed. + + * write.c Status indicator now indicates percent finished, and + estimated time of completion. + +Sun Feb 26 01:52:06 1995 Eric Youngdale (eric@largo) + + * Add patches from Ross Biro to allow you to merge arbitrary + trees into the image. This is not compiled in by default but + you need to add -DADD_FILES when compiling. + +Fri Feb 17 02:29:03 1995 Paul Eggert <eggert@twinsun.com> + + * tree.c: Port to Solaris 2.4. Prefer <sys/mkdev.h> if + HASMKDEV. Cast unknown integer types to unsigned long and + print them with %lu or %lx. + +Thu Jan 26 15:25:00 1995 H. Peter Anvin (hpa@yggdrasil.com) + + * mkisofs.c: Substitute underscore for leading dot in non-Rock + Ridge filenames, since MS-DOS cannot read files whose names + begin with a period. + +Mon Jan 16 18:31:41 1995 Eric Youngdale (eric@aib.com) + + * rock.c (generate_rock_ridge_attributes): Only use ROOT + record for symlinks if we are at the start of the symlink. + Otherwise just generate an empty entry. + +Mon Jan 16 16:19:50 1995 Eric Youngdale (eric@aib.com) + + * diag/isodump.c: Use isonum_733 instead of trying to dereference + pointers when trying to decode 733 numbers in the iso9660 image. + + * diag/isovfy.c: Likewise. + + * write.c: Always assign an extent number, even for zero length + files. A zero length file with a NULL extent is apparently dropped + by many readers. + +Wed Jan 11 13:46:50 1995 Eric Youngdale (eric@aib.com) + + * mkisofs.c: Modify extension record to conform to IEEE P1282 + specifications. This is commented out right now, but a trivial + change to a #define enables this. I need to see the specs + to see whether anything else changed before this becomes final. + + * write.c (FDECL4): Fix so that we properly determine error + conditions. + + * mkisofs.h: Change rr_attributes to unsigned. + + * tree.c(increment_nlink): Change pnt since rr_attributes is now + unsigned. + + Ultrix patches from petav@argon.e20.physik.tu-muenchen.de (Peter Averkamp) + + * rock.c: Fix for ultrix systems, we have 64 bit device numbers. + Type cast when generating file size. Change rr_attributes to + unsigned. + + * mkisofs.c: For ultrix systems, define our own function + for strdup. + + * mkisofs.c: Fix usage() since some compilers do not concatenate + strings properly (i.e. ultrix). + + Bugs found with Sentinel II: + + * write.c: Fix a couple of memory leaks. + + * mkisofs.c: Bugfix - always put a zero byte at end of name + for ".." entry. + + * tree.c: Set isorec.date from fstatbuf.st_ctime, not current_time, + since current_time might not be set. + +Sat Dec 3 14:55:42 1994 Eric Youngdale (eric@andante) + + * mkisofs.c: When returning entry for ".." file, set second byte + to 0. + + * write.c: Free name and rr_attributes fields when writing. + +Mon Nov 28 13:36:27 1994 Eric Youngdale (eric@andante) + + * mkisofs.h: Change rr_attributes to unsigned. + + * rock.c: Ditto. Work around >>32 bug in ultrix for 64 bit data types. + + * mkisofs.c (usage): Fix for ultrix - use continuation lines + instead of assuming that strings are catenated by the compiler. + +Mon Jun 20 20:25:26 1994 Eric Youngdale (eric@esp22) + + * mkisofs.c, mkisofs.8, Makefile (version_string): Bump to pre-1.02. + + * mkisofs.h: Fix declaration of e_malloc to use DECL macros. + + * tree.c: Fix bug in previous change. + + * diag/*.c: Add appropriate copyright notices. + +Sat Apr 9 13:30:46 1994 Eric Youngdale (ericy@cais.com) + + * Configure: New file - shell script that determines a bunch of + things to properly build mkisofs. + + * Makefile.in: New file - copy of Makefile, but Configure sets a + few things up for it. + + * tree.c: Do not depend upon opendir to return NULL if we cannot + open a directory - actually try and read the first entry. The + foibles of NFS seem to require this. + + * write.c: Fix definition of xfwrite (Use FDECL4) + + Add some changes to allow more configurability of some of the + volume header fields: + + * mkisofs.8: Document new configuration options. + + * mkisofs.c: Add variables to hold new fields. Add function to + read .mkisofsrc files. + + * defaults.h: Another way of configuring the same things. + + Add some changes from Leo Weppelman leo@ahwau.ahold.nl. + + * mkisofs.c: Allow -A to specify application ID. Fix usage(), + getopt and add case switch. + + * rock.c: Fix handling of device numbers (dev_t high should only + be used when sizeof(dev_t) > 32 bits). + + Add a bunch of changes from Manuel Bouyer. + + * diag/Makefile: New file. + + * diag/dump.c, diag/isodump.c: Use termios if system supports it. + + * (throughout): Replace all occurences of "malloc" with e_malloc. + + * mkisofs.c: For NetBSD, attempt to increase the rlimit for + the size of the data segment to about 33 Mb. + + * mkisofs.c (e_malloc): New function. Calls malloc, and prints + nice error message and exits if NULL is returned. + +Sun Jan 23 19:23:57 1994 Eric Youngdale (eric@esp22) + + * mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.01. + + Add a bunch of stuff so that mkisofs will work on a VMS system. + + * (ALL): Change any direct use of the "st_ino" field from + the statbuf to use a macro. + + * mkisofs.h: Define appropriate macros for both VMS and unix. + + * (ALL): Add type casts whenever we use the UNCACHED_DEV macro. + + * rock.c: Wrap a #ifndef VMS around block and character device + stuff. + + * write.c: Add prototype for strdup if VMS is defined. + + * make.com: Script for building mkisofs on a VMS system. + + * Makefile: Include make.com in the distribution. + + * mkisofs.c: Include <sys/type.h> on VMS systems. + + * tree.c: Include <sys/file.h> and "vms.h" on VMS systems. + + * mkisofs.h (PATH_SEPARATOR, SPATH_SEPARATOR): New macros + that define the ascii character that separates the last directory + component from the filename. + + * tree.c, mkisofs.c: Use them. + + * vms.c: New file. Contains version of getopt, strdup, opendir, + readdir and closedir. + + * vms.h: New file. Defines S_IS* macros. Define gmtime as + localtime, since gmtime under VMS returns NULL. + +Sat Jan 15 13:57:42 1994 Eric Youngdale (eric@esp22) + + * mkisofs.h (transparent_compression): New prototype. + + * mkisofs.c (transparent_compression): Declare, use + '-z' option to turn on. + + * tree.c: Change TRANS.TBL;1 to TRANS.TBL (version gets + added later, if required). + + * rock.c: If transparent compression requested, verify + file is really suitable (check magic numbers), and extract + correct file length to store in SUSP record. + +Sat Jan 15 01:57:42 1994 Eric Youngdale (eric@esp22) + + * write.c (compare_dirs): Bugfix for patch from Jan 6. + + * mkisofs.h (struct directory_entry): Add element total_rr_attr_size. + (struct file_hash): Add element ce_bytes. + + * write.c (iso_write): Update last_extent_written, as required, + and check it against last_extent as a sanity check. + (generate_one_directory): If ce_bytes is non-zero, allocate + a buffer and fill it with the CE records. Also, update + the extent and offset entries in the CE SUSP field and + output after directory is written. + (assign_directory_addresses): Allow for CE sectors after each + directory. + + * tree.c (sort_n_finish): Set field ce_bytes by summing + the sizes of all CE blocks in each files RR attributes. + Do not count these bytes for main directory. + + * rock.c (generate_rock_ridge_attributes): Generate + CE entries to break up large records into manageable sizes. + Allow long names to be split, and allow long symlinks to be split. + Allow splitting before each SUSP field as well, to make + sure we do not screw outselves. + +Thu Jan 6 21:47:43 1994 Eric Youngdale (eric@esp22) + + Bugfix. + + * write.c (compare_dirs): Only compare directory names up to + the ';' for the version number. + + Add four new options: (1) Full 31 character filenames, + (2) Omit version number, (3) Omit trailing period from filenames, + (4) Skip deep directory relocation. + + * iso9660.h: Allow 34 characters for filename. + + * mkisofs.8: Update for new options. + + * mkisofs.c: Add flag variables for new options. + Mention new options in usage(), tell getopt about + new options, and set appropriate flags when + new options are specified. + + * mkisofs.c (iso9660_file_length): Implement new options. + + * mkisofs.h: Declare flag variables for new options. + + * tree.c (sort_n_finish): Increase declaration of newname and + rootname to 34 characters. If full_iso9660_filenames in effect, + use different rules for making unique names. + + * tree.c (scan_directory_tree): Use RR_relocation_depth instead of + constant for threshold for starting deep directory relocation. + +Wed Jan 5 01:32:34 1994 John Brezak (brezak@ch.hp.com) + + * Makefile.bsd: New file. For NetBSD. + + * rock.c, tree.c: Do not include sys/sysmacros.h for NetBSD. + +Fri Dec 31 13:22:52 1993 Eric Youngdale (eric@esp22) + + * mkisofs.c, mkisofs.8, Makefile (version_string): Bump to 1.00. + + * tree.c (scan_directory_tree): Handle case where we do not + have permissions to open a directory. + + * write.c (xfwrite): New function - wrapper for fwrite, + except that we print message and punt if write fails. + + * write.c: Move include of mkisofs.h and iso9660.h until after + string.h and stdlib.h is included. + + * write.c: Do not attempt to use strerror on sun systems. + +Thu Dec 9 13:17:28 1993 R.-D. Marzusch (marzusch@odiehh.hanse.de) + + * exclude.c, exclude.h: New files. Contains list of files to + exclude from consideration. + + * Makefile: Compile exclude.c, add dependencies to other files. + + * mkisofs.8: Describe -x option. + + * mkisofs.c: Include exclude.h, handle -x option. + + +Fri Dec 10 01:07:43 1993 Peter van der Veen (peterv@qnx.com) + + * mkisofs.c, mkisofs.h: Moved declaration of root_record. + + * mkisofs.h: Added prototype for get_733(). + + * write.c(iso_write), tree.c, rock.c(generate_rock_ridge_attributes): + Added defines for QNX operation system + + * rock.c(generate_rock_ridge_attributes): symbolic links should + not have CONTINUE component flag set unless there are multiple + component records, and mkisofs does not generate these. + st_ctime was stored as the creation time, changed to attribute time. + QNX has a creation time, so that is stored as well under QNX. + +Thu Oct 28 19:54:38 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.99. + + * write.c(iso_write): Put hour, minute, second into date fields in + volume descriptor. + + * write.c (iso_write): Set file_structure_version to 1, instead of + ' ' (Seems to screw up Macs). + +Sun Oct 17 01:13:36 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.98. + + Increment nlink in root directory when rr_moved directory is present. + + * tree.c (increment_nlink): New function. + + * tree.c (finish_cl_pl_entries): Call increment_nlink for all + references to the root directory. + + * tree.c (root_statbuf): New variable. + + * tree.c (scan_directory_tree): Initialize root_statbuf when we + stat the root directory. + + * tree.c (generate_reloc_directory): Use root_statbuf when + generating the Rock Ridge stuff for the ".." entry in the + reloc_dir. + + * tree.c (scan_directory_tree): Use root_statbuf when generating + the ".." entry in the root directory. + +Sat Oct 16 10:28:30 1993 Eric Youngdale (eric@kafka) + + Fix path tables so that they are sorted. + + * tree.c (assign_directory_addresses): Move to write.c + + * write.c (generate_path_tables): Create an array of pointers to + the individual directories, and sort it based upon the name and + the parent path table index. Then update all of the indexes and + repeat the sort until the path table indexes no longer need to be + changed, and then write the path table. + + Fix problem where hard links were throwing off the total extent count. + + * write.c (iso_write): Call assign_file_addresses, and then + use last_extent to determine how big the volume is. + + * write.c (generate_one_directory): Decrement n_data_extents + for hard links to non-directories so that the expected number + of extents is written correctly. + + * write.c(assign_file_addresses): New function. + +Fri Oct 15 22:35:43 1993 Eric Youngdale (eric@kafka) + + The standard says we should do these things: + + * tree.c (generate_reloc_directory): Add RR attributes to + the rr_moved directory. + + * mkisofs.c(main): Change ER text strings back to recommended + values. + +Tue Oct 12 21:07:38 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.97. + + * tree.c (scan_directory_tree): Do not insert PL entry into + root directory record (i.e. !parent) + + * tree.c (finish_cl_pl_entries): Do not rely upon name + comparison to locate parent - use d_entry->self instead, + which is guaranteed to be correct. + + * mkisofs.h: New variable n_data_extents. + + * tree.c: Declare and initialize n_data_extents to 0. + (scan_directory_tree) for non-directories, add + ROUND_UP(statbuf.st_size) to n_data_extents. + (sort_n_finish): Increment n_data_extents for translation tables, + as appropriate. + + * write.c(iso_write): Add n_data_extents to the + volume_space_size field. + + * hash.c(add_hash): If size != 0 and extent == 0, or + if size == 0 and extent != 0, then complain about + inserting this into the hash table. Kind of a sanity check. + +Sat Oct 9 16:39:15 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.96. + + Numerous bugfixes, thanks to a one-off disc from rab@cdrom.com. + + * write.c(generate_one_directory): Wait until after we have + filled in the starting_extent field to s_entry before calling + add_hash. This fixes a problem where the hash table gets an + extent of 0 for all regular files, and this turns up when you have + hard links on the disc. (The hash table allows us to have each + hard link point to the same extent on the cdrom, thereby saving + some space). + + * tree.c(scan_directory_tree): Set statbuf.st_dev and + statbuf.st_ino to the UNCACHED numbers for symlinks that we + are not following. This prevents the function find_hash from + returning an inode that cooresponds to the file the symlink points + to, which in turn prevents generate_one_directory from filling in + a bogus file length (should be zero for symlinks). + + * tree.c(scan_directory_tree): Always call lstat for the file + so that non-RockRidge discs get correct treatment of symlinks. + Improve error message when we ignore a symlink on a non-RR disc. + + * write.c(generate_one_directory): Set fields for starting_extent + and size in the "." and ".." entries before we add them to the + file hash. Fixes problems with incorrect backlinks for second + level directories. + +Wed Oct 6 19:53:40 1993 Eric Youngdale (eric@kafka) + + * write.c (write_one_file): Print message and punt if we are + unable to open the file. + + * tree.c(scan_directory_tree): For regular files, use the access + function to verify that the file is readable in the first place. + If not, issue a warning and skip it. For directories, it probably + does not matter, since we would not be able to descend into them + in the first place. + +Wed Sep 29 00:02:47 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.95. + + * write.c, tree.c: Cosmetic changes to printed information. + + * tree.c(scan_directory_tree): Set size to zero for + special stub entries that correspond to the + relocated directories. Hopefully last big bug. + + * mkisofs.h: Change TABLE_INODE, UNCACHED_* macros + to be 0x7fff... to be compatible with signed datatypes. + +Mon Sep 27 20:14:49 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.94. + + * write.c (write_path_tables): Actually search the + directory for the matching entry in case we renamed + the directory because of a name conflict. + + * tree.c(scan_directory_tree): Take directory_entry pointer + as second argument so that we can create a backpointer + in the directory structure that points back to the original + dir. + + * mkisofs.c: Fix call to scan_directory_tree to use new calling + sequence. + + * write.c(generate_one_directory): Punt if the last_extent counter + ever exceeds 700Mb/2048. Print name of responsible file, + extent counter, and starting extent. Perhaps we can catch it in + the act. + +Sun Sep 26 20:58:05 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.93. + + * tree.c(scan_directory_tree): Handle symlinks better. Either + leave them as symlinks, or erase any trace that they were a + symlink but do not do it 1/2 way as before. Also, watch for + directory loops created with symlinks. + + * mkisofs.h: Add new flag follow_links. + + * mkisofs.c: Add command line switch "-f" to toggle follow_links. + + * mkisofs.8: Document new switch. + + * tree.c: Add code to handle symlinks using new flag. + + * hash.c: Add add_directory_hash, find_directory_hash functions. + + * mkisofs.h: Add prototypes. + +Sat Sep 25 14:26:31 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.92. + + * mkisofs.c: Make sure path is an actual directory before trying + to scan it. + + * mkisofs.h: Add DECL and FDECL? macros for sparc like systems. + Do proper define of optind and optarg under SVr4. + + * tree.c: Change translation table name from YMTRANS.TBL to TRANS.TBL. + + * mkisofs.c: Neaten up message in extension record when RRIP is + in use. + + * Throughout - change all function declarations so that + traditional C compilers (i.e. sparc) will work. + + * Makefile: Change to use system default C compiler. + + * mkisofs.c: Add some stuff so that this will compile under VMS. + Many things missing for VMS still. + + * iso9660.h: Do not use zero length array in struct definition. + + * tree.c (sort_n_finish): Account for this. + + * Change copyright notice. + + +Wed Aug 25 08:06:51 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.91. + + * mkisofs.h: Only include sys/dir.h for linux. Other systems + will need other things. + + * mkisofs.c, tree.c: Include unistd.h. + + * Makefile: Use OBJS to define list of object files. + +Sun Aug 22 20:55:17 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.9. + + * write.c (iso_7*): Fix so that they work properly on Motorola + systems. + +Fri Aug 20 00:14:36 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.8. + + * rock.c: Do not mask off write permissions from posix file modes. + +Wed Aug 18 09:02:12 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.7. + + * rock.c: Do not write NM field for . and .. (redundant and a + waste of space). + + * mkisofs.c: Take -P and -p options for publisher and preparer id + fields. + + * write.c: Store publisher and preparer id in volume + descriptor. + + * rock.c: Write optional SP field to identify SUSP. Write + optional CE field to point to the extension header. + + * tree.c: Request SP and CE fields be added to root directory. + + * tree.c: Fix bug in name conflict resolution. + + * write.c: Fill in date fields in the colume descriptor. + + * write.c (write_one_file): If the file is large enough, write in + chunks of 16 sectors to improve performance. + + * hash.c (add_hash, find_hash, etc): Do not hash s_entry, instead + store relevant info in hash structure (we free s_entry structs as + we write files, and we need to have access to the hash table the + whole way through. + + * write.c: Add a few statistics about directory sizes, RR sizes, + translation table sizes, etc. + + * tree.c: Use major, not MAJOR. Same for minor. Define S_ISSOCK + and S_ISLNK if not defined. + + * rock.c: Define S_ISLNK if not defined. + + * mkisofs.c: Print out max memory usage. Fix bug in call to getopt. + + * mkisofs.c, Makefile (version_string): Bump to 0.6. + + * tree.c: Simplify the calculation of isorec.len, isorec.name_len + and the calculation of the path table sizes by doing it all at + one point after conflict resolution is done. + + * tree.c: scan_directory_tree is now responsible for generating + the line that goes into the YMTRANS.TBL file. These lines are + collected later on into something that will be dumped to the + file. Correctly handle all of the special file types. + +Mon Aug 16 21:59:47 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.5. + + * mkisofs.c: Add -a option (to force all files to be + transferred). Remove find_file_hash stuff. + + * write.c: Pad length even if Rock Ridge is not in use. + + * hash.c: Rewrite hash_file_* stuff so that it can be used to + easily detect (and look up) filenames that have been accepted + for use in this directory. Used for name collision detection. + + * tree.c (sort_n_finish): If two names collide, generate a unique + one (verified with the hash routines). Change the lower priority + name if there is a difference. + + + +Sat Aug 14 13:18:21 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c, Makefile (version_string): Bump to 0.4. + + * tree.c (load_translation_table): New function - read + YMTRANS.TBL. (scan_directory_tree) Call it. + + * mkisofs.c (iso9660_file_length): Call find_file_hash to see + if translated name is specified. If so, use it. + + * hash.c (name_hash, add_file_hash, find_file_hash, + flush_file_hash): New functions for hashing stuff from + YMTRANS.TBL. + + * mkisofs.h: Add a bunch of prototypes for the new functions. + + * mkisofs.8: Update. + + * mkisofs.c, Makefile (version_string): Bump to 0.3. + + * Makefile: Add version number to tar file in dist target. + + * mkisofs.c: Call finish_cl_pl_entries() after directories have + been generated, and extent numbers assigned. + + * write.c (generate_one_directory): Update s_entry->size for + directories (as well as isorec.size). + + * rock.c: Add code to generate CL, PL, and RE entries. The + extent numbers for the CL and PL entries are NULL, and these + are filled in later once we know where they actually belong. + + * mkisofs.h: Add parent_rec to directory_entry. Used to fix CL/PL + stuff. + + * tree.c (scan_directory_tree): Set flag to generate CL/PL/RE + entries as required, update sizes as well. + +Fri Aug 13 19:49:30 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c (version_string): Bump to 0.2. + + * hash.c: Do not use entries with inode == 0xffffffff or dev == + 0xffff. + + * write.c (write_path_tables): Strip leading directory specifications. + + * mkisofs.h: Add definition for reloc_dir symbol. Add prototype + for sort_n_finish, add third parameter to scan_directory_tree + (for true parent, when directories are relocated). + + * mkisofs.c (main): Modify call to scan_directory_tree. Call + sort_n_finish for reloc_dir. + + * tree.c (sort_n_finish): New function - moved code from + scan_directory_tree. + + * tree.c (generate_reloc_directory): New function. Generate + directory to hold relocated directories. + + * tree.c (scan_directory_tree): Strip leading directories when + generating this_dir->name. If depth is too great, then move + directory to reloc_dir (creating if it does not exist, and leave + a dummy (non-directory) entry in the regular directory so that + we can eventually add the required Rock Ridge record. + + * tree.c (scan_directory_tree): Use s_entry instead of sort_dir, + assign to this_dir->contents sooner. + +Thu Aug 12 22:38:17 1993 Eric Youngdale (eric@kafka) + + * mkisofs.c (usage): Fix syntax. + + * mkisofs.c (main): Add new argument to scan_directory_tree + + * tree.c (scan_directory_tree): If directory is at depth 8 or + more, create rr_moved directory in main directory. + +Mon Jul 26 19:45:47 1993 Eric Youngdale (eric@kafka) + + * mkisofs v 0.1 released. + diff --git a/genisoimage/ChangeLog.mkhybrid b/genisoimage/ChangeLog.mkhybrid new file mode 100644 index 0000000..e641d96 --- /dev/null +++ b/genisoimage/ChangeLog.mkhybrid @@ -0,0 +1,482 @@ +Mon May 1 14:51:00 BST 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.13a01 + + mkhybrid has now been merged with, and is now part of mkisofs + +Wed Apr 26 10:18:44 BST 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12.1a10 + + The -icon-position will now attempt to preserve folder window + positions, scroll bars, views etc. for Apple/Unix file formats + that support this information (currently CAP, EtherShare, Netatalk) + + Added -root-info option - which works with the -icon-position + option to preserve the root folder window characteristics. + See README.rootinfo for more about this option. + + Added 'mac-roman' to the -jcharset option. Converts Macintosh + Roman file name characters to the correct Joliet characters. + +Tue Apr 18 14:06:00 BST 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12.1a07 + + HFS files/directories are made invisible (HFS_FNDR_ISINVISIBLE + flag set) if the ISO file/directory is hidden. + +Mon Apr 3 22:04:00 BST 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12.1a05 + + Custom HFS volume or folder icons are now recoginised + +Sun Mar 19 19:12:00 GMT 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12.1a03 + + New options -hfs-type & -hfs-creator + +Wed Mar 8 11:26:00 GMT 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12 + + Final release of mkhybrid v1.12 + + mkhybrid will now be integrated with the cdrecord package (see: + ftp://ftp.fokus.gmd.de/pub/unix/cdrecord/alpha) + + +Wed Feb 23 14:35:20 GMT 2000 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b6.0 + + Now based on mkisofs v1.12 available as part of the cdrecord + package from ftp://ftp.fokus.gmd.de/pub/unix/cdrecord/ + + Will now create an HFS volume of at least 800k in size. + + Added option to preserve the HFS icon position (if it exists) + from a Apple/Unix file. Use -icon-position (Alpha) + +Thu Nov 25 19:59:27 GMT 1999 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b5.4 + + Added partial support for Microsoft's "Services for Macintosh" + format files. See the man page for details. + + mkhybrid no longer tries to work out the "disk cluster size" + for use with Apple File Exchange. The disk cluster size now needs + to be given on the command line (-cluster-size). The code involved + was not portable across various operating systems. + + Added minor changes for Rhapsody and BeOS. + + Cleaned up the code in apple.c (thanks to Ed Randall + <ed_randall@yahoo.com>). + + mkhybrid will now create a valid HFS partition as the last session + on a multisession CD. (Alpha) + +Sun Aug 8 10:36:15 BST 1999 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b5.3 + + Changed the nature of the -hfs and -apple command line options - + see README.mkhybrid for details + + Added PReP boot option from Troy Benjegerdes - see README.prep_boot + + Added support for AppleDouble/Single file names as "Pascal Strings" + + Added checks for Joliet and Rock Ridge filename clashes. + + Fixed minor install bug in Makefile.in + +Tue Apr 30 21:33:39 BST 1999 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b5.2 + + Fixed bug where CREATOR/TYPE not padded with spaces if less + than 4 characters + + Added support for "DAVE" format files (and AppleDouble v2) + use --dave + + Fixed a small signed char bug in name.c + + Fixed bug in diag/isoinfo.c - didn't support UCS level 1 + filenames that mkisofs/mkhybrid now creates with the -J option. + + +Thu Apr 7 20:29:04 BST 1999 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b5.1 + + Fixed bugs with MacBinary names and symbolic links to HFS files + when using the -f option + + Re-introduced some minor changes "lost" from v1.12b4.8 + + Forgot to add -hide-hfs-list option in previous version ... + +Tue Mar 30 08:31:13 BST 1999 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b5.0 + + Now based on mkisofs v1.12b5 + + Option -mac-name now only uses the HFS name if the file is one + of the known HFS file types + + Added -hide-list, -hide-joliet-list, -hide-hfs-list, -exclude-list + and -path-list options. Allows a list of filenames to be excluded or + hidden to be given in a file instead of on the command line. + + Added option -hfs-volid to give the HFS volume its own name (not + using the ISO9660 volume name). + + +Tue Jan 5 15:44:24 GMT 1999 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12b4.8 + + Fixed an AppleDouble bug and added better support for more Unix + flavours. + + Fixed -hide-hfs bug that corrupted some HFS hidden files + + Made the verbose output less verbose. + + Added initial support for the AutoStart feature. + + HFS partition maps can now be added without having to create + a bootable HFS CD (as pre-v1.12a4.7). + + Added option to specify the PC Exchange "cluster size". + +Mon Aug 24 23:18:38 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.7 + + Fixed SGI/XINET and PC Exchange bugs + + By default, the output image no longer has an HFS partition map + (as pre-v1.12a3.4). Partition maps are only added if making a + bootable HFS CD + + Fixed possible bug with odd-length structure alignment with gcc on + some architectures + +Tue Aug 4 23:09:17 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.6 + + Made a couple of Netatalk changes + + Altered way Apple/Unix associated files are excluded - e.g. + if just --cap is selected, then files associated with the other + Apple/Unix encodings are processed as normal files. Previously they + would have been ignored + + Added option (-no-desktop) to prevent the (empty) HFS desktop files + being created. These will be created when the CD is used on a + Macintosh (and stored in the System Folder). + +Sun Jul 26 09:44:50 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.5 + + Fixed serious bug that could cause corrupt output when used with + the -J option + +Tue Jul 21 14:33:20 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.4 + + HFS file/directory names that share the first 31 characters have + '_N' (N == decimal number) substituted for the last few characters + to generate unique names. + + 1 year since the first release ... + +Sat Jul 11 12:57:04 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.3 + + Added options to "hide" (options -hide and -hide-joliet) files + or directories from the ISO9660/RockRidge and/or Joliet directory + trees. + + Renamed the -hfs-exclude option to -hide-hfs to be compatible + with the above options. + + Fixed a bug with the -hide-hfs option (very rare case ...) + +Thu Jun 25 20:02:20 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.2 + + Fixed an HFS bug introduced with v1.12a3.4 that created some + corrupt HFS volumes over about 400Mb + + Tighten up checking for MacBinary files to prevent false matches + +Sun Jun 21 11:55:09 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.1 + + Default TYPE and CREATOR can now be set via the .mkisofsrc file + + Order of magic and mapping file on the command line is now + important. This defines the order in which TYPE and CREATOR are set. + + Apple/Unix file types found are logged as part of the verbose output + (need to give -v twice) + + Added option (-log-file) to redirect stderr messages + + Added option (-hfs-exclude) to exclude files/directories from + the HFS part of the CD. + + Fixed a couple of MacBinary/AppleSingle bugs. + +Thu Jun 8 23:40:56 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a4.0 + + Resource fork file names not added to TRANS.TBL + + Re-enabled support of non-regular Win32 files. GNU-Win32 can + create symbolic links etc. These are now recognised. + + mkhybrid man page added. + + Based on mkisofs v1.12b4 + +Wed May 20 12:54:36 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a3.5 + + Added support for using a "magic" file to set CREATOR/TYPE for + a file - see README.hfs_magic for details. + +Mon May 18 16:22:32 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a3.4 + + Added possible support for bootable Mac CDs - see README.hfs_boot + or details. + + Fixed -x bug (mkisofs v1.12 bug) + +Mon May 4 14:23:46 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a3.3 + + Added support for UShare Mac/Unix files + + Individual Mac/Unix file types can now be selected instead + of searching for all possible types. See README.mkhybrid for + details. + +Fri May 1 10:34:29 BST 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a3.2 + + Various bug fixes to Mac file names + +Tue Mar 10 14:42:03 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a3.1 + + Added -no-hfs-files option that assumes there are no Unix/Mac + files (CAP, Netatalk, etc) - speeds up processing in these cases + + Case insensitive HFS file/folder names that are the same are now + allowed - one or more '_' characters are added to one or more of + the filenames. + + (Changed -macname option to -mac-name option) + +Mon Feb 23 16:09:27 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a3.0 + + Based on mkisofs v1.12b3 + + Fixed serious HFS bug that crept in from v1.11 -> v1.12 + +Tue Feb 17 16:20:12 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a2.0 + + Based on mkisofs v1.12b2 + + Improved Win32 support: using -r now makes all files executable + when run under Win95/NT4 + +Tue Feb 3 10:30:18 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a1.2 + + Fixed memory bug when used without any HFS options + + Improved PC Exchange support (although still needs testing) + +Tue Jan 27 10:32:26 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a1.1 + + Can now handle multiple hard linked source files with the -hfs option + (multiple hard linked source files are handled as separate files) + + configure script changed to check for ranlib + + Fixed a couple of AppleSingle bugs. + + Added option to use Mac names as starting point for ISO9660, Joliet + and RockRidge names + +Wed Jan 21 14:00:56 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.12a1 + + See README.mkhybrid for details + +Fri Jan 16 17:09:48 GMT 1998 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 1.11 + + Changed version numbering to be the same as mkisofs + + Code no longer considered beta level + + Minor changes to allow the code to be complied and run + on Win95/NT using Cygnus' GNU-Win32 (available from + http://www.cygnus.com/misc/gnu-win32/) + +Thu Dec 4 17:17:45 GMT 1997 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 0.49b + + Fixed an HFS bug that caused a failure with directory names that + had special AUFS characters + + Fixed mkisofs bug in eltorito.c that wrote warning messages + to stdout not stderr + + Code no longer considered alpha level + +Thu Nov 27 19:00:02 GMT 1997 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 0.48a + + Added Apple's extensions to ISO9660 that can be used instead of + the HFS options (see README.mkhybrid for more details). + + Added more verbose HFS error messages. + + Changed the Joliet option flag to -J (-j still works) to be + compatible the with next release of mkisofs (v1.12) + +Wed Oct 15 11:16:21 BST 1997 James Pearson <j.pearson@ge.ucl.ac.uk> + + Version 0.47a + + Fixed bug that prevented volume_space_size not being set in the + PVD (or SVD) + +Mon Oct 6 15:46:24 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.46a + + Small Joliet bug fix - source directories that are not readable + are set to empty ordinary files in the ISO9660 filesystem - this + is now true for the Joliet directory (partially responsible + for NT4 having problems with CDs where this happened) + + Minor documentation updates. + +Mon Sep 15 14:15:11 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.45a + + Attempt to prevent the HFS Catalog file growing (see + "Implementation" in README.mkhybrid for more details) + This is only likely to be a problem where folders have lots + of small files. + +Mon Aug 18 12:00:24 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.44a + + If the directories were deeper than 8 and the -D flag was not + used, then the "rr_moved" directory was not added to the Joliet + directory tree. This has now been fixed - but one day, the deep + Joliet directories may not have to be relocated ... + + Fixed memcmp problem with possible uninitialised memory in + j_compare_paths(), which *might* cause incorrect Joliet directory + sort order + +Wed Aug 13 14:58:56 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.43a + + Fixed bug for incorrect Joliet path table size + + Fixed some old minor mkisofs bugs (TRANS.TBL not having a + version number by default and incorrect date in the PVD). + +Mon Aug 11 17:17:07 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.42a + + Now will not try to create the HFS "Desktop DB" and "Desktop DF" + if they already exist when used with the HFS options. + + Fixed a serious bug in the hfs code that truncated some files. + + "TRANS.TBL" was missed out of the Joliet directory if the -T + option was given (previously an empty file with no name was used + which could cause problems on NT 4) + +Fri Aug 8 10:19:46 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.41a + + Fixed bug which created invalid HFS/ISO9660 volumes if the -j (Joliet) + option was not used + +Mon Aug 4 15:08:43 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.4a + + Added (partial?) Joliet support. + + Now based on mkisofs v1.11 + +Tue Jul 29 11:57:14 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.32a + + Allocation sizes improved to cut down on wasted space. Now uses + the HFS "allocation" size rounded up to the nearest 2048 bytes. + Savings can be significant with a large volume containing lots + of smallish files. + +Wed Jul 23 15:36:08 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.31a + + Deep directories (greater than RR_relocation_depth) cause core + dump in "copy_to_mac_volume" as the relocated directory was not + marked as an HFS folder. Fixed by putting deep HFS folders in + their correct location. + +Mon Jul 21 15:50:05 BST 1997 James Pearson <j.pearson@ps.ucl.ac.uk> + + Version 0.3a, first public release. diff --git a/genisoimage/RELEASE b/genisoimage/RELEASE new file mode 100644 index 0000000..c547f6e --- /dev/null +++ b/genisoimage/RELEASE @@ -0,0 +1,3 @@ +# @(#)RELEASE 1.35 04/09/09 joerg + +Release 2.01 diff --git a/genisoimage/TODO b/genisoimage/TODO new file mode 100644 index 0000000..cce3b24 --- /dev/null +++ b/genisoimage/TODO @@ -0,0 +1,57 @@ +/* @(#)TODO 1.6 03/04/27 joerg */ + 1) Finish multiple paths. Update nlink count on directories if it is + different than what stat returned. Save the nlink count that we store in + the rock ridge attributes so know when we don't have to adjust it. + + +Andy Polyakov <appro@fy.chalmers.se> +Well, it was rather hard to get it wrong... But the answer is "yes" if +you have to hear this very word. + +And while we're discussing this code. A *cosmetic* *suggestion*. +Consider modifying two lines above the "if(is_directory)" as following: + + set32(&fe->uid,0); + set32(&fe->gid,0); + +or to any other small number. Problem is that with -1 as now 'ls -l' +results in wider output which is rather annoying (it has to print +4294967295 twice while it formats for 8 chars). + +Cheers. A. + +/*--------------------------------------------------------------------------*/ + +Option to modify Volume id, ... in PVD after the image has been +created? + +/*--------------------------------------------------------------------------*/ +http://www.y-adagio.com/public/standards/iso_cdromr/tocont.htm + +Annex B has: + +Changes from ISO 9660:1988 to this International Standard: + +a) The Volume Descriptor Version is changed to indicate the new structure; + Version number 2 indicated the new specification. +b) The File Structure Version is changed to indicate the new structure; + Version number 2 indicated the new specification. +c) The limitation in the Depth of Hierarchy is lifted; + The levels in the hierarchy can exceed eight. +d) The File Identifier is not separated to components; + The SEPARATORS are not specified. + A complex file name can be expressed. +e) The File Identifier does not have File Version Numbers; + File with and without Version Numbers should not exist in the same directory. +f) The character used for filling byte positions which are specified to be characters is subject to agreement +between the originator and the recipient of the volume; +g) The length of File Identifier is limited to 207; + Long file name can be expressed. +h) The length of a Directory Identifier is limited to 207; + Long directory name can be expressed. +/*--------------------------------------------------------------------------*/ + +Extent # auch als off_t statt int + +Wenn HFS, dann max File size == 2 GB? + diff --git a/genisoimage/apple.c b/genisoimage/apple.c new file mode 100644 index 0000000..3939504 --- /dev/null +++ b/genisoimage/apple.c @@ -0,0 +1,2688 @@ +/* + * 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. + * + */ + +/* @(#)apple.c 1.19 04/03/02 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 James Pearson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Unix-HFS file interface including maping file extensions to TYPE/CREATOR + * + * Adapted from mkhfs routines for mkhybrid + * + * James Pearson 1/5/97 + * Bug fix JCP 4/12/97 + * Updated for 1.12 and added more Unix HFS filetypes. JCP 21/1/98 + * Tidy up to use Finfo and Dinfo for all formats where + * possible JCP 25/4/2000 + * + * Things still to de done: + * + * Check file size = finder + rsrc [+ data] is needed + */ + +#ifdef APPLE_HYB + +#include <mconfig.h> +#include "genisoimage.h" +#include <errno.h> +#include <fctldefs.h> +#include <utypes.h> +#include <ctype.h> +#include <netinet/in.h> +#include "apple.h" +#include <schily.h> + +#ifdef USE_MAGIC +#include <magic.h> +magic_t magic_state = NULL; +#ifndef MAGIC_ERROR +/* workaround for older ´API */ +#define MAGIC_ERROR 0 +#endif +#endif /* USE_MAGIC */ + +/* tidy up genisoimage definition ... */ +typedef struct directory_entry dir_ent; + +/* routines for getting HFS names and info */ +#ifndef HAVE_STRCASECMP +static int strcasecmp(const char *s1, const char *s2); +#endif +static int get_none_dir(char *, char *, dir_ent *, int); +static int get_none_info(char *, char *, dir_ent *, int); +static int get_cap_dir(char *, char *, dir_ent *, int); +static int get_cap_info(char *, char *, dir_ent *, int); +static int get_es_dir(char *, char *, dir_ent *, int); +static int get_es_info(char *, char *, dir_ent *, int); +static int get_dbl_dir(char *, char *, dir_ent *, int); +static int get_dbl_info(char *, char *, dir_ent *, int); +static int get_mb_info(char *, char *, dir_ent *, int); +static int get_sgl_info(char *, char *, dir_ent *, int); +static int get_fe_dir(char *, char *, dir_ent *, int); +static int get_fe_info(char *, char *, dir_ent *, int); +static int get_sgi_dir(char *, char *, dir_ent *, int); +static int get_sgi_info(char *, char *, dir_ent *, int); +static int get_sfm_info(char *, char *, dir_ent *, int); + +#ifdef IS_MACOS_X +static int get_xhfs_dir(char *, char *, dir_ent *, int); +static int get_xhfs_info(char *, char *, dir_ent *, int); +#else +#define get_xhfs_dir get_none_dir +#define get_xhfs_info get_none_info +#endif /* IS_MACOS_X */ + +static void set_ct(hfsdirent *, char *, char *); +static void set_Dinfo(byte *, hfsdirent *); +static void set_Finfo(byte *, hfsdirent *); +static void cstrncpy(char *, char *, int); +static unsigned char dehex(char); +static unsigned char hex2char(char *); +static void hstrncpy(unsigned char *, char *, int); +static int read_info_file(char *, void *, int); + +/*static unsigned short calc_mb_crc __PR((unsigned char *, long, unsigned short));*/ +static struct hfs_info *get_hfs_fe_info(struct hfs_info *, char *); +static struct hfs_info *get_hfs_sgi_info(struct hfs_info *, char *); +static struct hfs_info *match_key(struct hfs_info *, char *); + +static int get_hfs_itype(char *, char *, char *); +static void map_ext(char *, char **, char **, short *, char *); + +static afpmap **map; /* list of mappings */ +static afpmap *defmap; /* the default mapping */ +static int last_ent; /* previous mapped entry */ +static int map_num; /* number of mappings */ +static int mlen; /* min extension length */ +static char tmp[PATH_MAX]; /* tmp working buffer */ +static int hfs_num; /* number of file types */ +static char p_buf[PATH_MAX]; /* info working buffer */ +static FILE *p_fp = NULL; /* probe File pointer */ +static int p_num = 0; /* probe bytes read */ +static unsigned int hselect; /* type of HFS file selected */ + +struct hfs_type { /* Types of various HFS Unix files */ + int type; /* type of file */ + int flags; /* special flags */ + char *info; /* finderinfo name */ + char *rsrc; /* resource fork name */ + int (*get_info)(char *, char *, dir_ent *, int); /* finderinfo */ + /* function */ + int (*get_dir)(char *, char *, dir_ent *, int); /* directory */ + /* name */ + /* function */ + char *desc; /* description */ +}; + +/* Above filled in */ +static struct hfs_type hfs_types[] = { + {TYPE_NONE, INSERT, "", "", get_none_info, get_none_dir, "None"}, + {TYPE_CAP, INSERT, ".finderinfo/", ".resource/", + get_cap_info, get_cap_dir, "CAP"}, + {TYPE_NETA, INSERT, ".AppleDouble/", ".AppleDouble/", + get_dbl_info, get_dbl_dir, "Netatalk"}, + {TYPE_DBL, INSERT, "%", "%", get_dbl_info, get_dbl_dir, "AppleDouble"}, + {TYPE_ESH, INSERT, ".rsrc/", ".rsrc/", + get_es_info, get_es_dir, "EtherShare/UShare"}, + {TYPE_FEU, NOPEND, "FINDER.DAT", "RESOURCE.FRK/", + get_fe_info, get_fe_dir, "Exchange"}, + {TYPE_FEL, NOPEND, "finder.dat", "resource.frk/", + get_fe_info, get_fe_dir, "Exchange"}, + {TYPE_SGI, NOPEND, ".HSancillary", ".HSResource/", + get_sgi_info, get_sgi_dir, "XINET/SGI"}, + {TYPE_MBIN, PROBE, "", "", get_mb_info, get_none_dir, "MacBinary"}, + {TYPE_SGL, PROBE, "", "", get_sgl_info, get_none_dir, "AppleSingle"}, + {TYPE_DAVE, INSERT, "resource.frk/", "resource.frk/", + get_dbl_info, get_dbl_dir, "DAVE"}, + {TYPE_SFM, APPEND | NORSRC, ":Afp_AfpInfo", ":Afp_Resource", + get_sfm_info, get_none_dir, "SFM"}, + {TYPE_XDBL, INSERT, "._", "._", get_dbl_info, get_dbl_dir, + "MacOS X AppleDouble"}, + {TYPE_XHFS, APPEND | NOINFO, "/rsrc", "/rsrc", get_xhfs_info, get_xhfs_dir, + "MacOS X HFS"} +}; + +/* used by get_magic_match() return */ +static char tmp_type[CT_SIZE + 1], + tmp_creator[CT_SIZE + 1]; + +#ifdef __used__ +/* + * An array useful for CRC calculations that use 0x1021 as the "seed" + * taken from mcvert.c modified by Jim Van Verth. + */ + +static unsigned short mb_magic[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + +#endif /* __used__ */ + +#ifndef HAVE_STRCASECMP +static int +strcasecmp(const char *s1, const char *s2) +{ + while (tolower(*s1) == tolower(*s2)) { + if (*s1 == 0) + return (0); + s1++; + s2++; + } + return (tolower(*s1) - tolower(*s2)); +} +#endif + +/* + * set_ct: set CREATOR and TYPE in hfs_ent + * + * CREATOR and TYPE are padded with spaces if not CT_SIZE long + */ + +static void +set_ct(hfsdirent *hfs_ent, char *c, char *t) +{ + memset(hfs_ent->u.file.type, ' ', CT_SIZE); + memset(hfs_ent->u.file.creator, ' ', CT_SIZE); + + strncpy(hfs_ent->u.file.type, t, MIN(CT_SIZE, strlen(t))); + strncpy(hfs_ent->u.file.creator, c, MIN(CT_SIZE, strlen(c))); + + hfs_ent->u.file.type[CT_SIZE] = '\0'; + hfs_ent->u.file.creator[CT_SIZE] = '\0'; +} + +/* + * cstrncopy: Cap Unix name to HFS name + * + * ':' is replaced by '%' and string is terminated with '\0' + */ +static void +cstrncpy(char *t, char *f, int c) +{ + while (c-- && *f) { + switch (*f) { + case ':': + *t = '%'; + break; + default: + *t = *f; + break; + } + t++; + f++; + } + + *t = '\0'; +} + +/* + * dehex() + * + * Given a hexadecimal digit in ASCII, return the integer representation. + * + * Taken from linux/fs/hfs/trans.c by Paul H. Hargrove + */ +static unsigned char +dehex(char c) +{ + if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } + if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + 10); + } + if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + 10); + } +/* return (0xff); */ + return (0); +} + +static unsigned char +hex2char(char *s) +{ + unsigned char i1; + unsigned char i2; + unsigned char o; + + if (strlen(++s) < 2) + return (0); + + i1 = (unsigned char) s[0]; + i2 = (unsigned char) s[1]; + + if (!isxdigit(i1) || !isxdigit(i2)) + return (0); + + o = (dehex(i1) << 4) & 0xf0; + o |= (dehex(i2) & 0xf); + + return (o); +} + + +/* + * hstrncpy: Unix name to HFS name with special character + * translation. + * + * "%xx" or ":xx" is assumed to be a "special" character and + * replaced by character code given by the hex characters "xx" + * + * if "xx" is not a hex number, then it is left alone - except + * that ":" is replaced by "%" + * + */ +static void +hstrncpy(unsigned char *t, char *f, int c) +{ + unsigned char o; + + while (c-- && *f) { + switch (*f) { + case ':': + case '%': + if ((o = hex2char(f)) == 0) { + *t = conv_charset('%', in_nls, hfs_onls); + } else { + *t = o; + f += 2; + } + break; + default: + *t = conv_charset(*f, in_nls, hfs_onls); + break; + } + t++; + f++; + } + + *t = '\0'; +} + +/* + * basename: find just the filename with any directory component + */ +/* + not used at the moment ... +static char +basename(a) + char *a; +{ + char *b; + + if ((b = strchr(a, '/'))) + return (++b); + else + return (a); +} +*/ + +/* + * set_Dinfo: set directory info + */ +static void +set_Dinfo(byte *ptr, hfsdirent *ent) +{ + Dinfo *dinfo = (Dinfo *)ptr; + + /* finder flags */ + ent->fdflags = d_getw((unsigned char *) dinfo->frFlags); + + if (icon_pos) { + ent->u.dir.rect.top = + d_getw((unsigned char *) dinfo->frRect[0]); + ent->u.dir.rect.left = + d_getw((unsigned char *) dinfo->frRect[1]); + ent->u.dir.rect.bottom = + d_getw((unsigned char *) dinfo->frRect[2]); + ent->u.dir.rect.right = + d_getw((unsigned char *) dinfo->frRect[3]); + + ent->fdlocation.v = + d_getw((unsigned char *) dinfo->frLocation[0]); + ent->fdlocation.h = + d_getw((unsigned char *) dinfo->frLocation[1]); + + ent->u.dir.view = + d_getw((unsigned char *) dinfo->frView); + + ent->u.dir.frscroll.v = + d_getw((unsigned char *) dinfo->frScroll[0]); + ent->u.dir.frscroll.h = + d_getw((unsigned char *) dinfo->frScroll[1]); + + } else { + /* + * clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? + */ + ent->fdflags &= 0xfeff; + } +} + +/* + * set_Finfo: set file info + */ +static void +set_Finfo(byte *ptr, hfsdirent *ent) +{ + Finfo *finfo = (Finfo *)ptr; + + /* type and creator from finder info */ + set_ct(ent, finfo->fdCreator, finfo->fdType); + + /* finder flags */ + ent->fdflags = d_getw((unsigned char *) finfo->fdFlags); + + if (icon_pos) { + ent->fdlocation.v = + d_getw((unsigned char *) finfo->fdLocation[0]); + ent->fdlocation.h = + d_getw((unsigned char *) finfo->fdLocation[1]); + } else { + /* + * clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? + */ + ent->fdflags &= 0xfeff; + } +} + +/* + * get_none_dir: ordinary Unix directory + */ +static int +get_none_dir(char *hname, char *dname, dir_ent *s_entry, int ret) +{ + /* just copy the given name */ + hstrncpy((unsigned char *) (s_entry->hfs_ent->name), + dname, HFS_MAX_FLEN); + + return (ret); +} + +/* + * get_none_info: ordinary Unix file - try to map extension + */ +static int +get_none_info(char *hname, char *dname, dir_ent *s_entry, int ret) +{ + char *t, + *c; + hfsdirent *hfs_ent = s_entry->hfs_ent; + + map_ext(dname, &t, &c, &s_entry->hfs_ent->fdflags, s_entry->whole_name); + + /* just copy the given name */ + hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); + + set_ct(hfs_ent, c, t); + + return (ret); +} + +/* + * read_info_file: open and read a finderinfo file for an HFS file + * or directory + */ +static int +read_info_file(char *name, /* finderinfo filename */ + void *info, /* info buffer */ + int len /* length of above */) +{ + FILE *fp; + int num; + + /* clear out any old finderinfo stuf */ + memset(info, 0, len); + + if ((fp = fopen(name, "rb")) == NULL) + return (-1); + + /* read and ignore if the file is short - checked later */ + num = fread(info, 1, len, fp); + + fclose(fp); + + return (num); +} + +/* + * get_cap_dir: get the CAP name for a directory + */ +static int +get_cap_dir(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + FileInfo info; /* finderinfo struct */ + int num = -1; /* bytes read */ + hfsdirent *hfs_ent = s_entry->hfs_ent; + + num = read_info_file(hname, &info, sizeof (FileInfo)); + + /* check finder info is OK */ + if (num > 0 && + info.fi_magic1 == FI_MAGIC1 && + info.fi_magic == FI_MAGIC && + info.fi_bitmap & FI_BM_MACINTOSHFILENAME) { + /* use the finderinfo name if it exists */ + cstrncpy((char *) (hfs_ent->name), + (char *) (info.fi_macfilename), HFS_MAX_FLEN); + + set_Dinfo(info.finderinfo, hfs_ent); + + return (ret); + } else { + /* otherwise give it it's Unix name */ + hstrncpy((unsigned char *) (s_entry->hfs_ent->name), + dname, HFS_MAX_FLEN); + return (TYPE_NONE); + } +} + +/* +** get_cap_info: get CAP finderinfo for a file +*/ +static int +get_cap_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + FileInfo info; /* finderinfo struct */ + int num = -1; /* bytes read */ + hfsdirent *hfs_ent = s_entry->hfs_ent; + + num = read_info_file(hname, &info, sizeof (info)); + + /* check finder info is OK */ + if (num > 0 && + info.fi_magic1 == FI_MAGIC1 && + info.fi_magic == FI_MAGIC) { + + if (info.fi_bitmap & FI_BM_MACINTOSHFILENAME) { + /* use the finderinfo name if it exists */ + cstrncpy((char *) (hfs_ent->name), + (char *) (info.fi_macfilename), HFS_MAX_FLEN); + } else { + /* use Unix name */ + hstrncpy((unsigned char *) (hfs_ent->name), dname, + HFS_MAX_FLEN); + } + + set_Finfo(info.finderinfo, hfs_ent); +#ifdef USE_MAC_DATES + /* + * set created/modified dates - these date should have already + * been set from the Unix data fork dates. The finderinfo dates + * are in Mac format - but we have to convert them back to Unix + * for the time being + */ + if ((info.fi_datemagic & FI_CDATE)) { + /* use libhfs routines to get correct byte order */ + hfs_ent->crdate = d_toutime(d_getl(info.fi_ctime)); + } + if (info.fi_datemagic & FI_MDATE) { + hfs_ent->mddate = d_toutime(d_getl(info.fi_mtime)); + } +#endif /* USE_MAC_DATES */ + } else { + /* failed to open/read finderinfo - so try afpfile mapping */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + } + + return (ret); +} + +/* + * get_es_dir: get EtherShare/UShare finderinfo for a directory + * + * based on code from Jens-Uwe Mager (jum@helios.de) and Phil Sylvester + * <psylvstr@interaccess.com> + */ +static int +get_es_dir(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + es_FileInfo *einfo; /* EtherShare info struct */ + us_FileInfo *uinfo; /* UShare info struct */ + char info[ES_INFO_SIZE]; /* finderinfo buffer */ + int num = -1; /* bytes read */ + hfsdirent *hfs_ent = s_entry->hfs_ent; + + /* + * the EtherShare and UShare file layout is the same, but they store + * finderinfo differently + */ + einfo = (es_FileInfo *) info; + uinfo = (us_FileInfo *) info; + + num = read_info_file(hname, info, sizeof (info)); + + /* check finder info for EtherShare finderinfo */ + if (num >= (int)sizeof (es_FileInfo) && + d_getl(einfo->magic) == ES_MAGIC && + d_getw(einfo->version) == ES_VERSION) { + + set_Dinfo(einfo->finderinfo, hfs_ent); + + } else if (num >= (int)sizeof (us_FileInfo)) { + /* + * UShare has no magic number, so we assume that this is a valid + * info/resource file ... + */ + + set_Dinfo(uinfo->finderinfo, hfs_ent); + + } else { + /* failed to open/read finderinfo - so try afpfile mapping */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_dir(hname, dname, s_entry, TYPE_NONE); + return (ret); + } + + /* set name */ + hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); + + return (ret); +} + +/* + * get_es_info: get EtherShare/UShare finderinfo for a file + * + * based on code from Jens-Uwe Mager (jum@helios.de) and Phil Sylvester + * <psylvstr@interaccess.com> + */ +static int +get_es_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + es_FileInfo *einfo; /* EtherShare info struct */ + us_FileInfo *uinfo; /* UShare info struct */ + char info[ES_INFO_SIZE]; /* finderinfo buffer */ + int num = -1; /* bytes read */ + hfsdirent *hfs_ent = s_entry->hfs_ent; + dir_ent *s_entry1; + + /* + * the EtherShare and UShare file layout is the same, but they store + * finderinfo differently + */ + einfo = (es_FileInfo *) info; + uinfo = (us_FileInfo *) info; + + num = read_info_file(hname, info, sizeof (info)); + + /* check finder info for EtherShare finderinfo */ + if (num >= (int)sizeof (es_FileInfo) && + d_getl(einfo->magic) == ES_MAGIC && + d_getw(einfo->version) == ES_VERSION) { + + set_Finfo(einfo->finderinfo, hfs_ent); + + /* + * set create date - modified date set from the Unix + * data fork date + */ + + hfs_ent->crdate = d_getl(einfo->createTime); + + } else if (num >= (int)sizeof (us_FileInfo)) { + /* + * UShare has no magic number, so we assume that this is a valid + * info/resource file ... + */ + + set_Finfo(uinfo->finderinfo, hfs_ent); + + /* set create and modified date - if they exist */ + if (uinfo->ctime) + hfs_ent->crdate = + d_getl(uinfo->ctime); + + if (uinfo->mtime) + hfs_ent->mddate = + d_getl(uinfo->mtime); + } else { + /* failed to open/read finderinfo - so try afpfile mapping */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + return (ret); + } + + /* this should exist ... */ + if ((s_entry1 = s_entry->assoc) == NULL) + perr("TYPE_ESH error - shouldn't happen!"); + + /* set name */ + hstrncpy((unsigned char *) (hfs_ent->name), dname, HFS_MAX_FLEN); + + /* real rsrc file starts ES_INFO_SIZE bytes into the file */ + if (s_entry1->size <= ES_INFO_SIZE) { + s_entry1->size = 0; + hfs_ent->u.file.rsize = 0; + } else { + s_entry1->size -= ES_INFO_SIZE; + hfs_ent->u.file.rsize = s_entry1->size; + s_entry1->hfs_off = ES_INFO_SIZE; + } + + set_733((char *) s_entry1->isorec.size, s_entry1->size); + + return (ret); +} + +/* + * calc_crc() -- + * Compute the MacBinary II-style CRC for the data pointed to by p, with the + * crc seeded to seed. + * + * Modified by Jim Van Verth to use the magic array for efficiency. + */ +#ifdef __used__ +static unsigned short +calc_mb_crc(unsigned char *p, long len, unsigned short seed) +{ + unsigned short hold; /* crc computed so far */ + long i; /* index into data */ + + hold = seed; /* start with seed */ + for (i = 0; i < len; i++, p++) { + hold ^= (*p << 8); + hold = (hold << 8) ^ mb_magic[(unsigned char) (hold >> 8)]; + } + + return (hold); +}/* calc_mb_crc() */ + +#endif /* __used__ */ + +static int +get_mb_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + mb_info *info; /* finderinfo struct */ + char *c; + char *t; + hfsdirent *hfs_ent; + dir_ent *s_entry1; + int i; + +#ifdef TEST_CODE + unsigned short crc_file, + crc_calc; + +#endif + + info = (mb_info *) p_buf; + + /* + * routine called twice for each file - first to check that it is a + * valid MacBinary file, second to fill in the HFS info. p_buf holds + * the required raw data and it *should* remain the same between the + * two calls + */ + if (s_entry == 0) { + /* + * test that the CRC is OK - not set for MacBinary I files (and + * incorrect in some MacBinary II files!). If this fails, then + * perform some other checks + */ + +#ifdef TEST_CODE + /* leave this out for the time being ... */ + if (p_num >= MB_SIZE && info->version == 0 && info->zero1 == 0) { + crc_calc = calc_mb_crc((unsigned char *) info, 124, 0); + crc_file = d_getw(info->crc); +#ifdef DEBUG + fprintf(stderr, "%s: file %d, calc %d\n", hname, + crc_file, crc_calc); +#endif /* DEBUG */ + if (crc_file == crc_calc) + return (ret); + } +#endif /* TEST_CODE */ + + /* + * check some of the fields for a valid MacBinary file not + * zero1 and zero2 SHOULD be zero - but some files incorrect + */ + +/* if (p_num < MB_SIZE || info->nlen > 63 || info->zero2 || */ + if (p_num < MB_SIZE || info->zero1 || + info->zero2 || info->nlen > 63 || + info->version || info->nlen == 0 || *info->name == 0) + return (TYPE_NONE); + + /* check that the filename is OKish */ + for (i = 0; i < (int)info->nlen; i++) + if (info->name[i] == 0) + return (TYPE_NONE); + + /* check CREATOR and TYPE are valid */ + for (i = 0; i < 4; i++) + if (info->type[i] == 0 || info->auth[i] == 0) + return (TYPE_NONE); + } else { + /* we have a vaild MacBinary file, so fill in the bits */ + + /* this should exist ... */ + if ((s_entry1 = s_entry->assoc) == NULL) + perr("TYPE_MBIN error - shouldn't happen!"); + + hfs_ent = s_entry->hfs_ent; + + /* type and creator from finder info */ + t = (char *) (info->type); + c = (char *) (info->auth); + + set_ct(hfs_ent, c, t); + + /* finder flags */ + hfs_ent->fdflags = ((info->flags << 8) & 0xff00) | info->flags2; + + if (icon_pos) { + hfs_ent->fdlocation.v = + d_getw((unsigned char *) info->icon_vert); + hfs_ent->fdlocation.h = + d_getw((unsigned char *) info->icon_horiz); + } else { + /* + * clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? + */ + hfs_ent->fdflags &= 0xfeff; + } + + /* + * set created/modified dates - these date should have already + * been set from the Unix data fork dates. The finderinfo dates + * are in Mac format - but we have to convert them back to Unix + * for the time being + */ + hfs_ent->crdate = d_toutime(d_getl(info->cdate)); + hfs_ent->mddate = d_toutime(d_getl(info->mdate)); + + /* set name */ + hstrncpy((unsigned char *) (hfs_ent->name), + (char *) (info->name), MIN(HFS_MAX_FLEN, info->nlen)); + + /* set correct fork sizes */ + hfs_ent->u.file.dsize = d_getl(info->dflen); + hfs_ent->u.file.rsize = d_getl(info->rflen); + + /* update directory entries for data fork */ + s_entry->size = hfs_ent->u.file.dsize; + s_entry->hfs_off = MB_SIZE; + set_733((char *) s_entry->isorec.size, s_entry->size); + + /* + * real rsrc file starts after data fork (must be a multiple of + * MB_SIZE) + */ + s_entry1->size = hfs_ent->u.file.rsize; + s_entry1->hfs_off = MB_SIZE + ROUND_UP(hfs_ent->u.file.dsize, MB_SIZE); + set_733((char *) s_entry1->isorec.size, s_entry1->size); + } + + return (ret); +} + +/* + * get_dbl_dir: get Apple double finderinfo for a directory + * + * Based on code from cvt2cap.c (c) May 1988, Paul Campbell + */ +static int +get_dbl_dir(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + FileInfo info; /* finderinfo struct */ + a_hdr *hp; + a_entry *ep; + int num = -1; /* bytes read */ + int nentries; + FILE *fp; + hfsdirent *hfs_ent = s_entry->hfs_ent; + char name[64]; + int i; + int fail = 0; + int len = 0; + + hp = (a_hdr *) p_buf; + memset(hp, 0, A_HDR_SIZE); + + memset(name, 0, sizeof (name)); + + /* open and read the info/rsrc file (it's the same file) */ + if ((fp = fopen(hname, "rb")) != NULL) + num = fread(hp, 1, A_HDR_SIZE, fp); + + /* + * check finder info is OK - some Netatalk files don't have magic + * or version set - ignore if it's a netatalk file + */ + if (num == A_HDR_SIZE && ((ret == TYPE_NETA) || + (d_getl(hp->magic) == APPLE_DOUBLE && + (d_getl(hp->version) == A_VERSION1 || + d_getl(hp->version) == A_VERSION2)))) { + + /* read TOC of the AppleDouble file */ + nentries = (int) d_getw(hp->nentries); + if (fread(hp->entries, A_ENTRY_SIZE, nentries, fp) < 1) { + fail = 1; + nentries = 0; + } + /* extract what is needed */ + for (i = 0, ep = hp->entries; i < nentries; i++, ep++) { + switch ((int)d_getl(ep->id)) { + case ID_FINDER: + /* get the finder info */ + fseek(fp, (off_t)d_getl(ep->offset), SEEK_SET); + if (fread(&info, d_getl(ep->length), 1, fp) < 1) { + fail = 1; + } + break; + case ID_NAME: + /* get Mac file name */ + fseek(fp, (off_t)d_getl(ep->offset), SEEK_SET); + if (fread(name, d_getl(ep->length), 1, fp) < 1) + *name = '\0'; + len = d_getl(ep->length); + break; + default: + break; + } + } + + fclose(fp); + + /* skip this if we had a problem */ + if (!fail) { + + set_Dinfo(info.finderinfo, hfs_ent); + + /* use stored name if it exists */ + if (*name) { + /* + * In some cases the name is stored in the + * Pascal string format - first char is the + * length, the rest is the actual string. + * The following *should* be OK + */ + if (len == 32 && (int) name[0] < 32) { + cstrncpy(hfs_ent->name, &name[1], + MIN(name[0], HFS_MAX_FLEN)); + } else { + cstrncpy(hfs_ent->name, name, + HFS_MAX_FLEN); + } + } else { + hstrncpy((unsigned char *) (hfs_ent->name), + dname, HFS_MAX_FLEN); + } + } + } else { + /* failed to open/read finderinfo */ + fail = 1; + if (fp) + fclose(fp); + } + + if (fail) { + /* problem with the file - try mapping/magic */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_dir(hname, dname, s_entry, TYPE_NONE); + } + return (ret); +} + +/* + * Depending on the version, AppleDouble/Single stores dates + * relative to 1st Jan 1904 (v1) or 1st Jan 2000 (v2) + * + * The d_toutime() function uses 1st Jan 1904 to convert to + * Unix time (1st Jan 1970). + * + * The d_dtoutime() function uses 1st Jan 2000 to convert to + * Unix time (1st Jan 1970). + * + * However, NetaTalk files seem to do their own thing - older + * Netatalk files don't have a magic number of version and + * store dates in ID=7 (don't know how). Newer Netatalk files + * claim to be version 1, but store dates in ID=7 as if they + * were version 2 files. + */ + +/* + * get_dbl_info: get Apple double finderinfo for a file + * + * Based on code from cvt2cap.c (c) May 1988, Paul Campbell + */ +static int +get_dbl_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + FileInfo info; /* finderinfo struct */ + a_hdr *hp; + a_entry *ep; + int num = -1; /* bytes read */ + int nentries; + FILE *fp; + hfsdirent *hfs_ent = s_entry->hfs_ent; + dir_ent *s_entry1; + char name[64]; + int i; + int fail = 0; + int len = 0; + unsigned char dates[A_DATE]; + int ver = 0, dlen; + + hp = (a_hdr *) p_buf; + memset(hp, 0, A_HDR_SIZE); + + memset(name, 0, sizeof (name)); + memset(dates, 0, sizeof (dates)); + + /* get the rsrc file info - should exist ... */ + if ((s_entry1 = s_entry->assoc) == NULL) + perr("TYPE_DBL error - shouldn't happen!"); + + /* open and read the info/rsrc file (it's the same file) */ + if ((fp = fopen(hname, "rb")) != NULL) + num = fread(hp, 1, A_HDR_SIZE, fp); + + /* + * check finder info is OK - some Netatalk files don't have magic + * or version set - ignore if it's a netatalk file + */ + + ver = d_getl(hp->version); + if (num == A_HDR_SIZE && ((ret == TYPE_NETA) || + (d_getl(hp->magic) == APPLE_DOUBLE && + (ver == A_VERSION1 || ver == A_VERSION2)))) { + + /* read TOC of the AppleDouble file */ + nentries = (int) d_getw(hp->nentries); + if (fread(hp->entries, A_ENTRY_SIZE, nentries, fp) < 1) { + fail = 1; + nentries = 0; + } + /* extract what is needed */ + for (i = 0, ep = hp->entries; i < nentries; i++, ep++) { + switch ((int)d_getl(ep->id)) { + case ID_FINDER: + /* get the finder info */ + fseek(fp, (off_t)d_getl(ep->offset), SEEK_SET); + if (fread(&info, d_getl(ep->length), 1, fp) < 1) { + fail = 1; + } + break; + case ID_RESOURCE: + /* set the offset and correct rsrc fork size */ + s_entry1->size = d_getl(ep->length); + hfs_ent->u.file.rsize = s_entry1->size; + /* offset to start of real rsrc fork */ + s_entry1->hfs_off = d_getl(ep->offset); + set_733((char *) s_entry1->isorec.size, + s_entry1->size); + break; + case ID_NAME: + /* get Mac file name */ + fseek(fp, (off_t)d_getl(ep->offset), SEEK_SET); + if (fread(name, d_getl(ep->length), 1, fp) < 1) + *name = '\0'; + len = d_getl(ep->length); + break; + case ID_FILEI: + /* Workround for NetaTalk files ... */ + if (ret == TYPE_NETA && ver == A_VERSION1) + ver = A_VERSION2; + /* fall through */ + case ID_FILEDATESI: + /* get file info */ + fseek(fp, d_getl(ep->offset), 0); + dlen = MIN(d_getl(ep->length), A_DATE); + if (fread(dates, dlen, 1, fp) < 1) { + fail = 1; + } else { + /* get the correct Unix time */ + switch (ver) { + + case (A_VERSION1): + hfs_ent->crdate = + d_toutime(d_getl(dates)); + hfs_ent->mddate = + d_toutime(d_getl(dates+4)); + break; + case (A_VERSION2): + hfs_ent->crdate = + d_dtoutime(d_getl(dates)); + hfs_ent->mddate = + d_dtoutime(d_getl(dates+4)); + break; + default: + /* Use Unix dates */ + break; + } + } + break; + default: + break; + } + } + + fclose(fp); + + /* skip this if we had a problem */ + if (!fail) { + set_Finfo(info.finderinfo, hfs_ent); + + /* use stored name if it exists */ + if (*name) { + /* + * In some cases the name is stored in the + * Pascal string format - first char is the + * length, the rest is the actual string. + * The following *should* be OK + */ + if (len == 32 && (int) name[0] < 32) { + cstrncpy(hfs_ent->name, &name[1], + MIN(name[0], HFS_MAX_FLEN)); + } else { + cstrncpy(hfs_ent->name, name, + HFS_MAX_FLEN); + } + } else { + hstrncpy((unsigned char *) (hfs_ent->name), + dname, HFS_MAX_FLEN); + } + } + } else { + /* failed to open/read finderinfo */ + fail = 1; + if (fp) + fclose(fp); + } + + if (fail) { + /* problem with the file - try mapping/magic */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + } + return (ret); +} + +/* + * get_sgl_info: get Apple single finderinfo for a file + * + * Based on code from cvt2cap.c (c) May 1988, Paul Campbell + */ +static int +get_sgl_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + FileInfo *info = 0; /* finderinfo struct */ + a_hdr *hp; + static a_entry *entries; + a_entry *ep; + int nentries; + hfsdirent *hfs_ent; + dir_ent *s_entry1; + char name[64]; + int i; + int len = 0; + unsigned char *dates; + int ver = 0; + + /* + * routine called twice for each file + * - first to check that it is a valid + * AppleSingle file, second to fill in the HFS info. + * p_buf holds the required + * raw data and it *should* remain the same between the two calls + */ + hp = (a_hdr *) p_buf; + + if (s_entry == 0) { + if (p_num < A_HDR_SIZE || + d_getl(hp->magic) != APPLE_SINGLE || + (d_getl(hp->version) != A_VERSION1 && + d_getl(hp->version) != A_VERSION2)) + return (TYPE_NONE); + + /* check we have TOC for the AppleSingle file */ + nentries = (int) d_getw(hp->nentries); + if (p_num < (int)(A_HDR_SIZE + nentries * A_ENTRY_SIZE)) + return (TYPE_NONE); + + /* save the TOC */ + entries = (a_entry *) e_malloc(nentries * A_ENTRY_SIZE); + + memcpy(entries, (p_buf + A_HDR_SIZE), nentries * A_ENTRY_SIZE); + } else { + /* have a vaild AppleSingle File */ + memset(name, 0, sizeof (name)); + + /* get the rsrc file info - should exist ... */ + if ((s_entry1 = s_entry->assoc) == NULL) + perr("TYPE_SGL error - shouldn't happen!"); + + hfs_ent = s_entry->hfs_ent; + + nentries = (int) d_getw(hp->nentries); + ver = d_getl(hp->version); + + /* extract what is needed */ + for (i = 0, ep = entries; i < nentries; i++, ep++) { + switch ((int)d_getl(ep->id)) { + case ID_FINDER: + /* get the finder info */ + info = (FileInfo *) (p_buf + d_getl(ep->offset)); + break; + case ID_DATA: + /* set the offset and correct data fork size */ + hfs_ent->u.file.dsize = s_entry->size = + d_getl(ep->length); + /* offset to start of real data fork */ + s_entry->hfs_off = d_getl(ep->offset); + set_733((char *) s_entry->isorec.size, + s_entry->size); + break; + case ID_RESOURCE: + /* set the offset and correct rsrc fork size */ + hfs_ent->u.file.rsize = s_entry1->size = + d_getl(ep->length); + /* offset to start of real rsrc fork */ + s_entry1->hfs_off = d_getl(ep->offset); + set_733((char *) s_entry1->isorec.size, + s_entry1->size); + break; + case ID_NAME: + /* get Mac file name */ + strncpy(name, (p_buf + d_getl(ep->offset)), + d_getl(ep->length)); + len = d_getl(ep->length); + break; + case ID_FILEI: + /* get file info - ignore at the moment*/ + break; + case ID_FILEDATESI: + /* get file info */ + dates = (unsigned char *)p_buf + d_getl(ep->offset); + /* get the correct Unix time */ + if (ver == A_VERSION1) { + hfs_ent->crdate = + d_toutime(d_getl(dates)); + hfs_ent->mddate = + d_toutime(d_getl(dates+4)); + } else { + hfs_ent->crdate = + d_dtoutime(d_getl(dates)); + hfs_ent->mddate = + d_dtoutime(d_getl(dates+4)); + } + break; + default: + break; + } + } + + free(entries); + + if (info == NULL) { + /* + * failed to open/read finderinfo + * - so try afpfile mapping + */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, + hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + return (ret); + } + + set_Finfo(info->finderinfo, hfs_ent); + + /* use stored name if it exists */ + if (*name) { + /* + * In some cases the name is stored in the Pascal string + * format - first char is the length, the rest is the + * actual string. The following *should* be OK + */ + if (len == 32 && (int) name[0] < 32) { + cstrncpy(hfs_ent->name, &name[1], MIN(name[0], + HFS_MAX_FLEN)); + } else { + cstrncpy(hfs_ent->name, name, HFS_MAX_FLEN); + } + } else { + hstrncpy((unsigned char *) (hfs_ent->name), dname, + HFS_MAX_FLEN); + } + } + + return (ret); +} + +/* + * get_hfs_fe_info: read in the whole finderinfo for a PC Exchange + * directory - saves on reading this many times for each file. + * + * Based of information provided by Mark Weinstein <mrwesq@earthlink.net> + * + * Note: the FINDER.DAT file layout depends on the FAT cluster size + * therefore, files should only be read directly from the FAT media + * + * Only tested with PC Exchange v2.1 - don't know if it will work + * with v2.2 and above. + */ +static struct hfs_info * +get_hfs_fe_info(struct hfs_info *hfs_info, char *name) +{ + FILE *fp; + int fe_num, + fe_pad; + fe_info info; + int c = 0; + struct hfs_info *hfs_info1 = NULL; + char keyname[12]; + char *s, + *e, + *k; + int i; + + if ((fp = fopen(name, "rb")) == NULL) + return (NULL); + + /* + * no longer attempt to find out FAT cluster + * - rely on command line parameter + */ + if (afe_size <= 0) + return (NULL); + + fe_num = afe_size / FE_SIZE; + fe_pad = afe_size % FE_SIZE; + + while (fread(&info, 1, FE_SIZE, fp) != 0) { + + /* the Mac name may be NULL - so ignore this entry */ + if (info.nlen != 0) { + + hfs_info1 = + (struct hfs_info *)e_malloc(sizeof (struct hfs_info)); + /* add this entry to the list */ + hfs_info1->next = hfs_info; + hfs_info = hfs_info1; + + /* + * get the bits we need + * - ignore [cm]time for the moment + */ + cstrncpy(hfs_info->name, (char *) (info.name), + info.nlen); + + memcpy(hfs_info->finderinfo, info.finderinfo, INFOLEN); + + s = (char *) (info.sname); + e = (char *) (info.ext); + k = keyname; + + /* + * short (Unix) name is stored in PC format, + * so needs to be mangled a bit + */ + + /* name part */ + for (i = 0; i < 8; i++, s++, k++) { + if (*s == ' ') + break; + else + *k = *s; + } + + /* extension - if it exists */ + if (strncmp((const char *) (info.ext), " ", 3)) { + *k = '.'; + k++; + for (i = 0; i < 3; i++, e++, k++) { + if (*e == ' ') + break; + else + *k = *e; + } + } + *k = '\0'; + + hfs_info1->keyname = strdup(keyname); + } + /* + * each record is FE_SIZE long, and there are FE_NUM + * per each "cluster size", so we may need to skip the padding + */ + if (++c == fe_num) { + c = 0; + fseek(fp, (off_t)fe_pad, SEEK_CUR); + } + } + fclose(fp); + + return (hfs_info); +} + +/* + * get_hfs_sgi_info: read in the whole finderinfo for a SGI (XINET) + * directory - saves on reading this many times for each + * file. + */ +static struct hfs_info * +get_hfs_sgi_info(struct hfs_info *hfs_info, char *name) +{ + FILE *fp; + sgi_info info; + struct hfs_info *hfs_info1 = NULL; + + if ((fp = fopen(name, "rb")) == NULL) + return (NULL); + + while (fread(&info, 1, SGI_SIZE, fp) != 0) { + + hfs_info1 = (struct hfs_info *)e_malloc(sizeof (struct hfs_info)); + /* add this entry to the list */ + hfs_info1->next = hfs_info; + hfs_info = hfs_info1; + + /* get the bits we need - ignore [cm]time for the moment */ + cstrncpy(hfs_info->name, (char *)info.name, HFS_MAX_FLEN); + + memcpy(hfs_info->finderinfo, info.finderinfo, INFOLEN); + + /* use the HFS name as the key */ + hfs_info1->keyname = hfs_info->name; + + } + fclose(fp); + + return (hfs_info); +} + +/* + * del_hfs_info: delete the info list and recover memory + */ +void +del_hfs_info(struct hfs_info *hfs_info) +{ + struct hfs_info *hfs_info1; + + while (hfs_info) { + hfs_info1 = hfs_info; + hfs_info = hfs_info->next; + + /* key may be the same as the HFS name - so don't free it */ + *hfs_info1->name = '\0'; + if (*hfs_info1->keyname) + free(hfs_info1->keyname); + free(hfs_info1); + } +} + +/* + * match_key: find the correct hfs_ent using the Unix filename + * as the key + */ +static struct hfs_info * +match_key(struct hfs_info *hfs_info, char *key) +{ + while (hfs_info) { + if (strcasecmp(key, hfs_info->keyname) == 0) + return (hfs_info); + hfs_info = hfs_info->next; + } + + return (NULL); +} + +/* + * get_fe_dir: get PC Exchange directory name + * + * base on probing with od ... + */ +static int +get_fe_dir(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + struct hfs_info *hfs_info; + hfsdirent *hfs_ent = s_entry->hfs_ent; + + /* cached finderinfo stored with parent directory */ + hfs_info = s_entry->filedir->hfs_info; + + /* if we have no cache, then make one and store it */ + if (hfs_info == NULL) { + if ((hfs_info = get_hfs_fe_info(hfs_info, hname)) == NULL) + ret = TYPE_NONE; + else + s_entry->filedir->hfs_info = hfs_info; + } + if (ret != TYPE_NONE) { + /* see if we can find the details of this file */ + if ((hfs_info = match_key(hfs_info, dname)) != NULL) { + strcpy(hfs_ent->name, hfs_info->name); + + set_Dinfo(hfs_info->finderinfo, hfs_ent); + + return (ret); + } + } + /* can't find the entry, so use the Unix name */ + hstrncpy((unsigned char *)(hfs_ent->name), dname, HFS_MAX_FLEN); + + return (TYPE_NONE); +} + +/* + * get_fe_info: get PC Exchange file details. + * + * base on probing with od and details from Mark Weinstein + * <mrwesq@earthlink.net> + */ +static int +get_fe_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + struct hfs_info *hfs_info; + hfsdirent *hfs_ent = s_entry->hfs_ent; + + /* cached finderinfo stored with parent directory */ + hfs_info = s_entry->filedir->hfs_info; + + /* if we have no cache, then make one and store it */ + if (hfs_info == NULL) { + if ((hfs_info = get_hfs_fe_info(hfs_info, hname)) == NULL) + ret = TYPE_NONE; + else + s_entry->filedir->hfs_info = hfs_info; + } + if (ret != TYPE_NONE) { + char *dn = dname; + +#ifdef _WIN32_TEST + /* + * may have a problem here - v2.2 has long filenames, + * but we need to key on the short filename, + * so we need do go a bit of win32 stuff + * ... + */ + char sname[1024]; + char lname[1024]; + + cygwin32_conv_to_full_win32_path(s_entry->whole_name, lname); + + if (GetShortPathName(lname, sname, sizeof (sname))) { + if (dn = strrchr(sname, '\\')) + dn++; + else + dn = sname; + } +#endif /* _WIN32 */ + + /* see if we can find the details of this file */ + if ((hfs_info = match_key(hfs_info, dn)) != NULL) { + + strcpy(hfs_ent->name, hfs_info->name); + + set_Finfo(hfs_info->finderinfo, hfs_ent); + + return (ret); + } + } + /* no entry found - use extension mapping */ + if (verbose > 2) { + fprintf(stderr, "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + + return (TYPE_NONE); +} + +/* + * get_sgi_dir: get SGI (XINET) HFS directory name + * + * base on probing with od ... + */ +static int +get_sgi_dir(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + struct hfs_info *hfs_info; + hfsdirent *hfs_ent = s_entry->hfs_ent; + + /* cached finderinfo stored with parent directory */ + hfs_info = s_entry->filedir->hfs_info; + + /* if we haven't got a cache, then make one */ + if (hfs_info == NULL) { + if ((hfs_info = get_hfs_sgi_info(hfs_info, hname)) == NULL) + ret = TYPE_NONE; + else + s_entry->filedir->hfs_info = hfs_info; + } + /* find the matching entry in the cache */ + if (ret != TYPE_NONE) { + /* key is (hopefully) the real Mac name */ + cstrncpy(tmp, dname, strlen(dname)); + if ((hfs_info = match_key(hfs_info, tmp)) != NULL) { + strcpy(hfs_ent->name, hfs_info->name); + + set_Dinfo(hfs_info->finderinfo, hfs_ent); + + return (ret); + } + } + /* no entry found - use Unix name */ + hstrncpy((unsigned char *)(hfs_ent->name), dname, HFS_MAX_FLEN); + + return (TYPE_NONE); +} + +/* + * get_sgi_info: get SGI (XINET) HFS finder info + * + * base on probing with od ... + */ +static int +get_sgi_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + struct hfs_info *hfs_info; + hfsdirent *hfs_ent = s_entry->hfs_ent; + + /* cached finderinfo stored with parent directory */ + hfs_info = s_entry->filedir->hfs_info; + + /* if we haven't got a cache, then make one */ + if (hfs_info == NULL) { + if ((hfs_info = get_hfs_sgi_info(hfs_info, hname)) == NULL) + ret = TYPE_NONE; + else + s_entry->filedir->hfs_info = hfs_info; + } + if (ret != TYPE_NONE) { + /* + * tmp is the same as hname here, but we don't need hname + * anymore in this function ... see if we can find the + * details of this file using the Unix name as the key + */ + cstrncpy(tmp, dname, strlen(dname)); + if ((hfs_info = match_key(hfs_info, tmp)) != NULL) { + + strcpy(hfs_ent->name, hfs_info->name); + + set_Finfo(hfs_info->finderinfo, hfs_ent); + + return (ret); + } + } + /* no entry found, so try file extension */ + if (verbose > 2) { + fprintf(stderr, "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + + return (TYPE_NONE); +} + +/* + * get_sfm_info: get SFM finderinfo for a file + */ + +static byte sfm_magic[4] = {0x41, 0x46, 0x50, 0x00}; +static byte sfm_version[4] = {0x00, 0x00, 0x01, 0x00}; + +static int +get_sfm_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + sfm_info info; /* finderinfo struct */ + int num = -1; /* bytes read */ + hfsdirent *hfs_ent = s_entry->hfs_ent; + + num = read_info_file(hname, &info, sizeof (info)); + + /* check finder info is OK */ + if (num == sizeof (info) && + !memcmp((char *)info.afpi_Signature, (char *)sfm_magic, 4) && + !memcmp((char *)info.afpi_Version, (char *)sfm_version, 4)) { + /* use Unix name */ + hstrncpy((unsigned char *)(hfs_ent->name), dname, HFS_MAX_FLEN); + + set_Finfo(info.finderinfo, hfs_ent); + + } else { + /* failed to open/read finderinfo - so try afpfile mapping */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + } + + return (ret); +} + +#ifdef IS_MACOS_X +/* + * get_xhfs_dir: get MacOS X HFS finderinfo for a directory + * + * Code ideas from 'hfstar' by Marcel Weiher marcel@metaobject.com + * and another GNU hfstar by Torres Vedras paulotex@yahoo.com + * + * Here we are dealing with actual HFS files - not some encoding + * we have to use a system call to get the finderinfo + * + * The file name here is the pseudo name for the resource fork + */ +static int +get_xhfs_dir(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + int err; + hfsdirent *hfs_ent = s_entry->hfs_ent; + attrinfo ainfo; + struct attrlist attrs; + int i; + + memset(&attrs, 0, sizeof (attrs)); + + /* set flags we need to get info from getattrlist() */ + attrs.bitmapcount = ATTR_BIT_MAP_COUNT; + attrs.commonattr = ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | + ATTR_CMN_FNDRINFO; + + /* get the info */ + err = getattrlist(hname, &attrs, &ainfo, sizeof (ainfo), 0); + + if (err == 0) { + /* + * If the Finfo is blank then we assume it's not a + * 'true' HFS directory ... + */ + err = 1; + for (i = 0; i < sizeof (ainfo.info); i++) { + if (ainfo.info[i] != 0) { + err = 0; + break; + } + } + } + + /* check finder info is OK */ + if (err == 0) { + + hstrncpy((unsigned char *) (s_entry->hfs_ent->name), + dname, HFS_MAX_FLEN); + + set_Dinfo(ainfo.info, hfs_ent); + + return (ret); + } else { + /* otherwise give it it's Unix name */ + hstrncpy((unsigned char *) (s_entry->hfs_ent->name), + dname, HFS_MAX_FLEN); + return (TYPE_NONE); + } +} + +/* + * get_xhfs_info: get MacOS X HFS finderinfo for a file + * + * Code ideas from 'hfstar' by Marcel Weiher marcel@metaobject.com, + * another GNU hfstar by Torres Vedras paulotex@yahoo.com and + * hfspax by Howard Oakley howard@quercus.demon.co.uk + * + * Here we are dealing with actual HFS files - not some encoding + * we have to use a system call to get the finderinfo + * + * The file name here is the pseudo name for the resource fork + */ +static int +get_xhfs_info(char *hname, /* whole path */ + char *dname, /* this dir name */ + dir_ent *s_entry, /* directory entry */ + int ret) +{ + int err; + hfsdirent *hfs_ent = s_entry->hfs_ent; + attrinfo ainfo; + struct attrlist attrs; + int i; + int size; + + memset(&attrs, 0, sizeof (attrs)); + + /* set flags we need to get info from getattrlist() */ + attrs.bitmapcount = ATTR_BIT_MAP_COUNT; + attrs.commonattr = ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | + ATTR_CMN_FNDRINFO; + + /* get the info */ + err = getattrlist(hname, &attrs, &ainfo, sizeof (ainfo), 0); + + /* check finder info is OK */ + if (err == 0) { + + /* + * If the Finfo is blank and the resource file is empty, + * then we assume it's not a 'true' HFS file ... + * There will be not associated file if the resource fork + * is empty + */ + + if (s_entry->assoc == NULL) { + err = 1; + for (i = 0; i < sizeof (ainfo.info); i++) { + if (ainfo.info[i] != 0) { + err = 0; + break; + } + } + } + + if (err == 0) { + + /* use Unix name */ + hstrncpy((unsigned char *) (hfs_ent->name), dname, + HFS_MAX_FLEN); + + set_Finfo(ainfo.info, hfs_ent); + + /* + * dates have already been set - but we will + * set them here as well from the HFS info + * shouldn't need to check for byte order, as + * the source is HFS ... but we will just in case + */ + hfs_ent->crdate = d_getl((byte *)&ainfo.ctime.tv_sec); + + hfs_ent->mddate = d_getl((byte *)&ainfo.mtime.tv_sec); + } + + } + + if (err) { + /* not a 'true' HFS file - so try afpfile mapping */ +#if 0 + /* + * don't print a warning as we will get lots on HFS + * file systems ... + */ + if (verbose > 2) { + fprintf(stderr, + "warning: %s doesn't appear to be a %s file\n", + s_entry->whole_name, hfs_types[ret].desc); + } +#endif + ret = get_none_info(hname, dname, s_entry, TYPE_NONE); + } + + return (ret); +} +#endif /* IS_MACOS_X */ + +/* + * get_hfs_itype: get the type of HFS info for a file + */ +static int +get_hfs_itype(char *wname, char *dname, char *htmp) +{ + int wlen, + i; + int no_type = TYPE_NONE; + + wlen = strlen(wname) - strlen(dname); + + /* search through the known types looking for matches */ + for (i = 1; i < hfs_num; i++) { + /* skip the ones that we don't care about */ + if ((hfs_types[i].flags & PROBE) || + *(hfs_types[i].info) == TYPE_NONE) { + continue; + } + + strcpy(htmp, wname); + + /* + * special case - if the info file doesn't exist + * for a requested type, then remember the type - + * we don't return here, as we _may_ find another type + * so we save the type here in case - we will have + * problems if more than one of this type ever exists ... + */ + if (hfs_types[i].flags & NOINFO) { + no_type = i; + } else { + + /* append or insert finderinfo filename part */ + if (hfs_types[i].flags & APPEND) + strcat(htmp, hfs_types[i].info); + else + sprintf(htmp + wlen, "%s%s", hfs_types[i].info, + (hfs_types[i].flags & NOPEND) ? "" : dname); + + /* hack time ... Netatalk is a special case ... */ + if (i == TYPE_NETA) { + strcpy(htmp, wname); + strcat(htmp, "/.AppleDouble/.Parent"); + } + + if (!access(htmp, R_OK)) + return (hfs_types[i].type); + } + } + + return (no_type); +} + +/* + * set_root_info: set the root folder hfs_ent from given file + */ +void +set_root_info(char *name) +{ + dir_ent *s_entry; + hfsdirent *hfs_ent; + int i; + + s_entry = root->self; + + hfs_ent = (hfsdirent *) e_malloc(sizeof (hfsdirent)); + memset(hfs_ent, 0, sizeof (hfsdirent)); + + /* make sure root has a valid hfs_ent */ + s_entry->hfs_ent = root->hfs_ent = hfs_ent; + + /* search for correct type of root info data */ + for (i = 1; i < hfs_num; i++) { + if ((hfs_types[i].flags & PROBE) || + (hfs_types[i].get_info == get_none_info)) + continue; + + if ((*(hfs_types[i].get_dir))(name, "", s_entry, i) == i) + return; + } +} + + +/* + * get_hfs_dir: set the HFS directory name + */ +int +get_hfs_dir(char *wname, char *dname, dir_ent *s_entry) +{ + int type; + + /* get the HFS file type from the info file (if it exists) */ + type = get_hfs_itype(wname, dname, tmp); + + /* try to get the required info */ + type = (*(hfs_types[type].get_dir)) (tmp, dname, s_entry, type); + + return (type); +} + +/* + * get_hfs_info: set the HFS info for a file + */ +int +get_hfs_info(char *wname, char *dname, dir_ent *s_entry) +{ + int type, + wlen, + i; + + wlen = strlen(wname) - strlen(dname); + + /* we may already know the type of Unix/HFS file - so process */ + if (s_entry->hfs_type != TYPE_NONE) { + + type = s_entry->hfs_type; + + strcpy(tmp, wname); + + /* append or insert finderinfo filename part */ + if (hfs_types[type].flags & APPEND) + strcat(tmp, hfs_types[type].info); + else + sprintf(tmp + wlen, "%s%s", hfs_types[type].info, + (hfs_types[type].flags & NOPEND) ? "" : dname); + + type = (*(hfs_types[type].get_info))(tmp, dname, s_entry, type); + + /* if everything is as expected, then return */ + if (s_entry->hfs_type == type) + return (type); + } + /* we don't know what type we have so, find out */ + for (i = 1; i < hfs_num; i++) { + if ((hfs_types[i].flags & PROBE) || + *(hfs_types[i].info) == TYPE_NONE) { + continue; + } + + strcpy(tmp, wname); + + /* append or insert finderinfo filename part */ + if (hfs_types[i].flags & APPEND) { + strcat(tmp, hfs_types[i].info); + } else { + sprintf(tmp + wlen, "%s%s", hfs_types[i].info, + (hfs_types[i].flags & NOPEND) ? "" : dname); + } + + /* if the file exists - and not a type we've already tried */ + if (!access(tmp, R_OK) && i != s_entry->hfs_type) { + type = (*(hfs_types[i].get_info))(tmp, dname, + s_entry, i); + s_entry->hfs_type = type; + return (type); + } + } + + /* nothing found, so just a Unix file */ + type = (*(hfs_types[TYPE_NONE].get_info))(wname, dname, + s_entry, TYPE_NONE); + + return (type); +} + +/* + * get_hfs_rname: set the name of the Unix rsrc file for a file + * + * For the time being we ignore the 'NOINFO' flag - the only case + * at the moment is for MacOS X HFS files - for files the resource + * fork exists - so testing the "filename/rsrc" pseudo file as + * the 'info' filename is OK ... + */ +int +get_hfs_rname(char *wname, char *dname, char *rname) +{ + int wlen, + type, + i; + int p_fd = -1; + + wlen = strlen(wname) - strlen(dname); + + /* try to find what sort of Unix HFS file type we have */ + for (i = 1; i < hfs_num; i++) { + /* skip if don't want to probe the files - (default) */ + if (hfs_types[i].flags & PROBE) + continue; + + strcpy(rname, wname); + + /* if we have a different info file, the find out it's type */ + if (*(hfs_types[i].rsrc) && *(hfs_types[i].info)) { + /* first test the Info file */ + + /* append or insert finderinfo filename part */ + if (hfs_types[i].flags & APPEND) { + strcat(rname, hfs_types[i].info); + } else { + sprintf(rname + wlen, "%s%s", hfs_types[i].info, + (hfs_types[i].flags & NOPEND) ? + "" : dname); + } + + /* if it exists, then check the Rsrc file */ + if (!access(rname, R_OK)) { + if (hfs_types[i].flags & APPEND) { + sprintf(rname + wlen, "%s%s", dname, + hfs_types[i].rsrc); + } else { + sprintf(rname + wlen, "%s%s", + hfs_types[i].rsrc, dname); + } + + /* + * for some types, a rsrc fork may not exist, + * so just return the current type + * in these cases + */ + if (hfs_types[i].flags & NORSRC || + !access(rname, R_OK)) + return (hfs_types[i].type); + } + } else { + /* + * if we are probing, + * then have a look at the contents to find type + */ + if (p_fd < 0) { + /* open file, if not already open */ + if ((p_fd = open(wname, + O_RDONLY | O_BINARY)) < 0) { + /* can't open it, then give up */ + return (TYPE_NONE); + } else { + if ((p_num = read(p_fd, p_buf, + sizeof (p_buf))) <= 0) { + /* + * can't read, or zero length + * - give up + */ + close(p_fd); + return (TYPE_NONE); + } + /* get file pointer and close file */ + p_fp = fdopen(p_fd, "rb"); + close(p_fd); + if (p_fp == NULL) + return (TYPE_NONE); + } + } + /* + * call routine to do the work + * - use the given dname as this + * is the name we may use on the CD + */ + type = (*(hfs_types[i].get_info)) (rname, dname, 0, i); + if (type != 0) { + fclose(p_fp); + return (type); + } + if (p_fp) { + /* + * close file + * - just use contents of buffer next time + */ + fclose(p_fp); + p_fp = NULL; + } + } + } + + return (0); +} + +/* + * hfs_exclude: file/directory names that hold finder/resource + * information that we want to exclude from the tree. + * These files/directories are processed later ... + */ +int +hfs_exclude(char *d_name) +{ + /* we don't exclude "." and ".." */ + if (strcmp(d_name, ".") == 0) + return (0); + if (strcmp(d_name, "..") == 0) + return (0); + + /* do not add the following to our list of dir entries */ + if (DO_CAP & hselect) { + /* CAP */ + if (strcmp(d_name, ".finderinfo") == 0) + return (1); + if (strcmp(d_name, ".resource") == 0) + return (1); + if (strcmp(d_name, ".ADeskTop") == 0) + return (1); + if (strcmp(d_name, ".IDeskTop") == 0) + return (1); + if (strcmp(d_name, "Network Trash Folder") == 0) + return (1); + /* + * special case when HFS volume is mounted using Linux's hfs_fs + * Brad Midgley <brad@pht.com> + */ + if (strcmp(d_name, ".rootinfo") == 0) + return (1); + } + if (DO_ESH & hselect) { + /* Helios EtherShare files */ + if (strcmp(d_name, ".rsrc") == 0) + return (1); + if (strcmp(d_name, ".Desktop") == 0) + return (1); + if (strcmp(d_name, ".DeskServer") == 0) + return (1); + if (strcmp(d_name, ".Label") == 0) + return (1); + } + if (DO_DBL & hselect) { + /* Apple Double */ + /* + * special case when HFS volume is mounted using Linux's hfs_fs + */ + if (strcmp(d_name, "%RootInfo") == 0) + return (1); + /* + * have to be careful here - a filename starting with '%' + * may be vaild if the next two letters are a hex character - + * unfortunately '%' 'digit' 'digit' may be a valid resource + * file name ... + */ + if (*d_name == '%') + if (hex2char(d_name) == 0) + return (1); + } + if (DO_NETA & hselect) { + if (strcmp(d_name, ".AppleDouble") == 0) + return (1); + if (strcmp(d_name, ".AppleDesktop") == 0) + return (1); + } + if ((DO_FEU & hselect) || (DO_FEL & hselect)) { + /* PC Exchange */ + if (strcmp(d_name, "RESOURCE.FRK") == 0) + return (1); + if (strcmp(d_name, "FINDER.DAT") == 0) + return (1); + if (strcmp(d_name, "DESKTOP") == 0) + return (1); + if (strcmp(d_name, "FILEID.DAT") == 0) + return (1); + if (strcmp(d_name, "resource.frk") == 0) + return (1); + if (strcmp(d_name, "finder.dat") == 0) + return (1); + if (strcmp(d_name, "desktop") == 0) + return (1); + if (strcmp(d_name, "fileid.dat") == 0) + return (1); + } + if (DO_SGI & hselect) { + /* SGI */ + if (strcmp(d_name, ".HSResource") == 0) + return (1); + if (strcmp(d_name, ".HSancillary") == 0) + return (1); + } + if (DO_DAVE & hselect) { + /* DAVE */ + if (strcmp(d_name, "resource.frk") == 0) + return (1); + if (strcmp(d_name, "DesktopFolderDB") == 0) + return (1); + } +#ifndef _WIN32 + /* + * NTFS streams are not "seen" as files, + * so WinNT will not see these files - + * so ignore - used for testing under Unix + */ + if (DO_SFM & hselect) { + /* SFM */ + char *dn = strrchr(d_name, ':'); + + if (dn) { + if (strcmp(dn, ":Afp_Resource") == 0) + return (1); + if (strcmp(dn, ":Comments") == 0) + return (1); + if (strcmp(dn, ":Afp_AfpInfo") == 0) + return (1); + } + } +#endif /* _WIN32 */ + + if (DO_XDBL & hselect) { + /* XDB */ + if (strncmp(d_name, "._", 2) == 0) + return (1); + } + + return (0); +} + +/* + * print_hfs_info: print info about the HFS files. + * + */ +void +print_hfs_info(dir_ent *s_entry) +{ + fprintf(stderr, "Name: %s\n", s_entry->whole_name); + fprintf(stderr, "\tFile type: %s\n", hfs_types[s_entry->hfs_type].desc); + fprintf(stderr, "\tHFS Name: %s\n", s_entry->hfs_ent->name); + fprintf(stderr, "\tISO Name: %s\n", s_entry->isorec.name); + fprintf(stderr, "\tCREATOR: %s\n", s_entry->hfs_ent->u.file.creator); + fprintf(stderr, "\tTYPE: %s\n", s_entry->hfs_ent->u.file.type); +} + + +/* + * hfs_init: sets up the mapping list from the afpfile as well + * the default mapping (with or without) an afpfile + */ +void +hfs_init(char *name, Ushort fdflags, Uint hfs_select) +{ + FILE *fp; /* File pointer */ + int count = NUMMAP; /* max number of entries */ + char buf[PATH_MAX]; /* working buffer */ + afpmap *amap; /* mapping entry */ + char *c, + *t, + *e; + int i; + + /* setup number of Unix/HFS filetype - we may wish to not bother */ + if (hfs_select) { + hfs_num = sizeof (hfs_types) / sizeof (struct hfs_type); + + /* + * code below needs to be tidied up + * - most can be made redundant + */ + for (i = 0; i < hfs_num; i++) + hfs_types[i].flags &= ~1; /* 0xfffffffe */ + + for (i = 1; i < hfs_num; i++) + if (!((1 << i) & hfs_select)) + hfs_types[i].flags |= PROBE; + + hselect = hfs_select; + } else + hfs_num = hselect = 0; + +#ifdef DEBUG + for (i = 0; i < hfs_num; i++) + fprintf(stderr, "type = %d flags = %d\n", + i, hfs_types[i].flags); +#endif /* DEBUG */ + + /* min length set to max to start with */ + mlen = PATH_MAX; + +#ifdef USE_MAGIC + /* initialise magic state */ + if (magic_filename) { + magic_state = magic_open(MAGIC_ERROR); + if (magic_state == NULL) + perr("failed to initialise libmagic"); + if (magic_load(magic_state, magic_filename) == -1) { + fprintf(stderr, "failed to open magic file: %s\n", + magic_error(magic_state)); + exit(1); + } + } +#endif /* USE_MAGIC */ + + /* set defaults */ + map_num = last_ent = 0; + + /* allocate memory for the default entry */ + defmap = (afpmap *) e_malloc(sizeof (afpmap)); + + /* set default values */ + defmap->extn = DEFMATCH; + + /* make sure creator and type are 4 chars long */ + strcpy(defmap->type, BLANK); + strcpy(defmap->creator, BLANK); + + e = deftype; + t = defmap->type; + + while (*e && (e - deftype) < CT_SIZE) + *t++ = *e++; + + e = defcreator; + c = defmap->creator; + + while (*e && (e - defcreator) < CT_SIZE) + *c++ = *e++; + + /* length is not important here */ + defmap->elen = 0; + + /* no flags */ + defmap->fdflags = fdflags; + + /* no afpfile - no mappings */ + if (*name == '\0') { + map = NULL; + return; + } + if ((fp = fopen(name, "r")) == NULL) + perr("unable to open mapping file"); + + map = (afpmap **) e_malloc(NUMMAP * sizeof (afpmap *)); + + /* read afpfile line by line */ + while (fgets(buf, PATH_MAX, fp) != NULL) { + /* ignore any comment lines */ + c = tmp; + *c = '\0'; + if (sscanf(buf, "%1s", c) == EOF || *c == '#') + continue; + + /* increase list size if needed */ + if (map_num == count) { + count += NUMMAP; + map = (afpmap **)realloc(map, count * sizeof (afpmap *)); + if (map == NULL) + perr("not enough memory"); + } + /* allocate memory for this entry */ + amap = (afpmap *) e_malloc(sizeof (afpmap)); + + t = amap->type; + c = amap->creator; + + /* extract the info */ + if (sscanf(buf, "%s%*s%*1s%c%c%c%c%*1s%*1s%c%c%c%c%*1s", + tmp, c, c + 1, c + 2, c + 3, + t, t + 1, t + 2, t + 3) != 9) { + fprintf(stderr, + "error scanning afpfile %s - continuing", name); + free(amap); + continue; + } + /* copy the extension found */ + if ((amap->extn = (char *) strdup(tmp)) == NULL) + perr("not enough memory"); + + /* set end-of-string */ + *(t + 4) = *(c + 4) = '\0'; + + /* find the length of the extension */ + amap->elen = strlen(amap->extn); + + /* set flags */ + amap->fdflags = fdflags; + + /* see if we have the default creator/type */ + if (strcmp(amap->extn, DEFMATCH) == 0) { + /* get rid of the old default */ + free(defmap); + /* make this the default */ + defmap = amap; + continue; + } + /* update the smallest extension length */ + mlen = MIN(mlen, amap->elen); + + /* add entry to the list */ + map[map_num++] = amap; + + } + + /* free up some memory */ + if (map_num != count) { + map = (afpmap **) realloc(map, map_num * sizeof (afpmap *)); + if (map == NULL) + perr("not enough memory"); + } +} + +#ifdef USE_MAGIC +static int +try_map_magic(char *whole_name, char **type, /* set type */ + char **creator /* set creator */) +{ + const char * ret = magic_file(magic_state, whole_name); + +#ifdef DEBUG + fprintf(stderr, "magic_file(magic_state, \"%s\"): %s\n", + whole_name, ret ? ret : "NULL"); +#endif + /* + * check that we found a match; ignore results in the + * wrong format (probably due to libmagic's built-in rules) + */ + if (ret && strcspn(ret, " ") == CT_SIZE + && ret[CT_SIZE] == ' ' + && strcspn(ret + CT_SIZE + 1, " ") == CT_SIZE) { + memcpy(tmp_type, ret, CT_SIZE); + tmp_type[CT_SIZE] = 0; + memcpy(tmp_creator, ret + CT_SIZE + 1, CT_SIZE); + tmp_creator[CT_SIZE] = 0; +#ifdef DEBUG + fprintf(stderr, "tmp_type = \"%s\"; tmp_creator = \"%s\"\n", + tmp_type, tmp_creator); +#endif + *type = tmp_type; + *creator = tmp_creator; + return (1); + } + + return (0); +} +#endif /* USE_MAGIC */ + +/* + * map_ext: map a files extension with the list to get type/creator + */ +static void +map_ext(char *name, /* filename */ + char **type, /* set type */ + char **creator, /* set creator */ + short *fdflags, /* set finder flags */ + char *whole_name) +{ + int i; /* loop counter */ + int len; /* filename length */ + afpmap *amap; /* mapping entry */ + const char *ret; + + /* we don't take fdflags from the map or magic file */ + *fdflags = defmap->fdflags; + +#ifdef USE_MAGIC + /* + * if we have a magic file and we want to search it first, + * then try to get a match + */ + if (magic_state && hfs_last == MAP_LAST + && try_map_magic(whole_name, type, creator)) + return; +#endif /* USE_MAGIC */ + + len = strlen(name); + + /* have an afpfile and filename if long enough */ + if (map && len >= mlen) { + /* + * search through the list - we start where we left off + * last time in case this file is of the same type as the + * last one + */ + for (i = 0; i < map_num; i++) { + amap = map[last_ent]; + + /* compare the end of the filename */ +/* if (strcmp((name+len - amap->elen), amap->extn) == 0) { */ + if (strcasecmp((name+len - amap->elen), amap->extn) == 0) { + /* set the required info */ + *type = amap->type; + *creator = amap->creator; + *fdflags = amap->fdflags; + return; + } + /* + * move on to the next entry - wrapping round + * if neccessary + */ + last_ent++; + last_ent %= map_num; + } + } + /* + * if no matches are found, file name too short, or no afpfile, + * then take defaults + */ + *type = defmap->type; + *creator = defmap->creator; + +#ifdef USE_MAGIC + /* + * if we have a magic file and we haven't searched yet, + * then try to get a match + */ + if (magic_state && hfs_last == MAG_LAST) + try_map_magic(whole_name, type, creator); +#endif /* USE_MAGIC */ +} + +void +delete_rsrc_ent(dir_ent *s_entry) +{ + dir_ent *s_entry1 = s_entry->next; + + if (s_entry1 == NULL) + return; + + s_entry->next = s_entry1->next; + s_entry->assoc = NULL; + + free(s_entry1->name); + free(s_entry1->whole_name); + + free(s_entry1); +} + +void +clean_hfs() +{ + if (map) + free(map); + + if (defmap) + free(defmap); + +#ifdef USE_MAGIC + if (magic_state) { + magic_close(magic_state); + magic_state = NULL; + } +#endif /* USE_MAGIC */ +} + +#endif /* APPLE_HYB */ + +void +perr(char *a) +{ +#ifdef USE_LIBSCHILY + if (a) + comerr("%s\n", a); + else + comerr("<no error message given>\n"); +#else + if (a) + fprintf(stderr, "mkhybrid: %s\n", a); + perror("mkhybrid"); + exit(1); +#endif +} diff --git a/genisoimage/apple.h b/genisoimage/apple.h new file mode 100644 index 0000000..685a812 --- /dev/null +++ b/genisoimage/apple.h @@ -0,0 +1,386 @@ +/* + * 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. + * + */ + +/* @(#)apple.h 1.7 04/03/02 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 James Pearson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * apple.h: cut down macfile.h from CAP distribution + */ +#ifndef _APPLE_H +#define _APPLE_H + +#include "mactypes.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* O_BINARY */ + +#ifdef _WIN32_TEST +#undef UNICODE +#include <windows.h> +#endif /* _WIN32 */ + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a):(b)) +#endif /* MIN */ + +#define CT_SIZE 4 /* Size of type/creator */ +#define NUMMAP 512 /* initial number of maps */ +#define BLANK " " /* blank type/creator */ +#define DEFMATCH "*" /* default mapping extension */ + +typedef struct { + char *extn; /* filename extension */ + int elen; /* length of extension */ + char type[CT_SIZE+1]; /* extension type */ + char creator[CT_SIZE+1]; /* extension creator */ + unsigned short fdflags; /* finder flags */ +} afpmap; + +/* from "data.h" - libhfs routines */ +unsigned long d_toutime(unsigned long); +unsigned long d_dtoutime(long); +long d_getl(unsigned char *); +short d_getw(unsigned char *); + +/* for libfile routines */ +int init_magic(char *); +char * get_magic_match(const char *); + +typedef unsigned char byte; +typedef unsigned char word[2]; +typedef unsigned char dword[4]; + +#define INFOLEN 32 /* Finder info is 32 bytes */ + +typedef struct { + /* base finder information */ + char fdType[4]; /* File type [4] */ + char fdCreator[4]; /* File creator [8] */ + word fdFlags; /* Finder flags [10] */ + word fdLocation[2]; /* File's location [14] */ + word fdFldr; /* File's window [16] */ + /* extended finder information */ + word fdIconID; /* Icon ID [18] */ + word fdUnused[3]; /* Unused [24] */ + byte fdScript; /* Script system used [25] */ + byte fdXFlags; /* Reserved [26] */ + word fdComment; /* Comment ID [28] */ + dword fdPutAway; /* Home directory ID [32] */ +} Finfo; + +typedef struct { + /* base finder information */ + word frRect[4]; /* Folder's rectangle [8] */ + word frFlags; /* Finder flags [10] */ + word frLocation[2]; /* Folder's location [14] */ + word frView; /* Folder's view [16] */ + /* extended finder information */ + word frScroll[2]; /* Folder's scroll position [20] */ + dword frOpenChain; /* ID's of open folders [24] */ + byte frScript; /* Script system used [25] */ + byte frXFlags; /* Reserved [26] */ + word frComment; /* Comment ID [28] */ + dword frPutAway; /* Home directory ID [32] */ +} Dinfo; + +/****** TYPE_CAP ******/ + +/* + * taken from the CAP distribution: + * macfile.h - header file with Macintosh file definitions + * + * AppleTalk package for UNIX (4.2 BSD). + * + * Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the + * City of New York. + * + * Edit History: + * + * Sept 1987 Created by Charlie + * + */ + + +#ifndef USE_MAC_DATES +#define USE_MAC_DATES +#endif /* USE_MAC_DATES */ + +#define MAXCLEN 199 /* max size of a comment string */ +#define FINFOLEN 32 /* Finder info is 32 bytes */ +#define MAXMACFLEN 31 /* max Mac file name length */ + +typedef struct { + byte finderinfo[INFOLEN]; /* Finder info */ + word fi_attr; /* attributes */ +#define FI_MAGIC1 255 + byte fi_magic1; /* was: length of comment */ +#define FI_VERSION 0x10 /* version major 1, minor 0 */ + /* if we have more than 8 versions wer're */ + /* doiong something wrong anyway */ + byte fi_version; /* version number */ +#define FI_MAGIC 0xda + byte fi_magic; /* magic word check */ + byte fi_bitmap; /* bitmap of included info */ +#define FI_BM_SHORTFILENAME 0x1 /* is this included? */ +#define FI_BM_MACINTOSHFILENAME 0x2 /* is this included? */ + byte fi_shortfilename[12+1]; /* possible short file name */ + byte fi_macfilename[32+1]; /* possible macintosh file name */ + byte fi_comln; /* comment length */ + byte fi_comnt[MAXCLEN+1]; /* comment string */ +#ifdef USE_MAC_DATES + byte fi_datemagic; /* sanity check */ +#define FI_MDATE 0x01 /* mtime & utime are valid */ +#define FI_CDATE 0x02 /* ctime is valid */ + byte fi_datevalid; /* validity flags */ + byte fi_ctime[4]; /* mac file create time */ + byte fi_mtime[4]; /* mac file modify time */ + byte fi_utime[4]; /* (real) time mtime was set */ +#endif /* USE_MAC_DATES */ +} FileInfo; + +/* Atribute flags */ +#define FI_ATTR_SETCLEAR 0x8000 /* set-clear attributes */ +#define FI_ATTR_READONLY 0x20 /* file is read-only */ +#define FI_ATTR_ROPEN 0x10 /* resource fork in use */ +#define FI_ATTR_DOPEN 0x80 /* data fork in use */ +#define FI_ATTR_MUSER 0x2 /* multi-user */ +#define FI_ATTR_INVISIBLE 0x1 /* invisible */ + +/**** MAC STUFF *****/ + +/* Flags */ +#define FNDR_fOnDesk 0x1 +#define FNDR_fHasBundle 0x2000 +#define FNDR_fInvisible 0x4000 +/* locations */ +#define FNDR_fTrash -3 /* File in Trash */ +#define FNDR_fDesktop -2 /* File on desktop */ +#define FNDR_fDisk 0 /* File in disk window */ + +/****** TYPE_ESHARE ******/ + +/* + * Information supplied by Jens-Uwe Mager (jum@helios.de) + */ + +#define ES_VERSION 0x0102 +#define ES_MAGIC 0x3681093 +#define ES_INFOLEN 32 +#define ES_INFO_SIZE 512 + +typedef struct { + dword magic; + dword serno; /* written only, never read */ + word version; + word attr; /* invisible... */ + word openMax; /* max number of opens */ + word filler0; + dword backupCleared; /* time backup bit cleared */ + dword id; /* dir/file id */ + dword createTime; /* unix format */ + dword backupTime; /* unix format */ + byte finderinfo[INFOLEN]; /* Finder info */ +} es_FileInfo; + +/****** TYPE_USHARE ******/ + +/* + * similar to the EtherShare layout, but the finder info stuff is different + * info provided by: Phil Sylvester <psylvstr@interaccess.com> + */ + +typedef struct { + byte finderinfo[INFOLEN]; /* Finder info */ + dword btime; /* mac file backup time [36]*/ + byte unknown2[4]; /* ignore [40] */ + dword ctime; /* mac file create time [44]*/ + byte unknown3[8]; /* ignore [52] */ + dword mtime; /* mac file modify time [56]*/ + byte unknown4[456]; /* ignore [512] */ +} us_FileInfo; + +/****** TYPE_DOUBLE, TYPE_SINGLE ******/ + +/* + * Taken from cvt2cap (c) May 1988, Paul Campbell + */ + +typedef struct { + dword id; + dword offset; + dword length; +} a_entry; + +typedef struct { + dword magic; + dword version; + char home[16]; + word nentries; + a_entry entries[1]; +} a_hdr; + +#define A_HDR_SIZE 26 +#define A_ENTRY_SIZE sizeof (a_entry) + +#define A_VERSION1 0x00010000 +#define A_VERSION2 0x00020000 +#define APPLE_SINGLE 0x00051600 +#define APPLE_DOUBLE 0x00051607 +#define ID_DATA 1 +#define ID_RESOURCE 2 +#define ID_NAME 3 +#define ID_FILEI 7 /* v1 */ +#define ID_FILEDATESI 8 /* v2 */ +#define ID_FINDER 9 + +#define A_DATE 16 + +/****** TYPE_MACBIN ******/ +/* + * taken from capit.c by Nigel Perry, np@doc.ic.ac.uk which is adapted + * from unmacbin by John M. Sellens, jmsellens@watdragon.uwaterloo.ca + */ + + +#define MB_NAMELEN 63 /* maximum legal Mac file name length */ +#define MB_SIZE 128 + +/* + * Format of a bin file: + * A bin file is composed of 128 byte blocks. The first block is the + * info_header (see below). Then comes the data fork, null padded to fill the + * last block. Then comes the resource fork, padded to fill the last block. A + * proposal to follow with the text of the Get Info box has not been implemented, + * to the best of my knowledge. Version, zero1 and zero2 are what the receiving + * program looks at to determine if a MacBinary transfer is being initiated. + */ +typedef struct { /* info file header (128 bytes). Unfortunately, these */ + /* longs don't align to word boundaries */ + byte version; /* there is only a version 0 at this time */ + byte nlen; /* Length of filename. */ + byte name[MB_NAMELEN]; /* Filename */ + byte type[4]; /* File type. */ + byte auth[4]; /* File creator. */ + byte flags; /* file flags: LkIvBnSyBzByChIt */ + byte zero1; /* Locked, Invisible,Bundle, System */ + /* Bozo, Busy, Changed, Init */ + byte icon_vert[2]; /* Vertical icon position within window */ + byte icon_horiz[2]; /* Horizontal icon postion in window */ + byte window_id[2]; /* Window or folder ID. */ + byte protect; /* = 1 for protected file, 0 otherwise */ + byte zero2; + byte dflen[4]; /* Data Fork length (bytes) - most sig. */ + byte rflen[4]; /* Resource Fork length byte first */ + byte cdate[4]; /* File's creation date. */ + byte mdate[4]; /* File's "last modified" date. */ + byte ilen[2]; /* GetInfo message length */ + byte flags2; /* Finder flags, bits 0-7 */ + byte unused[14]; + byte packlen[4]; /* length of total files when unpacked */ + byte headlen[2]; /* length of secondary header */ + byte uploadvers; /* Version of MacBinary II that the uploading program is written for */ + byte readvers; /* Minimum MacBinary II version needed to read this file */ + byte crc[2]; /* CRC of the previous 124 bytes */ + byte padding[2]; /* two trailing unused bytes */ +} mb_info; + +/****** TYPE_FE ******/ + +/* Information provided by Mark Weinstein <mrwesq@earthlink.net> */ + +typedef struct { + byte nlen; + byte name[31]; + byte finderinfo[INFOLEN]; /* Finder info */ + byte cdate[4]; + byte mdate[4]; + byte bdate[4]; + byte fileid[4]; + byte sname[8]; + byte ext[3]; + byte pad; +} fe_info; + +#define FE_SIZE 92 + +/****** TYPE_SGI ******/ + +typedef struct { + byte unknown1[8]; + byte finderinfo[INFOLEN]; /* Finder info */ + byte unknown2[214]; + byte name[32]; + byte unknown3[14]; +} sgi_info; + +#define SGI_SIZE 300 + +/****** TYPE_SFM ******/ + +/* + * Information provided by Lou Rieger <lrieger@meridiancg.com> taken from + * an email from Eddie Bowers <eddieb@microsoft.com> + */ + +typedef struct { + byte afpi_Signature[4]; /* Must be 0x00504641 */ + byte afpi_Version[4]; /* Must be 0x00010000 */ + byte afpi_Reserved1[4]; + byte afpi_BackupTime[4]; /* Backup time for the file/dir */ + byte finderinfo[INFOLEN]; /* Finder info */ + byte afpi_ProDosInfo[6]; /* ProDos Info */ + byte afpi_Reserved2[6]; +} sfm_info; + +#define SFM_MAGIC 0x00504641 +#define SFM_VERSION 0x00010000 + +/****** TYPE_DHFS ******/ + +#ifdef IS_MACOS_X + +/* + * Code ideas from 'hfstar' by Marcel Weiher marcel@metaobject.com, + * another GNU hfstar by Torres Vedras paulotex@yahoo.com and + * hfspax by Howard Oakley howard@quercus.demon.co.uk + */ + +#include <sys/attr.h> + +typedef struct { + unsigned long info_length; + struct timespec ctime; + struct timespec mtime; + byte info[32]; +} attrinfo; + +#endif /* IS_MACOS_X */ + +#endif /* _APPLE_H */ diff --git a/genisoimage/apple_driver.8 b/genisoimage/apple_driver.8 new file mode 100644 index 0000000..773a074 --- /dev/null +++ b/genisoimage/apple_driver.8 @@ -0,0 +1,72 @@ +'\" te +.\" To print, first run through tbl +.TH APPLE_DRIVER 8 "18 May 1998" "Version 1.0" +.SH NAME +apple_driver \- extract Macintosh partition label, maps and boot driver +.SH SYNOPSIS +.B apple_driver +CDROM_device > HFS_driver_file +.SH DESCRIPTION +.I Apple_driver +extracts the information from an Apple (or compatible) CD-ROM required +for the +.I \-hfs-boot-file +option to +.IR mkhybrid (1). +.PP +The +.I CDROM_device +is the device name used by the CD-ROM (e.g. /dev/cdrom). +.PP +The format of the HFS driver file is: +.PP +.TS +l l . +HFS CD Label Block 512 bytes +Driver Partition Map (for 2048 byte blocks) 512 bytes +Driver Partition Map (for 512 byte blocks) 512 bytes +Empty 512 bytes +Driver Partition N x 2048 bytes +HFS Partition Boot Block 1024 bytes +.TE +.PP +The Perl script +.I hdisk.pl +can be used to give a listing of what's on a Mac CD. hdisk.pl is part of +hfsutils. +.SH NOTE +By using a driver from an Apple CD and copying Apple software to your CD, +you become liable to obey Apple Computer, Inc. Software License Agreements. + +.SH SEE\ ALSO +.IR mkhybrid (1) +.SH PROGRAMMER +James Pearson (j.pearson@ge.ucl.ac.uk) 18/5/98 +.PP +The driver code (both extracting the driver and creating partitions etc. +is based on code from +.I genisoimage 1.05 PLUS +by Andy Polyakov <appro@fy.chalmers.se> +(see http://fy.chalmers.se/~appro/genisoimage_plus.html) +.PP +This manpage describes the program implementation of +.B +apple_driver +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinof from the original program distributed by the cdrtools project. However, the cdrtools developers are not involved in the development of this spinoff and therefore shall not be made responsible for any problem caused by it. Do not try to get support for this program by contacting the original authors. +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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. diff --git a/genisoimage/apple_driver.c b/genisoimage/apple_driver.c new file mode 100644 index 0000000..24f8544 --- /dev/null +++ b/genisoimage/apple_driver.c @@ -0,0 +1,190 @@ +/* + * 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. + * + */ + +/* @(#)apple_driver.c 1.6 04/03/04 joerg */ +/* + * apple_driver.c: extract Mac partition label, maps and boot driver + * + * Based on Apple_Driver.pl, part of "genisoimage 1.05 PLUS" by Andy Polyakov + * <appro@fy.chalmers.se> (I don't know Perl, so I rewrote it C ...) + * (see http://fy.chalmers.se/~appro/genisoimage_plus.html for details) + * + * usage: apple_driver CDROM_device > HFS_driver_file + * + * The format of the HFS driver file: + * + * HFS CD Label Block 512 bytes + * Driver Partition Map (for 2048 byte blocks) 512 bytes + * Driver Partition Map (for 512 byte blocks) 512 bytes + * Empty 512 bytes + * Driver Partition N x 2048 bytes + * HFS Partition Boot Block 1024 bytes + * + * By extracting a driver from an Apple CD, you become liable to obey + * Apple Computer, Inc. Software License Agreements. + * + * James Pearson 17/5/98 + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <mac_label.h> +#include <schily.h> + +int get_732(char *p); +int get_722(char *p); + +int +get_732(char *p) +{ + return ((p[3] & 0xff) + | ((p[2] & 0xff) << 8) + | ((p[1] & 0xff) << 16) + | ((p[0] & 0xff) << 24)); +} + +int +get_722(char *p) +{ + return ((p[1] & 0xff) + | ((p[0] & 0xff) << 8)); +} + +#if 0 +EXPORT int +main(argc, argv) + int argc; + char **argv; +{ + FILE *fp; + MacLabel *mac_label; + MacPart *mac_part; + unsigned char Block0[HFS_BLOCKSZ]; + unsigned char block[SECTOR_SIZE]; + unsigned char bootb[2*HFS_BLOCKSZ]; + unsigned char pmBlock512[HFS_BLOCKSZ]; + unsigned int sbBlkSize; + unsigned int pmPyPartStart; + unsigned int pmPartStatus; + unsigned int pmMapBlkCnt; + int have_boot = 0, have_hfs = 0; + int hfs_start; + int i, j; + + + save_args(argc, argv); + + if (argc != 2) + comerrno(EX_BAD, "Usage: %s device-path", argv[0]); + + if ((fp = fopen(argv[1], "rb")) == NULL) + comerr("Can't open '%s'.", argv[1]); + + if (fread(Block0, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) + comerr("Can't read '%s'.", argv[1]); + + mac_label = (MacLabel *)Block0; + mac_part = (MacPart *)block; + + sbBlkSize = get_722((char *)mac_label->sbBlkSize); + + if (! IS_MAC_LABEL(mac_label) || sbBlkSize != SECTOR_SIZE) + comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]); + + i = 1; + do { + if (fseek(fp, i * HFS_BLOCKSZ, SEEK_SET) != 0) + comerr("Ccan't seek %s", argv[1]); + + if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) + comerr("Can't read '%s'.", argv[1]); + + pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt); + + if (!have_boot && strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) { + hfs_start = get_732((char *)mac_part->pmPyPartStart); + + fprintf(stderr, "%s: found 512 driver partition (at block %d)\n", argv[0], hfs_start); + memcpy(pmBlock512, block, HFS_BLOCKSZ); + have_boot = 1; + } + + if (!have_hfs && strncmp((char *)mac_part->pmPartType, pmPartType_4, 9) == 0) { + + hfs_start = get_732((char *)mac_part->pmPyPartStart); + + if (fseek(fp, hfs_start*HFS_BLOCKSZ, SEEK_SET) != 0) + comerr("Can't seek '%s'.", argv[1]); + + if (fread(bootb, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) + comerr("Can't read '%s'.", argv[1]); + + if (get_722((char *)bootb) == 0x4c4b) { + + fprintf(stderr, "%s: found HFS partition (at blk %d)\n", argv[0], hfs_start); + have_hfs = 1; + } + } + } while (i++ < pmMapBlkCnt); + + if (!have_hfs || !have_boot) + comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]); + + i = 1; + + do { + if (fseek(fp, i*sbBlkSize, SEEK_SET) != 0) + comerr("Can't seek '%s'.", argv[1]); + + if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) + comerr("Can't read '%s'.", argv[1]); + + pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt); + + if (strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) { + + int start, num; + + fprintf(stderr, "%s: extracting %s ", argv[0], mac_part->pmPartType); + start = get_732((char *)mac_part->pmPyPartStart); + num = get_732((char *)mac_part->pmPartBlkCnt); + fwrite(Block0, 1, HFS_BLOCKSZ, stdout); + fwrite(block, 1, HFS_BLOCKSZ, stdout); + fwrite(pmBlock512, 1, HFS_BLOCKSZ, stdout); + memset(block, 0, HFS_BLOCKSZ); + fwrite(block, 1, HFS_BLOCKSZ, stdout); + + if (fseek(fp, start*sbBlkSize, SEEK_SET) != 0) + comerr("Can't seek '%s'.", argv[1]); + + for (j = 0; j < num; j++) { + if (fread(block, 1, sbBlkSize, fp) != sbBlkSize) + comerr("Can't read '%s'.", argv[1]); + + fwrite(block, 1, sbBlkSize, stdout); + fprintf(stderr, "."); + } + fprintf(stderr, "\n"); + + fwrite(bootb, 2, HFS_BLOCKSZ, stdout); + fclose(fp); + exit(0); + } + + if (!IS_MAC_PART(mac_part)) + comerrno(EX_BAD, "Unable to find boot partition"); + + } while (i++ < pmMapBlkCnt); + + return (0); +} +#endif diff --git a/genisoimage/boot-alpha.c b/genisoimage/boot-alpha.c new file mode 100644 index 0000000..cfd4862 --- /dev/null +++ b/genisoimage/boot-alpha.c @@ -0,0 +1,137 @@ +/* + * 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. + * + */ + +/* + * Program boot-alpha.c - Handle Linux alpha boot extensions to iso9660. + * + * Written by Steve McIntyre <steve@einval.com> June 2004 + * + * Heavily inspired by isomarkboot by David Mosberger in 1996. + * + * Copyright 2004 Steve McIntyre + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <intcvt.h> +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include <schily.h> +#include "endianconv.h" + + int add_boot_alpha_filename(char *filename); +static int boot_alpha_write(FILE *outfile); +static int boot_alpha_hppa_write(FILE *outfile); +static char *boot_file_name = NULL; + +unsigned long long alpha_hppa_boot_sector[256]; /* One (ISO) sector */ +int boot_sector_initialized = 0; + +#define BOOT_STRING "Linux/Alpha aboot for ISO filesystem." + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_alpha_filename(char *filename) +{ + boot_file_name = filename; + return 0; +} + +static int boot_alpha_write(FILE *outfile) +{ + struct directory_entry *boot_file; /* Boot file we need to search for */ + unsigned long length = 0; + unsigned long extent = 0; + + if (!boot_sector_initialized) { + memset(alpha_hppa_boot_sector, 0, sizeof(alpha_hppa_boot_sector)); + boot_sector_initialized = 1; + } + + /* Write the text header into the boot sector */ + strcpy((char *)alpha_hppa_boot_sector, BOOT_STRING); + + /* Find the dir entry for the boot file by walking our file list */ + boot_file = search_tree_file(root, boot_file_name); + if (!boot_file) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I cant find the Alpha boot file '%s'!\n", + boot_file_name); +#else + fprintf(stderr, "Uh oh, I cant find the Alpha boot file '%s'!\n", + boot_file_name); + exit(1); +#endif + } + + /* Grab the ISO start sector and length from the dir entry. ISO + uses 2048-byte sectors, but we convert to 512-byte sectors here + for the sake of the firmware */ + extent = get_733(boot_file->isorec.extent); + extent *= 4; + + length = get_733(boot_file->isorec.size); + length /= 512; /* I'm sure we should take account of any overlap + here, but I'm copying what isomarkboot + does. Maybe the boot files are specified to be + exact multiples of 512 bytes? */ + + fprintf(stderr, "Found alpha boot image %s: using extent %lu, #blocks %lu\n", + boot_file_name, extent, length); + + /* Now write those values into the appropriate area of the boot + sector in LITTLE ENDIAN format. */ + write_le64(length, (unsigned char *)&alpha_hppa_boot_sector[60]); + write_le64(extent, (unsigned char *)&alpha_hppa_boot_sector[61]); + + return 0; +} + +static int boot_alpha_hppa_write(FILE *outfile) +{ + unsigned long long sum = 0; + int i = 0; + + /* Now generate a checksum of the first 504 bytes of the boot + sector and place it in alpha_hppa_boot_sector[63]. Isomarkboot currently + gets this wrong and will not work on big-endian systems! */ + for (i = 0; i < 63; i++) + sum += read_le64((unsigned char *)&alpha_hppa_boot_sector[i]); + + write_le64(sum, (unsigned char *)&alpha_hppa_boot_sector[63]); + + jtwrite(alpha_hppa_boot_sector, sizeof(alpha_hppa_boot_sector), 1, 0, FALSE); + xfwrite(alpha_hppa_boot_sector, sizeof(alpha_hppa_boot_sector), 1, outfile, 0, FALSE); + last_extent_written++; + + return 0; +} + +struct output_fragment alphaboot_desc = {NULL, NULL, NULL, boot_alpha_write, "alpha boot block"}; +struct output_fragment alpha_hppa_boot_desc = {NULL, oneblock_size, NULL, boot_alpha_hppa_write, "alpha/hppa boot block"}; diff --git a/genisoimage/boot-hppa.c b/genisoimage/boot-hppa.c new file mode 100644 index 0000000..5f3bd1c --- /dev/null +++ b/genisoimage/boot-hppa.c @@ -0,0 +1,207 @@ +/* + * 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. + * + */ + +/* + * Program boot-hppa.c - Handle HPPA boot extensions to iso9660. + * + * Written by Steve McIntyre <steve@einval.com> June 2004. + * + * Heavily inspired by palo: + * + **************************************************************************** + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com + * + **************************************************************************** + * Copyright 2004 Steve McIntyre + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <intcvt.h> +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include <schily.h> +#include "endianconv.h" + +extern long long alpha_hppa_boot_sector[256]; +extern int boot_sector_initialized; + +int add_boot_hppa_cmdline(char *cmdline); +int add_boot_hppa_kernel_32(char *filename); +int add_boot_hppa_kernel_64(char *filename); +int add_boot_hppa_bootloader(char *filename); +int add_boot_hppa_ramdisk(char *filename); + +static int boot_hppa_write(FILE *outfile); + +static char *hppa_cmdline = NULL; +static char *hppa_kernel_32 = NULL; +static char *hppa_kernel_64 = NULL; +static char *hppa_bootloader = NULL; +static char *hppa_ramdisk = NULL; + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_hppa_cmdline(char *cmdline) +{ + char *ptr = NULL; + hppa_cmdline = strdup(cmdline); + ptr = hppa_cmdline; + while (*ptr) + { + if (',' == *ptr) + *ptr = ' '; + ptr++; + } + return 0; +} + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_hppa_kernel_32(char *filename) +{ + hppa_kernel_32 = filename; + return 0; +} + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_hppa_kernel_64(char *filename) +{ + hppa_kernel_64 = filename; + return 0; +} + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_hppa_bootloader(char *filename) +{ + hppa_bootloader = filename; + return 0; +} + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_hppa_ramdisk(char *filename) +{ + hppa_ramdisk = filename; + return 0; +} + +static void exit_fatal(char *type, char *filename) +{ +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I can't find the %s '%s'!\n", + type, filename); +#else + fprintf(stderr, "Uh oh, I can't find the %s '%s'!\n", + type, filename); + exit(1); +#endif +} + +static int boot_hppa_write(FILE *outfile) +{ + struct directory_entry *boot_file; /* Boot file we need to search for */ + unsigned long length = 0; + unsigned long extent = 0; + unsigned char *boot_sector = (unsigned char *) alpha_hppa_boot_sector; + int i = 0; + + if (!boot_sector_initialized) { + memset(alpha_hppa_boot_sector, 0, sizeof(alpha_hppa_boot_sector)); + boot_sector_initialized = 1; + } + + printf("Address is: %p\n",alpha_hppa_boot_sector); + + boot_sector[0] = 0x80; /* magic */ + boot_sector[1] = 0x00; /* magic */ + boot_sector[2] = 'P'; + boot_sector[3] = 'A'; + boot_sector[4] = 'L'; + boot_sector[5] = 'O'; + boot_sector[6] = 0x00; + boot_sector[7] = 0x04; /* version */ + + /* Find the dir entry for the 32-bit kernel by walking our file list */ + boot_file = search_tree_file(root, hppa_kernel_32); + if (!boot_file) + exit_fatal("HPPA 32-bit kernel", hppa_kernel_32); + extent = 2048 * get_733(boot_file->isorec.extent); + length = get_733(boot_file->isorec.size); + fprintf(stderr, "Found hppa 32-bit kernel %s: using extent %lu (0x%lX), size %lu (0x%lX)\n", + hppa_kernel_32, extent, extent, length, length); + write_be32(extent, &boot_sector[8]); + write_be32(length, &boot_sector[12]); + + /* Find the dir entry for the ramdisk by walking our file list */ + boot_file = search_tree_file(root, hppa_ramdisk); + if (!boot_file) + exit_fatal("HPPA ramdisk", hppa_ramdisk); + extent = 2048 * get_733(boot_file->isorec.extent); + length = get_733(boot_file->isorec.size); + fprintf(stderr, "Found hppa ramdisk %s: using extent %lu (0x%lX), size %lu (0x%lX)\n", + hppa_ramdisk, extent, extent, length, length); + write_be32(extent, &boot_sector[16]); + write_be32(length, &boot_sector[20]); + + /* Now the commandline */ + snprintf((char *)&boot_sector[24], 127, "%s", hppa_cmdline); + + /* Find the dir entry for the 64-bit kernel by walking our file list */ + boot_file = search_tree_file(root, hppa_kernel_64); + if (!boot_file) + exit_fatal("HPPA 64-bit kernel", hppa_kernel_64); + extent = 2048 * get_733(boot_file->isorec.extent); + length = get_733(boot_file->isorec.size); + fprintf(stderr, "Found hppa 64-bit kernel %s: using extent %lu (0x%lX), size %lu (0x%lX)\n", + hppa_kernel_64, extent, extent, length, length); + write_be32(extent, &boot_sector[232]); + write_be32(length, &boot_sector[236]); + + /* Find the dir entry for the IPL by walking our file list */ + boot_file = search_tree_file(root, hppa_bootloader); + if (!boot_file) + exit_fatal("HPPA bootloader", hppa_bootloader); + extent = 2048 * get_733(boot_file->isorec.extent); + length = get_733(boot_file->isorec.size); + fprintf(stderr, "Found hppa bootloader %s: using extent %lu (0x%lX), size %lu (0x%lX)\n", + hppa_bootloader, extent, extent, length, length); + write_be32(extent, &boot_sector[240]); + write_be32(length, &boot_sector[244]); + + return 0; +} + +struct output_fragment hppaboot_desc = {NULL, NULL, NULL, boot_hppa_write, "hppa boot block"}; diff --git a/genisoimage/boot-mips.c b/genisoimage/boot-mips.c new file mode 100644 index 0000000..956b94f --- /dev/null +++ b/genisoimage/boot-mips.c @@ -0,0 +1,341 @@ +/* + * 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. + * + */ + +/* + * Program boot-mips.c - Handle big-endian boot extensions to iso9660. + * + * Written by Steve McIntyre <steve@einval.com> June 2004 + * + * Heavily inspired by / borrowed from genisovh: + * + * Copyright: (C) 2002 by Florian Lohoff <flo@rfc822.org> + * (C) 2004 by Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> + * + * 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. + * + * Format for volume header information + * + * The volume header is a block located at the beginning of all disk + * media (sector 0). It contains information pertaining to physical + * device parameters and logical partition information. + * + * The volume header is manipulated by disk formatters/verifiers, + * partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers. + * + * Previous versions of IRIX wrote a copy of the volume header is + * located at sector 0 of each track of cylinder 0. These copies were + * never used, and reduced the capacity of the volume header to hold large + * files, so this practice was discontinued. + * The volume header is constrained to be less than or equal to 512 + * bytes long. A particular copy is assumed valid if no drive errors + * are detected, the magic number is correct, and the 32 bit 2's complement + * of the volume header is correct. The checksum is calculated by initially + * zeroing vh_csum, summing the entire structure and then storing the + * 2's complement of the sum. Thus a checksum to verify the volume header + * should be 0. + * + * The error summary table, bad sector replacement table, and boot blocks are + * located by searching the volume directory within the volume header. + * + * Tables are sized simply by the integral number of table records that + * will fit in the space indicated by the directory entry. + * + * The amount of space allocated to the volume header, replacement blocks, + * and other tables is user defined when the device is formatted. + */ + +#include <inttypes.h> +#ifndef MIN +#define MIN(a,b) ( (a<b) ? a : b ) +#endif + +/* + * device parameters are in the volume header to determine mapping + * from logical block numbers to physical device addresses + * + * Linux doesn't care ... + */ +struct device_parameters { + uint8_t dp_skew; /* spiral addressing skew */ + uint8_t dp_gap1; /* words of 0 before header */ + uint8_t dp_gap2; /* words of 0 between hdr and data */ + uint8_t dp_spares_cyl; /* This is for drives (such as SCSI + that support zone oriented sparing, where the zone is larger + than one track. It gets subracteded from the cylinder size + ( dp_trks0 * dp_sec) when doing partition size calculations */ + uint16_t dp_cyls; /* number of usable cylinders (i.e., + doesn't include cylinders reserved by the drive for badblocks, + etc.). For drives with variable geometry, this number may be + decreased so that: + dp_cyls * ((dp_heads * dp_trks0) - dp_spares_cyl) <= actualcapacity + This happens on SCSI drives such as the Wren IV and Toshiba 156 + Also see dp_cylshi below */ + uint16_t dp_shd0; /* starting head vol 0 */ + uint16_t dp_trks0; /* number of tracks / cylinder vol 0*/ + uint8_t dp_ctq_depth; /* Depth of CTQ queue */ + uint8_t dp_cylshi; /* high byte of 24 bits of cylinder count */ + uint16_t dp_unused; /* not used */ + uint16_t dp_secs; /* number of sectors/track */ + uint16_t dp_secbytes; /* length of sector in bytes */ + uint16_t dp_interleave; /* sector interleave */ + int32_t dp_flags; /* controller characteristics */ + int32_t dp_datarate; /* bytes/sec for kernel stats */ + int32_t dp_nretries; /* max num retries on data error */ + int32_t dp_mspw; /* ms per word to xfer, for iostat */ + uint16_t dp_xgap1; /* Gap 1 for xylogics controllers */ + uint16_t dp_xsync; /* sync delay for xylogics controllers */ + uint16_t dp_xrdly; /* read delay for xylogics controllers */ + uint16_t dp_xgap2; /* gap 2 for xylogics controllers */ + uint16_t dp_xrgate; /* read gate for xylogics controllers */ + uint16_t dp_xwcont; /* write continuation for xylogics */ +}; + +/* + * Device characterization flags + * (dp_flags) + */ +#define DP_SECTSLIP 0x00000001 /* sector slip to spare sector */ +#define DP_SECTFWD 0x00000002 /* forward to replacement sector */ +#define DP_TRKFWD 0x00000004 /* forward to replacement track */ +#define DP_MULTIVOL 0x00000008 /* multiple volumes per spindle */ +#define DP_IGNOREERRORS 0x00000010 /* transfer data regardless of errors */ +#define DP_RESEEK 0x00000020 /* recalibrate as last resort */ +#define DP_CTQ_EN 0x00000040 /* enable command tag queueing */ + +/* + * Boot blocks, bad sector tables, and the error summary table, are located + * via the volume_directory. + */ +#define VDNAMESIZE 8 + +struct volume_directory { + int8_t vd_name[VDNAMESIZE]; /* name */ + int32_t vd_lbn; /* logical block number */ + int32_t vd_nbytes; /* file length in bytes */ +}; + +/* + * partition table describes logical device partitions + * (device drivers examine this to determine mapping from logical units + * to cylinder groups, device formatters/verifiers examine this to determine + * location of replacement tracks/sectors, etc) + * + * NOTE: pt_firstlbn SHOULD BE CYLINDER ALIGNED + */ +struct partition_table { /* one per logical partition */ + int32_t pt_nblks; /* # of logical blks in partition */ + int32_t pt_firstlbn; /* first lbn of partition */ + int32_t pt_type; /* use of partition */ +}; + +#define PTYPE_VOLHDR 0 /* partition is volume header */ +#define PTYPE_TRKREPL 1 /* partition is used for repl trks */ +#define PTYPE_SECREPL 2 /* partition is used for repl secs */ +#define PTYPE_RAW 3 /* partition is used for data */ +#define PTYPE_BSD42 4 /* partition is 4.2BSD file system */ +#define PTYPE_BSD 4 /* partition is 4.2BSD file system */ +#define PTYPE_SYSV 5 /* partition is SysV file system */ +#define PTYPE_VOLUME 6 /* partition is entire volume */ +#define PTYPE_EFS 7 /* partition is sgi EFS */ +#define PTYPE_LVOL 8 /* partition is part of a logical vol */ +#define PTYPE_RLVOL 9 /* part of a "raw" logical vol */ +#define PTYPE_XFS 10 /* partition is sgi XFS */ +#define PTYPE_XFSLOG 11 /* partition is sgi XFS log */ +#define PTYPE_XLV 12 /* partition is part of an XLV vol */ +#define PTYPE_XVM 13 /* partition is sgi XVM */ +#define PTYPE_LSWAP 0x82 /* partition is Linux swap */ +#define PTYPE_LINUX 0x83 /* partition is Linux native */ +#define NPTYPES 16 + +#define VHMAGIC 0xbe5a941 /* randomly chosen value */ +#define NPARTAB 16 /* 16 unix partitions */ +#define NVDIR 15 /* max of 15 directory entries */ +#define BFNAMESIZE 16 /* max 16 chars in boot file name */ + +/* Partition types for ARCS */ +#define NOT_USED 0 /* Not used */ +#define FAT_SHORT 1 /* FAT filesystem, 12-bit FAT entries */ +#define FAT_LONG 4 /* FAT filesystem, 16-bit FAT entries */ +#define EXTENDED 5 /* extended partition */ +#define HUGE 6 /* huge partition- MS/DOS 4.0 and later */ + +/* Active flags for ARCS */ +#define BOOTABLE 0x00; +#define NOT_BOOTABLE 0x80; + +struct volume_header { + int32_t vh_magic; /* identifies volume header */ + int16_t vh_rootpt; /* root partition number */ + int16_t vh_swappt; /* swap partition number */ + int8_t vh_bootfile[BFNAMESIZE]; /* name of file to boot */ + struct device_parameters vh_dp; /* device parameters */ + struct volume_directory vh_vd[NVDIR]; /* other vol hdr contents */ + struct partition_table vh_pt[NPARTAB]; /* device partition layout */ + int32_t vh_csum; /* volume header checksum */ + int32_t vh_fill; /* fill out to 512 bytes */ + char pad[1536]; /* pad out to 2048 */ +}; + +#include <mconfig.h> +#include "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <intcvt.h> +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include <schily.h> +#include "endianconv.h" + +int add_boot_mips_filename(char *filename); + +static int boot_mips_write(FILE *outfile); + +#define MAX_NAMES 15 +static char *boot_mips_filename[MAX_NAMES] = +{ + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL +}; + +static int boot_mips_num_files = 0; + +#define SECTORS_PER_TRACK 32 +#define BYTES_PER_SECTOR 512 + +int add_boot_mips_filename(char *filename) +{ + if (boot_mips_num_files < MAX_NAMES) + { + boot_mips_filename[boot_mips_num_files] = filename; + boot_mips_num_files++; + } + + else + { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Too many MIPS boot files!\n"); +#else + fprintf(stderr, "Too many MIPS boot files!\n"); + exit(1); +#endif + } + return 0; +} + +static void vh_calc_checksum(struct volume_header *vh) +{ + uint32_t newsum = 0; + unsigned char *buffer = (unsigned char *)vh; + unsigned int i; + + vh->vh_csum = 0; + + for(i = 0; i < sizeof(struct volume_header); i += 4) + newsum -= read_be32(&buffer[i]); + + write_be32(newsum, (unsigned char *)&vh->vh_csum); +} + +static char *file_base_name(char *path) +{ + char *endptr = path; + char *ptr = path; + + while (*ptr != '\0') + { + if ('/' == *ptr) + endptr = ++ptr; + else + ++ptr; + } + return endptr; +} + +static int boot_mips_write(FILE *outfile) +{ + struct directory_entry *boot_file; /* Boot file we need to search for */ + unsigned long length = 0; + unsigned long extent = 0; + int i; + struct volume_header vh; + unsigned long long iso_size = 0; + char *filename = NULL; + + memset(&vh, 0, sizeof(vh)); + + iso_size = last_extent * 2048; + + write_be32(VHMAGIC, (unsigned char *)&vh.vh_magic); + + /* Values from an IRIX cd */ + write_be16(BYTES_PER_SECTOR, (unsigned char *)&vh.vh_dp.dp_secbytes); + write_be16(SECTORS_PER_TRACK, (unsigned char *)&vh.vh_dp.dp_secs); + write_be32(DP_RESEEK|DP_IGNOREERRORS|DP_TRKFWD, (unsigned char *)&vh.vh_dp.dp_flags); + write_be16(1, (unsigned char *)&vh.vh_dp.dp_trks0); + + write_be16((iso_size + BYTES_PER_SECTOR - 1) / (SECTORS_PER_TRACK * BYTES_PER_SECTOR), + (unsigned char *)&vh.vh_dp.dp_cyls); + + for(i = 0; i < boot_mips_num_files; i++) + { + boot_file = search_tree_file(root, boot_mips_filename[i]); + + if (!boot_file) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I cant find the MIPS boot file '%s'!\n", + boot_mips_filename[i]); +#else + fprintf(stderr, "Uh oh, I cant find the MIPS boot file '%s'!\n", + boot_mips_filename[i]); + exit(1); +#endif + } + + extent = get_733(boot_file->isorec.extent) * 4; + length = ((get_733(boot_file->isorec.size) + 2047) / 2048) * 2048; + filename = file_base_name(boot_mips_filename[i]); + + strncpy((char *)vh.vh_vd[i].vd_name, filename, MIN(VDNAMESIZE, strlen(filename))); + write_be32(extent, (unsigned char *)&vh.vh_vd[i].vd_lbn); + write_be32(length, (unsigned char *)&vh.vh_vd[i].vd_nbytes); + + fprintf(stderr, "Found mips boot image %s, using extent %lu (0x%lX), #blocks %lu (0x%lX)\n", + filename, extent, extent, length, length); + } + + /* Create volume partition on whole cd iso */ + write_be32((iso_size + (BYTES_PER_SECTOR - 1))/ BYTES_PER_SECTOR, (unsigned char *)&vh.vh_pt[10].pt_nblks); + write_be32(0, (unsigned char *)&vh.vh_pt[10].pt_firstlbn); + write_be32(PTYPE_VOLUME, (unsigned char *)&vh.vh_pt[10].pt_type); + + /* Create volume header partition, also on WHOLE cd iso */ + write_be32((iso_size + (BYTES_PER_SECTOR - 1))/ BYTES_PER_SECTOR, (unsigned char *)&vh.vh_pt[8].pt_nblks); + write_be32(0, (unsigned char *)&vh.vh_pt[8].pt_firstlbn); + write_be32(PTYPE_VOLHDR, (unsigned char *)&vh.vh_pt[8].pt_type); + + /* Create checksum */ + vh_calc_checksum(&vh); + + jtwrite(&vh, sizeof(vh), 1, 0, FALSE); + xfwrite(&vh, sizeof(vh), 1, outfile, 0, FALSE); + last_extent_written++; + + return 0; +} + +struct output_fragment mipsboot_desc = {NULL, oneblock_size, NULL, boot_mips_write, "MIPS boot block"}; diff --git a/genisoimage/boot-mipsel.c b/genisoimage/boot-mipsel.c new file mode 100644 index 0000000..3d8ca65 --- /dev/null +++ b/genisoimage/boot-mipsel.c @@ -0,0 +1,259 @@ +/* + * 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. + * + */ + +/* + * Program boot-mipsel.c - Handle Mipsel boot extensions to iso9660. + * + * Written by Steve McIntyre <steve@einval.com> (2004). + * + * Heavily inspired by / borrowed from delo: + * + * Copyright: (C) 2002 by Florian Lohoff <flo@rfc822.org> + * (C) 2004 by Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> + * + * 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. + * + * Format for volume header information + * + * The volume header is a block located at the beginning of all disk + * media (sector 0). It contains information pertaining to physical + * device parameters and logical partition information. + * + * The volume header is manipulated by disk formatters/verifiers, + * partition builders (e.g. fx, dvhtool, and mkfs), and disk drivers. + * + * Previous versions of IRIX wrote a copy of the volume header is + * located at sector 0 of each track of cylinder 0. These copies were + * never used, and reduced the capacity of the volume header to hold large + * files, so this practice was discontinued. + * The volume header is constrained to be less than or equal to 512 + * bytes long. A particular copy is assumed valid if no drive errors + * are detected, the magic number is correct, and the 32 bit 2's complement + * of the volume header is correct. The checksum is calculated by initially + * zeroing vh_csum, summing the entire structure and then storing the + * 2's complement of the sum. Thus a checksum to verify the volume header + * should be 0. + * + * The error summary table, bad sector replacement table, and boot blocks are + * located by searching the volume directory within the volume header. + * + * Tables are sized simply by the integral number of table records that + * will fit in the space indicated by the directory entry. + * + * The amount of space allocated to the volume header, replacement blocks, + * and other tables is user defined when the device is formatted. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <intcvt.h> +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include <schily.h> +#include "endianconv.h" +#include <errno.h> +#include <glibc_elf.h> + +int add_boot_mipsel_filename(char *filename); +static int boot_mipsel_write(FILE *outfile); + +static char *boot_file_name = NULL; + +#define MAX_MAPS 51 +#define DEC_BOOT_MAGIC 0x02757a +#define HD_SECTOR_SIZE 512 + +/* Those were stolen from linux kernel headers. */ + +struct extent { + uint32_t count; + uint32_t start; +} +#ifdef __GNUC__ +__attribute__((packed)) +#endif + ; + +struct dec_bootblock { + int8_t pad[8]; + int32_t magic; /* We are a DEC BootBlock */ + int32_t mode; /* 0: Single extent, 1: Multi extent boot */ + int32_t loadAddr; /* Load below kernel */ + int32_t execAddr; /* And exec there */ + struct extent bootmap[MAX_MAPS]; +} +#ifdef __GNUC__ +__attribute__((packed)) +#endif + ; + +static void swap_in_elf32_ehdr(Elf32_Ehdr *ehdr) +{ + ehdr->e_type = read_le16((unsigned char *)&ehdr->e_type); + ehdr->e_machine = read_le16((unsigned char *)&ehdr->e_machine); + ehdr->e_version = read_le32((unsigned char *)&ehdr->e_version); + ehdr->e_entry = read_le32((unsigned char *)&ehdr->e_entry); + ehdr->e_phoff = read_le32((unsigned char *)&ehdr->e_phoff); + ehdr->e_shoff = read_le32((unsigned char *)&ehdr->e_shoff); + ehdr->e_flags = read_le32((unsigned char *)&ehdr->e_flags); + ehdr->e_ehsize = read_le16((unsigned char *)&ehdr->e_ehsize); + ehdr->e_phentsize = read_le16((unsigned char *)&ehdr->e_phentsize); + ehdr->e_phnum = read_le16((unsigned char *)&ehdr->e_phnum); + ehdr->e_shentsize = read_le16((unsigned char *)&ehdr->e_shentsize); + ehdr->e_shnum = read_le16((unsigned char *)&ehdr->e_shnum); + ehdr->e_shstrndx = read_le16((unsigned char *)&ehdr->e_shstrndx); +} + +static void swap_in_elf32_phdr(Elf32_Phdr *phdr) +{ + phdr->p_type = read_le32((unsigned char *)&phdr->p_type); + phdr->p_offset = read_le32((unsigned char *)&phdr->p_offset); + phdr->p_vaddr = read_le32((unsigned char *)&phdr->p_vaddr); + phdr->p_paddr = read_le32((unsigned char *)&phdr->p_paddr); + phdr->p_filesz = read_le32((unsigned char *)&phdr->p_filesz); + phdr->p_memsz = read_le32((unsigned char *)&phdr->p_memsz); + phdr->p_flags = read_le32((unsigned char *)&phdr->p_flags); + phdr->p_align = read_le32((unsigned char *)&phdr->p_align); +} + +/* Simple function: store the filename to be used later when we need + to find the boot file */ +extern int add_boot_mipsel_filename(char *filename) +{ + boot_file_name = filename; + return 0; +} + +/* Parse the ELF header of the boot loaded to work out the load + address and exec address */ +static int parse_boot_file(char *filename, int32_t *loadaddr, int32_t *execaddr, int32_t *offset, int32_t *count) +{ + int error = 0; + FILE *loader = NULL; + Elf32_Ehdr ehdr; + Elf32_Phdr phdr; + + loader = fopen(filename, "rb"); + if (!loader) + return errno; + + error = fread(&ehdr, sizeof(ehdr), 1, loader); + if (1 != error) + return EIO; + + swap_in_elf32_ehdr(&ehdr); + if (!(ehdr.e_ident[EI_MAG0] == ELFMAG0 + && ehdr.e_ident[EI_MAG1] == ELFMAG1 + && ehdr.e_ident[EI_MAG2] == ELFMAG2 + && ehdr.e_ident[EI_MAG3] == ELFMAG3 + && ehdr.e_ident[EI_CLASS] == ELFCLASS32 + && ehdr.e_ident[EI_DATA] == ELFDATA2LSB + && ehdr.e_ident[EI_VERSION] == EV_CURRENT + && ehdr.e_type == ET_EXEC + && ehdr.e_machine == EM_MIPS + && ehdr.e_version == EV_CURRENT)) + { + fprintf(stderr, "Sorry, %s is not a MIPS ELF32 little endian file", filename); + return EINVAL; + } + if (ehdr.e_phnum != 1) + { + fprintf(stderr, "Sorry, %s has more than one ELF segment", filename); + return EINVAL; + } + fseek(loader, ehdr.e_phoff, SEEK_SET); + error = fread(&phdr, sizeof(phdr), 1, loader); + if (1 != error) + return EIO; + + *loadaddr = phdr.p_vaddr; + *execaddr = ehdr.e_entry; + *offset = (phdr.p_offset + HD_SECTOR_SIZE - 1) / HD_SECTOR_SIZE; + *count = (phdr.p_filesz + HD_SECTOR_SIZE - 1) / HD_SECTOR_SIZE; + + fprintf(stderr, "Parsed mipsel boot image %s: using loadaddr 0x%X, execaddr 0x%X, offset 0x%X, count 0x%X\n", + filename, *loadaddr, *execaddr, *offset, *count); + + fclose(loader); + return 0; +} + +static int boot_mipsel_write(FILE *outfile) +{ + char sector[2048]; + struct dec_bootblock *bb = (struct dec_bootblock *)sector; + int error = 0; + int offset = 0; + int count = 0; + struct directory_entry *boot_file; /* Boot file we need to search for in the image */ + unsigned long length = 0; + unsigned long extent = 0; + int loadaddr = 0; + int execaddr = 0; + + memset(sector, 0, sizeof(sector)); + + /* Fill in our values we care on */ + write_le32(DEC_BOOT_MAGIC, (unsigned char *)&bb->magic); + write_le32(1, (unsigned char *)&bb->mode); + + /* Find the file entry in the CD image */ + boot_file = search_tree_file(root, boot_file_name); + if (!boot_file) + { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, unable to find the mipsel boot file '%s'!\n", + boot_file_name); +#else + fprintf(stderr, "Uh oh, unable to find the mipsel boot file '%s'!\n", + boot_file_name); + exit(1); +#endif + } + + extent = get_733(boot_file->isorec.extent); + length = get_733(boot_file->isorec.size); + fprintf(stderr, "Found mipsel boot loader %s: using extent %lu, #blocks %lu\n", + boot_file_name, extent, length); + + /* Parse the ELF headers on the boot file */ + error = parse_boot_file(boot_file->whole_name, &loadaddr, &execaddr, &offset, &count); + if (error) + { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, unable to parse the mipsel boot file '%s'!\n", + boot_file->whole_name); +#else + fprintf(stderr, "Uh oh, unable to parse the mipsel boot file '%s'!\n", + boot_file->whole_name); + exit(1); +#endif + } + + write_le32(loadaddr, (unsigned char *)&bb->loadAddr); + write_le32(execaddr, (unsigned char *)&bb->execAddr); + write_le32((extent * 4) + offset, (unsigned char *)&bb->bootmap[0].start); + write_le32(count, (unsigned char *)&bb->bootmap[0].count); + + jtwrite(sector, sizeof(sector), 1, 0, FALSE); + xfwrite(sector, sizeof(sector), 1, outfile, 0, FALSE); + last_extent_written++; + + return 0; +} + +struct output_fragment mipselboot_desc = {NULL, oneblock_size, NULL, boot_mipsel_write, "mipsel boot block"}; diff --git a/genisoimage/boot.c b/genisoimage/boot.c new file mode 100644 index 0000000..51b6fb7 --- /dev/null +++ b/genisoimage/boot.c @@ -0,0 +1,537 @@ +/* + * 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. + * + */ + +/* @(#)boot.c 1.13 04/02/22 Copyright 1999-2003 J. Schilling */ +/* + * Support for generic boot (sector 0..16) + * and to boot Sun sparc and Sun x86 systems. + * + * Copyright (c) 1999-2003 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 "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <intcvt.h> +#include <schily.h> +#include "sunlabel.h" + +extern int use_sunx86boot; + +static struct sun_label cd_label; +static struct x86_label sx86_label; +static struct pc_part fdisk_part; +static char *boot_files[NDKMAP]; /* Change this for > 8 x86 parts */ + +static void init_sparc_label(void); +static void init_sunx86_label(void); +void sparc_boot_label(char *label); +void sunx86_boot_label(char *label); +void scan_sparc_boot(char *files); +void scan_sunx86_boot(char *files); +int make_sun_label(void); +int make_sunx86_label(void); +static void dup_sun_label(int part); +static int sunboot_write(FILE *outfile); +static int sunlabel_size(int starting_extent); +static int sunlabel_write(FILE * outfile); +static int genboot_size(int starting_extent); +static int genboot_write(FILE * outfile); + +/* + * Set the virtual geometry in the disk label. + * If we like to make the geometry variable, we may change + * dkl_ncyl and dkl_pcyl later. + */ +static void +init_sparc_label() +{ + i_to_4_byte(cd_label.dkl_vtoc.v_version, V_VERSION); + i_to_2_byte(cd_label.dkl_vtoc.v_nparts, NDKMAP); + i_to_4_byte(cd_label.dkl_vtoc.v_sanity, VTOC_SANE); + + i_to_2_byte(cd_label.dkl_rpm, CD_RPM); + i_to_2_byte(cd_label.dkl_pcyl, CD_PCYL); + i_to_2_byte(cd_label.dkl_apc, CD_APC); + i_to_2_byte(cd_label.dkl_intrlv, CD_INTRLV); + i_to_2_byte(cd_label.dkl_ncyl, CD_NCYL); + i_to_2_byte(cd_label.dkl_acyl, CD_ACYL); + i_to_2_byte(cd_label.dkl_nhead, CD_NHEAD); + i_to_2_byte(cd_label.dkl_nsect, CD_NSECT); + + cd_label.dkl_magic[0] = DKL_MAGIC_0; + cd_label.dkl_magic[1] = DKL_MAGIC_1; +} + +static void +init_sunx86_label() +{ + li_to_4_byte(sx86_label.dkl_vtoc.v_sanity, VTOC_SANE); + li_to_4_byte(sx86_label.dkl_vtoc.v_version, V_VERSION); + li_to_2_byte(sx86_label.dkl_vtoc.v_sectorsz, 512); + li_to_2_byte(sx86_label.dkl_vtoc.v_nparts, NX86MAP); + + li_to_4_byte(sx86_label.dkl_pcyl, CD_PCYL); + li_to_4_byte(sx86_label.dkl_ncyl, CD_NCYL); + li_to_2_byte(sx86_label.dkl_acyl, CD_ACYL); + li_to_2_byte(sx86_label.dkl_bcyl, 0); + + li_to_4_byte(sx86_label.dkl_nhead, CD_NHEAD); + li_to_4_byte(sx86_label.dkl_nsect, CD_NSECT); + li_to_2_byte(sx86_label.dkl_intrlv, CD_INTRLV); + li_to_2_byte(sx86_label.dkl_skew, 0); + li_to_2_byte(sx86_label.dkl_apc, CD_APC); + li_to_2_byte(sx86_label.dkl_rpm, CD_RPM); + + li_to_2_byte(sx86_label.dkl_write_reinstruct, 0); + li_to_2_byte(sx86_label.dkl_read_reinstruct, 0); + + li_to_2_byte(sx86_label.dkl_magic, DKL_MAGIC); +} + +/* + * For command line parser: set ASCII label. + */ +void +sparc_boot_label(char *label) +{ + strncpy(cd_label.dkl_ascilabel, label, 127); + cd_label.dkl_ascilabel[127] = '\0'; +} + +void +sunx86_boot_label(char *label) +{ + strncpy(sx86_label.dkl_vtoc.v_asciilabel, label, 127); + sx86_label.dkl_vtoc.v_asciilabel[127] = '\0'; +} + +/* + * Parse the command line argument for boot images. + */ +void +scan_sparc_boot(char *files) +{ + char *p; + int i = 1; + struct stat statbuf; + int status; + + init_sparc_label(); + + do { + if (i >= NDKMAP) + comerrno(EX_BAD, "Too many boot partitions.\n"); + boot_files[i++] = files; + if ((p = strchr(files, ',')) != NULL) + *p++ = '\0'; + files = p; + } while (p); + + i_to_2_byte(cd_label.dkl_vtoc.v_part[0].p_tag, V_USR); + i_to_2_byte(cd_label.dkl_vtoc.v_part[0].p_flag, V_RONLY); + for (i = 0; i < NDKMAP; i++) { + p = boot_files[i]; + if (p == NULL || *p == '\0') + continue; + if (strcmp(p, "...") == '\0') + break; + + status = stat_filter(p, &statbuf); + if (status < 0 || access(p, R_OK) < 0) + comerr("Cannot access '%s'.\n", p); + + i_to_4_byte(cd_label.dkl_map[i].dkl_nblk, + roundup(statbuf.st_size, CD_CYLSIZE)/512); + + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_tag, V_ROOT); + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_flag, V_RONLY); + } +} + +void +scan_sunx86_boot(char *files) +{ + char *p; + int i = 0; + struct stat statbuf; + int status; + + init_sunx86_label(); + + do { + if (i >= NDKMAP) + comerrno(EX_BAD, "Too many boot partitions.\n"); + boot_files[i++] = files; + if ((p = strchr(files, ',')) != NULL) + *p++ = '\0'; + files = p; + } while (p); + + li_to_2_byte(sx86_label.dkl_vtoc.v_part[0].p_tag, V_ROOT); /* UFS */ + li_to_2_byte(sx86_label.dkl_vtoc.v_part[0].p_flag, V_RONLY); + li_to_2_byte(sx86_label.dkl_vtoc.v_part[1].p_tag, V_USR); /* ISO */ + li_to_2_byte(sx86_label.dkl_vtoc.v_part[1].p_flag, V_RONLY); + li_to_2_byte(sx86_label.dkl_vtoc.v_part[2].p_tag, 0); /* ALL */ + li_to_2_byte(sx86_label.dkl_vtoc.v_part[2].p_flag, 0); + for (i = 0; i < NDKMAP; i++) { + p = boot_files[i]; + if (p == NULL || *p == '\0') + continue; + if (i == 1 || i == 2) { + comerrno(EX_BAD, + "Partition %d may not have a filename.\n", i); + } + + status = stat_filter(p, &statbuf); + if (status < 0 || access(p, R_OK) < 0) + comerr("Cannot access '%s'.\n", p); + + li_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_size, + roundup(statbuf.st_size, CD_CYLSIZE)/512); + + if (i > 2) { + li_to_2_byte(sx86_label.dkl_vtoc.v_part[i].p_tag, V_USR); + li_to_2_byte(sx86_label.dkl_vtoc.v_part[i].p_flag, V_RONLY); + } + } +} + +/* + * Finish the Sun disk label and compute the size of the additional data. + */ +int +make_sun_label() +{ + int last; + int cyl = 0; + int nblk; + int bsize; + int i; + char *p; + + /* + * Compute the size of the padding for the iso9660 image + * to allow the next partition to start on a cylinder boundary. + */ + last = roundup(last_extent, (CD_CYLSIZE/SECTOR_SIZE)); + + i_to_4_byte(cd_label.dkl_map[0].dkl_nblk, last*4); + bsize = 0; + for (i = 0; i < NDKMAP; i++) { + p = boot_files[i]; + if (p != NULL && strcmp(p, "...") == '\0') { + dup_sun_label(i); + break; + } + if ((nblk = a_to_4_byte(cd_label.dkl_map[i].dkl_nblk)) == 0) + continue; + + i_to_4_byte(cd_label.dkl_map[i].dkl_cylno, cyl); + cyl += nblk / (CD_CYLSIZE/512); + if (i > 0) + bsize += nblk; + } + bsize /= 4; + return (last-last_extent+bsize); +} + +/* + * A typical Solaris boot/install CD from a Sun CD set looks + * this way: + * + * UFS Part 0 tag 2 flag 10 start 3839 size 1314560 + * ISO Part 1 tag 4 flag 10 start 0 size 3839 + * ALL Part 2 tag 0 flag 0 start 0 size 1318400 + */ +int +make_sunx86_label() +{ + int last; + int cyl = 0; + int nblk; + int bsize; + int i; + int partoff = 1; /* The offset of the Solaris 0x82 partition */ + char *p; + + /* + * Compute the size of the padding for the iso9660 image + * to allow the next partition to start on a cylinder boundary. + */ + last = roundup(last_extent, (CD_CYLSIZE/SECTOR_SIZE)); + + li_to_4_byte(sx86_label.dkl_vtoc.v_part[1].p_size, last*4); + + /* + * Note that the Solaris fdisk partition with fdisk signature 0x82 + * is created at fixed offset 1 sector == 512 Bytes by this + * implementation. + * We need subtract this partition offset from all absolute + * partition offsets in order to get offsets relative to the + * Solaris primary partition. + */ + bsize = 0; + for (i = 0; i < NDKMAP; i++) { + if (i == 2) /* Never include the whole disk in */ + continue; /* size/offset computations */ + p = boot_files[i]; + + if ((nblk = la_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_size)) == 0) + continue; + + li_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_start, + cyl*(CD_CYLSIZE/512)-partoff); + cyl += nblk / (CD_CYLSIZE/512); + if (i == 0 || i > 2) + bsize += nblk; + } + li_to_4_byte(sx86_label.dkl_vtoc.v_part[0].p_start, last*4-partoff); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[1].p_start, 0); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[1].p_size, last*4-partoff); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[2].p_start, 0); + li_to_4_byte(sx86_label.dkl_vtoc.v_part[2].p_size, last*4+bsize); + + fdisk_part.part[0].pr_status = STATUS_ACTIVE; + fdisk_part.part[0].pr_type = TYPE_SOLARIS; + li_to_4_byte(fdisk_part.part[0].pr_partoff, partoff); + li_to_4_byte(fdisk_part.part[0].pr_nsect, last*4+bsize-partoff); + fdisk_part.magic[0] = 0x55; + fdisk_part.magic[1] = 0xAA; + + bsize /= 4; + return (last-last_extent+bsize); +} + +/* + * Duplicate a partition of the Sun disk label until all partitions are filled up. + */ +static void +dup_sun_label(int part) +{ + int cyl; + int nblk; + int i; + + + if (part < 1 || part >= NDKMAP) + part = 1; + cyl = a_to_4_byte(cd_label.dkl_map[part-1].dkl_cylno); + nblk = a_to_4_byte(cd_label.dkl_map[part-1].dkl_nblk); + + for (i = part; i < NDKMAP; i++) { + i_to_4_byte(cd_label.dkl_map[i].dkl_cylno, cyl); + i_to_4_byte(cd_label.dkl_map[i].dkl_nblk, nblk); + + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_tag, V_ROOT); + i_to_2_byte(cd_label.dkl_vtoc.v_part[i].p_flag, V_RONLY); + } +} + +/* + * Write out Sun boot partitions. + */ +static int +sunboot_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + int i; + int n; + int nblk; + int amt; + int f; + char *p; + + memset(buffer, 0, sizeof (buffer)); + + /* + * Write padding to the iso9660 image to allow the + * boot partitions to start on a cylinder boundary. + */ + amt = roundup(last_extent_written, (CD_CYLSIZE/SECTOR_SIZE)) - last_extent_written; + for (n = 0; n < amt; n++) { + jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + if (use_sunx86boot) + i = 0; + else + i = 1; + for (; i < NDKMAP; i++) { + if (use_sunx86boot && (i == 1 || i == 2)) + continue; + p = boot_files[i]; + if (p == NULL || *p == '\0') + continue; + if (p != NULL && strcmp(p, "...") == '\0') + break; + if (use_sunx86boot) { + if ((nblk = la_to_4_byte(sx86_label.dkl_vtoc.v_part[i].p_size)) == 0) + continue; + } else { + if ((nblk = a_to_4_byte(cd_label.dkl_map[i].dkl_nblk)) == 0) + continue; + } + if ((f = open(boot_files[i], O_RDONLY| O_BINARY)) < 0) + comerr("Cannot open '%s'.\n", boot_files[i]); + + amt = nblk / 4; + for (n = 0; n < amt; n++) { + memset(buffer, 0, sizeof (buffer)); + if (read(f, buffer, SECTOR_SIZE) < 0) + comerr("Read error on '%s'.\n", boot_files[i]); + jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + close(f); + } + fprintf(stderr, "Total extents including %s boot = %u\n", + use_sunx86boot ? "Solaris x86":"sparc", + last_extent_written - session_start); + return (0); +} + +/* + * Do size management for the Sun disk label that is located in the first + * sector of a disk. + */ +static int +sunlabel_size(int starting_extent) +{ + if (last_extent != session_start) + comerrno(EX_BAD, "Cannot create sparc boot on offset != 0.\n"); + last_extent++; + return (0); +} + +/* + * Cumpute the checksum and write a Sun disk label to the first sector + * of the disk. + * If the -generic-boot option has been specified too, overlay the + * Sun disk label on the firs 512 bytes of the generic boot code. + */ +static int +sunlabel_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + register char *p; + register short count = (512/2) - 1; + int f; + + memset(buffer, 0, sizeof (buffer)); + if (genboot_image) { + if ((f = open(genboot_image, O_RDONLY| O_BINARY)) < 0) + comerr("Cannot open '%s'.\n", genboot_image); + + if (read(f, buffer, SECTOR_SIZE) < 0) + comerr("Read error on '%s'.\n", genboot_image); + close(f); + } + + if (use_sunx86boot) { + if (sx86_label.dkl_vtoc.v_asciilabel[0] == '\0') + strcpy(sx86_label.dkl_vtoc.v_asciilabel, CD_X86LABEL); + + p = (char *)&sx86_label; + sx86_label.dkl_cksum[0] = 0; + sx86_label.dkl_cksum[1] = 0; + while (count-- > 0) { + sx86_label.dkl_cksum[0] ^= *p++; + sx86_label.dkl_cksum[1] ^= *p++; + } + memcpy(&buffer[0x1BE], &fdisk_part.part, 512-0x1BE); + memcpy(&buffer[1024], &sx86_label, 512); + } else { + /* + * If we don't already have a Sun disk label text + * set up the default. + */ + if (cd_label.dkl_ascilabel[0] == '\0') + strcpy(cd_label.dkl_ascilabel, CD_DEFLABEL); + + p = (char *)&cd_label; + cd_label.dkl_cksum[0] = 0; + cd_label.dkl_cksum[1] = 0; + while (count--) { + cd_label.dkl_cksum[0] ^= *p++; + cd_label.dkl_cksum[1] ^= *p++; + } + memcpy(buffer, &cd_label, 512); + } + + jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Do size management for the generic boot code on sectors 0..16. + */ +static int +genboot_size(int starting_extent) +{ + if (last_extent > (session_start + 1)) + comerrno(EX_BAD, "Cannot create generic boot on offset != 0.\n"); + last_extent = session_start + 16; + return (0); +} + +/* + * Write the generic boot code to sectors 0..16. + * If there is a Sun disk label, start writing at sector 1. + */ +static int +genboot_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + int i; + int f; + + if ((f = open(genboot_image, O_RDONLY| O_BINARY)) < 0) + comerr("Cannot open '%s'.\n", genboot_image); + + for (i = 0; i < 16; i++) { + memset(buffer, 0, sizeof (buffer)); + if (read(f, buffer, SECTOR_SIZE) < 0) + comerr("Read error on '%s'.\n", genboot_image); + + if (i != 0 || last_extent_written == session_start) { + jtwrite(buffer, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buffer, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + } + close(f); + return (0); +} + +struct output_fragment sunboot_desc = {NULL, NULL, NULL, sunboot_write, "Sun Boot" }; +struct output_fragment sunlabel_desc = {NULL, sunlabel_size, NULL, sunlabel_write, "Sun Disk Label" }; +struct output_fragment genboot_desc = {NULL, genboot_size, NULL, genboot_write, "Generic Boot" }; diff --git a/genisoimage/bootinfo.h b/genisoimage/bootinfo.h new file mode 100644 index 0000000..a02bd65 --- /dev/null +++ b/genisoimage/bootinfo.h @@ -0,0 +1,46 @@ +/* + * 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. + * + */ + +/* @(#)bootinfo.h 1.3 04/03/02 Copyright 1999, 2004 J. Schilling */ +/* + * Header file bootinfo.h - genisoimage-defined boot information table + * useful for an El Torito-loaded disk image. + * + * Copyright (c) 1999, 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. + */ + +#ifndef _BOOTINFO_H +#define _BOOTINFO_H + +struct genisoimage_boot_info { + char bi_pvd [ISODCL(1, 4)]; /* LBA of PVD */ + char bi_file [ISODCL(5, 8)]; /* LBA of boot image */ + char bi_length [ISODCL(9, 12)]; /* Length of boot image */ + char bi_csum [ISODCL(13, 16)]; /* Checksum of boot image */ + char bi_reserved [ISODCL(17, 56)]; /* Reserved */ +}; + +#endif /* _BOOTINFO_H */ diff --git a/genisoimage/bswap.h b/genisoimage/bswap.h new file mode 100644 index 0000000..5f3fd9d --- /dev/null +++ b/genisoimage/bswap.h @@ -0,0 +1,67 @@ +/* + * 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. + * + */ + +/* @(#)bswap.h 1.2 03/03/25 Copyright 2002 J. Schilling */ +#ifndef _BSWAP_H +#define _BSWAP_H + +/* + * Allow to use B2N_* macros found in libdvdread in a portable way. + * These macros should better be avoided as in place conversion in + * general only works on processors like Motorola 68000 and Intel x86. + * Modern processors usually have alignement restrictions that may + * cause problems. The stripped down libdvdread for genisoimage is known + * not to have these alignement problems, so we may use the macros + * as they have been introduced by the authors of libdvdread. + * + * Copyright (c) 2002 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 <btorder.h> +#include <intcvt.h> + +#if defined(WORDS_BIGENDIAN) + +/* All bigendian systems are fine, just ignore the swaps. */ +#define B2N_16(x) (void)(x) +#define B2N_32(x) (void)(x) +#define B2N_64(x) (void)(x) + +#else + +/* + * It is a bad idea to convert numbers in place. + * In protocols, there is usually the additional problem that the + * data is not properly aligned. + */ +#define B2N_16(x) (x) = a_to_u_2_byte(&(x)) +#define B2N_32(x) (x) = a_to_u_4_byte(&(x)) +#define B2N_64(x) (x) = a_to_u_8_byte(&(x)) + +#endif + +#endif /* _BSWAP_H */ diff --git a/genisoimage/checksum.c b/genisoimage/checksum.c new file mode 100644 index 0000000..704167c --- /dev/null +++ b/genisoimage/checksum.c @@ -0,0 +1,583 @@ +/* + * checksum.c + * + * Copyright (c) 2008- Steve McIntyre <steve@einval.com> + * + * Implementation of a generic checksum interface, used in JTE. + * + * GNU GPL v2 + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <timedefs.h> +#include <fctldefs.h> +#include <regex.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "md5.h" +#include "sha1.h" +#include "sha256.h" +#include "sha512.h" +#include "checksum.h" + +#ifdef THREADED_CHECKSUMS +# include <pthread.h> +#endif + +static void md5_init(void *context) +{ + mk_MD5Init(context); +} +static void md5_update(void *context, unsigned char const *buf, unsigned int len) +{ + mk_MD5Update(context, buf, len); +} +static void md5_final(unsigned char *digest, void *context) +{ + mk_MD5Final(digest, context); +} + +static void sha1_init(void *context) +{ + sha1_init_ctx(context); +} +static void sha1_update(void *context, unsigned char const *buf, unsigned int len) +{ + sha1_process_bytes(buf, len, context); +} +static void sha1_final(unsigned char *digest, void *context) +{ + sha1_finish_ctx(context, digest); +} + +static void sha256_init(void *context) +{ + sha256_init_ctx(context); +} +static void sha256_update(void *context, unsigned char const *buf, unsigned int len) +{ + sha256_process_bytes(buf, len, context); +} +static void sha256_final(unsigned char *digest, void *context) +{ + sha256_finish_ctx(context, digest); +} + +static void sha512_init(void *context) +{ + sha512_init_ctx(context); +} +static void sha512_update(void *context, unsigned char const *buf, unsigned int len) +{ + sha512_process_bytes(buf, len, context); +} +static void sha512_final(unsigned char *digest, void *context) +{ + sha512_finish_ctx(context, digest); +} + +struct checksum_details +{ + char *name; + char *prog; + int digest_size; + int context_size; + void (*init)(void *context); + void (*update)(void *context, unsigned char const *buf, unsigned int len); + void (*final)(unsigned char *digest, void *context); +}; + +static const struct checksum_details algorithms[] = +{ + { + "MD5", + "md5sum", + 16, + sizeof(struct mk_MD5Context), + md5_init, + md5_update, + md5_final + }, + { + "SHA1", + "sha1sum", + 20, + sizeof(struct sha1_ctx), + sha1_init, + sha1_update, + sha1_final + }, + { + "SHA256", + "sha256sum", + 32, + sizeof(struct sha256_ctx), + sha256_init, + sha256_update, + sha256_final + }, + { + "SHA512", + "sha512sum", + 64, + sizeof(struct sha512_ctx), + sha512_init, + sha512_update, + sha512_final + } +}; + +struct algo_context +{ + void *context; + unsigned char *digest; + int enabled; + int finalised; + char *hexdump; +#ifdef THREADED_CHECKSUMS + unsigned char const *buf; + unsigned int len; + int which; + pthread_t thread; + struct _checksum_context *parent; + pthread_mutex_t start_mutex; + pthread_cond_t start_cv; +#endif +}; + +struct _checksum_context +{ +#ifdef THREADED_CHECKSUMS + unsigned int index; + unsigned int threads_running; + unsigned int threads_desired; + pthread_mutex_t done_mutex; + pthread_cond_t done_cv; +#endif + char *owner; + struct algo_context algo[NUM_CHECKSUMS]; +}; + +struct checksum_info *checksum_information(enum checksum_types which) +{ + return (struct checksum_info *)&algorithms[which]; +} + +/* Dump a buffer in hex */ +static void hex_dump_to_buffer(char *output_buffer, unsigned char *buf, size_t buf_size) +{ + unsigned int i; + char *p = output_buffer; + + memset(output_buffer, 0, 1 + (2*buf_size)); + for (i = 0; i < buf_size ; i++) + p += sprintf(p, "%2.2x", buf[i]); +} + +#ifdef THREADED_CHECKSUMS +static void *checksum_thread(void *arg) +{ + struct algo_context *a = arg; + struct _checksum_context *c = a->parent; + int num_blocks_summed = 0; + + while (1) + { + /* wait to be given some work to do */ + pthread_mutex_lock(&a->start_mutex); + while (a->buf == NULL) + { + pthread_cond_wait(&a->start_cv, &a->start_mutex); + } + pthread_mutex_unlock(&a->start_mutex); + + /* if we're given a zero-length buffer, then that means we're + * done */ + if (a->len == 0) + break; + + /* actually do the checksum on the supplied buffer */ + algorithms[a->which].update(a->context, a->buf, a->len); + num_blocks_summed++; + a->buf = NULL; + + /* and tell the main thread that we're done with that + * buffer */ + pthread_mutex_lock(&c->done_mutex); + c->threads_running--; + if (c->threads_running == 0) + pthread_cond_signal(&c->done_cv); + pthread_mutex_unlock(&c->done_mutex); + } + + pthread_exit(0); +} +#endif + +checksum_context_t *checksum_init_context(int checksums, const char *owner) +{ + int i = 0; + int ret = 0; + struct _checksum_context *context = calloc(1, sizeof(struct _checksum_context)); + + if (!context) + return NULL; + + context->owner = strdup(owner); + if (!context->owner) + { + free(context); + return NULL; + } + +#ifdef THREADED_CHECKSUMS + pthread_mutex_init(&context->done_mutex, NULL); + pthread_cond_init(&context->done_cv, NULL); + context->index = 0; + context->threads_running = 0; + context->threads_desired = 0; + + for (i = 0; i < NUM_CHECKSUMS; i++) + if ( (1 << i) & checksums) + context->threads_desired++; +#endif + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + struct algo_context *a = &context->algo[i]; + if ( (1 << i) & checksums) + { + a->context = malloc(algorithms[i].context_size); + if (!a->context) + { + checksum_free_context(context); + return NULL; + } + a->digest = malloc(algorithms[i].digest_size); + if (!a->digest) + { + checksum_free_context(context); + return NULL; + } + a->hexdump = malloc(1 + (2*algorithms[i].digest_size)); + if (!a->hexdump) + { + checksum_free_context(context); + return NULL; + } + algorithms[i].init(a->context); + a->enabled = 1; + a->finalised = 0; +#ifdef THREADED_CHECKSUMS + a->which = i; + a->parent = context; + a->buf = NULL; + a->len = 0; + pthread_mutex_init(&a->start_mutex, NULL); + pthread_cond_init(&a->start_cv, NULL); + ret = pthread_create(&a->thread, NULL, checksum_thread, a); + if (ret != 0) + { + fprintf(stderr, "failed to create new thread: %d\n", ret); + checksum_free_context(context); + return NULL; + } +#endif + } + else + a->enabled = 0; + } + + return context; +} + +void checksum_free_context(checksum_context_t *context) +{ + int i = 0; + struct _checksum_context *c = context; + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + struct algo_context *a = &c->algo[i]; + +#ifdef THREADED_CHECKSUMS + if (a->thread) + { + void *ret; + pthread_cancel(a->thread); + pthread_join(a->thread, &ret); + a->thread = 0; + } +#endif + free(a->context); + free(a->digest); + free(a->hexdump); + } + free(c->owner); + free(c); +} + +#ifdef THREADED_CHECKSUMS +void checksum_update(checksum_context_t *context, + unsigned char const *buf, unsigned int len) +{ + int i = 0; + struct _checksum_context *c = context; + static int index = 0; + + index++; + + c->threads_running = c->threads_desired; + for (i = 0; i < NUM_CHECKSUMS; i++) + { + if (c->algo[i].enabled) + { + struct algo_context *a = &c->algo[i]; + pthread_mutex_lock(&a->start_mutex); + a->len = len; + a->buf = buf; + pthread_cond_signal(&a->start_cv); + pthread_mutex_unlock(&a->start_mutex); + } + } + + /* Should now all be running, wait on them all to return */ + pthread_mutex_lock(&c->done_mutex); + while (c->threads_running > 0) + { + pthread_cond_wait(&c->done_cv, &c->done_mutex); + } + pthread_mutex_unlock(&c->done_mutex); +} + +#else // THREADED_CHECKSUMS + +void checksum_update(checksum_context_t *context, + unsigned char const *buf, unsigned int len) +{ + int i = 0; + struct _checksum_context *c = context; + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + if (c->algo[i].enabled) + { + struct algo_context *a = &c->algo[i]; + algorithms[i].update(a->context, buf, len); + } + } +} + +#endif // THREADED_CHECKSUMS + +void checksum_final(checksum_context_t *context) +{ + int i = 0; + struct _checksum_context *c = context; + +#ifdef THREADED_CHECKSUMS + void *thread_ret; + /* Clean up the threads */ + c->threads_running = c->threads_desired; + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + if (c->algo[i].enabled) + { + void *ret = 0; + struct algo_context *a = &c->algo[i]; + + pthread_mutex_lock(&a->start_mutex); + a->len = 0; + a->buf = (unsigned char *)-1; + pthread_cond_signal(&a->start_cv); + pthread_mutex_unlock(&a->start_mutex); + pthread_join(a->thread, &ret); + a->thread = 0; + } + } +#endif + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + struct algo_context *a = &c->algo[i]; + if (a->enabled) + { + algorithms[i].final(a->digest, a->context); + hex_dump_to_buffer(a->hexdump, a->digest, algorithms[i].digest_size); + a->finalised = 1; + } + } +} + +void checksum_copy(checksum_context_t *context, + enum checksum_types which, + unsigned char *digest) +{ + struct _checksum_context *c = context; + + if (c->algo[which].enabled) + { + if (c->algo[which].finalised) + memcpy(digest, c->algo[which].digest, algorithms[which].digest_size); + else + memset(digest, 0, algorithms[which].digest_size); + } + else + fprintf(stderr, "Asked for %s checksum, not enabled!\n", + algorithms[which].name); +} + +const char *checksum_hex(checksum_context_t *context, + enum checksum_types which) +{ + struct _checksum_context *c = context; + + if (c->algo[which].enabled && c->algo[which].finalised) + return c->algo[which].hexdump; + + /* else */ + return NULL; +} + + +/* Parse the command line options for which checksums to use */ +int parse_checksum_algo(char *arg, int *algo) +{ + int error = 0; + int i = 0; + char *start_ptr = arg; + int len = 0; + + *algo = 0; + + if (!strcasecmp(arg, "all")) + { + *algo = 0xFF; + return 0; + } + + while (*start_ptr != 0) + { + int match = 0; + len = 0; + + while (start_ptr[len] != ',' && start_ptr[len] != 0) + len++; + + if (len) + { + for (i = 0; i < NUM_CHECKSUMS; i++) + { + if (len == strlen(algorithms[i].name) && + !strncasecmp(start_ptr, algorithms[i].name, len)) + { + match = 1; + *algo |= (1 << i); + } + } + + if (!match) + { + fprintf(stderr, "invalid algorithm name found in %s\n", arg); + return EINVAL; + } + } + + if (start_ptr[len] == 0) + break; + + start_ptr += len + 1; + } + + if (! (*algo & CHECK_MD5_USED)) + { + fprintf(stderr, "invalid choices: algorithms *must* include MD5\n"); + return EINVAL; + } + + return 0; +} + +#ifdef CHECKSUM_SELF_TEST +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +int main(int argc, char **argv) +{ + char buf[1024]; + int fd = -1; + char *filename; + int err = 0; + static checksum_context_t *test_context = NULL; + int i = 0; + + if (argc != 2) + { + fprintf(stderr, "Need a filename to act on!\n"); + return 1; + } + + filename = argv[1]; + fd = open(filename, O_RDONLY); + if (fd < 0) + { + fprintf(stderr, "Unable to open file %s, errno %d\n", filename, errno); + return 1; + } + + test_context = checksum_init_context(CHECK_ALL_USED, "test"); + if (!test_context) + { + fprintf(stderr, "Unable to initialise checksum context\n"); + return 1; + } + + while(1) + { + err = read(fd, buf, sizeof(buf)); + if (err < 0) + { + fprintf(stderr, "Failed to read from file, errno %d\n", errno); + return 1; + } + + if (err == 0) + break; // EOF + + /* else */ + checksum_update(test_context, buf, err); + } + close(fd); + checksum_final(test_context); + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + struct checksum_info *info; + unsigned char r[64]; + int j = 0; + + info = checksum_information(i); + memset(r, 0, sizeof(r)); + + checksum_copy(test_context, i, r); + + printf("OUR %s:\n", info->name); + for (j = 0; j < info->digest_size; j++) + printf("%2.2x", r[j]); + printf(" %s\n", filename); + printf("system checksum program (%s):\n", info->prog); + sprintf(buf, "%s %s", info->prog, filename); + system(buf); + printf("\n"); + } + return 0; +} +#endif /* CHECKSUM_SELF_TEST */ + diff --git a/genisoimage/checksum.h b/genisoimage/checksum.h new file mode 100644 index 0000000..367fae2 --- /dev/null +++ b/genisoimage/checksum.h @@ -0,0 +1,74 @@ +/* + * checksum.h + * + * Copyright (c) 2008- Steve McIntyre <steve@einval.com> + * + * Definitions and prototypes for a generic checksum interface, used + * in JTE. Inspired heavily by the interface to the MD5 code we're + * using already. + * + * GNU GPL v2 + */ + +enum checksum_types +{ + CHECK_MD5 = 0, + CHECK_SHA1, + CHECK_SHA256, + CHECK_SHA512, + NUM_CHECKSUMS +}; + +#define CHECK_MD5_USED (1 << CHECK_MD5) +#define CHECK_SHA1_USED (1 << CHECK_SHA1) +#define CHECK_SHA256_USED (1 << CHECK_SHA256) +#define CHECK_SHA512_USED (1 << CHECK_SHA512) +#define CHECK_ALL_USED 0xFFFFFFFF + +typedef void checksum_context_t; + +struct checksum_info +{ + char *name; + char *prog; + int digest_size; +}; + +/* Ask the library for information about a particular checksum + * algorithm. Returns a pointer to internal memory - DO NOT + * MODIFY/FREE! */ +struct checksum_info *checksum_information(enum checksum_types which); + +/* Allocate / initialise a context for the chosen checksums. OR + * together the desired checksums as the parameter */ +checksum_context_t *checksum_init_context(int checksums, const char *owner); + +/* Cleanup and free a context when it's finished with */ +void checksum_free_context(checksum_context_t *context); + +/* Pass a new buffer full of data through the checksum code */ +void checksum_update(checksum_context_t *context, + unsigned char const *buf, + unsigned int len); + +/* Finish the current set of checksums */ +void checksum_final(checksum_context_t *context); + +/* Extract a particular algorithm's checksum once checksum_final() has + * been called. Use the details in checksum_information() above first + * to see how big the digest will be. Only valid once checksum_final() + * has been called, otherwise the digest returned will be all + * zeroes. */ +void checksum_copy(checksum_context_t *context, + enum checksum_types which, + unsigned char *digest); + +/* Helper function: return a pointer to a string containing the ASCII + * hexadecimal dump of a checksum. Only valid once checksum_final() + * has been called, otherwise will return NULL */ +const char * checksum_hex(checksum_context_t *context, + enum checksum_types which); + + +extern int parse_checksum_algo(char *arg, + int *algo); diff --git a/genisoimage/config.h b/genisoimage/config.h new file mode 100644 index 0000000..b0f49ce --- /dev/null +++ b/genisoimage/config.h @@ -0,0 +1,34 @@ +/* + * 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. + * + */ + +/* @(#)config.h 1.1 97/05/16 Copyright 1997 J. Schilling */ +/* + * Adaption for mconfig.h from make file system. + * + * Copyright (c) 1997 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> diff --git a/genisoimage/defaults.h b/genisoimage/defaults.h new file mode 100644 index 0000000..60fea33 --- /dev/null +++ b/genisoimage/defaults.h @@ -0,0 +1,147 @@ +/* + * 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. + * + */ + +/* @(#)defaults.h 1.19 06/01/30 joerg */ +/* + * Header file defaults.h - assorted default values for character strings in + * the volume descriptor. + * + * Copyright (c) 1999-2004 J. Schilling + */ + +#define PREPARER_DEFAULT NULL +#define PUBLISHER_DEFAULT NULL +/* + * Define me when it's needed again +#ifndef APPID_DEFAULT +#ifdef APPLE_HYB +#define APPID_DEFAULT "MKISOFS ISO 9660/HFS FILESYSTEM BUILDER (C) 1993 E.YOUNGDALE (C) 1997 J.PEARSON/J.SCHILLING" +#else +#define APPID_DEFAULT "MKISOFS ISO 9660 FILESYSTEM BUILDER (C) 1993 E.YOUNGDALE (C) 1997 J.PEARSON/J.SCHILLING" +#endif / * APPLE_HYB * / +#endif */ +#define COPYRIGHT_DEFAULT NULL +#define BIBLIO_DEFAULT NULL +#define ABSTRACT_DEFAULT NULL +#define VOLSET_ID_DEFAULT NULL +#define VOLUME_ID_DEFAULT "CDROM" +#define BOOT_CATALOG_DEFAULT "boot.catalog" +#define BOOT_IMAGE_DEFAULT NULL +#define SILO_BOOT_IMAGE_DEFAULT "boot/second.b" +#define SILO_BOOTBLOCK_DEFAULT "boot/cd.b" +#define SILO_CONF_FILE_DEFAULT "/etc/silo.conf" +#ifdef APPLE_HYB +#define APPLE_TYPE_DEFAULT "TEXT" +#define APPLE_CREATOR_DEFAULT "unix" +#endif /* APPLE_HYB */ + +#ifdef __QNX__ +#define SYSTEM_ID_DEFAULT "QNX" +#endif + +#ifdef __osf__ +#define SYSTEM_ID_DEFAULT "OSF" +#endif + +#ifdef __sun +#ifdef __SVR4 +#define SYSTEM_ID_DEFAULT "Solaris" +#else +#define SYSTEM_ID_DEFAULT "SunOS" +#endif +#endif + +#ifdef __hpux +#define SYSTEM_ID_DEFAULT "HP-UX" +#endif + +#ifdef __sgi +#define SYSTEM_ID_DEFAULT "SGI" +#endif + +#if defined(_IBMR2) || defined(_AIX) +#define SYSTEM_ID_DEFAULT "AIX" +#endif + +#if defined(_WIN) || defined(__CYGWIN32__) || defined(__CYGWIN__) +#define SYSTEM_ID_DEFAULT "Win32" +#endif /* _WIN */ + +#ifdef __EMX__ +#define SYSTEM_ID_DEFAULT "OS/2" +#endif + +#ifdef __FreeBSD__ +#define SYSTEM_ID_DEFAULT "FreeBSD" +#endif + +#ifdef __DragonFly__ +#define SYSTEM_ID_DEFAULT "DragonFly" +#endif + +#ifdef __NetBSD__ +#define SYSTEM_ID_DEFAULT "NetBSD" +#endif + +#ifdef __OpenBSD__ +#define SYSTEM_ID_DEFAULT "OpenBSD" +#endif + +#ifdef __bsdi__ +#define SYSTEM_ID_DEFAULT "BSD/OS" +#endif + +#ifdef __NeXT__ +#define SYSTEM_ID_DEFAULT "NeXT" +#endif + +#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody +#undef SYSTEM_ID_DEFAULT +#define SYSTEM_ID_DEFAULT "Rhapsody" +#endif + +#if defined(__APPLE__) && defined(__MACH__) +#undef SYSTEM_ID_DEFAULT +#define SYSTEM_ID_DEFAULT "Mac OS X" +#endif + +#ifdef __BEOS__ +#define SYSTEM_ID_DEFAULT "BeOS" +#endif + +#ifdef __OS2 +#define SYSTEM_ID_DEFAULT "OS/2" +#endif + +#ifdef VMS +#define SYSTEM_ID_DEFAULT "VMS" +#endif + +#ifdef OPENSERVER +#define SYSTEM_ID_DEFAULT "SCO-OPENSERVER" +#endif + +#ifdef UNIXWARE +#define SYSTEM_ID_DEFAULT "SCO-UNIXWARE" +#endif + +#ifdef linux +#define SYSTEM_ID_DEFAULT "LINUX" +#endif + +#ifdef __DJGPP__ +#define SYSTEM_ID_DEFAULT "DOS" +#endif + +#ifndef SYSTEM_ID_DEFAULT +#define SYSTEM_ID_DEFAULT "UNIX" +#endif diff --git a/genisoimage/desktop.c b/genisoimage/desktop.c new file mode 100644 index 0000000..51b0269 --- /dev/null +++ b/genisoimage/desktop.c @@ -0,0 +1,180 @@ +/* + * 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. + * + */ + +/* @(#)desktop.c 1.6 04/03/04 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 James Pearson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * make_desktop: create "Desktop DB" and "Desktop DF" files. + * + * These are set up to prevent the Mac "rebuilding the desktop" + * when the CD is inserted ??? + * + * I don't know if these files should be populated, but I've just + * created these files in their initial states: + * + * Desktop DB: Initial size == volume's clump size + * first block contents found by using od ... + * rest of file seems to be padding + * No resource fork + * + * Desktop DF: Empty + * + * If the files already exist, then set correct type/creator/flags + * + * James Pearson 11/8/97 + * Adapted from mkhfs routines for mkhybrid + */ + +#ifdef APPLE_HYB + +#include <mconfig.h> +#include "genisoimage.h" + +#define DB "Desktop DB" +#define DBFC "DMGR" +#define DBT "BTFL" + +#define DF "Desktop DF" +#define DFT "DTFL" + +/* + * from "data.h" - libhfs routines + */ +extern void d_putw(unsigned char *, short); +extern void d_putl(unsigned char *, long); + +int make_desktop(hfsvol *vol, int end); + + +extern hce_mem *hce; /* libhfs/genisoimage extras */ + +int +make_desktop(hfsvol *vol, int end) +{ + hfsfile *hfp; /* Mac file */ + hfsdirent ent; /* Mac finderinfo */ + unsigned long clps; /* clump size */ + unsigned short blks; /* blocks in a clump */ + unsigned char *blk; /* user data */ + + /* + * set up default directory entries - not all these fields are needed, + * but we'll set them up anyway ... + * First do a memset because there was a report about randomly + * changing Desktop DB/DF entries... + */ + memset(&ent, 0, sizeof (hfsdirent)); /* First clear all ... */ + ent.u.file.rsize = 0; /* resource size == 0 */ + strcpy(ent.u.file.creator, DBFC); /* creator */ + strcpy(ent.u.file.type, DBT); /* type */ + ent.crdate = ent.mddate = time(0); /* date is now */ + ent.fdflags = HFS_FNDR_ISINVISIBLE; /* invisible files */ + + /* + * clear the DB file + */ + blk = hce->hfs_ce + hce->hfs_ce_size * HFS_BLOCKSZ; + blks = hce->hfs_dt_size; + clps = blks * HFS_BLOCKSZ; + + memset(blk, 0, clps); + + /* + * create "Desktop DB" (if it doesn't exist) + */ + if (hfs_create(vol, DB, ent.u.file.type, ent.u.file.creator) == 0) { + /* + * DB file size from hce_mem info + * set up "Desktop DB" data - following found by od'ing the + * "Desktop DB" file + */ + d_putw(blk + 8, 0x100); + d_putw(blk + 10, 0x3); + + d_putw(blk + 32, 0x200); + d_putw(blk + 34, 0x25); + + d_putl(blk + 36, blks); + d_putl(blk + 40, blks - 1); + + d_putl(blk + 46, clps); + d_putw(blk + 50, 0xff); + + d_putw(blk + 120, 0x20a); + d_putw(blk + 122, 0x100); + + d_putw(blk + 248, 0x8000); + + d_putl(blk + 504, 0x1f800f8); + d_putl(blk + 508, 0x78000e); + + /* entries for "Desktop DB" */ + ent.u.file.dsize = clps; /* size = clump size */ + + /* open file */ + if ((hfp = hfs_open(vol, DB)) == 0) + perr(hfs_error); + + /* "write" file */ + write_fork(hfp, clps); + + /* set DB file attributes */ + if (hfs_fsetattr(hfp, &ent) < 0) + perr(hfs_error); + + /* find the real start of the file */ + end += hce->hfs_ce_size; + + /* close DB file */ + if (hfs_close(hfp, end, 0) < 0) + perr(hfs_error); + } else { + /* + * if it already exists, then make sure it has the correct + * type/creator and flags + */ + if (hfs_setattr(vol, DB, &ent) < 0) + perr(hfs_error); + } + + /* setup "Desktop DF" file as an empty file */ + strcpy(ent.u.file.type, DFT); /* type */ + ent.u.file.dsize = 0; /* empty */ + + /* create DF file (if it doesn't exist) - no need to open it */ + hfs_create(vol, DF, ent.u.file.type, ent.u.file.creator); + + /* set DB file attributes */ + if (hfs_setattr(vol, DF, &ent) < 0) + perr(hfs_error); + + return (0); +} + +#endif /* APPLE_HYB */ diff --git a/genisoimage/diag/README b/genisoimage/diag/README new file mode 100644 index 0000000..26851f2 --- /dev/null +++ b/genisoimage/diag/README @@ -0,0 +1,76 @@ +# @(#)README 1.1 97/02/23 eric +# + I am enclosing 3 test programs that I use to verify the +integrity of an iso9660 disc. The first one (isodump) is pretty +simple - it dumps to the screen the contents of the various +directories. The second one (isovfy) goes through and looks for +problems of one kind or another. + + To use, type something like "./isodump /dev/ramdisk" or +"./isodump /dev/scd0", depending upon where the iso9660 disc is. It +starts by displaying the files in the first sector of the root +directory. It has some pretty simple one letter commands that you +can use to traverse the directory tree. + + a - move back one sector. + b - move forward one sector. + g - go to new logical sector. + q - quit + +The a and b commands do not try and stop you from going past the +beginning or end of a sector, and the g command does not have any way +of knowing whether the sector you request is actually a directory or +not. + + The output is displayed in several columns. The first column +is the total length of the directory record for the file. The second +column (in [] brackets) is the volume number. Next comes the starting +extent number (in hex), and then comes the file size in bytes. Then +cones the filename (not the Rock Ridge version), and this is preceeded +by an "*" if the file is a directory. After this is a summary of the +Rock Ridge fields present along with a display of the translation of +the symbolic link name if the SL Rock Ridge record is present. + + I tailored this program for debugging some of the problems +that I was having earlier. The idea is that you can tailor it +to test for problems that you might be having, so it is not intended +as a be-all and end-all dump program. + + If you move to a sector that does not contain directory +information, the results are unpredictable. + + The second program, isovfy, is run in the same way as isodump, +except that you do not have to do much except let it run. I have it +written to verify all kinds of different things, and as people find +other sorts of problems other tests could be added. + + The third program, dump.c, basically does a hexdump of the cd. +This is screen oriented, and there are some simple commands: + + a - move back one sector. + b - move forward one sector. + f - enter new search string. + + - search forward for search string. + g - go to new logical sector. + q - quit + + + Note that with the 'g' command, sectors are always given in +hex, and represent 2048 byte sectors (as on the cdrom). If you know +how to decode a raw iso9660 directory, you can pick out the starting +extent number from the hexdump and know where to go from there. The +starting extent appears something like 30 bytes prior to the start of +the iso9660 (not Rock Ridge) filename, and it appears in a 7.3.3 +format (meaning that it occupies 8 bytes, 4 in little endian format, +and 4 in big endian format). Thus you should see a mirror image of +the bytes when looking at the extent number. + + The isovfy program can also dump the contents of the path +tables, but this capability is commented out right now. Feel free +to enable this to see what is in the tables. Ultimately I may fix +it so that this checks the integrity of the tables as well. + + The isovfy program gives warnings about things like files that +have a size of 0 but have an extent number assigned. The genisoimage program +should never do this, but the YM software does leave these around. +I think it is probably harmless in the YM case.~ diff --git a/genisoimage/diag/devdump.1 b/genisoimage/diag/devdump.1 new file mode 100644 index 0000000..b170c59 --- /dev/null +++ b/genisoimage/diag/devdump.1 @@ -0,0 +1,2 @@ +.so man1/isoinfo.1 +.\" %Z%%M% %I% %E% joerg diff --git a/genisoimage/diag/dump.c b/genisoimage/diag/dump.c new file mode 100644 index 0000000..b853c4e --- /dev/null +++ b/genisoimage/diag/dump.c @@ -0,0 +1,428 @@ +/* + * 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. + * + */ + +/* @(#)dump.c 1.24 05/05/15 joerg */ +/* + * File dump.c - dump a file/device both in hex and in ASCII. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999-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 <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <utypes.h> + +#include <stdio.h> +#include <standard.h> +#include <ttydefs.h> +#include <signal.h> +#include <schily.h> + +#include "../scsi.h" +#include "../../wodim/defaults.h" + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define infile in_image +FILE *infile = NULL; +static off_t file_addr; +static off_t sec_addr = (off_t)-1; +static Uchar sector[2048]; +#define PAGE 256 +static Uchar buffer[PAGE]; +static Uchar search[64]; + +#ifdef USE_V7_TTY +static struct sgttyb savetty; +static struct sgttyb newtty; +#else +static struct termios savetty; +static struct termios newtty; +#endif + +static void reset_tty(void); +static void set_tty(void); +static void onsusp(int sig); +static void crsr2(int row, int col); +static void readblock(void); +static void showblock(int flag); +static int getbyte(void); +static void usage(int excode); + +static void +reset_tty() +{ +#ifdef USE_V7_TTY + if (ioctl(STDIN_FILENO, TIOCSETN, &savetty) == -1) { +#else +#ifdef TCSANOW + if (tcsetattr(STDIN_FILENO, TCSANOW, &savetty) == -1) { +#else + if (ioctl(STDIN_FILENO, TCSETAF, &savetty) == -1) { +#endif +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot put tty into normal mode\n"); +#else + printf("Cannot put tty into normal mode\n"); + exit(1); +#endif + } +} + +static void +set_tty() +{ +#ifdef USE_V7_TTY + if (ioctl(STDIN_FILENO, TIOCSETN, &newtty) == -1) { +#else +#ifdef TCSANOW + if (tcsetattr(STDIN_FILENO, TCSANOW, &newtty) == -1) { +#else + if (ioctl(STDIN_FILENO, TCSETAF, &newtty) == -1) { +#endif +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot put tty into raw mode\n"); +#else + printf("Cannot put tty into raw mode\n"); + exit(1); +#endif + } +} + + +/* + * Come here when we get a suspend signal from the terminal + */ +static void +onsusp(int sig) +{ +#ifdef SIGTTOU + /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */ + signal(SIGTTOU, SIG_IGN); +#endif + reset_tty(); + fflush(stdout); +#ifdef SIGTTOU + signal(SIGTTOU, SIG_DFL); + /* Send the TSTP signal to suspend our process group */ + signal(SIGTSTP, SIG_DFL); + /* sigsetmask(0);*/ + kill(0, SIGTSTP); + /* Pause for station break */ + + /* We're back */ + signal(SIGTSTP, onsusp); +#endif + set_tty(); +} + + +static void +crsr2(int row, int col) +{ + printf("\033[%d;%dH", row, col); +} + +static void +readblock() +{ + off_t dpos = file_addr - sec_addr; + + if (sec_addr < 0 || + dpos < 0 || (dpos + sizeof (buffer)) > sizeof (sector)) { + sec_addr = file_addr & ~2047; +#ifdef USE_SCG + readsecs(sec_addr/2048, sector, ISO_BLOCKS(sizeof (sector))); +#else + lseek(fileno(infile), sec_addr, SEEK_SET); + read(fileno(infile), sector, sizeof (sector)); +#endif + dpos = file_addr - sec_addr; + } + movebytes(§or[dpos], buffer, sizeof (buffer)); +} + +static void +showblock(int flag) +{ + unsigned int k; + int i; + int j; + + readblock(); + if (flag) { + for (i = 0; i < 16; i++) { + crsr2(i+3, 1); + if (sizeof (file_addr) > sizeof (long)) { + printf("%16.16llx ", (Llong)file_addr+(i<<4)); + } else { + printf("%8.8lx ", (long)file_addr+(i<<4)); + } + for (j = 15; j >= 0; j--) { + printf("%2.2x", buffer[(i<<4)+j]); + if (!(j & 0x3)) + printf(" "); + } + for (j = 0; j < 16; j++) { + k = buffer[(i << 4) + j]; + if (k >= ' ' && k < 0x80) + printf("%c", k); + else + printf("."); + } + } + } + crsr2(20, 1); + if (sizeof (file_addr) > sizeof (long)) { + printf(" Zone, zone offset: %14llx %12.12llx ", + (Llong)file_addr>>11, (Llong)file_addr & 0x7ff); + } else { + printf(" Zone, zone offset: %6lx %4.4lx ", + (long)(file_addr>>11), (long)(file_addr & 0x7ff)); + } + fflush(stdout); +} + +static int +getbyte() +{ + char c1; + + c1 = buffer[file_addr & (PAGE-1)]; + file_addr++; + if ((file_addr & (PAGE-1)) == 0) + showblock(0); + return (c1); +} + +static void +usage(int excode) +{ + errmsgno(EX_BAD, "Usage: %s [options] [image]\n", + get_progname()); + + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t-help, -h Print this help\n"); + fprintf(stderr, "\t-version Print version info and exit\n"); + fprintf(stderr, "\t-i filename Filename to read ISO-9660 image from\n"); + fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n"); + fprintf(stderr, "\nIf neither -i nor dev= are speficied, <image> is needed.\n"); + exit(excode); +} + +int +main(int argc, char *argv[]) +{ + int cac; + char * const *cav; + char *opts = "help,h,version,i*,dev*"; + BOOL help = FALSE; + BOOL prvers = FALSE; + char *filename = NULL; + char *devname = NULL; + char c; + int i; + int j; + + save_args(argc, argv); + + cac = argc - 1; + cav = argv + 1; + if (getallargs(&cac, &cav, opts, &help, &help, &prvers, + &filename, &devname) < 0) { + errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (help) + usage(0); + if (prvers) { + printf("devdump %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM); + exit(0); + } + cac = argc - 1; + cav = argv + 1; + if (filename == NULL && devname == NULL) { + if (getfiles(&cac, &cav, opts) != 0) { + filename = cav[0]; + cac--, cav++; + } + } + if (getfiles(&cac, &cav, opts) != 0) { + errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (filename != NULL && devname != NULL) { + errmsgno(EX_BAD, "Only one of -i or dev= allowed\n"); + usage(EX_BAD); + } +#ifdef USE_SCG + if (filename == NULL && devname == NULL) + cdr_defaults(&devname, NULL, NULL, NULL); +#endif + if (filename == NULL && devname == NULL) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "ISO-9660 image not specified\n"); +#else + fprintf(stderr, "ISO-9660 image not specified\n"); +#endif + usage(EX_BAD); + } + + if (filename != NULL) + infile = fopen(filename, "rb"); + else + filename = devname; + + if (infile != NULL) { + /* EMPTY */; +#ifdef USE_SCG + } else if (scsidev_open(filename) < 0) { +#else + } else { +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot open '%s'\n", filename); +#else + fprintf(stderr, "Cannot open '%s'\n", filename); + exit(1); +#endif + } + + for (i = 0; i < 30; i++) + printf("\n"); + file_addr = (off_t)0; + + /* + * Now setup the keyboard for single character input. + */ +#ifdef USE_V7_TTY + if (ioctl(STDIN_FILENO, TIOCGETP, &savetty) == -1) { +#else +#ifdef TCSANOW + if (tcgetattr(STDIN_FILENO, &savetty) == -1) { +#else + if (ioctl(STDIN_FILENO, TCGETA, &savetty) == -1) { +#endif +#endif +#ifdef USE_LIBSCHILY + comerr("Stdin must be a tty\n"); +#else + printf("Stdin must be a tty\n"); + exit(1); +#endif + } + newtty = savetty; +#ifdef USE_V7_TTY + newtty.sg_flags &= ~(ECHO|CRMOD); + newtty.sg_flags |= CBREAK; +#else + newtty.c_lflag &= ~ICANON; + newtty.c_lflag &= ~ECHO; + newtty.c_cc[VMIN] = 1; +#endif + set_tty(); +#ifdef SIGTSTP + signal(SIGTSTP, onsusp); +#endif + on_comerr((void(*)(int, void *))reset_tty, NULL); + + do { + if (file_addr < (off_t)0) file_addr = (off_t)0; + showblock(1); + read(STDIN_FILENO, &c, 1); /* FIXME: check return value */ + if (c == 'a') + file_addr -= PAGE; + if (c == 'b') + file_addr += PAGE; + if (c == 'g') { + crsr2(20, 1); + printf("Enter new starting block (in hex):"); + if (sizeof (file_addr) > sizeof (long)) { + Llong ll; + scanf("%llx", &ll); /* FIXME: check return value */ + file_addr = (off_t)ll; + } else { + long l; + scanf("%lx", &l); /* FIXME: check return value */ + file_addr = (off_t)l; + } + file_addr = file_addr << 11; + crsr2(20, 1); + printf(" "); + } + if (c == 'f') { + crsr2(20, 1); + printf("Enter new search string:"); + fgets((char *)search, sizeof (search), stdin); /* FIXME: check return value */ + while (search[strlen((char *)search)-1] == '\n') + search[strlen((char *)search)-1] = 0; + crsr2(20, 1); + printf(" "); + } + if (c == '+') { + while (1 == 1) { + int slen; + + while (1 == 1) { + c = getbyte(); + if (c == search[0]) + break; + } + slen = (int)strlen((char *)search); + for (j = 1; j < slen; j++) { + if (search[j] != getbyte()) + break; + } + if (j == slen) + break; + } + file_addr &= ~(PAGE-1); + showblock(1); + } + if (c == 'q') + break; + } while (1 == 1); + reset_tty(); + if (infile != NULL) + fclose(infile); + return (0); +} diff --git a/genisoimage/diag/isodebug.1 b/genisoimage/diag/isodebug.1 new file mode 100644 index 0000000..58f0d9d --- /dev/null +++ b/genisoimage/diag/isodebug.1 @@ -0,0 +1,108 @@ +.\" @(#)isodebug.8 1.1 06/02/08 Copyr 2006 J. Schilling +.\" Manual page for isodebug +.\" Modified for cdrkit distribution by E.Bloch +.\" +.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 ISODEBUG 1 "06/02/08" "J\*org Schilling" "Schily\'s USER COMMANDS" +.SH NAME +isodebug \- print genisoimage debug info from ISO-9660 image +.SH SYNOPSIS +.B +isodebug +[ +.I options +] +[ +.I file +] +.SH DESCRIPTION +.B Isodebug +reads the debug info written by +.BR genisoimage (8) +from within a ISO-9660 file system image and prints them. +. \" .SH RETURNS +. \" .SH ERRORS +.SH OPTIONS +.TP +.B \-help +Prints a short summary of the +.B isodebug +options and exists. +.TP +.B \-version +Prints the +.B isodebug +version number string and exists. +.TP +.BI \-i " filename +Filename to read ISO-9660 image from. +.TP +.BI dev= target +SCSI target to use as CD/DVD-Recorder. +See +.BR wodim (1) +for more information on now to use this option. +.SH FILES +.SH "SEE ALSO" +.BR wodim (1), +.BR genisoimage (1). +.SH AUTHOR +.nf +J\*org Schilling +Seestr. 110 +D-13353 Berlin +Germany +.fi +.PP + + +.SH AUTHOR +.nf +J\*org Schilling +Seestr. 110 +D-13353 Berlin +Germany +.fi + +.PP +This manpage describes the program implementation of +.B +isodebug +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program distributed in the +cdrtools package [1]. However, the cdrtools developers are not +involved in the development of this spinoff and therefore shall not be made +responsible for any problem caused by it. Do not try to get support for this +program by contacting the original author(s). +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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. +.PP +.br +[1] Cdrtools 2.01.01a08 from May 2006, http://cdrecord.berlios.de + + diff --git a/genisoimage/diag/isodebug.c b/genisoimage/diag/isodebug.c new file mode 100644 index 0000000..f322021 --- /dev/null +++ b/genisoimage/diag/isodebug.c @@ -0,0 +1,281 @@ +/* + * 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. + * + */ + +/* @(#)isodebug.c 1.10 05/05/01 Copyright 1996-2004 J. Schilling */ +/* + * Copyright (c) 1996-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 <sys/types.h> +#include <sys/stat.h> +#include <statdefs.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <standard.h> +#include <utypes.h> +#include <intcvt.h> +#include <schily.h> + +#include "../scsi.h" +#include "../../wodim/defaults.h" + +#define _delta(from, to) ((to) - (from) + 1) + +#define VD_BOOT 0 +#define VD_PRIMARY 1 +#define VD_SUPPLEMENT 2 +#define VD_PARTITION 3 +#define VD_TERM 255 + +#define VD_ID "CD001" + +struct iso9660_voldesc { + char vd_type [_delta(1, 1)]; + char vd_id [_delta(2, 6)]; + char vd_version [_delta(7, 7)]; + char vd_fill [_delta(8, 2048)]; +}; + +struct iso9660_boot_voldesc { + char vd_type [_delta(1, 1)]; + char vd_id [_delta(2, 6)]; + char vd_version [_delta(7, 7)]; + char vd_bootsys [_delta(8, 39)]; + char vd_bootid [_delta(40, 71)]; + char vd_bootcode [_delta(72, 2048)]; +}; + +struct iso9660_pr_voldesc { + char vd_type [_delta(1, 1)]; + char vd_id [_delta(2, 6)]; + char vd_version [_delta(7, 7)]; + char vd_unused1 [_delta(8, 8)]; + char vd_system_id [_delta(9, 40)]; + char vd_volume_id [_delta(41, 72)]; + char vd_unused2 [_delta(73, 80)]; + char vd_volume_space_size [_delta(81, 88)]; + char vd_unused3 [_delta(89, 120)]; + char vd_volume_set_size [_delta(121, 124)]; + char vd_volume_seq_number [_delta(125, 128)]; + char vd_lbsize [_delta(129, 132)]; + char vd_path_table_size [_delta(133, 140)]; + char vd_pos_path_table_l [_delta(141, 144)]; + char vd_opt_pos_path_table_l [_delta(145, 148)]; + char vd_pos_path_table_m [_delta(149, 152)]; + char vd_opt_pos_path_table_m [_delta(153, 156)]; + char vd_root_dir [_delta(157, 190)]; + char vd_volume_set_id [_delta(191, 318)]; + char vd_publisher_id [_delta(319, 446)]; + char vd_data_preparer_id [_delta(447, 574)]; + char vd_application_id [_delta(575, 702)]; + char vd_copyr_file_id [_delta(703, 739)]; + char vd_abstr_file_id [_delta(740, 776)]; + char vd_bibl_file_id [_delta(777, 813)]; + char vd_create_time [_delta(814, 830)]; + char vd_mod_time [_delta(831, 847)]; + char vd_expiry_time [_delta(848, 864)]; + char vd_effective_time [_delta(865, 881)]; + char vd_file_struct_vers [_delta(882, 882)]; + char vd_reserved1 [_delta(883, 883)]; + char vd_application_use [_delta(884, 1395)]; + char vd_fill [_delta(1396, 2048)]; +}; + +#define GET_UBYTE(a) a_to_u_byte(a) +#define GET_SBYTE(a) a_to_byte(a) +#define GET_SHORT(a) a_to_u_2_byte(&((unsigned char *) (a))[0]) +#define GET_BSHORT(a) a_to_u_2_byte(&((unsigned char *) (a))[2]) +#define GET_INT(a) a_to_4_byte(&((unsigned char *) (a))[0]) +#define GET_LINT(a) la_to_4_byte(&((unsigned char *) (a))[0]) +#define GET_BINT(a) a_to_4_byte(&((unsigned char *) (a))[4]) + +#define infile in_image +FILE *infile = NULL; + +static void usage(int excode); +static char *isodinfo(FILE *f); + +static void +usage(int excode) +{ + errmsgno(EX_BAD, "Usage: %s [options] image\n", + get_progname()); + + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t-help,-h Print this help\n"); + fprintf(stderr, "\t-version Print version info and exit\n"); + fprintf(stderr, "\t-i filename Filename to read ISO-9660 image from\n"); + fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n"); + fprintf(stderr, "\nIf neither -i nor dev= are speficied, <image> is needed.\n"); + exit(excode); +} + +static char * +isodinfo(FILE *f) +{ +static struct iso9660_voldesc vd; + struct iso9660_pr_voldesc *vp; +#ifndef USE_SCG + struct stat sb; + mode_t mode; +#endif + BOOL found = FALSE; + off_t sec_off = 16L; + +#ifndef USE_SCG + /* + * First check if a bad guy tries to call isosize() + * with an unappropriate file descriptor. + * return -1 in this case. + */ + if (isatty(fileno(f))) + return (NULL); + if (fstat(fileno(f), &sb) < 0) + return (NULL); + mode = sb.st_mode & S_IFMT; + if (!S_ISREG(mode) && !S_ISBLK(mode) && !S_ISCHR(mode)) + return (NULL); +#endif + + vp = (struct iso9660_pr_voldesc *) &vd; + + do { +#ifdef USE_SCG + readsecs(sec_off, &vd, 1); +#else + if (lseek(fileno(f), (off_t)(sec_off * 2048L), SEEK_SET) == -1) + return (NULL); + read(fileno(f), &vd, sizeof (vd)); +#endif + sec_off++; + + if (GET_UBYTE(vd.vd_type) == VD_PRIMARY) { + found = TRUE; +/* break;*/ + } + + } while (GET_UBYTE(vd.vd_type) != VD_TERM); + + if (GET_UBYTE(vd.vd_type) != VD_TERM) + return (NULL); + +#ifdef USE_SCG + readsecs(sec_off, &vd, 1); +#else + if (lseek(fileno(f), (off_t)(sec_off * 2048L), SEEK_SET) == -1) + return (NULL); + read(fileno(f), &vd, sizeof (vd)); +#endif + sec_off++; + + return ((char *)&vd); +} + +int +main(int argc, char *argv[]) +{ + int cac; + char * const *cav; + char *opts = "help,h,version,i*,dev*"; + BOOL help = FALSE; + BOOL prvers = FALSE; + char *filename = NULL; + char *devname = NULL; + char *p; + char *eol; + + save_args(argc, argv); + + cac = argc - 1; + cav = argv + 1; + if (getallargs(&cac, &cav, opts, &help, &help, &prvers, + &filename, &devname) < 0) { + errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (help) + usage(0); + if (prvers) { + printf("isodebug %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM); + exit(0); + } + cac = argc - 1; + cav = argv + 1; + if (filename == NULL && devname == NULL) { + if (getfiles(&cac, &cav, opts) != 0) { + filename = cav[0]; + cac--, cav++; + } + } + if (getfiles(&cac, &cav, opts) != 0) { + errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (filename != NULL && devname != NULL) { + errmsgno(EX_BAD, "Only one of -i or dev= allowed\n"); + usage(EX_BAD); + } +#ifdef USE_SCG + if (filename == NULL && devname == NULL) + cdr_defaults(&devname, NULL, NULL, NULL); +#endif + if (filename == NULL && devname == NULL) { + errmsgno(EX_BAD, "ISO-9660 image not specified\n"); + usage(EX_BAD); + } + + if (filename != NULL) + infile = fopen(filename, "rb"); + else + filename = devname; + + if (infile != NULL) { + /* EMPTY */; +#ifdef USE_SCG + } else if (scsidev_open(filename) < 0) { +#else + } else { +#endif + comerr("Cannot open '%s'\n", filename); + } + + p = isodinfo(infile); + if (p == NULL) { + printf("No ISO-9660 image debug info.\n"); + } else if (strncmp(p, "MKI ", 4) == 0) { + eol = strchr(p, '\n'); + if (eol) + *eol = '\0'; + printf("ISO-9660 image created at %s\n", &p[4]); + if (eol) { + printf("\nCmdline: '%s'\n", &eol[1]); + } + } + return (0); +} diff --git a/genisoimage/diag/isodump.1 b/genisoimage/diag/isodump.1 new file mode 100644 index 0000000..b170c59 --- /dev/null +++ b/genisoimage/diag/isodump.1 @@ -0,0 +1,2 @@ +.so man1/isoinfo.1 +.\" %Z%%M% %I% %E% joerg diff --git a/genisoimage/diag/isodump.c b/genisoimage/diag/isodump.c new file mode 100644 index 0000000..34fa8f1 --- /dev/null +++ b/genisoimage/diag/isodump.c @@ -0,0 +1,715 @@ +/* + * 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. + * + */ + +/* @(#)isodump.c 1.27 05/05/15 joerg */ +/* + * File isodump.c - dump iso9660 directory information. + * + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999-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 <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <utypes.h> + +#include <stdio.h> +#include <standard.h> +#include <ttydefs.h> +#include <signal.h> +#include <schily.h> + +#include "../scsi.h" +#include "../../wodim/defaults.h" + +/* + * XXX JS: Some structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See iso9660.h + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define infile in_image +FILE *infile = NULL; +off_t file_addr; +unsigned char buffer[2048]; +unsigned char search[64]; +int blocksize; + +#define PAGE sizeof (buffer) + +#define ISODCL(from, to) (to - from + 1) + +struct iso_primary_descriptor { + unsigned char type [ISODCL(1, 1)]; /* 711 */ + unsigned char id [ISODCL(2, 6)]; + unsigned char version [ISODCL(7, 7)]; /* 711 */ + unsigned char unused1 [ISODCL(8, 8)]; + unsigned char system_id [ISODCL(9, 40)]; /* aunsigned chars */ + unsigned char volume_id [ISODCL(41, 72)]; /* dunsigned chars */ + unsigned char unused2 [ISODCL(73, 80)]; + unsigned char volume_space_size [ISODCL(81, 88)]; /* 733 */ + unsigned char unused3 [ISODCL(89, 120)]; + unsigned char volume_set_size [ISODCL(121, 124)]; /* 723 */ + unsigned char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + unsigned char logical_block_size [ISODCL(129, 132)]; /* 723 */ + unsigned char path_table_size [ISODCL(133, 140)]; /* 733 */ + unsigned char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + unsigned char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + unsigned char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + unsigned char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + unsigned char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + unsigned char volume_set_id [ISODCL(191, 318)]; /* dunsigned chars */ + unsigned char publisher_id [ISODCL(319, 446)]; /* achars */ + unsigned char preparer_id [ISODCL(447, 574)]; /* achars */ + unsigned char application_id [ISODCL(575, 702)]; /* achars */ + unsigned char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + unsigned char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + unsigned char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + unsigned char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + unsigned char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + unsigned char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + unsigned char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + unsigned char file_structure_version [ISODCL(882, 882)]; /* 711 */ + unsigned char unused4 [ISODCL(883, 883)]; + unsigned char application_data [ISODCL(884, 1395)]; + unsigned char unused5 [ISODCL(1396, 2048)]; +}; + +struct iso_directory_record { + unsigned char length [ISODCL(1, 1)]; /* 711 */ + unsigned char ext_attr_length [ISODCL(2, 2)]; /* 711 */ + unsigned char extent [ISODCL(3, 10)]; /* 733 */ + unsigned char size [ISODCL(11, 18)]; /* 733 */ + unsigned char date [ISODCL(19, 25)]; /* 7 by 711 */ + unsigned char flags [ISODCL(26, 26)]; + unsigned char file_unit_size [ISODCL(27, 27)]; /* 711 */ + unsigned char interleave [ISODCL(28, 28)]; /* 711 */ + unsigned char volume_sequence_number [ISODCL(29, 32)]; /* 723 */ + unsigned char name_len [ISODCL(33, 33)]; /* 711 */ + unsigned char name [1]; +}; + +static int isonum_731(char * p); +static int isonum_72(char * p); +static int isonum_723(char * p); +static int isonum_733(unsigned char * p); +static void reset_tty(void); +static void set_tty(void); +static void onsusp(int signo); +static void crsr2(int row, int col); +static int parse_rr(unsigned char * pnt, int len, int cont_flag); +static void dump_rr(struct iso_directory_record * idr); +static void showblock(int flag); +static int getbyte(void); +static void usage(int excode); + +static int +isonum_731(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +static int +isonum_721(char *p) +{ + return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); +} + +static int +isonum_723(char *p) +{ +#if 0 + if (p[0] != p[3] || p[1] != p[2]) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "invalid format 7.2.3 number\n"); +#else + fprintf(stderr, "invalid format 7.2.3 number\n"); + exit(1); +#endif + } +#endif + return (isonum_721(p)); +} + + +static int +isonum_733(unsigned char *p) +{ + return (isonum_731((char *)p)); +} + +#ifdef USE_V7_TTY +static struct sgttyb savetty; +static struct sgttyb newtty; +#else +static struct termios savetty; +static struct termios newtty; +#endif + +static void +reset_tty() +{ +#ifdef USE_V7_TTY + if (ioctl(STDIN_FILENO, TIOCSETN, &savetty) == -1) { +#else +#ifdef TCSANOW + if (tcsetattr(STDIN_FILENO, TCSANOW, &savetty) == -1) { +#else + if (ioctl(STDIN_FILENO, TCSETAF, &savetty) == -1) { +#endif +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot put tty into normal mode\n"); +#else + printf("Cannot put tty into normal mode\n"); + exit(1); +#endif + } +} + +static void +set_tty() +{ +#ifdef USE_V7_TTY + if (ioctl(STDIN_FILENO, TIOCSETN, &newtty) == -1) { +#else +#ifdef TCSANOW + if (tcsetattr(STDIN_FILENO, TCSANOW, &newtty) == -1) { +#else + if (ioctl(STDIN_FILENO, TCSETAF, &newtty) == -1) { +#endif +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot put tty into raw mode\n"); +#else + printf("Cannot put tty into raw mode\n"); + exit(1); +#endif + } +} + +/* Come here when we get a suspend signal from the terminal */ + +static void +onsusp(int signo) +{ +#ifdef SIGTTOU + /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */ + signal(SIGTTOU, SIG_IGN); +#endif + reset_tty(); + fflush(stdout); +#ifdef SIGTTOU + signal(SIGTTOU, SIG_DFL); + /* Send the TSTP signal to suspend our process group */ + signal(SIGTSTP, SIG_DFL); +/* sigsetmask(0);*/ + kill(0, SIGTSTP); + /* Pause for station break */ + + /* We're back */ + signal(SIGTSTP, onsusp); +#endif + set_tty(); +} + + + +static void +crsr2(int row, int col) +{ + printf("\033[%d;%dH", row, col); +} + +static int +parse_rr(unsigned char *pnt, int len, int cont_flag) +{ + int slen; + int ncount; + int extent; + off_t cont_extent; + int cont_offset; + int cont_size; + int flag1; + int flag2; + unsigned char *pnts; + char symlinkname[1024]; + char name[1024]; + int goof; + +/* printf(" RRlen=%d ", len); */ + + symlinkname[0] = 0; + + cont_extent = (off_t)0; + cont_offset = cont_size = 0; + + ncount = 0; + flag1 = flag2 = 0; + while (len >= 4) { + if (ncount) + printf(","); + else + printf("["); + printf("%c%c", pnt[0], pnt[1]); + if (pnt[3] != 1 && pnt[3] != 2) { + printf("**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]); + return (0); /* JS ??? Is this right ??? */ + } else if (pnt[0] == 'R' && pnt[1] == 'R') { + printf("=%d", pnt[3]); + } + ncount++; + if (pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff; + if (strncmp((char *)pnt, "PX", 2) == 0) flag2 |= 1; + if (strncmp((char *)pnt, "PN", 2) == 0) flag2 |= 2; + if (strncmp((char *)pnt, "SL", 2) == 0) flag2 |= 4; + if (strncmp((char *)pnt, "NM", 2) == 0) { + slen = pnt[2] - 5; + pnts = pnt+5; + if ((pnt[4] & 6) != 0) { + printf("*"); + } + memset(name, 0, sizeof (name)); + memcpy(name, pnts, slen); + printf("=%s", name); + flag2 |= 8; + } + if (strncmp((char *)pnt, "CL", 2) == 0) flag2 |= 16; + if (strncmp((char *)pnt, "PL", 2) == 0) flag2 |= 32; + if (strncmp((char *)pnt, "RE", 2) == 0) flag2 |= 64; + if (strncmp((char *)pnt, "TF", 2) == 0) flag2 |= 128; + + if (strncmp((char *)pnt, "PX", 2) == 0) { + extent = isonum_733(pnt+12); + printf("=%x", extent); + } + + if (strncmp((char *)pnt, "CE", 2) == 0) { + cont_extent = (off_t)isonum_733(pnt+4); + cont_offset = isonum_733(pnt+12); + cont_size = isonum_733(pnt+20); + printf("=[%x,%x,%d]", (int)cont_extent, cont_offset, + cont_size); + } + + if (strncmp((char *)pnt, "PL", 2) == 0 || strncmp((char *)pnt, "CL", 2) == 0) { + extent = isonum_733(pnt+4); + printf("=%x", extent); + } + + if (strncmp((char *)pnt, "SL", 2) == 0) { + int cflag; + + cflag = pnt[4]; + pnts = pnt+5; + slen = pnt[2] - 5; + while (slen >= 1) { + switch (pnts[0] & 0xfe) { + case 0: + strncat(symlinkname, (char *)(pnts+2), pnts[1]); + break; + case 2: + strcat(symlinkname, "."); + break; + case 4: + strcat(symlinkname, ".."); + break; + case 8: + if ((pnts[0] & 1) == 0) + strcat(symlinkname, "/"); + break; + case 16: + strcat(symlinkname, "/mnt"); + printf("Warning - mount point requested"); + break; + case 32: + strcat(symlinkname, "kafka"); + printf("Warning - host_name requested"); + break; + default: + printf("Reserved bit setting in symlink"); + goof++; + break; + } + if ((pnts[0] & 0xfe) && pnts[1] != 0) { + printf("Incorrect length in symlink component"); + } + if ((pnts[0] & 1) == 0) + strcat(symlinkname, "/"); + + slen -= (pnts[1] + 2); + pnts += (pnts[1] + 2); + } + if (cflag) + strcat(symlinkname, "+"); + printf("=%s", symlinkname); + symlinkname[0] = 0; + } + + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + unsigned char sector[2048]; + +#ifdef USE_SCG + readsecs(cont_extent * blocksize / 2048, sector, ISO_BLOCKS(sizeof (sector))); +#else + lseek(fileno(infile), cont_extent * blocksize, SEEK_SET); + read(fileno(infile), sector, sizeof (sector)); +#endif + flag2 |= parse_rr(§or[cont_offset], cont_size, 1); + } + } + if (ncount) + printf("]"); + if (!cont_flag && flag1 != flag2) { + printf("Flag %x != %x", flag1, flag2); + goof++; + } + return (flag2); +} + +static void +dump_rr(struct iso_directory_record *idr) +{ + int len; + unsigned char *pnt; + + len = idr->length[0] & 0xff; + len -= offsetof(struct iso_directory_record, name[0]); + len -= idr->name_len[0]; + pnt = (unsigned char *) idr; + pnt += offsetof(struct iso_directory_record, name[0]); + pnt += idr->name_len[0]; + if ((idr->name_len[0] & 1) == 0) { + pnt++; + len--; + } + parse_rr(pnt, len, 0); +} + + +static void +showblock(int flag) +{ + int i; + int j; + int line; + struct iso_directory_record *idr; + +#ifdef USE_SCG + readsecs(file_addr / 2048, buffer, ISO_BLOCKS(sizeof (buffer))); +#else + lseek(fileno(infile), file_addr, SEEK_SET); + read(fileno(infile), buffer, sizeof (buffer)); +#endif + for (i = 0; i < 60; i++) + printf("\n"); + fflush(stdout); + i = line = 0; + if (flag) { + while (1 == 1) { + crsr2(line+3, 1); + idr = (struct iso_directory_record *) &buffer[i]; + if (idr->length[0] == 0) + break; + printf("%3d ", idr->length[0]); + printf("[%2d] ", idr->volume_sequence_number[0]); + printf("%5x ", isonum_733(idr->extent)); + printf("%8d ", isonum_733(idr->size)); + printf("%02x/", idr->flags[0]); + printf((idr->flags[0] & 2) ? "*" : " "); + if (idr->name_len[0] == 1 && idr->name[0] == 0) + printf(". "); + else if (idr->name_len[0] == 1 && idr->name[0] == 1) + printf(".. "); + else { + for (j = 0; j < (int)idr->name_len[0]; j++) printf("%c", idr->name[j]); + for (j = 0; j < (14 - (int)idr->name_len[0]); j++) printf(" "); + } + dump_rr(idr); + printf("\n"); + i += buffer[i]; + if (i > 2048 - offsetof(struct iso_directory_record, name[0])) + break; + line++; + } + } + printf("\n"); + if (sizeof (file_addr) > sizeof (long)) { + printf(" Zone, zone offset: %14llx %12.12llx ", + (Llong)file_addr / blocksize, + (Llong)file_addr & (Llong)(blocksize - 1)); + } else { + printf(" Zone, zone offset: %6lx %4.4lx ", + (long) (file_addr / blocksize), + (long) file_addr & (blocksize - 1)); + } + fflush(stdout); +} + +static int +getbyte() +{ + char c1; + + c1 = buffer[file_addr & (blocksize-1)]; + file_addr++; + if ((file_addr & (blocksize-1)) == 0) + showblock(0); + return (c1); +} + +static void +usage(int excode) +{ + errmsgno(EX_BAD, "Usage: %s [options] image\n", + get_progname()); + + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t-help, -h Print this help\n"); + fprintf(stderr, "\t-version Print version info and exit\n"); + fprintf(stderr, "\t-i filename Filename to read ISO-9660 image from\n"); + fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n"); + fprintf(stderr, "\nIf neither -i nor dev= are speficied, <image> is needed.\n"); + exit(excode); +} + +int +main(int argc, char *argv[]) +{ + int cac; + char * const *cav; + char *opts = "help,h,version,i*,dev*"; + BOOL help = FALSE; + BOOL prvers = FALSE; + char *filename = NULL; + char *devname = NULL; + char c; + int i; + struct iso_primary_descriptor ipd; + struct iso_directory_record *idr; + + save_args(argc, argv); + + cac = argc - 1; + cav = argv + 1; + if (getallargs(&cac, &cav, opts, &help, &help, &prvers, + &filename, &devname) < 0) { + errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (help) + usage(0); + if (prvers) { + printf("isodump %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM); + exit(0); + } + cac = argc - 1; + cav = argv + 1; + if (filename == NULL && devname == NULL) { + if (getfiles(&cac, &cav, opts) != 0) { + filename = cav[0]; + cac--, cav++; + } + } + if (getfiles(&cac, &cav, opts) != 0) { + errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (filename != NULL && devname != NULL) { + errmsgno(EX_BAD, "Only one of -i or dev= allowed\n"); + usage(EX_BAD); + } +#ifdef USE_SCG + if (filename == NULL && devname == NULL) + cdr_defaults(&devname, NULL, NULL, NULL); +#endif + if (filename == NULL && devname == NULL) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "ISO-9660 image not specified\n"); +#else + fprintf(stderr, "ISO-9660 image not specified\n"); +#endif + usage(EX_BAD); + } + + if (filename != NULL) + infile = fopen(filename, "rb"); + else + filename = devname; + + if (infile != NULL) { + /* EMPTY */; +#ifdef USE_SCG + } else if (scsidev_open(filename) < 0) { +#else + } else { +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot open '%s'\n", filename); +#else + fprintf(stderr, "Cannot open '%s'\n", filename); + exit(1); +#endif + } + + file_addr = (off_t) (16 << 11); +#ifdef USE_SCG + readsecs(file_addr / 2048, &ipd, ISO_BLOCKS(sizeof (ipd))); +#else + lseek(fileno(infile), file_addr, SEEK_SET); + read(fileno(infile), &ipd, sizeof (ipd)); +#endif + idr = (struct iso_directory_record *)ipd.root_directory_record; + + blocksize = isonum_723((char *)ipd.logical_block_size); + if (blocksize != 512 && blocksize != 1024 && blocksize != 2048) { + blocksize = 2048; + } + + file_addr = (off_t)isonum_733(idr->extent); + file_addr = file_addr * blocksize; + +/* Now setup the keyboard for single character input. */ +#ifdef USE_V7_TTY + if (ioctl(STDIN_FILENO, TIOCGETP, &savetty) == -1) { +#else +#ifdef TCSANOW + if (tcgetattr(STDIN_FILENO, &savetty) == -1) { +#else + if (ioctl(STDIN_FILENO, TCGETA, &savetty) == -1) { +#endif +#endif +#ifdef USE_LIBSCHILY + comerr("Stdin must be a tty\n"); +#else + printf("Stdin must be a tty\n"); + exit(1); +#endif + } + newtty = savetty; +#ifdef USE_V7_TTY + newtty.sg_flags &= ~(ECHO|CRMOD); + newtty.sg_flags |= CBREAK; +#else + newtty.c_lflag &= ~ICANON; + newtty.c_lflag &= ~ECHO; + newtty.c_cc[VMIN] = 1; +#endif + set_tty(); +#ifdef SIGTSTP + signal(SIGTSTP, onsusp); +#endif + on_comerr((void(*)(int, void *))reset_tty, NULL); + + do { + if (file_addr < 0) + file_addr = (off_t)0; + showblock(1); + read(STDIN_FILENO, &c, 1); /* FIXME: check return value */ + if (c == 'a') + file_addr -= blocksize; + if (c == 'b') + file_addr += blocksize; + if (c == 'g') { + crsr2(20, 1); + printf("Enter new starting block (in hex):"); + if (sizeof (file_addr) > sizeof (long)) { + Llong ll; + scanf("%llx", &ll); /* FIXME: check return value */ + file_addr = (off_t)ll; + } else { + long l; + scanf("%lx", &l); /* FIXME: check return value */ + file_addr = (off_t)l; + } + file_addr = file_addr * blocksize; + crsr2(20, 1); + printf(" "); + } + if (c == 'f') { + crsr2(20, 1); + printf("Enter new search string:"); + fgets((char *)search, sizeof (search), stdin); /* FIXME: check return value */ + while (search[strlen((char *)search)-1] == '\n') + search[strlen((char *)search)-1] = 0; + crsr2(20, 1); + printf(" "); + } + if (c == '+') { + while (1 == 1) { + int slen; + + while (1 == 1) { + c = getbyte(); + if (c == search[0]) + break; + } + slen = (int)strlen((char *)search); + for (i = 1; i < slen; i++) { + if (search[i] != getbyte()) + break; + } + if (i == slen) + break; + } + file_addr &= ~(blocksize-1); + showblock(1); + } + if (c == 'q') + break; + } while (1 == 1); + reset_tty(); + if (infile != NULL) + fclose(infile); + return (0); +} diff --git a/genisoimage/diag/isoinfo.1 b/genisoimage/diag/isoinfo.1 new file mode 100644 index 0000000..1a00540 --- /dev/null +++ b/genisoimage/diag/isoinfo.1 @@ -0,0 +1,365 @@ +.\" +.\" @(#)isoinfo.8 1.7 04/06/01 joerg +.\" +.\" Modified for cdrkit in 12/2006 +.\" +.\" -*- nroff -*- +.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 ISOINFO 1 "04/06/01" "Version 2.0" +.SH NAME +devdump, isoinfo, isovfy, isodump \- Utility programs for dumping and verifying iso9660 +images. +.SH SYNOPSIS +.B devdump +.I isoimage +.PP +.B isodump +.I isoimage +.PP +.B isoinfo +[ +.B \-d +] +[ +.B \-h +] +[ +.B \-R +] +[ +.B \-J +] +[ +.B \-j +.I charset +] +[ +.B \-f +] +[ +.B \-l +] +[ +.B \-p +] +[ +.B \-T +.I sector +] +[ +.B \-N +.I sector +] +[ +.B \-i +.I isoimage +] +[ +.B \-x +.I path +] +.PP +.B isovfy +.I isoimage +.SH DESCRIPTION +.B devdump +is a crude utility to interactively display the contents of device or +filesystem images. +The initial screen is a display of the first 256 bytes of the first 2048 byte +sector. +The commands are the same as with +.BR isodump . +.PP +.B isodump +is a crude utility to interactively display the contents of iso9660 images +in order to verify directory integrity. +The initial screen is a display of the first part of the root directory, +and the prompt shows you the extent number and offset in the extent. +.RS +.PP +You can use the 'a' and 'b' +commands to move backwards and forwards within the image. The 'g' command +allows you to goto an arbitrary extent, and the 'f' command specifies +a search string to be used. The '+' command searches forward for the next +instance of the search string, and the 'q' command exits +.B devdump +or +.BR isodump . +.RE +.PP +.B isoinfo +is a utility to perform directory like listings of iso9660 images. +.PP +.B isovfy +is a utility to verify the integrity of an iso9660 image. Most of the tests +in +.B isovfy +were added after bugs were discovered in early versions of +.B genisoimage. +It isn't all that clear how useful this is anymore, but it doesn't hurt to +have this around. + +.SH OPTIONS +The options common to all programs are +.BR \-help , \-h , \-version , +.BI i =name, dev =name. +The +.B isoinfo +program has additional command line options. The options are: +.TP +.B \-help +.TP +.B \-h +print a summary of all options. +.TP +.B \-d +Print information from the primary volume descriptor (PVD) of the iso9660 +image. This includes information about Rock Ridge, Joliet extensions +and Eltorito boot information +if present. +.TP +.B \-f +generate output as if a 'find . -print' command had been run on the iso9660 +image. You should not use the +.B -l +image with the +.B -f +option. +.TP +.B \-i iso_image +Specifies the path of the iso9660 image that we wish to examine. +The options +.B \-i +and +.BI dev= target +are mutual exclusive. +.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, the program +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). +.sp +The options +.B \-i +and +.BI dev= target +are mutual exclusive. +.TP +.B \-l +generate output as if a 'ls -lR' command had been run on the iso9660 image. +You should not use the +.B -f +image with the +.B -l +option. +.TP +.B \-N sector +Quick hack to help examine single session disc files that are to be written to +a multi-session disc. The sector number specified is the sector number at +which the iso9660 image should be written when send to the cd-writer. Not +used for the first session on the disc. +.TP +.B \-p +Print path table information. +.TP +.B \-R +Extract information from Rock Ridge extensions (if present) for permissions, +file names and ownerships. +.TP +.B \-J +Extract information from Joliet extensions (if present) for file names. +.TP +.B \-j charset +Convert Joliet file names (if present) to the supplied charset. See +.BR genisoimage (8) +for details. +.TP +.B \-T sector +Quick hack to help examine multi-session images that have already been burned +to a multi-session disc. The sector number specified is the sector number for +the start of the session we wish to display. +.TP +.B \-x pathname +Extract specified file to stdout. +.SH AUTHOR +The author of the original sources (1993 .\|.\|. 1998) is +Eric Youngdale <ericy@gnu.ai.mit.edu> or <eric@andante.jic.com> is to blame +for these shoddy hacks. +J\*org Schilling wrote the SCSI transport library and its adaptation layer to +the programs and newer parts (starting from 1999) of the utilities, this makes +them +Copyright (C) 1999-2004 J\*org Schilling. +Patches to improve general usability would be gladly accepted. +.PP +This manpage describes the program implementation of +.B +isoinfo +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program distributed in the +cdrtools package [1]. However, the cdrtools +developers are not involved in the development of this spinoff and therefore +shall not be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original author(s). +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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 BUGS +The user interface really sucks. +.SH FUTURE IMPROVEMENTS +These utilities are really quick hacks, which are very useful for debugging +problems in genisoimage or in an iso9660 filesystem. In the long run, it would +be nice to have a daemon that would NFS export a iso9660 image. +.PP +The isoinfo program is probably the program that is of the most use to +the general user. +.SH AVAILABILITY +These utilities come with the +.B cdrkit +package, and the primary download site +is http://debburn.alioth.debian.org/ and FTP mirrors of distributions. +Despite the name, the software is not beta. + +.SH ENVIRONMENT +.TP +.B CDR_DEVICE +This may either hold a device identifier that is suitable to the open +call of the SCSI transport library or a label in the file /etc/wodim.conf. +.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 the program +to create a pipe to the +.B rsh(1) +program and disallows the program +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 FILES +.TP +/etc/wodim.conf +Default values can be set for the following options in /etc/wodim.conf. +.RS +.TP +CDR_DEVICE +This may either hold a device identifier that is suitable to the open +call of the SCSI transport library or a label in the file /etc/wodim.conf +that allows to identify a specific drive on the system. +.TP +Any other label +is an identifier for a specific drive on the system. +Such an identifier may not contain the characters ',', '/', '@' or ':'. +.sp +Each line that follows a label contains a TAB separated list of items. +Currently, four items are recognized: the SCSI ID of the drive, the +default speed that should be used for this drive, the default FIFO size +that should be used for this drive and drive specific options. The values for +.I speed +and +.I fifosize +may be set to -1 to tell the program to use the global defaults. +The value for driveropts may be set to "" if no driveropts are used. +A typical line may look this way: +.sp +teac1= 0,5,0 4 8m "" +.sp +yamaha= 1,6,0 -1 -1 burnfree +.sp +This tells the program +that a drive named +.I teac1 +is at scsibus 0, target 5, lun 0 and should be used with speed 4 and +a FIFO size of 8 MB. +A second drive may be found at scsibus 1, target 6, lun 0 and uses the +default speed and the default FIFO size. +.RE +.SH SEE ALSO +.BR genisoimage (1), +.BR wodim (1), +.BR readcd (1), +.BR ssh (1). +.RE +.SH SOURCES +.PP +.br +[1] Cdrtools 2.01.01a08 from May 2006, http://cdrecord.berlios.de + diff --git a/genisoimage/diag/isoinfo.c b/genisoimage/diag/isoinfo.c new file mode 100644 index 0000000..55396c2 --- /dev/null +++ b/genisoimage/diag/isoinfo.c @@ -0,0 +1,1321 @@ +/* + * 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. + * + */ + +/* @(#)isoinfo.c 1.50 05/05/15 joerg */ +/* + * File isodump.c - dump iso9660 directory information. + * + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999-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. + */ + +/* + * Simple program to dump contents of iso9660 image in more usable format. + * + * Usage: + * To list contents of image (with or without RR): + * isoinfo -l [-R] -i imagefile + * To extract file from image: + * isoinfo -i imagefile -x xtractfile > outfile + * To generate a "find" like list of files: + * isoinfo -f -i imagefile + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> + +#include <stdio.h> +#include <utypes.h> +#include <standard.h> +#include <signal.h> +#include <sys/stat.h> +#include <statdefs.h> +#include <fctldefs.h> +#include <schily.h> + +#include "../iso9660.h" +#include "../scsi.h" +#include "../../wodim/defaults.h" + +#include <unls.h> + +#if defined(__CYGWIN32__) || defined(__EMX__) || defined(__DJGPP__) +#include <io.h> /* for setmode() prototype */ +#endif + +/* + * Make sure we have a definition for this. If not, take a very conservative + * guess. + * POSIX requires the max pathname component lenght to be defined in limits.h + * If variable, it may be undefined. If undefined, there should be + * a definition for _POSIX_NAME_MAX in limits.h or in unistd.h + * As _POSIX_NAME_MAX is defined to 14, we cannot use it. + * XXX Eric's wrong comment: + * XXX From what I can tell SunOS is the only one with this trouble. + */ +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifndef NAME_MAX +#ifdef FILENAME_MAX +#define NAME_MAX FILENAME_MAX +#else +#define NAME_MAX 256 +#endif +#endif + +#ifndef PATH_MAX +#ifdef FILENAME_MAX +#define PATH_MAX FILENAME_MAX +#else +#define PATH_MAX 1024 +#endif +#endif + +/* + * XXX JS: Some structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See iso9660.h + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#ifndef S_ISLNK +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#endif +#ifndef S_ISSOCK +#ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +#else +# define S_ISSOCK(m) (0) +#endif +#endif + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define infile in_image +FILE *infile = NULL; +int use_rock = 0; +int use_joliet = 0; +int do_listing = 0; +int do_find = 0; +int do_sectors = 0; +int do_pathtab = 0; +int do_pvd = 0; +BOOL debug = FALSE; +char *xtract = 0; +int su_version = 0; +int aa_version = 0; +int ucs_level = 0; + +struct stat fstat_buf; +int found_rr; +char name_buf[256]; +char xname[2048]; +unsigned char date_buf[9]; +/* + * Use sector_offset != 0 (-N #) if we have an image file + * of a single session and we need to list the directory contents. + * This is the session block (sector) number of the start + * of the session when it would be on disk. + */ +unsigned int sector_offset = 0; + +unsigned char buffer[2048]; + +struct unls_table *unls; + +#define PAGE sizeof (buffer) + +#define ISODCL(from, to) (to - from + 1) + + +int isonum_721(char * p); +int isonum_723(char * p); +int isonum_731(char * p); +int isonum_732(char * p); +int isonum_733(unsigned char * p); +void printchars(char *s, int n); +char *sdate(char *dp); +void dump_pathtab(int block, int size); +int parse_rr(unsigned char * pnt, int len, int cont_flag); +void find_rr(struct iso_directory_record * idr, Uchar **pntp, int *lenp); +int dump_rr(struct iso_directory_record * idr); +void dump_stat(struct iso_directory_record * idr, int extent); +void extract_file(struct iso_directory_record * idr); +void parse_dir(char * rootname, int extent, int len); +void usage(int excode); + +static void printf_bootinfo(FILE *f, int bootcat_offset); +static char *arch_name(int val); +static char *boot_name(int val); +static char *bootmedia_name(int val); + + +int +isonum_721(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8)); +} + +int +isonum_723(char *p) +{ +#if 0 + if (p[0] != p[3] || p[1] != p[2]) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "invalid format 7.2.3 number\n"); +#else + fprintf(stderr, "invalid format 7.2.3 number\n"); + exit(1); +#endif + } +#endif + return (isonum_721(p)); +} + +int +isonum_731(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +int +isonum_732(char *p) +{ + return ((p[3] & 0xff) + | ((p[2] & 0xff) << 8) + | ((p[1] & 0xff) << 16) + | ((p[0] & 0xff) << 24)); +} + +int +isonum_733(unsigned char *p) +{ + return (isonum_731((char *)p)); +} + +void +printchars(char *s, int n) +{ + int i; + char *p; + + for (; n > 0 && *s; n--) { + if (*s == ' ') { + p = s; + i = n; + while (--i >= 0 && *p++ == ' ') + ; + if (i <= 0) + break; + } + putchar(*s++); + } +} + +/* + * Print date info from PVD + */ +char * +sdate(char *dp) +{ + static char d[30]; + + sprintf(d, "%4.4s %2.2s %2.2s %2.2s:%2.2s:%2.2s.%2.2s", + &dp[0], /* Year */ + &dp[4], /* Month */ + &dp[6], /* Monthday */ + &dp[8], /* Hour */ + &dp[10], /* Minute */ + &dp[12], /* Seconds */ + &dp[14]); /* Hunreds of a Seconds */ + + /* + * dp[16] contains minute offset from Greenwich + * Positive values are to the east of Greenwich. + */ + return (d); +} + +void +dump_pathtab(int block, int size) +{ + unsigned char *buf; + int offset; + int idx; + int extent; + int pindex; + int j; + int len; + int jlen; + char namebuf[255]; + unsigned char uh, ul, uc, *up; + + + printf("Path table starts at block %d, size %d\n", block, size); + + buf = (unsigned char *) malloc(ISO_ROUND_UP(size)); + +#ifdef USE_SCG + readsecs(block - sector_offset, buf, ISO_BLOCKS(size)); +#else + lseek(fileno(infile), ((off_t)(block - sector_offset)) << 11, SEEK_SET); + read(fileno(infile), buf, size); +#endif + + offset = 0; + idx = 1; + while (offset < size) { + len = buf[offset]; + extent = isonum_731((char *)buf + offset + 2); + pindex = isonum_721((char *)buf + offset + 6); + switch (ucs_level) { + case 3: + case 2: + case 1: + jlen = len/2; + namebuf[0] = '\0'; + for (j = 0; j < jlen; j++) { + uh = buf[offset + 8 + j*2]; + ul = buf[offset + 8 + j*2+1]; + + up = unls->unls_uni2cs[uh]; + + if (up == NULL) + uc = '\0'; + else + uc = up[ul]; + + namebuf[j] = uc ? uc : '_'; + } + printf("%4d: %4d %x %.*s\n", + idx, pindex, extent, jlen, namebuf); + break; + case 0: + printf("%4d: %4d %x %.*s\n", + idx, pindex, extent, len, buf + offset + 8); + } + + idx++; + offset += 8 + len; + if (offset & 1) + offset++; + } + + free(buf); +} + +int +parse_rr(unsigned char *pnt, int len, int cont_flag) +{ + int slen; + int xlen; + int ncount; + int extent; + int cont_extent, cont_offset, cont_size; + int flag1, flag2; + unsigned char *pnts; + char symlinkname[1024]; + int goof; + + symlinkname[0] = 0; + + cont_extent = cont_offset = cont_size = 0; + + ncount = 0; + flag1 = flag2 = 0; + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { + printf("**BAD RRVERSION (%d)\n", pnt[3]); + return (0); /* JS ??? Is this right ??? */ + } + ncount++; + if (pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff; + if (strncmp((char *)pnt, "PX", 2) == 0) flag2 |= 1; /* POSIX attributes */ + if (strncmp((char *)pnt, "PN", 2) == 0) flag2 |= 2; /* POSIX device number */ + if (strncmp((char *)pnt, "SL", 2) == 0) flag2 |= 4; /* Symlink */ + if (strncmp((char *)pnt, "NM", 2) == 0) flag2 |= 8; /* Alternate Name */ + if (strncmp((char *)pnt, "CL", 2) == 0) flag2 |= 16; /* Child link */ + if (strncmp((char *)pnt, "PL", 2) == 0) flag2 |= 32; /* Parent link */ + if (strncmp((char *)pnt, "RE", 2) == 0) flag2 |= 64; /* Relocated Direcotry */ + if (strncmp((char *)pnt, "TF", 2) == 0) flag2 |= 128; /* Time stamp */ + if (strncmp((char *)pnt, "SP", 2) == 0) { + flag2 |= 1024; /* SUSP record */ + su_version = pnt[3] & 0xff; + } + if (strncmp((char *)pnt, "AA", 2) == 0) { + flag2 |= 2048; /* Apple Signature record */ + aa_version = pnt[3] & 0xff; + } + + if (strncmp((char *)pnt, "PX", 2) == 0) { /* POSIX attributes */ + fstat_buf.st_mode = isonum_733(pnt+4); + fstat_buf.st_nlink = isonum_733(pnt+12); + fstat_buf.st_uid = isonum_733(pnt+20); + fstat_buf.st_gid = isonum_733(pnt+28); + } + + if (strncmp((char *)pnt, "NM", 2) == 0) { /* Alternate Name */ + int l = strlen(name_buf); + + if (!found_rr) + l = 0; + strncpy(&name_buf[l], (char *)(pnt+5), pnt[2] - 5); + name_buf[l + pnt[2] - 5] = 0; + found_rr = 1; + } + + if (strncmp((char *)pnt, "CE", 2) == 0) { /* Continuation Area */ + cont_extent = isonum_733(pnt+4); + cont_offset = isonum_733(pnt+12); + cont_size = isonum_733(pnt+20); + } + + if (strncmp((char *)pnt, "PL", 2) == 0 || strncmp((char *)pnt, "CL", 2) == 0) { + extent = isonum_733(pnt+4); + } + + if (strncmp((char *)pnt, "SL", 2) == 0) { /* Symlink */ + int cflag; + + cflag = pnt[4]; + pnts = pnt+5; + slen = pnt[2] - 5; + while (slen >= 1) { + switch (pnts[0] & 0xfe) { + case 0: + strncat(symlinkname, (char *)(pnts+2), pnts[1]); + symlinkname[pnts[1]] = 0; + break; + case 2: + strcat(symlinkname, "."); + break; + case 4: + strcat(symlinkname, ".."); + break; + case 8: + strcat(symlinkname, "/"); + break; + case 16: + strcat(symlinkname, "/mnt"); + printf("Warning - mount point requested"); + break; + case 32: + strcat(symlinkname, "kafka"); + printf("Warning - host_name requested"); + break; + default: + printf("Reserved bit setting in symlink"); + goof++; + break; + } + if ((pnts[0] & 0xfe) && pnts[1] != 0) { + printf("Incorrect length in symlink component"); + } + if (xname[0] == 0) strcpy(xname, "-> "); + strcat(xname, symlinkname); + symlinkname[0] = 0; + xlen = strlen(xname); + if ((pnts[0] & 1) == 0 && xname[xlen-1] != '/') strcat(xname, "/"); + + slen -= (pnts[1] + 2); + pnts += (pnts[1] + 2); + } + symlinkname[0] = 0; + } + + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + unsigned char sector[2048]; + +#ifdef USE_SCG + readsecs(cont_extent - sector_offset, sector, ISO_BLOCKS(sizeof (sector))); +#else + lseek(fileno(infile), ((off_t)(cont_extent - sector_offset)) << 11, SEEK_SET); + read(fileno(infile), sector, sizeof (sector)); +#endif + flag2 |= parse_rr(§or[cont_offset], cont_size, 1); + } + } + /* + * for symbolic links, strip out the last '/' + */ + if (xname[0] != 0 && xname[strlen(xname)-1] == '/') { + xname[strlen(xname)-1] = '\0'; + } + return (flag2); +} + +void +find_rr(struct iso_directory_record *idr, Uchar **pntp, int *lenp) +{ + struct iso_xa_dir_record *xadp; + int len; + unsigned char * pnt; + + len = idr->length[0] & 0xff; + len -= offsetof(struct iso_directory_record, name[0]); + len -= idr->name_len[0]; + + pnt = (unsigned char *) idr; + pnt += offsetof(struct iso_directory_record, name[0]); + pnt += idr->name_len[0]; + if ((idr->name_len[0] & 1) == 0) { + pnt++; + len--; + } + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + } + } + *pntp = pnt; + *lenp = len; +} + +int +dump_rr(struct iso_directory_record *idr) +{ + int len; + unsigned char * pnt; + + find_rr(idr, &pnt, &len); + return (parse_rr(pnt, len, 0)); +} + +struct todo +{ + struct todo *next; + char *name; + int extent; + int length; +}; + +struct todo *todo_idr = NULL; + +char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", + "Aug", "Sep", "Oct", "Nov", "Dec"}; + +void +dump_stat(struct iso_directory_record *idr, int extent) +{ + int i; + char outline[80]; + + memset(outline, ' ', sizeof (outline)); + + if (S_ISREG(fstat_buf.st_mode)) + outline[0] = '-'; + else if (S_ISDIR(fstat_buf.st_mode)) + outline[0] = 'd'; + else if (S_ISLNK(fstat_buf.st_mode)) + outline[0] = 'l'; + else if (S_ISCHR(fstat_buf.st_mode)) + outline[0] = 'c'; + else if (S_ISBLK(fstat_buf.st_mode)) + outline[0] = 'b'; + else if (S_ISFIFO(fstat_buf.st_mode)) + outline[0] = 'f'; + else if (S_ISSOCK(fstat_buf.st_mode)) + outline[0] = 's'; + else + outline[0] = '?'; + + memset(outline+1, '-', 9); + if (fstat_buf.st_mode & S_IRUSR) + outline[1] = 'r'; + if (fstat_buf.st_mode & S_IWUSR) + outline[2] = 'w'; + if (fstat_buf.st_mode & S_IXUSR) + outline[3] = 'x'; + + if (fstat_buf.st_mode & S_IRGRP) + outline[4] = 'r'; + if (fstat_buf.st_mode & S_IWGRP) + outline[5] = 'w'; + if (fstat_buf.st_mode & S_IXGRP) + outline[6] = 'x'; + + if (fstat_buf.st_mode & S_IROTH) + outline[7] = 'r'; + if (fstat_buf.st_mode & S_IWOTH) + outline[8] = 'w'; + if (fstat_buf.st_mode & S_IXOTH) + outline[9] = 'x'; + + /* + * XXX This is totally ugly code from Eric. + * XXX If one field is wider than expected then it is truncated. + */ + sprintf(outline+11, "%3ld", (long)fstat_buf.st_nlink); + sprintf(outline+15, "%4lo", (unsigned long)fstat_buf.st_uid); + sprintf(outline+20, "%4lo", (unsigned long)fstat_buf.st_gid); + sprintf(outline+30, "%10lld", (Llong)fstat_buf.st_size); + + if (do_sectors == 0) { + sprintf(outline+30, "%10lld", (Llong)fstat_buf.st_size); + } else { + sprintf(outline+30, "%10lld", (Llong)((fstat_buf.st_size+PAGE-1)/PAGE)); + } + + if (date_buf[1] >= 1 && date_buf[1] <= 12) { + memcpy(outline+41, months[date_buf[1]-1], 3); + } + + sprintf(outline+45, "%2d", date_buf[2]); + outline[63] = 0; + sprintf(outline+48, "%4d", date_buf[0]+1900); + + sprintf(outline+53, "[%7d", extent); /* XXX up to 20 GB */ + sprintf(outline+61, " %02X]", idr->flags[0]); + + for (i = 0; i < 66; i++) { + if (outline[i] == 0) outline[i] = ' '; + } + outline[66] = 0; + printf("%s %s %s\n", outline, name_buf, xname); +} + +void +extract_file(struct iso_directory_record *idr) +{ + int extent, len, tlen; + unsigned char buff[2048]; + +#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__EMX__) || defined(__DJGPP__) + setmode(fileno(stdout), O_BINARY); +#endif + + extent = isonum_733((unsigned char *)idr->extent); + len = isonum_733((unsigned char *)idr->size); + + while (len > 0) { +#ifdef USE_SCG + readsecs(extent - sector_offset, buff, ISO_BLOCKS(sizeof (buff))); + tlen = (len > sizeof (buff) ? sizeof (buff) : len); +#else + lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET); + tlen = (len > sizeof (buff) ? sizeof (buff) : len); + read(fileno(infile), buff, tlen); +#endif + len -= tlen; + extent++; + write(STDOUT_FILENO, buff, tlen); /* FIXME: check return value */ + } +} + +void +parse_dir(char *rootname, int extent, int len) +{ + char testname[PATH_MAX+1]; + struct todo *td; + int i; + struct iso_directory_record * idr; + unsigned char uh, ul, uc, *up; + + + if (do_listing) + printf("\nDirectory listing of %s\n", rootname); + + while (len > 0) { +#ifdef USE_SCG + readsecs(extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer))); +#else + lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET); + read(fileno(infile), buffer, sizeof (buffer)); +#endif + len -= sizeof (buffer); + extent++; + i = 0; + while (1 == 1) { + idr = (struct iso_directory_record *) &buffer[i]; + if (idr->length[0] == 0) break; + memset(&fstat_buf, 0, sizeof (fstat_buf)); + found_rr = 0; + name_buf[0] = xname[0] = 0; + fstat_buf.st_size = (off_t)(unsigned)isonum_733((unsigned char *)idr->size); + if (idr->flags[0] & 2) + fstat_buf.st_mode |= S_IFDIR; + else + fstat_buf.st_mode |= S_IFREG; + if (idr->name_len[0] == 1 && idr->name[0] == 0) + strcpy(name_buf, "."); + else if (idr->name_len[0] == 1 && idr->name[0] == 1) + strcpy(name_buf, ".."); + else { + switch (ucs_level) { + case 3: + case 2: + case 1: + /* + * Unicode name. Convert as best we can. + */ + { + int j; + + name_buf[0] = '\0'; + for (j = 0; j < (int)idr->name_len[0] / 2; j++) { + uh = idr->name[j*2]; + ul = idr->name[j*2+1]; + + up = unls->unls_uni2cs[uh]; + + if (up == NULL) + uc = '\0'; + else + uc = up[ul]; + + name_buf[j] = uc ? uc : '_'; + } + name_buf[idr->name_len[0]/2] = '\0'; + } + break; + case 0: + /* + * Normal non-Unicode name. + */ + strncpy(name_buf, idr->name, idr->name_len[0]); + name_buf[idr->name_len[0]] = 0; + break; + default: + /* + * Don't know how to do these yet. Maybe they are the same + * as one of the above. + */ + exit(1); + } + } + memcpy(date_buf, idr->date, 9); + if (use_rock) + dump_rr(idr); + if ((idr->flags[0] & 2) != 0 && + (idr->name_len[0] != 1 || + (idr->name[0] != 0 && idr->name[0] != 1))) { + /* + * Add this directory to the todo list. + */ + td = todo_idr; + if (td != NULL) { + while (td->next != NULL) + td = td->next; + td->next = (struct todo *) malloc(sizeof (*td)); + td = td->next; + } else { + todo_idr = td = (struct todo *) malloc(sizeof (*td)); + } + td->next = NULL; + td->extent = isonum_733((unsigned char *)idr->extent); + td->length = isonum_733((unsigned char *)idr->size); + td->name = (char *) malloc(strlen(rootname) + + strlen(name_buf) + 2); + strcpy(td->name, rootname); + strcat(td->name, name_buf); + strcat(td->name, "/"); + } else { + strcpy(testname, rootname); + strcat(testname, name_buf); + if (xtract && strcmp(xtract, testname) == 0) { + extract_file(idr); + } + } + if (do_find && + (idr->name_len[0] != 1 || + (idr->name[0] != 0 && idr->name[0] != 1))) { + strcpy(testname, rootname); + strcat(testname, name_buf); + printf("%s\n", testname); + } + if (do_listing) + dump_stat(idr, isonum_733((unsigned char *)idr->extent)); + i += buffer[i]; + if (i > 2048 - offsetof(struct iso_directory_record, name[0])) break; + } + } +} + +void +usage(int excode) +{ + errmsgno(EX_BAD, "Usage: %s [options] -i filename\n", get_progname()); + + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t-help,-h Print this help\n"); + fprintf(stderr, "\t-version Print version info and exit\n"); + fprintf(stderr, "\t-debug Print additional debug info\n"); + fprintf(stderr, "\t-d Print information from the primary volume descriptor\n"); + fprintf(stderr, "\t-f Generate output similar to 'find . -print'\n"); + fprintf(stderr, "\t-J Print information from Joliet extensions\n"); + fprintf(stderr, "\t-j charset Use charset to display Joliet file names\n"); + fprintf(stderr, "\t-l Generate output similar to 'ls -lR'\n"); + fprintf(stderr, "\t-p Print Path Table\n"); + fprintf(stderr, "\t-R Print information from Rock Ridge extensions\n"); + fprintf(stderr, "\t-s Print file size infos in multiples of sector size (%ld bytes).\n", (long)PAGE); + fprintf(stderr, "\t-N sector Sector number where ISO image should start on CD\n"); + fprintf(stderr, "\t-T sector Sector number where actual session starts on CD\n"); + fprintf(stderr, "\t-i filename Filename to read ISO-9660 image from\n"); + fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n"); + fprintf(stderr, "\t-x pathname Extract specified file to stdout\n"); + exit(excode); +} + +int +main(int argc, char *argv[]) +{ + int cac; + char * const *cav; + int c; + char * filename = NULL; + char * devname = NULL; + /* + * Use toc_offset != 0 (-T #) if we have a complete multi-session + * disc that we want/need to play with. + * Here we specify the offset where we want to + * start searching for the TOC. + */ + int toc_offset = 0; + int extent; + struct todo * td; + struct iso_primary_descriptor ipd; + struct iso_primary_descriptor jpd; + struct eltorito_boot_descriptor bpd; + struct iso_directory_record * idr; + char *charset = NULL; + char *opts = "help,h,version,debug,d,p,i*,dev*,J,R,l,x*,f,s,N#l,T#l,j*"; + BOOL help = FALSE; + BOOL prvers = FALSE; + BOOL found_eltorito = FALSE; + int bootcat_offset = 0; + + + save_args(argc, argv); + + cac = argc - 1; + cav = argv + 1; + if (getallargs(&cac, &cav, opts, + &help, &help, &prvers, &debug, + &do_pvd, &do_pathtab, + &filename, &devname, + &use_joliet, &use_rock, + &do_listing, + &xtract, + &do_find, &do_sectors, + §or_offset, &toc_offset, + &charset) < 0) { + errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (help) + usage(0); + if (prvers) { + printf("isoinfo %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM); + exit(0); + } + cac = argc - 1; + cav = argv + 1; + if (getfiles(&cac, &cav, opts) != 0) { + errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]); + usage(EX_BAD); + } + + init_unls(); /* Initialize UNICODE tables */ + init_unls_file(charset); + if (charset == NULL) { +#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__)) && !defined(IS_CYGWIN_1) + unls = load_unls("cp437"); +#else + unls = load_unls("iso8859-1"); +#endif + } else { + if (strcmp(charset, "default") == 0) + unls = load_unls_default(); + else + unls = load_unls(charset); + } + if (unls == NULL) { /* Unknown charset specified */ + fprintf(stderr, "Unknown charset: %s\nKnown charsets are:\n", + charset); + list_unls(); /* List all known charset names */ + exit(1); + } + + if (filename != NULL && devname != NULL) { + errmsgno(EX_BAD, "Only one of -i or dev= allowed\n"); + usage(EX_BAD); + } +#ifdef USE_SCG + if (filename == NULL && devname == NULL) + cdr_defaults(&devname, NULL, NULL, NULL); +#endif + if (filename == NULL && devname == NULL) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "ISO-9660 image not specified\n"); +#else + fprintf(stderr, "ISO-9660 image not specified\n"); +#endif + usage(EX_BAD); + } + + if (filename != NULL) + infile = fopen(filename, "rb"); + else + filename = devname; + + if (infile != NULL) { + /* EMPTY */; +#ifdef USE_SCG + } else if (scsidev_open(filename) < 0) { +#else + } else { +#endif +#ifdef USE_LIBSCHILY + comerr("Unable to open %s\n", filename); +#else + fprintf(stderr, "Unable to open %s\n", filename); + exit(1); +#endif + } + + /* + * Absolute sector offset, so don't subtract sector_offset here. + */ +#ifdef USE_SCG + readsecs(16 + toc_offset, &ipd, ISO_BLOCKS(sizeof (ipd))); +#else + lseek(fileno(infile), ((off_t)(16 + toc_offset)) <<11, SEEK_SET); + read(fileno(infile), &ipd, sizeof (ipd)); +#endif + idr = (struct iso_directory_record *)ipd.root_directory_record; + if (do_pvd) { + /* + * High sierra: + * + * DESC TYPE == 1 (VD_SFS) offset 8 len 1 + * STR ID == "CDROM" offset 9 len 5 + * STD_VER == 1 offset 14 len 1 + */ + if ((((char *)&ipd)[8] == 1) && + (strncmp(&((char *)&ipd)[9], "CDROM", 5) == 0) && + (((char *)&ipd)[14] == 1)) { + printf("CD-ROM is in High Sierra format\n"); + exit(0); + } + /* + * ISO 9660: + * + * DESC TYPE == 1 (VD_PVD) offset 0 len 1 + * STR ID == "CD001" offset 1 len 5 + * STD_VER == 1 offset 6 len 1 + */ + if ((ipd.type[0] != ISO_VD_PRIMARY) || + (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) || + (ipd.version[0] != 1)) { + printf("CD-ROM is NOT in ISO 9660 format\n"); + exit(1); + } + + printf("CD-ROM is in ISO 9660 format\n"); + printf("System id: "); + printchars(ipd.system_id, 32); + putchar('\n'); + printf("Volume id: "); + printchars(ipd.volume_id, 32); + putchar('\n'); + + printf("Volume set id: "); + printchars(ipd.volume_set_id, 128); + putchar('\n'); + printf("Publisher id: "); + printchars(ipd.publisher_id, 128); + putchar('\n'); + printf("Data preparer id: "); + printchars(ipd.preparer_id, 128); + putchar('\n'); + printf("Application id: "); + printchars(ipd.application_id, 128); + putchar('\n'); + + printf("Copyright File id: "); + printchars(ipd.copyright_file_id, 37); + putchar('\n'); + printf("Abstract File id: "); + printchars(ipd.abstract_file_id, 37); + putchar('\n'); + printf("Bibliographic File id: "); + printchars(ipd.bibliographic_file_id, 37); + putchar('\n'); + + printf("Volume set size is: %d\n", isonum_723(ipd.volume_set_size)); + printf("Volume set sequence number is: %d\n", isonum_723(ipd.volume_sequence_number)); + printf("Logical block size is: %d\n", isonum_723(ipd.logical_block_size)); + printf("Volume size is: %d\n", isonum_733((unsigned char *)ipd.volume_space_size)); + if (debug) { + int dextent; + int dlen; + + dextent = isonum_733((unsigned char *)idr->extent); + dlen = isonum_733((unsigned char *)idr->size); + printf("Root directory extent: %d size: %d\n", + dextent, dlen); + printf("Path table size is: %d\n", + isonum_733((unsigned char *)ipd.path_table_size)); + printf("L Path table start: %d\n", + isonum_731(ipd.type_l_path_table)); + printf("L Path opt table start: %d\n", + isonum_731(ipd.opt_type_l_path_table)); + printf("M Path table start: %d\n", + isonum_732(ipd.type_m_path_table)); + printf("M Path opt table start: %d\n", + isonum_732(ipd.opt_type_m_path_table)); + printf("Creation Date: %s\n", + sdate(ipd.creation_date)); + printf("Modification Date: %s\n", + sdate(ipd.modification_date)); + printf("Expiration Date: %s\n", + sdate(ipd.expiration_date)); + printf("Effective Date: %s\n", + sdate(ipd.effective_date)); + printf("File structure version: %d\n", + ipd.file_structure_version[0]); + } + { + int block = 16; + movebytes(&ipd, &jpd, sizeof (ipd)); + while ((Uchar)jpd.type[0] != ISO_VD_END) { + + if (debug && (Uchar) jpd.type[0] == ISO_VD_SUPPLEMENTARY) + fprintf(stderr, "Joliet escape sequence 0: '%c' 1: '%c' 2: '%c' 3: '%c'\n", + jpd.escape_sequences[0], + jpd.escape_sequences[1], + jpd.escape_sequences[2], + jpd.escape_sequences[3]); + /* + * If Joliet UCS escape sequence found, we may be wrong + */ + if (jpd.escape_sequences[0] == '%' && + jpd.escape_sequences[1] == '/' && + (jpd.escape_sequences[3] == '\0' || + jpd.escape_sequences[3] == ' ') && + (jpd.escape_sequences[2] == '@' || + jpd.escape_sequences[2] == 'C' || + jpd.escape_sequences[2] == 'E')) { + + if (jpd.version[0] == 1) + goto nextblock; + } + if (jpd.type[0] == 0) { + movebytes(&jpd, &bpd, sizeof (bpd)); + if (strncmp(bpd.system_id, EL_TORITO_ID, sizeof (EL_TORITO_ID)) == 0) { + bootcat_offset = (Uchar)bpd.bootcat_ptr[0] + + (Uchar)bpd.bootcat_ptr[1] * 256 + + (Uchar)bpd.bootcat_ptr[2] * 65536 + + (Uchar)bpd.bootcat_ptr[3] * 16777216; + found_eltorito = TRUE; + printf("El Torito VD version %d found, boot catalog is in sector %d\n", + bpd.version[0], + bootcat_offset); + } + } + if (jpd.version[0] == 2) { + printf("CD-ROM uses ISO 9660:1999 relaxed format\n"); + break; + } + + nextblock: + block++; +#ifdef USE_SCG + readsecs(block + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd))); +#else + lseek(fileno(infile), ((off_t)(block + toc_offset)) <<11, SEEK_SET); + read(fileno(infile), &jpd, sizeof (jpd)); +#endif + } + } + } + /* + * ISO 9660: + * + * DESC TYPE == 1 (VD_PVD) offset 0 len 1 + * STR ID == "CD001" offset 1 len 5 + * STD_VER == 1 offset 6 len 1 + */ + if ((ipd.type[0] != ISO_VD_PRIMARY) || + (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) || + (ipd.version[0] != 1)) { + printf("CD-ROM is NOT in ISO 9660 format\n"); + exit(1); + } + + if (use_joliet || do_pvd) { + int block = 16; + movebytes(&ipd, &jpd, sizeof (ipd)); + while ((unsigned char) jpd.type[0] != ISO_VD_END) { + if (debug && (unsigned char) jpd.type[0] == ISO_VD_SUPPLEMENTARY) + fprintf(stderr, "Joliet escape sequence 0: '%c' 1: '%c' 2: '%c' 3: '%c'\n", + jpd.escape_sequences[0], + jpd.escape_sequences[1], + jpd.escape_sequences[2], + jpd.escape_sequences[3]); + /* + * Find the UCS escape sequence. + */ + if (jpd.escape_sequences[0] == '%' && + jpd.escape_sequences[1] == '/' && + (jpd.escape_sequences[3] == '\0' || + jpd.escape_sequences[3] == ' ') && + (jpd.escape_sequences[2] == '@' || + jpd.escape_sequences[2] == 'C' || + jpd.escape_sequences[2] == 'E')) { + break; + } + + block++; +#ifdef USE_SCG + readsecs(block + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd))); +#else + lseek(fileno(infile), + ((off_t)(block + toc_offset)) <<11, SEEK_SET); + read(fileno(infile), &jpd, sizeof (jpd)); +#endif + } + + if (use_joliet && ((unsigned char) jpd.type[0] == ISO_VD_END)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Unable to find Joliet SVD\n"); +#else + fprintf(stderr, "Unable to find Joliet SVD\n"); + exit(1); +#endif + } + + switch (jpd.escape_sequences[2]) { + case '@': + ucs_level = 1; + break; + case 'C': + ucs_level = 2; + break; + case 'E': + ucs_level = 3; + break; + } + + if (ucs_level > 3) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Don't know what ucs_level == %d means\n", + ucs_level); +#else + fprintf(stderr, + "Don't know what ucs_level == %d means\n", + ucs_level); + exit(1); +#endif + } + if (jpd.escape_sequences[3] == ' ') + errmsgno(EX_BAD, + "Warning: Joliet escape sequence uses illegal space at offset 3\n"); + } + + if (do_pvd) { + if (ucs_level > 0) + printf("Joliet with UCS level %d found\n", ucs_level); + else + printf("NO Joliet present\n"); + + extent = isonum_733((unsigned char *)idr->extent); + +#ifdef USE_SCG + readsecs(extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer))); +#else + lseek(fileno(infile), + ((off_t)(extent - sector_offset)) <<11, SEEK_SET); + read(fileno(infile), buffer, sizeof (buffer)); +#endif + idr = (struct iso_directory_record *) buffer; + if ((c = dump_rr(idr)) != 0) { +/* printf("RR %X %d\n", c, c);*/ + if (c & 1024) { + printf( + "Rock Ridge signatures version %d found\n", + su_version); + } else { + printf( + "Bad Rock Ridge signatures found (SU record missing)\n"); + } + /* + * This is currently a no op! + * We need to check the first plain file instead of + * the '.' entry in the root directory. + */ + if (c & 2048) { + printf("Apple signatures version %d found\n", + aa_version); + } + } else { + printf("NO Rock Ridge present\n"); + } + if (found_eltorito) + printf_bootinfo(infile, bootcat_offset); + exit(0); + } + + if (use_joliet) + idr = (struct iso_directory_record *)jpd.root_directory_record; + + if (do_pathtab) { + if (use_joliet) { + dump_pathtab(isonum_731(jpd.type_l_path_table), + isonum_733((unsigned char *)jpd.path_table_size)); + } else { + dump_pathtab(isonum_731(ipd.type_l_path_table), + isonum_733((unsigned char *)ipd.path_table_size)); + } + } + + parse_dir("/", isonum_733((unsigned char *)idr->extent), + isonum_733((unsigned char *)idr->size)); + td = todo_idr; + while (td) { + parse_dir(td->name, td->extent, td->length); + td = td->next; + } + + if (infile != NULL) + fclose(infile); + return (0); +} + +#include <intcvt.h> + +static void +printf_bootinfo(FILE *f, int bootcat_offset) +{ + struct eltorito_validation_entry *evp; + struct eltorito_defaultboot_entry *ebe; + +#ifdef USE_SCG + readsecs(bootcat_offset, buffer, ISO_BLOCKS(sizeof (buffer))); +#else + lseek(fileno(f), ((off_t)bootcat_offset) <<11, SEEK_SET); + read(fileno(f), buffer, sizeof (buffer)); +#endif + + evp = (struct eltorito_validation_entry *)buffer; + ebe = (struct eltorito_defaultboot_entry *)&buffer[32]; + + printf("Eltorito validation header:\n"); + printf(" Hid %d\n", (Uchar)evp->headerid[0]); + printf(" Arch %d (%s)\n", (Uchar)evp->arch[0], arch_name((Uchar)evp->arch[0])); + printf(" ID '%.23s'\n", evp->id); + printf(" Key %X %X\n", (Uchar)evp->key1[0], (Uchar)evp->key2[0]); + + printf(" Eltorito defaultboot header:\n"); + printf(" Bootid %X (%s)\n", (Uchar)ebe->boot_id[0], boot_name((Uchar)ebe->boot_id[0])); + printf(" Boot media %X (%s)\n", (Uchar)ebe->boot_media[0], bootmedia_name((Uchar)ebe->boot_media[0])); + printf(" Load segment %X\n", la_to_2_byte(ebe->loadseg)); + printf(" Sys type %X\n", (Uchar)ebe->sys_type[0]); + printf(" Nsect %X\n", la_to_2_byte(ebe->nsect)); + printf(" Bootoff %lX %ld\n", la_to_4_byte(ebe->bootoff), la_to_4_byte(ebe->bootoff)); + +} + +static char * +arch_name(int val) +{ + switch (val) { + + case EL_TORITO_ARCH_x86: + return ("x86"); + case EL_TORITO_ARCH_PPC: + return ("PPC"); + case EL_TORITO_ARCH_MAC: + return ("MAC"); + default: + return ("Unknown Arch"); + } +} + +static char * +boot_name(int val) +{ + switch (val) { + + case EL_TORITO_BOOTABLE: + return ("bootable"); + case EL_TORITO_NOT_BOOTABLE: + return ("not bootable"); + default: + return ("Illegal"); + } +} + +static char * +bootmedia_name(int val) +{ + switch (val) { + + case EL_TORITO_MEDIA_NOEMUL: + return ("No Emulation Boot"); + case EL_TORITO_MEDIA_12FLOP: + return ("1200 Floppy"); + case EL_TORITO_MEDIA_144FLOP: + return ("1.44MB Floppy"); + case EL_TORITO_MEDIA_288FLOP: + return ("2.88MB Floppy"); + case EL_TORITO_MEDIA_HD: + return ("Hard Disk Emulation"); + default: + return ("Illegal Bootmedia"); + } +} diff --git a/genisoimage/diag/isovfy.1 b/genisoimage/diag/isovfy.1 new file mode 100644 index 0000000..b170c59 --- /dev/null +++ b/genisoimage/diag/isovfy.1 @@ -0,0 +1,2 @@ +.so man1/isoinfo.1 +.\" %Z%%M% %I% %E% joerg diff --git a/genisoimage/diag/isovfy.c b/genisoimage/diag/isovfy.c new file mode 100644 index 0000000..18ed340 --- /dev/null +++ b/genisoimage/diag/isovfy.c @@ -0,0 +1,794 @@ +/* + * 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. + * + */ + +/* @(#)isovfy.c 1.26 05/05/15 joerg */ +/* + * File isovfy.c - verify consistency of iso9660 filesystem. + * + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999-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 <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <utypes.h> + +#include <stdio.h> +#include <standard.h> +#include <signal.h> +#include <schily.h> + +#include "../scsi.h" +#include "../../wodim/defaults.h" + +/* + * XXX JS: Some structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See iso9660.h + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define infile in_image +FILE *infile = NULL; +int blocksize; + +#define PAGE sizeof (buffer) + +#define ISODCL(from, to) (to - from + 1) + +struct iso_primary_descriptor { + unsigned char type [ISODCL(1, 1)]; /* 711 */ + unsigned char id [ISODCL(2, 6)]; + unsigned char version [ISODCL(7, 7)]; /* 711 */ + unsigned char unused1 [ISODCL(8, 8)]; + unsigned char system_id [ISODCL(9, 40)]; /* aunsigned chars */ + unsigned char volume_id [ISODCL(41, 72)]; /* dunsigned chars */ + unsigned char unused2 [ISODCL(73, 80)]; + unsigned char volume_space_size [ISODCL(81, 88)]; /* 733 */ + unsigned char unused3 [ISODCL(89, 120)]; + unsigned char volume_set_size [ISODCL(121, 124)]; /* 723 */ + unsigned char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + unsigned char logical_block_size [ISODCL(129, 132)]; /* 723 */ + unsigned char path_table_size [ISODCL(133, 140)]; /* 733 */ + unsigned char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + unsigned char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + unsigned char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + unsigned char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + unsigned char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + unsigned char volume_set_id [ISODCL(191, 318)]; /* dunsigned chars */ + unsigned char publisher_id [ISODCL(319, 446)]; /* achars */ + unsigned char preparer_id [ISODCL(447, 574)]; /* achars */ + unsigned char application_id [ISODCL(575, 702)]; /* achars */ + unsigned char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + unsigned char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + unsigned char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + unsigned char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + unsigned char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + unsigned char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + unsigned char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + unsigned char file_structure_version [ISODCL(882, 882)]; /* 711 */ + unsigned char unused4 [ISODCL(883, 883)]; + unsigned char application_data [ISODCL(884, 1395)]; + unsigned char unused5 [ISODCL(1396, 2048)]; +}; + +struct iso_directory_record { + unsigned char length [ISODCL(1, 1)]; /* 711 */ + unsigned char ext_attr_length [ISODCL(2, 2)]; /* 711 */ + unsigned char extent [ISODCL(3, 10)]; /* 733 */ + unsigned char size [ISODCL(11, 18)]; /* 733 */ + unsigned char date [ISODCL(19, 25)]; /* 7 by 711 */ + unsigned char flags [ISODCL(26, 26)]; + unsigned char file_unit_size [ISODCL(27, 27)]; /* 711 */ + unsigned char interleave [ISODCL(28, 28)]; /* 711 */ + unsigned char volume_sequence_number [ISODCL(29, 32)]; /* 723 */ + unsigned char name_len [ISODCL(33, 33)]; /* 711 */ + unsigned char name [38]; +}; + +static int isonum_721(char * p); +static int isonum_723(char * p); +static int isonum_711(char * p); +static int isonum_731(char * p); +static int isonum_722(char * p); +static int isonum_732(char * p); +static int isonum_733(unsigned char * p); +static int parse_rr(unsigned char * pnt, int len, int cont_flag); +static int dump_rr(struct iso_directory_record * idr); +static void check_tree(off_t file_addr, int file_size, off_t parent_addr); +static void check_path_tables(int typel_extent, int typem_extent, + int path_table_size); +static void usage(int excode); + +static int +isonum_721(char *p) +{ + return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); +} + +static int +isonum_723(char *p) +{ +#if 0 + if (p[0] != p[3] || p[1] != p[2]) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "invalid format 7.2.3 number\n"); +#else + fprintf(stderr, "invalid format 7.2.3 number\n"); + exit(1); +#endif + } +#endif + return (isonum_721(p)); +} + +static int +isonum_711(char *p) +{ + return (*p & 0xff); +} + +static int +isonum_731(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +static int +isonum_722(char *p) +{ + return ((p[1] & 0xff) + | ((p[0] & 0xff) << 8)); +} + +static int +isonum_732(char *p) +{ + return ((p[3] & 0xff) + | ((p[2] & 0xff) << 8) + | ((p[1] & 0xff) << 16) + | ((p[0] & 0xff) << 24)); +} + +static int +isonum_733(unsigned char *p) +{ + return (isonum_731((char *)p)); +} + +char lbuffer[1024]; +int iline; +int rr_goof; + + +static int +parse_rr(unsigned char *pnt, int len, int cont_flag) +{ + int slen; + int ncount; + int flag1; + int flag2; + int extent; + unsigned char *pnts; + off_t cont_extent; + int cont_offset; + int cont_size; + char symlinkname[1024]; + + sprintf(lbuffer+iline, " RRlen=%d ", len); + iline += strlen(lbuffer+iline); + + cont_extent = (off_t)0; + cont_offset = cont_size = 0; + + symlinkname[0] = 0; + + ncount = 0; + flag1 = flag2 = 0; + while (len >= 4) { + if (ncount) + sprintf(lbuffer+iline, ","); + else + sprintf(lbuffer+iline, "["); + iline += strlen(lbuffer + iline); + sprintf(lbuffer+iline, "%c%c", pnt[0], pnt[1]); + iline += strlen(lbuffer + iline); + if (pnt[0] < 'A' || pnt[0] > 'Z' || pnt[1] < 'A' || + pnt[1] > 'Z') { + sprintf(lbuffer+iline, "**BAD SUSP %d %d]", + pnt[0], pnt[1]); + rr_goof++; + iline += strlen(lbuffer + iline); + return (flag2); + } + + if (pnt[3] != 1 && pnt[3] != 2) { + sprintf(lbuffer+iline, "**BAD RRVERSION (%d)\n", pnt[3]); + rr_goof++; + iline += strlen(lbuffer + iline); + return (flag2); + } + ncount++; + if (pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff; + if (strncmp((char *)pnt, "PX", 2) == 0) flag2 |= 1; + if (strncmp((char *)pnt, "PN", 2) == 0) flag2 |= 2; + if (strncmp((char *)pnt, "SL", 2) == 0) flag2 |= 4; + if (strncmp((char *)pnt, "NM", 2) == 0) flag2 |= 8; + if (strncmp((char *)pnt, "CL", 2) == 0) flag2 |= 16; + if (strncmp((char *)pnt, "PL", 2) == 0) flag2 |= 32; + if (strncmp((char *)pnt, "RE", 2) == 0) flag2 |= 64; + if (strncmp((char *)pnt, "TF", 2) == 0) flag2 |= 128; + + if (strncmp((char *)pnt, "CE", 2) == 0) { + cont_extent = (off_t)isonum_733(pnt+4); + cont_offset = isonum_733(pnt+12); + cont_size = isonum_733(pnt+20); + sprintf(lbuffer+iline, "=[%x,%x,%d]", + (int)cont_extent, cont_offset, cont_size); + iline += strlen(lbuffer + iline); + } + + if (strncmp((char *)pnt, "PL", 2) == 0 || strncmp((char *)pnt, "CL", 2) == 0) { + extent = isonum_733(pnt+4); + sprintf(lbuffer+iline, "=%x", extent); + iline += strlen(lbuffer + iline); + if (extent == 0) + rr_goof++; + } + if (strncmp((char *)pnt, "SL", 2) == 0) { + pnts = pnt+5; + slen = pnt[2] - 5; + while (slen >= 1) { + switch (pnts[0] & 0xfe) { + case 0: + strncat(symlinkname, (char *)(pnts+2), pnts[1]); + break; + case 2: + strcat(symlinkname, "."); + break; + case 4: + strcat(symlinkname, ".."); + break; + case 8: + strcat(symlinkname, "/"); + break; + case 16: + strcat(symlinkname, "/mnt"); + sprintf(lbuffer+iline, "Warning - mount point requested"); + iline += strlen(lbuffer + iline); + break; + case 32: + strcat(symlinkname, "kafka"); + sprintf(lbuffer+iline, "Warning - host_name requested"); + iline += strlen(lbuffer + iline); + break; + default: + sprintf(lbuffer+iline, "Reserved bit setting in symlink"); + rr_goof++; + iline += strlen(lbuffer + iline); + break; + } + if ((pnts[0] & 0xfe) && pnts[1] != 0) { + sprintf(lbuffer+iline, "Incorrect length in symlink component"); + iline += strlen(lbuffer + iline); + } + if ((pnts[0] & 1) == 0) + strcat(symlinkname, "/"); + slen -= (pnts[1] + 2); + pnts += (pnts[1] + 2); + } + if (symlinkname[0] != 0) { + sprintf(lbuffer+iline, "=%s", symlinkname); + iline += strlen(lbuffer + iline); + symlinkname[0] = 0; + } + } + + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + unsigned char sector[2048]; +#ifdef USE_SCG + readsecs(cont_extent * blocksize / 2048, sector, ISO_BLOCKS(sizeof (sector))); +#else + lseek(fileno(infile), cont_extent * blocksize, SEEK_SET); + read(fileno(infile), sector, sizeof (sector)); +#endif + flag2 |= parse_rr(§or[cont_offset], cont_size, 1); + } + } + if (ncount) { + sprintf(lbuffer+iline, "]"); + iline += strlen(lbuffer + iline); + } + if (!cont_flag && flag1 && flag1 != flag2) { + sprintf(lbuffer+iline, "Flag %x != %x", flag1, flag2); + rr_goof++; + iline += strlen(lbuffer + iline); + } + return (flag2); +} + +static int +dump_rr(struct iso_directory_record *idr) +{ + int len; + char * pnt; + + len = idr->length[0] & 0xff; + len -= offsetof(struct iso_directory_record, name[0]); + len -= idr->name_len[0]; + pnt = (char *) idr; + pnt += offsetof(struct iso_directory_record, name[0]); + pnt += idr->name_len[0]; + + if ((idr->name_len[0] & 1) == 0) { + pnt++; + len--; + } + + rr_goof = 0; + parse_rr((unsigned char *)pnt, len, 0); + return (rr_goof); +} + + +static int dir_count = 0; +static int dir_size_count = 0; +static int ngoof = 0; + +static void +check_tree(off_t file_addr, int file_size, off_t parent_addr) +{ + unsigned char buffer[2048]; + unsigned int k; + int rflag = 0; + int i; + int i1; + int j; + int goof; + int extent; + int size; + off_t orig_file_addr; + off_t parent_file_addr; + struct iso_directory_record *idr; + + i1 = 0; + + orig_file_addr = file_addr / blocksize; /* Actual extent of this directory */ + parent_file_addr = parent_addr / blocksize; + + if ((dir_count % 100) == 0) + printf("[%d %d]\n", dir_count, dir_size_count); +#if 0 + if (sizeof (file_addr) > sizeof (long)) { + printf("Starting directory %ld %d %lld\n", + file_addr, file_size, + (Llong)parent_addr); + } else { + printf("Starting directory %ld %d %ld\n", file_addr, file_size, parent_addr); + } +#endif + + dir_count++; + dir_size_count += file_size / blocksize; + + if (file_size & 0x3ff) + printf("********Directory has unusual size\n"); + + for (k = 0; k < (file_size / sizeof (buffer)); k++) { +#ifdef USE_SCG + readsecs(file_addr / 2048, buffer, ISO_BLOCKS(sizeof (buffer))); +#else + lseek(fileno(infile), file_addr, SEEK_SET); + read(fileno(infile), buffer, sizeof (buffer)); +#endif + i = 0; + while (1 == 1) { + goof = iline = 0; + idr = (struct iso_directory_record *) &buffer[i]; + if (idr->length[0] == 0) break; + sprintf(&lbuffer[iline], "%3d ", idr->length[0]); + iline += strlen(lbuffer + iline); + extent = isonum_733(idr->extent); + size = isonum_733(idr->size); + sprintf(&lbuffer[iline], "%5x ", extent); + iline += strlen(lbuffer + iline); + sprintf(&lbuffer[iline], "%8d ", size); + iline += strlen(lbuffer + iline); + sprintf(&lbuffer[iline], "%c", (idr->flags[0] & 2) ? '*' : ' '); + iline += strlen(lbuffer + iline); + + if (idr->name_len[0] > 33) { + sprintf(&lbuffer[iline], "File name length=(%d)", + idr->name_len[0]); + goof++; + iline += strlen(lbuffer + iline); + } else if (idr->name_len[0] == 1 && idr->name[0] == 0) { + sprintf(&lbuffer[iline], ". "); + iline += strlen(lbuffer + iline); + rflag = 0; + if (orig_file_addr != (off_t)(isonum_733(idr->extent) + isonum_711((char *) idr->ext_attr_length))) { + sprintf(&lbuffer[iline], "***** Directory has null extent."); + goof++; + iline += strlen(lbuffer + iline); + } + if (i1) { + sprintf(&lbuffer[iline], "***** . not first entry."); + rr_goof++; + iline += strlen(lbuffer + iline); + } + } else if (idr->name_len[0] == 1 && idr->name[0] == 1) { + sprintf(&lbuffer[iline], ".. "); + iline += strlen(lbuffer + iline); + rflag = 0; + if (parent_file_addr != (off_t)(isonum_733(idr->extent) + isonum_711((char *) idr->ext_attr_length))) { + sprintf(&lbuffer[iline], "***** Directory has null extent."); + goof++; + iline += strlen(lbuffer + iline); + } + if (i1 != 1) { + sprintf(&lbuffer[iline], "***** .. not second entry."); + rr_goof++; + iline += strlen(lbuffer + iline); + } + } else { + if (i1 < 2) { + sprintf(&lbuffer[iline], " Improper sorting."); + rr_goof++; + } + for (j = 0; j < (int)idr->name_len[0]; j++) { + sprintf(&lbuffer[iline], "%c", idr->name[j]); + } + for (j = 0; j < (14 - (int) idr->name_len[0]); j++) { + sprintf(&lbuffer[iline], " "); + iline += strlen(lbuffer + iline); + } + rflag = 1; + } + + if (size && extent == 0) { + sprintf(&lbuffer[iline], "****Extent==0, size != 0"); + goof++; + iline += strlen(lbuffer + iline); + } +#if 0 + /* This is apparently legal. */ + if (size == 0 && extent) { + sprintf(&lbuffer[iline], "****Extent!=0, size == 0"); + goof++; + iline += strlen(lbuffer + iline); + } +#endif + + if (idr->flags[0] & 0xf5) { + sprintf(&lbuffer[iline], "Flags=(%x) ", idr->flags[0]); + goof++; + iline += strlen(lbuffer + iline); + } + if (idr->interleave[0]) { + sprintf(&lbuffer[iline], "Interleave=(%d) ", idr->interleave[0]); + goof++; + iline += strlen(lbuffer + iline); + } + + if (idr->file_unit_size[0]) { + sprintf(&lbuffer[iline], "File unit size=(%d) ", idr->file_unit_size[0]); + goof++; + iline += strlen(lbuffer + iline); + } + + if (idr->volume_sequence_number[0] != 1) { + sprintf(&lbuffer[iline], "Volume sequence number=(%d) ", idr->volume_sequence_number[0]); + goof++; + iline += strlen(lbuffer + iline); + } + + goof += dump_rr(idr); + sprintf(&lbuffer[iline], "\n"); + iline += strlen(lbuffer + iline); + + + if (goof) { + ngoof++; + lbuffer[iline++] = 0; + if (sizeof (orig_file_addr) > sizeof (long)) { + printf("%llx: %s", (Llong)orig_file_addr, lbuffer); + } else { + printf("%lx: %s", (long)orig_file_addr, lbuffer); + } + } + + + + if (rflag && (idr->flags[0] & 2)) + check_tree((off_t)(isonum_733(idr->extent) + isonum_711((char *)idr->ext_attr_length)) * blocksize, + isonum_733(idr->size), + orig_file_addr * blocksize); + i += buffer[i]; + i1++; + if (i > 2048 - offsetof(struct iso_directory_record, name[0])) + break; + } + file_addr += sizeof (buffer); + } + fflush(stdout); +} + + +/* + * This function simply dumps the contents of the path tables. No + * consistency checking takes place, although this would proably be a good + * idea. + */ +struct path_table_info { + char *name; + unsigned int extent; + unsigned short index; + unsigned short parent; +}; + +static void +check_path_tables(int typel_extent, int typem_extent, int path_table_size) +{ + int count; + int j; + char *pnt; + char *typel; + char *typem; + + /* Now read in the path tables */ + + typel = (char *) malloc(ISO_ROUND_UP(path_table_size)); +#ifdef USE_SCG + readsecs(typel_extent * blocksize / 2048, typel, ISO_BLOCKS(path_table_size)); +#else + lseek(fileno(infile), (off_t)((off_t)typel_extent) * blocksize, SEEK_SET); + read(fileno(infile), typel, path_table_size); /* FIXME: check return value */ +#endif + typem = (char *) malloc(path_table_size); + lseek(fileno(infile), (off_t)((off_t)typem_extent) * blocksize, SEEK_SET); + read(fileno(infile), typem, path_table_size); /* FIXME: check return value */ + + j = path_table_size; + pnt = typel; + count = 1; + while (j) { + int namelen; + int extent; + int idx; + char name[32]; + + namelen = *pnt++; pnt++; + extent = isonum_731(pnt); + pnt += 4; + idx = isonum_721(pnt); + pnt += 2; + j -= 8 + namelen; + memset(name, 0, sizeof (name)); + + strncpy(name, pnt, namelen); + pnt += namelen; + if (j & 1) { + j--; + pnt++; + } + printf("%4.4d %4.4d %8.8x %s\n", count++, idx, extent, name); + } + + j = path_table_size; + pnt = typem; + count = 1; + + while (j) { + int namelen; + int extent; + int idx; + char name[32]; + + namelen = *pnt++; pnt++; + extent = isonum_732(pnt); + pnt += 4; + idx = isonum_722(pnt); + pnt += 2; + j -= 8+namelen; + memset(name, 0, sizeof (name)); + + strncpy(name, pnt, namelen); + pnt += namelen; + if (j & 1) { + j--; + pnt++; + } + printf("%4.4d %4.4d %8.8x %s\n", count++, idx, extent, name); + } +} + +static void +usage(int excode) +{ + errmsgno(EX_BAD, "Usage: %s [options] image\n", + get_progname()); + + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t-help, -h Print this help\n"); + fprintf(stderr, "\t-version Print version info and exit\n"); + fprintf(stderr, "\t-i filename Filename to read ISO-9660 image from\n"); + fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n"); + fprintf(stderr, "\nIf neither -i nor dev= are speficied, <image> is needed.\n"); + exit(excode); +} + +int +main(int argc, char *argv[]) +{ + int cac; + char * const *cav; + char *opts = "help,h,version,i*,dev*"; + BOOL help = FALSE; + BOOL prvers = FALSE; + char *filename = NULL; + char *devname = NULL; + off_t file_addr; + int file_size; + struct iso_primary_descriptor ipd; + struct iso_directory_record *idr; + int typel_extent; + int typem_extent; + int path_table_size; + + save_args(argc, argv); + + cac = argc - 1; + cav = argv + 1; + if (getallargs(&cac, &cav, opts, &help, &help, &prvers, + &filename, &devname) < 0) { + errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (help) + usage(0); + if (prvers) { + printf("isovfy %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM); + exit(0); + } + cac = argc - 1; + cav = argv + 1; + if (filename == NULL && devname == NULL) { + if (getfiles(&cac, &cav, opts) != 0) { + filename = cav[0]; + cac--, cav++; + } + } + if (getfiles(&cac, &cav, opts) != 0) { + errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]); + usage(EX_BAD); + } + if (filename != NULL && devname != NULL) { + errmsgno(EX_BAD, "Only one of -i or dev= allowed\n"); + usage(EX_BAD); + } +#ifdef USE_SCG + if (filename == NULL && devname == NULL) + cdr_defaults(&devname, NULL, NULL, NULL); +#endif + if (filename == NULL && devname == NULL) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "ISO-9660 image not specified\n"); +#else + fprintf(stderr, "ISO-9660 image not specified\n"); +#endif + usage(EX_BAD); + } + + if (filename != NULL) + infile = fopen(filename, "rb"); + else + filename = devname; + + if (infile != NULL) { + /* EMPTY */; +#ifdef USE_SCG + } else if (scsidev_open(filename) < 0) { +#else + } else { +#endif +#ifdef USE_LIBSCHILY + comerr("Cannot open '%s'\n", filename); +#else + fprintf(stderr, "Cannot open '%s'\n", filename); + exit(1); +#endif + } + + + file_addr = (off_t)32768; +#ifdef USE_SCG + readsecs(file_addr / 2048, &ipd, ISO_BLOCKS(sizeof (ipd))); +#else + lseek(fileno(infile), file_addr, SEEK_SET); + read(fileno(infile), &ipd, sizeof (ipd)); +#endif + + idr = (struct iso_directory_record *)ipd.root_directory_record; + + blocksize = isonum_723((char *)ipd.logical_block_size); + if (blocksize != 512 && blocksize != 1024 && blocksize != 2048) { + blocksize = 2048; + } + + file_addr = (off_t)isonum_733(idr->extent) + isonum_711((char *)idr->ext_attr_length); + file_size = isonum_733(idr->size); + + if (sizeof (file_addr) > sizeof (long)) { + printf("Root at extent %llx, %d bytes\n", (Llong)file_addr, file_size); + } else { + printf("Root at extent %lx, %d bytes\n", (long)file_addr, file_size); + } + file_addr = file_addr * blocksize; + + check_tree(file_addr, file_size, file_addr); + + typel_extent = isonum_731((char *)ipd.type_l_path_table); + typem_extent = isonum_732((char *)ipd.type_m_path_table); + path_table_size = isonum_733(ipd.path_table_size); + + /* Enable this to get the dump of the path tables */ +#if 0 + check_path_tables(typel_extent, typem_extent, path_table_size); +#endif + + if (infile != NULL) + fclose(infile); + + if (!ngoof) + printf("No errors found\n"); + return (0); +} diff --git a/genisoimage/diskmbr.h b/genisoimage/diskmbr.h new file mode 100644 index 0000000..84501bd --- /dev/null +++ b/genisoimage/diskmbr.h @@ -0,0 +1,65 @@ +/* + * 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. + * + */ + +/* @(#)diskmbr.h 1.2 04/03/02 Copyright 1999-2004 J. Schilling */ +/* + * Header file diskmbr.h - assorted structure definitions and macros + * describing standard PC partition table + * + * Copyright (c) 1999-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. + */ + +#ifndef _DISKMBR_H +#define _DISKMBR_H + +#define MBR_MAGIC 0xAA55 + +#define PARTITION_UNUSED 0x00 +#define PARTITION_ACTIVE 0x80 + +#define PARTITION_COUNT 4 + +#define MBR_SECTOR(x) ((x)&0x3F) +#define MBR_CYLINDER(x) ((x)>>8|((x)<<2&0x300)) + +struct disk_partition { + unsigned char status; + unsigned char s_head; + unsigned char s_cyl_sec[2]; + unsigned char type; + unsigned char e_head; + unsigned char e_cyl_sec[2]; + unsigned char boot_sec[4]; + unsigned char size[4]; +}; + +struct disk_master_boot_record { + char pad[0x1BE]; + struct disk_partition partition[PARTITION_COUNT]; + unsigned char magic[2]; +}; + +#endif /* _DISKMBR_H */ diff --git a/genisoimage/dvd_file.c b/genisoimage/dvd_file.c new file mode 100644 index 0000000..ffd4ef1 --- /dev/null +++ b/genisoimage/dvd_file.c @@ -0,0 +1,771 @@ +/* + * 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. + * + */ + +/* @(#)dvd_file.c 1.3 04/03/04 joerg */ +/* + * DVD_VIDEO code + * Copyright (c) 2002 Olaf Beck - olaf_sc@yahoo.com + * Jörg Schilling <schilling@fokus.gmd.de> + * (making the code portable) + */ +/* + * 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. + */ + +#ifdef DVD_VIDEO + +#include <mconfig.h> +#include "genisoimage.h" +#include <schily.h> +#include "dvd_reader.h" +#include "dvd_file.h" +#include "ifo_read.h" + +static void bsort(int sector[], int title[], int size); +static void uniq(int sector[], int title[], int title_sets_array[], + int sector_sets_array[], int titles); +static void DVDFreeFileSetArrays(int *sector, int *title, + int *title_sets_array, + int *sector_sets_array); +void DVDFreeFileSet(title_set_info_t *title_set_info); +title_set_info_t *DVDGetFileSet(char *dvd); +int DVDGetFilePad(title_set_info_t *title_set_info, char *name); + + +static void +bsort(int sector[], int title[], int size) +{ + int temp_title; + int temp_sector; + int i; + int j; + + /* this is not bubble sort, this is primitive selection sort. Replace with + * bubble sort later, maybe bidirectional, aka Coctail Sort */ + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + if (sector[i] < sector[j]) { + temp_sector = sector[i]; + temp_title = title[i]; + sector[i] = sector[j]; + title[i] = title[j]; + sector[j] = temp_sector; + title[j] = temp_title; + } + } + } +} + + +static void +uniq(int sector[], int title[], int title_sets_array[], + int sector_sets_array[], int titles) +{ + int i; + int j; + + + for (i = 0, j = 0; j < titles; ) { + if (sector[j] != sector[j+1]) { + title_sets_array[i] = title[j]; + sector_sets_array[i] = sector[j]; +#ifdef DEBUG + fprintf(stderr, "Sector offset is %d\n", sector_sets_array[i]); +#endif + i++; + j++; + } else { + do { + if (j < titles) + j++; + + } while (sector[j] == sector[j+1]); + + } + } + +} + +static void +DVDFreeFileSetArrays(int *sector, int *title, int *title_sets_array, + int *sector_sets_array) +{ + free(sector); + free(title); + free(title_sets_array); + free(sector_sets_array); +} + +void +DVDFreeFileSet(title_set_info_t *title_set_info) +{ + free(title_set_info->title_set); + free(title_set_info); +} + +title_set_info_t * +DVDGetFileSet(char *dvd) +{ + /* + * TODO Fix close of files if + * we error out + * We also assume that all + * DVD files are of valid + * size i.e. file%2048 == 0 + */ + + /* title interation */ + int title_sets; + int titles; + int counter; + int i; + + /* DVD file structures */ + dvd_reader_t * _dvd = NULL; + + ifo_handle_t * vmg_ifo = NULL; + ifo_handle_t * vts_ifo = NULL; + + dvd_file_t * vmg_vob_file = NULL; + dvd_file_t * vmg_ifo_file = NULL; + + dvd_file_t * vts_ifo_file = NULL; + dvd_file_t * vts_menu_file = NULL; + dvd_file_t * vts_title_file = NULL; + + /* The sizes it self of each file */ + int ifo; + int bup; + int menu_vob; + int title_vob; + + /* Arrays keeping the title - filset relationship */ + int * sector; + int * title; + int * title_sets_array; + int * sector_sets_array; + + /* DVD Video files */ + struct stat fileinfo; + char temppoint[PATH_MAX + 1]; + + /* The Title Set Info struct*/ + title_set_info_t * title_set_info; + + /* Temporary mount point - to be used later */ + char mountpoint[PATH_MAX + 1]; + + strncpy(mountpoint, dvd, sizeof (mountpoint)); + mountpoint[sizeof (mountpoint)-1] = '\0'; + + + _dvd = DVDOpen(dvd); + if (!_dvd) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Can't open device '%s'\n", dvd); +#else + fprintf(stderr, "Can't open device\n"); +#endif + return (0); + } + vmg_ifo = ifoOpen(_dvd, 0); + if (!vmg_ifo) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Can't open VMG info for '%s'.\n", dvd); +#else + fprintf(stderr, "Can't open VMG info.\n"); +#endif + return (0); + } + + /* Check mount point */ + + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VIDEO_TS.IFO", mountpoint); + + + if (stat(temppoint, &fileinfo) < 0) { + /* If we can't stat the file, give up */ +#ifdef USE_LIBSCHILY + errmsg("Can't stat %s\n", temppoint); +#else + fprintf(stderr, "Can't stat %s\n", temppoint); + perror(""); +#endif + return (0); + } + + + + title_sets = vmg_ifo->vmgi_mat->vmg_nr_of_title_sets; + titles = vmg_ifo->tt_srpt->nr_of_srpts; + + sector = e_malloc(titles * sizeof (int)); + memset(sector, 0, titles * sizeof (int)); + title = e_malloc(titles * sizeof (int)); + title_sets_array = e_malloc(title_sets * sizeof (int)); + sector_sets_array = e_malloc(title_sets * sizeof (int)); + title_set_info = (title_set_info_t *)e_malloc(sizeof (title_set_info_t)); + title_set_info->title_set = (title_set_t *)e_malloc((title_sets + 1) * + sizeof (title_set_t)); + + title_set_info->num_titles = title_sets; + + + /* Fill and sort the arrays for titles*/ + + if (titles >= 1) { + for (counter = 0; counter < titles; counter++) { + sector[counter] = vmg_ifo->tt_srpt->title[counter].title_set_sector; + title[counter] = counter + 1; + } + } + + /* Yes, we should probably do a better sort than B - but what the heck*/ + bsort(sector, title, titles); + + + /* + * Since title sets and titles are not the same we will need to sort + * out "bogus" titles + */ + + uniq(sector, title, title_sets_array, sector_sets_array, titles); + + + /* Open VIDEO_TS.VOB is present */ + + vmg_vob_file = DVDOpenFile(_dvd, 0, DVD_READ_MENU_VOBS); + + /* Check VIDEO_TS title set */ + + vmg_ifo_file = DVDOpenFile(_dvd, 0, DVD_READ_INFO_FILE); + + if ((vmg_vob_file == 0) && vmg_ifo->vmgi_mat->vmg_last_sector + 1 + < 2 * DVDFileSize(vmg_ifo_file)) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "IFO is not of correct size aborting\n"); +#else + fprintf(stderr, "IFO is not of correct size aborting\n"); +#endif + DVDFreeFileSetArrays(sector, title, title_sets_array, + sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } else if ((vmg_vob_file != 0) && (vmg_ifo->vmgi_mat->vmg_last_sector + + 1 < 2 * DVDFileSize(vmg_ifo_file) + + DVDFileSize(vmg_vob_file))) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size"); +#else + fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size"); +#endif + DVDFreeFileSetArrays(sector, title, title_sets_array, + sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + /* Find the actuall right size of VIDEO_TS.IFO */ + if (vmg_vob_file == 0) { + if (vmg_ifo->vmgi_mat->vmg_last_sector + 1 > 2 + * DVDFileSize(vmg_ifo_file)) { + ifo = vmg_ifo->vmgi_mat->vmg_last_sector + - DVDFileSize(vmg_ifo_file) + 1; + } else { + ifo = vmg_ifo->vmgi_mat->vmgi_last_sector + 1; + } + } else { + if (vmg_ifo->vmgi_mat->vmgi_last_sector + 1 + < vmg_ifo->vmgi_mat->vmgm_vobs) { + ifo = vmg_ifo->vmgi_mat->vmgm_vobs; + } else { + ifo = vmg_ifo->vmgi_mat->vmgi_last_sector + 1; + } + } + + title_set_info->title_set[0].size_ifo = ifo * 2048; + title_set_info->title_set[0].realsize_ifo = fileinfo.st_size; + title_set_info->title_set[0].pad_ifo = ifo - DVDFileSize(vmg_ifo_file); + + /* Find the actuall right size of VIDEO_TS.VOB */ + if (vmg_vob_file != 0) { + if (ifo + DVDFileSize(vmg_ifo_file) + + DVDFileSize(vmg_vob_file) - 1 < + vmg_ifo->vmgi_mat->vmg_last_sector) { + menu_vob = vmg_ifo->vmgi_mat->vmg_last_sector - + ifo - DVDFileSize(vmg_ifo_file) + 1; + } else { + menu_vob = vmg_ifo->vmgi_mat->vmg_last_sector + - ifo - DVDFileSize(vmg_ifo_file) + 1; + } + + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VIDEO_TS.VOB", mountpoint); + if (stat(temppoint, &fileinfo) < 0) { +#ifdef USE_LIBSCHILY + errmsg("calc: Can't stat %s\n", temppoint); +#else + fprintf(stderr, "calc: Can't stat %s\n", temppoint); + perror(""); +#endif + DVDFreeFileSetArrays(sector, title, title_sets_array, + sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + title_set_info->title_set[0].realsize_menu = fileinfo.st_size; + title_set_info->title_set[0].pad_menu = menu_vob - + DVDFileSize(vmg_vob_file); + title_set_info->title_set[0].size_menu = menu_vob * 2048; + DVDCloseFile(vmg_vob_file); + } else { + title_set_info->title_set[0].size_menu = 0; + title_set_info->title_set[0].realsize_menu = 0; + title_set_info->title_set[0].pad_menu = 0; + menu_vob = 0; + } + + + /* Finding the actuall right size of VIDEO_TS.BUP */ + if (title_sets >= 1) { + bup = sector_sets_array[0] - menu_vob - ifo; + } else { + /* Just in case we burn a DVD-Video without any title_sets */ + bup = vmg_ifo->vmgi_mat->vmg_last_sector + 1 - menu_vob - ifo; + } + + /* Never trust the BUP file - use a copy of the IFO */ + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VIDEO_TS.IFO", mountpoint); + + if (stat(temppoint, &fileinfo) < 0) { +#ifdef USE_LIBSCHILY + errmsg("calc: Can't stat %s\n", temppoint); +#else + fprintf(stderr, "calc: Can't stat %s\n", temppoint); + perror(""); +#endif + DVDFreeFileSetArrays(sector, title, title_sets_array, + sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + title_set_info->title_set[0].realsize_bup = fileinfo.st_size; + title_set_info->title_set[0].size_bup = bup * 2048; + title_set_info->title_set[0].pad_bup = bup - DVDFileSize(vmg_ifo_file); + + /* Take care of the titles which we don't have in VMG */ + + title_set_info->title_set[0].number_of_vob_files = 0; + title_set_info->title_set[0].realsize_vob[0] = 0; + title_set_info->title_set[0].pad_title = 0; + + DVDCloseFile(vmg_ifo_file); + + if (title_sets >= 1) { + for (counter = 0; counter < title_sets; counter++) { + + vts_ifo = ifoOpen(_dvd, counter + 1); + + if (!vts_ifo) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Can't open VTS info.\n"); +#else + fprintf(stderr, "Can't open VTS info.\n"); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VTS_%02i_0.IFO", + mountpoint, counter + 1); + + if (stat(temppoint, &fileinfo) < 0) { +#ifdef USE_LIBSCHILY + errmsg("calc: Can't stat %s\n", temppoint); +#else + fprintf(stderr, "calc: Can't stat %s\n", + temppoint); + perror(""); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + + /* Test if VTS_XX_0.VOB is present */ + + vts_menu_file = DVDOpenFile(_dvd, counter + 1, + DVD_READ_MENU_VOBS); + + /* Test if VTS_XX_X.VOB are present */ + + vts_title_file = DVDOpenFile(_dvd, counter + 1, + DVD_READ_TITLE_VOBS); + + /* Check VIDEO_TS.IFO */ + + vts_ifo_file = DVDOpenFile(_dvd, counter + 1, + DVD_READ_INFO_FILE); + + /* + * Checking that title will fit in the + * space given by the ifo file + */ + + + if (vts_ifo->vtsi_mat->vts_last_sector + 1 + < 2 * DVDFileSize(vts_ifo_file)) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "IFO is not of correct size aborting.\n"); +#else + fprintf(stderr, "IFO is not of correct size aborting\n"); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } else if ((vts_title_file != 0) && + (vts_menu_file != 0) && + (vts_ifo->vtsi_mat->vts_last_sector + 1 + < 2 * DVDFileSize(vts_ifo_file) + + DVDFileSize(vts_title_file) + + DVDFileSize(vts_menu_file))) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"); +#else + fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size"); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } else if ((vts_title_file != 0) && + (vts_menu_file == 0) && + (vts_ifo->vtsi_mat->vts_last_sector + 1 + < 2 * DVDFileSize(vts_ifo_file) + + DVDFileSize(vts_title_file))) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"); +#else + fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size"); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } else if ((vts_menu_file != 0) && + (vts_title_file == 0) && + (vts_ifo->vtsi_mat->vts_last_sector + 1 + < 2 * DVDFileSize(vts_ifo_file) + + DVDFileSize(vts_menu_file))) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"); +#else + fprintf(stderr, "Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size"); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + + /* Find the actuall right size of VTS_XX_0.IFO */ + if ((vts_title_file == 0) && (vts_menu_file == 0)) { + if (vts_ifo->vtsi_mat->vts_last_sector + 1 > + 2 * DVDFileSize(vts_ifo_file)) { + ifo = vts_ifo->vtsi_mat->vts_last_sector + - DVDFileSize(vts_ifo_file) + 1; + } else { + ifo = vts_ifo->vtsi_mat->vts_last_sector + - DVDFileSize(vts_ifo_file) + 1; + } + } else if (vts_title_file == 0) { + if (vts_ifo->vtsi_mat->vtsi_last_sector + 1 < + vts_ifo->vtsi_mat->vtstt_vobs) { + ifo = vmg_ifo->vtsi_mat->vtstt_vobs; + } else { + ifo = vmg_ifo->vtsi_mat->vtstt_vobs; + } + } else { + if (vts_ifo->vtsi_mat->vtsi_last_sector + 1 < + vts_ifo->vtsi_mat->vtsm_vobs) { + ifo = vts_ifo->vtsi_mat->vtsm_vobs; + } else { + ifo = vts_ifo->vtsi_mat->vtsi_last_sector + 1; + } + } + title_set_info->title_set[counter + 1].size_ifo = + ifo * 2048; + title_set_info->title_set[counter + 1].realsize_ifo = + fileinfo.st_size; + title_set_info->title_set[counter + 1].pad_ifo = + ifo - DVDFileSize(vts_ifo_file); + + + /* Find the actuall right size of VTS_XX_0.VOB */ + if (vts_menu_file != 0) { + if (vts_ifo->vtsi_mat->vtsm_vobs == 0) { + /* + * Apparently start sector 0 means that + * VTS_XX_0.VOB is empty after all... + */ + menu_vob = 0; + if (DVDFileSize(vts_menu_file) != 0) { + /* + * Paranoia: we most likely never + * come here... + */ +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "%s/VIDEO_TS/VTS_%02i_0.IFO appears to be corrupted.\n", + mountpoint, counter+1); +#else + fprintf(stderr, + "%s/VIDEO_TS/VTS_%02i_0.IFO appears to be corrupted.\n", + mountpoint, counter+1); +#endif + return (0); + } + } else if ((vts_title_file != 0) && + (vts_ifo->vtsi_mat->vtstt_vobs - + vts_ifo->vtsi_mat->vtsm_vobs > + DVDFileSize(vts_menu_file))) { + menu_vob = vts_ifo->vtsi_mat->vtstt_vobs - + vts_ifo->vtsi_mat->vtsm_vobs; + } else if ((vts_title_file == 0) && + (vts_ifo->vtsi_mat->vtsm_vobs + + DVDFileSize(vts_menu_file) + + DVDFileSize(vts_ifo_file) - 1 < + vts_ifo->vtsi_mat->vts_last_sector)) { + menu_vob = vts_ifo->vtsi_mat->vts_last_sector + - DVDFileSize(vts_ifo_file) + - vts_ifo->vtsi_mat->vtsm_vobs + 1; + } else { + menu_vob = vts_ifo->vtsi_mat->vtstt_vobs - + vts_ifo->vtsi_mat->vtsm_vobs; + } + + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VTS_%02i_0.VOB", mountpoint, counter + 1); + + if (stat(temppoint, &fileinfo) < 0) { +#ifdef USE_LIBSCHILY + errmsg("calc: Can't stat %s\n", temppoint); +#else + fprintf(stderr, "calc: Can't stat %s\n", + temppoint); + perror(""); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + title_set_info->title_set[counter + 1].realsize_menu = fileinfo.st_size; + title_set_info->title_set[counter + 1].size_menu = menu_vob * 2048; + title_set_info->title_set[counter + 1].pad_menu = menu_vob - DVDFileSize(vts_menu_file); + + } else { + title_set_info->title_set[counter + 1].size_menu = 0; + title_set_info->title_set[counter + 1].realsize_menu = 0; + title_set_info->title_set[counter + 1].pad_menu = 0; + menu_vob = 0; + } + + + /* Find the actuall total size of VTS_XX_[1 to 9].VOB */ + + if (vts_title_file != 0) { + if (ifo + menu_vob + DVDFileSize(vts_ifo_file) - + 1 < vts_ifo->vtsi_mat->vts_last_sector) { + title_vob = vts_ifo->vtsi_mat->vts_last_sector + + 1 - ifo - menu_vob - + DVDFileSize(vts_ifo_file); + } else { + title_vob = vts_ifo->vtsi_mat->vts_last_sector + + 1 - ifo - menu_vob - + DVDFileSize(vts_ifo_file); + } + /* + * Find out how many vob files + * and the size of them + */ + for (i = 0; i < 9; ++i) { + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VTS_%02i_%i.VOB", + mountpoint, counter + 1, i + 1); + if (stat(temppoint, &fileinfo) < 0) { + break; + } + title_set_info->title_set[counter + 1].realsize_vob[i] = fileinfo.st_size; + } + title_set_info->title_set[counter + 1].number_of_vob_files = i; + title_set_info->title_set[counter + 1].size_title = title_vob * 2048; + title_set_info->title_set[counter + 1].pad_title = title_vob - DVDFileSize(vts_title_file); + } else { + title_set_info->title_set[counter + 1].number_of_vob_files = 0; + title_set_info->title_set[counter + 1].realsize_vob[0] = 0; + title_set_info->title_set[counter + 1].size_title = 0; + title_set_info->title_set[counter + 1].pad_title = 0; + title_vob = 0; + + } + + + /* Find the actuall total size of VTS_XX_0.BUP */ + if (title_sets - 1 > counter) { + bup = sector_sets_array[counter+1] + - sector_sets_array[counter] + - title_vob - menu_vob - ifo; + } else { + bup = vts_ifo->vtsi_mat->vts_last_sector + 1 + - title_vob - menu_vob - ifo; + } + + /* Never trust the BUP use a copy of the IFO */ + snprintf(temppoint, sizeof (temppoint), + "%s/VIDEO_TS/VTS_%02i_0.IFO", + mountpoint, counter + 1); + + if (stat(temppoint, &fileinfo) < 0) { +#ifdef USE_LIBSCHILY + errmsg("calc: Can't stat %s\n", temppoint); +#else + fprintf(stderr, "calc: Can't stat %s\n", + temppoint); + perror(""); +#endif + DVDFreeFileSetArrays(sector, title, + title_sets_array, sector_sets_array); + DVDFreeFileSet(title_set_info); + return (0); + } + + title_set_info->title_set[counter + 1].size_bup = + bup * 2048; + title_set_info->title_set[counter + 1].realsize_bup = + fileinfo.st_size; + title_set_info->title_set[counter + 1].pad_bup = + bup - DVDFileSize(vts_ifo_file); + + + /* Closing files */ + + if (vts_menu_file != 0) { + DVDCloseFile(vts_menu_file); + } + + if (vts_title_file != 0) { + DVDCloseFile(vts_title_file); + } + + + if (vts_ifo_file != 0) { + DVDCloseFile(vts_ifo_file); + } + + ifoClose(vts_ifo); + + } + + } + + DVDFreeFileSetArrays(sector, title, title_sets_array, sector_sets_array); + + /* Close the VMG ifo file we got all the info we need */ + ifoClose(vmg_ifo); + + + /* Close the DVD */ + DVDClose(_dvd); + + /* Return the actuall info*/ + return (title_set_info); + + +} + +int +DVDGetFilePad(title_set_info_t *title_set_info, char *name) +{ + char title_a[3]; + char vob_a[2]; + int title; + int vob; + + title_a[0] = title_a[1] = title_a[2] = '\0'; + vob_a[0] = vob_a[1] = '\0'; + + if (name[0] != 'V') { + return (0); + } + if (memcmp(name, "VIDEO_TS", 8) == 0) { + if (strstr(name, ".IFO") != 0) { + return (title_set_info->title_set[0].pad_ifo); + } else if (strstr(name, ".VOB") != 0) { + return (title_set_info->title_set[0].pad_menu); + } else if (strstr(name, ".BUP") != 0) { + return (title_set_info->title_set[0].pad_bup); + } else { + return (0); + } + } else if (memcmp(name, "VTS_", 4) == 0) { + title_a[0] = name[4]; + title_a[1] = name[5]; + title_a[2] = '\0'; + vob_a[0] = name[7]; + vob_a[1] = '\0'; + title = atoi(title_a); + vob = atoi(vob_a); + if (title > title_set_info->num_titles) { + return (0); + } else { + if (strstr(name, ".IFO") != 0) { + return (title_set_info->title_set[title].pad_ifo); + } else if (strstr(name, ".BUP") != 0) { + return (title_set_info->title_set[title].pad_bup); + } else if (vob == 0) { + return (title_set_info->title_set[title].pad_menu); + } else if (vob == title_set_info->title_set[title].number_of_vob_files) { + return (title_set_info->title_set[title].pad_title); + } else { + return (0); + } + } + } else { + return (0); + } +} + +#endif /*DVD_VIDEO*/ diff --git a/genisoimage/dvd_file.h b/genisoimage/dvd_file.h new file mode 100644 index 0000000..234a1de --- /dev/null +++ b/genisoimage/dvd_file.h @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +/* @(#)dvd_file.h 1.1 02/07/21 Copyright 2002 J. Schilling */ +/* + * Defnitions for users of dvd_file.c + * + * Copyright (c) 2002 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. + */ + +#ifndef _DVD_FILE_H +#define _DVD_FILE_H + +extern void DVDFreeFileSet(title_set_info_t *title_set_info); +extern title_set_info_t *DVDGetFileSet(char *dvd); +extern int DVDGetFilePad(title_set_info_t *title_set_info, char *name); + +#endif /* _DVD_FILE_H */ diff --git a/genisoimage/dvd_reader.c b/genisoimage/dvd_reader.c new file mode 100644 index 0000000..1a85abe --- /dev/null +++ b/genisoimage/dvd_reader.c @@ -0,0 +1,295 @@ +/* + * 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. + * + */ + +/* @(#)dvd_reader.c 1.3 04/03/04 joerg */ +/* + * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>, + * Håkan Hjort <d95hjort@dtek.chalmers.se>, + * Olaf Beck <olaf_sc@yahoo.com> + * (I only did the cut down no other contribs) + * Jörg Schilling <schilling@fokus.gmd.de> + * (making the code portable) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTE: This is a cut down version of libdvdread for genisoimage, due + * to portability issues with the current libdvdread according to + * the maintainer of genisoimage. + * This cut down version only reads from a harddisk file structure + * and it only implements the functions necessary inorder to make + * genisoimage produce valid DVD-Video images. + * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL + * LIBDVDREAD INSTEAD + */ +#ifdef DVD_VIDEO + +#include "genisoimage.h" +#include <fctldefs.h> +#include <schily.h> + +#include "dvd_reader.h" + +struct dvd_file_s { + /* Basic information. */ + dvd_reader_t *dvd; + + /* Calculated at open-time, size in blocks. */ + ssize_t filesize; +}; + + +void DVDCloseFile(dvd_file_t *dvd_file); +static dvd_file_t *DVDOpenFilePath(dvd_reader_t *dvd, char *filename); +static dvd_file_t *DVDOpenVOBPath(dvd_reader_t *dvd, int title, int menu); +dvd_file_t *DVDOpenFile(dvd_reader_t *dvd, int titlenum, + dvd_read_domain_t domain); +static dvd_reader_t *DVDOpenPath(const char *path_root); +dvd_reader_t *DVDOpen(const char *path); +void DVDClose(dvd_reader_t *dvd); +ssize_t DVDFileSize(dvd_file_t *dvd_file); + + +/* + * Free a DVD file + */ +void +DVDCloseFile(dvd_file_t *dvd_file) +{ + free(dvd_file); + dvd_file = 0; +} + + +/* + * Stat a IFO or BUP file from a DVD directory tree. + */ +static dvd_file_t * +DVDOpenFilePath(dvd_reader_t *dvd, char *filename) +{ + + char full_path[PATH_MAX + 1]; + dvd_file_t *dvd_file; + struct stat fileinfo; + + /* Get the full path of the file. */ + + snprintf(full_path, sizeof (full_path), + "%s/%s", dvd->path_root, filename); + + + dvd_file = (dvd_file_t *) e_malloc(sizeof (dvd_file_t)); + if (!dvd_file) + return (0); + dvd_file->dvd = dvd; + dvd_file->filesize = 0; + + if (stat(full_path, &fileinfo) < 0) { + free(dvd_file); + return (0); + } + dvd_file->filesize = fileinfo.st_size / DVD_VIDEO_LB_LEN; + + return (dvd_file); +} + + +/* + * Stat a VOB file from a DVD directory tree. + */ +static dvd_file_t * +DVDOpenVOBPath(dvd_reader_t *dvd, int title, int menu) +{ + + char filename[PATH_MAX + 1]; + struct stat fileinfo; + dvd_file_t *dvd_file; + int i; + + dvd_file = (dvd_file_t *) e_malloc(sizeof (dvd_file_t)); + if (!dvd_file) + return (0); + dvd_file->dvd = dvd; + dvd_file->filesize = 0; + + if (menu) { + if (title == 0) { + snprintf(filename, sizeof (filename), + "%s/VIDEO_TS/VIDEO_TS.VOB", dvd->path_root); + } else { + snprintf(filename, sizeof (filename), + "%s/VIDEO_TS/VTS_%02i_0.VOB", dvd->path_root, title); + } + if (stat(filename, &fileinfo) < 0) { + free(dvd_file); + return (0); + } + dvd_file->filesize = fileinfo.st_size / DVD_VIDEO_LB_LEN; + } else { + for (i = 0; i < 9; ++i) { + + snprintf(filename, sizeof (filename), + "%s/VIDEO_TS/VTS_%02i_%i.VOB", dvd->path_root, title, i + 1); + if (stat(filename, &fileinfo) < 0) { + break; + } + + dvd_file->filesize += fileinfo.st_size / DVD_VIDEO_LB_LEN; + } + } + + return (dvd_file); +} + +/* + * Stat a DVD file from a DVD directory tree + */ +EXPORT dvd_file_t * +DVDOpenFile(dvd_reader_t *dvd, int titlenum, dvd_read_domain_t domain) +{ + char filename[MAX_UDF_FILE_NAME_LEN]; + + switch (domain) { + + case DVD_READ_INFO_FILE: + if (titlenum == 0) { + snprintf(filename, sizeof (filename), + "/VIDEO_TS/VIDEO_TS.IFO"); + } else { + snprintf(filename, sizeof (filename), + "/VIDEO_TS/VTS_%02i_0.IFO", titlenum); + } + break; + + case DVD_READ_INFO_BACKUP_FILE: + if (titlenum == 0) { + snprintf(filename, sizeof (filename), + "/VIDEO_TS/VIDEO_TS.BUP"); + } else { + snprintf(filename, sizeof (filename), + "/VIDEO_TS/VTS_%02i_0.BUP", titlenum); + } + break; + + case DVD_READ_MENU_VOBS: + return (DVDOpenVOBPath(dvd, titlenum, 1)); + + case DVD_READ_TITLE_VOBS: + if (titlenum == 0) + return (0); + return (DVDOpenVOBPath(dvd, titlenum, 0)); + + default: +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Invalid domain for file open.\n"); +#else + fprintf(stderr, "Invalid domain for file open.\n"); +#endif + return (0); + } + return (DVDOpenFilePath(dvd, filename)); +} + + + +/* + * Stat a DVD directory structure + */ +static dvd_reader_t * +DVDOpenPath(const char *path_root) +{ + dvd_reader_t *dvd; + + dvd = (dvd_reader_t *) e_malloc(sizeof (dvd_reader_t)); + if (!dvd) + return (0); + dvd->path_root = strdup(path_root); + + return (dvd); +} + + +/* + * Stat a DVD structure - this one only works with directory structures + */ +dvd_reader_t * +DVDOpen(const char *path) +{ + struct stat fileinfo; + int ret; + + if (!path) + return (0); + + ret = stat(path, &fileinfo); + if (ret < 0) { + /* If we can't stat the file, give up */ +#ifdef USE_LIBSCHILY + errmsg("Can't stat %s\n", path); +#else + fprintf(stderr, "Can't stat %s\n", path); + perror(""); +#endif + return (0); + } + + + if (S_ISDIR(fileinfo.st_mode)) { + return (DVDOpenPath(path)); + } + + /* If it's none of the above, screw it. */ +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Could not open %s\n", path); +#else + fprintf(stderr, "Could not open %s\n", path); +#endif + return (0); +} + +/* + * Free a DVD structure - this one will only close a directory tree + */ +void +DVDClose(dvd_reader_t *dvd) +{ + if (dvd) { + if (dvd->path_root) free(dvd->path_root); + free(dvd); + dvd = 0; + } +} + + + +/* + * Return the size of a DVD file + */ +ssize_t +DVDFileSize(dvd_file_t *dvd_file) +{ + return (dvd_file->filesize); +} + +#endif /* DVD_VIDEO */ diff --git a/genisoimage/dvd_reader.h b/genisoimage/dvd_reader.h new file mode 100644 index 0000000..1ec2648 --- /dev/null +++ b/genisoimage/dvd_reader.h @@ -0,0 +1,151 @@ +/* + * 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. + * + */ + +/* @(#)dvd_reader.h 1.2 04/03/02 joerg */ + +#ifndef _DVD_READER_H +#define _DVD_READER_H + +/* + * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>, + * Håkan Hjort <d95hjort@dtek.chalmers.se + * Olaf Beck <olaf_sc@yahoo.com> + * (I only did the cut down no other contribs) + * Jörg Schilling <schilling@fokus.gmd.de> + * (making the code portable) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTE: This is a cut down version of libdvdread for genisoimage, due + * to portability issues with the current libdvdread according to + * the maintainer of genisoimage. + * This cut down version only reads from a harddisk file structure + * and it only implements the functions necessary inorder to make + * genisoimage produce valid DVD-Video images. + * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL + * LIBDVDREAD INSTEAD + */ + + +#include <unixstd.h> /* Make sure <sys/types.h> is included */ + +/* + * Maximum length of filenames for UDF. + */ +#define MAX_UDF_FILE_NAME_LEN 2048 + +/* + * The length of one Logical Block of a DVD Video. + */ +#define DVD_VIDEO_LB_LEN 2048 + +#ifdef __cplusplus +extern "C" { +#endif + + +struct dvd_reader_s { + /* Information required for a directory path drive. */ + char *path_root; +}; + + +typedef struct dvd_reader_s dvd_reader_t; +typedef struct dvd_file_s dvd_file_t; + + +/* + * dvd = DVDOpen(path); + * Opens a directory name of a DVD-Video structure on HD. + * Returns zero if it fails. + * The path should be like this + * "path/VIDEO_TS/VTS_01_1.VOB" + */ + + +extern dvd_reader_t *DVDOpen(const char *); + + +/* + * DVDClose(dvd); + * + * Closes and cleans up the DVD reader object. You must close all open files + * before calling this function. + */ + + +extern void DVDClose(dvd_reader_t *); + +/* + * INFO_FILE : VIDEO_TS.IFO (manager) + * VTS_XX_0.IFO (title) + * + * INFO_BACKUP_FILE: VIDEO_TS.BUP (manager) + * VTS_XX_0.BUP (title) + * + * MENU_VOBS : VIDEO_TS.VOB (manager) + * VTS_XX_0.VOB (title) + * + * TITLE_VOBS : VTS_XX_[1-9].VOB (title) + * All files in the title set are opened and + * read as a single file. + */ +typedef enum { + DVD_READ_INFO_FILE, + DVD_READ_INFO_BACKUP_FILE, + DVD_READ_MENU_VOBS, + DVD_READ_TITLE_VOBS +} dvd_read_domain_t; + +/* + * dvd_file = DVDOpenFile(dvd, titlenum, domain); + * + * Opens a file on the DVD given the title number and domain. If the title + * number is 0, the video manager information is opened + * (VIDEO_TS.[IFO,BUP,VOB]). Returns a file structure which may be used for + * reads, or 0 if the file was not found. + */ +extern dvd_file_t * DVDOpenFile(dvd_reader_t *, int, dvd_read_domain_t); + +/* + * DVDCloseFile(dvd_file); + * + * Closes a file and frees the associated structure. + */ +extern void DVDCloseFile(dvd_file_t *); + + +/* + * blocks = DVDFileSize(dvd_file); + * + * Returns the file size in blocks. + */ +extern ssize_t DVDFileSize(dvd_file_t *); + + +#ifdef __cplusplus +}; +#endif +#endif /* _DVD_READER_H */ diff --git a/genisoimage/eltorito.c b/genisoimage/eltorito.c new file mode 100644 index 0000000..d52e17e --- /dev/null +++ b/genisoimage/eltorito.c @@ -0,0 +1,716 @@ +/* + * 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. + * + */ + +/* @(#)eltorito.c 1.33 05/02/27 joerg */ +/* + * Program eltorito.c - Handle El Torito specific extensions to iso9660. + * + * + * Written by Michael Fulbright <msf@redhat.com> (1996). + * + * Copyright 1996 RedHat Software, Incorporated + * Copyright (c) 1999-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 as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <intcvt.h> +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include <schily.h> + +#undef MIN +#define MIN(a, b) (((a) < (b))? (a): (b)) + +static struct eltorito_validation_entry valid_desc; +static struct eltorito_boot_descriptor gboot_desc; +static struct disk_master_boot_record disk_mbr; +static unsigned int bcat_de_flags; + +void init_boot_catalog(const char *path); +void insert_boot_cat(void); +static void get_torito_desc(struct eltorito_boot_descriptor *boot_desc); +static void fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry, + struct eltorito_boot_entry_info *boot_entry); +void get_boot_entry(void); +void new_boot_entry(void); +static int tvd_write(FILE *outfile); + + +static char *bootcat_path; /* filename of boot catalog */ +/* + * Make sure any existing boot catalog is excluded + */ +void +init_boot_catalog(const char *path) +{ +#ifdef SORTING + struct eltorito_boot_entry_info * cbe; + + for (cbe = first_boot_entry; + cbe != NULL; + cbe = cbe->next) { + char *p; + + if (cbe->boot_image == NULL) + comerrno(EX_BAD, "Missing boot image name, use -eltorito-boot option.\n"); + p = (char *) e_malloc(strlen(cbe->boot_image) + strlen(path) + 2); + strcpy(p, path); + if (p[strlen(p) - 1] != '/') { + strcat(p, "/"); + } + strcat(p, cbe->boot_image); + add_sort_match(p, sort_matches(p, 1)); + free(p); + } +#endif + bootcat_path = (char *) e_malloc(strlen(boot_catalog) + strlen(path) + 2); + strcpy(bootcat_path, path); + if (bootcat_path[strlen(bootcat_path) - 1] != '/') { + strcat(bootcat_path, "/"); + } + strcat(bootcat_path, boot_catalog); + + /* + * we are going to create a virtual catalog file + * - so make sure any existing is excluded + */ + add_match(bootcat_path); + + /* flag the file as a memory file */ + bcat_de_flags = MEMORY_FILE; + + /* find out if we want to "hide" this file */ + if (i_matches(boot_catalog) || i_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_ISO9660_ENTRY; + + if (j_matches(boot_catalog) || j_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_JOLIET_ENTRY; + +}/* init_boot_catalog(... */ + +/* + * Create a boot catalog file in memory - genisoimage already uses this type of + * file for the TRANS.TBL files. Therefore the boot catalog is set up in + * similar way + */ +void +insert_boot_cat() +{ + struct directory_entry *de; + struct directory_entry *s_entry; + char *p1; + char *p2; + char *p3; + struct directory *this_dir; + struct directory *dir; + char *buffer; + + init_fstatbuf(); + + buffer = (char *) e_malloc(SECTOR_SIZE); + memset(buffer, 0, SECTOR_SIZE); + + /* + * try to find the directory that will contain the boot.cat file + * - not very neat, but I can't think of a better way + */ + p1 = strdup(boot_catalog); + + /* get dirname (p1) and basename (p2) of boot.cat */ + if ((p2 = strrchr(p1, '/')) != NULL) { + *p2 = '\0'; + p2++; + + /* find the dirname directory entry */ + de = search_tree_file(root, p1); + if (!de) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p1); +#else + fprintf(stderr, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p1); + exit(1); +#endif + } + this_dir = 0; + + /* get the basename (p3) of the directory */ + if ((p3 = strrchr(p1, '/')) != NULL) + p3++; + else + p3 = p1; + + /* find the correct sub-directory entry */ + for (dir = de->filedir->subdir; dir; dir = dir->next) + if (!(strcmp(dir->de_name, p3))) + this_dir = dir; + + if (this_dir == 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p3); +#else + fprintf(stderr, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p3); + exit(1); +#endif + } + } else { + /* boot.cat is in the root directory */ + this_dir = root; + p2 = p1; + } + + /* + * make a directory entry in memory (using the same set up as for table + * entries + */ + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = this_dir->contents; + this_dir->contents = s_entry; + +#ifdef SORTING + /* inherit any sort weight from parent directory */ + s_entry->sort = this_dir->sort; + s_entry->sort += 2; + + /* see if this entry should have a new weighting */ + if (do_sort) { + s_entry->sort = sort_matches(bootcat_path, s_entry->sort); + } +#endif /* SORTING */ + + s_entry->isorec.flags[0] = ISO_FILE; + s_entry->priority = 32768; + iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); + s_entry->inode = TABLE_INODE; + s_entry->dev = (dev_t) UNCACHED_DEVICE; + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733((char *) s_entry->isorec.size, SECTOR_SIZE); + s_entry->size = SECTOR_SIZE; + s_entry->filedir = this_dir; + s_entry->name = strdup(p2); + iso9660_file_length(p2, s_entry, 0); + + /* flag file as necessary */ + + /* + * If the current directory is hidden, then hide this entry + */ + if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) + bcat_de_flags |= INHIBIT_ISO9660_ENTRY; + if (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) + bcat_de_flags |= INHIBIT_JOLIET_ENTRY; + + s_entry->de_flags = bcat_de_flags; + + if ((use_XA || use_RockRidge) && + !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) { + fstatbuf.st_mode = 0444 | S_IFREG; + fstatbuf.st_nlink = 1; + generate_xa_rr_attributes("", + p2, s_entry, + &fstatbuf, &fstatbuf, 0); + } + /* + * memory files are stored at s_entry->table + * - but this is also used for each s_entry to generate + * TRANS.TBL entries. So if we are generating tables, + * store the TRANS.TBL data here for the moment + */ + if (generate_tables && !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) { + sprintf(buffer, "F\t%s\n", s_entry->name); + + /* copy the TRANS.TBL entry info and clear the buffer */ + s_entry->table = strdup(buffer); + memset(buffer, 0, SECTOR_SIZE); + + /* + * store the (empty) file data in the + * unused s_entry->whole_name element for the time being + * - this will be transferred to s_entry->table after any + * TRANS.TBL processing later + */ + s_entry->whole_name = buffer; + } else { + /* store the (empty) file data in the s_entry->table element */ + s_entry->table = buffer; + s_entry->whole_name = NULL; + } +} + +static void +get_torito_desc(struct eltorito_boot_descriptor *boot_desc) +{ + int checksum; + unsigned char *checksum_ptr; + struct directory_entry *de2; /* Boot catalog */ + int i; + int offset; + struct eltorito_defaultboot_entry boot_desc_record; + + memset(boot_desc, 0, sizeof (*boot_desc)); + boot_desc->type[0] = 0; + memcpy(boot_desc->id, ISO_STANDARD_ID, sizeof (ISO_STANDARD_ID)); + boot_desc->version[0] = 1; + + memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof (EL_TORITO_ID)); + + /* + * search from root of iso fs to find boot catalog + * - we already know where the boot catalog is + * - we created it above - but lets search for it anyway + * - good sanity check! + */ + de2 = search_tree_file(root, boot_catalog); + if (!de2 || !(de2->de_flags & MEMORY_FILE)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I cant find the boot catalog '%s'!\n", + boot_catalog); +#else + fprintf(stderr, "Uh oh, I cant find the boot catalog '%s'!\n", + boot_catalog); + exit(1); +#endif + } + set_731(boot_desc->bootcat_ptr, + (unsigned int) get_733(de2->isorec.extent)); + + /* + * we have the boot image, so write boot catalog information + * Next we write out the primary descriptor for the disc + */ + memset(&valid_desc, 0, sizeof (valid_desc)); + valid_desc.headerid[0] = 1; + valid_desc.arch[0] = EL_TORITO_ARCH_x86; + + /* + * we'll shove start of publisher id into id field, + * may get truncated but who really reads this stuff! + */ + if (publisher) + memcpy_max(valid_desc.id, publisher, + MIN(23, strlen(publisher))); + + valid_desc.key1[0] = (char) 0x55; + valid_desc.key2[0] = (char) 0xAA; + + /* compute the checksum */ + checksum = 0; + checksum_ptr = (unsigned char *) &valid_desc; + /* Set checksum to 0 before computing checksum */ + set_721(valid_desc.cksum, 0); + for (i = 0; i < (int)sizeof (valid_desc); i += 2) { + checksum += (unsigned int) checksum_ptr[i]; + checksum += ((unsigned int) checksum_ptr[i + 1]) * 256; + } + + /* now find out the real checksum */ + checksum = -checksum; + set_721(valid_desc.cksum, (unsigned int) checksum); + + /* now write it to the virtual boot catalog */ + memcpy(de2->table, &valid_desc, 32); + + for (current_boot_entry = first_boot_entry, offset = sizeof (valid_desc); + current_boot_entry != NULL; + current_boot_entry = current_boot_entry->next, + offset += sizeof (boot_desc_record)) { + + if (offset >= SECTOR_SIZE) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Too many El Torito boot entries\n"); +#else + fprintf(stderr, + "Too many El Torito boot entries\n"); + exit(1); +#endif + } + fill_boot_desc(&boot_desc_record, current_boot_entry); + memcpy(de2->table + offset, &boot_desc_record, + sizeof (boot_desc_record)); + } +}/* get_torito_desc(... */ + +static void +fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry, + struct eltorito_boot_entry_info *boot_entry) +{ + struct directory_entry *de; /* Boot file */ + int bootmbr; + int i; + int nsectors; + int geosec; + + if (!boot_desc_entry || !boot_entry) + return; + + /* now adjust boot catalog lets find boot image first */ + de = search_tree_file(root, boot_entry->boot_image); + if (!de) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I cant find the boot image '%s' !\n", + boot_entry->boot_image); +#else + fprintf(stderr, "Uh oh, I cant find the boot image '%s' !\n", + boot_entry->boot_image); + exit(1); +#endif + } + /* now make the initial/default entry for boot catalog */ + memset(boot_desc_entry, 0, sizeof (*boot_desc_entry)); + boot_desc_entry->boot_id[0] = (char) boot_entry->not_bootable ? + EL_TORITO_NOT_BOOTABLE : EL_TORITO_BOOTABLE; + + /* use default BIOS loadpnt */ + set_721(boot_desc_entry->loadseg, boot_entry->load_addr); + + /* + * figure out size of boot image in 512-byte sectors. + * However, round up to the nearest integral CD (2048-byte) sector. + * This is only used for no-emulation booting. + */ + nsectors = boot_entry->load_size ? boot_entry->load_size : + ISO_BLOCKS(de->size) * (SECTOR_SIZE/512); + + if (verbose > 0) { + fprintf(stderr, + "Size of boot image is %d sectors -> ", nsectors); + } + + if (boot_entry->hard_disk_boot) { + /* sanity test hard disk boot image */ + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_HD; + if (verbose > 0) + fprintf(stderr, "Emulating a hard disk\n"); + + /* read MBR */ + bootmbr = open(de->whole_name, O_RDONLY | O_BINARY); + if (bootmbr == -1) { +#ifdef USE_LIBSCHILY + comerr("Error opening boot image '%s' for read.\n", + de->whole_name); +#else + fprintf(stderr, + "Error opening boot image '%s' for read.\n", + de->whole_name); + perror(""); + exit(1); +#endif + } + if (read(bootmbr, &disk_mbr, sizeof (disk_mbr)) != + sizeof (disk_mbr)) { +#ifdef USE_LIBSCHILY + comerr("Error reading MBR from boot image '%s'.\n", + de->whole_name); +#else + fprintf(stderr, + "Error reading MBR from boot image '%s'.\n", + de->whole_name); + exit(1); +#endif + } + close(bootmbr); + if (la_to_u_2_byte(disk_mbr.magic) != MBR_MAGIC) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: boot image '%s' MBR is not a boot sector.\n", + de->whole_name); +#else + fprintf(stderr, + "Warning: boot image '%s' MBR is not a boot sector.\n", + de->whole_name); +#endif + } + /* find partition type */ + boot_desc_entry->sys_type[0] = PARTITION_UNUSED; + for (i = 0; i < PARTITION_COUNT; ++i) { + int s_cyl_sec; + int e_cyl_sec; + + s_cyl_sec = + la_to_u_2_byte(disk_mbr.partition[i].s_cyl_sec); + e_cyl_sec = + la_to_u_2_byte(disk_mbr.partition[i].e_cyl_sec); + + if (disk_mbr.partition[i].type != PARTITION_UNUSED) { + if (boot_desc_entry->sys_type[0] != + PARTITION_UNUSED) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image '%s' has multiple partitions.\n", + de->whole_name); +#else + fprintf(stderr, + "Boot image '%s' has multiple partitions.\n", + de->whole_name); + exit(1); +#endif + } + boot_desc_entry->sys_type[0] = + disk_mbr.partition[i].type; + + /* a few simple sanity warnings */ + if (!boot_entry->not_bootable && + disk_mbr.partition[i].status != + PARTITION_ACTIVE) { + fprintf(stderr, + "Warning: partition not marked active.\n"); + } + if (MBR_CYLINDER(s_cyl_sec) != 0 || + disk_mbr.partition[i].s_head != 1 || + MBR_SECTOR(s_cyl_sec != 1)) { + fprintf(stderr, + "Warning: partition does not start at 0/1/1.\n"); + } + geosec = (MBR_CYLINDER(e_cyl_sec) + 1) * + (disk_mbr.partition[i].e_head + 1) * + MBR_SECTOR(e_cyl_sec); + if (geosec != nsectors) { + fprintf(stderr, + "Warning: image size does not match geometry (%d)\n", + geosec); + } +#ifdef DEBUG_TORITO + fprintf(stderr, "Partition start %u/%u/%u\n", + MBR_CYLINDER(s_cyl_sec), + disk_mbr.partition[i].s_head, + MBR_SECTOR(s_cyl_sec)); + fprintf(stderr, "Partition end %u/%u/%u\n", + MBR_CYLINDER(e_cyl_sec), + disk_mbr.partition[i].e_head, + MBR_SECTOR(e_cyl_sec)); +#endif + } + } + if (boot_desc_entry->sys_type[0] == PARTITION_UNUSED) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image '%s' has no partitions.\n", + de->whole_name); +#else + fprintf(stderr, + "Boot image '%s' has no partitions.\n", + de->whole_name); + exit(1); +#endif + } +#ifdef DEBUG_TORITO + fprintf(stderr, "Partition type %u\n", + boot_desc_entry->sys_type[0]); +#endif + /* load single boot sector, in this case the MBR */ + nsectors = 1; + + } else if (boot_entry->no_emul_boot) { + /* + * no emulation is a simple image boot of all the sectors + * in the boot image + */ + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_NOEMUL; + if (verbose > 0) + fprintf(stderr, "No emulation\n"); + + } else { + /* choose size of emulated floppy based on boot image size */ + if (nsectors == 2880) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_144FLOP; + if (verbose > 0) + fprintf(stderr, "Emulating a 1440 kB floppy\n"); + + } else if (nsectors == 5760) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_288FLOP; + if (verbose > 0) + fprintf(stderr, "Emulating a 2880 kB floppy\n"); + + } else if (nsectors == 2400) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_12FLOP; + if (verbose > 0) + fprintf(stderr, "Emulating a 1200 kB floppy\n"); + + } else { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Error - boot image '%s' has not an allowable size.\n", + de->whole_name); +#else + fprintf(stderr, + "Error - boot image '%s' has not an allowable size.\n", + de->whole_name); + exit(1); +#endif + } + + /* load single boot sector for floppies */ + nsectors = 1; + } + + /* fill in boot image details */ +#ifdef DEBUG_TORITO + fprintf(stderr, "Boot %u sectors\n", nsectors); + fprintf(stderr, "Extent of boot images is %d\n", + get_733(de->isorec.extent)); +#endif + set_721(boot_desc_entry->nsect, (unsigned int) nsectors); + set_731(boot_desc_entry->bootoff, + (unsigned int) get_733(de->isorec.extent)); + + + /* If the user has asked for it, patch the boot image */ + if (boot_entry->boot_info_table) { + int bootimage; + unsigned int bi_checksum; + unsigned int total_len; + static char csum_buffer[SECTOR_SIZE]; + int len; + struct genisoimage_boot_info bi_table; + bootimage = open(de->whole_name, O_RDWR | O_BINARY); + if (bootimage == -1) { +#ifdef USE_LIBSCHILY + comerr( + "Error opening boot image file '%s' for update.\n", + de->whole_name); +#else + fprintf(stderr, + "Error opening boot image file '%s' for update.\n", + de->whole_name); + perror(""); + exit(1); +#endif + } + /* Compute checksum of boot image, sans 64 bytes */ + total_len = 0; + bi_checksum = 0; + while ((len = read(bootimage, csum_buffer, SECTOR_SIZE)) > 0) { + if (total_len & 3) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Odd alignment at non-end-of-file in boot image '%s'.\n", + de->whole_name); +#else + fprintf(stderr, + "Odd alignment at non-end-of-file in boot image '%s'.\n", + de->whole_name); + exit(1); +#endif + } + if (total_len < 64) + memset(csum_buffer, 0, 64 - total_len); + if (len < SECTOR_SIZE) + memset(csum_buffer + len, 0, SECTOR_SIZE-len); + for (i = 0; i < SECTOR_SIZE; i += 4) + bi_checksum += get_731(&csum_buffer[i]); + total_len += len; + } + + if (total_len != de->size) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image file '%s' changed underneath us!\n", + de->whole_name); +#else + fprintf(stderr, + "Boot image file '%s' changed underneath us!\n", + de->whole_name); + exit(1); +#endif + } + /* End of file, set position to byte 8 */ + lseek(bootimage, (off_t)8, SEEK_SET); + memset(&bi_table, 0, sizeof (bi_table)); + /* Is it always safe to assume PVD is at session_start+16? */ + set_731(bi_table.bi_pvd, session_start + 16); + set_731(bi_table.bi_file, de->starting_block); + set_731(bi_table.bi_length, de->size); + set_731(bi_table.bi_csum, bi_checksum); + + write(bootimage, &bi_table, sizeof (bi_table)); /* FIXME: check return value */ + close(bootimage); + } +}/* fill_boot_desc(... */ + +void +get_boot_entry() +{ + if (current_boot_entry) + return; + + current_boot_entry = (struct eltorito_boot_entry_info *) + e_malloc(sizeof (struct eltorito_boot_entry_info)); + memset(current_boot_entry, 0, sizeof (*current_boot_entry)); + + if (!first_boot_entry) { + first_boot_entry = current_boot_entry; + last_boot_entry = current_boot_entry; + } else { + last_boot_entry->next = current_boot_entry; + last_boot_entry = current_boot_entry; + } +} + +void +new_boot_entry() +{ + current_boot_entry = NULL; +} + +/* + * Function to write the EVD for the disc. + */ +static int +tvd_write(FILE *outfile) +{ + /* check the boot image is not NULL */ + if (!boot_image) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "No boot image specified.\n"); +#else + fprintf(stderr, "No boot image specified.\n"); + exit(1); +#endif + } + /* Next we write out the boot volume descriptor for the disc */ + get_torito_desc(&gboot_desc); + jtwrite(&gboot_desc, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(&gboot_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write, "Eltorito Volume Descriptor"}; diff --git a/genisoimage/endian.c b/genisoimage/endian.c new file mode 100644 index 0000000..461e65c --- /dev/null +++ b/genisoimage/endian.c @@ -0,0 +1,177 @@ +/* + * endian.c + * + * Copyright (c) 2004-2006 Steve McIntyre <steve@einval.com> + * + * Simple helper routines for marshalling data + * + * GNU GPL v2 + */ + +#include <mconfig.h> +#include "endianconv.h" + +/* Write a 64-bit quantity out into memory in BIG ENDIAN order */ +void write_be64(unsigned long long in, unsigned char *out) +{ + out[0] = (in >> 56) & 0xFF; + out[1] = (in >> 48) & 0xFF; + out[2] = (in >> 40) & 0xFF; + out[3] = (in >> 32) & 0xFF; + out[4] = (in >> 24) & 0xFF; + out[5] = (in >> 16) & 0xFF; + out[6] = (in >> 8) & 0xFF; + out[7] = in & 0xFF; +} + +/* Read in a 64-bit BIG ENDIAN quantity */ +unsigned long long read_be64(unsigned char *in) +{ + unsigned long long result = 0; + + result |= (unsigned long long)in[0] << 56; + result |= (unsigned long long)in[1] << 48; + result |= (unsigned long long)in[2] << 40; + result |= (unsigned long long)in[3] << 32; + result |= (unsigned long long)in[4] << 24; + result |= (unsigned long long)in[5] << 16; + result |= (unsigned long long)in[6] << 8; + result |= (unsigned long long)in[7]; + + return result; +} + +/* Write a 64-bit quantity out into memory in LITTLE ENDIAN order */ +void write_le64(unsigned long long in, unsigned char *out) +{ + out[0] = in & 0xFF; + out[1] = (in >> 8) & 0xFF; + out[2] = (in >> 16) & 0xFF; + out[3] = (in >> 24) & 0xFF; + out[4] = (in >> 32) & 0xFF; + out[5] = (in >> 40) & 0xFF; + out[6] = (in >> 48) & 0xFF; + out[7] = (in >> 56) & 0xFF; +} + +/* Read in a 64-bit LITTLE ENDIAN quantity */ +unsigned long long read_le64(unsigned char *in) +{ + unsigned long long result = 0; + + result |= (unsigned long long)in[0]; + result |= (unsigned long long)in[1] << 8; + result |= (unsigned long long)in[2] << 16; + result |= (unsigned long long)in[3] << 24; + result |= (unsigned long long)in[4] << 32; + result |= (unsigned long long)in[5] << 40; + result |= (unsigned long long)in[6] << 48; + result |= (unsigned long long)in[7] << 56; + + return result; +} + +/* Write a 48-bit quantity out into memory in LITTLE ENDIAN order */ +void write_le48(unsigned long long in, unsigned char *out) +{ + out[0] = in & 0xFF; + out[1] = (in >> 8) & 0xFF; + out[2] = (in >> 16) & 0xFF; + out[3] = (in >> 24) & 0xFF; + out[4] = (in >> 32) & 0xFF; + out[5] = (in >> 40) & 0xFF; +} + +/* Read in a 48-bit LITTLE ENDIAN quantity */ +unsigned long long read_le48(unsigned char *in) +{ + unsigned long long result = 0; + + result |= (unsigned long long)in[0]; + result |= (unsigned long long)in[1] << 8; + result |= (unsigned long long)in[2] << 16; + result |= (unsigned long long)in[3] << 24; + result |= (unsigned long long)in[4] << 32; + result |= (unsigned long long)in[5] << 40; + + return result; +} + +/* Write a 32-bit quantity out into memory in BIG ENDIAN order */ +void write_be32(unsigned long in, unsigned char *out) +{ + out[0] = (in >> 24) & 0xFF; + out[1] = (in >> 16) & 0xFF; + out[2] = (in >> 8) & 0xFF; + out[3] = in & 0xFF; +} + +/* Read in a 32-bit BIG ENDIAN quantity */ +unsigned long read_be32(unsigned char *in) +{ + unsigned long result = 0; + + result |= (unsigned long)in[0] << 24; + result |= (unsigned long)in[1] << 16; + result |= (unsigned long)in[2] << 8; + result |= (unsigned long)in[3]; + + return result; +} + +/* Write a 32-bit quantity out into memory in LITTLE ENDIAN order */ +void write_le32(unsigned long in, unsigned char *out) +{ + out[0] = in & 0xFF; + out[1] = (in >> 8) & 0xFF; + out[2] = (in >> 16) & 0xFF; + out[3] = (in >> 24) & 0xFF; +} + +/* Read in a 32-bit LITTLE ENDIAN quantity */ +unsigned long read_le32(unsigned char *in) +{ + unsigned long result = 0; + + result |= (unsigned long)in[0]; + result |= (unsigned long)in[1] << 8; + result |= (unsigned long)in[2] << 16; + result |= (unsigned long)in[3] << 24; + + return result; +} + +/* Write a 16-bit quantity out into memory in BIG ENDIAN order */ +void write_be16(unsigned short in, unsigned char *out) +{ + out[0] = (in >> 8) & 0xFF; + out[1] = in & 0xFF; +} + +/* Read in a 16-bit BIG ENDIAN quantity */ +unsigned short read_be16(unsigned char *in) +{ + unsigned short result = 0; + + result |= (unsigned short)in[0] << 8; + result |= (unsigned short)in[1]; + return result; +} + +/* Write a 16-bit quantity out into memory in LITTLE ENDIAN order */ +void write_le16(unsigned short in, unsigned char *out) +{ + out[0] = in & 0xFF; + out[1] = in & 0xFF >> 8; +} + +/* Read in a 16-bit LITTLE ENDIAN quantity */ +unsigned short read_le16(unsigned char *in) +{ + unsigned short result = 0; + + result |= (unsigned short)in[0]; + result |= (unsigned short)in[1] << 8; + return result; +} + diff --git a/genisoimage/endianconv.h b/genisoimage/endianconv.h new file mode 100644 index 0000000..2337cf9 --- /dev/null +++ b/genisoimage/endianconv.h @@ -0,0 +1,27 @@ +/* + * endian_conv.h + * + * Copyright (c) 2004-2006 Steve McIntyre <steve@einval.com> + * + * Simple helper routines for marshalling data - prototypes + * + * GNU GPL v2 + */ + +void write_be64(unsigned long long in, unsigned char *out); +unsigned long long read_be64(unsigned char *in); +void write_le64(unsigned long long in, unsigned char *out); +unsigned long long read_le64(unsigned char *in); + +void write_le48(unsigned long long in, unsigned char *out); +unsigned long long read_le48(unsigned char *in); + +void write_be32(unsigned long in, unsigned char *out); +unsigned long read_be32(unsigned char *in); +void write_le32(unsigned long in, unsigned char *out); +unsigned long read_le32(unsigned char *in); + +void write_be16(unsigned short in, unsigned char *out); +unsigned short read_be16(unsigned char *in); +void write_le16(unsigned short in, unsigned char *out); +unsigned short read_le16(unsigned char *in); diff --git a/genisoimage/exclude.c b/genisoimage/exclude.c new file mode 100644 index 0000000..759bf35 --- /dev/null +++ b/genisoimage/exclude.c @@ -0,0 +1,78 @@ +/* + * 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. + * + */ + +/* @(#)exclude.c 1.9 04/03/04 joerg */ +/* + * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de: + * added 'exclude' option (-x) to specify pathnames NOT to be included in + * CD image. + */ + +#include <mconfig.h> +#include <stdio.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <standard.h> +#include <schily.h> + + +/* this allows for 1000 entries to be excluded ... */ +#define MAXEXCL 1000 + +static char *excl[MAXEXCL]; + +void exclude(char *fn); +int is_excluded(char *fn); + + +void +exclude(char *fn) +{ + register int i; + + for (i = 0; excl[i] && i < MAXEXCL; i++) + ; + + if (i == MAXEXCL) { + fprintf(stderr, + "Can't exclude '%s' - too many entries in table\n", + fn); + return; + } + excl[i] = (char *) malloc(strlen(fn) + 1); + if (excl[i] == NULL) { +#ifdef USE_LIBSCHILY + errmsg("Can't allocate memory for excluded filename\n"); +#else + fprintf(stderr, + "Can't allocate memory for excluded filename\n"); +#endif + return; + } + strcpy(excl[i], fn); +} + +int +is_excluded(char *fn) +{ + register int i; + + /* + * very dumb search method ... + */ + for (i = 0; excl[i] && i < MAXEXCL; i++) { + if (strcmp(excl[i], fn) == 0) { + return (1); /* found -> excluded filenmae */ + } + } + return (0); /* not found -> not excluded */ +} diff --git a/genisoimage/exclude.h b/genisoimage/exclude.h new file mode 100644 index 0000000..ca20879 --- /dev/null +++ b/genisoimage/exclude.h @@ -0,0 +1,21 @@ +/* + * 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. + * + */ + +/* @(#)exclude.h 1.3 04/03/02 eric */ +/* + * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de: + * added 'exclude' option (-x) to specify pathnames NOT to be included in + * CD image. + */ + +void exclude(char * fn); +int is_excluded(char * fn); diff --git a/genisoimage/files.c b/genisoimage/files.c new file mode 100644 index 0000000..d17a2c7 --- /dev/null +++ b/genisoimage/files.c @@ -0,0 +1,398 @@ +/* + * 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. + * + */ + +/* @(#)files.c 1.12 04/03/04 joerg */ +/* + * File files.c - Handle ADD_FILES related stuff. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <errno.h> +#include <schily.h> +#include <ctype.h> + +#ifdef ADD_FILES + +void add_one_file(char *addpath, char *path); +void add_file_list(int argc, char **argv, int ind); +void add_file(char *filename); +char *look_up_addition(char **newpath, char *path, struct dirent **de); +void nuke_duplicates(char *path, struct dirent **de); +struct dirent *readdir_add_files(char **pathp, char *path, DIR *dir); + +struct file_adds { + char *name; + struct file_adds *child; + struct file_adds *next; + int add_count; + int used; + union diru { + /* + * XXX Struct dirent is not guaranteed to be any size on a POSIX + * XXX compliant system. + * XXX We need to allocate enough space here, to allow the hacky + * XXX code in tree.c made by Ross Biro biro@yggdrasil.com + * XXX to work on operating systems other than Linux :-( + * XXX Changes made by Joerg Schilling + * XXX joerg@schily.isdn.cs.tu-berlin.de + * XXX to prevent core dumps on Solaris. + * XXX Space allocated: + * XXX 1024 bytes == NAME_MAX + * XXX + 2 bytes for directory record length + * XXX + 2*8 bytes for inode number & offset (64 for future exp) + */ + struct dirent de; + char dspace[NAME_MAX + 2 + 2 * 8]; + } du; + struct { + char *path; + char *name; + } *adds; +}; +extern struct file_adds *root_file_adds; + +/* + * FIXME(eric) - the file adding code really doesn't work very well + * at all. We should differentiate between adding directories, and adding + * single files, as adding a full directory affects how we should be + * searching for things. Ideally what we should do is make two passes + * through the local filesystem - one to figure out what trees we need + * to scan (and merge in any additions at that point), and the second to + * actually fill out each structure with the appropriate contents. + */ + +struct file_adds *root_file_adds = NULL; + +void +add_one_file(char *addpath, char *path) +{ + char *cp; + char *name; + struct file_adds *f; + struct file_adds *tmp; + + f = root_file_adds; + tmp = NULL; + + name = strrchr(addpath, PATH_SEPARATOR); + if (name == NULL) { + name = addpath; + } else { + name++; + } + + cp = strtok(addpath, SPATH_SEPARATOR); + + while (cp != NULL && strcmp(name, cp)) { + if (f == NULL) { + root_file_adds = e_malloc(sizeof (*root_file_adds)); + f = root_file_adds; + f->name = NULL; + f->child = NULL; + f->next = NULL; + f->add_count = 0; + f->adds = NULL; + f->used = 0; + } + if (f->child) { + for (tmp = f->child; tmp->next != NULL; + tmp = tmp->next) { + if (strcmp(tmp->name, cp) == 0) { + f = tmp; + goto next; + } + } + if (strcmp(tmp->name, cp) == 0) { + f = tmp; + goto next; + } + /* add a new node. */ + tmp->next = e_malloc(sizeof (*tmp->next)); + f = tmp->next; + f->name = strdup(cp); + f->child = NULL; + f->next = NULL; + f->add_count = 0; + f->adds = NULL; + f->used = 0; + } else { + /* no children. */ + f->child = e_malloc(sizeof (*f->child)); + f = f->child; + f->name = strdup(cp); + f->child = NULL; + f->next = NULL; + f->add_count = 0; + f->adds = NULL; + f->used = 0; + + } +next: + cp = strtok(NULL, SPATH_SEPARATOR); + } + /* Now f if non-null points to where we should add things */ + if (f == NULL) { + root_file_adds = e_malloc(sizeof (*root_file_adds)); + f = root_file_adds; + f->name = NULL; + f->child = NULL; + f->next = NULL; + f->add_count = 0; + f->adds = NULL; + } + /* Now f really points to where we should add this name. */ + f->add_count++; + f->adds = realloc(f->adds, sizeof (*f->adds) * f->add_count); + f->adds[f->add_count - 1].path = strdup(path); + f->adds[f->add_count - 1].name = strdup(name); +} + +/* + * Function: add_file_list + * + * Purpose: Register an add-in file. + * + * Arguments: + */ +void +add_file_list(int argc, char **argv, int ind) +{ + char *ptr; + char *dup_arg; + + while (ind < argc) { + dup_arg = strdup(argv[ind]); + ptr = strchr(dup_arg, '='); + if (ptr == NULL) { + free(dup_arg); + return; + } + *ptr = 0; + ptr++; + add_one_file(dup_arg, ptr); + free(dup_arg); + ind++; + } +} + +void +add_file(char *filename) +{ + char buff[PATH_MAX]; + FILE *f; + char *ptr; + char *p2; + int count = 0; + + if (strcmp(filename, "-") == 0) { + f = stdin; + } else { + f = fopen(filename, "r"); + if (f == NULL) { +#ifdef USE_LIBSCHILY + comerr("Cannot open '%s'.\n", filename); +#else + perror("fopen"); + exit(1); +#endif + } + } + while (fgets(buff, sizeof (buff), f)) { + count++; + ptr = buff; + while (isspace(*ptr)) + ptr++; + if (*ptr == 0) + continue; + if (*ptr == '#') + continue; + + if (ptr[strlen(ptr) - 1] == '\n') + ptr[strlen(ptr) - 1] = 0; + p2 = strchr(ptr, '='); + if (p2 == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Error in file '%s' line %d: %s\n", + filename, count, buff); +#else + fprintf(stderr, "Error in file '%s' line %d: %s\n", + filename, count, buff); + exit(1); +#endif + } + *p2 = 0; + p2++; + add_one_file(ptr, p2); + } + if (f != stdin) + fclose(f); +} + +/* This function looks up additions. */ +char * +look_up_addition(char **newpath, char *path, struct dirent **de) +{ + char *dup_path; + char *cp; + struct file_adds *f; + struct file_adds *tmp = NULL; + + f = root_file_adds; + if (!f) + return (NULL); + + /* I don't trust strtok */ + dup_path = strdup(path); + + cp = strtok(dup_path, SPATH_SEPARATOR); + while (cp != NULL) { + for (tmp = f->child; tmp != NULL; tmp = tmp->next) { + if (strcmp(tmp->name, cp) == 0) + break; + } + if (tmp == NULL) { + /* no match */ + free(dup_path); + return (NULL); + } + f = tmp; + cp = strtok(NULL, SPATH_SEPARATOR); + } + free(dup_path); + + /* If nothing, then return. */ + if (tmp == NULL) { + /* no match */ + return (NULL); + } + /* looks like we found something. */ + if (tmp->used >= tmp->add_count) + return (NULL); + + *newpath = tmp->adds[tmp->used].path; + tmp->used++; + *de = &(tmp->du.de); + return (tmp->adds[tmp->used - 1].name); + +} + +/* This function looks up additions. */ +void +nuke_duplicates(char *path, struct dirent **de) +{ + char *dup_path; + char *cp; + struct file_adds *f; + struct file_adds *tmp; + + f = root_file_adds; + if (!f) + return; + + /* I don't trust strtok */ + dup_path = strdup(path); + + cp = strtok(dup_path, SPATH_SEPARATOR); + while (cp != NULL) { + for (tmp = f->child; tmp != NULL; tmp = tmp->next) { + if (strcmp(tmp->name, cp) == 0) + break; + } + if (tmp == NULL) { + /* no match */ + free(dup_path); + return; + } + f = tmp; + cp = strtok(NULL, SPATH_SEPARATOR); + } + free(dup_path); + +#if 0 + /* looks like we found something. */ + if (tmp->used >= tmp->add_count) + return; + + *newpath = tmp->adds[tmp->used].path; + tmp->used++; + *de = &(tmp->du.de); + return (tmp->adds[tmp->used - 1].name); +#endif +} + +/* + * This function lets us add files from outside the standard file tree. + * It is useful if we want to duplicate a cd, but add/replace things. + * We should note that the real path will be used for exclusions. + */ + +struct dirent * +readdir_add_files(char **pathp, char **path, DIR *dir) +{ + struct dirent *de; + + char *addpath; + char *name; + + de = readdir(dir); + if (de) { + nuke_duplicates(path, &de); + return (de); + } + name = look_up_addition(&addpath, path, &de); + + if (!name) { + return (NULL); + } + *pathp = addpath; + + /* + * Now we must create the directory entry. + * fortuneately only the name seems to matter. + */ +/* de->d_ino = -1; de->d_off = 0; de->d_reclen = strlen (name); */ + strncpy(de->d_name, name, NAME_MAX); + de->d_name[NAME_MAX] = 0; + nuke_duplicates(path, &de); + return (de); + +} + +#else +struct dirent * +readdir_add_files(char **pathp, char *path, DIR *dir) +{ + return (readdir(dir)); +} + +#endif diff --git a/genisoimage/fnmatch.c b/genisoimage/fnmatch.c new file mode 100644 index 0000000..d30de89 --- /dev/null +++ b/genisoimage/fnmatch.c @@ -0,0 +1,239 @@ +/* + * 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. + * + */ + +/* @(#)fnmatch.c 1.4 02/02/10 eric */ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +NOTE: The canonical source of this file is maintained with the GNU C Library. +Bugs can be reported to bug-glibc@prep.ai.mit.edu. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <utypes.h> +#include "fnmatch.h" + +#ifndef __STDC__ +#define const +#endif + +#ifndef FNM_FILE_NAME +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#endif + +#ifndef FNM_LEADING_DIR +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#endif + +#ifndef FNM_CASEFOLD +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + + +#include <ctype.h> + +#if defined (STDC_HEADERS) || !defined (isascii) +#define ISASCII(c) 1 +#else +#define ISASCII(c) isascii(c) +#endif + +#define ISUPPER(c) (ISASCII (c) && isupper (c)) + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +fnmatch (const char *pattern, const char *string, int flags) +{ + register const char *p = pattern, *n = string; + register char c; + +/* Note that this evalutes C many times. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) + + while ((c = *p++) != '\0') + { + c = FOLD ((Uchar)c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + c = FOLD ((Uchar )c); + } + if (FOLD ((Uchar )*n) != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_FILE_NAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + c1 = FOLD ((Uchar )c1); + for (--p; *n != '\0'; ++n) + if ((c == '[' || FOLD ((Uchar )*n) == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + cstart = cend = FOLD ((Uchar)cstart); + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + c = FOLD ((Uchar)c); + + if ((flags & FNM_FILE_NAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + cend = FOLD ((Uchar)cend); + + c = *p++; + } + + if ((Uchar)FOLD((Uchar)*n) >= (Uchar)cstart && (Uchar)FOLD((Uchar)*n) <= (Uchar)cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD ((Uchar)*n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/genisoimage/fnmatch.h b/genisoimage/fnmatch.h new file mode 100644 index 0000000..ef2bbd9 --- /dev/null +++ b/genisoimage/fnmatch.h @@ -0,0 +1,101 @@ +/* + * 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. + * + */ + +/* @(#)fnmatch.h 1.4 04/03/02 eric */ +/* + * Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + * + * NOTE: The canonical source of this file is maintained with the GNU C Library. + * Bugs can be reported to bug-glibc@prep.ai.mit.edu. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)*/ +#ifdef PROTOTYPES +#undef __P +#define __P(protos) protos +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +/* + * We can get away without defining `const' here only because in this file + * it is used only inside the prototype for `fnmatch', which is elided in + * non-ANSI C where `const' is problematical. + */ +#endif /* C++ or ANSI C. */ + + +/* + * We #undef these before defining them because some losing systems + * (HP-UX A.08.07 for example) define these in <unistd.h>. + */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined(_GNU_SOURCE) +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +#ifndef FNM_FILE_NAME +/* + * Apparently GNU libc doesn't define this thing. + */ +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* + * Match STRING against the filename pattern PATTERN, + * returning zero if it matches, FNM_NOMATCH if not. + */ +extern int fnmatch(const char *__pattern, const char *__string, int __flags); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/genisoimage/genisoimage.1 b/genisoimage/genisoimage.1 new file mode 100644 index 0000000..d05b24a --- /dev/null +++ b/genisoimage/genisoimage.1 @@ -0,0 +1,2823 @@ +'\" t +.\" genisoimage.1 -*- nroff -*- To render, first run through tbl +.\" Copyright 1993-1998 by Yggdrasil Computing +.\" Copyright 1996-1997 by Robert Leslie +.\" Copyright 1997-2001 by James Pearson +.\" Copyright 1999-2006 by Joerg Schilling +.\" Copyright 2002-2003 by Jungshik Shin +.\" Copyright 2003 by Jaakko Heinonen +.\" Copyright 2006 by the Cdrkit maintainers +.\" +.TH GENISOIMAGE 1 "13 Dec 2006" +.\" ---------------------------------------- +.SH NAME +genisoimage \- create ISO9660/Joliet/HFS filesystem with optional Rock Ridge attributes +.\" ---------------------------------------- +.SH SYNOPSIS +.B genisoimage +.RI [ options ] +.RB [ \-o +.IR filename ] +.IR pathspec " [" "pathspec ..." ] +.\" ---------------------------------------- +.SH DESCRIPTION +.B genisoimage +is a pre-mastering program to generate ISO9660/Joliet/HFS hybrid +filesystems. +.PP +.B genisoimage +is capable of generating the +.B System Use Sharing Protocol records (SUSP) +specified by the +.BR "Rock Ridge Interchange Protocol" . +This is used to further describe the +files in the ISO9660 filesystem to a Unix host, and provides information such +as long filenames, UID/GID, POSIX permissions, symbolic links, and +block and character device files. +.PP +If Joliet or HFS hybrid command line options are specified, +.B genisoimage +will create the additional filesystem metadata needed for Joliet or HFS. +Otherwise +.B genisoimage +will generate a pure ISO9660 filesystem. +.PP +.B genisoimage +can generate a +.I true +(or +.IR shared ) +HFS hybrid filesystem. The same files are seen as HFS files when +accessed from a Macintosh and as ISO9660 files when accessed from other +machines. HFS stands for +.I Hierarchical File System +and is the native filesystem used on Macintosh computers. +.PP +As an alternative, +.B genisoimage +can generate the +.I Apple Extensions to ISO9660 +for each file. These extensions provide each file with CREATOR, TYPE and +certain Finder flags when accessed from a Macintosh. See the +.B HFS MACINTOSH FILE FORMATS +section below. +.PP +.B genisoimage +takes a snapshot of a given directory tree, and generates a +binary image which will correspond to an ISO9660 and/or HFS filesystem when +written to a block device. +.PP +Each file written to the ISO9660 filesystem must have a filename in the 8.3 +format (up to 8 characters, period, up to 3 characters, all uppercase), even +if Rock Ridge is in use. This filename is used on systems that are not able +to make use of the Rock Ridge extensions (such as MS-DOS), and each filename +in each directory must be different from the other filenames in the same +directory. +.B genisoimage +generally tries to form correct names by forcing the Unix filename to +uppercase and truncating as required, but often this yields unsatisfactory +results when the truncated names are not all unique. +.B genisoimage +assigns weightings to each filename, and if two names that are otherwise the +same are found, the name with the lower priority is renamed to include a +3-digit number (guaranteed to be unique). For example, the two files +.I foo.bar +and +.I foo.bar.~1~ +could be rendered as +.I FOO.BAR;1 +and +.IR FOO000.BAR;1 . +.PP +When used with various HFS options, +.B genisoimage +will attempt to recognise files stored in a number of Apple/Unix file formats +and will copy the data and resource forks as well as any +relevant Finder information. See the +.B HFS MACINTOSH FILE FORMATS +section below for more about formats +.B genisoimage +supports. +.PP +Note that +.B genisoimage +is not designed to communicate with the writer directly. Most writers +have proprietary command sets which vary from one manufacturer to +another, and you need a specialized tool to actually burn the disc. +.B wodim +is one such tool. The latest version of +.B wodim +is available from +.IR http://www.cdrkit.org/ . +.PP +.B pathspec +is the path of the directory tree to be copied into the ISO9660 filesystem. +Multiple paths can be specified, and +.B genisoimage +will merge the files found in all of the specified path components to +form the filesystem image. +.PP +If the option +.B \-graft\-points +has been specified, it is possible to graft the paths at points other +than the root directory, and it is possible to graft files or +directories onto the cdrom image with names different than what they +have in the source filesystem. This is easiest to illustrate with a +couple of examples. Let's start by assuming that a local file +.I ../old.lis +exists, and you wish to include it in the cdrom image. +.IP +foo/bar/=../old.lis +.PP +will include +.I old.lis +in the cdrom image at +.IR /foo/bar/old.lis , +while +.IP +foo/bar/xxx=../old.lis +.PP +will include +.I old.lis +in the cdrom image at +.IR /foo/bar/xxx . +The same sort of syntax can be used with directories as well. +.B genisoimage +will create any directories required such that the graft +points exist on the cdrom image \(em the directories do not need to +appear in one of the paths. By default, any directories that are created on +the fly like this will have permissions 0555 and appear to be owned by the +person running +.BR genisoimage . +If you wish other permissions or owners of +the intermediate directories, see +.BR \-uid ", " \-gid ", " \-dir\-mode ", " \-file\-mode " and " \-new\-dir\-mode . +.PP +.B genisoimage +will also run on Windows machines when compiled with Cygnus' cygwin +(available from +.IR http://www.cygwin.com/ ). +Therefore most references in this man page to +.I Unix +can be replaced with +.IR Win32 . +.\" ---------------------------------------- +.SH OPTIONS +.PP +Several options can be specified as defaults in a +.I .genisoimagerc +configuration file, as well as on the command line. If a parameter is +specified in both places, the setting from the command line is used. +For details on the format and possible locations of this file, see +.BR genisoimagerc (5). +.TP +.BI \-abstract " file" +Specifies the abstract filename. There is space for 37 characters. +Equivalent to +.B ABST +in the +.I .genisoimagerc +file. +.TP +.BI \-A " application_id" +Specifies a text string that will be written into the volume header. +This should describe the application that will be on the disc. There +is space for 128 characters. Equivalent to +.B APPI +in the +.I .genisoimagerc +file. +.TP +.B \-allow\-limited\-size +When processing files larger than 2GiB which cannot be easily represented in +ISO9660, add them with a shrunk visible file size to ISO9660 and with the +correct visible file size to the UDF system. The result is an inconsistent +filesystem and users need to make sure that they really use UDF rather than +ISO9660 driver to read a such disk. Implies enabling +.BR \-udf. +.TP +.B \-allow\-leading\-dots +.TP +.B \-ldots +Allow ISO9660 filenames to begin with a period. Usually, a leading dot is +replaced with an underscore in order to maintain MS-DOS compatibility. +.br +This violates the ISO9660 standard, but it happens to work on many systems. +Use with caution. +.TP +.B \-allow\-lowercase +This options allows lowercase characters to appear in ISO9660 filenames. +.br +This violates the ISO9660 standard, but it happens to work on some systems. +Use with caution. +.TP +.B \-allow\-multidot +This options allows more than one dot to appear in ISO9660 filenames. +A leading dot is not affected by this option, it +may be allowed separately using +.BR \-allow\-leading\-dots . +.br +This violates the ISO9660 standard, but it happens to work on many systems. +Use with caution. +.TP +.BI \-biblio " file" +Specifies the bibliographic filename. There is space for 37 characters. +Equivalent to +.B BIBL +in the +.I .genisoimagerc +file. +.TP +.B \-cache\-inodes +.TP +.B \-no\-cache\-inodes +Enable or disable caching inode and device numbers to find hard links +to files. If +.B genisoimage +finds a hard link (a file with multiple names), the file will also be +hard-linked on the CD, so the file contents only appear once. This +helps to save space. +.B \-cache\-inodes +is default on Unix-like operating systems, but +.B \-no\-cache\-inodes +is default on some other systems such as Cygwin, because it is not safe +to assume that inode numbers are unique on those systems. (Some +versions of Cygwin create fake inode numbers using a weak hashing +algorithm, which may produce duplicates.) If two files have the same +inode number but are not hard links to the same file, +.B genisoimage \-cache\-inodes +will not behave correctly. +.B \-no\-cache\-inodes +is safe in all situations, but in that case +.B genisoimage +cannot detect hard links, so the resulting CD image may be larger +than necessary. +.TP +.BI \-alpha\-boot " alpha_boot_image" +Specifies the path and filename of the boot image to be used when +making an Alpha/SRM bootable CD. The pathname must be relative to the +source path specified to +.BR genisoimage . +.TP +.BI \-hppa\-bootloader " hppa_bootloader_image" +Specifies the path and filename of the boot image to be used when +making an HPPA bootable CD. The pathname must be relative to the +source path specified to +.BR genisoimage . +Other options are required, at the very least a kernel filename and +a boot command line. See the +.B HPPA NOTES +section below for more information. +.TP +.BI \-hppa\-cmdline " hppa_boot_command_line" +Specifies the command line to be passed to the HPPA boot loader when +making a bootable CD. Separate the parameters with spaces or +commas. More options must be passed to +.B genisoimage, +at the very least a kernel filename and the boot loader filename. +See the +.B HPPA NOTES +section below for more information. +.TP +.BI \-hppa\-kernel\-32 " hppa_kernel_32" +.TP +.BI \-hppa\-kernel\-64 " hppa_kernel_64" +Specifies the path and filename of the 32-bit and/or 64-bit kernel images +to be used when making an HPPA bootable CD. The pathnames must be +relative to the source path specified to +.BR genisoimage . +Other options are required, at the very least the boot loader filename +and the boot command line. See the +.B HPPA NOTES +section below for more information. +.TP +.BI \-hppa\-ramdisk " hppa_ramdisk_image" +Specifies the path and filename of the ramdisk image to be used when +making an HPPA bootable CD. The pathname must be relative to the +source path specified to +.BR genisoimage . +This parameter is optional. Other options are required, at the very +least a kernel filename and the boot command line. See the +.B HPPA NOTES +section below for more information. +.TP +.BI \-mips\-boot " mips_boot_image" +Specifies the path and filename of the boot image to be used when +making an SGI/big-endian MIPS bootable CD. The pathname must be +relative to the source path specified to +.BR genisoimage . +This option may be specified several times, to store up to 15 boot +images. +.TP +.BI \-mipsel\-boot " mipsel_boot_image" +Specifies the path and filename of the boot image to be used when +making an DEC/little-endian MIPS bootable CD. The pathname must be +relative to the source path specified to +.BR genisoimage . +.TP +.BI \-B " img_sun4,img_sun4c,img_sun4m,img_sun4d,img_sun4e" +.TP +.BI \-sparc\-boot " img_sun4,img_sun4c,img_sun4m,img_sun4d,img_sun4e" +Specifies a comma-separated list of boot images that are needed to make +a bootable CD for SPARC systems. +Partition 0 is used for the ISO9660 image, the first image file is mapped +to partition 1. +The comma-separated list may have up to 7 fields, including empty fields. +This option is required to make a bootable CD for Sun SPARC systems. +If +.B \-B +or +.B \-sparc\-boot +has been specified, the first sector of the resulting image will +contain a Sun disk label. This disk label specifies slice 0 for the +ISO9660 image and slices 1 to 7 for the boot images that +have been specified with this option. Byte offsets 512 to 8191 +within each of the additional boot images must contain a primary boot +that works for the appropriate SPARC architecture. The rest of each +of the images usually contains a UFS filesystem used for the primary +kernel boot stage. +.IP +The implemented boot method is the one found with SunOS 4.x and SunOS 5.x. +However, it does not depend on SunOS internals but only on properties of +the Open Boot prom, so it should be usable for any OS for SPARC systems. +For more information also see the +.B NOTES +section below. +.IP +If the special filename +.B ... +is used, the actual and all following boot partitions are mapped to the +previous partition. If +.B genisoimage +is called with +.BI \-G " image " \-B " ..." +all boot partitions are mapped to the partition that contains the ISO9660 +filesystem image and the generic boot image that is located in the first +16 sectors of the disc is used for all architectures. +.TP +.BI \-G " generic_boot_image" +Specifies the path and filename of the generic boot image to be used when making +a generic bootable CD. The boot image will be placed on the first 16 +sectors of the CD, before the ISO9660 primary volume descriptor. +If this option is used together with +.BR \-sparc\-boot , +the Sun disk label will overlay the first 512 bytes of the generic +boot image. +.TP +.BI \-b " eltorito_boot_image" +Specifies the path and filename of the boot image to be used when making +an El Torito bootable CD for x86 PCs. The pathname must be relative to +the source path specified to +.BR genisoimage . +This option is required to make an El Torito bootable CD. +The boot image must be exactly 1200 kB, 1440 kB or 2880 kB, and +.B genisoimage +will use this size when creating the output ISO9660 filesystem. The PC +BIOS will use the image to emulate a floppy disk, so the first 512-byte +sector should contain PC boot code. This will work, for example, if +the boot image is a LILO-based boot floppy. +.IP +If the boot image is not an image of a floppy, you need to add either +.BR \-hard\-disk\-boot " or " \-no\-emul\-boot . +If the system should not boot off the emulated disk, use +.BR \-no\-boot . +.IP +If +.B \-sort +has not been specified, the boot images are sorted +with low priority (+2) to the beginning of the medium. +If you don't like this, you need to specify a sort weight of 0 for the boot images. +.TP +.B \-eltorito\-alt\-boot +Start with a new set of El Torito boot parameters. Up to 63 El Torito +boot entries may be stored on a single CD. +.TP +.BI \-hard\-disk\-boot +Specifies that the boot image used to create El Torito bootable CDs is +a hard disk image. The image must begin with a master boot +record that contains a single partition. +.TP +.BI \-no\-emul\-boot +Specifies that the boot image used to create El Torito bootable CDs is +a "no emulation" image. The system will load and execute this image without +performing any disk emulation. +.TP +.BI \-no\-boot +Specifies that the created El Torito CD should be marked as not bootable. The +system will provide an emulated drive for the image, but will boot off +a standard boot device. +.TP +.BI \-boot\-load\-seg " segment_address" +Specifies the load segment address of the boot image for no-emulation +El Torito CDs. +.TP +.BI \-boot\-load\-size " load_sectors" +Specifies the number of "virtual" (512-byte) sectors to load in +no-emulation mode. The default is to load the entire boot file. Some +BIOSes may have problems if this is not a multiple of 4. +.TP +.B \-boot\-info\-table +Specifies that a 56-byte table with information of the CD-ROM layout +will be patched in at offset 8 in the boot file. If this option is +given, the boot file is +.IR "modified in the source filesystem" , +so make a copy of this file if it cannot be easily regenerated! +See the +.B EL TORITO BOOT INFO TABLE +section for a description of this table. +.TP +.BI \-C " last_sess_start,next_sess_start" +This option is needed to create a CD Extra or the image of a second +session or a higher-level session for a multisession disc. +.B \-C +takes two numbers separated by a comma. The first is the first sector +in the last session of the disc that should be appended to. +The second number is the starting sector number of the new session. +The correct numbers may be retrieved by calling +.B wodim \-msinfo ... +If +.B \-C +is used in conjunction with +.BR \-M , +.B genisoimage +will create a filesystem image that is intended to be a continuation +of the previous session. +If +.B \-C +is used without +.BR \-M , +.B genisoimage +will create a filesystem image that is intended to be used for a second +session on a CD Extra. This is a multisession CD that holds audio data +in the first session and an ISO9660 filesystem in the second session. +.TP +.BI \-c " boot_catalog" +Specifies the path and filename of the boot catalog, which is required +for an El Torito bootable CD. The pathname must be relative to the source +path specified to +.BR genisoimage . +This file will be inserted into the output tree and not created +in the source filesystem, so be +sure the specified filename does not conflict with an existing file, or +it will be excluded. Usually a name like +.I boot.catalog +is chosen. +.IP +If +.B \-sort +has not been specified, the boot catalog sorted +with low priority (+1) to the beginning of the medium. +If you don't like this, you need to specify a sort weight of 0 for the boot catalog. +.TP +.B \-check\-oldnames +Check all filenames imported from the old session for compliance with +the ISO9660 file naming rules. +Without this option, only names longer than 31 characters are checked, +as these files are a serious violation of the ISO9660 standard. +.TP +.BI \-check\-session " file" +Check all old sessions for compliance with actual +.B genisoimage +ISO9660 file naming rules. +This is a high-level option that combines +.B \-M +.I file +.BR "\-C 0,0 \-check\-oldnames" . +For the parameter +.IR file , +see the description of +.BR \-M . +.TP +.BI \-copyright " file" +Specifies copyright information, typically a filename on the disc. +There is space for 37 characters. Equivalent to +.B COPY +in the +.I .genisoimagerc +file. +.TP +.B \-d +Do not append a period to files that do not have one. +.br +This violates the ISO9660 standard, but it happens to work on many systems. +Use with caution. +.TP +.B \-D +Do not use deep directory relocation, and instead just pack them in the +way we see them. +.br +If ISO9660:1999 has not been selected, +this violates the ISO9660 standard, but it happens to work on many systems. +Use with caution. +.TP +.BI \-dir\-mode " mode" +Overrides the mode of directories used to create the image to +.IR mode , +specified as 4 digits of permission bits as in +.BR chmod (1). +This option automatically enables Rock Ridge extensions. +.TP +.B \-dvd\-video +Generate a DVD-Video compliant UDF filesystem. This is done by sorting the +order of the content of the appropriate files and by adding padding +between the files if needed. +Note that the sorting only works if the DVD-Video filenames include uppercase +characters only. +.IP +Note that in order to get a DVD-Video compliant filesystem image, you +need to prepare a DVD-Video compliant directory tree. This requires a +directory +.B VIDEO_TS +(all caps) in the root directory of the resulting DVD, and usually +another directory +.BR AUDIO_TS . +.B VIDEO_TS +needs to include all needed files (filenames must be all caps) for a +compliant DVD-Video filesystem. +.TP +.B \-f +Follow symbolic links when generating the filesystem. When this option is not +in use, symbolic links will be entered using Rock Ridge if enabled, otherwise +they will be ignored. +.TP +.BI \-file\-mode " mode" +Overrides the mode of regular files used to create the image to +.IR mode , +specified as 4 digits of permission bits as in +.BR chmod (1). +This option automatically enables Rock Ridge extensions. +.TP +.BI \-gid " gid" +Overrides the group ID read from the source files to the value of +.IR gid . +Specifying this option automatically enables Rock Ridge extensions. +.TP +.B \-gui +Switch the behaviour for a GUI. This currently makes the output more verbose +but may have other effects in the future. +.TP +.B \-graft\-points +Allow use of graft points for filenames. If this option is used, all +filenames are checked for graft points. The filename is divided at the +first unescaped equal sign. All occurrences of `\(rs' and `=' characters +must be escaped with `\(rs' if +.B \-graft\-points +has been specified. +.TP +.BI \-hide " glob" +Hide any files matching +.IR glob , +a shell wildcard pattern, from being seen in the ISO9660 or Rock Ridge +directory. +.I glob +may match any part of the filename or path. If +.I glob +matches a directory, the contents of that directory will be hidden. +In order to match a directory name, make sure the pathname does not include +a trailing `/' character. +All the hidden files will still be written to the output CD image file. +See also +.BR \-hide\-joliet , +and +.IR README.hide . +This option may be used multiple times. +.TP +.BI \-hide\-list " file" +A file containing a list of shell wildcards to be hidden. See +.BR \-hide . +.TP +.BI \-hidden " glob" +Add the hidden (existence) ISO9660 directory attribute for files and +directories matching +.IR glob , +a shell wildcard pattern. This attribute will prevent the files from +being shown by some MS-DOS and Windows commands. +.I glob +may match any part of the filename or path. +In order to match a directory name, make sure the pathname does not include +a trailing `/' character. +This option may be used multiple times. +.TP +.BI \-hidden\-list " file" +A file containing a list of shell wildcards to get the hidden +attribute. See +.BR \-hidden . +.TP +.BI \-hide\-joliet " glob" +Hide files and directories matching +.IR glob , +a shell wildcard pattern, from being seen in the Joliet directory. +.I glob +may match any part of the filename or path. If +.I glob +matches a directory, the contents of that directory will be hidden. +In order to match a directory name, make sure the pathname does not include +a trailing `/' character. +All the hidden files will still be written to the output CD image file. +This option is usually used with +.BR \-hide . +See also +.IR README.hide . +This option may be used multiple times. +.TP +.BI \-hide\-joliet\-list " file" +A file containing a list of shell wildcards to be hidden from the +Joliet tree. See +.BR \-hide\-joliet . +.TP +.B \-hide\-joliet\-trans\-tbl +Hide the +.I TRANS.TBL +files from the Joliet tree. +These files usually don't make sense in the Joliet world as they list +the real name and the ISO9660 name which may both be different from the +Joliet name. +.TP +.B \-hide\-rr\-moved +Rename the directory +.I RR_MOVED +to +.I .rr_moved +in the Rock Ridge tree. +It seems to be impossible to completely hide the +.I RR_MOVED +directory from the Rock Ridge tree. +This option only makes the visible tree less confusing for +people who don't know what this directory is for. +If you need to have no +.I RR_MOVED +directory at all, you should use +.BR \-D . +Note that if +.B \-D +has been specified, the resulting filesystem is not ISO9660 +level-1 compliant and will not be readable on MS-DOS. +See also the +.B NOTES +section. +.TP +.BI \-input\-charset " charset" +Input charset that defines the characters used in local filenames. +To get a list of valid charset names, call +.BR "genisoimage \-input\-charset help" . +To get a 1:1 mapping, you may use +.B default +as charset name. The default initial values are +.I cp437 +on DOS-based systems and +.I iso8859-1 +on all other systems. See the +.B CHARACTER SETS +section below for more details. +.TP +.BI \-output\-charset " charset" +Output charset that defines the characters that will be used in Rock Ridge +filenames. Defaults to the input charset. See +.B CHARACTER SETS +section below for more details. +.TP +.BI \-iso\-level " level" +Set the ISO9660 conformance level. Valid numbers are 1 to 4. +.IP +With level 1, files may only consist of one section and filenames are +restricted to 8.3 characters. +.IP +With level 2, files may only consist of one section. +.IP +With level 3, no restrictions (other than ISO-9660:1988) do apply. +.IP +With all ISO9660 levels from 1 to 3, all filenames are restricted to +uppercase letters, numbers and underscores (_). Filenames are +limited to 31 characters, directory nesting is limited to 8 +levels, and pathnames are limited to 255 characters. +.IP +Level 4 officially does not exist but +.B genisoimage +maps it to ISO-9660:1999, which is ISO9660 version 2. +.IP +With level 4, an enhanced volume descriptor with version number +and file structure version number set to 2 is emitted. +Directory nesting is not limited to 8 levels, +there is no need for a file to contain a dot and the dot has no +special meaning, filenames do not have version numbers, +.\" (f XXX ??? The character used for filling byte positions which are +.\" specified to be characters is subject to agreement between the +.\" originator and the recipient of the volume), +and filenames can be up to 207 characters long, or 197 characters if +Rock Ridge is used. +.IP +When creating Version 2 images, +.B genisoimage +emits an enhanced volume descriptor, similar but not identical to a +primary volume descriptor. Be careful not to use broken software +to make ISO9660 images bootable by assuming a second PVD copy and patching +this putative PVD copy into an El Torito VD. +.TP +.B \-J +Generate Joliet directory records in addition to regular ISO9660 +filenames. This is primarily useful when the discs are to be used on +Windows machines. Joliet filenames are specified in Unicode and each +path component can be up to 64 Unicode characters long. +Note that Joliet is not a standard \(em only Microsoft Windows and Linux +systems can read Joliet extensions. For greater portability, consider +using both Joliet and Rock Ridge extensions. +.TP +.B \-joliet\-long +Allow Joliet filenames to be up to 103 Unicode characters, instead of +64. This breaks the Joliet specification, but appears to work. Use +with caution. +.\" The number 103 is derived from: the maximum Directory Record Length +.\" (254), minus the length of Directory Record (33), minus CD-ROM XA +.\" System Use Extension Information (14), divided by the UTF-16 +.\" character size (2). +.TP +.BI \-jcharset " charset" +A combination of +.B \-J \-input\-charset +.IR charset . +See the +.B CHARACTER SETS +section below for more details. +.TP +.B \-l +Allow full 31-character filenames. Normally the ISO9660 filename will be in an +8.3 format which is compatible with MS-DOS, even though the ISO9660 standard +allows filenames of up to 31 characters. If you use this option, the disc may +be difficult to use on a MS-DOS system, but will work on most other systems. +Use with caution. +.TP +.B \-L +Outdated option; use +.B \-allow\-leading\-dots +instead. +.TP +.BI \-jigdo\-jigdo " jigdo_file" +Produce a +.B jigdo +.I .jigdo +metadata file as well as the filesystem image. See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-jigdo\-template " template_file" +Produce a +.B jigdo +.I .template +file as well as the filesystem image. See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-jigdo\-min\-file\-size " size" +Specify the minimum size for a file to be listed in the +.I .jigdo +file. Default (and minimum allowed) is 1KB. See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-jigdo\-force\-md5 " path" +Specify a file pattern where files +.I must +be contained in the externally-supplied MD5 list as supplied by +.BR \-md5\-list . +See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-jigdo\-exclude " path" +Specify a file pattern where files will not be listed in the +.I .jigdo +file. See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-jigdo\-map " path" +Specify a pattern mapping for the jigdo file +(e.g. +.IR Debian=/mirror/debian ). +See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-md5\-list " md5_file" +Specify a file containing the MD5sums, sizes and pathnames of the +files to be included in the +.I .jigdo +file. See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-jigdo\-template\-compress " algorithm +Specify a compression algorithm to use for template date. gzip and +bzip2 are currently supported, and gzip is the default. See the +.B JIGDO NOTES +section below for more information. +.TP +.BI \-log\-file " log_file" +Redirect all error, warning and informational messages to +.I log_file +instead of the standard error. +.TP +.BI \-m " glob" +Exclude files matching +.IR glob , +a shell wildcard pattern, from being written to CD-ROM. +.I glob +may match either the filename component or the full pathname. +This option may be used multiple times. For example: +.sp + genisoimage \-o rom \-m \(aq*.o\(aq \-m core \-m foobar +.sp +would exclude all files ending in `.o', or called +.IR core " or " foobar +from the image. Note that if you had a directory called +.IR foobar , +it too (and of course all its descendants) would be excluded. +.TP +.BI \-exclude\-list " file" +A file containing a list of shell wildcards to be excluded. See +.BR \-m . +.TP +.B \-max\-iso9660\-filenames +Allow ISO9660 filenames to be up to 37 characters long. +This option enables +.B \-N +as the extra name space is taken from the space reserved for +file version numbers. +.br +This violates the ISO9660 standard, but it happens to work on many systems. +Although a conforming application needs to provide a buffer space of at +least 37 characters, discs created with this option may cause a buffer +overflow in the reading operating system. Use with extreme care. +.TP +.BI \-M " path" +.TP +.BI \-M " device" +.TP +.BI \-dev " device" +Specifies path to existing ISO9660 image to be merged. The alternate form +takes a SCSI device specifier that uses the same syntax as the +.B dev= +parameter of +.BR wodim . +The output of +.B genisoimage +will be a new session which should get written to the end of the +image specified in +.BR \-M . +Typically this requires multisession capability for the CD recorder +used to write the image. This option may only be used in conjunction +with +.BR \-C . +.TP +.B \-N +Omit version numbers from ISO9660 filenames. +.br +This violates the ISO9660 standard, but no one really uses the +version numbers anyway. Use with caution. +.TP +.BI \-new\-dir\-mode " mode" +Specify the mode, a 4-digit number as used in +.BR chmod (1), +to use when creating new directories in the filesystem image. The +default is 0555. +.TP +.B \-nobak +.TP +.B \-no\-bak +Exclude backup files files on the ISO9660 filesystem; that is, +filenames that contain the characters `~' or `#' or end in +.IR .bak . +These are typically backup files for Unix text editors. +.TP +.B \-force\-rr +Do not use the automatic Rock Ridge attributes recognition for previous sessions. +This can work around problems with images created by, e.g., NERO Burning ROM. +.TP +.B \-no\-rr +Do not use the Rock Ridge attributes from previous sessions. +This may help to avoid problems when +.B genisoimage +finds illegal Rock Ridge signatures on an old session. +.TP +.B \-no\-split\-symlink\-components +Don't split the symlink components, but begin a new Continuation Area (CE) +instead. This may waste some space, but the SunOS 4.1.4 cdrom driver +has a bug in reading split symlink components. +.IP +It is questionable whether this option is useful nowadays. +.TP +.B \-no\-split\-symlink\-fields +Don't split the symlink fields, but begin a new Continuation Area (CE) +instead. This may waste some space, but the SunOS 4.1.4 and +Solaris 2.5.1 cdrom driver have a bug in reading split symlink fields +(a `/' can be dropped). +.IP +It is questionable whether this option is useful nowadays. +.TP +.BI \-o " filename" +Specify the output file for the the ISO9660 filesystem image. +This can be a disk file, a tape drive, or it can correspond directly +to the device name of the optical disc writer. If not specified, stdout is +used. Note that the output can also be a block device for a regular +disk partition, in which case the ISO9660 filesystem can be mounted +normally to verify that it was generated correctly. +.TP +.B \-pad +Pad the end of the whole image by 150 sectors (300 kB). This option is +enabled by default. If used in combination with +.BR \-B , +padding is inserted between the ISO9660 partition and the boot +partitions, such that the first boot partition starts +on a sector number that is a multiple of 16. +.IP +The padding is needed as many operating systems (e.g. Linux) +implement read-ahead bugs in their filesystem I/O. These bugs result in read +errors on files that are located near the end of a track, particularly +if the disc is written in Track At Once mode, or where a CD audio track +follows the data track. +.\" XXX: Someone should check to see if the Linux readahead bug is +.\" XXX: still present, and update this comment accordingly. +.TP +.B \-no\-pad +Do not pad the end by 150 sectors (300 kB) and do not make the the boot partitions +start on a multiple of 16 sectors. +.TP +.BI \-path\-list " file" +A file containing a list of +.I pathspec +directories and filenames to be added to the ISO9660 filesystem. This list +of pathspecs are processed after any that appear on the command line. If the +argument is +.IR \- , +the list is read from the standard input. +.TP +.B \-P +Outdated option; use +.B \-publisher +instead. +.TP +.BI \-publisher " publisher_id" +Specifies a text string that will be written into the volume header. +This should describe the publisher of the CD-ROM, usually with a +mailing address and phone number. There is space for 128 characters. +Equivalent to +.B PUBL +in the +.I .genisoimagerc +file. +.TP +.BI \-p " preparer_id" +Specifies a text string that will be written into the volume header. +This should describe the preparer of the CD-ROM, usually with a mailing +address and phone number. There is space for 128 characters. +Equivalent to +.B PREP +in the +.I .genisoimagerc +file. +.TP +.B \-print\-size +Print estimated filesystem size in multiples of the sector size (2048 bytes) +and exit. This option is needed for +Disk At Once mode and with some CD-R drives when piping directly into +.BR wodim , +cases where +.B wodim +needs to know the size of the filesystem image in advance. +Old versions of +.B mkisofs +wrote this information (among other information) to +.IR stderr . +As this turns out to be hard to parse, the number without any other information +is now printed on +.I stdout +too. +If you like to write a simple shell script, redirect +.I stderr +and catch the number from +.IR stdout . +This may be done with: +.sp + cdblocks=\` genisoimage \-print\-size \-quiet .\|.\|. \` +.br + genisoimage .\|.\|. | wodim .\|.\|. tsize=${cdblocks}s \- +.TP +.B \-quiet +This makes +.B genisoimage +even less verbose. No progress output will be provided. +.TP +.B \-R +Generate SUSP and RR records using the Rock Ridge protocol to further describe +the files on the ISO9660 filesystem. +.TP +.B \-r +This is like the \-R option, but file ownership and modes are set to +more useful values. The uid and gid are set to zero, because they are +usually only useful on the author's system, and not useful to the +client. All the file read bits are set true, so that files and +directories are globally readable on the client. If any execute bit is +set for a file, set all of the execute bits, so that executables are +globally executable on the client. If any search bit is set for a +directory, set all of the search bits, so that directories are globally +searchable on the client. All write bits are cleared, because the +filesystem will be mounted read-only in any case. If any of the special +mode bits are set, clear them, because file locks are not useful on a +read-only filesystem, and set-id bits are not desirable for uid 0 or +gid 0. +When used on Win32, the execute bit is set on +.I all +files. This is a result of the lack of file permissions on Win32 and the +Cygwin POSIX emulation layer. See also +.BR \-uid ", " \-gid , +.BR \-dir\-mode ", " \-file\-mode +and +.BR \-new\-dir\-mode . +.TP +.B \-relaxed\-filenames +Allows ISO9660 filenames to include all 7-bit ASCII characters except +lowercase letters. +.br +This violates the ISO9660 standard, but it happens to work on many systems. +Use with caution. +.TP +.BI \-root " dir" +Moves all files and directories into +.I dir +in the image. This is essentially the +same as using +.B \-graft\-points +and adding +.I dir +in front of every pathspec, but is easier to use. +.I dir +may actually be several levels deep. It is +created with the same permissions as other graft points. +.TP +.BI \-old-root " dir" +This option is necessary when writing a multisession +image and the previous (or even older) session was written with +.B -root +.IR dir . +Using a directory name not found in the previous session +causes +.B genisoimage +to abort with an error. +Without this option, +.B genisoimage +would not be able to find unmodified files and would +be forced to write their data into the image once more. +.B \-root +and +.B \-old-root +are meant to be used together to do incremental backups. +The initial session would e.g. use: +.B genisoimage \-root backup_1 +.IR dirs . +The next incremental backup with +.B genisoimage \-root backup_2 \-old-root backup_1 +.I dirs +would take another snapshot of these directories. The first +snapshot would be found in +.BR backup_1 , +the second one in +.BR backup_2 , +but only modified or new files need to be written +into the second session. +Without these options, new files would be added and old ones would be +preserved. But old ones would be overwritten if the file was +modified. Recovering the files by copying the whole directory back +from CD would also restore files that were deleted +intentionally. Accessing several older versions of a file requires +support by the operating system to choose which sessions are to be +mounted. +.TP +.BI \-sort " sort_file" +Sort file locations on the media. Sorting is controlled by a file that +contains pairs of filenames and sorting offset weighting. +If the weighting is higher, the file will be located closer to the +beginning of the media, if the weighting is lower, the file will be located +closer to the end of the media. There must be only one space or tabs +character between the filename and the +weight and the weight must be the last characters on a line. The filename +is taken to include all the characters up to, but not including the last +space or tab character on a line. This is to allow for space characters to +be in, or at the end of a filename. +This option does +.B not +sort the order of the filenames that appear +in the ISO9660 directory. It sorts the order in which the file data is +written to the CD image, which is useful in order to optimize the +data layout on a CD. See +.B README.sort +for more details. +.TP +.BI \-sparc\-boot " img_sun4,img_sun4c,img_sun4m,img_sun4d,img_sun4e" +See +.B \-B +above. +.TP +.BI \-sparc\-label " label" +Set the Sun disk label name for the Sun disk label that is created with +.BR \-sparc-boot . +.TP +.B \-split\-output +Split the output image into several files of approximately 1 GB each. +This helps to create DVD-sized ISO9660 images on operating systems without +large file support. +.B wodim +will concatenate more than one file into a single track if writing to a DVD. +To make +.B \-split\-output +work, +.BI \-o " filename" +must be specified. The resulting output images will be named: +.IR filename_00 ", " filename_01 ", " filename_02 .... +.TP +.BI \-stream\-media\-size " #" +Select streaming operation and set the media size to # sectors. +This allows you to pipe the output of the +.BR tar (1) +program into +.B genisoimage +and to create an ISO9660 filesystem without the need of an intermediate +tar archive file. +If this option has been specified, +.B genisoimage +reads from +.I stdin +and creates a file with the name +.IR STREAM.IMG . +The maximum size of the file (with padding) is 200 sectors less than the +specified media size. If +.B \-no\-pad +has been specified, the file size is 50 sectors less than the specified media size. +If the file is smaller, +.B genisoimage +will write padding. This may take awhile. +.IP +The option +.B \-stream\-media\-size +creates simple ISO9660 filesystems only and may not used together with multisession +or hybrid filesystem options. +.TP +.BI \-stream\-file\-name " name" +Reserved for future use. +.TP +.BI \-sunx86\-boot " UFS_img,,,AUX1_img" +Specifies a comma-separated list of filesystem images that are needed to make +a bootable CD for Solaris x86 systems. +.IP +Note that partition 1 is used for the ISO9660 image and that partition 2 is +the whole disk, so partition 1 and 2 may not be used by external partition data. +The first image file is mapped to partition 0. +There may be empty fields in the comma-separated list, +and list entries for partition 1 and 2 must be empty. +The maximum number of supported partitions is 8 (although the Solaris x86 +partition table could support up to 16 partitions), so it is impossible +to specify more than 6 partition images. +This option is required to make a bootable CD for Solaris x86 systems. +.IP +If +.B \-sunx86\-boot +has been specified, the first sector of the resulting image will +contain a PC fdisk label with a Solaris type 0x82 fdisk partition that +starts at offset 512 and spans the whole CD. +In addition, for the Solaris type 0x82 fdisk partition, there is a +SVr4 disk label at offset 1024 in the first sector of the CD. +This disk label specifies slice 0 for the first (usually UFS type) +filesystem image that is used to boot the PC and slice 1 for +the ISO9660 image. +Slice 2 spans the whole CD slice 3 .\|.\|. slice 7 may be used for additional +filesystem images that have been specified with this option. +.IP +A Solaris x86 boot CD uses a 1024 byte sized primary boot that uses the +.B El-Torito no-emulation +boot mode and a secondary generic boot that is in CD sectors 1\|.\|.15. +For this reason, both +.BI "-b " bootimage " \-no\-emul\-boot" +and +.BI \-G " genboot" +must be specified. +.TP +.BI \-sunx86\-label " label" +Set the SVr4 disk label name for the SVr4 disk label that is created with +.BR \-sunx86-boot . +.TP +.BI \-sysid " ID" +Specifies the system ID. There is space for 32 characters. +Equivalent to +.B SYSI +in the +.I .genisoimagerc +file. +.TP +.B \-T +Generate a file +.I TRANS.TBL +in each directory on the CD-ROM, which can be used +on non-Rock\ Ridge-capable systems to help establish the correct filenames. +There is also information present in the file that indicates the major and +minor numbers for block and character devices, and each symlink has the name of +the link file given. +.TP +.BI \-table\-name " table_name" +Alternative translation table filename (see above). Implies +.BR \-T . +If you are creating a multisession image you must use the same name +as in the previous session. +.TP +.BI \-ucs\-level " level" +Set Unicode conformance level in the Joliet SVD. The default level is 3. +It may be set to 1..3 using this option. +.TP +.B \-udf +Include UDF filesystem support in the generated filesystem image. UDF +support is currently in alpha status and for this reason, it is not +possible to create UDF-only images. UDF data structures are currently +coupled to the Joliet structures, so there are many pitfalls with the +current implementation. There is no UID/GID support, there is no POSIX +permission support, there is no support for symlinks. Note that UDF +wastes the space from sector ~20 to sector 256 at the beginning of the +disc in addition to the space needed for real UDF data structures. +.TP +.BI \-uid " uid" +Overrides the uid read from the source files to the value of +.IR uid . +Specifying this option automatically enables Rock Ridge extensions. +.TP +.B \-use\-fileversion +The option +.B \-use\-fileversion +allows +.B genisoimage +to use file version numbers from the filesystem. +If the option is not specified, +.B genisoimage +creates a version number of 1 for all files. +File versions are strings in the range +.I ;1 +to +.I ;32767 +This option is the default on VMS. +.TP +.B \-U +Allows "untranslated" filenames, completely violating the ISO9660 standards +described above. Enables the following flags: +.B \-d \-l \-N \-allow\-leading\-dots \-relaxed\-filenames +.BR "\-allow\-lowercase \-allow\-multidot \-no\-iso\-translate" . +Allows more than one `.' character in the filename, as well as +mixed-case filenames. This is useful on HP-UX, where the built-in +.I cdfs +filesystem does not recognize any extensions. Use with extreme caution. +.TP +.B \-no\-iso\-translate +Do not translate the characters `#' and `~' which are invalid for ISO9660 filenames. +Although invalid, these characters are often used by Microsoft systems. +.br +This violates the ISO9660 standard, but it happens to work on many systems. +Use with caution. +.TP +.BI \-V " volid" +Specifies the volume ID (volume name or label) to be written into the +master block. There is space for 32 characters. Equivalent to +.B VOLI +in the +.I .genisoimagerc +file. The volume ID is used as the mount point by the Solaris volume +manager and as a label assigned to a disc on various other platforms +such as Windows and Apple Mac OS. +.TP +.BI \-volset " ID" +Specifies the volume set ID. There is space for 128 characters. +Equivalent to +.B VOLS +in the +.I .genisoimagerc +file. +.TP +.BI \-volset\-size " #" +Sets the volume set size to #. +The volume set size is the number of CDs that are in a CD volume set. +A volume set is a collection of one or more volumes, on which a set of +files is recorded. +.IP +Volume Sets are not intended to be used to create a set numbered CDs +that are part of e.g. a Operation System installation set of CDs. +Volume Sets are rather used to record a big directory tree that would not +fit on a single volume. +Each volume of a Volume Set contains a description of all the directories +and files that are recorded on the volumes where the sequence numbers +are less than, or equal to, the assigned Volume Set Size of the current +volume. +.IP +.B genisoimage +currently does not support a +.B \-volset\-size +that is larger than 1. +.IP +The option +.B \-volset\-size +must be specified before +.B \-volset\-seqno +on each command line. +.TP +.BI \-volset\-seqno " #" +Sets the volume set sequence number to #. +The volume set sequence number is the index number of the current +CD in a CD set. +The option +.B \-volset\-size +must be specified before +.B \-volset\-seqno +on each command line. +.TP +.B \-v +Verbose execution. If given twice on the command line, extra debug information +will be printed. +.TP +.BI \-x " glob" +Identical to +.B \-m +.IR glob . +.TP +.B \-z +Generate special +.I RRIP +records for transparently compressed files. +This is only of use and interest for hosts that support transparent +decompression, such as Linux 2.4.14 or later. You must specify +.BR \-R " or " \-r +to enable Rock Ridge, and generate compressed files using the +.B mkzftree +utility before running +.BR genisoimage . +Note that transparent compression is a nonstandard Rock Ridge extension. +The resulting disks are only transparently readable if used on Linux. +On other operating systems you will need to call +.B mkzftree +by hand to decompress the files. +.\" ---------------------------------------- +.SH "HFS OPTIONS" +.TP +.B \-hfs +Create an ISO9660/HFS hybrid CD. This option should be used in conjunction +with the +.BR \-map , +.B \-magic +and/or the various +.I double dash +options given below. +.TP +.B \-apple +Create an ISO9660 CD with Apple's extensions. Similar to +.BR \-hfs , +except that the Apple Extensions to ISO9660 are added instead of +creating an HFS hybrid volume. +Former +.B genisoimage +versions did include Rock Ridge attributes by default if +.B \-apple +was specified. This versions of +.B genisoimage +does not do this anymore. If you like to have Rock Ridge attributes, +you need to specify this separately. +.TP +.BI \-map " mapping_file" +Use the +.I mapping_file +to set the CREATOR and TYPE information for a file based on the +filename's extension. A filename is +mapped only if it is not one of the know Apple/Unix file formats. See the +.B HFS CREATOR/TYPE +section below. +.TP +.BI \-magic " magic_file" +The CREATOR and TYPE information is set by using a file's +.I magic number +(usually the first few bytes of a file). The +.I magic_file +is only used if a file is not one of the known Apple/Unix file formats, or +the filename extension has not been mapped using +.BR \-map . +See the +.B HFS CREATOR/TYPE +section below for more details. +.TP +.BI \-hfs\-creator " creator" +Set the default CREATOR for all files. Must be exactly 4 characters. See the +.B HFS CREATOR/TYPE +section below for more details. +.TP +.BI \-hfs\-type " type" +Set the default TYPE for all files. Must be exactly 4 characters. See the +.B HFS CREATOR/TYPE +section below for more details. +.TP +.B \-probe +Search the contents of files for all the known Apple/Unix file formats. +See the +.B HFS MACINTOSH FILE FORMATS +section below for more about these formats. +However, the only way to check for +.I MacBinary +and +.I AppleSingle +files is to open and read them, so this option may +increase processing time. It is better to use one or more +.I double dash +options given below if the Apple/Unix formats in use are known. +.TP +.B \-no\-desktop +Do not create (empty) Desktop files. New HFS Desktop files will be created +when the CD is used on a Macintosh (and stored in the System Folder). +By default, empty Desktop files are added to the HFS volume. +.TP +.B \-mac\-name +Use the HFS filename as the starting point for the ISO9660, Joliet and +Rock Ridge filenames. See the +.B HFS MACINTOSH FILENAMES +section below for more information. +.TP +.BI \-boot\-hfs\-file " driver_file" +Installs the +.I driver_file +that +.I may +make the CD bootable on a Macintosh. See the +.B HFS BOOT DRIVER +section below. (Alpha). +.TP +.B \-part +Generate an HFS partition table. By default, no partition table is generated, +but some older Macintosh CD-ROM drivers need an HFS partition table on the +CD-ROM to be able to recognize a hybrid CD-ROM. +.TP +.BI \-auto " AutoStart_file" +Make the HFS CD use the QuickTime 2.0 Autostart feature to launch an +application or document. The given filename must be the name of a document or +application located at the top level of the CD. The filename must be less +than 12 characters. (Alpha). +.TP +.BI \-cluster\-size " size" +Set the size in bytes of the cluster or allocation units of PC Exchange +files. Implies +.BR \-\-exchange . +See the +.B HFS MACINTOSH FILE FORMATS +section below. +.TP +.BI \-hide\-hfs " glob" +Hide +.IR glob , +a shell wildcard pattern, from the HFS volume. The file or directory +will still exist in the ISO9660 and/or Joliet directory. +.I glob +may match any part of the filename. Multiple globs may be excluded. +Example: +.sp + genisoimage \-o rom \-hfs \-hide\-hfs \(aq*.o\(aq \-hide\-hfs foobar +.sp +would exclude all files ending in `.o' or called +.I foobar +from the HFS volume. Note that if you had a directory called +.IR foobar , +it too (and of course all its descendants) would be excluded. The +.I glob +can also be a path name relative to the source directories given on the +command line. Example: +.sp + genisoimage \-o rom \-hfs \-hide\-hfs src/html src +.sp +would exclude just the file or directory called +.I html +from the +.I src +directory. Any other file or directory called +.I html +in the tree will not be excluded. Should be used with +.B \-hide +and/or +.BR \-hide\-joliet . +In order to match a directory name, make sure the pattern does not +include a trailing `/' character. See +.I README.hide +for more details. +.TP +.BI \-hide\-hfs\-list " file" +Specify a file containing a list of wildcard patterns to be hidden as in +.BR \-hide\-hfs . +.TP +.BI \-hfs\-volid " hfs_volid" +Volume name for the HFS partition. This is the name that is +assigned to the disc on a Macintosh and replaces the +.I volid +used with +.BR \-V . +.TP +.B \-icon\-position +Use the icon position information, if it exists, from the Apple/Unix file. +The icons will appear in the same position as they would on a Macintosh +desktop. Folder location and size on screen, its scroll positions, folder +View (view as Icons, Small Icons, etc.) are also preserved. +.\" This option may become set by default in the future. +(Alpha). +.TP +.BI \-root\-info " file" +Set the location, size on screen, scroll positions, folder View etc. for the +root folder of an HFS volume. See +.I README.rootinfo +for more information. (Alpha) +.TP +.BI \-prep\-boot " file" +PReP boot image file. Up to 4 are allowed. See +.I README.prep_boot +for more information. (Alpha) +.TP +.BI \-chrp\-boot +Add CHRP boot header. +.TP +.BI \-input\-hfs\-charset " charset" +Input charset that defines the characters used in HFS filenames when +used with +.BR \-mac\-name . +The default charset is +.I cp10000 +(Mac Roman). See the +.B CHARACTER SETS +and +.B HFS MACINTOSH FILENAMES +sections below for more details. +.TP +.BI \-output\-hfs\-charset " charset" +Output charset that defines the characters that will be used in the HFS +filenames. Defaults to the input charset. See the +.B CHARACTER SETS +section below for more details. +.TP +.B \-hfs\-unlock +By default, +.B genisoimage +will create an HFS volume that is locked. +This option leaves the volume unlocked so that other applications (e.g. +.BR hfsutils ) +can modify the volume. See the +.B HFS PROBLEMS/LIMITATIONS +section below for warnings about using this option. +.TP +.BI \-hfs\-bless " folder_name" +"Bless" the given directory (folder). This is usually the +.I System Folder +and is used in creating HFS bootable CDs. The name of the directory must +be the whole path name as +.B genisoimage +sees it. E.g., if the given pathspec is +.I ./cddata +and the required folder is called +.IR "System Folder" , +the whole path name is +.I \(dq/cddata/System Folder\(dq +(remember to use quotes if the name contains spaces). +.TP +.BI \-hfs\-parms " parameters" +Override certain parameters used to create the HFS filesystem. Unlikely to +be used in normal circumstances. See the +.I libhfs_iso/hybrid.h +source file for details. +.TP +.B \-\-cap +Look for AUFS CAP Macintosh files. Search for CAP Apple/Unix file formats +only. Searching for the other possible Apple/Unix file formats is disabled, +unless other +.I double dash +options are given. +.TP +.B \-\-netatalk +Look for NETATALK Macintosh files +.TP +.B \-\-double +Look for AppleDouble Macintosh files +.TP +.B \-\-ethershare +Look for Helios EtherShare Macintosh files +.TP +.B \-\-ushare +Look for IPT UShare Macintosh files +.TP +.B \-\-exchange +Look for PC Exchange Macintosh files +.TP +.B \-\-sgi +Look for SGI Macintosh files +.TP +.B \-\-xinet +Look for XINET Macintosh files +.TP +.B \-\-macbin +Look for MacBinary Macintosh files +.TP +.B \-\-single +Look for AppleSingle Macintosh files +.TP +.B \-\-dave +Look for Thursby Software Systems DAVE Macintosh files +.TP +.B \-\-sfm +Look for Microsoft's Services for Macintosh files (NT only) (Alpha) +.TP +.B \-\-osx\-double +Look for Mac OS X AppleDouble Macintosh files +.TP +.B \-\-osx\-hfs +Look for Mac OS X HFS Macintosh files +.\" ---------------------------------------- +.SH "CHARACTER SETS" +.B genisoimage +processes filenames in a POSIX-compliant way as strings of 8-bit characters. +To represent all codings for all languages, 8-bit characters are not +sufficient. Unicode or ISO-10646 +define character codings that need at least 21 bits to represent all +known languages. They may be represented with +.IR UTF-32 ", " UTF-16 " or " UTF-8 +coding. UTF-32 uses a plain 32-bit coding but seems to be uncommon. +UTF-16 is used by Microsoft with Win32 with the disadvantage that +16-bit characters are not compliant with the POSIX filesystem +interface. +.PP +Modern Unix operating systems may use UTF-8 coding for filenames. +Each 32-bit character is represented by one or more 8-bit characters. +If a character is coded in +.I ISO-8859-1 +(used in Central Europe and North America) is maps 1:1 to a +UTF-32 or UTF-16 coded Unicode character. +If a character is coded in +.I 7-Bit ASCII +(used in USA and other countries with limited character set) +is maps 1:1 to a UTF-32, UTF-16 or UTF-8 coded Unicode character. +Character codes that cannot be represented as a single byte in UTF-8 +(if the value is > 0x7F) use escape sequences that map to more than +one 8-bit character. +.PP +If all operating systems used UTF-8, +.B genisoimage +would not need to recode characters in filenames. +Unfortunately, Apple uses completely nonstandard codings and Microsoft +uses a Unicode coding that is not compatible with the POSIX filename +interface. +.PP +For all non-UTF-8-coded operating systems, the actual character +that each byte represents depends on the +.I character set +or +.I codepage +(the name used by Microsoft) +used by the local operating system \(em the characters in a character +set will reflect the region or natural language set by the user. +.PP +Usually character codes 0x00-0x1f are control characters, codes 0x20-0x7f +are the 7-bit ASCII characters and (on PCs and Macs) 0x80-0xff are used +for other characters. +.PP +As there are a lot more than 256 characters/symbols in use, only a small +subset are represented in a character set. Therefore the same character code +may represent a different character in different character sets. So a filename +generated, say in central Europe, may not display the same character +when viewed on a machine in, say eastern Europe. +.PP +To make matters more complicated, different operating systems use +different character sets for the region or language. For example, the +character code for `\('e' (small e with acute accent) +may be character code 0x82 on a PC, +code 0x8e on a Macintosh, code 0xe9 on a Unix system in western Europe, +and code 0x000e9 in Unicode. +.PP +As long as not all operating systems and applications use the same +character set as the basis for filenames, it may be +necessary to specify which character set your filenames use in and which +character set the filenames should appear on the CD. +.PP +There are four options to specify the character sets you want to use: +.TP +.B \-input\-charset +Defines the local character set you are using on your host machine. +Any character set conversions that take place will use this character +set as the starting point. The default input character sets are +.I cp437 +on MS-DOS-based systems and +.I iso8859-1 +on all other systems. If +.B \-J +is given, the Unicode equivalents of the input character set +will be used in the Joliet directory. +.B \-jcharset +is the same as +.BR "\-input\-charset \-J" . +.TP +.B \-output\-charset +Defines the character set that will be used with for the Rock Ridge names +on the CD. Defaults to the input character set. +.TP +.B \-input\-hfs\-charset +Defines the HFS character set used for HFS filenames decoded from +any of the various Apple/Unix file formats. Only useful when used with +.BR \-mac\-name . +See the +.B HFS MACINTOSH FILENAMES +for more information. Defaults to +.I cp10000 +(Mac Roman). +.TP +.B \-output\-hfs\-charset +Defines the HFS character set used to create HFS filenames from the input +character set in use. In most cases this will be from the character set +given with +.BR \-input\-charset . +Defaults to the input HFS character set. +.PP +There are a number of character sets built in to +.BR genisoimage . +To get a listing, use +.BR "\-input\-charset help" . +This list doesn't include the charset derived from the current locale, +if +.B genisoimage +is built with +.I iconv +support. +.PP +Additional character sets can be read from file for any of the character +set options by giving a filename as the argument to the options. The given +file will only be read if its name does not match one of the built-in +character sets. +.PP +The format of the character set files is the same as the mapping files +available from +.IR http://www.unicode.org/Public/MAPPINGS . +This format is: +.IP +Column #1 is the input byte code (in hex as 0xXX) +.br +Column #2 is the Unicode (in hex as 0xXXXX) +.br +The rest of the line is ignored. +.PP +Any blank line, line without two (or more) columns in the above format +or comments lines (starting with the # character) are ignored without any +warnings. Any missing input code is mapped to Unicode character 0x0000. +.PP +Note that, while UTF-8 is supported, other Unicode encodings such as +UCS-2/UTF-16 and UCS-4/UTF-32 are not, as POSIX operating systems +cannot handle them natively. +.PP +A 1:1 character set mapping can be defined by using the keyword +.I default +as the argument to any of the character set options. This is the behaviour +of old versions of +.BR mkisofs . +.PP +The ISO9660 filenames generated from the input filenames are not converted +from the input character set. The ISO9660 character set is a very limited +subset of the ASCII characters, so any conversion would be pointless. +.PP +Any character that +.B genisoimage +cannot convert will be replaced with a `_' character. +.\" ---------------------------------------- +.SH "HFS CREATOR/TYPE" +A Macintosh file has two properties associated with it which define +which application created the file, the +.I CREATOR +and what data the file contains, the +.IR TYPE . +Both are (exactly) 4 letter strings. Usually this +allows a Macintosh user to double-click on a file and launch the correct +application etc. The CREATOR and TYPE of a particular file can be found by +using something like ResEdit (or similar) on a Macintosh. +.PP +The CREATOR and TYPE information is stored in all the various Apple/Unix +encoded files. +For other files it is possible to base the CREATOR and TYPE on the +filename's extension using a +.I mapping +file (with +.BR \-map ) +and/or using the +.I magic number +(usually a +.I signature +in the first few bytes) of a file (with +.BR \-magic ). +If both these options are given, their order on the command +line is significant. If +.B \-map +is given first, a filename extension match is attempted +before a magic number match. However, if +.B \-magic +is given first, a magic number match is attempted before a +filename extension match. +.PP +If a mapping or magic file is not used, or no match is found, the default +CREATOR and TYPE for all regular files can be set by using entries in the +.I .genisoimagerc +file or using +.B \-hfs\-creator +and/or +.BR \-hfs\-type , +otherwise the default CREATOR and TYPE are +.IR Unix " and " TEXT . +.PP +The format of the +.I mapping +file is the same +.I afpfile +format as used by +.BR aufs . +This file has five columns for the +.IR extension , +.IR "file translation" , +.IR CREATOR , +.IR TYPE " and" +.IR Comment . +Lines starting with the `#' character are +comment lines and are ignored. An example file would be like: +.PP +.TS +tab (/); +l s s s s +l s s s s +l l l l l . +# Example filename mapping file +# +# EXTN/XLate/CREATOR/TYPE/Comment +\&.tif/Raw/\(aq8BIM\(aq/\(aqTIFF\(aq/\(dqPhotoshop TIFF image\(dq +\&.hqx/Ascii/\(aqBnHq\(aq/\(aqTEXT\(aq/\(dqBinHex file\(dq +\&.doc/Raw/\(aqMSWD\(aq/\(aqWDBN\(aq/\(dqWord file\(dq +\&.mov/Raw/\(aqTVOD\(aq/\(aqMooV\(aq/\(dqQuickTime Movie\(dq +*/Ascii/\(aqttxt\(aq/\(aqTEXT\(aq/\(dqText file\(dq +.TE +.PP +Where: +.IP +The first column +.I EXTN +defines the Unix filename extension to be +mapped. The default mapping for any filename extension that doesn't +match is defined with the `*' character. +.IP +The +.I Xlate +column defines the type of text translation between the Unix and +Macintosh file it is ignored by +.BR genisoimage , +but is kept to be compatible with +.BR aufs (1). +Although +.B genisoimage +does not alter the contents of a file, if a binary file has its TYPE +set as +.IR TEXT ", it " may +be read incorrectly on a Macintosh. Therefore a better choice for the +default TYPE may be +.IR ???? . +.IP +The +.I CREATOR +and +.I TYPE +keywords must be 4 characters long and enclosed in single quotes. +.IP +The comment field is enclosed in double quotes \(em it is ignored by +.BR genisoimage , +but is kept to be compatible with +.BR aufs . +.PP +The format of the +.I magic +file is almost identical to the +.BR magic (5) +file used by the +.BR file (1) +command. +.PP +This file has four tab-separated columns for the +.IR "byte offset" , +.IR type , +.I test +and +.IR message . +Lines starting with the `#' character are +comment lines and are ignored. An example file would be like: +.PP +.TS +tab (/); +l s s s +l s s s +l l l l . +# Example magic file +# +# off/type/test/message +0/string/GIF8/8BIM GIFf GIF image +0/beshort/0xffd8/8BIM JPEG image data +0/string/SIT!/SIT! SIT! StuffIt Archive +0/string/\(rs037\(rs235/LZIV ZIVU standard Unix compress +0/string/\(rs037\(rs213/GNUz ZIVU gzip compressed data +0/string/%!/ASPS TEXT Postscript +0/string/\(rs004%!/ASPS TEXT PC Postscript with a ^D to start +4/string/moov/txtt MooV QuickTime movie file (moov) +4/string/mdat/txtt MooV QuickTime movie file (mdat) +.TE +.PP +The format of the file is described in +.BR magic (5). +The only difference here is that for each entry in the magic file, the +.I message +for the initial offset must be be 4 characters for the CREATOR followed +by 4 characters for the TYPE \(em white space is +optional between them. Any other characters on this line are ignored. +Continuation lines (starting with a `>') are also ignored, i.e., only +the initial offset lines are used. +.PP +Using +.B \-magic +may significantly increase processing time as each file has to opened +and read to find its magic number. +.PP +In summary, for all files, the default CREATOR is +.I Unix +and the default TYPE is +.IR TEXT . +These can be changed by using entries in the +.I .genisoimagerc +file or by using +.B \-hfs\-creator +and/or +.BR \-hfs\-type . +.PP +If the a file is in one of the known Apple/Unix formats (and the format +has been selected), the CREATOR and TYPE are taken from the values +stored in the Apple/Unix file. +.PP +Other files can have their CREATOR and TYPE set from their filename +extension (with +.BR \-map ), +or their magic number (with +.BR \-magic ). +If the default match is used in the +.I mapping +file, these values override the default CREATOR and TYPE. +.PP +A full CREATOR/TYPE database can be found at +.IR http://www.angelfire.com/il/szekely/ . +.\" ---------------------------------------- +.SH "HFS MACINTOSH FILE FORMATS" +Macintosh files have two parts called the +.I Data +and +.IR "Resource fork" . +Either may be empty. Unix (and many other OSs) can only +cope with files having one part (or fork). To add to this, Macintosh files +have a number of attributes associated with them \(em probably the most +important are the TYPE and CREATOR. Again, Unix has no concept of these +types of attributes. +.PP +E.g., a Macintosh file may be a JPEG image where the image is stored in the +Data fork and a desktop thumbnail stored in the Resource fork. It is usually +the information in the data fork that is useful across platforms. +.PP +Therefore to store a Macintosh file on a Unix filesystem, a way has to be +found to cope with the two forks and the extra attributes (which are +referred to as the +.IR "Finder info" ). +Unfortunately, it seems that every software package that stores Macintosh +files on Unix has chosen a completely different storage method. +.PP +The Apple/Unix formats that +.B genisoimage +(partially) supports are: +.IP "CAP AUFS format" +Data fork stored in a file. Resource fork in subdirectory +.I .resource +with same filename as data fork. Finder info in subdirectory +.I .finderinfo +with same filename. +.IP "AppleDouble/Netatalk" +Data fork stored in a file. Resource fork stored in a file with +same name prefixed with `%'. Finder info also stored in same +`%' file. Netatalk uses the same format, but the resource +fork/Finder info stored in subdirectory +.I .AppleDouble +with same filename as data fork. +.IP AppleSingle +Data structures similar to above, except both forks and Finder +info are stored in one file. +.IP "Helios EtherShare" +Data fork stored in a file. Resource fork and Finder info together in +subdirectory +.I .rsrc +with same filename as data fork. +.IP "IPT UShare" +Like the EtherShare format, but the Finder info +is stored slightly differently. +.IP MacBinary +Both forks and Finder info stored in one file. +.IP "Apple PC Exchange" +Used by Macintoshes to store Apple files on DOS (FAT) disks. +Data fork stored in a file. Resource fork in subdirectory +.IR resource.frk " (or " RESOURCE.FRK ). +Finder info as one record in file +.IR finder.dat " (or " FINDER.DAT ). +Separate +.I finder.dat +for each data fork directory. +.IP +Note: +.B genisoimage +needs to know the native FAT cluster size of the disk that the PC Exchange +files are on (or have been copied from). This size is given by +.BR \-cluster\-size . +The cluster or allocation size can be found by using the DOS utility +.BR chkdsk . +.IP +May not work with PC Exchange v2.2 or higher files (available with MacOS 8.1). +DOS media containing PC Exchange files should be mounted as type +.I msdos +(not +.IR vfat ) +when using Linux. +.IP SGI/XINET +Used by SGI machines when they mount HFS disks. Data fork stored +in a file. Resource fork in subdirectory +.I .HSResource +with same filename. Finder info as one record in file +.IR .HSancillary ". Separate " .HSancillary +for each data fork directory. +.IP "Thursby Software Systems DAVE" +Allows Macintoshes to store Apple files on SMB servers. +Data fork stored in a file. Resource fork in subdirectory +.IR resource.frk . +Uses the AppleDouble format to store resource fork. +.IP "Services for Macintosh" +Format of files stored by NT Servers on NTFS filesystems. Data fork is +stored as +.IR filename . +Resource fork stored as a NTFS stream called +.IR filename:AFP_Resource . +The Finder info is stored as a NTFS stream called +.IR filename:Afp_AfpInfo . +NTFS streams are normally invisible to the user. +.IP +Warning: +.B genisoimage +only partially supports the SFM format. If an HFS file +or folder stored on the NT server contains an illegal +NT character in its name, NT converts these characters to +.I Private Use Unicode +characters. The characters are: \(dq * / < > ? \(rs | and a space or +period if it is the last character of the filename, character codes 0x01 +to 0x1f (control characters) and Apple's apple logo. +.IP +Unfortunately, these private Unicode characters are not readable by the +.B genisoimage +NT executable. Therefore any file or directory +name containing these characters will be ignored \(em including the contents of +any such directory. +.IP "Mac OS X AppleDouble" +When HFS/HFS+ files are copied or saved by Mac OS X on to a non-HFS +filesystem (e.g. UFS, NFS etc.), the files are stored in AppleDouble format. +Data fork stored in a file. Resource fork stored in a file with +same name prefixed with `._'. Finder info also stored in same `._' file. +.IP "Mac OS X HFS (Alpha)" +Not really an Apple/Unix encoding, but actual HFS/HFS+ files on a Mac\ OS\ X +system. Data fork stored in a file. Resource fork stored in a pseudo file +with the same name with the suffix +.IR /rsrc . +The Finder info is only available via a Mac OS X library call. +.IP +See also +.IR README.macosx . +.IP +Only works when used on Mac OS X. +.IP +If a file is found with a zero +length resource fork and empty finderinfo, it is assumed not to have +any Apple/Unix encoding \(em therefore a TYPE and CREATOR can be set using +other methods. +.PP +.B genisoimage +will attempt to set the CREATOR, TYPE, date and possibly other flags from +the finder info. Additionally, if it exists, the Macintosh filename is set +from the finder info, otherwise the Macintosh name is based on the Unix +filename \(em see the +.B HFS MACINTOSH FILENAMES +section below. +.PP +When using +.BR \-apple , +the TYPE and CREATOR are stored in the optional System Use or +.I SUSP +field +in the ISO9660 Directory Record \(em in much the same way as the Rock Ridge +attributes are. In fact to make life easy, the Apple extensions are added +at the beginning of the existing Rock Ridge attributes (i.e., to get the Apple +extensions you get the Rock Ridge extensions as well). +.PP +The Apple extensions require the resource fork to be stored as an ISO9660 +.I associated +file. This is just like any normal file stored in the ISO9660 filesystem +except that the associated file flag is set in the Directory Record (bit +2). This file has the same name as the data fork (the file seen by +non-Apple machines). Associated files are normally ignored by other OSs +.PP +When using +.BR \-hfs , +the TYPE and CREATOR plus other finder info, are stored in a separate +HFS directory, not visible on the ISO9660 volume. The HFS directory references +the same data and resource fork files described above. +.PP +In most cases, it is better to use +.B \-hfs +instead of +.BR \-apple , +as the latter imposes the limited ISO9660 characters allowed in +filenames. However, the Apple extensions do give the advantage that the +files are packed on the disk more efficiently and it may be possible to fit +more files on a CD. +.\" ---------------------------------------- +.SH "HFS MACINTOSH FILENAMES" +Where possible, the HFS filename that is stored with an Apple/Unix file +is used for the HFS part of the CD. However, not all the Apple/Unix +encodings store the HFS filename with the finderinfo. In these cases, +the Unix filename is used \(em with escaped special characters. Special +characters include `/' and characters with codes over 127. +.PP +AUFS escapes these characters by using `:' followed by the character code +as two hex digits. Netatalk and EtherShare have a similar scheme, but uses +`%' instead of a `:'. +.PP +If +.B genisoimage +cannot find an HFS filename, it uses the Unix name, with any +.IR %xx " or " :xx +characters +.RI ( xx +are two hex digits) converted to a single character code. If +.I xx +are not hex digits ([0-9a-fA-F]), they are +left alone \(em although any remaining `:' is converted to `%', as `:' +is the HFS directory separator. Care must be taken, as an ordinary Unix +file with +.I %xx +or +.I :xx +will also be converted. e.g. +.PP +.TS +l l +l s +l l +l s +l l . +This:2fFile converted to This/File + +This:File converted to This%File + +This:t7File converted to This%t7File +.TE +.PP +Although HFS filenames appear to support uppercase and lowercase letters, +the filesystem is case-insensitive, i.e., the filenames +.IR aBc " and " AbC +are the same. If a file is found in a directory with the same HFS name, +.B genisoimage +will attempt to make a unique name by adding `_' characters +to one of the filenames. +.PP +If an HFS filename exists for a file, +.B genisoimage +can use this name as the starting point for the ISO9660, Joliet and +Rock Ridge filenames using +.BR \-mac\-name . +Normal Unix files without an HFS name will still use their Unix name. +e.g. +.PP +If a MacBinary (or PC Exchange) file is stored as +.I someimage.gif.bin +on the Unix filesystem, but contains a HFS file called +.IR someimage.gif , +this is the name that would appear on the HFS part of the CD. However, as +.B genisoimage +uses the Unix name as the starting point for the other names, +the ISO9660 name generated will probably be +.I SOMEIMAG.BIN +and the Joliet/Rock Ridge would be +.IR someimage.gif.bin . +This option will use +the HFS filename as the starting point and the ISO9660 name will probably be +.I SOMEIMAG.GIF +and the Joliet/Rock Ridge would be +.IR someimage.gif . +.PP +.B \-mac\-name +will not currently work with +.B \-T +\(em the Unix name will be used in the +.I TRANS.TBL +file, not the Macintosh name. +.PP +The character set used to convert any HFS filename to a Joliet/Rock Ridge +filename defaults to +.I cp10000 +(Mac Roman). +The character set used can be specified using +.BR \-input\-hfs\-charset . +Other built-in HFS character sets are: +.I cp10006 +(MacGreek), +.I cp10007 +(MacCyrillic), +.I cp10029 +(MacLatin2), +.I cp10079 +(MacIcelandandic) and +.I cp10081 +(MacTurkish). +.PP +Note: the character codes used by HFS filenames taken from the various +Apple/Unix formats will not be converted as they are assumed to be in the +correct Apple character set. Only the Joliet/Rock Ridge names derived from +the HFS filenames will be converted. +.PP +The existing +.B genisoimage +code will filter out any illegal characters for the ISO9660 and Joliet +filenames, but as +.B genisoimage +expects to be dealing directly with Unix names, it leaves the Rock +Ridge names as is. But as `/' is a legal HFS filename character, +.B \-mac\-name +converts `/' to a `_' in Rock Ridge filenames. +.PP +If the Apple extensions are used, only the ISO9660 filenames will +appear on the Macintosh. However, as the Macintosh ISO9660 drivers can use +.I Level 2 +filenames, you can use options like +.B \-allow\-multidot +without problems on +a Macintosh \(em still take care over the names, for example +.I this.file.name +will be converted to +.I THIS.FILE +i.e. only have one `.', also filename +.I abcdefgh +will be seen as +.I ABCDEFGH +but +.I abcdefghi +will be seen as +.I ABCDEFGHI. +i.e. with a `.' at the end \(em don't know if this is a Macintosh +problem or a +.BR genisoimage / mkhybrid +problem. All filenames will be in uppercase +when viewed on a Macintosh. Of course, DOS/Win3.X machines will not be able +to see Level 2 filenames... +.\" ---------------------------------------- +.SH "HFS CUSTOM VOLUME/FOLDER ICONS" +To give a HFS CD a custom icon, make sure the root (top level) folder includes +a standard Macintosh volume icon file. To give a volume a custom icon on +a Macintosh, an icon has to be pasted over the volume's icon in the "Get Info" +box of the volume. This creates an invisible file called +.I Icon\(rsr +(`\(rsr' is the carriage return character) in the root folder. +.P +A custom folder icon is very similar \(em an invisible file called +.I Icon\(rsr +exists in the folder itself. +.P +Probably the easiest way to create a custom icon that +.B genisoimage +can use is to format a blank HFS floppy disk on a Mac and paste an icon +to its "Get Info" box. If using Linux with the HFS module installed, +mount the floppy: +.IP +mount \-t hfs /dev/fd0 /mnt/floppy +.PP +The floppy will be mounted as a CAP filesystem by default. Then run +.B genisoimage +using something like: +.IP +genisoimage \-\-cap \-o output source_dir /mnt/floppy +.PP +If you are not using Linux, you can use +.B hfsutils +to copy the icon file from the floppy. However, care has to be taken, +as the icon file contains a control character. For example: +.IP +hmount /dev/fd0 +.br +hdir \-a +.br +hcopy \-m Icon^V^M icon_dir/icon +.PP +Where `^V^M' is control-V followed by control-M. Then run +.B genisoimage +by using something like: +.IP +genisoimage \-\-macbin \-o output source_dir icon_dir +.PP +The procedure for creating/using custom folder icons is very similar \(em paste +an icon to folder's "Get Info" box and transfer the resulting +.I Icon\(rsr +file to the relevant directory in the +.B genisoimage +source tree. +.PP +You may want to hide the icon files from the ISO9660 and Joliet trees. +.PP +To give a custom icon to a Joliet CD, follow the instructions found at +.IR http://www.cdrfaq.org/faq03.html#S3-21-1 . +.\" ---------------------------------------- +.SH "HFS BOOT DRIVER" +It +.I may +be possible to make the hybrid CD bootable on a Macintosh. +.PP +A bootable HFS CD requires an Apple CD-ROM (or compatible) driver, a bootable +HFS partition and the necessary System, Finder, etc. files. +.PP +A driver can be obtained from any other Macintosh bootable CD-ROM using the +.B apple_driver +utility. This file can then be used with +.BR \-boot\-hfs\-file . +.PP +The HFS partition (i.e. the hybrid disk in our case) must contain a +suitable System Folder, again from another CD-ROM or disk. +.PP +For a partition to be bootable, it must have its +.I boot block +set. The boot +block is in the first two blocks of a partition. For a non-bootable partition +the boot block is full of zeros. Normally, when a System file is copied to +partition on a Macintosh disk, the boot block is filled with a number of +required settings \(em unfortunately I don't know the full spec for the boot +block, so I'm guessing that the following will work. +.PP +Therefore, the utility +.B apple_driver +also extracts the boot block from the +first HFS partition it finds on the given CD-ROM and this is used for the +HFS partition created by +.BR genisoimage . +.PP +.I Please note: +By using a driver from an Apple CD and copying Apple software to your CD, +you become liable to obey Apple Computer, Inc. Software License Agreements. +.\" ---------------------------------------- +.SH "EL TORITO BOOT INFORMATION TABLE" +When +.B \-boot\-info\-table +is given, +.B genisoimage +will modify the boot file specified by +.B \-b +by inserting a 56-byte +.I boot information table +at offset 8 in +the file. This modification is done in the source filesystem, so make +sure you use a copy if this file is not easily recreated! This file +contains pointers which may not be easily or reliably obtained at boot +time. +.PP +The format of this table is as follows; all integers are in +section 7.3.1 ("little endian") format. +.sp +.RS +.2i +.ta 1.0i 2.5i 3.5i +.nf +Offset Name Size Meaning + 8 bi_pvd 4 bytes LBA of primary volume descriptor +12 bi_file 4 bytes LBA of boot file +16 bi_length 4 bytes Boot file length in bytes +20 bi_csum 4 bytes 32-bit checksum +24 bi_reserved 40 bytes Reserved +.fi +.RE +.IP +The 32-bit checksum is the sum of all the 32-bit words in the boot +file starting at byte offset 64. All linear block addresses (LBAs) +are given in CD sectors (normally 2048 bytes). +.\" ---------------------------------------- +.SH "HPPA NOTES" +To make a bootable CD for HPPA, at the very least a boot loader file +.RB ( \-hppa\-bootloader ), +a kernel image file (32-bit, 64-bit, or both, depending on hardware) +and a boot command line +.RB ( \-hppa\-cmdline ) +must be specified. Some systems can boot either a 32- or a 64-bit +kernel, and the firmware will choose one if both are present. +Optionally, a ramdisk can be used for the root filesystem using +.BR \-hppa\-cmdline . +.\" ---------------------------------------- +.SH "JIGDO NOTES" +Jigdo is a tool to help in the distribution of large files like CD and +DVD images; see +.I http://atterer.org/jigdo/ +for more details. Debian CDs and DVD ISO +images are published on the web in jigdo format to allow end users to download +them more efficiently. +.PP +To create jigdo and template files alongside the ISO image from +.BR genisoimage , +you must first generate a list of the files that will be +used, in the following format: +.sp +.RS +.2i +.ta 2.0i 2.0i 5.0i +.nf +MD5sum File size Path +32 chars 12 chars to end of line +.fi +.RE +.IP +.PP +The MD5sum must be written in standard hexadecimal notation, the +file size must list the size of the file in bytes, and the path +must list the absolute path to the file. For example: +.sp +.nf +00006dcd58ff0756c36d2efae21be376 14736 /mirror/debian/file1 +000635c69b254a1be8badcec3a8d05c1 211822 /mirror/debian/file2 +00083436a3899a09633fc1026ef1e66e 22762 /mirror/debian/file3 +.fi +.PP +Once you have this file, call +.B genisoimage +with all of your normal command-line parameters. Specify the output +filenames for the jigdo and template files using +.BR \-jigdo\-jigdo " and " \-jigdo\-template , +and pass in the location of your MD5 list with +.BR \-md5\-list . +.PP +If there are files that you do NOT want to be added into the jigdo +file (e.g. if they are likely to change often), specify them using +\-jigdo\-exclude. If you want to verify some of the files as they are +written into the image, specify them using \-jigdo\-force\-md5. If any +files don't match, +.B genisoimage +will then abort. Both of these options take +regular expressions as input. It is possible to restrict the set of +files that will be used further based on size \(em use the +\-jigdo\-min\-file\-size option. +.PP +Finally, the jigdo code needs to know how to map the files it is given +onto a mirror-style configuration. Specify how to map paths using +.BR \-jigdo\-map . +Using +.I Debian=/mirror/debian +will cause all +paths starting with +.I /mirror/debian +to be mapped to +.I Debian:<file> +in the output jigdo file. +.\" ---------------------------------------- +.SH EXAMPLES +.PP +To create a vanilla ISO9660 filesystem image in the file +.IR cd.iso , +where the directory +.I cd_dir +will become the root directory of the CD, call: +.IP +% genisoimage \-o cd.iso cd_dir +.PP +To create a CD with Rock Ridge extensions of +the source directory +.IR cd_dir : +.IP +% genisoimage \-o cd.iso \-R cd_dir +.PP +To create a CD with Rock Ridge extensions of +the source directory +.I cd_dir +where all files have at least read permission and all files +are owned by +.IR root , +call: +.IP +% genisoimage \-o cd.iso \-r cd_dir +.PP +To write a tar archive directly to a CD that will later contain a simple +ISO9660 filesystem with the tar archive call: +.IP +% tar cf \- . | genisoimage \-stream\-media\-size 333000 | \(rs +.br + wodim dev=b,t,l \-dao tsize=333000s \- +.PP +To create a HFS hybrid CD with the Joliet and Rock Ridge extensions of +the source directory +.IR cd_dir : +.IP +% genisoimage \-o cd.iso \-R \-J \-hfs cd_dir +.PP +To create a HFS hybrid CD from the source directory +.I cd_dir +that contains +Netatalk Apple/Unix files: +.IP +% genisoimage \-o cd.iso \-\-netatalk cd_dir +.PP +To create a HFS hybrid CD from the source directory +.IR cd_dir , +giving all files +CREATOR and TYPES based on just their filename extensions listed in the file +"mapping".: +.IP +% genisoimage \-o cd.iso \-map mapping cd_dir +.PP +To create a CD with the Apple Extensions to ISO9660, from the source +directories +.I cd_dir +and +.IR another_dir . +Files in all the known Apple/Unix format +are decoded and any other files are given CREATOR and TYPE based on their +magic number given in the file +.IR magic : +.IP +% genisoimage \-o cd.iso \-apple \-magic magic \-probe \(rs +.br + cd_dir another_dir +.PP +The following example puts different files on the CD that all have +the name README, but have different contents when seen as a +ISO9660/Rock Ridge, Joliet or HFS CD. +.PP +Current directory contains: +.IP +% ls \-F +.br +README.hfs README.joliet README.Unix cd_dir/ +.PP +The following command puts the contents of the directory +.I cd_dir +on the +CD along with the three README files \(em but only one will be seen from +each of the three filesystems: +.IP +% genisoimage \-o cd.iso \-hfs \-J \-r \-graft\-points \(rs +.br + \-hide README.hfs \-hide README.joliet \(rs +.br + \-hide\-joliet README.hfs \-hide\-joliet README.Unix \(rs +.br + \-hide\-hfs README.joliet \-hide\-hfs README.Unix \(rs +.br + README=README.hfs README=README.joliet \(rs +.br + README=README.Unix cd_dir +.PP +i.e. the file README.hfs will be seen as README on the HFS CD and the +other two README files will be hidden. Similarly for the Joliet and +ISO9660/Rock Ridge CD. +.PP +There are probably all sorts of strange results possible with +combinations of the hide options ... +.\" ---------------------------------------- +.SH NOTES +.PP +.B genisoimage +may safely be installed suid root. This may be needed to allow +.B genisoimage +to read the previous session when creating a multisession image. +.PP +If +.B genisoimage +is creating a filesystem image with Rock Ridge attributes and the +directory nesting level of the source directory tree is too much +for ISO9660, +.B genisoimage +will do deep directory relocation. +This results in a directory called +.B RR_MOVED +in the root directory of the CD. You cannot avoid this directory. +.PP +Many boot code options for different platforms are mutualy exclusive because +the boot blocks cannot coexist, ie. different platforms share the same data +locations in the image. See +http://lists.debian.org/debian-cd/2006/12/msg00109.html for details. +.\" ---------------------------------------- +.SH BUGS +.PP +Any files that have hard links to files not in the tree being copied to the +ISO9660 filesystem will have an incorrect file reference count. +.PP +Does not check for SUSP record(s) in `.' entry of the +root directory to verify the existence of Rock Ridge +enhancements. +This problem is present when reading old sessions while +adding data in multisession mode. +.PP +Does not properly read relocated directories in multisession +mode when adding data. +Any relocated deep directory is lost if the new session does not +include the deep directory. +.\" Repeat by: create first session with deep directory relocation +.\" then add new session with a single dir that differs from the +.\" old deep path. +.PP +Does not re-use +.I RR_MOVED +when doing multisession from +.IR TRANS.TBL . +.PP +Does not create whole_name entry for +.I RR_MOVED +in multisession mode. +.PP +There may be other bugs. Please, report them to the maintainers. +.\" ---------------------------------------- +.SH "HFS PROBLEMS/LIMITATIONS" +I have had to make several assumptions on how I expect the modified +libhfs routines to work, however there may be situations that either +I haven't thought of, or come across when these assumptions fail. +Therefore I can't guarantee that +.B genisoimage +will work as expected +(although I haven't had a major problem yet). Most of the HFS features work +fine, but some are not fully tested. These are marked as +.I Alpha +above. +.PP +Although HFS filenames appear to support uppercase and lowercase letters, +the filesystem is case-insensitive, i.e., the filenames +.IR aBc " and "AbC +are the same. If a file is found in a directory with the same HFS name, +.B genisoimage +will attempt to make a unique name by adding `_' characters +to one of the filenames. +.PP +HFS file/directory names that share the first 31 characters have +`_N' (a decimal number) substituted for the last few characters +to generate unique names. +.PP +Care must be taken when "grafting" Apple/Unix files or directories (see +above for the method and syntax involved). It is not possible to use a +new name for an Apple/Unix encoded file/directory. e.g. If a Apple/Unix +encoded file called +.I oldname +is to added to the CD, you cannot use the command line: +.IP +genisoimage \-o output.raw \-hfs \-graft\-points newname=oldname cd_dir +.PP +.B genisoimage +will be unable to decode +.IR oldname . +However, you can graft +Apple/Unix encoded files or directories as long as you do not attempt to +give them new names as above. +.PP +When creating an HFS volume with the multisession options, +.B \-M +and +.BR \-C , +only files in the last session will be in the HFS volume. i.e. +.B genisoimage +cannot +.I add +existing files from previous sessions to the HFS volume. +.PP +However, if each session is created with +.BR \-part , +each session will appear as +separate volumes when mounted on a Mac. In this case, it is worth using +.BR \-V " or " \-hfs\-volid +to give each session a unique volume name, +otherwise each "volume" will appear on the Desktop with the same name. +.PP +Symbolic links (as with all other non-regular files) are not added to +the HFS directory. +.PP +Hybrid volumes may be larger than pure ISO9660 volumes +containing the same data. In some cases (e.g. DVD sized volumes) the +difference can be significant. As an HFS volume gets bigger, so does the +allocation block size (the smallest amount of space a file can occupy). +For a 650MB CD, the allocation block is 10kB, for a 4.7GB DVD it will be +about 70kB. +.PP +The maximum number of files in an HFS volume is about 65500 \(em although +the real limit will be somewhat less than this. +.PP +The resulting hybrid volume can be accessed on a Unix machine by using +the hfsutils routines. However, no changes can be made to the volume as it +is set as +.B locked. +The option +.B \-hfs\-unlock +will create an output image that is unlocked \(em however no changes should be +made to the contents of the volume (unless you really know what you are +doing) as it's not a "real" HFS volume. +.PP +.B \-mac\-name +will not currently work with +.B \-T +\(em the Unix name will be used in the +.I TRANS.TBL +file, not the Macintosh name. +.PP +Although +.B genisoimage +does not alter the contents of a file, if a binary file has its TYPE +set as +.IR TEXT ", it " may +be read incorrectly on a Macintosh. Therefore a better choice for the +default TYPE may be +.IR ???? . +.PP +.B \-mac\-boot\-file +may not work at all... +.PP +May not work with PC Exchange v2.2 or higher files (available with MacOS 8.1). +DOS media containing PC Exchange files should be mounted as type +.B msdos +(not +.BR vfat ) +when using Linux. +.PP +The SFM format is only partially supported \(em see +.B HFS MACINTOSH FILE FORMATS +section above. +.PP +It is not possible to use +.BR \-sparc\-boot " or " \-generic\-boot " with" +.BR \-boot\-hfs\-file " or " \-prep\-boot . +.PP +.B genisoimage +should be able to create HFS hybrid images over 4Gb, although this has not +been fully tested. +.\" ---------------------------------------- +.SH "SEE ALSO" +.BR genisoimagerc (5), +.BR wodim (1), +.BR mkzftree (8), +.BR magic (5). +.\" ---------------------------------------- +.SH AUTHORS +.B genisoimage +is derived from +.B mkisofs +from the +.B cdrtools 2.01.01a08 +package from May 2006 (with few updates extracted from cdrtools 2.01.01a24 from +March 2007) from .IR http://cdrecord.berlios.de/ , +but is now part of the +.B cdrkit +suite, maintained by Joerg Jaspert, Eduard Bloch, Steve McIntyre, Peter +Samuelson, Christian Fromme, Ben Hutchings, and other contributors. +The maintainers can be contacted at +.IR debburn-devel@lists.alioth.debian.org , +or see the +.B cdrkit +project web site at +.IR http://www.cdrkit.org/ . +.PP +Eric Youngdale wrote the first versions (1993\(en1998) of +.BR mkisofs . +J\(:org Schilling wrote the SCSI transport library and its +interface, and has maintained +.B mkisofs +since 1999. James Pearson wrote the HFS hybrid code, using +.I libhfs +by Robert Leslie. Pearson, Schilling, Jungshik Shin and Jaakko +Heinonen contributed to the character set conversion code. The +.B cdrkit +maintainers have maintained +.B genisoimage +since 2006. +.PP +.nf +Copyright 1993-1998 by Yggdrasil Computing, Inc. +Copyright 1996-1997 by Robert Leslie +Copyright 1997-2001 by James Pearson +Copyright 1999-2006 by J\(:org Schilling +Copyright 2007 by J\(:org Schilling (originating few updates) +Copyright 2002-2003 by Jungshik Shin +Copyright 2003 by Jaakko Heinonen +Copyright 2006 by the Cdrkit maintainers +.fi +.PP +If you want to take part in the development of +.BR genisoimage , +you may join the +.B cdrkit +developer mailing list by following the instructions on +.IR http://alioth.debian.org/mail/?group_id=31006 . +The email address of the list is +.IR debburn-devel@lists.alioth.debian.org . +This is also the address for user support questions. Note that +.BR cdrkit " and " cdrtools +are not affiliated. +.PP +.\" ---------------------------------------- +.SH ACKNOWLEDGEMENTS +UNIX is a registered trademark of The Open Group in the US and other countries. diff --git a/genisoimage/genisoimage.c b/genisoimage/genisoimage.c new file mode 100644 index 0000000..46f0cb7 --- /dev/null +++ b/genisoimage/genisoimage.c @@ -0,0 +1,3831 @@ +/* + * 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. + * + */ + +/* + * + * Patched version with stuff from the Debian's cdrtools. + * Replaced various warnings/disclaimers with more simple ones. + * + * Eduard Bloch <blade@debian.org> +*/ +/* @(#)mkisofs.c 1.167 06/01/30 joerg */ +/* Parts from @(#)mkisofs.c 1.206 07/02/26 joerg */ +/* + * Program genisoimage.c - generate iso9660 filesystem based upon directory + * tree on hard disk. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-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 as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 22/2/2000 */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <errno.h> +#include <timedefs.h> +#include <fctldefs.h> +#include <ctype.h> +#include "match.h" +#include "exclude.h" +#include <unls.h> /* For UNICODE translation */ +#include <schily.h> +#ifdef UDF +#include "udf.h" +#endif + +#ifdef NEED_O_BINARY +#include <io.h> /* for setmode() prototype */ +#endif + +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#else +#include "getopt.h" +extern int optind; +extern char *optarg; +#endif + +#ifdef VMS +#include "vms.h" +#endif + +#ifdef no_more_needed +#ifdef __NetBSD__ +#include <sys/resource.h> +#endif +#endif /* no_more_needed */ + +#ifdef USE_ICONV +#include <locale.h> +#include <langinfo.h> +#endif + +struct directory *root = NULL; +int path_ind; + +char version_string[] = "genisoimage " CDRKIT_VERSION; + +char *outfile; +FILE *discimage; +unsigned int next_extent = 0; +unsigned int last_extent = 0; +unsigned int session_start = 0; +unsigned int path_table_size = 0; +unsigned int path_table[4] = {0, }; +unsigned int path_blocks = 0; + + +unsigned int jpath_table_size = 0; +unsigned int jpath_table[4] = {0, }; +unsigned int jpath_blocks = 0; + +struct iso_directory_record root_record; +struct iso_directory_record jroot_record; + +char *extension_record = NULL; +int extension_record_extent = 0; +int extension_record_size = 0; + +/* These variables are associated with command line options */ +int check_oldnames = 0; +int check_session = 0; +int use_eltorito = 0; +int hard_disk_boot = 0; +int not_bootable = 0; +int no_emul_boot = 0; +int load_addr = 0; +int load_size = 0; +int boot_info_table = 0; +int use_alphaboot = 0; +int use_sparcboot = 0; +int use_hppaboot = 0; +int use_mipsboot = 0; +int use_mipselboot = 0; +int use_sunx86boot = 0; +int use_genboot = 0; +int use_RockRidge = 0; +int use_XA = 0; +int osecsize = 0; /* Output-sector size, 0 means default secsize 2048 */ +int use_Joliet = 0; +int jlen = JMAX; /* maximum Joliet file name length */ +int verbose = 1; +int debug = 0; +int gui = 0; +int all_files = 1; /* New default is to include all files */ +int follow_links = 0; +#ifdef IS_CYGWIN +int cache_inodes = 0; /* Do not cache inodes on Cygwin by default */ +#else +int cache_inodes = 1; /* Cache inodes if OS has unique inodes */ +#endif +int rationalize = 0; +int rationalize_uid = 0; +int rationalize_gid = 0; +int rationalize_filemode = 0; +int rationalize_dirmode = 0; +uid_t uid_to_use = 0; /* when rationalizing uid */ +gid_t gid_to_use = 0; /* when rationalizing gid */ +int filemode_to_use = 0; /* if non-zero, when rationalizing file mode */ +int dirmode_to_use = 0; /* if non-zero, when rationalizing dir mode */ +int new_dir_mode = 0555; +int generate_tables = 0; +int dopad = 1; /* Now default to do padding */ +int print_size = 0; +int split_output = 0; +char *icharset = NULL; /* input charset to convert to UNICODE */ +char *ocharset = NULL; /* output charset to convert from UNICODE */ +char *preparer = PREPARER_DEFAULT; +char *publisher = PUBLISHER_DEFAULT; +char *appid = APPID_DEFAULT; +char *copyright = COPYRIGHT_DEFAULT; +char *biblio = BIBLIO_DEFAULT; +char *abstract = ABSTRACT_DEFAULT; +char *volset_id = VOLSET_ID_DEFAULT; +char *volume_id = VOLUME_ID_DEFAULT; +char *system_id = SYSTEM_ID_DEFAULT; +char *boot_catalog = BOOT_CATALOG_DEFAULT; +char *boot_image = BOOT_IMAGE_DEFAULT; +char *genboot_image = BOOT_IMAGE_DEFAULT; +int ucs_level = 3; /* We now have Unicode tables so use level 3 */ +int volume_set_size = 1; +int volume_sequence_number = 1; + +struct eltorito_boot_entry_info *first_boot_entry = NULL; +struct eltorito_boot_entry_info *last_boot_entry = NULL; +struct eltorito_boot_entry_info *current_boot_entry = NULL; + +int use_graft_ptrs; /* Use graft points */ +int jhide_trans_tbl; /* Hide TRANS.TBL from Joliet tree */ +int hide_rr_moved; /* Name RR_MOVED .rr_moved in Rock Ridge tree */ +int omit_period = 0; /* Violates iso9660, but these are a pain */ +int transparent_compression = 0; /* So far only works with linux */ +int omit_version_number = 0; /* May violate iso9660, but noone uses vers */ +int no_rr = 0; /* Do not use RR attributes from old session */ +int force_rr = 0; /* Force to use RR attributes from old session */ +Uint RR_relocation_depth = 6; /* Violates iso9660, but most systems work */ +int iso9660_level = 1; +int iso9660_namelen = LEN_ISONAME; /* 31 characters, may be set to 37 */ +int full_iso9660_filenames = 0; /* Full 31 character iso9660 filenames */ +int relaxed_filenames = 0; /* For Amiga. Disc will not work with DOS */ +int allow_lowercase = 0; /* Allow lower case letters */ +int allow_multidot = 0; /* Allow more than on dot in filename */ +int iso_translate = 1; /* 1 == enables '#', '-' and '~' removal */ +int allow_leading_dots = 0; /* DOS cannot read names with leading dots */ +int allow_limited_size = 0; /* Let the user to allow the trick explicitely */ +#ifdef VMS +int use_fileversion = 1; /* Use file version # from filesystem */ +#else +int use_fileversion = 0; /* Use file version # from filesystem */ +#endif +int split_SL_component = 1; /* circumvent a bug in the SunOS driver */ +int split_SL_field = 1; /* circumvent a bug in the SunOS */ +char *trans_tbl = "TRANS.TBL"; /* default name for translation table */ +int stream_media_size = 0; /* # of blocks on the media */ +char *stream_filename = NULL; /* Stream file, 0 to use default STREAM.IMG */ + +#ifdef APPLE_HYB +int apple_hyb = 0; /* create HFS hybrid flag */ +int apple_ext = 0; /* create HFS extensions flag */ +int apple_both = 0; /* common flag (for above) */ +int hfs_extra = 0; /* extra HFS blocks added to end of ISO vol */ +int use_mac_name = 0; /* use Mac name for ISO/Joliet/RR flag */ +hce_mem *hce; /* libhfs/genisoimage extras */ +char *hfs_boot_file = 0; /* name of HFS boot file */ +int gen_pt = 0; /* generate HFS partition table */ +char *autoname = 0; /* AutoStart filename */ +char *magic_filename = 0; /* name of magic file */ +int probe = 0; /* search files for HFS/Unix type */ +int nomacfiles = 0; /* don't look for Mac/Unix files */ +int hfs_select = 0; /* Mac/Unix types to select */ +int create_dt = 1; /* create the Desktp files */ +int afe_size = 0; /* Apple File Exchange block size */ +int hfs_last = MAG_LAST; /* process magic file after map file */ +char *deftype = APPLE_TYPE_DEFAULT; /* default Apple TYPE */ +char *defcreator = APPLE_CREATOR_DEFAULT; /* default Apple CREATOR */ +char *hfs_volume_id = NULL; /* HFS volume ID */ +int icon_pos = 0; /* Keep icon position */ +char *hfs_icharset = NULL; /* input HFS charset name */ +char *hfs_ocharset = NULL; /* output HFS charset name */ +int hfs_lock = 1; /* lock HFS volume (read-only) */ +char *hfs_bless = NULL; /* name of folder to 'bless' (System Folder) */ +char *hfs_parms = NULL; /* low level HFS parameters */ + +#ifdef PREP_BOOT +char *prep_boot_image[4]; +int use_prep_boot = 0; +int use_chrp_boot = 0; +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +#ifdef UDF +int use_udf = 0; +#endif + +#ifdef DVD_VIDEO +int dvd_video = 0; +#endif + +#ifdef SORTING +int do_sort = 0; /* sort file data */ +#endif /* SORTING */ + +#ifdef USE_ICONV +int iconv_possible; +#endif + +struct unls_table *in_nls = NULL; /* input UNICODE conversion table */ +struct unls_table *out_nls = NULL; /* output UNICODE conversion table */ +#ifdef APPLE_HYB +struct unls_table *hfs_inls = NULL; /* input HFS UNICODE conversion table */ +struct unls_table *hfs_onls = NULL; /* output HFS UNICODE conversion table */ +#endif /* APPLE_HYB */ + +struct rcopts { + char *tag; + char **variable; +}; + +struct rcopts rcopt[] = { + {"PREP", &preparer}, + {"PUBL", &publisher}, + {"APPI", &appid}, + {"COPY", ©right}, + {"BIBL", &biblio}, + {"ABST", &abstract}, + {"VOLS", &volset_id}, + {"VOLI", &volume_id}, + {"SYSI", &system_id}, +#ifdef APPLE_HYB + {"HFS_TYPE", &deftype}, + {"HFS_CREATOR", &defcreator}, +#endif /* APPLE_HYB */ + {NULL, NULL} +}; + +char *merge_warn_msg=0; /* use as pointer and boolean */ + +/* + * In case it isn't obvious, the option handling code was ripped off + * from GNU-ld. + */ +struct ld_option { + /* The long option information. */ + struct option opt; + /* The short option with the same meaning ('\0' if none). */ + char shortopt; + /* The name of the argument (NULL if none). */ + const char *arg; + /* + * The documentation string. If this is NULL, this is a synonym for + * the previous option. + */ + const char *doc; + enum { + /* Use one dash before long option name. */ + ONE_DASH, + /* Use two dashes before long option name. */ + TWO_DASHES, + /* Don't mention this option in --help output. */ + NO_HELP + } control; +}; + +/* + * Codes used for the long options with no short synonyms. Note that all these + * values must not be ASCII or EBCDIC. + */ +#define OPTION_HELP 1000 +#define OPTION_QUIET 1001 +#define OPTION_NOSPLIT_SL_COMPONENT 1002 +#define OPTION_NOSPLIT_SL_FIELD 1003 +#define OPTION_PRINT_SIZE 1004 +#define OPTION_SPLIT_OUTPUT 1005 +#define OPTION_ABSTRACT 1006 +#define OPTION_BIBLIO 1007 +#define OPTION_COPYRIGHT 1008 +#define OPTION_SYSID 1009 +#define OPTION_VOLSET 1010 +#define OPTION_VOLSET_SIZE 1011 +#define OPTION_VOLSET_SEQ_NUM 1012 +#define OPTION_I_HIDE 1013 +#define OPTION_J_HIDE 1014 +#define OPTION_LOG_FILE 1015 +#define OPTION_PVERSION 1016 +#define OPTION_NOBAK 1017 +#define OPTION_SPARCLABEL 1018 +#define OPTION_HARD_DISK_BOOT 1019 +#define OPTION_NO_EMUL_BOOT 1020 +#define OPTION_NO_BOOT 1021 +#define OPTION_BOOT_LOAD_ADDR 1022 +#define OPTION_BOOT_LOAD_SIZE 1023 +#define OPTION_BOOT_INFO_TABLE 1024 +#define OPTION_HIDE_TRANS_TBL 1025 +#define OPTION_HIDE_RR_MOVED 1026 +#define OPTION_GUI 1027 +#define OPTION_TRANS_TBL 1028 +#define OPTION_P_LIST 1029 +#define OPTION_I_LIST 1030 +#define OPTION_J_LIST 1031 +#define OPTION_X_LIST 1032 +#define OPTION_NO_RR 1033 +#define OPTION_JCHARSET 1034 +#define OPTION_PAD 1035 +#define OPTION_H_HIDE 1036 +#define OPTION_H_LIST 1037 +#define OPTION_CHECK_OLDNAMES 1038 + +#ifdef SORTING +#define OPTION_SORT 1039 +#endif /* SORTING */ +#define OPTION_UCS_LEVEL 1040 +#define OPTION_ISO_TRANSLATE 1041 +#define OPTION_ISO_LEVEL 1042 +#define OPTION_RELAXED_FILENAMES 1043 +#define OPTION_ALLOW_LOWERCASE 1044 +#define OPTION_ALLOW_MULTIDOT 1045 +#define OPTION_USE_FILEVERSION 1046 +#define OPTION_MAX_FILENAMES 1047 +#define OPTION_ALT_BOOT 1048 +#define OPTION_USE_GRAFT 1049 + +#define OPTION_INPUT_CHARSET 1050 +#define OPTION_OUTPUT_CHARSET 1051 + +#define OPTION_NOPAD 1052 +#define OPTION_UID 1053 +#define OPTION_GID 1054 +#define OPTION_FILEMODE 1055 +#define OPTION_DIRMODE 1056 +#define OPTION_NEW_DIR_MODE 1057 +#define OPTION_CACHE_INODES 1058 +#define OPTION_NOCACHE_INODES 1059 + +#define OPTION_CHECK_SESSION 1060 +#define OPTION_FORCE_RR 1061 + +#define OPTION_DEBUG 1062 + +#define OPTION_JLONG 1063 + +#define OPTION_STREAM_FILE_NAME 1064 +#define OPTION_STREAM_CD_SIZE 1065 + +#define OPTION_XA 1066 +#define OPTION_XA_RATIONALIZED 1067 + +#define OPTION_SUNX86BOOT 1068 +#define OPTION_SUNX86LABEL 1069 + +#define OPTION_ALLOW_LEADING_DOTS 1070 +#define OPTION_PUBLISHER 1071 + +#ifdef JIGDO_TEMPLATE +#define OPTION_JTT_OUTPUT 1101 +#define OPTION_JTJ_OUTPUT 1102 +#define OPTION_JT_MIN_SIZE 1103 +#define OPTION_JT_PATH_MAP 1104 +#define OPTION_JT_MD5_LIST 1105 +#define OPTION_JT_INCLUDE 1106 +#define OPTION_JT_EXCLUDE 1107 +#define OPTION_JT_COMPRESS_ALGO 1108 + +#define OPTION_JT_CHECKSUM_ALGO_ISO 1120 +#define OPTION_JT_CHECKSUM_ALGO_TMPL 1121 +#endif + +#define OPTION_BOOTALPHA 1200 + +#define OPTION_HPPA_CMDLINE 1210 +#define OPTION_HPPA_KERNEL_32 1211 +#define OPTION_HPPA_KERNEL_64 1212 +#define OPTION_HPPA_BOOTLOADER 1213 +#define OPTION_HPPA_RAMDISK 1214 + +#define OPTION_BOOTMIPS 1220 + +#define OPTION_BOOTMIPSEL 1230 + +#ifdef UDF +#define OPTION_UDF 1500 +#endif +#ifdef DVD_VIDEO +#define OPTION_DVD 1501 +#endif + +#ifdef APPLE_HYB +#define OPTION_CAP 2000 +#define OPTION_NETA 2001 +#define OPTION_DBL 2002 +#define OPTION_ESH 2003 +#define OPTION_FE 2004 +#define OPTION_SGI 2005 +#define OPTION_MBIN 2006 +#define OPTION_SGL 2007 +/* aliases */ +#define OPTION_USH 2008 +#define OPTION_XIN 2009 + +#define OPTION_DAVE 2010 +#define OPTION_SFM 2011 +#define OPTION_XDBL 2012 +#define OPTION_XHFS 2013 + +#define OPTION_PROBE 2020 +#define OPTION_MACNAME 2021 +#define OPTION_NOMACFILES 2022 +#define OPTION_BOOT_HFS_FILE 2023 +#define OPTION_MAGIC_FILE 2024 + +#define OPTION_HFS_LIST 2025 + +#define OPTION_GEN_PT 2026 + +#define OPTION_CREATE_DT 2027 +#define OPTION_HFS_HIDE 2028 + +#define OPTION_AUTOSTART 2029 +#define OPTION_BSIZE 2030 +#define OPTION_HFS_VOLID 2031 +#define OPTION_PREP_BOOT 2032 +#define OPTION_ICON_POS 2033 + +#define OPTION_HFS_TYPE 2034 +#define OPTION_HFS_CREATOR 2035 + +#define OPTION_ROOT_INFO 2036 + +#define OPTION_HFS_INPUT_CHARSET 2037 +#define OPTION_HFS_OUTPUT_CHARSET 2038 + +#define OPTION_HFS_UNLOCK 2039 +#define OPTION_HFS_BLESS 2040 +#define OPTION_HFS_PARMS 2041 + +#define OPTION_CHRP_BOOT 2042 + +#define OPTION_RELOC_ROOT 2043 +#define OPTION_RELOC_OLD_ROOT 2044 + +#define OPTION_MAP_FILE 2045 + +#define OPTION_ALLOW_LIMITED_SIZE 2046 + +#endif /* APPLE_HYB */ + +static int save_pname = 0; + +static const struct ld_option ld_options[] = +{ + {{"nobak", no_argument, NULL, OPTION_NOBAK}, + '\0', NULL, "Do not include backup files", ONE_DASH}, + {{"no-bak", no_argument, NULL, OPTION_NOBAK}, + '\0', NULL, "Do not include backup files", ONE_DASH}, + {{"abstract", required_argument, NULL, OPTION_ABSTRACT}, + '\0', "FILE", "Set Abstract filename", ONE_DASH}, + {{"appid", required_argument, NULL, 'A'}, + 'A', "ID", "Set Application ID", ONE_DASH}, + {{"biblio", required_argument, NULL, OPTION_BIBLIO}, + '\0', "FILE", "Set Bibliographic filename", ONE_DASH}, + {{"cache-inodes", no_argument, NULL, OPTION_CACHE_INODES}, + '\0', NULL, "Cache inodes (needed to detect hard links)", ONE_DASH}, + {{"no-cache-inodes", no_argument, NULL, OPTION_NOCACHE_INODES}, + '\0', NULL, "Do not cache inodes (if filesystem has no unique unides)", ONE_DASH}, + {{"check-oldnames", no_argument, NULL, OPTION_CHECK_OLDNAMES}, + '\0', NULL, "Check all imported ISO9660 names from old session", ONE_DASH}, + {{"check-session", required_argument, NULL, OPTION_CHECK_SESSION}, + '\0', "FILE", "Check all ISO9660 names from previous session", ONE_DASH}, + {{"copyright", required_argument, NULL, OPTION_COPYRIGHT}, + '\0', "FILE", "Set Copyright filename", ONE_DASH}, + {{"debug", no_argument, NULL, OPTION_DEBUG}, + '\0', NULL, "Set debug flag", ONE_DASH}, + {{"eltorito-boot", required_argument, NULL, 'b'}, + 'b', "FILE", "Set El Torito boot image name", ONE_DASH}, + {{"eltorito-alt-boot", no_argument, NULL, OPTION_ALT_BOOT}, + '\0', NULL, "Start specifying alternative El Torito boot parameters", ONE_DASH}, + {{"sparc-boot", required_argument, NULL, 'B'}, + 'B', "FILES", "Set sparc boot image names", ONE_DASH}, + {{"sunx86-boot", required_argument, NULL, OPTION_SUNX86BOOT}, + '\0', "FILES", "Set sunx86 boot image names", ONE_DASH}, + {{"generic-boot", required_argument, NULL, 'G'}, + 'G', "FILE", "Set generic boot image name", ONE_DASH}, + {{"sparc-label", required_argument, NULL, OPTION_SPARCLABEL}, + '\0', "label text", "Set sparc boot disk label", ONE_DASH}, + {{"sunx86-label", required_argument, NULL, OPTION_SUNX86LABEL}, + '\0', "label text", "Set sunx86 boot disk label", ONE_DASH}, + {{"eltorito-catalog", required_argument, NULL, 'c'}, + 'c', "FILE", "Set El Torito boot catalog name", ONE_DASH}, + {{"cdrecord-params", required_argument, NULL, 'C'}, + 'C', "PARAMS", "Magic paramters from cdrecord", ONE_DASH}, + {{"omit-period", no_argument, NULL, 'd'}, + 'd', NULL, "Omit trailing periods from filenames (violates ISO9660)", ONE_DASH}, + {{"dir-mode", required_argument, NULL, OPTION_DIRMODE}, + '\0', "mode", "Make the mode of all directories this mode.", ONE_DASH}, + {{"disable-deep-relocation", no_argument, NULL, 'D'}, + 'D', NULL, "Disable deep directory relocation (violates ISO9660)", ONE_DASH}, + {{"file-mode", required_argument, NULL, OPTION_FILEMODE}, + '\0', "mode", "Make the mode of all plain files this mode.", ONE_DASH}, + {{"follow-links", no_argument, NULL, 'f'}, + 'f', NULL, "Follow symbolic links", ONE_DASH}, + {{"gid", required_argument, NULL, OPTION_GID}, + '\0', "gid", "Make the group owner of all files this gid.", + ONE_DASH}, + {{"graft-points", no_argument, NULL, OPTION_USE_GRAFT}, + '\0', NULL, "Allow to use graft points for filenames", ONE_DASH}, + {{"root", required_argument, NULL, OPTION_RELOC_ROOT}, + '\0', "DIR", "Set root directory for all new files and directories", ONE_DASH}, + {{"old-root", required_argument, NULL, OPTION_RELOC_OLD_ROOT}, + '\0', "DIR", "Set root directory in previous session that is searched for files", ONE_DASH}, + {{"help", no_argument, NULL, OPTION_HELP}, + '\0', NULL, "Print option help", ONE_DASH}, + {{"hide", required_argument, NULL, OPTION_I_HIDE}, + '\0', "GLOBFILE", "Hide ISO9660/RR file", ONE_DASH}, + {{"hide-list", required_argument, NULL, OPTION_I_LIST}, + '\0', "FILE", "File with list of ISO9660/RR files to hide", ONE_DASH}, + {{"hidden", required_argument, NULL, OPTION_H_HIDE}, + '\0', "GLOBFILE", "Set hidden attribute on ISO9660 file", ONE_DASH}, + {{"hidden-list", required_argument, NULL, OPTION_H_LIST}, + '\0', "FILE", "File with list of ISO9660 files with hidden attribute", ONE_DASH}, + {{"hide-joliet", required_argument, NULL, OPTION_J_HIDE}, + '\0', "GLOBFILE", "Hide Joliet file", ONE_DASH}, + {{"hide-joliet-list", required_argument, NULL, OPTION_J_LIST}, + '\0', "FILE", "File with list of Joliet files to hide", ONE_DASH}, + {{"hide-joliet-trans-tbl", no_argument, NULL, OPTION_HIDE_TRANS_TBL}, + '\0', NULL, "Hide TRANS.TBL from Joliet tree", ONE_DASH}, + {{"hide-rr-moved", no_argument, NULL, OPTION_HIDE_RR_MOVED}, + '\0', NULL, "Rename RR_MOVED to .rr_moved in Rock Ridge tree", ONE_DASH}, + {{"gui", no_argument, NULL, OPTION_GUI}, + '\0', NULL, "Switch behaviour for GUI", ONE_DASH}, + {{NULL, required_argument, NULL, 'i'}, + 'i', "ADD_FILES", "No longer supported", TWO_DASHES}, + {{"input-charset", required_argument, NULL, OPTION_INPUT_CHARSET}, + '\0', "CHARSET", "Local input charset for file name conversion", ONE_DASH}, + {{"output-charset", required_argument, NULL, OPTION_OUTPUT_CHARSET}, + '\0', "CHARSET", "Output charset for file name conversion", ONE_DASH}, + {{"iso-level", required_argument, NULL, OPTION_ISO_LEVEL}, + '\0', "LEVEL", "Set ISO9660 conformance level (1..3) or 4 for ISO9660 version 2", ONE_DASH}, + {{"joliet", no_argument, NULL, 'J'}, + 'J', NULL, "Generate Joliet directory information", ONE_DASH}, + {{"joliet-long", no_argument, NULL, OPTION_JLONG}, + '\0', NULL, "Allow Joliet file names to be 103 Unicode characters", ONE_DASH}, + {{"jcharset", required_argument, NULL, OPTION_JCHARSET}, + '\0', "CHARSET", "Local charset for Joliet directory information", ONE_DASH}, + {{"full-iso9660-filenames", no_argument, NULL, 'l'}, + 'l', NULL, "Allow full 31 character filenames for ISO9660 names", ONE_DASH}, + {{"max-iso9660-filenames", no_argument, NULL, OPTION_MAX_FILENAMES}, + '\0', NULL, "Allow 37 character filenames for ISO9660 names (violates ISO9660)", ONE_DASH}, + + {{"allow-limited-size", no_argument, NULL, OPTION_ALLOW_LIMITED_SIZE}, + '\0', NULL, "Allow different file sizes in ISO9660/UDF on large files", ONE_DASH}, + + {{"allow-leading-dots", no_argument, NULL, OPTION_ALLOW_LEADING_DOTS}, + '\0', NULL, "Allow ISO9660 filenames to start with '.' (violates ISO9660)", ONE_DASH}, + {{"ldots", no_argument, NULL, OPTION_ALLOW_LEADING_DOTS}, + '\0', NULL, "Allow ISO9660 filenames to start with '.' (violates ISO9660)", ONE_DASH}, + {{"allow-leading-dots", no_argument, NULL, 'L'}, + 'L', NULL, "Allow ISO9660 filenames to start with '.' (violates ISO9660)", ONE_DASH}, + + {{"log-file", required_argument, NULL, OPTION_LOG_FILE}, + '\0', "LOG_FILE", "Re-direct messages to LOG_FILE", ONE_DASH}, + {{"exclude", required_argument, NULL, 'm'}, + 'm', "GLOBFILE", "Exclude file name", ONE_DASH}, + {{"exclude-list", required_argument, NULL, OPTION_X_LIST}, + '\0', "FILE", "File with list of file names to exclude", ONE_DASH}, + {{"pad", no_argument, NULL, OPTION_PAD}, + 0, NULL, "Pad output to a multiple of 32k (default)", ONE_DASH}, + {{"no-pad", no_argument, NULL, OPTION_NOPAD}, + 0, NULL, "Do not pad output to a multiple of 32k", ONE_DASH}, + {{"prev-session", required_argument, NULL, 'M'}, + 'M', "FILE", "Set path to previous session to merge", ONE_DASH}, + {{"dev", required_argument, NULL, 'M'}, + '\0', "SCSIdev", "Set path to previous session to merge", ONE_DASH}, + {{"omit-version-number", no_argument, NULL, 'N'}, + 'N', NULL, "Omit version number from ISO9660 filename (violates ISO9660)", ONE_DASH}, + {{"new-dir-mode", required_argument, NULL, OPTION_NEW_DIR_MODE}, + '\0', "mode", "Mode used when creating new directories.", ONE_DASH}, + {{"force-rr", no_argument, NULL, OPTION_FORCE_RR}, + 0, NULL, "Inhibit automatic Rock Ridge detection for previous session", ONE_DASH}, + {{"no-rr", no_argument, NULL, OPTION_NO_RR}, + 0, NULL, "Inhibit reading of Rock Ridge attributes from previous session", ONE_DASH}, + {{"no-split-symlink-components", no_argument, NULL, OPTION_NOSPLIT_SL_COMPONENT}, + 0, NULL, "Inhibit splitting symlink components", ONE_DASH}, + {{"no-split-symlink-fields", no_argument, NULL, OPTION_NOSPLIT_SL_FIELD}, + 0, NULL, "Inhibit splitting symlink fields", ONE_DASH}, + {{"output", required_argument, NULL, 'o'}, + 'o', "FILE", "Set output file name", ONE_DASH}, + {{"path-list", required_argument, NULL, OPTION_P_LIST}, + '\0', "FILE", "File with list of pathnames to process", ONE_DASH}, + {{"preparer", required_argument, NULL, 'p'}, + 'p', "PREP", "Set Volume preparer", ONE_DASH}, + {{"print-size", no_argument, NULL, OPTION_PRINT_SIZE}, + '\0', NULL, "Print estimated filesystem size and exit", ONE_DASH}, + {{"publisher", required_argument, NULL, OPTION_PUBLISHER}, + '\0', "PUB", "Set Volume publisher", ONE_DASH}, + {{"publisher", required_argument, NULL, 'P'}, + 'P', "PUB", "Set Volume publisher", ONE_DASH}, + {{"quiet", no_argument, NULL, OPTION_QUIET}, + '\0', NULL, "Run quietly", ONE_DASH}, + {{"rational-rock", no_argument, NULL, 'r'}, + 'r', NULL, "Generate rationalized Rock Ridge directory information", ONE_DASH}, + {{"rock", no_argument, NULL, 'R'}, + 'R', NULL, "Generate Rock Ridge directory information", ONE_DASH}, + {{"sectype", required_argument, NULL, 's'}, + 's', "TYPE", "Set output sector type to e.g. data/xa1/raw", ONE_DASH}, + + {{"alpha-boot", required_argument, NULL, OPTION_BOOTALPHA}, + '\0', "FILE", "Set alpha boot image name (relative to image root)", ONE_DASH}, + + {{"hppa-cmdline", required_argument, NULL, OPTION_HPPA_CMDLINE}, + '\0', "CMDLINE", "Set hppa boot command line (relative to image root)", ONE_DASH}, + {{"hppa-kernel-32", required_argument, NULL, OPTION_HPPA_KERNEL_32}, + '\0', "FILE", "Set hppa 32-bit image name (relative to image root)", ONE_DASH}, + {{"hppa-kernel-64", required_argument, NULL, OPTION_HPPA_KERNEL_64}, + '\0', "FILE", "Set hppa 64-bit image name (relative to image root)", ONE_DASH}, + {{"hppa-bootloader", required_argument, NULL, OPTION_HPPA_BOOTLOADER}, + '\0', "FILE", "Set hppa boot loader file name (relative to image root)", ONE_DASH}, + {{"hppa-ramdisk", required_argument, NULL, OPTION_HPPA_RAMDISK}, + '\0', "FILE", "Set hppa ramdisk file name (relative to image root)", ONE_DASH}, + + {{"mips-boot", required_argument, NULL, OPTION_BOOTMIPS}, + '\0', "FILE", "Set mips boot image name (relative to image root)", ONE_DASH}, + + {{"mipsel-boot", required_argument, NULL, OPTION_BOOTMIPSEL}, + '\0', "FILE", "Set mipsel boot image name (relative to image root)", ONE_DASH}, + +#ifdef JIGDO_TEMPLATE + {{"jigdo-jigdo", required_argument, NULL, OPTION_JTJ_OUTPUT}, + '\0', "FILE", "Produce a jigdo .jigdo file as well as the .iso", ONE_DASH }, + {{"jigdo-template", required_argument, NULL, OPTION_JTT_OUTPUT}, + '\0', "FILE", "Produce a jigdo .template file as well as the .iso", ONE_DASH }, + {{"jigdo-min-file-size", required_argument, NULL, OPTION_JT_MIN_SIZE}, + '\0', "SIZE", "Minimum size for a file to be listed in the jigdo file", ONE_DASH }, + {{"jigdo-force-md5", required_argument, NULL, OPTION_JT_INCLUDE}, + '\0', "PATTERN", "Pattern(s) where files MUST match an externally-supplied MD5sum", ONE_DASH }, + {{"jigdo-exclude", required_argument, NULL, OPTION_JT_EXCLUDE}, + '\0', "PATTERN", "Pattern(s) to exclude from the jigdo file", ONE_DASH }, + {{"jigdo-map", required_argument, NULL, OPTION_JT_PATH_MAP}, + '\0', "PATTERN1=PATTERN2", "Pattern(s) to map paths (e.g. Debian=/mirror/debian)", ONE_DASH }, + {{"md5-list", required_argument, NULL, OPTION_JT_MD5_LIST}, + '\0', "FILE", "File containing MD5 sums of the files that should be checked", ONE_DASH }, + {{"jigdo-template-compress", required_argument, NULL, OPTION_JT_COMPRESS_ALGO}, + '\0', "ALGORITHM", "Choose to use gzip or bzip2 compression for template data; default is gzip", ONE_DASH }, + {{"checksum_algorithm_iso", required_argument, NULL, OPTION_JT_CHECKSUM_ALGO_ISO}, + '\0', "alg1,alg2,...", "Specify the checksum types desired for the output image", ONE_DASH}, + {{"checksum_algorithm_template", required_argument, NULL, OPTION_JT_CHECKSUM_ALGO_TMPL}, + '\0', "alg1,alg2,...", "Specify the checksum types desired for the output jigdo template", ONE_DASH}, +#endif + +#ifdef SORTING + { {"sort", required_argument, NULL, OPTION_SORT}, + '\0', "FILE", "Sort file content locations according to rules in FILE", ONE_DASH }, +#endif /* SORTING */ + + {{"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT}, + '\0', NULL, "Split output into files of approx. 1GB size", ONE_DASH}, + {{"stream-file-name", required_argument, NULL, OPTION_STREAM_FILE_NAME}, + '\0', "FILE_NAME", "Set the stream file ISO9660 name (incl. version)", ONE_DASH}, + {{"stream-media-size", required_argument, NULL, OPTION_STREAM_CD_SIZE}, + '\0', "#", "Set the size of your CD media in sectors", ONE_DASH}, + {{"sysid", required_argument, NULL, OPTION_SYSID}, + '\0', "ID", "Set System ID", ONE_DASH}, + {{"translation-table", no_argument, NULL, 'T'}, + 'T', NULL, "Generate translation tables for systems that don't understand long filenames", ONE_DASH}, + {{"table-name", required_argument, NULL, OPTION_TRANS_TBL}, + '\0', "TABLE_NAME", "Translation table file name", ONE_DASH}, + {{"ucs-level", required_argument, NULL, OPTION_UCS_LEVEL}, + '\0', "LEVEL", "Set Joliet UCS level (1..3)", ONE_DASH}, + +#ifdef UDF + {{"udf", no_argument, NULL, OPTION_UDF}, + '\0', NULL, "Generate UDF file system", ONE_DASH}, +#endif + +#ifdef DVD_VIDEO + {{"dvd-video", no_argument, NULL, OPTION_DVD}, + '\0', NULL, "Generate DVD-Video compliant UDF file system", ONE_DASH}, +#endif + + {{"uid", required_argument, NULL, OPTION_UID}, + '\0', "uid", "Make the owner of all files this uid.", + ONE_DASH}, + {{"untranslated-filenames", no_argument, NULL, 'U'}, + /* CSTYLED */ + 'U', NULL, "Allow Untranslated filenames (for HPUX & AIX - violates ISO9660). Forces -l, -d, -N, -allow-leading-dots, -relaxed-filenames, -allow-lowercase, -allow-multidot", ONE_DASH}, + {{"relaxed-filenames", no_argument, NULL, OPTION_RELAXED_FILENAMES}, + '\0', NULL, "Allow 7 bit ASCII except lower case characters (violates ISO9660)", ONE_DASH}, + {{"no-iso-translate", no_argument, NULL, OPTION_ISO_TRANSLATE}, + '\0', NULL, "Do not translate illegal ISO characters '~', '-' and '#' (violates ISO9660)", ONE_DASH}, + {{"allow-lowercase", no_argument, NULL, OPTION_ALLOW_LOWERCASE}, + '\0', NULL, "Allow lower case characters in addition to the current character set (violates ISO9660)", ONE_DASH}, + {{"allow-multidot", no_argument, NULL, OPTION_ALLOW_MULTIDOT}, + '\0', NULL, "Allow more than one dot in filenames (e.g. .tar.gz) (violates ISO9660)", ONE_DASH}, + {{"use-fileversion", no_argument, NULL, OPTION_USE_FILEVERSION}, + '\0', "LEVEL", "Use file version # from filesystem", ONE_DASH}, + {{"verbose", no_argument, NULL, 'v'}, + 'v', NULL, "Verbose", ONE_DASH}, + {{"version", no_argument, NULL, OPTION_PVERSION}, + '\0', NULL, "Print the current version", ONE_DASH}, + {{"volid", required_argument, NULL, 'V'}, + 'V', "ID", "Set Volume ID", ONE_DASH}, + {{"volset", required_argument, NULL, OPTION_VOLSET}, + '\0', "ID", "Set Volume set ID", ONE_DASH}, + {{"volset-size", required_argument, NULL, OPTION_VOLSET_SIZE}, + '\0', "#", "Set Volume set size", ONE_DASH}, + {{"volset-seqno", required_argument, NULL, OPTION_VOLSET_SEQ_NUM}, + '\0', "#", "Set Volume set sequence number", ONE_DASH}, + {{"old-exclude", required_argument, NULL, 'x'}, + 'x', "FILE", "Exclude file name(depreciated)", ONE_DASH}, + {{"hard-disk-boot", no_argument, NULL, OPTION_HARD_DISK_BOOT}, + '\0', NULL, "Boot image is a hard disk image", ONE_DASH}, + {{"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT}, + '\0', NULL, "Boot image is 'no emulation' image", ONE_DASH}, + {{"no-boot", no_argument, NULL, OPTION_NO_BOOT}, + '\0', NULL, "Boot image is not bootable", ONE_DASH}, + {{"boot-load-seg", required_argument, NULL, OPTION_BOOT_LOAD_ADDR}, + '\0', "#", "Set load segment for boot image", ONE_DASH}, + {{"boot-load-size", required_argument, NULL, OPTION_BOOT_LOAD_SIZE}, + '\0', "#", "Set numbers of load sectors", ONE_DASH}, + {{"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE}, + '\0', NULL, "Patch boot image with info table", ONE_DASH}, + {{"XA", no_argument, NULL, OPTION_XA}, + '\0', NULL, "Generate XA directory attruibutes", ONE_DASH}, + {{"xa", no_argument, NULL, OPTION_XA_RATIONALIZED}, + '\0', NULL, "Generate rationalized XA directory attruibutes", ONE_DASH}, + {{"transparent-compression", no_argument, NULL, 'z'}, + 'z', NULL, "Enable transparent compression of files", ONE_DASH}, + +#ifdef APPLE_HYB + {{"hfs-type", required_argument, NULL, OPTION_HFS_TYPE}, + '\0', "TYPE", "Set HFS default TYPE", ONE_DASH}, + {{"hfs-creator", required_argument, NULL, OPTION_HFS_CREATOR}, + '\0', "CREATOR", "Set HFS default CREATOR", ONE_DASH}, + {{"apple", no_argument, NULL, 'g'}, + 'g', NULL, "Add Apple ISO9660 extensions", ONE_DASH}, + {{"hfs", no_argument, NULL, 'h'}, + 'h', NULL, "Create ISO9660/HFS hybrid", ONE_DASH}, + {{"map", required_argument, NULL, OPTION_MAP_FILE}, + '\0', "MAPPING_FILE", "Map file extensions to HFS TYPE/CREATOR", ONE_DASH}, + {{"map", required_argument, NULL, 'H'}, + 'H', "MAPPING_FILE", "Map file extensions to HFS TYPE/CREATOR", ONE_DASH}, + {{"magic", required_argument, NULL, OPTION_MAGIC_FILE}, + '\0', "FILE", "Magic file for HFS TYPE/CREATOR", ONE_DASH}, + {{"probe", no_argument, NULL, OPTION_PROBE}, + '\0', NULL, "Probe all files for Apple/Unix file types", ONE_DASH}, + {{"mac-name", no_argument, NULL, OPTION_MACNAME}, + '\0', NULL, "Use Macintosh name for ISO9660/Joliet/RockRidge file name", + ONE_DASH}, + {{"no-mac-files", no_argument, NULL, OPTION_NOMACFILES}, + '\0', NULL, "Do not look for Unix/Mac files (depreciated)", ONE_DASH}, + {{"boot-hfs-file", required_argument, NULL, OPTION_BOOT_HFS_FILE}, + '\0', "FILE", "Set HFS boot image name", ONE_DASH}, + {{"part", no_argument, NULL, OPTION_GEN_PT}, + '\0', NULL, "Generate HFS partition table", ONE_DASH}, + {{"cluster-size", required_argument, NULL, OPTION_BSIZE}, + '\0', "SIZE", "Cluster size for PC Exchange Macintosh files", ONE_DASH}, + {{"auto", required_argument, NULL, OPTION_AUTOSTART}, + '\0', "FILE", "Set HFS AutoStart file name", ONE_DASH}, + {{"no-desktop", no_argument, NULL, OPTION_CREATE_DT}, + '\0', NULL, "Do not create the HFS (empty) Desktop files", ONE_DASH}, + {{"hide-hfs", required_argument, NULL, OPTION_HFS_HIDE}, + '\0', "GLOBFILE", "Hide HFS file", ONE_DASH}, + {{"hide-hfs-list", required_argument, NULL, OPTION_HFS_LIST}, + '\0', "FILE", "List of HFS files to hide", ONE_DASH}, + {{"hfs-volid", required_argument, NULL, OPTION_HFS_VOLID}, + '\0', "HFS_VOLID", "Volume name for the HFS partition", ONE_DASH}, + {{"icon-position", no_argument, NULL, OPTION_ICON_POS}, + '\0', NULL, "Keep HFS icon position", ONE_DASH}, + {{"root-info", required_argument, NULL, OPTION_ROOT_INFO}, + '\0', "FILE", "finderinfo for root folder", ONE_DASH}, + {{"input-hfs-charset", required_argument, NULL, OPTION_HFS_INPUT_CHARSET}, + '\0', "CHARSET", "Local input charset for HFS file name conversion", ONE_DASH}, + {{"output-hfs-charset", required_argument, NULL, OPTION_HFS_OUTPUT_CHARSET}, + '\0', "CHARSET", "Output charset for HFS file name conversion", ONE_DASH}, + {{"hfs-unlock", no_argument, NULL, OPTION_HFS_UNLOCK}, + '\0', NULL, "Leave HFS Volume unlocked", ONE_DASH}, + {{"hfs-bless", required_argument, NULL, OPTION_HFS_BLESS}, + '\0', "FOLDER_NAME", "Name of Folder to be blessed", ONE_DASH}, + {{"hfs-parms", required_argument, NULL, OPTION_HFS_PARMS}, + '\0', "PARAMETERS", "Comma separated list of HFS parameters", ONE_DASH}, +#ifdef PREP_BOOT + {{"prep-boot", required_argument, NULL, OPTION_PREP_BOOT}, + '\0', "FILE", "PReP boot image file -- up to 4 are allowed", ONE_DASH}, + {{"chrp-boot", no_argument, NULL, OPTION_CHRP_BOOT}, + '\0', NULL, "Add CHRP boot header", ONE_DASH}, +#endif /* PREP_BOOT */ + {{"cap", no_argument, NULL, OPTION_CAP}, + '\0', NULL, "Look for AUFS CAP Macintosh files", TWO_DASHES}, + {{"netatalk", no_argument, NULL, OPTION_NETA}, + '\0', NULL, "Look for NETATALK Macintosh files", TWO_DASHES}, + {{"double", no_argument, NULL, OPTION_DBL}, + '\0', NULL, "Look for AppleDouble Macintosh files", TWO_DASHES}, + {{"ethershare", no_argument, NULL, OPTION_ESH}, + '\0', NULL, "Look for Helios EtherShare Macintosh files", TWO_DASHES}, + {{"exchange", no_argument, NULL, OPTION_FE}, + '\0', NULL, "Look for PC Exchange Macintosh files", TWO_DASHES}, + {{"sgi", no_argument, NULL, OPTION_SGI}, + '\0', NULL, "Look for SGI Macintosh files", TWO_DASHES}, + {{"macbin", no_argument, NULL, OPTION_MBIN}, + '\0', NULL, "Look for MacBinary Macintosh files", TWO_DASHES}, + {{"single", no_argument, NULL, OPTION_SGL}, + '\0', NULL, "Look for AppleSingle Macintosh files", TWO_DASHES}, + {{"ushare", no_argument, NULL, OPTION_USH}, + '\0', NULL, "Look for IPT UShare Macintosh files", TWO_DASHES}, + {{"xinet", no_argument, NULL, OPTION_XIN}, + '\0', NULL, "Look for XINET Macintosh files", TWO_DASHES}, + {{"dave", no_argument, NULL, OPTION_DAVE}, + '\0', NULL, "Look for DAVE Macintosh files", TWO_DASHES}, + {{"sfm", no_argument, NULL, OPTION_SFM}, + '\0', NULL, "Look for SFM Macintosh files", TWO_DASHES}, + {{"osx-double", no_argument, NULL, OPTION_XDBL}, + '\0', NULL, "Look for MacOS X AppleDouble Macintosh files", TWO_DASHES}, + {{"osx-hfs", no_argument, NULL, OPTION_XHFS}, + '\0', NULL, "Look for MacOS X HFS Macintosh files", TWO_DASHES}, +#endif /* APPLE_HYB */ +}; + +#define OPTION_COUNT (sizeof ld_options / sizeof (ld_options[0])) + +static void read_rcfile(char *appname); +static void susage(int excode); +static void usage(int excode); +int iso9660_date(char *result, time_t crtime); +static void hide_reloc_dir(void); +static char *get_pnames(int argc, char **argv, int opt, char *pname, + int pnsize, FILE *fp); +char *findgequal(char *s); +static char *escstrcpy(char *to, char *from); +void *e_malloc(size_t size); + +static int +read_one_rcfile(char *filename) +{ + int linum = 0; + char linebuffer[256]; + FILE *fp; + + if (!filename) + return 0; + + fp = fopen(filename, "r"); + if (!fp) { + if (errno == ENOENT) + return 0; +#ifdef USE_LIBSCHILY + errmsg("Cannot open '%s'.\n", filename); +#else + perror(filename); +#endif + return 0; + } + if (verbose > 0) + fprintf(stderr, "Using \"%s\"\n", filename); + + while (fgets(linebuffer, sizeof(linebuffer), fp)) { + char *name, *p, *p1; + struct rcopts *rco; + + ++linum; + /* skip any leading white space */ + for (p = linebuffer; *p == ' ' || *p == '\t'; p++) + ; + /* Skip comments and blank lines */ + if (!*p || *p == '\n' || *p == '\r' || *p == '#') + continue; + /* + * The name should begin in the left margin. Make sure it is + * in upper case. Stop when we see white space or a comment. + */ + name = p; + while (*p && (isalpha((unsigned char) *p) || *p == '_')) + *p++ = toupper((unsigned char) *p); + + if (name == p) { + fprintf(stderr, "%s:%d: name required\n", filename, + linum); + continue; + } + + p1 = p; + /* Skip past white space after the name */ + while (*p == ' ' || *p == '\t') + p++; + /* silently ignore errors in the rc file. */ + if (*p != '=') { + fprintf(stderr, "%s:%d: equals sign required after '%.*s'\n", + filename, linum, + (int)(p1-name), name); + continue; + } + *p1 = 0; + + /* Skip pas the = sign, and any white space following it */ + p++; + while (*p == ' ' || *p == '\t') + p++; + + /* Get rid of trailing newline */ + for (p1 = p; *p1 && *p1 != '\n' && *p1 != '\r'; p1++) + ; + *p1 = 0; + + /* Figure out which option we have */ + for (rco = rcopt; rco->tag; rco++) + if (strcmp(rco->tag, name) == 0) { + /* memleak if we ever do this more than once */ + *rco->variable = strdup(p); + break; + } + + if (!rco->tag) { + fprintf(stderr, "%s:%d: field name '%s' unknown\n", + filename, linum, + name); + } + } + if (ferror(fp)) { +#ifdef USE_LIBSCHILY + errmsg("Read error on '%s'.\n", filename); +#else + perror(filename); +#endif + fclose(fp); + return 0; + } + fclose(fp); + return 1; +} + +#define ETCDIR "/etc" +#define RCFILENAME "genisoimagerc" +#define OLD_RCFILENAME "mkisofsrc" + +static void +read_rcfile(char *appname) +{ + char *p; + char filename[1000]; + + if (read_one_rcfile(getenv("GENISOIMAGERC"))) + return; + if (read_one_rcfile(getenv("MKISOFSRC"))) + return; + if (read_one_rcfile("." RCFILENAME)) + return; + if (read_one_rcfile("." OLD_RCFILENAME)) + return; + + p = getenv("HOME"); + if (p && strlen(p) + 1 + sizeof(RCFILENAME) < sizeof(filename)) { + strcpy(filename, p); + p = filename + strlen(filename); + *p++ = PATH_SEPARATOR; + strcpy(p, "." RCFILENAME); + if (read_one_rcfile(filename)) + return; + strcpy(p, "." OLD_RCFILENAME); + if (read_one_rcfile(filename)) + return; + } + + if (read_one_rcfile(ETCDIR SPATH_SEPARATOR RCFILENAME)) + return; + + if (appname && + strlen(appname) + 1 + sizeof(RCFILENAME) < sizeof(filename)) { + strcpy(filename, appname); + p = strrchr(filename, PATH_SEPARATOR); + if (p) { + strcpy(p + 1, RCFILENAME); + if (read_one_rcfile(filename)) + return; + } + } +} + +char *path_table_l = NULL; +char *path_table_m = NULL; + +char *jpath_table_l = NULL; +char *jpath_table_m = NULL; + +int goof = 0; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +static void +susage(int excode) +{ + const char *program_name = "genisoimage"; + + fprintf(stderr, "Usage: %s [options] -o file directory ...\n", program_name); + fprintf(stderr, "\nUse %s -help\n", program_name); + fprintf(stderr, "to get a list of valid options.\n"); + fprintf(stderr, "\nReport problems to debburn-devel@lists.alioth.debian.org.\n"); + + exit(excode); +} + +static void +usage(int excode) +{ + const char *program_name = "genisoimage"; + + int i; + +/* const char **targets, **pp;*/ + + fprintf(stderr, "Usage: %s [options] file...\n", program_name); + + fprintf(stderr, "Options:\n"); + for (i = 0; i < (int)OPTION_COUNT; i++) { + if (ld_options[i].doc != NULL) { + int comma; + int len; + int j; + + fprintf(stderr, " "); + + comma = FALSE; + len = 2; + + j = i; + do { + if (ld_options[j].shortopt != '\0' && + ld_options[j].control != NO_HELP) { + fprintf(stderr, "%s-%c", + comma ? ", " : "", + ld_options[j].shortopt); + len += (comma ? 2 : 0) + 2; + if (ld_options[j].arg != NULL) { + if (ld_options[j].opt.has_arg != optional_argument) { + fprintf(stderr, " "); + ++len; + } + fprintf(stderr, "%s", + ld_options[j].arg); + len += strlen(ld_options[j].arg); + } + comma = TRUE; + } + ++j; + } + while (j < (int)OPTION_COUNT && ld_options[j].doc == NULL); + + j = i; + do { + if (ld_options[j].opt.name != NULL && + ld_options[j].control != NO_HELP) { + fprintf(stderr, "%s-%s%s", + comma ? ", " : "", + ld_options[j].control == TWO_DASHES ? "-" : "", + ld_options[j].opt.name); + len += ((comma ? 2 : 0) + + 1 + + (ld_options[j].control == TWO_DASHES ? 1 : 0) + + strlen(ld_options[j].opt.name)); + if (ld_options[j].arg != NULL) { + fprintf(stderr, " %s", + ld_options[j].arg); + len += 1 + + strlen(ld_options[j].arg); + } + comma = TRUE; + } + ++j; + } + while (j < (int)OPTION_COUNT && ld_options[j].doc == NULL); + + if (len >= 30) { + fprintf(stderr, "\n"); + len = 0; + } + for (; len < 30; len++) + fputc(' ', stderr); + + fprintf(stderr, "%s\n", ld_options[i].doc); + } + } + fprintf(stderr, + "\nReport problems to debburn-devel@lists.alioth.debian.org.\n"); + exit(excode); +} + + +/* + * Fill in date in the iso9660 format + * + * The standards state that the timezone offset is in multiples of 15 + * minutes, and is what you add to GMT to get the localtime. The U.S. + * is always at a negative offset, from -5h to -8h (can vary a little + * with DST, I guess). The Linux iso9660 filesystem has had the sign + * of this wrong for ages (genisoimage had it wrong too for the longest time). + */ +int +iso9660_date(char *result, time_t crtime) +{ + struct tm *local; + + local = localtime(&crtime); + result[0] = local->tm_year; + result[1] = local->tm_mon + 1; + result[2] = local->tm_mday; + result[3] = local->tm_hour; + result[4] = local->tm_min; + result[5] = local->tm_sec; + + /* + * Must recalculate proper timezone offset each time, as some files use + * daylight savings time and some don't... + */ + result[6] = local->tm_yday; /* save yday 'cause gmtime zaps it */ + local = gmtime(&crtime); + local->tm_year -= result[0]; + local->tm_yday -= result[6]; + local->tm_hour -= result[3]; + local->tm_min -= result[4]; + if (local->tm_year < 0) { + local->tm_yday = -1; + } else { + if (local->tm_year > 0) + local->tm_yday = 1; + } + + result[6] = -(local->tm_min + 60 * + (local->tm_hour + 24 * local->tm_yday)) / 15; + + return (0); +} + +/* hide "./rr_moved" if all its contents are hidden */ +static void +hide_reloc_dir() +{ + struct directory_entry *s_entry; + + for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) { + if (strcmp(s_entry->name, ".") == 0 || + strcmp(s_entry->name, "..") == 0) + continue; + + if ((s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) + return; + } + + /* all entries are hidden, so hide this directory */ + reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; + reloc_dir->self->de_flags |= INHIBIT_ISO9660_ENTRY; +} + +/* + * get pathnames from the command line, and then from given file + */ +static char * +get_pnames(int argc, char **argv, int opt, char *pname, int pnsize, FILE *fp) +{ + int len; + + /* we may of already read the first line from the pathnames file */ + if (save_pname) { + save_pname = 0; + return (pname); + } + + if (opt < argc) + return (argv[opt]); + + if (fp == NULL) + return ((char *) 0); + + if (fgets(pname, pnsize, fp)) { + /* Discard newline */ + len = strlen(pname); + if (pname[len - 1] == '\n') { + pname[len - 1] = '\0'; + } + return (pname); + } + return ((char *) 0); +} + +extern char *cdrecord_data; + +int main(int argc, char *argv[]) +{ + struct directory_entry de; + +#ifdef HAVE_SBRK + unsigned long mem_start; + +#endif + struct stat statbuf; + char *merge_image = NULL; + char *reloc_root = NULL; + char *reloc_old_root = NULL; + struct iso_directory_record *mrootp = NULL; + struct output_fragment *opnt; + int longind; + char shortopts[OPTION_COUNT * 3 + 2]; + struct option longopts[OPTION_COUNT + 1]; + int c; + int n; + char *log_file = 0; + char *node = NULL; + char *pathnames = 0; + FILE *pfp = NULL; + char pname[2*PATH_MAX + 1 + 1]; /* may be too short */ + char *arg; /* if '\\' present */ + char nodename[PATH_MAX + 1]; + int no_path_names = 1; + int warn_violate = 0; + int have_cmd_line_pathspec = 0; + int rationalize_all = 0; + char *mkisofs_call = 0; /* use as pointer and boolean */ + +#ifdef APPLE_HYB + char *afpfile = ""; /* mapping file for TYPE/CREATOR */ + int hfs_ct = 0; + char *root_info = 0; +#endif /* APPLE_HYB */ + + /* abusing arg */ + mkisofs_call=strstr(argv[0], "mkisofs"); + if(mkisofs_call && '\0' == mkisofs_call[7]) /* lame cheater detected */ + argv[0]="genisoimage"; + +#ifdef __EMX__ + /* This gives wildcard expansion with Non-Posix shells with EMX */ + _wildcard(&argc, &argv); +#endif + save_args(argc, argv); + + if (argc < 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Missing pathspec.\n"); +#endif + susage(1); + } + /* Get the defaults from the .genisoimagerc file */ + read_rcfile(argv[0]); + + outfile = NULL; + + /* + * Copy long option initialization from GNU-ld. + */ + /* + * Starting the short option string with '-' is for programs that + * expect options and other ARGV-elements in any order and that care + * about the ordering of the two. We describe each non-option + * ARGV-element as if it were the argument of an option with + * character code 1. + */ + { + int i, + is, + il; + + shortopts[0] = '-'; + is = 1; + il = 0; + for (i = 0; i < (int)OPTION_COUNT; i++) { + if (ld_options[i].shortopt != '\0') { + shortopts[is] = ld_options[i].shortopt; + ++is; + if (ld_options[i].opt.has_arg == + required_argument || + ld_options[i].opt.has_arg == + optional_argument) { + shortopts[is] = ':'; + ++is; + if (ld_options[i].opt.has_arg == + optional_argument) { + shortopts[is] = ':'; + ++is; + } + } + } + if (ld_options[i].opt.name != NULL) { + longopts[il] = ld_options[i].opt; + ++il; + } + } + shortopts[is] = '\0'; + longopts[il].name = NULL; + } + + while ((c = getopt_long_only(argc, argv, shortopts, + longopts, &longind)) != EOF) + switch (c) { + case 1: + /* A filename that we take as input. */ + optind--; + have_cmd_line_pathspec = 1; + goto parse_input_files; + + case OPTION_USE_GRAFT: + use_graft_ptrs = 1; + break; + case 'C': + /* + * This is a temporary hack until cdrecord gets the + * proper hooks in it. + */ + cdrecord_data = optarg; + break; + case OPTION_GUI: + gui++; + break; + case 'i': +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "-i option no longer supported.\n"); +#else + fprintf(stderr, "-i option no longer supported.\n"); + exit(1); +#endif + break; + case OPTION_ISO_LEVEL: + iso9660_level = atoi(optarg); + + switch (iso9660_level) { + + case 1: + /* + * Only on file section + * 8.3 d or d1 characters for files + * 8 d or d1 characters for directories + */ + break; + case 2: + /* + * Only on file section + */ + break; + case 3: + /* + * No restrictions + */ + break; + case 4: + /* + * This is ISO-9660:1988 (ISO-9660 version 2) + */ + iso9660_namelen = MAX_ISONAME_V2; /* allow 207 chars */ + full_iso9660_filenames++; /* 31+ chars */ + omit_version_number++; + RR_relocation_depth = 32767; + + /* + * From -U ... + */ + omit_period++; /* trailing dot */ + allow_leading_dots++; + relaxed_filenames++; /* all chars */ + allow_lowercase++; /* even lowcase */ + allow_multidot++; /* > 1 dots */ + break; + + default: + comerrno(EX_BAD, "Illegal iso9660 Level %d, use 1..3 or 4.\n", + iso9660_level); + } + break; + case 'J': + use_Joliet++; + break; + case OPTION_JLONG: + use_Joliet++; + jlen = JLONGMAX; + break; + case OPTION_JCHARSET: + use_Joliet++; + /* FALLTHROUGH */ + case OPTION_INPUT_CHARSET: + icharset = optarg; + break; + case OPTION_OUTPUT_CHARSET: + ocharset = optarg; + break; +#ifdef JIGDO_TEMPLATE + case OPTION_JTT_OUTPUT: + jtemplate_out = optarg; + break; + case OPTION_JTJ_OUTPUT: + jjigdo_out = optarg; + break; + case OPTION_JT_MD5_LIST: + jmd5_list = optarg; + break; + case OPTION_JT_MIN_SIZE: + jte_min_size = atoi(optarg); + if (jte_min_size < MIN_JIGDO_FILE_SIZE) { + fprintf(stderr, "Jigdo min size %d too small; using default %d instead\n", jte_min_size, MIN_JIGDO_FILE_SIZE); + jte_min_size = MIN_JIGDO_FILE_SIZE; + } + break; + case OPTION_JT_INCLUDE: + if (jte_add_include(optarg)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Failed to build jigdo-include list\n"); +#else + fprintf(stderr, + "Failed to build jigdo-include list\n"); + exit(1); +#endif + } + break; + case OPTION_JT_EXCLUDE: + if (jte_add_exclude(optarg)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Failed to build jigdo-exclude list\n"); +#else + fprintf(stderr, + "Failed to build jigdo-exclude list\n"); + exit(1); +#endif + } + break; + case OPTION_JT_PATH_MAP: + if (jte_add_mapping(optarg)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Failed to build jigdo mapping list\n"); +#else + fprintf(stderr, + "Failed to build jigdo mapping list\n"); + exit(1); +#endif + } + break; + case OPTION_JT_COMPRESS_ALGO: + if (!strcasecmp(optarg, "gzip")) + jte_template_compression = JTE_TEMP_GZIP; + else if (!strcasecmp(optarg, "bzip2")) + jte_template_compression = JTE_TEMP_BZIP2; + else + { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Compression algorithm %s unknown\n", optarg); +#else + fprintf(stderr, "Compression algorithm %s unknown\n", optarg); + exit(1); +#endif + } + break; + + case OPTION_JT_CHECKSUM_ALGO_ISO: + if (parse_checksum_algo(optarg, &checksum_algo_iso)) + { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Problem with ISO checksum choices: %s \n", optarg); +#else + fprintf(stderr, "Problem with ISO checksum choices: %s\n", optarg); + exit(1); +#endif + } + + break; + + case OPTION_JT_CHECKSUM_ALGO_TMPL: + if (parse_checksum_algo(optarg, &checksum_algo_tmpl)) + { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Problem with template checksum choices: %s \n", optarg); +#else + fprintf(stderr, "Problem with template checksum choices: %s\n", optarg); + exit(1); +#endif + } + break; + +#endif /* JIGDO_TEMPLATE */ + case OPTION_NOBAK: + all_files = 0; + break; + case 'b': + do_sort++; /* We sort bootcat/botimage */ + use_eltorito++; + boot_image = optarg; /* pathname of the boot image */ + /* on disk */ + if (boot_image == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Required Eltorito boot image pathname missing\n"); +#else + fprintf(stderr, + "Required Eltorito boot image pathname missing\n"); + exit(1); +#endif + } + get_boot_entry(); + current_boot_entry->boot_image = boot_image; + break; + case OPTION_ALT_BOOT: + /* + * Start new boot entry parameter list. + */ + new_boot_entry(); + break; + case OPTION_BOOTALPHA: + use_alphaboot++; + /* list of pathnames of boot images */ + add_boot_alpha_filename(optarg); + break; + case OPTION_HPPA_CMDLINE: + use_hppaboot++; + add_boot_hppa_cmdline(optarg); + break; + case OPTION_HPPA_KERNEL_32: + use_hppaboot++; + add_boot_hppa_kernel_32(optarg); + break; + case OPTION_HPPA_KERNEL_64: + use_hppaboot++; + add_boot_hppa_kernel_64(optarg); + break; + case OPTION_HPPA_BOOTLOADER: + use_hppaboot++; + add_boot_hppa_bootloader(optarg); + break; + case OPTION_HPPA_RAMDISK: + use_hppaboot++; + /* list of pathnames of boot images */ + add_boot_hppa_ramdisk(optarg); + break; + case OPTION_BOOTMIPS: + use_mipsboot++; + /* list of pathnames of boot images */ + add_boot_mips_filename(optarg); + break; + case OPTION_BOOTMIPSEL: + use_mipselboot++; + add_boot_mipsel_filename(optarg); + break; + case 'B': + if (use_sunx86boot) + comerrno(EX_BAD, + "-sparc-boot and -sunx86-boot are mutual exclusive.\n"); + use_sparcboot++; + /* list of pathnames of boot images */ + scan_sparc_boot(optarg); + break; + case OPTION_SUNX86BOOT: + if (use_sparcboot) + comerrno(EX_BAD, + "-sparc-boot and -sunx86-boot are mutual exclusive.\n"); + use_sunx86boot++; + /* list of pathnames of boot images */ + scan_sunx86_boot(optarg); + break; + case 'G': + use_genboot++; + /* pathname of the boot image on disk */ + genboot_image = optarg; + if (genboot_image == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Required generic boot image pathname missing\n"); +#else + fprintf(stderr, + "Required generic boot image pathname missing\n"); + exit(1); +#endif + } + break; + case OPTION_SPARCLABEL: + /* Sun disk label string */ + sparc_boot_label(optarg); + break; + case OPTION_SUNX86LABEL: + /* Sun disk label string */ + sunx86_boot_label(optarg); + break; + case 'c': + use_eltorito++; + /* pathname of the boot image on cd */ + boot_catalog = optarg; + if (boot_catalog == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Required boot catalog pathname missing\n"); +#else + fprintf(stderr, + "Required boot catalog pathname missing\n"); + exit(1); +#endif + } + break; + case OPTION_ABSTRACT: + abstract = optarg; + if (strlen(abstract) > 37) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Abstract filename string too long\n"); +#else + fprintf(stderr, + "Abstract filename string too long\n"); + exit(1); +#endif + } + break; + case 'A': + appid = optarg; + if (strlen(appid) > 128) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Application-id string too long\n"); +#else + fprintf(stderr, + "Application-id string too long\n"); + exit(1); +#endif + } + break; + case OPTION_BIBLIO: + biblio = optarg; + if (strlen(biblio) > 37) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Bibliographic filename string too long\n"); +#else + fprintf(stderr, + "Bibliographic filename string too long\n"); + exit(1); +#endif + } + break; + case OPTION_CACHE_INODES: + cache_inodes = 1; + break; + case OPTION_NOCACHE_INODES: + cache_inodes = 0; + break; + case OPTION_CHECK_OLDNAMES: + check_oldnames++; + break; + case OPTION_CHECK_SESSION: + check_session++; + check_oldnames++; + merge_image = optarg; + outfile = "/dev/null"; + /* + * cdrecord_data is handled specially in multi.c + * as we cannot write to all strings. + * If genisoimage is called with -C xx,yy + * our default is overwritten. + */ +/* cdrecord_data = "0,0";*/ + break; + case OPTION_COPYRIGHT: + copyright = optarg; + if (strlen(copyright) > 37) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Copyright filename string too long\n"); +#else + fprintf(stderr, + "Copyright filename string too long\n"); + exit(1); +#endif + } + break; + case OPTION_DEBUG: + debug++; + break; + case 'd': + omit_period++; + warn_violate++; + break; + case 'D': + RR_relocation_depth = 32767; + break; + case 'f': + follow_links++; + break; + case 'l': + full_iso9660_filenames++; + break; + case OPTION_MAX_FILENAMES: + iso9660_namelen = MAX_ISONAME_V1; /* allow 37 chars */ + full_iso9660_filenames++; + omit_version_number++; + warn_violate++; + break; + case 'L': + /* FALLTHRU */ + case OPTION_ALLOW_LEADING_DOTS: + allow_leading_dots++; + warn_violate++; + break; + case OPTION_LOG_FILE: + log_file = optarg; + break; + case 'M': + merge_image = optarg; + break; + case OPTION_RELOC_ROOT: + reloc_root = optarg; + break; + case OPTION_RELOC_OLD_ROOT: + reloc_old_root = optarg; + break; + case 'N': + omit_version_number++; + warn_violate++; + break; + case OPTION_FORCE_RR: + force_rr++; + break; + case OPTION_NO_RR: + no_rr++; + break; + case 'o': + outfile = optarg; + break; + case OPTION_PAD: + dopad++; + break; + case OPTION_NOPAD: + dopad = 0; + break; + case OPTION_P_LIST: + pathnames = optarg; + break; + case 'p': + preparer = optarg; + if (strlen(preparer) > 128) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Preparer string too long\n"); +#else + fprintf(stderr, "Preparer string too long\n"); + exit(1); +#endif + } + break; + case OPTION_PRINT_SIZE: + print_size++; + break; + case 'P': + /* FALLTHRU */ + case OPTION_PUBLISHER: + publisher = optarg; + if (strlen(publisher) > 128) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Publisher string too long\n"); +#else + fprintf(stderr, "Publisher string too long\n"); + exit(1); +#endif + } + break; + case OPTION_QUIET: + verbose = 0; + break; + case 'R': + use_RockRidge++; + break; + case 'r': + rationalize_all++; + use_RockRidge++; + break; + case OPTION_XA: + use_XA++; + break; + case OPTION_XA_RATIONALIZED: + rationalize_all++; + use_XA++; + break; + + case 's': + if (strcmp(optarg, "data") == 0) + osecsize = 2048; + else if (strcmp(optarg, "xa1") == 0) + osecsize = 2056; + else if (strcmp(optarg, "raw") == 0) { + osecsize = 2352; + comerrno(EX_BAD, + "Unsupported sector type '%s'.\n", + optarg); + } + break; + case 'S': +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Option -%c is reserved for future use.\n", c); +#else + fprintf(stderr, "Option -%c is reserved for future use.\n", c); +#endif + susage(1); + /* NOTREACHED */ + + case OPTION_NEW_DIR_MODE: + rationalize++; + { + char *end = 0; + + new_dir_mode = strtol(optarg, &end, 8); + if (!end || *end != 0 || + new_dir_mode < 0 || new_dir_mode > 07777) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Bad mode for -new-dir-mode\n"); +#else + fprintf(stderr, "Bad mode for -new-dir-mode\n"); + exit(1); +#endif + } + break; + } + + case OPTION_UID: + rationalize++; + use_RockRidge++; + rationalize_uid++; + { + char *end = 0; + + uid_to_use = strtol(optarg, &end, 0); + if (!end || *end != 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Bad value for -uid\n"); +#else + fprintf(stderr, "Bad value for -uid\n"); + exit(1); +#endif + } + break; + } + + case OPTION_GID: + rationalize++; + use_RockRidge++; + rationalize_gid++; + { + char *end = 0; + + gid_to_use = strtol(optarg, &end, 0); + if (!end || *end != 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Bad value for -gid\n"); +#else + fprintf(stderr, "Bad value for -gid\n"); + exit(1); +#endif + } + break; + } + + case OPTION_FILEMODE: + rationalize++; + use_RockRidge++; + rationalize_filemode++; + { + char *end = 0; + + filemode_to_use = strtol(optarg, &end, 8); + if (!end || *end != 0 || + filemode_to_use < 0 || filemode_to_use > 07777) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Bad mode for -file-mode\n"); +#else + fprintf(stderr, "Bad mode for -file-mode\n"); + exit(1); +#endif + } + break; + } + + case OPTION_DIRMODE: + rationalize++; + use_RockRidge++; + rationalize_dirmode++; + { + char *end = 0; + + dirmode_to_use = strtol(optarg, &end, 8); + if (!end || *end != 0 || + dirmode_to_use < 0 || dirmode_to_use > 07777) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Bad mode for -dir-mode\n"); +#else + fprintf(stderr, "Bad mode for -dir-mode\n"); + exit(1); +#endif + } + break; + } + +#ifdef SORTING + case OPTION_SORT: + do_sort++; + add_sort_list(optarg); + break; +#endif /* SORTING */ + + case OPTION_SPLIT_OUTPUT: + split_output++; + break; + + case OPTION_STREAM_FILE_NAME: + stream_filename = optarg; + break; + + case OPTION_STREAM_CD_SIZE: + stream_media_size = atoi(optarg); + break; + + case OPTION_SYSID: + system_id = optarg; + if (strlen(system_id) > 32) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "System ID string too long\n"); +#else + fprintf(stderr, "System ID string too long\n"); + exit(1); +#endif + } + break; + case OPTION_TRANS_TBL: + trans_tbl = optarg; + /* FALLTHRU */ + case 'T': + generate_tables++; + break; + case OPTION_UCS_LEVEL: + ucs_level = atoi(optarg); + if (ucs_level < 1 || ucs_level > 3) + comerrno(EX_BAD, "Illegal UCS Level %d, use 1..3.\n", + ucs_level); + break; +#ifdef UDF + case OPTION_UDF: + use_udf++; + break; +#endif + +#ifdef DVD_VIDEO + case OPTION_DVD: + use_udf++; + dvd_video++; + break; +#endif + case OPTION_USE_FILEVERSION: + use_fileversion++; + break; + case 'U': + /* + * Minimal (only truncation of 31+ characters) + * translation of filenames. + * + * Forces -l, -d, -N, -allow-leading-dots, + * -relaxed-filenames, + * -allow-lowercase, -allow-multidot + * + * This is for HP-UX, which does not recognize ANY + * extentions (Rock Ridge, Joliet), causing pain when + * loading software. pfs_mount can be used to read the + * extensions, but the untranslated filenames can be + * read by the "native" cdfs mounter. Completely + * violates iso9660. + */ + full_iso9660_filenames++; /* 31 chars */ + omit_period++; /* trailing dot */ + allow_leading_dots++; + omit_version_number++; + relaxed_filenames++; /* all chars */ + allow_lowercase++; /* even lowcase */ + allow_multidot++; /* > 1 dots */ + warn_violate++; + break; + + case OPTION_RELAXED_FILENAMES: + relaxed_filenames++; + warn_violate++; + break; + case OPTION_ALLOW_LOWERCASE: + allow_lowercase++; + warn_violate++; + break; + case OPTION_ALLOW_MULTIDOT: + allow_multidot++; + warn_violate++; + break; + case OPTION_ISO_TRANSLATE: + iso_translate = 0; + warn_violate++; + break; + case 'V': + volume_id = optarg; + if (strlen(volume_id) > 32) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Volume ID string too long\n"); +#else + fprintf(stderr, + "Volume ID string too long\n"); + exit(1); +#endif + } + break; + case OPTION_VOLSET: + volset_id = optarg; + if (strlen(volset_id) > 128) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Volume set ID string too long\n"); +#else + fprintf(stderr, + "Volume set ID string too long\n"); + exit(1); +#endif + } + break; + case OPTION_VOLSET_SIZE: + volume_set_size = atoi(optarg); + if (volume_set_size <= 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Illegal Volume Set Size %s\n", optarg); +#else + fprintf(stderr, + "Illegal Volume Set Size %s\n", optarg); + exit(1); +#endif + } + if (volume_set_size > 1) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Volume Set Size > 1 not yet supported\n"); +#else + fprintf(stderr, + "Volume Set Size > 1 not yet supported\n"); + exit(1); +#endif + } + break; + case OPTION_VOLSET_SEQ_NUM: + volume_sequence_number = atoi(optarg); + if (volume_sequence_number > volume_set_size) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Volume set sequence number too big\n"); +#else + fprintf(stderr, + "Volume set sequence number too big\n"); + exit(1); +#endif + } + break; + case 'v': + verbose++; + break; + case 'z': +#ifdef VMS +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Transparent compression not supported with VMS\n"); +#else + fprintf(stderr, + "Transparent compression not supported with VMS\n"); + exit(1); +#endif +#else + transparent_compression++; +#endif + break; + case 'x': + case 'm': + /* + * Somehow two options to do basically the same thing + * got added somewhere along the way. The 'match' + * code supports limited globbing, so this is the one + * that got selected. Unfortunately the 'x' switch is + * probably more intuitive. + */ + add_match(optarg); + break; + case OPTION_X_LIST: + add_list(optarg); + break; + case OPTION_I_HIDE: + i_add_match(optarg); + break; + case OPTION_I_LIST: + i_add_list(optarg); + break; + case OPTION_H_HIDE: + h_add_match(optarg); + break; + case OPTION_H_LIST: + h_add_list(optarg); + break; + case OPTION_J_HIDE: + j_add_match(optarg); + break; + case OPTION_J_LIST: + j_add_list(optarg); + break; + case OPTION_HIDE_TRANS_TBL: + jhide_trans_tbl++; + break; + case OPTION_HIDE_RR_MOVED: + hide_rr_moved++; + break; + case OPTION_HELP: + usage(0); + break; + case OPTION_PVERSION: + if(mkisofs_call) + printf("mkisofs 2.01 is not what you see here. This line is only a fake for too clever\n" + "GUIs and other frontend applications. In fact, this program is:\n"); + printf("%s (%s)\n", version_string, HOST_SYSTEM); + exit(0); + break; + case OPTION_NOSPLIT_SL_COMPONENT: + split_SL_component = 0; + break; + case OPTION_NOSPLIT_SL_FIELD: + split_SL_field = 0; + break; + case OPTION_HARD_DISK_BOOT: + use_eltorito++; + hard_disk_boot++; + get_boot_entry(); + current_boot_entry->hard_disk_boot = 1; + break; + case OPTION_NO_EMUL_BOOT: + use_eltorito++; + no_emul_boot++; + get_boot_entry(); + current_boot_entry->no_emul_boot = 1; + break; + case OPTION_NO_BOOT: + use_eltorito++; + not_bootable++; + get_boot_entry(); + current_boot_entry->not_bootable = 1; + break; + case OPTION_BOOT_LOAD_ADDR: + use_eltorito++; + { + long val; + char *ptr; + + val = strtol(optarg, &ptr, 0); + if (*ptr || val < 0 || val >= 0x10000) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Boot image load address invalid.\n"); +#else + fprintf(stderr, "Boot image load address invalid.\n"); + exit(1); +#endif + } + load_addr = val; + } + get_boot_entry(); + current_boot_entry->load_addr = load_addr; + break; + case OPTION_BOOT_LOAD_SIZE: + use_eltorito++; + { + long val; + char *ptr; + + val = strtol(optarg, &ptr, 0); + if (*ptr || val < 0 || val >= 0x10000) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image load size invalid.\n"); +#else + fprintf(stderr, + "Boot image load size invalid.\n"); + exit(1); +#endif + } + load_size = val; + } + get_boot_entry(); + current_boot_entry->load_size = load_size; + break; + case OPTION_BOOT_INFO_TABLE: + use_eltorito++; + boot_info_table++; + get_boot_entry(); + current_boot_entry->boot_info_table = 1; + break; +#ifdef APPLE_HYB + case OPTION_HFS_TYPE: + deftype = optarg; + hfs_ct++; + if (strlen(deftype) != 4) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "HFS default TYPE string has illegal length.\n"); +#else + fprintf(stderr, + "HFS default TYPE string has illegal length.\n"); + exit(1); +#endif + } + break; + case OPTION_HFS_CREATOR: + defcreator = optarg; + hfs_ct++; + if (strlen(defcreator) != 4) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "HFS default CREATOR string has illegal length.\n"); +#else + fprintf(stderr, + "HFS default CREATOR string has illegal length.\n"); + exit(1); +#endif + } + break; + case 'H': + /* FALLTHRU */ + case OPTION_MAP_FILE: + afpfile = optarg; + hfs_last = MAP_LAST; + break; + case 'h': + apple_hyb = 1; + break; + case 'g': + apple_ext = 1; + break; + case OPTION_PROBE: + probe = 1; + break; + case OPTION_MACNAME: + use_mac_name = 1; + break; + case OPTION_NOMACFILES: +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: -no-mac-files no longer used ... ignoring\n"); +#else + fprintf(stderr, + "Warning: -no-mac-files no longer used ... ignoring\n"); +#endif + break; + case OPTION_BOOT_HFS_FILE: + hfs_boot_file = optarg; + /* FALLTHRU */ + case OPTION_GEN_PT: + gen_pt = 1; + break; + case OPTION_MAGIC_FILE: +#ifndef USE_MAGIC + fprintf(stderr, "This program has been compiled without magic library support.\n" + "Ignoring the -magic option.\n"); +#endif + magic_filename = optarg; + hfs_last = MAG_LAST; + break; + case OPTION_AUTOSTART: + autoname = optarg; + /* gen_pt = 1; */ + break; + case OPTION_BSIZE: + afe_size = atoi(optarg); + hfs_select |= DO_FEU; + hfs_select |= DO_FEL; + break; + case OPTION_HFS_VOLID: + hfs_volume_id = optarg; + break; + case OPTION_ROOT_INFO: + root_info = optarg; + /* FALLTHRU */ + case OPTION_ICON_POS: + icon_pos = 1; + break; + /* Mac/Unix types to include */ + case OPTION_CAP: + hfs_select |= DO_CAP; + break; + case OPTION_NETA: + hfs_select |= DO_NETA; + break; + case OPTION_DBL: + hfs_select |= DO_DBL; + break; + case OPTION_ESH: + case OPTION_USH: + hfs_select |= DO_ESH; + break; + case OPTION_FE: + hfs_select |= DO_FEU; + hfs_select |= DO_FEL; + break; + case OPTION_SGI: + case OPTION_XIN: + hfs_select |= DO_SGI; + break; + case OPTION_MBIN: + hfs_select |= DO_MBIN; + break; + case OPTION_SGL: + hfs_select |= DO_SGL; + break; + case OPTION_DAVE: + hfs_select |= DO_DAVE; + break; + case OPTION_SFM: + hfs_select |= DO_SFM; + break; + case OPTION_XDBL: + hfs_select |= DO_XDBL; + break; + case OPTION_XHFS: +#ifdef IS_MACOS_X + hfs_select |= DO_XHFS; +#else /* IS_MACOS_X */ +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: --osx-hfs only works on MacOS X ... ignoring\n"); +#else /* USE_LIBSCHILY */ + fprintf(stderr, + "Warning: --osx-hfs only works on MacOS X ... ignoring\n"); +#endif /* USE_LIBSCHILY */ +#endif /* IS_MACOS_X */ + break; + case OPTION_CREATE_DT: + create_dt = 0; + break; + case OPTION_HFS_HIDE: + hfs_add_match(optarg); + break; + case OPTION_HFS_LIST: + hfs_add_list(optarg); + break; + case OPTION_HFS_INPUT_CHARSET: + use_mac_name = 1; + hfs_icharset = optarg; + break; + case OPTION_HFS_OUTPUT_CHARSET: + hfs_ocharset = optarg; + break; + case OPTION_HFS_UNLOCK: + hfs_lock = 0; + break; + case OPTION_HFS_BLESS: + hfs_bless = optarg; + break; + case OPTION_HFS_PARMS: + hfs_parms = strdup(optarg); + break; +#ifdef PREP_BOOT + case OPTION_PREP_BOOT: + use_prep_boot++; + if (use_prep_boot > 4 - use_chrp_boot) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Maximum of 4 PRep+CHRP partition entries are allowed\n"); +#else + fprintf(stderr, + "Maximum of 4 PRep+CHRP partition entries are allowed\n"); +#endif + exit(1); + } + /* pathname of the boot image on cd */ + prep_boot_image[use_prep_boot - 1] = optarg; + if (prep_boot_image[use_prep_boot - 1] == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Required PReP boot image pathname missing\n"); +#else + fprintf(stderr, + "Required PReP boot image pathname missing\n"); +#endif + exit(1); + } + break; + case OPTION_CHRP_BOOT: + if (use_chrp_boot) + break; /* silently allow duplicates */ + use_chrp_boot = 1; + if (use_prep_boot > 3) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Maximum of 4 PRep+CHRP partition entries are allowed\n"); +#else + fprintf(stderr, + "Maximum of 4 PRep+CHRP partition entries are allowed\n"); +#endif + exit(1); + } + break; +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + case OPTION_ALLOW_LIMITED_SIZE: + allow_limited_size++; + use_udf++; + break; + default: + susage(1); + } + /* + * "--" was found, the next argument is a pathspec + */ + if (argc != optind) + have_cmd_line_pathspec = 1; + +parse_input_files: + path_ind = optind; + + /* + * XXX This is a hack until we have a decent separate name handling + * XXX for UDF filenames. + */ + if (dvd_video && use_Joliet) { + use_Joliet = 0; + fprintf(stderr, "Warning: Disabling Joliet support for DVD-Video.\n"); + } + if (use_udf && !use_Joliet) + jlen = 255; + + if (preparer) { + if (strlen(preparer) > 128) { + comerrno(EX_BAD, "Preparer string too long\n"); + } + } + if (publisher) { + if (strlen(publisher) > 128) { + comerrno(EX_BAD, + "Publisher string too long\n"); + } + } + if (stream_filename) { + if (strlen(stream_filename) > MAX_ISONAME) + comerrno(EX_BAD, + "stream-file-name too long (%d), max is %d.\n", + (int)strlen(stream_filename), (int)MAX_ISONAME); + if (strchr(stream_filename, '/')) + comerrno(EX_BAD, "Illegal character '/' in stream-file-name.\n"); + iso9660_level = 4; + } else { + stream_filename = "STREAM.IMG;1"; + } + if (system_id) { + if (strlen(system_id) > 32) { + comerrno(EX_BAD, + "System ID string too long\n"); + } + } + + + if (use_RockRidge && (iso9660_namelen > MAX_ISONAME_V2_RR)) + iso9660_namelen = MAX_ISONAME_V2_RR; + + if (warn_violate) /* this one is enough for quiet mode, print others warnings only in more verbose modes */ + fprintf(stderr, "Warning: creating filesystem that does not conform to ISO-9660.\n"); + if (iso9660_level > 3 && verbose>0) + fprintf(stderr, "Warning: Creating ISO-9660:1999 (version 2) filesystem.\n"); + if (iso9660_namelen > LEN_ISONAME && verbose>0) + fprintf(stderr, "Warning: ISO-9660 filenames longer than %d may cause buffer overflows in the OS.\n", + LEN_ISONAME); + if (use_Joliet && !use_RockRidge && verbose>0) { + fprintf(stderr, + "Warning: creating filesystem with Joliet extensions but without Rock Ridge\n" + " extensions. It is highly recommended to add Rock Ridge.\n"); + } + if (transparent_compression && verbose>0) { + fprintf(stderr, "Warning: using transparent compression. This is a nonstandard Rock Ridge\n"); + fprintf(stderr, " extension. The resulting filesystem can only be transparently\n"); + fprintf(stderr, " read on Linux. On other operating systems you need to call\n"); + fprintf(stderr, " mkzftree by hand to decompress the files.\n"); + } + if (transparent_compression && !use_RockRidge && verbose>0) { + fprintf(stderr, "Warning: transparent decompression is a Linux Rock Ridge extension, but\n"); + fprintf(stderr, " creating filesystem without Rock Ridge attributes; files\n"); + fprintf(stderr, " will not be transparently decompressed.\n"); + } + if(follow_links && verbose>0) + fprintf(stderr, + "Warning: -follow-links does not always work correctly; be careful.\n"); + + init_unls(); /* Initialize UNICODE tables */ + + /* initialize code tables from a file - if they exists */ + init_unls_file(icharset); + init_unls_file(ocharset); +#ifdef APPLE_HYB + init_unls_file(hfs_icharset); + init_unls_file(hfs_ocharset); +#endif /* APPLE_HYB */ + +#ifdef USE_ICONV + iconv_possible = !(iso9660_level >= 4 || ((ocharset && + strcmp(ocharset, icharset ? icharset : "")) && + use_RockRidge) || apple_ext || apple_hyb); + + setlocale(LC_CTYPE, ""); + + if (icharset == NULL && iconv_possible) { + char *charset = nl_langinfo(CODESET); + /* set to detected value but only if it is not pure US-ASCII */ + if(charset) { /* workaround for SunOS, iconv is case-sensitive */ + char *t; + charset = strdup(charset); + for(t=charset;*t!='\0';t++) + *t=tolower(*t); + } + + if(strcmp(charset, "ansi_x3.4-1968") != 0) + icharset = charset; + + if(icharset && verbose > 0) + fprintf(stderr, "I: -input-charset not specified, using %s (detected in locale settings)\n", + icharset); + } + + if(iconv_possible) { + /* + * don't care if initialization fails + */ + init_nls_iconv(icharset); + init_nls_iconv(ocharset); + } +#endif + + if (icharset == NULL) { +#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__)) && !defined(IS_CYGWIN_1) + in_nls = load_unls("cp437"); +#else + in_nls = load_unls("iso8859-1"); +#endif + } else { + if (strcmp(icharset, "default") == 0) + in_nls = load_unls_default(); + else + in_nls = load_unls(icharset); + } + /* + * set the output charset to the same as the input or the given output + * charset + */ + if (ocharset == NULL) { + out_nls = in_nls; + } else { + if (strcmp(ocharset, "default") == 0) + out_nls = load_unls_default(); + else + out_nls = load_unls(ocharset); + } + if (in_nls == NULL || out_nls == NULL) { /* Unknown charset specified */ + fprintf(stderr, "Unknown charset\nKnown charsets are:\n"); + list_unls(); /* List all known charset names */ +#ifdef USE_ICONV + fprintf(stderr, "\nAdditional input charsets are available for Joliet through the iconv support." + "\nRun \"iconv -l\" to display them. Iconv charsets cannot be used with HFS, Apple" + "\nextension, ISO9660 version 2 or Rock Ridge.\n"); +#endif + exit(1); + } + + +#ifdef APPLE_HYB + if (hfs_icharset == NULL || strcmp(hfs_icharset, "mac-roman")) { + hfs_inls = load_unls("cp10000"); + } else { + if (strcmp(hfs_icharset, "default") == 0) + hfs_inls = load_unls_default(); + else + hfs_inls = load_unls(hfs_icharset); + } + if (hfs_ocharset == NULL) { + hfs_onls = hfs_inls; + } else { + if (strcmp(hfs_ocharset, "default") == 0) + hfs_onls = load_unls_default(); + else if (strcmp(hfs_ocharset, "mac-roman") == 0) + hfs_onls = load_unls("cp10000"); + else + hfs_onls = load_unls(hfs_ocharset); + } + + if (hfs_inls == NULL || hfs_onls == NULL) { + fprintf(stderr, "Unknown HFS charset\nKnown charsets are:\n"); + list_unls(); + exit(1); + } +#endif /* APPLE_HYB */ + + if (merge_image != NULL) { + if (open_merge_image(merge_image) < 0) { + /* Complain and die. */ +#ifdef USE_LIBSCHILY + comerr("Unable to open previous session image '%s'.\n", + merge_image); +#else + fprintf(stderr, + "Unable to open previous session image '%s'.\n", + merge_image); + exit(1); +#endif + } + } + /* 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 +#ifdef USE_LIBSCHILY + comerr("Panic cannot set back effective uid.\n"); +#else + { + perror("Panic cannot set back effective uid."); + exit(1); + } +#endif + + +#ifdef no_more_needed +#ifdef __NetBSD__ + { + int resource; + struct rlimit rlp; + + if (getrlimit(RLIMIT_DATA, &rlp) == -1) + perror("Warning: getrlimit failed"); + else { + rlp.rlim_cur = 33554432; + if (setrlimit(RLIMIT_DATA, &rlp) == -1) + perror("Warning: setrlimit failed"); + } + } +#endif +#endif /* no_more_needed */ +#ifdef HAVE_SBRK + mem_start = (unsigned long) sbrk(0); +#endif + + /* + * if the -hide-joliet option has been given, set the Joliet option + */ + if (!use_Joliet && j_ishidden()) + use_Joliet++; + +#ifdef APPLE_HYB + if (apple_hyb && apple_ext) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Can't have both -apple and -hfs options"); +#else + fprintf(stderr, "Can't have both -apple and -hfs options"); + exit(1); +#endif + } + /* + * if -probe, -macname, any hfs selection and/or mapping file is given, + * but no HFS option, then select apple_hyb + */ + if (!apple_hyb && !apple_ext) { + if (*afpfile || probe || use_mac_name || hfs_select || + hfs_boot_file || magic_filename || + hfs_ishidden() || gen_pt || autoname || + afe_size || icon_pos || hfs_ct || + hfs_icharset || hfs_ocharset) { + apple_hyb = 1; + } + } + if (apple_ext && hfs_boot_file) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Can't have -hfs-boot-file with -apple\n"); +#else + fprintf(stderr, "Can't have -hfs-boot-file with -apple\n"); + exit(1); +#endif + } + if (apple_ext && autoname) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Can't have -auto with -apple\n"); +#else + fprintf(stderr, "Can't have -auto with -apple\n"); + exit(1); +#endif + } + if (apple_hyb && (use_sparcboot || use_sunx86boot)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Can't have -hfs with -sparc-boot/-sunx86-boot\n"); +#else + fprintf(stderr, "Can't have -hfs with -sparc-boot/-sunx86-boot\n"); + exit(1); +#endif + } + if (apple_hyb && use_genboot) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Can't have -hfs with -generic-boot\n"); +#else + fprintf(stderr, "Can't have -hfs with -generic-boot\n"); + exit(1); +#endif + } +#ifdef PREP_BOOT + if (apple_ext && use_prep_boot) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Can't have -prep-boot with -apple\n"); +#else + fprintf(stderr, "Can't have -prep-boot with -apple\n"); + exit(1); +#endif + } +#endif /* PREP_BOOT */ + + if (apple_hyb || apple_ext) + apple_both = 1; + + if (probe) + /* we need to search for all types of Apple/Unix files */ + hfs_select = ~0; + + if (apple_both && verbose && !(hfs_select || *afpfile || magic_filename)) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: no Apple/Unix files will be decoded/mapped\n"); +#else + fprintf(stderr, + "Warning: no Apple/Unix files will be decoded/mapped\n"); +#endif + } + if (apple_both && verbose && !afe_size && + (hfs_select & (DO_FEU | DO_FEL))) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: assuming PC Exchange cluster size of 512 bytes\n"); +#else + fprintf(stderr, + "Warning: assuming PC Exchange cluster size of 512 bytes\n"); +#endif + afe_size = 512; + } + if (apple_both) { + /* set up the TYPE/CREATOR mappings */ + hfs_init(afpfile, 0, hfs_select); + } + if (apple_ext && !use_RockRidge) { +#ifdef nonono + /* use RockRidge to set the SystemUse field ... */ + use_RockRidge++; + rationalize_all++; +#else + /* EMPTY */ +#endif + } + if (apple_ext && !(use_XA || use_RockRidge)) { + comerrno(EX_BAD, "Need either -XA/-xa or -R/-r for -apple to become active.\n"); + } + +#endif /* APPLE_HYB */ + + if (rationalize_all) { + rationalize++; + rationalize_uid++; + rationalize_gid++; + rationalize_filemode++; + rationalize_dirmode++; + } + + if (verbose > 1) { + fprintf(stderr, "%s (%s)\n", version_string, HOST_SYSTEM); + } + if (cdrecord_data == NULL && !check_session && merge_image != NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Multisession usage bug: Must specify -C if -M is used.\n"); +#else + fprintf(stderr, + "Multisession usage bug: Must specify -C if -M is used.\n"); + exit(1); +#endif + } + if (cdrecord_data != NULL && merge_image == NULL) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: -C specified without -M: old session data will not be merged.\n"); +#else + fprintf(stderr, + "Warning: -C specified without -M: old session data will not be merged.\n"); +#endif + } +#ifdef APPLE_HYB + if (merge_image != NULL && apple_hyb) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: files from previous sessions will not be included in the HFS volume.\n"); +#else + fprintf(stderr, + "Warning: files from previous sessions will not be included in the HFS volume.\n"); +#endif + } +#endif /* APPLE_HYB */ + + /* + * see if we have a list of pathnames to process + */ + if (pathnames) { + /* "-" means take list from the standard input */ + if (strcmp(pathnames, "-")) { + if ((pfp = fopen(pathnames, "r")) == NULL) { +#ifdef USE_LIBSCHILY + comerr("Unable to open pathname list %s.\n", + pathnames); +#else + fprintf(stderr, + "Unable to open pathname list %s.\n", + pathnames); + exit(1); +#endif + } + } else + pfp = stdin; + } + + /* The first step is to scan the directory tree, and take some notes */ + + if ((arg = get_pnames(argc, argv, optind, pname, + sizeof (pname), pfp)) == NULL) { + if (check_session == 0 && !stream_media_size) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Missing pathspec.\n"); +#endif + susage(1); + } + } + + /* + * if we don't have a pathspec, then save the pathspec found + * in the pathnames file (stored in pname) - we don't want + * to skip this pathspec when we read the pathnames file again + */ + if (!have_cmd_line_pathspec && !stream_media_size) { + save_pname = 1; + } + if (stream_media_size) { + if (use_XA || use_RockRidge || use_udf || use_Joliet) + comerrno(EX_BAD, + "Cannot use XA, Rock Ridge, UDF or Joliet with -stream-media-size\n"); + if (merge_image) + comerrno(EX_BAD, + "Cannot use multi session with -stream-media-size\n"); + if (use_eltorito || use_sparcboot || use_sunx86boot || + use_genboot || use_prep_boot || hfs_boot_file) + comerrno(EX_BAD, + "Cannot use boot options with -stream-media-size\n"); + if (apple_hyb) + comerrno(EX_BAD, + "Cannot use Apple hybrid options with -stream-media-size\n"); + } + + if (use_RockRidge) { + /* BEGIN CSTYLED */ +#if 1 + extension_record = generate_rr_extension_record("RRIP_1991A", + "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", + "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", + &extension_record_size); +#else + extension_record = generate_rr_extension_record("IEEE_P1282", + "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", + "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", + &extension_record_size); +#endif + /* END CSTYLED */ + } + if (log_file) { + FILE *lfp; + int i; + + /* open log file - test that we can open OK */ + if ((lfp = fopen(log_file, "w")) == NULL) { +#ifdef USE_LIBSCHILY + comerr("Can't open logfile: '%s'.\n", log_file); +#else + fprintf(stderr, "Can't open logfile: '%s'.\n", log_file); + exit(1); +#endif + } + fclose(lfp); + + /* redirect all stderr message to log_file */ + fprintf(stderr, "re-directing all messages to %s\n", log_file); + fflush(stderr); + + /* associate stderr with the log file */ + if (freopen(log_file, "w", stderr) == NULL) { +#ifdef USE_LIBSCHILY + comerr("Can't open logfile: '%s'.\n", log_file); +#else + fprintf(stderr, "Can't open logfile: '%s'.\n", log_file); + exit(1); +#endif + } + if (verbose > 1) { + for (i = 0; i < argc; i++) + fprintf(stderr, "%s ", argv[i]); + + fprintf(stderr, "\n%s (%s)\n", + version_string, HOST_SYSTEM); + } + } + /* Find name of root directory. */ + if (arg != NULL) + node = findgequal(arg); + if (!use_graft_ptrs) + node = NULL; + if (node == NULL) { + if (use_graft_ptrs && arg != NULL) + node = escstrcpy(nodename, arg); + else + node = arg; + } else { + /* + * Remove '\\' escape chars which are located + * before '\\' and '=' chars + */ + node = escstrcpy(nodename, ++node); + } + + /* + * See if boot catalog file exists in root directory, if not we will + * create it. + */ + if (use_eltorito) + init_boot_catalog(node); + + /* + * Find the device and inode number of the root directory. Record this + * in the hash table so we don't scan it more than once. + */ + stat_filter(node, &statbuf); + add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); + + memset(&de, 0, sizeof (de)); + + /* + * PO: + * Isn't root NULL at this time anyway? + * I think it is created by the first call to + * find_or_create_directory() below. + */ + de.filedir = root; /* We need this to bootstrap */ + + if (cdrecord_data != NULL && merge_image == NULL) { + /* + * in case we want to add a new session, but don't want to + * merge old one + */ + get_session_start(NULL); + } + if (merge_image != NULL) { + char sector[SECTOR_SIZE]; + + errno = 0; + mrootp = merge_isofs(merge_image); + if (mrootp == NULL) { + /* Complain and die. */ +#ifdef USE_LIBSCHILY + if (errno == 0) + errno = -1; + comerr("Unable to find previous session PVD '%s'.\n", + merge_image); +#else + fprintf(stderr, + "Unable to find previous session PVD '%s'.\n", + merge_image); + exit(1); +#endif + } + memcpy(de.isorec.extent, mrootp->extent, 8); + + /* + * Look for RR Attributes in '.' entry of root dir. + * This is the first ISO directory entry in the root dir. + */ + c = isonum_733((unsigned char *)mrootp->extent); +#ifdef USE_SCG + readsecs(c, sector, 1); +#else + lseek(fileno(in_image), c*2048, SEEK_SET); + read(fileno(in_image), sector, sizeof (sector)); +#endif + c = rr_flags((struct iso_directory_record *)sector); + if (c & RR_FLAG_XA) + fprintf(stderr, "XA signatures found\n"); + if (c & RR_FLAG_AA) + fprintf(stderr, "AA signatures found\n"); + if (c & ~(RR_FLAG_XA|RR_FLAG_AA)) { + if (c & RR_FLAG_SP) { + fprintf(stderr, "Rock Ridge signatures found\n"); + } else { + fprintf(stderr, "Bad Rock Ridge signatures found (SU record missing)\n"); + if (!force_rr) + no_rr++; + } + } else { + fprintf(stderr, "NO Rock Ridge present\n"); + if ((c & (RR_FLAG_XA|RR_FLAG_AA)) == 0) { + if (!force_rr) + no_rr++; + } + } + if (no_rr) + fprintf(stderr, "Disabling Rock Ridge / XA / AA\n"); + } + /* + * Create an empty root directory. If we ever scan it for real, + * we will fill in the contents. + */ + find_or_create_directory(NULL, "", &de, TRUE, NULL); + +#ifdef APPLE_HYB + /* may need to set window layout of the volume */ + if (root_info) + set_root_info(root_info); +#endif /* APPLE_HYB */ + + if(optind < argc-1) + merge_warn_msg="NOTE: multiple source directories have been specified and merged into the root\n" + "of the filesystem. Check your program arguments. genisoimage is not tar.\n"; + + /* + * Scan the actual directory (and any we find below it) for files to + * write out to the output image. Note - we take multiple source + * directories and keep merging them onto the image. + */ +if (check_session == 0) + while ((arg = get_pnames(argc, argv, optind, pname, + sizeof (pname), pfp)) != NULL) { + struct directory *graft_dir; + struct stat st; + char *short_name; + int status; + char graft_point[PATH_MAX + 1]; + + /* + * We would like a syntax like: + * + * /tmp=/usr/tmp/xxx + * + * where the user can specify a place to graft each component + * of the tree. To do this, we may have to create directories + * along the way, of course. Secondly, I would like to allow + * the user to do something like: + * + * /home/baz/RMAIL=/u3/users/baz/RMAIL + * + * so that normal files could also be injected into the tree + * at an arbitrary point. + * + * The idea is that the last component of whatever is being + * entered would take the name from the last component of + * whatever the user specifies. + * + * The default will be that the file is injected at the root of + * the image tree. + */ + node = findgequal(arg); + if (!use_graft_ptrs) + node = NULL; + /* + * Remove '\\' escape chars which are located + * before '\\' and '=' chars ---> below in escstrcpy() + */ + + short_name = NULL; + + if (node != NULL || reloc_root) { + char *pnt; + char *xpnt; + size_t len; + int node_is_dir; + + /* insert -root prefix */ + if (reloc_root != NULL) { + strcpy(graft_point, reloc_root); + len = strlen(graft_point); + if (graft_point[len] != '/') { + graft_point[len++] = '/'; + graft_point[len] = '\0'; + } + } else { + len = 0; + } + + if (node) { + *node = '\0'; + escstrcpy(&graft_point[len], arg); + *node = '='; + } + + /* + * Remove unwanted "./" & "/" sequences from start... + */ + do { + xpnt = graft_point; + while (xpnt[0] == '.' && xpnt[1] == '/') + xpnt += 2; + while (*xpnt == PATH_SEPARATOR) { + xpnt++; + } + memmove(graft_point, xpnt, strlen(xpnt)+1); + } while (xpnt > graft_point); + + if (node) { + node = escstrcpy(nodename, ++node); + } else { + node = arg; + } + + graft_dir = root; + xpnt = graft_point; + + /* + * If "node" points to a directory, then graft_point + * needs to point to a directory too. + */ + if (follow_links) + status = stat_filter(node, &st); + else + status = lstat_filter(node, &st); + + node_is_dir = S_ISDIR(st.st_mode); + if (status == 0 && node_is_dir) { + len = strlen(graft_point); + + if ((len <= (sizeof (graft_point) -1)) && + graft_point[len-1] != '/') { + graft_point[len++] = '/'; + graft_point[len] = '\0'; + } + } + if (debug) + fprintf(stderr, "GRAFT:'%s'\n", xpnt); + /* + * Loop down deeper and deeper until we find the + * correct insertion spot. + * Canonicalize the filename while parsing it. + */ + for (;;) { + struct stat* stat_template; + + do { + while (xpnt[0] == '.' && xpnt[1] == '/') + xpnt += 2; + while (xpnt[0] == '/') + xpnt += 1; + if (xpnt[0] == '.' && xpnt[1] == '.' && xpnt[2] == '/') { + if (graft_dir && graft_dir != root) { + graft_dir = graft_dir->parent; + xpnt += 2; + } + } + } while ((xpnt[0] == '/') || (xpnt[0] == '.' && xpnt[1] == '/')); + pnt = strchr(xpnt, PATH_SEPARATOR); + if (pnt == NULL) { + if (*xpnt != '\0') { + short_name = xpnt; + } + break; + } + *pnt = '\0'; + if (debug) { + fprintf(stderr, "GRAFT Point:'%s' in '%s : %s' (%s)\n", + xpnt, + graft_dir->whole_name, + graft_dir->de_name, + graft_point); + } + /* + * If the node being grafted is a + * directory, then we want the last + * directory in this graft chain to have + * the ownership and permissions of the + * source node. Other directories in the + * chain get default ownership and + * permissions. + */ + stat_template = + (pnt[1] == '\0' && node_is_dir) ? &st : 0; + + graft_dir = find_or_create_directory(graft_dir, + graft_point, NULL, TRUE, + stat_template); + + *pnt = PATH_SEPARATOR; + xpnt = pnt + 1; + } + } else { + graft_dir = root; + if (use_graft_ptrs) + node = escstrcpy(nodename, arg); + else + node = arg; + } + + /* + * Get information on the node + */ + if (follow_links) + status = stat_filter(node, &st); + else + status = lstat_filter(node, &st); + if (status != 0) { + /* + * This is a fatal error - the user won't be getting + * what they want if we were to proceed. + */ +#ifdef USE_LIBSCHILY + comerr("Invalid node - '%s'.\n", node); +#else + fprintf(stderr, "Invalid node - '%s'.\n", node); + exit(1); +#endif + } else { + /* + * Now see whether the user wants to add a regular + * file or a directory at this point. + */ + if (S_ISDIR(st.st_mode)) { + if (debug) { + fprintf(stderr, "graft_dir: '%s : %s', node: '%s', (scan)\n", + graft_dir->whole_name, + graft_dir->de_name, node); + } + if (!scan_directory_tree(graft_dir, + node, &de)) { + exit(1); + } + if (debug) { + fprintf(stderr, "scan done\n"); + } + } else { + if (short_name == NULL) { + short_name = strrchr(node, + PATH_SEPARATOR); + if (short_name == NULL || + short_name < node) { + short_name = node; + } else { + short_name++; + } + } + if (debug) { + fprintf(stderr, "graft_dir: '%s : %s', node: '%s', short_name: '%s'\n", + graft_dir->whole_name, + graft_dir->de_name, node, + short_name); + } +#ifdef APPLE_HYB + if (!insert_file_entry(graft_dir, node, + short_name, 0)) +#else + if (!insert_file_entry(graft_dir, node, + short_name)) +#endif /* APPLE_HYB */ + { + /* + * Should we ignore this? + */ +/* exit(1);*/ + /* EMPTY */ + } + } + } + + optind++; + no_path_names = 0; + } + + if (pfp && pfp != stdin) + fclose(pfp); + + /* + * exit if we don't have any pathnames to process + * - not going to happen at the moment as we have to have at least one + * path on the command line + */ + if (no_path_names && !check_session && !stream_media_size) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "No pathnames found.\n"); +#endif + susage(1); + } + /* + * Now merge in any previous sessions. This is driven on the source + * side, since we may need to create some additional directories. + */ + if (merge_image != NULL) { + if (merge_previous_session(root, mrootp, + reloc_root, reloc_old_root) < 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Cannot merge previous session.\n"); +#else + fprintf(stderr, "Cannot merge previous session.\n"); + exit(1); +#endif + } + close_merge_image(); + + /* + * set up parent_dir and filedir in relocated entries which + * were read from previous session so that + * finish_cl_pl_entries can do its job + */ + match_cl_re_entries(); + } +#ifdef APPLE_HYB + /* free up any HFS filename mapping memory */ + if (apple_both) + clean_hfs(); +#endif /* APPLE_HYB */ + + /* hide "./rr_moved" if all its contents have been hidden */ + if (reloc_dir && i_ishidden()) + hide_reloc_dir(); + + /* insert the boot catalog if required */ + if (use_eltorito) + insert_boot_cat(); + + /* + * Free up any matching memory + */ + for (n = 0; n < MAX_MAT; n++) + gen_del_match(n); + +#ifdef SORTING + del_sort(); +#endif /* SORTING */ + + /* + * Sort the directories in the required order (by ISO9660). Also, + * choose the names for the 8.3 filesystem if required, and do any + * other post-scan work. + */ + goof += sort_tree(root); + + if (goof) { + fprintf(stderr, "ISO9660/Rock Ridge tree sort failed.\n"); + if(merge_warn_msg) + fprintf(stderr, merge_warn_msg); + exit(1); + } +#ifdef UDF + if (use_Joliet || use_udf) { +#else + if (use_Joliet) { +#endif + goof += joliet_sort_tree(root); + } + if (goof) { + fprintf(stderr, "Joliet tree sort failed. The -joliet-long switch may help you.\n"); + if(merge_warn_msg) + fprintf(stderr, merge_warn_msg); + exit(1); + } + /* + * Fix a couple of things in the root directory so that everything is + * self consistent. Fix this up so that the path tables get done right. + */ + root->self = root->contents; + + /* OK, ready to write the file. Open it up, and generate the thing. */ + if (print_size) { + discimage = fopen("/dev/null", "wb"); + if (!discimage) { +#ifdef USE_LIBSCHILY + comerr("Unable to open /dev/null\n"); +#else + fprintf(stderr, "Unable to open /dev/null\n"); + exit(1); +#endif + } + } else if (outfile && (strcmp (outfile, "-")) != 0) { + discimage = fopen(outfile, "wb"); + if (!discimage) { +#ifdef USE_LIBSCHILY + comerr("Unable to open disc image file '%s'.\n", outfile); +#else + fprintf(stderr, "Unable to open disc image file '%s'.\n", outfile); + exit(1); +#endif + } + if (jtemplate_out || jjigdo_out) { + if (!jtemplate_out || !jjigdo_out || !jmd5_list) { +#ifdef USE_LIBSCHILY + comerr("Bad options - need to specify output names for jigdo and template file, and also the md5-list input file!\n"); +#else + fprintf(stderr, "Bad options - need to specify output names for jigdo and template file, and also the md5-list input file!\n"); + exit(1); +#endif + } + jtjigdo = fopen(jjigdo_out, "wb"); + jttemplate = fopen(jtemplate_out, "wb"); + if (!jtjigdo || !jttemplate) { +#ifdef USE_LIBSCHILY + comerr("Unable to open jigdo template image file\n"); +#else + fprintf(stderr, "Unable to open jigdo template image file\n"); + exit(1); +#endif + } + write_jt_header(jttemplate, jtjigdo); + } + } else if ((outfile == NULL) + && isatty (fileno (stdout))) { + /* FIXME: a cleaner way to override this check? */ + fputs (("image not written to a terminal.\n" + "Use -o - to force the output.\n"), + stderr); + exit (1); + } else { + discimage = stdout; + +#ifdef NEED_O_BINARY + setmode(fileno(stdout), O_BINARY); +#endif + } + + /* Now assign addresses on the disc for the path table. */ + + path_blocks = ISO_BLOCKS(path_table_size); + if (path_blocks & 1) + path_blocks++; + + jpath_blocks = ISO_BLOCKS(jpath_table_size); + if (jpath_blocks & 1) + jpath_blocks++; + + /* + * Start to set up the linked list that we use to track the contents + * of the disc. + */ +#ifdef APPLE_HYB +#ifdef PREP_BOOT + if (apple_hyb || use_prep_boot || use_chrp_boot) +#else /* PREP_BOOT */ + if (apple_hyb) +#endif /* PREP_BOOT */ + outputlist_insert(&hfs_desc); +#endif /* APPLE_HYB */ + if (use_sparcboot || use_sunx86boot) + outputlist_insert(&sunlabel_desc); + if (use_alphaboot) + outputlist_insert(&alphaboot_desc); + if (use_hppaboot) + outputlist_insert(&hppaboot_desc); + if (use_alphaboot || use_hppaboot) + outputlist_insert(&alpha_hppa_boot_desc); + if (use_mipsboot) + outputlist_insert(&mipsboot_desc); + if (use_mipselboot) + outputlist_insert(&mipselboot_desc); + if (use_genboot) + outputlist_insert(&genboot_desc); + outputlist_insert(&startpad_desc); + + /* PVD for disc. */ + outputlist_insert(&voldesc_desc); + + /* SVD for El Torito. MUST be immediately after the PVD! */ + if (use_eltorito) { + outputlist_insert(&torito_desc); + } + /* Enhanced PVD for disc. neded if we write ISO-9660:1999 */ + if (iso9660_level > 3) + outputlist_insert(&xvoldesc_desc); + + /* SVD for Joliet. */ + if (use_Joliet) { + outputlist_insert(&joliet_desc); + } + /* Finally the last volume descriptor. */ + outputlist_insert(&end_vol); + +#ifdef UDF + if (use_udf) { + outputlist_insert(&udf_vol_recognition_area_frag); + } +#endif + + /* Insert the version descriptor. */ + outputlist_insert(&version_desc); + +#ifdef UDF + if (use_udf) { + /* + * Most of the space before sector 256 is wasted when + * UDF is turned on. The waste could be reduced by + * putting the ISO9660/Joliet structures before the + * pad_to_sector_256; the problem is that they might + * overshoot sector 256, so there would have to be some + * ugly logic to detect this case and rearrange things + * appropriately. I don't know if it's worth it. + */ + outputlist_insert(&udf_pad_to_sector_32_frag); + outputlist_insert(&udf_main_seq_frag); + outputlist_insert(&udf_main_seq_copy_frag); + outputlist_insert(&udf_integ_seq_frag); + outputlist_insert(&udf_pad_to_sector_256_frag); + outputlist_insert(&udf_anchor_vol_desc_frag); + outputlist_insert(&udf_file_set_desc_frag); + outputlist_insert(&udf_dirtree_frag); + outputlist_insert(&udf_file_entries_frag); + } +#endif + + /* Now start with path tables and directory tree info. */ + if (!stream_media_size) + outputlist_insert(&pathtable_desc); + else + outputlist_insert(&strpath_desc); + + if (use_Joliet) { + outputlist_insert(&jpathtable_desc); + } + + if (!stream_media_size) + outputlist_insert(&dirtree_desc); + + if (use_Joliet) { + outputlist_insert(&jdirtree_desc); + } + outputlist_insert(&dirtree_clean); + + if (extension_record) { + outputlist_insert(&extension_desc); + } + + if (!stream_media_size) { + outputlist_insert(&files_desc); + } else { + outputlist_insert(&strfile_desc); + outputlist_insert(&strdir_desc); + } + + /* + * Allow room for the various headers we will be writing. + * There will always be a primary and an end volume descriptor. + */ + last_extent = session_start; + + /* + * Calculate the size of all of the components of the disc, and assign + * extent numbers. + */ + for (opnt = out_list; opnt; opnt = opnt->of_next) { + opnt->of_start_extent = last_extent; + if (opnt->of_size != NULL) { + (*opnt->of_size) (last_extent); + } + } + + /* + * Generate the contents of any of the sections that we want to + * generate. Not all of the fragments will do anything here + * - most will generate the data on the fly when we get to the write + * pass. + */ + for (opnt = out_list; opnt; opnt = opnt->of_next) { + if (opnt->of_generate != NULL) { + (*opnt->of_generate) (); + } + } + + /* + * Padding just after the ISO-9660 filesystem. + * + * files_desc does not have an of_size function. For this + * reason, we must insert us after the files content has been + * generated. + */ +#ifdef UDF + if (use_udf) { + /* Single anchor volume descriptor pointer at end */ + outputlist_insert(&udf_end_anchor_vol_desc_frag); + if (udf_end_anchor_vol_desc_frag.of_size != NULL) { + (*udf_end_anchor_vol_desc_frag.of_size) (last_extent); + } + if (dopad) { + /* + * Pad with anchor volume descriptor pointer + * blocks instead of zeroes. + */ + outputlist_insert(&udf_padend_avdp_frag); + if (udf_padend_avdp_frag.of_size != NULL) { + (*udf_padend_avdp_frag.of_size) (last_extent); + } + } + } else +#endif + if (dopad && !(use_sparcboot || use_sunx86boot)) { + outputlist_insert(&endpad_desc); + if (endpad_desc.of_size != NULL) { + (*endpad_desc.of_size) (last_extent); + } + } + c = 0; + if (use_sparcboot) { + if (dopad) { + /* Padding before the boot partitions. */ + outputlist_insert(&interpad_desc); + if (interpad_desc.of_size != NULL) { + (*interpad_desc.of_size) (last_extent); + } + } + c = make_sun_label(); + last_extent += c; + outputlist_insert(&sunboot_desc); + if (dopad) { + outputlist_insert(&endpad_desc); + if (endpad_desc.of_size != NULL) { + (*endpad_desc.of_size) (last_extent); + } + } + } else if (use_sunx86boot) { + if (dopad) { + /* Padding before the boot partitions. */ + outputlist_insert(&interpad_desc); + if (interpad_desc.of_size != NULL) { + (*interpad_desc.of_size) (last_extent); + } + } + c = make_sunx86_label(); + last_extent += c; + outputlist_insert(&sunboot_desc); + if (dopad) { + outputlist_insert(&endpad_desc); + if (endpad_desc.of_size != NULL) { + (*endpad_desc.of_size) (last_extent); + } + } + } + if (print_size > 0) { + if (verbose > 0) + fprintf(stderr, + "Total extents scheduled to be written = %u\n", + (last_extent - session_start)); + printf("%u\n", (last_extent - session_start)); + exit(0); + } + /* + * Now go through the list of fragments and write the data that + * corresponds to each one. + */ + for (opnt = out_list; opnt; opnt = opnt->of_next) { + Uint oext; + + oext = last_extent_written; + if (opnt->of_start_extent != 0 && + opnt->of_start_extent != last_extent_written) { + /* + * Consistency check. + * XXX Should make sure that all entries have + * XXXX of_start_extent set up correctly. + */ + comerrno(EX_BAD, + "Implementation botch: %s should start at %u but starts at %u.\n", + opnt->of_name, opnt->of_start_extent, last_extent_written); + } + if (opnt->of_write != NULL) { + if (verbose > 1) + fprintf(stderr, "Writing: %-40sStart Block %u\n", + opnt->of_name, last_extent_written); + (*opnt->of_write) (discimage); + if (verbose > 1) + fprintf(stderr, "Done with: %-40sBlock(s) %u\n", + opnt->of_name, last_extent_written-oext); + } + } + if (last_extent != last_extent_written) { + comerrno(EX_BAD, + "Implementation botch: FS should end at %u but ends at %u.\n", + last_extent, last_extent_written); + } + + if (jttemplate) { + write_jt_footer(); + fclose(jttemplate); + } + if (jtjigdo) + fclose(jtjigdo); + + if (verbose > 0) { +#ifdef HAVE_SBRK + fprintf(stderr, "Max brk space used %x\n", + (unsigned int)(((unsigned long) sbrk(0)) - mem_start)); +#endif + fprintf(stderr, "%u extents written (%u MB)\n", + last_extent, last_extent >> 9); + } +#ifdef VMS + return (1); +#else + return (0); +#endif +} + +/* + * Find unescaped equal sign in graft pointer string. + */ +char * +findgequal(char *s) +{ + char *p = s; + + while ((p = strchr(p, '=')) != NULL) { + if (p > s && p[-1] != '\\') + return (p); + p++; + } + return (NULL); +} + +/* + * Find unescaped equal sign in string. + */ +static char * +escstrcpy(char *to, char *from) +{ + char *p = to; + + if (debug) + fprintf(stderr, "FROM: '%s'\n", from); + + while ((*p = *from++) != '\0') { + if (*p == '\\') { + if ((*p = *from++) == '\0') + break; + if (*p != '\\' && *p != '=') { + p[1] = p[0]; + *p++ = '\\'; + } + } + p++; + } + if (debug) + fprintf(stderr, "ESC: '%s'\n", to); + return (to); +} + +void * +e_malloc(size_t size) +{ + void *pt = 0; + + if ((size > 0) && ((pt = malloc(size)) == NULL)) { +#ifdef USE_LIBSCHILY + comerr("Not enough memory\n"); +#else + fprintf(stderr, "Not enough memory\n"); + exit(1); +#endif + } + /* + * Not all code is clean yet. + * Filling all allocated data with zeroes will help + * to avoid core dumps. + */ + if (size > 0) /* a workaround for gcc bug gcc.gnu.org/PR25639 */ + memset(pt, 0, size); + return (pt); +} diff --git a/genisoimage/genisoimage.h b/genisoimage/genisoimage.h new file mode 100644 index 0000000..bbedfb0 --- /dev/null +++ b/genisoimage/genisoimage.h @@ -0,0 +1,802 @@ +/* + * 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. + * + */ + +/* @(#)genisoimage.h 1.95 05/05/01 joerg */ +/* + * Header file genisoimage.h - assorted structure definitions and typecasts. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2003 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +#define APPID_DEFAULT "GENISOIMAGE ISO 9660/HFS FILESYSTEM CREATOR (C) 1993 E.YOUNGDALE (C) 1997-2006 J.PEARSON/J.SCHILLING (C) 2006-2007 CDRKIT TEAM" + + +#include <mconfig.h> /* Must be before stdio.h for LARGEFILE support */ +#include <stdio.h> +#include <statdefs.h> +#include <stdxlib.h> +#include <unixstd.h> /* Needed for for LARGEFILE support */ +#include <strdefs.h> +#include <dirdefs.h> +#include <utypes.h> +#include <standard.h> +#include <libport.h> +#include "scsi.h" +#ifdef JIGDO_TEMPLATE +#include "jte.h" +#endif + +#ifdef DVD_VIDEO +#ifndef UDF +#define UDF +#endif +#endif + +/*#if _LFS_LARGEFILE*/ +#ifdef HAVE_LARGEFILES +/* + * XXX Hack until fseeko()/ftello() are available everywhere or until + * XXX we know a secure way to let autoconf ckeck for fseeko()/ftello() + * XXX without defining FILE_OFFSETBITS to 64 in confdefs.h + */ +# define fseek fseeko +# define ftell ftello +#endif + +#ifndef HAVE_LSTAT +#ifndef VMS +#define lstat stat +#endif +#endif + +#include "iso9660.h" +#include "defaults.h" +#include <unls.h> + +extern struct unls_table *in_nls; /* input UNICODE conversion table */ +extern struct unls_table *out_nls; /* output UNICODE conversion table */ +extern struct unls_table *hfs_inls; /* input HFS UNICODE conversion table */ +extern struct unls_table *hfs_onls; /* output HFS UNICODE conversion table */ + +#ifdef APPLE_HYB +#include "mactypes.h" +#include "hfs.h" + +struct hfs_info { + unsigned char finderinfo[32]; + char name[HFS_MAX_FLEN + 1]; + /* should have fields for dates here as well */ + char *keyname; + struct hfs_info *next; +}; + +#endif /* APPLE_HYB */ + +struct directory_entry { + struct directory_entry *next; + struct directory_entry *jnext; + struct iso_directory_record isorec; + unsigned int starting_block; + off_t size; + unsigned short priority; + unsigned char jreclen; /* Joliet record len */ + char *name; + char *table; + char *whole_name; + struct directory *filedir; + struct directory_entry *parent_rec; + unsigned int de_flags; + ino_t inode; /* Used in the hash table */ + dev_t dev; /* Used in the hash table */ + unsigned char *rr_attributes; + unsigned int rr_attr_size; + unsigned int total_rr_attr_size; + unsigned int got_rr_name; +#ifdef APPLE_HYB + struct directory_entry *assoc; /* entry has a resource fork */ + hfsdirent *hfs_ent; /* HFS parameters */ + off_t hfs_off; /* offset to real start of fork */ + int hfs_type; /* type of HFS Unix file */ +#endif /* APPLE_HYB */ +#ifdef SORTING + int sort; /* sort weight for entry */ +#endif /* SORTING */ +#ifdef UDF + int udf_file_entry_sector; /* also used as UDF unique ID */ +#endif + uint64_t realsize; +}; + +struct file_hash { + struct file_hash *next; + ino_t inode; /* Used in the hash table */ + dev_t dev; /* Used in the hash table */ + nlink_t nlink; /* Used to compute new link count */ + unsigned int starting_block; + off_t size; +#ifdef SORTING + struct directory_entry *de; +#endif /* SORTING */ +}; + + +/* + * This structure is used to control the output of fragments to the cdrom + * image. Everything that will be written to the output image will eventually + * go through this structure. There are two pieces - first is the sizing where + * we establish extent numbers for everything, and the second is when we actually + * generate the contents and write it to the output image. + * + * This makes it trivial to extend genisoimage to write special things in the image. + * All you need to do is hook an additional structure in the list, and the rest + * works like magic. + * + * The three passes each do the following: + * + * The 'size' pass determines the size of each component and assigns the extent number + * for that component. + * + * The 'generate' pass will adjust the contents and pointers as required now that extent + * numbers are assigned. In some cases, the contents of the record are also generated. + * + * The 'write' pass actually writes the data to the disc. + */ +struct output_fragment { + struct output_fragment *of_next; + int (*of_size)(int); + int (*of_generate)(void); + int (*of_write)(FILE *); + char *of_name; /* Textual description */ + unsigned int of_start_extent; /* For consist check */ +}; + +extern struct output_fragment *out_list; +extern struct output_fragment *out_tail; + +extern struct output_fragment startpad_desc; +extern struct output_fragment voldesc_desc; +extern struct output_fragment xvoldesc_desc; +extern struct output_fragment joliet_desc; +extern struct output_fragment torito_desc; +extern struct output_fragment end_vol; +extern struct output_fragment version_desc; +extern struct output_fragment pathtable_desc; +extern struct output_fragment jpathtable_desc; +extern struct output_fragment dirtree_desc; +extern struct output_fragment dirtree_clean; +extern struct output_fragment jdirtree_desc; +extern struct output_fragment extension_desc; +extern struct output_fragment files_desc; +extern struct output_fragment interpad_desc; +extern struct output_fragment endpad_desc; +extern struct output_fragment sunboot_desc; +extern struct output_fragment sunlabel_desc; +extern struct output_fragment genboot_desc; +extern struct output_fragment strfile_desc; +extern struct output_fragment strdir_desc; +extern struct output_fragment strpath_desc; +extern struct output_fragment alphaboot_desc; +extern struct output_fragment hppaboot_desc; +extern struct output_fragment alpha_hppa_boot_desc; +extern struct output_fragment mipsboot_desc; +extern struct output_fragment mipselboot_desc; + +#ifdef APPLE_HYB +extern struct output_fragment hfs_desc; + +#endif /* APPLE_HYB */ +#ifdef DVD_VIDEO +/* + * This structure holds the information necessary to create a valid + * DVD-Video image. Basically it's how much to pad the files so the + * file offsets described in the video_ts.ifo and vts_xx_0.ifo are + * the correct one in the image that we create. + */ +typedef struct { + int realsize_ifo; + int realsize_menu; + int realsize_bup; + int size_ifo; + int size_menu; + int size_title; + int size_bup; + int pad_ifo; + int pad_menu; + int pad_title; + int pad_bup; + int number_of_vob_files; + int realsize_vob[10]; +} title_set_t; + +typedef struct { + int num_titles; + title_set_t *title_set; +} title_set_info_t; +#endif /* DVD_VIDEO */ + +/* + * This structure describes one complete directory. It has pointers + * to other directories in the overall tree so that it is clear where + * this directory lives in the tree, and it also must contain pointers + * to the contents of the directory. Note that subdirectories of this + * directory exist twice in this stucture. Once in the subdir chain, + * and again in the contents chain. + */ +struct directory { + struct directory *next; /* Next directory at same level as this one */ + struct directory *subdir; /* First subdirectory in this directory */ + struct directory *parent; + struct directory_entry *contents; + struct directory_entry *jcontents; + struct directory_entry *self; + char *whole_name; /* Entire path */ + char *de_name; /* Entire path */ + unsigned int ce_bytes; /* Number of bytes of CE entries read */ + /* for this dir */ + unsigned int depth; + unsigned int size; + unsigned int extent; + unsigned int jsize; + unsigned int jextent; + unsigned int path_index; + unsigned int jpath_index; + unsigned short dir_flags; + unsigned short dir_nlink; +#ifdef APPLE_HYB + hfsdirent *hfs_ent; /* HFS parameters */ + struct hfs_info *hfs_info; /* list of info for all entries in dir */ +#endif /* APPLE_HYB */ +#ifdef SORTING + int sort; /* sort weight for child files */ +#endif /* SORTING */ +}; + +struct deferred_write { + struct deferred_write *next; + char *table; + unsigned int extent; + off_t size; + char *name; + struct directory_entry *s_entry; + unsigned int pad; + off_t off; +}; + +struct eltorito_boot_entry_info { + struct eltorito_boot_entry_info *next; + char *boot_image; + int not_bootable; + int no_emul_boot; + int hard_disk_boot; + int boot_info_table; + int load_size; + int load_addr; +}; + +extern int goof; +extern struct directory *root; +extern struct directory *reloc_dir; +extern unsigned int next_extent; +extern unsigned int last_extent; +extern unsigned int last_extent_written; +extern unsigned int session_start; + +extern unsigned int path_table_size; +extern unsigned int path_table[4]; +extern unsigned int path_blocks; +extern char *path_table_l; +extern char *path_table_m; + +extern unsigned int jpath_table_size; +extern unsigned int jpath_table[4]; +extern unsigned int jpath_blocks; +extern char *jpath_table_l; +extern char *jpath_table_m; + +extern struct iso_directory_record root_record; +extern struct iso_directory_record jroot_record; + +extern int check_oldnames; +extern int check_session; +extern int use_eltorito; +extern int hard_disk_boot; +extern int not_bootable; +extern int no_emul_boot; +extern int load_addr; +extern int load_size; +extern int boot_info_table; +extern int use_RockRidge; +extern int osecsize; +extern int use_XA; +extern int use_Joliet; +extern int rationalize; +extern int rationalize_uid; +extern int rationalize_gid; +extern int rationalize_filemode; +extern int rationalize_dirmode; +extern uid_t uid_to_use; +extern gid_t gid_to_use; +extern int filemode_to_use; +extern int dirmode_to_use; +extern int new_dir_mode; +extern int follow_links; +extern int cache_inodes; +extern int verbose; +extern int debug; +extern int gui; +extern int all_files; +extern int generate_tables; +extern int print_size; +extern int split_output; +extern int use_graft_ptrs; +extern int jhide_trans_tbl; +extern int hide_rr_moved; +extern int omit_period; +extern int omit_version_number; +extern int no_rr; +extern int transparent_compression; +extern Uint RR_relocation_depth; +extern int iso9660_level; +extern int iso9660_namelen; +extern int full_iso9660_filenames; +extern int relaxed_filenames; +extern int allow_lowercase; +extern int allow_multidot; +extern int iso_translate; +extern int allow_leading_dots; +extern int use_fileversion; +extern int split_SL_component; +extern int split_SL_field; +extern char *trans_tbl; +char *outfile; + +#define JMAX 64 /* maximum Joliet file name length (spec) */ +#define JLONGMAX 103 /* out of spec Joliet file name length */ +extern int jlen; /* selected maximum Joliet file name length */ + +#ifdef DVD_VIDEO +extern int dvd_video; +#endif /* DVD_VIDEO */ + + +#ifdef APPLE_HYB +extern int apple_hyb; /* create HFS hybrid */ +extern int apple_ext; /* use Apple extensions */ +extern int apple_both; /* common flag (for above) */ +extern int hfs_extra; /* extra ISO extents (hfs_ce_size) */ +extern hce_mem *hce; /* libhfs/genisoimage extras */ +extern int use_mac_name; /* use Mac name for ISO9660/Joliet/RR */ +extern int create_dt; /* create the Desktp files */ +extern char *hfs_boot_file; /* name of HFS boot file */ +extern char *magic_filename; /* magic file for CREATOR/TYPE matching */ +extern int hfs_last; /* order in which to process map/magic files */ +extern char *deftype; /* default Apple TYPE */ +extern char *defcreator; /* default Apple CREATOR */ +extern int gen_pt; /* generate HFS partition table */ +extern char *autoname; /* Autostart filename */ +extern int afe_size; /* Apple File Exchange block size */ +extern char *hfs_volume_id; /* HFS volume ID */ +extern int icon_pos; /* Keep Icon position */ +extern int hfs_lock; /* lock HFS volume (read-only) */ +extern char *hfs_bless; /* name of folder to 'bless' (System Folder) */ +extern char *hfs_parms; /* low level HFS parameters */ + +#define MAP_LAST 1 /* process magic then map file */ +#define MAG_LAST 2 /* process map then magic file */ + +#ifndef PREP_BOOT +#define PREP_BOOT +#endif /* PREP_BOOT */ + +#ifdef PREP_BOOT +extern char *prep_boot_image[4]; +extern int use_prep_boot; +extern int use_chrp_boot; + +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +#ifdef SORTING +extern int do_sort; +#endif /* SORTING */ + +/* tree.c */ +extern int stat_filter(char *, struct stat *); +extern int lstat_filter(char *, struct stat *); +extern int sort_tree(struct directory *); +extern struct directory * +find_or_create_directory(struct directory *, const char *, + struct directory_entry *self, + int, + struct stat *stat_template); +extern void finish_cl_pl_entries(void); +extern int scan_directory_tree(struct directory *this_dir, char *path, + struct directory_entry *self); + +#ifdef APPLE_HYB +extern int insert_file_entry(struct directory *, char *, char *, int); +#else +extern int insert_file_entry(struct directory *, char *, char *); +#endif /* APPLE_HYB */ + +extern void generate_iso9660_directories(struct directory *, FILE *); +extern void dump_tree(struct directory * node); +extern struct directory_entry * +search_tree_file(struct directory * node, char *filename); +extern void update_nlink_field(struct directory * node); +extern void init_fstatbuf(void); +extern struct stat root_statbuf; +extern struct stat fstatbuf; + +/* eltorito.c */ +extern void init_boot_catalog(const char *path); +extern void insert_boot_cat(void); +extern void get_boot_entry(void); +extern void new_boot_entry(void); + +/* boot.c */ +extern void sparc_boot_label(char *label); +extern void sunx86_boot_label(char *label); +extern void scan_sparc_boot(char *files); +extern void scan_sunx86_boot(char *files); +extern int make_sun_label(void); +extern int make_sunx86_label(void); + +/* boot-alpha.c */ +extern int add_boot_alpha_filename(char *filename); + +/* boot-hppa.c */ +extern int add_boot_hppa_cmdline(char *cmdline); +extern int add_boot_hppa_kernel_32(char *filename); +extern int add_boot_hppa_kernel_64(char *filename); +extern int add_boot_hppa_bootloader(char *filename); +extern int add_boot_hppa_ramdisk(char *filename); + +/* boot-mips.c */ +extern int add_boot_mips_filename(char *filename); + +/* boot-mipsel.c */ +extern int add_boot_mipsel_filename(char *filename); + +/* rsync.c */ +extern unsigned long long rsync64(unsigned char *mem, size_t size); + +/* write.c */ +extern int get_731(char *); +extern int get_732(char *); +extern int get_733(char *); +extern int isonum_733(unsigned char *); +extern void set_723(char *, unsigned int); +extern void set_731(char *, unsigned int); +extern void set_721(char *, unsigned int); +extern void set_733(char *, unsigned int); +extern int sort_directory(struct directory_entry **, int); +extern void generate_one_directory(struct directory *, FILE *); +extern void memcpy_max(char *, char *, int); +extern int oneblock_size(int starting_extent); +extern struct iso_primary_descriptor vol_desc; +extern void xfwrite(void *buffer, int size, int count, FILE *file, int submode, + BOOL islast); +extern void set_732(char *pnt, unsigned int i); +extern void set_722(char *pnt, unsigned int i); +extern void outputlist_insert(struct output_fragment * frag); + +#ifdef APPLE_HYB +extern Ulong get_adj_size(int Csize); +extern int adj_size(int Csize, int start_extent, int extra); +extern void adj_size_other(struct directory * dpnt); +extern int insert_padding_file(int size); +extern int gen_mac_label(struct deferred_write *); + +#ifdef PREP_BOOT +extern void gen_prepboot_label(unsigned char *); + +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +/* multi.c */ + +extern FILE *in_image; +extern int open_merge_image(char *path); +extern int close_merge_image(void); +extern struct iso_directory_record * +merge_isofs(char *path); +extern unsigned char *parse_xa(unsigned char *pnt, int *lenp, + struct directory_entry *dpnt); +extern int rr_flags(struct iso_directory_record *idr); +extern int merge_previous_session(struct directory *, + struct iso_directory_record *, + char *, char *); +extern int get_session_start(int *); + +/* joliet.c */ +#ifdef UDF +# ifdef USE_ICONV +extern size_t convert_to_unicode (unsigned char *buffer, + int size, char *source, struct unls_table *inls); +# else +extern void convert_to_unicode (unsigned char *buffer, + int size, char *source, struct unls_table *inls); +# endif +extern int joliet_strlen (const char *string, struct unls_table *inls); +#endif +extern unsigned char conv_charset(unsigned char, struct unls_table *, + struct unls_table *); +extern int joliet_sort_tree(struct directory * node); + +/* match.c */ +extern int matches(char *); +extern int add_match(char *); + +/* files.c */ +struct dirent *readdir_add_files(char **, char *, DIR *); + +/* name.c */ + +extern void iso9660_check(struct iso_directory_record *idr, + struct directory_entry *ndr); +extern int iso9660_file_length(const char *name, + struct directory_entry *sresult, int flag); + +/* various */ +extern int iso9660_date(char *, time_t); +extern void add_hash(struct directory_entry *); +extern struct file_hash *find_hash(dev_t, ino_t); + +extern void flush_hash(void); +extern void add_directory_hash(dev_t, ino_t); +extern struct file_hash *find_directory_hash(dev_t, ino_t); +extern void flush_file_hash(void); +extern int delete_file_hash(struct directory_entry *); +extern struct directory_entry *find_file_hash(char *); +extern void add_file_hash(struct directory_entry *); + +extern int generate_xa_rr_attributes(char *, char *, struct directory_entry *, + struct stat *, struct stat *, + int deep_flag); +extern char *generate_rr_extension_record(char *id, char *descriptor, + char *source, int *size); + +extern int check_prev_session(struct directory_entry **, int len, + struct directory_entry *, struct stat *, + struct stat *, struct directory_entry **); + +extern void match_cl_re_entries(void); +extern void finish_cl_pl_for_prev_session(void); +extern char *find_rr_attribute(unsigned char *pnt, int len, char *attr_type); + +#ifdef APPLE_HYB +/* volume.c */ +extern int make_mac_volume(struct directory * dpnt, int start_extent); +extern int write_fork(hfsfile * hfp, long tot); + +/* apple.c */ + +extern void del_hfs_info(struct hfs_info *); +extern int get_hfs_dir(char *, char *, struct directory_entry *); +extern int get_hfs_info(char *, char *, struct directory_entry *); +extern int get_hfs_rname(char *, char *, char *); +extern int hfs_exclude(char *); +extern void print_hfs_info(struct directory_entry *); +extern void hfs_init(char *, unsigned short, unsigned int); +extern void delete_rsrc_ent(struct directory_entry *); +extern void clean_hfs(void); +extern void perr(char *); +extern void set_root_info(char *); + +/* desktop.c */ + +extern int make_desktop(hfsvol *, int); + +/* mac_label.c */ + +#ifdef _MAC_LABEL_H +#ifdef PREP_BOOT +extern void gen_prepboot_label(MacLabel * mac_label); +#endif +extern int gen_mac_label(defer *); +#endif +extern int autostart(void); + +/* libfile */ + +extern char *get_magic_match(const char *); +extern void clean_magic(void); + +#endif /* APPLE_HYB */ + +extern char *extension_record; +extern int extension_record_extent; +extern int n_data_extents; + +/* + * These are a few goodies that can be specified on the command line, and are + * filled into the root record + */ +extern char *preparer; +extern char *publisher; +extern char *copyright; +extern char *biblio; +extern char *abstract; +extern char *appid; +extern char *volset_id; +extern char *system_id; +extern char *volume_id; +extern char *boot_catalog; +extern char *boot_image; +extern char *genboot_image; +extern int ucs_level; +extern int volume_set_size; +extern int volume_sequence_number; + +extern struct eltorito_boot_entry_info *first_boot_entry; +extern struct eltorito_boot_entry_info *last_boot_entry; +extern struct eltorito_boot_entry_info *current_boot_entry; + +extern char *findgequal(char *); +extern void *e_malloc(size_t); + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define ROUND_UP(X, Y) (((X + (Y - 1)) / Y) * Y) + +#ifdef APPLE_HYB +/* + * ISO blocks == 2048, HFS blocks == 512 + */ +#define HFS_BLK_CONV (SECTOR_SIZE/HFS_BLOCKSZ) + +#define HFS_ROUND_UP(X) ISO_ROUND_UP(((X)*HFS_BLOCKSZ)) /* XXX ??? */ +#define HFS_BLOCKS(X) (ISO_BLOCKS(X) * HFS_BLK_CONV) + +#define USE_MAC_NAME(E) (use_mac_name && ((E)->hfs_ent != NULL) && (E)->hfs_type) +#endif /* APPLE_HYB */ + +/* + * Rock Ridge defines + */ +#define NEED_RE 1 /* Need Relocated Direcotry */ +#define NEED_PL 2 /* Need Parent link */ +#define NEED_CL 4 /* Need Child link */ +#define NEED_CE 8 /* Need Continuation Area */ +#define NEED_SP 16 /* Need SUSP record */ + +#define RR_FLAG_PX 1 /* POSIX attributes */ +#define RR_FLAG_PN 2 /* POSIX device number */ +#define RR_FLAG_SL 4 /* Symlink */ +#define RR_FLAG_NM 8 /* Alternate Name */ +#define RR_FLAG_CL 16 /* Child link */ +#define RR_FLAG_PL 32 /* Parent link */ +#define RR_FLAG_RE 64 /* Relocated Direcotry */ +#define RR_FLAG_TF 128 /* Time stamp */ + +#define RR_FLAG_SP 1024 /* SUSP record */ +#define RR_FLAG_AA 2048 /* Apple Signature record */ +#define RR_FLAG_XA 4096 /* XA signature record */ + +#define RR_FLAG_CE 8192 /* SUSP Continuation aerea */ +#define RR_FLAG_ER 16384 /* Extension record for RR signature */ +#define RR_FLAG_RR 32768 /* RR Signature in every file */ +#define RR_FLAG_ZF 65535 /* Linux compression extension */ + + +#define PREV_SESS_DEV (sizeof (dev_t) >= 4 ? 0x7ffffffd : 0x7ffd) +#define TABLE_INODE (sizeof (ino_t) >= 4 ? 0x7ffffffe : 0x7ffe) +#define UNCACHED_INODE (sizeof (ino_t) >= 4 ? 0x7fffffff : 0x7fff) +#define UNCACHED_DEVICE (sizeof (dev_t) >= 4 ? 0x7fffffff : 0x7fff) + +#ifdef VMS +#define STAT_INODE(X) (X.st_ino[0]) +#define PATH_SEPARATOR ']' +#define SPATH_SEPARATOR "" +#else +#define STAT_INODE(X) (X.st_ino) +#define PATH_SEPARATOR '/' +#define SPATH_SEPARATOR "/" +#endif + +/* + * When using multi-session, indicates that we can reuse the + * TRANS.TBL information for this directory entry. If this flag + * is set for all entries in a directory, it means we can just + * reuse the TRANS.TBL and not generate a new one. + */ +#define SAFE_TO_REUSE_TABLE_ENTRY 0x01 /* de_flags only */ +#define DIR_HAS_DOT 0x02 /* dir_flags only */ +#define DIR_HAS_DOTDOT 0x04 /* dir_flags only */ +#define INHIBIT_JOLIET_ENTRY 0x08 +#define INHIBIT_RR_ENTRY 0x10 /* not used */ +#define RELOCATED_DIRECTORY 0x20 /* de_flags only */ +#define INHIBIT_ISO9660_ENTRY 0x40 +#define MEMORY_FILE 0x80 /* de_flags only */ +#define HIDDEN_FILE 0x100 /* de_flags only */ +#define DIR_WAS_SCANNED 0x200 /* dir_flags only */ + +/* + * Volume sequence number to use in all of the iso directory records. + */ +#define DEF_VSN 1 + +/* + * Make sure we have a definition for this. If not, take a very conservative + * guess. + * POSIX requires the max pathname component lenght to be defined in limits.h + * If variable, it may be undefined. If undefined, there should be + * a definition for _POSIX_NAME_MAX in limits.h or in unistd.h + * As _POSIX_NAME_MAX is defined to 14, we cannot use it. + * XXX Eric's wrong comment: + * XXX From what I can tell SunOS is the only one with this trouble. + */ +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifndef NAME_MAX +#ifdef FILENAME_MAX +#define NAME_MAX FILENAME_MAX +#else +#define NAME_MAX 256 +#endif +#endif + +#ifndef PATH_MAX +#ifdef FILENAME_MAX +#define PATH_MAX FILENAME_MAX +#else +#define PATH_MAX 1024 +#endif +#endif + +/* + * XXX JS: Some structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See iso9660.h + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +/* + * EB: various shared stuff + */ +extern char *merge_warn_msg; diff --git a/genisoimage/genisoimagerc.5 b/genisoimage/genisoimagerc.5 new file mode 100644 index 0000000..71082b4 --- /dev/null +++ b/genisoimage/genisoimagerc.5 @@ -0,0 +1,144 @@ +.\" genisoimagerc.5 -*- nroff -*- +.\" Derived from genisoimage.1 +.\" Copyright 1993-1998 by Yggdrasil Computing +.\" Copyright 1996-1997 by Robert Leslie +.\" Copyright 1997-2001 by James Pearson +.\" Copyright 1999-2006 by Joerg Schilling +.\" Copyright 2002-2003 by Jungshik Shin +.\" Copyright 2003 by Jaakko Heinonen +.\" Copyright 2006 by the Cdrkit maintainers +.\" +.TH GENISOIMAGERC 5 "13 Dec 2006" +.\" ---------------------------------------- +.SH NAME +genisoimagerc \- startup configuration file for genisoimage +.SH DESCRIPTION +.BR genisoimage (1) +searches for a configuration file in several places; it uses the first +one it is able to open. First, if the +.B GENISOIMAGERC +environment variable is set, its value is used as the filename; +likewise for the +.B MKISOFSRC +environment variable. Next, +.B genisoimage +looks for files named +.IR .genisoimagerc " or " .mkisofsrc , +first in the current working directory, then in the user's home +directory. Next, it looks for +.IR /etc/genisoimagerc . +Finally, it looks for a +.I .genisoimagerc +in the same directory as +.B genisoimage +itself is stored. +.PP +The +.I .genisoimagerc +file contains lines of the form +.IP +.BI TAG= value +.PP +where +.B TAG +is one of the settings defined below. The case of the tag is not +significant. All settings have command-line equivalents; if the +command-line parameter is specified, it takes priority over the +configuration file. +.PP +Blank lines and lines beginning with `#' are ignored. +.\" ---------------------------------------- +.SH "CONFIGURATION SETTINGS" +.IP ABST +The abstract information, typically the name of a file on the disc +containing an abstract. There is space for 37 characters. +Equivalent to the +.B \-abstract +command-line option. +.IP APPI +The application identifier should describe the application that will be +on the disc. There is space for 128 characters. Equivalent to the +.B \-A +command-line option. +.IP BIBL +The bibliographic information, often the name of a file on the disc +containing a bibliography. There is space for 37 characters. +Equivalent to the +.B \-biblio +command-line option. +.IP COPY +The copyright information, typically the name of a file on the disc +containing the copyright notice. There is space for 37 characters. +Equivalent to the +.B \-copyright +command-line option. +.IP HFS_TYPE +The default +.B TYPE +for Macintosh files. Must be exactly 4 characters. Equivalent to the +.B \-hfs\-type +command-line option. The default value is +.IR TEXT . +.IP HFS_CREATOR +The default +.B CREATOR +for Macintosh files. Must be exactly 4 characters. Equivalent to the +.B \-hfs\-creator +command-line option. The default value is +.IR Unix . +.IP PREP +This should describe the preparer of the CD-ROM, usually with a mailing +address and phone number. There is space for 128 characters. +Equivalent to the +.B \-p +command-line option. +.IP PUBL +This should describe the publisher of the CD-ROM, usually with a +mailing address and phone number. There is space for 128 characters. +Equivalent to the +.B \-publisher +command-line option. +.IP SYSI +The System Identifier. There is space for 32 characters. +Equivalent to the +.B \-sysid +command-line option. +.IP VOLI +The Volume Identifier. There is space for 32 characters. +Equivalent to the +.B \-V +command-line option. +.IP VOLS +The Volume Set Name. There is space for 128 characters. +Equivalent to the +.B \-volset +command-line option. +.PP +.B genisoimage +can also be configured at compile time with defaults for many of these +fields. See the file +.IR defaults.h . +.\" ---------------------------------------- +.SH EXAMPLES +The following file +.IP +.nf +COPY=src/COPYING +SYSI=Multics 75 +.fi +.PP +is equivalent to the +.B genisoimage +command-line parameters +.IP +.I "\-copyright src/COPYING \-sysid \(dqMultics 75\(dq" +.\" ---------------------------------------- +.SH "SEE ALSO" +.BR genisoimage (1). +.\" ---------------------------------------- +.SH AUTHORS +See the +.BR genisoimage (1) +manual page for credits for the +.B genisoimage +program and documentation. diff --git a/genisoimage/getopt.c b/genisoimage/getopt.c new file mode 100644 index 0000000..64fcb18 --- /dev/null +++ b/genisoimage/getopt.c @@ -0,0 +1,790 @@ +/* + * 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. + * + */ + +/* @(#)getopt.c 1.6 03/03/09 joerg */ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95 + Free Software Foundation, Inc. + +This file is part of the libiberty library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +/* + * XXX Never do it this way, it is FSF junk + */ +#ifndef _NO_PROTO +/*#define _NO_PROTO*/ +#endif +/* + * We do this instead: + */ +#undef getopt +#define getopt __nothing__ + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ +/* Many versions of the Linux C library include older, broken versions + of these routines, which will break the linker's command-line + parsing. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include <stdlib.h> +#define __DID_STDLIB__ /* FSF rubbish compensation */ +#endif /* GNU C library. */ + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +static void exchange(char **argv); +static const char *_getopt_initialize(const char *optstring); + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include <string.h> +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char *my_index(const char *str, int chr); + +static char * +my_index (const char *str, int chr) +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#ifndef __STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +#ifndef __DID_STDLIB__ /* FSF rubbish compensation */ +/* + * This is the clean code using Schily constructs... + */ +#undef getopt +#define getopt __nothing__ +#include <stdxlib.h> +#endif +#ifndef my_index +/* + * FSF rubbish compensation + * If GCC has problems with the system include files, it has to be fixed + */ +#include <strdefs.h> +#endif +#undef getopt + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (char **argv) +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (const char *optstring) +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (getenv ("POSIXLY_CORRECT") != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, int long_only) +{ + optarg = NULL; + + if (optind == 0) + optstring = _getopt_initialize (optstring); + + if (argc == 0) + return EOF; + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if (nameend - nextchar == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); + } + optopt = c; + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (int argc, char *argv[]) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/genisoimage/getopt.h b/genisoimage/getopt.h new file mode 100644 index 0000000..e2eb2b7 --- /dev/null +++ b/genisoimage/getopt.h @@ -0,0 +1,148 @@ +/* + * 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. + * + */ + +/* @(#)getopt.h 1.3 03/03/06 eric */ +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +/*#if __STDC__*/ +#ifdef PROTOTYPES + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +/*#if __STDC__*/ +#ifdef PROTOTYPES +#if defined(__GNU_LIBRARY__) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* not __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/genisoimage/getopt1.c b/genisoimage/getopt1.c new file mode 100644 index 0000000..9c51b0c --- /dev/null +++ b/genisoimage/getopt1.c @@ -0,0 +1,193 @@ +/* + * 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. + * + */ + +/* @(#)getopt1.c 1.1 97/11/04 eric */ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#include "getopt.h" + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ +/* Many versions of the Linux C library include older, broken versions + of these routines, which will break the linker's command-line + parsing. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#else +char *getenv (); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/genisoimage/hash.c b/genisoimage/hash.c new file mode 100644 index 0000000..054aea6 --- /dev/null +++ b/genisoimage/hash.c @@ -0,0 +1,404 @@ +/* + * 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. + * + */ + +/* @(#)hash.c 1.18 04/06/18 joerg */ +/* @(#)hash.c 1.23 06/10/04 joerg */ +/* + * File hash.c - generate hash tables for iso9660 filesystem. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-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 as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +/* + * From jb@danware.dk: + * + * Cygwin fakes inodes by hashing file info, actual collisions observed! + * This is documented in the cygwin source, look at winsup/cygwin/path.cc + * and search for the word 'Hash'. On NT, cygwin ORs together the + * high and low 32 bits of the 64 bit genuine inode, look at fhandler.cc. + * + * Note: Other operating systems which support the FAT filesystem may + * have the same problem because FAT does not use the inode + * concept. For NTFS, genuine inode numbers exist, but they are + * 64 bits and available only through an open file handle. + * + * The solution is the new options -no-cache-inodes/-cache-inodes that + * allow to disable the genisoimage inode cache. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <schily.h> + +#define NR_HASH (16*1024) + +#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 8) + (INO << 16)) % NR_HASH) + +static struct file_hash *hash_table[NR_HASH]; + +void add_hash(struct directory_entry *spnt); +struct file_hash *find_hash(dev_t dev, ino_t inode); +void flush_hash(void); +void add_directory_hash(dev_t dev, ino_t inode); +struct file_hash *find_directory_hash(dev_t dev, ino_t inode); +static unsigned int name_hash(const char *name); +void add_file_hash(struct directory_entry *de); +struct directory_entry *find_file_hash(char *name); +static BOOL isoname_endsok(char *name); +int delete_file_hash(struct directory_entry *de); +void flush_file_hash(void); + +void +add_hash(struct directory_entry *spnt) +{ + struct file_hash *s_hash; + unsigned int hash_number; + + if (spnt->size == 0 || spnt->starting_block == 0) + if (spnt->size != 0 && spnt->starting_block == 0) { + comerrno(EX_BAD, + "Non zero-length file '%s' assigned zero extent.\n", + spnt->name); + }; + + if (!cache_inodes) + return; + if (spnt->dev == UNCACHED_DEVICE && + (spnt->inode == TABLE_INODE || spnt->inode == UNCACHED_INODE)) { + return; + } + hash_number = HASH_FN((unsigned int) spnt->dev, + (unsigned int) spnt->inode); + +#if 0 + if (verbose > 1) + fprintf(stderr, "%s ", spnt->name); +#endif + s_hash = (struct file_hash *) e_malloc(sizeof (struct file_hash)); + s_hash->next = hash_table[hash_number]; + s_hash->inode = spnt->inode; + s_hash->dev = spnt->dev; + s_hash->nlink = 0; + s_hash->starting_block = spnt->starting_block; + s_hash->size = spnt->size; +#ifdef SORTING + s_hash->de = spnt; +#endif /* SORTING */ + hash_table[hash_number] = s_hash; +} + +struct file_hash * +find_hash(dev_t dev, ino_t inode) +{ + unsigned int hash_number; + struct file_hash *spnt; + + if (!cache_inodes) + return (NULL); + if (dev == UNCACHED_DEVICE && + (inode == TABLE_INODE || inode == UNCACHED_INODE)) + return (NULL); + + hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); + spnt = hash_table[hash_number]; + while (spnt) { + if (spnt->inode == inode && spnt->dev == dev) + return (spnt); + spnt = spnt->next; + }; + return (NULL); +} + +/* + * based on flush_file_hash() below - needed as we want to re-use the + * file hash table. + */ +void +flush_hash() +{ + struct file_hash *fh; + struct file_hash *fh1; + int i; + + for (i = 0; i < NR_HASH; i++) { + fh = hash_table[i]; + while (fh) { + fh1 = fh->next; + free(fh); + fh = fh1; + } + hash_table[i] = NULL; + } +} + +static struct file_hash *directory_hash_table[NR_HASH]; + +void +add_directory_hash(dev_t dev, ino_t inode) +{ + struct file_hash *s_hash; + unsigned int hash_number; + + if (!cache_inodes) + return; + if (dev == UNCACHED_DEVICE && + (inode == TABLE_INODE || inode == UNCACHED_INODE)) + return; + + hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); + + s_hash = (struct file_hash *) e_malloc(sizeof (struct file_hash)); + s_hash->next = directory_hash_table[hash_number]; + s_hash->inode = inode; + s_hash->dev = dev; + s_hash->nlink = 0; + directory_hash_table[hash_number] = s_hash; +} + +struct file_hash * +find_directory_hash(dev_t dev, ino_t inode) +{ + unsigned int hash_number; + struct file_hash *spnt; + + if (!cache_inodes) + return (NULL); + if (dev == UNCACHED_DEVICE && + (inode == TABLE_INODE || inode == UNCACHED_INODE)) + return (NULL); + + hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); + spnt = directory_hash_table[hash_number]; + while (spnt) { + if (spnt->inode == inode && spnt->dev == dev) + return (spnt); + spnt = spnt->next; + }; + return (NULL); +} + +struct name_hash { + struct name_hash *next; + struct directory_entry *de; + int sum; +}; + +#define NR_NAME_HASH (256*1024) + +static struct name_hash *name_hash_table[NR_NAME_HASH] = {0, }; + +/* + * Find the hash bucket for this name. + */ +static unsigned int +name_hash(const char *name) +{ + unsigned int hash = 0; + const char *p; + + p = name; + + while (*p) { + /* + * Don't hash the iso9660 version number. + * This way we can detect duplicates in cases where we have + * directories (i.e. foo) and non-directories (i.e. foo;1). + */ + if (*p == ';') { + break; + } + hash = (hash << 15) + (hash << 3) + (hash >> 3) + (*p++ & 0xFF); + } + return (hash % NR_NAME_HASH); +} + +void +add_file_hash(struct directory_entry *de) +{ + struct name_hash *new; + int hash; + Uchar *p; + int sum = 0; + + new = (struct name_hash *) e_malloc(sizeof (struct name_hash)); + new->de = de; + new->next = NULL; + for (p = (Uchar *)de->isorec.name; *p; p++) { + if (*p == ';') + break; + sum += *p & 0xFF; + } + new->sum = sum; + hash = name_hash(de->isorec.name); + + /* Now insert into the hash table */ + new->next = name_hash_table[hash]; + name_hash_table[hash] = new; +} + +struct directory_entry * +find_file_hash(register char *name) +{ + register char *p1; + register char *p2; + register struct name_hash *nh; + register int sum = 0; + + if (debug > 1) + fprintf(stderr, "find_hash('%s')\n", name); + + for (p1 = name; *p1; p1++) { + if (*p1 == ';') + break; + sum += *p1 & 0xFF; + } + + for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) { + if (nh->sum != sum) + continue; + + p1 = name; + p2 = nh->de->isorec.name; + if (debug > 1) + fprintf(stderr, "Checking name '%s' isorec.name '%s'\n", p1, p2); + + /* Look for end of string, or a mismatch. */ + while (1 == 1) { + if ((*p1 == '\0' || *p1 == ';') || + (*p2 == '\0' || *p2 == ';') || + (*p1 != *p2)) { + break; + } + p1++; + p2++; + } + if (!isoname_endsok(p1) || !isoname_endsok(p2)) { + if (debug > 1) { + if (!isoname_endsok(p1)) + fprintf(stderr, "'%s' does NOT END OK\n", p1); + if (!isoname_endsok(p2)) + fprintf(stderr, "'%s' does NOT END OK\n", p2); + } + /* + * If one file does not end with a valid version number + * and the other name ends here, we found a miss match. + */ + if (*p1 == '\0' || *p2 == '\0') + continue; + + if (*p1 == ';' && *p2 == ';') { + p1++; + p2++; + continue; + } + } + + /* + * If we are at the end of both strings, then we have a match. + */ + if ((*p1 == '\0' || *p1 == ';') && + (*p2 == '\0' || *p2 == ';')) { + return (nh->de); + } + } + return (NULL); +} + +/* + * The macro 'eo' is just an idea on how one might speed up isoname_endsok() + */ +#define eo(p) (((p)[0] == '\0') || \ + ((p)[0] == ';' && (p)[1] == '1' && (p)[2] == '\0') || \ + isoname_endsok(p)) + +static BOOL +isoname_endsok(char *name) +{ + int i; + char *p; + + if (*name == '\0') + return (TRUE); + if (*name != ';') + return (FALSE); + + for (p = ++name, i = 0; *p && i < 5; p++, i++) { + if (*p < '0' || *p > '9') + return (FALSE); + } + i = atoi(name); + if (i < 1 || i > 32767) + return (FALSE); + return (TRUE); +} + +int +delete_file_hash(struct directory_entry *de) +{ + struct name_hash *nh; + struct name_hash *prev; + int hash; + + prev = NULL; + hash = name_hash(de->isorec.name); + for (nh = name_hash_table[hash]; nh; nh = nh->next) { + if (nh->de == de) + break; + prev = nh; + } + if (!nh) + return (1); + if (!prev) + name_hash_table[hash] = nh->next; + else + prev->next = nh->next; + free(nh); + return (0); +} + +void +flush_file_hash() +{ + struct name_hash *nh; + struct name_hash *nh1; + int i; + + for (i = 0; i < NR_NAME_HASH; i++) { + nh = name_hash_table[i]; + while (nh) { + nh1 = nh->next; + free(nh); + nh = nh1; + } + name_hash_table[i] = NULL; + + } +} diff --git a/genisoimage/hdisk.pl b/genisoimage/hdisk.pl new file mode 100755 index 0000000..55ef66c --- /dev/null +++ b/genisoimage/hdisk.pl @@ -0,0 +1,65 @@ +#!/usr/bin/perl + +############################################################################### +# +# hfsutils - tools for reading and writing Macintosh HFS volumes +# Copyright (C) 1996, 1997 Robert Leslie +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +############################################################################### + +die "Usage: $0 device-path\n" unless (@ARGV == 1); + +($disk) = @ARGV; + +format STDOUT_TOP = + # Partition Type HFS Volume Name Start Length +------------------------------------------------------------------------------- +. + +format STDOUT = +@# @<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<< @####### @######## +$bnum, $pmParType, $drVN, $pmPyPartStart, $pmPartBlkCnt +. + +open(DISK, $disk) || die "$disk: $!\n"; + +$bnum = 1; + +do { + seek(DISK, 512 * $bnum, 0) || die "seek: $!\n"; + read(DISK, $block, 512) || die "read: $!\n"; + + ($pmSig, $pmMapBlkCnt, $pmPyPartStart, $pmPartBlkCnt, $pmParType) = + (unpack('n2 N3 A32 A32 N10 A16', $block))[0, 2..4, 6]; + + die "$disk: unsupported partition map\n" if ($pmSig == 0x5453); + die "$disk: no partition map\n" unless ($pmSig == 0x504d); + + if ($pmParType eq 'Apple_HFS') { + seek(DISK, 512 * ($pmPyPartStart + 2), 0) || die "seek: $!\n"; + read(DISK, $block, 512) || die "read: $!\n"; + + ($len, $drVN) = (unpack('n N2 n5 N2 n N n c A27', $block))[13, 14]; + $drVN = substr($drVN, 0, $len); + } else { + $drVN = ''; + } + + write; +} while ($bnum++ < $pmMapBlkCnt); + +close(DISK); diff --git a/genisoimage/ifo_read.c b/genisoimage/ifo_read.c new file mode 100644 index 0000000..0173c47 --- /dev/null +++ b/genisoimage/ifo_read.c @@ -0,0 +1,559 @@ +/* + * 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. + * + */ + +/* @(#)ifo_read.c 1.5 04/03/04 joerg */ +/* + * Copyright (C) 2002 Olaf Beck <olaf_sc@yahoo.com> + * Jörg Schilling <schilling@fokus.gmd.de> + * (making the code portable) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTE: This is a cut down version of libdvdread for genisoimage, due + * to portability issues with the current libdvdread according to + * the maintainer of genisoimage. + * This cut down version only reads from a harddisk file structure + * and it only implements the functions necessary inorder to make + * genisoimage produce valid DVD-Video images. + * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL + * LIBDVDREAD INSTEAD + */ +#ifdef DVD_VIDEO + +#include <mconfig.h> +#include "genisoimage.h" +#include <fctldefs.h> +#include <utypes.h> +#include <schily.h> + +#include "ifo_read.h" +#include "bswap.h" + +#define MSGEREAD "Failed to read VIDEO_TS.IFO\n" +#define MSGESEEK "Failed to seek VIDEO_TS.IFO\n" +#define MSGEOPEN "Failed to open VIDEO_TS.IFO\n" + +static ifo_handle_t *ifoReadVTSI(int file, ifo_handle_t * ifofile); +static ifo_handle_t *ifoReadVGMI(int file, ifo_handle_t * ifofile); +ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title); +static void ifoFree_TT_SRPT(ifo_handle_t *ifofile); +void ifoClose(ifo_handle_t * ifofile); + + +static ifo_handle_t * +ifoReadVTSI(int file, ifo_handle_t *ifofile) +{ + off_t offset; + UInt32_t sector; + + vtsi_mat_t * vtsi_mat; + + /* Make the VMG part NULL */ + ifofile->vmgi_mat = NULL; + ifofile->tt_srpt = NULL; + + vtsi_mat = (vtsi_mat_t *)e_malloc(sizeof (vtsi_mat_t)); + if (!vtsi_mat) { +/* fprintf(stderr, "Memmory allocation error\n");*/ + free(ifofile); + return (0); + } + + ifofile->vtsi_mat = vtsi_mat; + + /* Last sector of VTS i.e. last sector of BUP */ + + offset = 12; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vtsi_mat->vts_last_sector = sector; + + /* Last sector of IFO */ + + offset = 28; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vtsi_mat->vtsi_last_sector = sector; + + + /* Star sector of VTS Menu VOB */ + + offset = 192; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vtsi_mat->vtsm_vobs = sector; + + + /* Start sector of VTS Title VOB */ + + offset = 196; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vtsi_mat->vtstt_vobs = sector; + + return (ifofile); +} + + +static ifo_handle_t * +ifoReadVGMI(int file, ifo_handle_t *ifofile) +{ + off_t offset; + Uint counter; + UInt32_t sector; + UInt16_t titles; + + vmgi_mat_t *vmgi_mat; + tt_srpt_t *tt_srpt; + + /* Make the VTS part null */ + ifofile->vtsi_mat = NULL; + + vmgi_mat = (vmgi_mat_t *)e_malloc(sizeof (vmgi_mat_t)); + if (!vmgi_mat) { +/* fprintf(stderr, "Memmory allocation error\n");*/ + free(ifofile); + return (0); + } + + ifofile->vmgi_mat = vmgi_mat; + + /* Last sector of VMG i.e. last sector of BUP */ + + offset = 12; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vmgi_mat->vmg_last_sector = sector; + + /* Last sector of IFO */ + + offset = 28; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vmgi_mat->vmgi_last_sector = sector; + + + /* Number of VTS i.e. title sets */ + + offset = 62; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + + if (read(file, &titles, sizeof (titles)) != sizeof (titles)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_16(titles); + + vmgi_mat->vmg_nr_of_title_sets = titles; + + + /* Star sector of VMG Menu VOB */ + + offset = 192; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vmgi_mat->vmgm_vobs = sector; + + + /* Sector offset to TT_SRPT */ + + offset = 196; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + vmgi_mat->tt_srpt = sector; + + tt_srpt = (tt_srpt_t *)e_malloc(sizeof (tt_srpt_t)); + if (!tt_srpt) { +/* fprintf(stderr, "Memmory allocation error\n");*/ + ifoClose(ifofile); + return (0); + } + + ifofile->tt_srpt = tt_srpt; + + + /* Number of titles in TT_SRPT */ + + offset = 2048 * vmgi_mat->tt_srpt; + + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + return (0); + } + + if (read(file, &titles, sizeof (titles)) != sizeof (titles)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + return (0); + } + + B2N_16(titles); + + tt_srpt->nr_of_srpts = titles; + + tt_srpt->title = (title_info_t *)e_malloc(sizeof (title_info_t) * tt_srpt->nr_of_srpts); + if (!tt_srpt->title) { +/* fprintf(stderr, "Memmory allocation error\n");*/ + ifoClose(ifofile); + return (0); + } + + /* Start sector of each title in TT_SRPT */ + + for (counter = 0; counter < tt_srpt->nr_of_srpts; counter++) { + offset = (2048 * vmgi_mat->tt_srpt) + 8 + (counter * 12) + 8; + if (lseek(file, offset, SEEK_SET) != offset) { +#ifdef USE_LIBSCHILY + errmsg(MSGESEEK); +#else + printf(stderr, MSGESEEK); +#endif + ifoClose(ifofile); + return (0); + } + + if (read(file, §or, sizeof (sector)) != sizeof (sector)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + ifoClose(ifofile); + return (0); + } + + B2N_32(sector); + + tt_srpt->title[counter].title_set_sector = sector; + + } + return (ifofile); +} + +ifo_handle_t * +ifoOpen(dvd_reader_t *dvd, int title) +{ + /* The main ifofile structure */ + ifo_handle_t *ifofile; + + /* File handles and offset */ + int file; + off_t offset; + char full_path[ PATH_MAX + 1 ]; + + /* Identifier of the IFO */ + char identifier[13]; + + identifier[0] = '\0'; + + ifofile = (ifo_handle_t *)e_malloc(sizeof (ifo_handle_t)); + + memset(ifofile, 0, sizeof (ifo_handle_t)); + + if (title) { + snprintf(full_path, sizeof (full_path), + "%s/VIDEO_TS/VTS_%02d_0.IFO", dvd->path_root, title); + } else { + snprintf(full_path, sizeof (full_path), + "%s/VIDEO_TS/VIDEO_TS.IFO", dvd->path_root); + } + + if ((file = open(full_path, O_RDONLY | O_BINARY)) == -1) { +#ifdef USE_LIBSCHILY + errmsg(MSGEOPEN); +#else + printf(stderr, MSGEOPEN); +#endif + free(ifofile); + return (0); + } + + offset = 0; + + /* Determine if we have a VMGI or VTSI */ + + if (read(file, identifier, sizeof (identifier)) != sizeof (identifier)) { +#ifdef USE_LIBSCHILY + errmsg(MSGEREAD); +#else + printf(stderr, MSGEREAD); +#endif + return (0); + } + + if ((strstr("DVDVIDEO-VMG", identifier) != 0) && (title == 0)) { + ifofile = ifoReadVGMI(file, ifofile); + close(file); + return (ifofile); + } else if ((strstr("DVDVIDEO-VTS", identifier) != 0) && (title != 0)) { + ifofile = ifoReadVTSI(file, ifofile); + close(file); + return (ifofile); + } else { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Giving up this is not a valid IFO file\n"); +#else + fprintf(stderr, "Giving up this is not a valid IFO file\n"); +#endif + close(file); + free(ifofile); + ifofile = 0; + return (0); + } +} + +static void +ifoFree_TT_SRPT(ifo_handle_t *ifofile) +{ + if (!ifofile) + return; + + if (ifofile->tt_srpt) { + if (ifofile->tt_srpt->title) { + free(ifofile->tt_srpt->title); + } + free(ifofile->tt_srpt); + ifofile->tt_srpt = 0; + } +} + +void +ifoClose(ifo_handle_t *ifofile) +{ + + if (!ifofile) + return; + + ifoFree_TT_SRPT(ifofile); + + if (ifofile->vmgi_mat) { + free(ifofile->vtsi_mat); + } + + if (ifofile->vtsi_mat) { + free(ifofile->vtsi_mat); + } + + free(ifofile); + ifofile = 0; +} +#endif /* DVD_VIDEO */ diff --git a/genisoimage/ifo_read.h b/genisoimage/ifo_read.h new file mode 100644 index 0000000..b8fa009 --- /dev/null +++ b/genisoimage/ifo_read.h @@ -0,0 +1,81 @@ +/* + * 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. + * + */ + +/* @(#)ifo_read.h 1.2 04/03/02 joerg */ + +#ifndef _IFO_READ_H +#define _IFO_READ_H + +/* + * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>, + * Håkan Hjort <d95hjort@dtek.chalmers.se + * Olaf Beck <olaf_sc@yahoo.com> + * (I only did the cut down no other contribs) + * Jörg Schilling <schilling@fokus.gmd.de> + * (making the code portable) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTE: This is a cut down version of libdvdread for genisoimage, due + * to portability issues with the current libdvdread according to + * the maintainer of genisoimage. + * This cut down version only reads from a harddisk file structure + * and it only implements the functions necessary inorder to make + * genisoimage produce valid DVD-Video images. + * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL + * LIBDVDREAD INSTEAD + */ + + + +#include "ifo_types.h" +#include "dvd_reader.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * handle = ifoOpen(dvd, title); + * + * Opens an IFO and reads a tiny fraction of the data for the IFO file + * corresponding to the given title set. If title 0 is given, the video + * manager IFO file is read. + * Returns a handle to a tiny parsed fraction of a IFO strcuture + */ +extern ifo_handle_t *ifoOpen(dvd_reader_t *, int); + + +/* + * ifoClose(ifofile); + * Cleans up the IFO information. This will free all data allocated. + */ +extern void ifoClose(ifo_handle_t *); + +#ifdef __cplusplus +}; +#endif +#endif /* _IFO_READ_H */ diff --git a/genisoimage/ifo_types.h b/genisoimage/ifo_types.h new file mode 100644 index 0000000..00b3bde --- /dev/null +++ b/genisoimage/ifo_types.h @@ -0,0 +1,91 @@ +/* + * 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. + * + */ + +/* @(#)ifo_types.h 1.2 04/03/02 joerg */ + +#ifndef _IFO_TYPES_H +#define _IFO_TYPES_H +/* + * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>, + * Håkan Hjort <d95hjort@dtek.chalmers.se>, + * Olaf Beck <olaf_sc@yahoo.com> + * (I only did the cut down no other contribs) + * Jörg Schilling <schilling@fokus.gmd.de> + * (making the code portable) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTE: This is a cut down version of libdvdread for genisoimage, due + * to portability issues with the current libdvdread according to + * the maintainer of genisoimage. + * This cut down version only reads from a harddisk file structure + * and it only implements the functions necessary inorder to make + * genisoimage produce valid DVD-Video images. + * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL + * LIBDVDREAD INSTEAD + */ + +#include "dvd_reader.h" + + +typedef struct { + UInt32_t title_set_sector; /* sector */ +} title_info_t; + + +typedef struct { + UInt16_t nr_of_srpts; + title_info_t * title; /* array of title info */ +} tt_srpt_t; + +typedef struct { + UInt32_t vmg_last_sector; /*sector */ + UInt32_t vmgi_last_sector; /* sector */ + UInt16_t vmg_nr_of_title_sets; + UInt32_t vmgm_vobs; /* sector */ + UInt32_t tt_srpt; /* sector */ +} vmgi_mat_t; + + + +typedef struct { + UInt32_t vts_last_sector; /* sector */ + UInt32_t vtsi_last_sector; /* sector */ + UInt32_t vtsm_vobs; /* sector */ + UInt32_t vtstt_vobs; /* sector */ +} vtsi_mat_t; + + +typedef struct { + /* VMGI */ + vmgi_mat_t * vmgi_mat; + tt_srpt_t * tt_srpt; + + /* VTSI */ + vtsi_mat_t * vtsi_mat; +} ifo_handle_t; + + +#endif /* _IFO_TYPES_H */ diff --git a/genisoimage/iso9660.h b/genisoimage/iso9660.h new file mode 100644 index 0000000..c74c2a9 --- /dev/null +++ b/genisoimage/iso9660.h @@ -0,0 +1,359 @@ +/* + * 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. + * + */ + +/* @(#)iso9660.h 1.19 04/03/02 joerg */ +/* + * Header file iso9660.h - assorted structure definitions and typecasts. + * specific to iso9660 filesystem. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-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 as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef _ISOFS_FS_H +#define _ISOFS_FS_H + +/* + * The isofs filesystem constants/structures + */ + +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) (to - from + 1) + +struct iso_volume_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; + char data [ISODCL(8, 2048)]; +}; + +/* volume descriptor types */ +#define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */ +#define ISO_VD_END 255 + +#define ISO_STANDARD_ID "CD001" + +#define EL_TORITO_ID "EL TORITO SPECIFICATION" +#define EL_TORITO_ARCH_x86 0 +#define EL_TORITO_ARCH_PPC 1 +#define EL_TORITO_ARCH_MAC 2 + +#define EL_TORITO_BOOTABLE 0x88 +#define EL_TORITO_NOT_BOOTABLE 0 + +#define EL_TORITO_MEDIA_NOEMUL 0 +#define EL_TORITO_MEDIA_12FLOP 1 +#define EL_TORITO_MEDIA_144FLOP 2 +#define EL_TORITO_MEDIA_288FLOP 3 +#define EL_TORITO_MEDIA_HD 4 + +struct iso_primary_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char unused1 [ISODCL(8, 8)]; + char system_id [ISODCL(9, 40)]; /* achars */ + char volume_id [ISODCL(41, 72)]; /* dchars */ + char unused2 [ISODCL(73, 80)]; + char volume_space_size [ISODCL(81, 88)]; /* 733 */ + char escape_sequences [ISODCL(89, 120)]; + char volume_set_size [ISODCL(121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + char logical_block_size [ISODCL(129, 132)]; /* 723 */ + char path_table_size [ISODCL(133, 140)]; /* 733 */ + char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL(191, 318)]; /* dchars */ + char publisher_id [ISODCL(319, 446)]; /* achars */ + char preparer_id [ISODCL(447, 574)]; /* achars */ + char application_id [ISODCL(575, 702)]; /* achars */ + char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL(882, 882)]; /* 711 */ + char unused4 [ISODCL(883, 883)]; + char application_data [ISODCL(884, 1395)]; + char unused5 [ISODCL(1396, 2048)]; +}; + +/* + * Supplementary or enhanced volume descriptor + */ +struct iso_enhanced_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char flags [ISODCL(8, 8)]; + char system_id [ISODCL(9, 40)]; /* achars */ + char volume_id [ISODCL(41, 72)]; /* dchars */ + char unused2 [ISODCL(73, 80)]; + char volume_space_size [ISODCL(81, 88)]; /* 733 */ + char escape_sequences [ISODCL(89, 120)]; + char volume_set_size [ISODCL(121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + char logical_block_size [ISODCL(129, 132)]; /* 723 */ + char path_table_size [ISODCL(133, 140)]; /* 733 */ + char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL(191, 318)]; /* dchars */ + char publisher_id [ISODCL(319, 446)]; /* achars */ + char preparer_id [ISODCL(447, 574)]; /* achars */ + char application_id [ISODCL(575, 702)]; /* achars */ + char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL(882, 882)]; /* 711 */ + char unused4 [ISODCL(883, 883)]; + char application_data [ISODCL(884, 1395)]; + char unused5 [ISODCL(1396, 2048)]; +}; + +/* El Torito Boot Record Volume Descriptor */ +struct eltorito_boot_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char system_id [ISODCL(8, 39)]; + char unused2 [ISODCL(40, 71)]; + char bootcat_ptr [ISODCL(72, 75)]; + char unused5 [ISODCL(76, 2048)]; +}; + +/* Validation entry for El Torito */ +struct eltorito_validation_entry { + char headerid [ISODCL(1, 1)]; /* 711 */ + char arch [ISODCL(2, 2)]; + char pad1 [ISODCL(3, 4)]; /* 711 */ + char id [ISODCL(5, 28)]; /* CD devel/man*/ + char cksum [ISODCL(29, 30)]; + char key1 [ISODCL(31, 31)]; + char key2 [ISODCL(32, 32)]; +}; + +/* El Torito initial/default entry in boot catalog */ +struct eltorito_defaultboot_entry { + char boot_id [ISODCL(1, 1)]; /* 711 */ + char boot_media [ISODCL(2, 2)]; + char loadseg [ISODCL(3, 4)]; /* 711 */ + char sys_type [ISODCL(5, 5)]; + char pad1 [ISODCL(6, 6)]; + char nsect [ISODCL(7, 8)]; + char bootoff [ISODCL(9, 12)]; + char pad2 [ISODCL(13, 32)]; +}; + +/* + * XXX JS: The next two structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See genisoimage.h + */ + +/* We use this to help us look up the parent inode numbers. */ + +struct iso_path_table { + unsigned char name_len[2]; /* 721 */ + char extent[4]; /* 731 */ + char parent[2]; /* 721 */ + char name[1]; +}; + +/* + * A ISO filename is: "abcde.eee;1" -> <filename> '.' <ext> ';' <version #> + * + * The maximum needed string length is: + * 30 chars (filename + ext) + * + 2 chars ('.' + ';') + * + strlen("32767") + * + null byte + * ================================ + * = 38 chars + * + * We currently do not support CD-ROM-XA entension records, but we must honor + * the needed space for ISO-9660:1999 (Version 2). + * + * XXX If we ever will start to support XA records, we will need to take care + * XXX that the the maximum ISO-9660 name length will be reduced by another + * XXX 14 bytes resulting in a new total of 179 Bytes. + */ +#define LEN_ISONAME 31 +#define MAX_ISONAME_V1 37 +#define MAX_ISONAME_V2 207 /* 254 - 33 - 14 (XA Record) */ +#define MAX_ISONAME_V2_RR 193 /* 254 - 33 - 28 (CE Record) */ +#define MAX_ISONAME_V2_RR_XA 179 /* 254 - 33 - 14 - 28 */ +#define MAX_ISONAME MAX_ISONAME_V2 /* Used for array space defs */ +#define MAX_ISODIR 254 /* Must be even and <= 255 */ + +struct iso_directory_record { + unsigned char length [ISODCL(1, 1)]; /* 711 */ + char ext_attr_length [ISODCL(2, 2)]; /* 711 */ + char extent [ISODCL(3, 10)]; /* 733 */ + char size [ISODCL(11, 18)]; /* 733 */ + char date [ISODCL(19, 25)]; /* 7 by 711 */ + char flags [ISODCL(26, 26)]; + char file_unit_size [ISODCL(27, 27)]; /* 711 */ + char interleave [ISODCL(28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL(29, 32)]; /* 723 */ + unsigned char name_len [ISODCL(33, 33)]; /* 711 */ + char name [MAX_ISONAME+1]; /* Not really, but we need something here */ +}; + + +/* + * Iso directory flags. + */ +#define ISO_FILE 0 /* Not really a flag... */ +#define ISO_EXISTENCE 1 /* Do not make existence known (hidden) */ +#define ISO_DIRECTORY 2 /* This file is a directory */ +#define ISO_ASSOCIATED 4 /* This file is an assiciated file */ +#define ISO_RECORD 8 /* Record format in extended attr. != 0 */ +#define ISO_PROTECTION 16 /* No read/execute perm. in ext. attr. */ +#define ISO_DRESERVED1 32 /* Reserved bit 5 */ +#define ISO_DRESERVED2 64 /* Reserved bit 6 */ +#define ISO_MULTIEXTENT 128 /* Not final entry of a mult. ext. file */ + + +struct iso_ext_attr_record { + char owner [ISODCL(1, 4)]; /* 723 */ + char group [ISODCL(5, 8)]; /* 723 */ + char permissions [ISODCL(9, 10)]; /* 16 bits */ + char creation_date [ISODCL(11, 27)]; /* 8.4.26.1 */ + char modification_date [ISODCL(28, 44)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(45, 61)]; /* 8.4.26.1 */ + char effective_date [ISODCL(62, 78)]; /* 8.4.26.1 */ + char record_format [ISODCL(79, 79)]; /* 711 */ + char record_attributes [ISODCL(80, 80)]; /* 711 */ + char record_length [ISODCL(81, 84)]; /* 723 */ + char system_id [ISODCL(85, 116)]; /* achars */ + char system_use [ISODCL(117, 180)]; + char ext_attr_version [ISODCL(181, 181)]; /* 711 */ + char esc_seq_len [ISODCL(182, 182)]; /* 711 */ + char reserved [ISODCL(183, 246)]; /* for future use */ + char appl_use_len [ISODCL(247, 250)]; /* 723 */ + char appl_use[1]; /* really more */ +/* char esc_seq[]; escape sequences recorded after appl_use */ +}; + +/* + * Iso extended attribute permissions. + */ +#define ISO_GS_READ 0x0001 /* System Group Read */ +#define ISO_BIT_1 0x0002 +#define ISO_GS_EXEC 0x0004 /* System Group Execute */ +#define ISO_BIT_3 0x0008 + +#define ISO_O_READ 0x0010 /* Owner Read */ +#define ISO_BIT_5 0x0020 +#define ISO_O_EXEC 0x0040 /* Owner Exexute */ +#define ISO_BIT_7 0x0080 + +#define ISO_G_READ 0x0100 /* Group Read */ +#define ISO_BIT_9 0x0200 +#define ISO_G_EXEC 0x0400 /* Group Execute */ +#define ISO_BIT_11 0x0800 + +#define ISO_W_READ 0x1000 /* World (other) Read */ +#define ISO_BIT_13 0x2000 +#define ISO_W_EXEC 0x4000 /* World (other) Execute */ +#define ISO_BIT_15 0x8000 + +#define ISO_MB_ONE (ISO_BIT_1|ISO_BIT_3|ISO_BIT_5|ISO_BIT_7| \ + ISO_BIT_9|ISO_BIT_11|ISO_BIT_13|ISO_BIT_15) + +/* + * Extended Attributes record according to Yellow Book. + */ +struct iso_xa_dir_record { + char group_id [ISODCL(1, 2)]; + char user_id [ISODCL(3, 4)]; + char attributes [ISODCL(5, 6)]; + char signature [ISODCL(7, 8)]; + char file_number [ISODCL(9, 9)]; + char reserved [ISODCL(10, 14)]; +}; + +/* + * Definitions for XA attributes + */ +#define XA_O_READ 0x0001 /* Owner Read */ +#define XA_O_RES 0x0002 /* Owner Reserved (write ?) */ +#define XA_O_EXEC 0x0004 /* Owner Execute */ +#define XA_O_RES2 0x0008 /* Owner Reserved */ +#define XA_G_READ 0x0010 /* Group Read */ +#define XA_G_RES 0x0020 /* Group Reserved (write ?) */ +#define XA_G_EXEC 0x0040 /* Group Execute */ +#define XA_G_RES2 0x0080 /* Group Reserved */ +#define XA_W_READ 0x0100 /* World Read */ +#define XA_W_RES 0x0200 /* World Reserved (write ?) */ +#define XA_W_EXEC 0x0400 /* World Execute */ + +#define XA_FORM1 0x0800 /* File contains Form 1 sector */ +#define XA_FORM2 0x1000 /* File contains Form 2 sector */ +#define XA_INTERLEAVED 0x2000 /* File contains interleaved sectors */ +#define XA_CDDA 0x4000 /* File contains audio data */ +#define XA_DIR 0x8000 /* This is a directory */ + +/* + * Definitions for CD-ROM XA-Mode-2-form-1/2 sector sub-headers + */ +struct xa_subhdr { + Uchar file_number; /* Identifies file for block */ + Uchar channel_number; /* Playback channel selection */ + Uchar sub_mode; /* See bit definitions below */ + Uchar coding; /* Coding information */ +}; + +/* + * Sub mode bit definitions + */ +#define XA_SUBH_EOR 0x01 /* End-Of-Record */ +#define XA_SUBH_VIDEO 0x02 /* Video Block */ +#define XA_SUBH_AUDIO 0x04 /* Audio Block (not CD-DA) */ +#define XA_SUBH_DATA 0x08 /* Data Block */ +#define XA_SUBH_TRIGGER 0x10 /* Trigger Block */ +#define XA_SUBH_FORM2 0x20 /* 0 == Form1, 1 == Form2 */ +#define XA_SUBH_REALTIME 0x40 /* Real Time Block */ +#define XA_SUBH_EOF 0x80 /* End-Of-File */ + +#endif /* _ISOFS_FS_H */ diff --git a/genisoimage/joliet.c b/genisoimage/joliet.c new file mode 100644 index 0000000..b36f8f7 --- /dev/null +++ b/genisoimage/joliet.c @@ -0,0 +1,1456 @@ +/* + * 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. + * + */ + +/* @(#)joliet.c 1.38 05/05/01 joerg */ +/* + * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660. + * + * Copyright 1997 Eric Youngdale. + * APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 22/2/2000 + * Copyright (c) 1999,2000,2001 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Joliet extensions for ISO9660. These are spottily documented by + * Microsoft. In their infinite stupidity, they completely ignored + * the possibility of using an SUSP record with the long filename + * in it, and instead wrote out a duplicate directory tree with the + * long filenames in it. + * + * I am not sure why they did this. One reason is that they get the path + * tables with the long filenames in them. + * + * There are two basic principles to Joliet, and the non-Unicode variant + * known as Romeo. Long filenames seem to be the main one, and the second + * is that the character set and a few other things is substantially relaxed. + * + * The SVD is identical to the PVD, except: + * + * Id is 2, not 1 (indicates SVD). + * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3). + * The root directory record points to a different extent (with different + * size). + * There are different path tables for the two sets of directory trees. + * + * The Unicode level is coded in the SVD as follows: + * + * Standard Level ASCII escape code + * UCS-2 Level-1 %/@ + * UCS-2 Level-2 %/C + * UCS-2 Level-3 %/E + * + * The following fields are recorded in Unicode: + * system_id + * volume_id + * volume_set_id + * publisher_id + * preparer_id + * application_id + * copyright_file_id + * abstract_file_id + * bibliographic_file_id + * + * Unicode strings are always encoded in big-endian format. + * + * In a directory record, everything is the same as with iso9660, except + * that the name is recorded in unicode. The name length is specified in + * total bytes, not in number of unicode characters. + * + * The character set used for the names is different with UCS - the + * restrictions are that the following are not allowed: + * + * Characters (00)(00) through (00)(1f) (control chars) + * (00)(2a) '*' + * (00)(2f) '/' + * (00)(3a) ':' + * (00)(3b) ';' + * (00)(3f) '?' + * (00)(5c) '\' + */ +#include <mconfig.h> +#include "genisoimage.h" +#include <timedefs.h> +#include <utypes.h> +#include <intcvt.h> +#include <unls.h> /* For UNICODE translation */ +#include <schily.h> +#include <string.h> + +#ifdef USE_ICONV +#include <iconv.h> +#include <errno.h> +#endif + +static Uint jpath_table_index; +static struct directory **jpathlist; +static int next_jpath_index = 1; +static int jsort_goof; + +static char ucs_codes[] = { + '\0', /* UCS-level 0 is illegal */ + '@', /* UCS-level 1 */ + 'C', /* UCS-level 2 */ + 'E', /* UCS-level 3 */ +}; + +#ifdef UDF +#ifdef USE_ICONV +size_t +#else +void +#endif +convert_to_unicode(unsigned char *buffer, int size, char *source, + struct unls_table *inls); +int joliet_strlen(const char *string, struct unls_table *inls); +#else +#ifdef USE_ICONV +static size_t +#else +static void +#endif +convert_to_unicode(unsigned char *buffer, int size, char *source, + struct unls_table *inls); +static int joliet_strlen(const char *string, struct nls_table *inls); +#endif +static void get_joliet_vol_desc(struct iso_primary_descriptor *jvol_desc); +static void assign_joliet_directory_addresses(struct directory *node); +static void build_jpathlist(struct directory *node); +static int joliet_compare_paths(void const *r, void const *l); +static int generate_joliet_path_tables(void); +static void generate_one_joliet_directory(struct directory *dpnt, + FILE *outfile); +static int joliet_sort_n_finish(struct directory *this_dir); +static int joliet_compare_dirs(const void *rr, const void *ll); +static int joliet_sort_directory(struct directory_entry **sort_dir); +int joliet_sort_tree(struct directory *node); +static void generate_joliet_directories(struct directory *node, FILE *outfile); +static int jpathtab_write(FILE *outfile); +static int jdirtree_size(int starting_extent); +static int jroot_gen(void); +static int jdirtree_write(FILE *outfile); +static int jvd_write(FILE *outfile); +static int jpathtab_size(int starting_extent); + +/* + * conv_charset: convert to/from charsets via Unicode. + * + * Any unknown character is set to '_' + * + */ +unsigned char +conv_charset(unsigned char c, + struct unls_table *inls, + struct unls_table *onls) +{ + unsigned char uh; + unsigned char ul; + unsigned char uc; + unsigned char *up; + + /* if we have a null mapping, just return the input character */ + if (inls == onls) + return (c); + +#ifdef USE_ICONV + if(inls->unls_cs2uni == NULL || onls->unls_uni2cs == NULL) { + /* + * This shouldn't be reached + */ + static BOOL iconv_warned = FALSE; + if(!iconv_warned) { + fprintf(stderr, "Warning: Iconv conversion not supported in conv_charset.\n"); + iconv_warned = TRUE; + } + return (c); + } +#endif + + /* get high and low UNICODE bytes */ + uh = inls->unls_cs2uni[c].unls_high; + ul = inls->unls_cs2uni[c].unls_low; + + /* get the backconverted page from the output charset */ + up = onls->unls_uni2cs[uh]; + + /* if the page exists, get the backconverted character */ + if (up == NULL) + uc = '\0'; + else + uc = up[ul]; + + /* return the backconverted, if it's not NULL */ + return (uc ? uc : '_'); +} + +/* + * Function: convert_to_unicode + * + * Purpose: Perform a unicode conversion on a text string + * using the supplied input character set. + * + * Notes: + */ +#ifdef USE_ICONV +# if UDF +size_t +# else +static size_t +# endif +#else +# if UDF +void +# else +static void +# endif +#endif +convert_to_unicode(unsigned char *buffer, int size, char *source, + struct unls_table *inls) +{ + unsigned char *tmpbuf; + int i; + int j; + unsigned char uh, + ul, + uc, + *up; + + /* + * If we get a NULL pointer for the source, it means we have an + * inplace copy, and we need to make a temporary working copy first. + */ + if (source == NULL) { + tmpbuf = (Uchar *) e_malloc(size+1); + memcpy(tmpbuf, buffer, size); + tmpbuf[size] = 0; + } else { + tmpbuf = (Uchar *) source; + } + +#ifdef USE_ICONV + if (inls->iconv_d && inls->unls_cs2uni==NULL && + inls->unls_uni2cs==NULL) { + char *inptr = (char *)tmpbuf; + char *outptr = (char *)buffer; + size_t inleft = strlen((char *)tmpbuf); + size_t inlen = inleft; + size_t outleft = size; + + iconv(inls->iconv_d, NULL, NULL, NULL, NULL); + if(iconv(inls->iconv_d, &inptr, &inleft, &outptr, &outleft) == + (size_t)-1 && errno == EILSEQ) { + fprintf(stderr, "Incorrectly encoded string (%s) " + "encountered.\nPossibly creating an invalid " + "Joliet extension. Aborting.\n", source); + exit(1); + } + + for (i = 0; (i + 1) < size - outleft; i += 2) { /* Size may be odd!!!*/ + if (buffer[i]=='\0') { + switch (buffer[i+1]) { /* Invalid characters for Joliet */ + case '*': + case '/': + case ':': + case ';': + case '?': + case '\\': + buffer[i+1]='_'; + default: + if (buffer[i+1] == 0x7f || + buffer[i+1] < 0x20) + buffer[i+1]='_'; + } + } + } + if (size & 1) { /* beautification */ + buffer[size - 1] = 0; + } + if (source == NULL) { + free(tmpbuf); + } + return (inlen - inleft); + } +#endif + + /* + * Now start copying characters. If the size was specified to be 0, + * then assume the input was 0 terminated. + */ + j = 0; + for (i = 0; (i + 1) < size; i += 2, j++) { /* Size may be odd! */ + /* + * JS integrated from: Achim_Kaiser@t-online.de + * SGE modified according to Linux kernel source + * Let all valid unicode characters pass + * through (according to charset). Others are set to '_' . + */ + uc = tmpbuf[j]; /* temporary copy */ + if (uc != '\0') { /* must be converted */ + uh = inls->unls_cs2uni[uc].unls_high; /* convert forward: */ + /* hibyte... */ + ul = inls->unls_cs2uni[uc].unls_low; /* ...lobyte */ + up = inls->unls_uni2cs[uh]; /* convert backward: */ + /* page... */ + if (up == NULL) + uc = '\0'; /* wrong unicode page */ + else + uc = up[ul]; /* backconverted character */ + if (uc != tmpbuf[j]) + uc = '\0'; /* should be identical */ + if (uc <= 0x1f || uc == 0x7f) + uc = '\0'; /* control char */ + switch (uc) { /* test special characters */ + + case '*': + case '/': + case ':': + case ';': + case '?': + case '\\': + case '\0': /* illegal char mark */ + /* + * Even Joliet has some standards as to what is + * allowed in a pathname. Pretty tame in + * comparison to what DOS restricts you to. + */ + uc = '_'; + } + } + buffer[i] = inls->unls_cs2uni[uc].unls_high; /* final UNICODE */ + /* conversion */ + buffer[i + 1] = inls->unls_cs2uni[uc].unls_low; + } + + if (size & 1) { /* beautification */ + buffer[size - 1] = 0; + } + if (source == NULL) { + free(tmpbuf); + } +#ifdef USE_ICONV + return j; +#endif +} + +/* + * Function: joliet_strlen + * + * Purpose: Return length in bytes of string after conversion to unicode. + * + * Notes: This is provided mainly as a convenience so that when more + * intelligent Unicode conversion for either Multibyte or 8-bit + * codes is available that we can easily adapt. + */ +#ifdef UDF +int +#else +static int +#endif +joliet_strlen(const char *string, struct unls_table *inls) +{ + int rtn; + +#ifdef USE_ICONV + if (inls->iconv_d && inls->unls_cs2uni==NULL && + inls->unls_uni2cs==NULL) { + /* + * we const-cast since we're sure iconv won't change + * the string itself + */ + char *string_ptr = (char *)string; + size_t string_len = strlen(string); + + /* + * iconv has no way of finding out the required size + * in the target + */ + + char *tmp, *tmp_ptr; + /* we assume that the maximum length is 2 * jlen */ + size_t tmp_len = (size_t)jlen * 2 + 1; + tmp = e_malloc(tmp_len); + tmp_ptr = tmp; + + iconv(inls->iconv_d, NULL, NULL, NULL, NULL); + iconv(inls->iconv_d, &string_ptr, &string_len, &tmp_ptr, + &tmp_len); + + /* + * iconv advanced the tmp pointer with as many chars + * as it has written to it, so we add up the delta + */ + rtn = (tmp_ptr - tmp); + + free(tmp); + } else { + rtn = strlen(string) << 1; + } +#else + rtn = strlen(string) << 1; +#endif + + /* + * We do clamp the maximum length of a Joliet string to be the + * maximum path size. This helps to ensure that we don't completely + * bolix things up with very long paths. The Joliet specs say that + * the maximum length is 128 bytes, or 64 unicode characters. + */ + if (rtn > 2*jlen) { + rtn = 2*jlen; + } + return (rtn); +} + +/* + * Function: get_joliet_vol_desc + * + * Purpose: generate a Joliet compatible volume desc. + * + * Notes: Assume that we have the non-joliet vol desc + * already present in the buffer. Just modifiy the + * appropriate fields. + */ +static void +get_joliet_vol_desc(struct iso_primary_descriptor *jvol_desc) +{ + jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY; + jvol_desc->version[0] = 1; + jvol_desc->file_structure_version[0] = 1; + + /* + * For now, always do Unicode level 3. + * I don't really know what 1 and 2 are - perhaps a more limited + * Unicode set. + * FIXME(eric) - how does Romeo fit in here? + */ + sprintf(jvol_desc->escape_sequences, "%%/%c", ucs_codes[ucs_level]); + + /* Until we have Unicode path tables, leave these unset. */ + set_733((char *) jvol_desc->path_table_size, jpath_table_size); + set_731(jvol_desc->type_l_path_table, jpath_table[0]); + set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]); + set_732(jvol_desc->type_m_path_table, jpath_table[2]); + set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]); + + /* Set this one up. */ + memcpy(jvol_desc->root_directory_record, &jroot_record, + offsetof(struct iso_directory_record, name[0]) + 1); + + /* + * Finally, we have a bunch of strings to convert to Unicode. + * FIXME(eric) - I don't know how to do this in general, + * so we will just be really lazy and do a char -> short conversion. + * We probably will want to filter any characters >= 0x80. + */ + convert_to_unicode((Uchar *) jvol_desc->system_id, + sizeof (jvol_desc->system_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->volume_id, + sizeof (jvol_desc->volume_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->volume_set_id, + sizeof (jvol_desc->volume_set_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->publisher_id, + sizeof (jvol_desc->publisher_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->preparer_id, + sizeof (jvol_desc->preparer_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->application_id, + sizeof (jvol_desc->application_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->copyright_file_id, + sizeof (jvol_desc->copyright_file_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->abstract_file_id, + sizeof (jvol_desc->abstract_file_id), NULL, in_nls); + convert_to_unicode((Uchar *) jvol_desc->bibliographic_file_id, + sizeof (jvol_desc->bibliographic_file_id), NULL, in_nls); +} + +static void +assign_joliet_directory_addresses(struct directory *node) +{ + int dir_size; + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { + /* + * If we already have an extent for this + * (i.e. it came from a multisession disc), then + * don't reassign a new extent. + */ + dpnt->jpath_index = next_jpath_index++; + if (dpnt->jextent == 0) { + dpnt->jextent = last_extent; + dir_size = ISO_BLOCKS(dpnt->jsize); + last_extent += dir_size; + } + } + /* skip if hidden - but not for the rr_moved dir */ + if (dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) { + assign_joliet_directory_addresses(dpnt->subdir); + } + dpnt = dpnt->next; + } +} + +static void +build_jpathlist(struct directory *node) +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { + jpathlist[dpnt->jpath_index] = dpnt; + } + if (dpnt->subdir) + build_jpathlist(dpnt->subdir); + dpnt = dpnt->next; + } +}/* build_jpathlist(... */ + +static int +joliet_compare_paths(void const *r, void const *l) +{ + struct directory const *ll = *(struct directory * const *) l; + struct directory const *rr = *(struct directory * const *) r; + int rparent, + lparent; + char *rpnt, + *lpnt; + unsigned char rtmp[2], + ltmp[2]; + struct unls_table *rinls, *linls; + + /* make sure root directory is first */ + if (rr == root) + return (-1); + + if (ll == root) + return (1); + + rparent = rr->parent->jpath_index; + lparent = ll->parent->jpath_index; + if (rr->parent == reloc_dir) { + rparent = rr->self->parent_rec->filedir->jpath_index; + } + if (ll->parent == reloc_dir) { + lparent = ll->self->parent_rec->filedir->jpath_index; + } + if (rparent < lparent) { + return (-1); + } + if (rparent > lparent) { + return (1); + } +#ifdef APPLE_HYB + /* + * we may be using the HFS name - so select the correct input + * charset + */ + if (USE_MAC_NAME(rr->self)) { + rpnt = rr->self->hfs_ent->name; + rinls = hfs_inls; + } else { + rpnt = rr->self->name; + rinls = in_nls; + } + + if (USE_MAC_NAME(ll->self)) { + lpnt = ll->self->hfs_ent->name; + linls = hfs_inls; + } else { + lpnt = ll->self->name; + linls = in_nls; + } +#else + rpnt = rr->self->name; + lpnt = ll->self->name; + linls = rinls = in_nls; +#endif /* APPLE_HYB */ + + /* compare the Unicode names */ + + while (*rpnt && *lpnt) { +#ifdef USE_ICONV + size_t ri, li; + + ri = convert_to_unicode(rtmp, 2, rpnt, rinls); + li = convert_to_unicode(ltmp, 2, lpnt, linls); + rpnt += ri; + lpnt += li; + if(!ri && !li) + return (0); + else if(ri && !li) + return (1); + else if(!ri && li) + return (-1); +#else + convert_to_unicode(rtmp, 2, rpnt, rinls); + convert_to_unicode(ltmp, 2, lpnt, linls); +#endif + + if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp)) + return (-1); + if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp)) + return (1); + +#ifndef USE_ICONV + rpnt++; + lpnt++; +#endif + } + + if (*rpnt) + return (1); + if (*lpnt) + return (-1); + + return (0); + +}/* compare_paths(... */ + +static int +generate_joliet_path_tables() +{ + struct directory_entry *de; + struct directory *dpnt; + int fix; + int j; + int namelen; + char *npnt; + char *npnt1; + int tablesize; + + /* First allocate memory for the tables and initialize the memory */ + tablesize = jpath_blocks << 11; + jpath_table_m = (char *) e_malloc(tablesize); + jpath_table_l = (char *) e_malloc(tablesize); + memset(jpath_table_l, 0, tablesize); + memset(jpath_table_m, 0, tablesize); + + /* Now start filling in the path tables. Start with root directory */ + jpath_table_index = 0; + jpathlist = (struct directory **) e_malloc(sizeof (struct directory *) + * next_jpath_index); + memset(jpathlist, 0, sizeof (struct directory *) * next_jpath_index); + build_jpathlist(root); + + do { + fix = 0; +#ifdef PROTOTYPES + qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *), + (int (*) (const void *, const void *)) joliet_compare_paths); +#else + qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *), + joliet_compare_paths); +#endif + + for (j = 1; j < next_jpath_index; j++) { + if (jpathlist[j]->jpath_index != j) { + jpathlist[j]->jpath_index = j; + fix++; + } + } + } while (fix); + + for (j = 1; j < next_jpath_index; j++) { + dpnt = jpathlist[j]; + if (!dpnt) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Entry %d not in path tables\n", j); +#else + fprintf(stderr, "Entry %d not in path tables\n", j); + exit(1); +#endif + } + npnt = dpnt->de_name; + + npnt1 = strrchr(npnt, PATH_SEPARATOR); + if (npnt1) { + npnt = npnt1 + 1; + } + de = dpnt->self; + if (!de) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Fatal Joliet goof - directory has amnesia\n"); +#else + fprintf(stderr, + "Fatal Joliet goof - directory has amnesia\n"); + exit(1); +#endif + } +#ifdef APPLE_HYB + if (USE_MAC_NAME(de)) + namelen = joliet_strlen(de->hfs_ent->name, hfs_inls); + else +#endif /* APPLE_HYB */ + namelen = joliet_strlen(de->name, in_nls); + + if (dpnt == root) { + jpath_table_l[jpath_table_index] = 1; + jpath_table_m[jpath_table_index] = 1; + } else { + jpath_table_l[jpath_table_index] = namelen; + jpath_table_m[jpath_table_index] = namelen; + } + jpath_table_index += 2; + + set_731(jpath_table_l + jpath_table_index, dpnt->jextent); + set_732(jpath_table_m + jpath_table_index, dpnt->jextent); + jpath_table_index += 4; + + if (dpnt->parent->jpath_index > 0xffff) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to generate sane path tables - too many directories (%d)\n", + dpnt->parent->jpath_index); +#else + fprintf(stderr, + "Unable to generate sane path tables - too many directories (%d)\n", + dpnt->parent->jpath_index); + exit(1); +#endif + } + + if (dpnt->parent != reloc_dir) { + set_721(jpath_table_l + jpath_table_index, + dpnt->parent->jpath_index); + set_722(jpath_table_m + jpath_table_index, + dpnt->parent->jpath_index); + } else { + set_721(jpath_table_l + jpath_table_index, + dpnt->self->parent_rec->filedir->jpath_index); + set_722(jpath_table_m + jpath_table_index, + dpnt->self->parent_rec->filedir->jpath_index); + } + + jpath_table_index += 2; + + /* + * The root directory is still represented in non-unicode + * fashion. + */ + if (dpnt == root) { + jpath_table_l[jpath_table_index] = 0; + jpath_table_m[jpath_table_index] = 0; + jpath_table_index++; + } else { +#ifdef APPLE_HYB + if (USE_MAC_NAME(de)) { + convert_to_unicode((Uchar *) jpath_table_l + + jpath_table_index, + namelen, de->hfs_ent->name, hfs_inls); + convert_to_unicode((Uchar *) jpath_table_m + + jpath_table_index, + namelen, de->hfs_ent->name, hfs_inls); + } else { +#endif /* APPLE_HYB */ + convert_to_unicode((Uchar *) jpath_table_l + + jpath_table_index, + namelen, de->name, in_nls); + convert_to_unicode((Uchar *) jpath_table_m + + jpath_table_index, + namelen, de->name, in_nls); +#ifdef APPLE_HYB + } +#endif /* APPLE_HYB */ + + jpath_table_index += namelen; + } + + if (jpath_table_index & 1) { + jpath_table_index++; /* For odd lengths we pad */ + } + } + + free(jpathlist); + if (jpath_table_index != jpath_table_size) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Joliet path table lengths do not match %d expected: %d\n", + jpath_table_index, + jpath_table_size); +#else + fprintf(stderr, + "Joliet path table lengths do not match %d expected: %d\n", + jpath_table_index, + jpath_table_size); +#endif + } + return (0); +}/* generate_path_tables(... */ + +static void +generate_one_joliet_directory(struct directory *dpnt, FILE *outfile) +{ + unsigned int dir_index; + char *directory_buffer; + int new_reclen; + struct directory_entry *s_entry; + struct directory_entry *s_entry1; + struct iso_directory_record jrec; + unsigned int total_size; + int cvt_len; + struct directory *finddir; + + total_size = ISO_ROUND_UP(dpnt->jsize); + directory_buffer = (char *) e_malloc(total_size); + memset(directory_buffer, 0, total_size); + dir_index = 0; + + s_entry = dpnt->jcontents; + while (s_entry) { + if (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { + s_entry = s_entry->jnext; + continue; + } + /* + * If this entry was a directory that was relocated, + * we have a bit of trouble here. We need to dig out the real + * thing and put it back here. In the Joliet tree, there is + * no relocated rock ridge, as there are no depth limits to a + * directory tree. + */ + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + for (s_entry1 = reloc_dir->contents; s_entry1; + s_entry1 = s_entry1->next) { + if (s_entry1->parent_rec == s_entry) { + break; + } + } + if (s_entry1 == NULL) { + /* We got trouble. */ +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to locate relocated directory\n"); +#else + fprintf(stderr, + "Unable to locate relocated directory\n"); + exit(1); +#endif + } + } else { + s_entry1 = s_entry; + } + + /* + * We do not allow directory entries to cross sector + * boundaries. Simply pad, and then start the next entry at + * the next sector + */ + new_reclen = s_entry1->jreclen; + if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) { + dir_index = ISO_ROUND_UP(dir_index); + } + memcpy(&jrec, &s_entry1->isorec, offsetof(struct iso_directory_record, name[0])); + +#ifdef APPLE_HYB + /* Use the HFS name if it exists */ + if (USE_MAC_NAME(s_entry1)) + cvt_len = joliet_strlen(s_entry1->hfs_ent->name, hfs_inls); + else +#endif /* APPLE_HYB */ + cvt_len = joliet_strlen(s_entry1->name, in_nls); + + /* + * Fix the record length + * - this was the non-Joliet version we were seeing. + */ + jrec.name_len[0] = cvt_len; + jrec.length[0] = s_entry1->jreclen; + + /* + * If this is a directory, + * fix the correct size and extent number. + */ + if ((jrec.flags[0] & ISO_DIRECTORY) != 0) { + if (strcmp(s_entry1->name, ".") == 0) { + jrec.name_len[0] = 1; + set_733((char *) jrec.extent, dpnt->jextent); + set_733((char *) jrec.size, ISO_ROUND_UP(dpnt->jsize)); + } else if (strcmp(s_entry1->name, "..") == 0) { + jrec.name_len[0] = 1; + if (dpnt->parent == reloc_dir) { + set_733((char *)jrec.extent, dpnt->self->parent_rec->filedir->jextent); + set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->self->parent_rec->filedir->jsize)); + } else { + set_733((char *)jrec.extent, dpnt->parent->jextent); + set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->parent->jsize)); + } + } else { + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + finddir = reloc_dir->subdir; + } else { + finddir = dpnt->subdir; + } + while (1 == 1) { + if (finddir->self == s_entry1) + break; + finddir = finddir->next; + if (!finddir) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Fatal goof - unable to find directory location\n"); +#else + fprintf(stderr, "Fatal goof - unable to find directory location\n"); + exit(1); +#endif + } + } + set_733((char *)jrec.extent, finddir->jextent); + set_733((char *)jrec.size, + ISO_ROUND_UP(finddir->jsize)); + } + } + memcpy(directory_buffer + dir_index, &jrec, + offsetof(struct iso_directory_record, name[0])); + + dir_index += offsetof(struct iso_directory_record, name[0]); + + /* + * Finally dump the Unicode version of the filename. + * Note - . and .. are the same as with non-Joliet discs. + */ + if ((jrec.flags[0] & ISO_DIRECTORY) != 0 && + strcmp(s_entry1->name, ".") == 0) { + directory_buffer[dir_index++] = 0; + } else if ((jrec.flags[0] & ISO_DIRECTORY) != 0 && + strcmp(s_entry1->name, "..") == 0) { + directory_buffer[dir_index++] = 1; + } else { +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry1)) { + /* Use the HFS name if it exists */ + convert_to_unicode( + (Uchar *) directory_buffer+dir_index, + cvt_len, + s_entry1->hfs_ent->name, hfs_inls); + } else +#endif /* APPLE_HYB */ + { + convert_to_unicode( + (Uchar *) directory_buffer+dir_index, + cvt_len, + s_entry1->name, in_nls); + } + dir_index += cvt_len; + } + + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + s_entry = s_entry->jnext; + } + + if (dpnt->jsize != dir_index) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Unexpected joliet directory length %d expected: %d '%s'\n", + dpnt->jsize, + dir_index, dpnt->de_name); +#else + fprintf(stderr, + "Unexpected joliet directory length %d expected: %d '%s'\n", + dpnt->jsize, + dir_index, dpnt->de_name); +#endif + } + jtwrite(directory_buffer, total_size, 1, 0, FALSE); + xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE); + last_extent_written += total_size >> 11; + free(directory_buffer); +}/* generate_one_joliet_directory(... */ + +static int +joliet_sort_n_finish(struct directory *this_dir) +{ + struct directory_entry *s_entry; + int status = 0; + + /* + * don't want to skip this directory if it's the reloc_dir + * at the moment + */ + if (this_dir != reloc_dir && + this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { + return (0); + } + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + /* skip hidden entries */ + if ((s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0) { + continue; + } + /* + * First update the path table sizes for directories. + * + * Finally, set the length of the directory entry if Joliet is + * used. The name is longer, but no Rock Ridge is ever used + * here, so depending upon the options the entry size might + * turn out to be about the same. The Unicode name is always + * a multiple of 2 bytes, so we always add 1 to make it an + * even number. + */ + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) { + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry)) + /* Use the HFS name if it exists */ + jpath_table_size += + joliet_strlen(s_entry->hfs_ent->name, hfs_inls) + + offsetof(struct iso_path_table, name[0]); + else +#endif /* APPLE_HYB */ + jpath_table_size += + joliet_strlen(s_entry->name, in_nls) + + offsetof(struct iso_path_table, name[0]); + if (jpath_table_size & 1) { + jpath_table_size++; + } + } else { + if (this_dir == root && + strlen(s_entry->name) == 1) { + + jpath_table_size += 1 + offsetof(struct iso_path_table, name[0]); + if (jpath_table_size & 1) + jpath_table_size++; + } + } + } + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry)) + /* Use the HFS name if it exists */ + s_entry->jreclen = + offsetof(struct iso_directory_record, name[0]) + + joliet_strlen(s_entry->hfs_ent->name, hfs_inls) + + 1; + else +#endif /* APPLE_HYB */ + s_entry->jreclen = + offsetof(struct iso_directory_record, name[0]) + + joliet_strlen(s_entry->name, in_nls) + + 1; + } else { + /* + * Special - for '.' and '..' we generate the same + * records we did for non-Joliet discs. + */ + s_entry->jreclen = + offsetof(struct iso_directory_record, name[0]) + + 1; + } + + + } + + if ((this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0) { + return (0); + } + this_dir->jcontents = this_dir->contents; + status = joliet_sort_directory(&this_dir->jcontents); + + /* + * Now go through the directory and figure out how large this one will + * be. Do not split a directory entry across a sector boundary + */ + s_entry = this_dir->jcontents; + /* + * XXX Is it ok to comment this out? + */ +/*XXX JS this_dir->ce_bytes = 0;*/ + for (s_entry = this_dir->jcontents; s_entry; + s_entry = s_entry->jnext) { + int jreclen; + + if ((s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0) { + continue; + } + jreclen = s_entry->jreclen; + + if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= + SECTOR_SIZE) { + this_dir->jsize = ISO_ROUND_UP(this_dir->jsize); + } + this_dir->jsize += jreclen; + } + return (status); +} + +/* + * Similar to the iso9660 case, + * except here we perform a full sort based upon the + * regular name of the file, not the 8.3 version. + */ +static int +joliet_compare_dirs(const void *rr, const void *ll) +{ + char *rpnt, + *lpnt; + struct directory_entry **r, + **l; + unsigned char rtmp[2], + ltmp[2]; + struct unls_table *linls, *rinls; + + r = (struct directory_entry **) rr; + l = (struct directory_entry **) ll; + +#ifdef APPLE_HYB + /* + * we may be using the HFS name - so select the correct input + * charset + */ + if (USE_MAC_NAME(*r)) { + rpnt = (*r)->hfs_ent->name; + rinls = hfs_inls; + } else { + rpnt = (*r)->name; + rinls = in_nls; + } + + if (USE_MAC_NAME(*l)) { + lpnt = (*l)->hfs_ent->name; + linls = hfs_inls; + } else { + lpnt = (*l)->name; + linls = in_nls; + } +#else + rpnt = (*r)->name; + lpnt = (*l)->name; + rinls = linls = in_nls; +#endif /* APPLE_HYB */ + + /* + * If the entries are the same, this is an error. + * Joliet specs allow for a maximum of 64 characters. + */ + if (strncmp(rpnt, lpnt, jlen) == 0) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Error: %s and %s have the same Joliet name\n", + (*r)->whole_name, (*l)->whole_name); +#else + fprintf(stderr, + "Error: %s and %s have the same Joliet name\n", + (*r)->whole_name, (*l)->whole_name); +#endif + jsort_goof++; + } + /* + * Put the '.' and '..' entries on the head of the sorted list. + * For normal ASCII, this always happens to be the case, but out of + * band characters cause this not to be the case sometimes. + */ + if (strcmp(rpnt, ".") == 0) + return (-1); + if (strcmp(lpnt, ".") == 0) + return (1); + + if (strcmp(rpnt, "..") == 0) + return (-1); + if (strcmp(lpnt, "..") == 0) + return (1); + +#ifdef DVD_VIDEO + /* + * There're rumors claiming that some players assume VIDEO_TS.IFO + * to be the first file in VIDEO_TS/ catalog. Well, it's basically + * the only file a player has to actually look for, as the whole + * video content can be "rolled down" from this file alone. + * <appro@fy.chalmers.se> + */ + /* + * XXX This code has to be moved from the Joliet implementation + * XXX to the UDF implementation if we implement decent UDF support + * XXX with a separate name space for the UDF file tree. + */ + if (dvd_video) { + if (strcmp(rpnt, "VIDEO_TS.IFO") == 0) + return (-1); + if (strcmp(lpnt, "VIDEO_TS.IFO") == 0) + return (1); + } +#endif + + while (*rpnt && *lpnt) { +#ifdef USE_ICONV + size_t ri, li; +#endif + if (*rpnt == ';' && *lpnt != ';') + return (-1); + if (*rpnt != ';' && *lpnt == ';') + return (1); + + if (*rpnt == ';' && *lpnt == ';') + return (0); + + /* + * Extensions are not special here. + * Don't treat the dot as something that must be bumped to + * the start of the list. + */ +#if 0 + if (*rpnt == '.' && *lpnt != '.') + return (-1); + if (*rpnt != '.' && *lpnt == '.') + return (1); +#endif + +#ifdef USE_ICONV + + ri = convert_to_unicode(rtmp, 2, rpnt, rinls); + li = convert_to_unicode(ltmp, 2, lpnt, linls); + rpnt += ri; + lpnt += li; + if(!ri && !li) + return (0); + else if(ri && !li) + return (1); + else if(!ri && li) + return (-1); +#else + convert_to_unicode(rtmp, 2, rpnt, rinls); + convert_to_unicode(ltmp, 2, lpnt, linls); +#endif + + if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp)) + return (-1); + if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp)) + return (1); + +#ifndef USE_ICONV + rpnt++; + lpnt++; +#endif + } + if (*rpnt) + return (1); + if (*lpnt) + return (-1); + return (0); +} + + +/* + * Function: sort_directory + * + * Purpose: Sort the directory in the appropriate ISO9660 + * order. + * + * Notes: Returns 0 if OK, returns > 0 if an error occurred. + */ +static int +joliet_sort_directory(struct directory_entry **sort_dir) +{ + int dcount = 0; + int i; + struct directory_entry *s_entry; + struct directory_entry **sortlist; + + s_entry = *sort_dir; + while (s_entry) { + /* skip hidden entries */ + if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) + dcount++; + s_entry = s_entry->next; + } + + /* OK, now we know how many there are. Build a vector for sorting. */ + sortlist = (struct directory_entry **) + e_malloc(sizeof (struct directory_entry *) * dcount); + + dcount = 0; + s_entry = *sort_dir; + while (s_entry) { + /* skip hidden entries */ + if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) { + sortlist[dcount] = s_entry; + dcount++; + } + s_entry = s_entry->next; + } + + jsort_goof = 0; +#ifdef PROTOTYPES + qsort(sortlist, dcount, sizeof (struct directory_entry *), + (int (*) (const void *, const void *)) joliet_compare_dirs); +#else + qsort(sortlist, dcount, sizeof (struct directory_entry *), + joliet_compare_dirs); +#endif + + /* Now reassemble the linked list in the proper sorted order */ + for (i = 0; i < dcount - 1; i++) { + sortlist[i]->jnext = sortlist[i + 1]; + } + + sortlist[dcount - 1]->jnext = NULL; + *sort_dir = sortlist[0]; + + free(sortlist); + return (jsort_goof); +} + +int +joliet_sort_tree(struct directory *node) +{ + struct directory *dpnt; + int ret = 0; + + dpnt = node; + + while (dpnt) { + ret = joliet_sort_n_finish(dpnt); + if (ret) { + break; + } + if (dpnt->subdir) + ret = joliet_sort_tree(dpnt->subdir); + if (ret) { + break; + } + dpnt = dpnt->next; + } + return (ret); +} + +static void +generate_joliet_directories(struct directory *node, FILE *outfile) +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { + /* + * In theory we should never reuse a directory, so this + * doesn't make much sense. + */ + if (dpnt->jextent > session_start) { + generate_one_joliet_directory(dpnt, outfile); + } + } + /* skip if hidden - but not for the rr_moved dir */ + if (dpnt->subdir && + (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || + dpnt == reloc_dir)) { + generate_joliet_directories(dpnt->subdir, outfile); + } + dpnt = dpnt->next; + } +} + + +/* + * Function to write the EVD for the disc. + */ +static int +jpathtab_write(FILE *outfile) +{ + /* Next we write the path tables */ + jtwrite(jpath_table_l, jpath_blocks << 11, 1, 0, FALSE); + xfwrite(jpath_table_l, jpath_blocks << 11, 1, outfile, 0, FALSE); + last_extent_written += jpath_blocks; + jtwrite(jpath_table_m, jpath_blocks << 11, 1, 0, FALSE); + xfwrite(jpath_table_m, jpath_blocks << 11, 1, outfile, 0, FALSE); + last_extent_written += jpath_blocks; + free(jpath_table_l); + free(jpath_table_m); + jpath_table_l = NULL; + jpath_table_m = NULL; + return (0); +} + +static int +jdirtree_size(int starting_extent) +{ + assign_joliet_directory_addresses(root); + return (0); +} + +static int +jroot_gen() +{ + jroot_record.length[0] = + 1 + offsetof(struct iso_directory_record, name[0]); + jroot_record.ext_attr_length[0] = 0; + set_733((char *) jroot_record.extent, root->jextent); + set_733((char *) jroot_record.size, ISO_ROUND_UP(root->jsize)); + iso9660_date(jroot_record.date, root_statbuf.st_mtime); + jroot_record.flags[0] = ISO_DIRECTORY; + jroot_record.file_unit_size[0] = 0; + jroot_record.interleave[0] = 0; + set_723(jroot_record.volume_sequence_number, volume_sequence_number); + jroot_record.name_len[0] = 1; + return (0); +} + +static int +jdirtree_write(FILE *outfile) +{ + generate_joliet_directories(root, outfile); + return (0); +} + +/* + * Function to write the EVD for the disc. + */ +static int +jvd_write(FILE *outfile) +{ + struct iso_primary_descriptor jvol_desc; + + /* Next we write out the boot volume descriptor for the disc */ + jvol_desc = vol_desc; + get_joliet_vol_desc(&jvol_desc); + jtwrite(&jvol_desc, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(&jvol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Functions to describe padding block at the start of the disc. + */ +static int +jpathtab_size(int starting_extent) +{ + jpath_table[0] = starting_extent; + jpath_table[1] = 0; + jpath_table[2] = jpath_table[0] + jpath_blocks; + jpath_table[3] = 0; + + last_extent += 2 * jpath_blocks; + return (0); +} + +struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen, jvd_write, "Joliet Volume Descriptor" }; +struct output_fragment jpathtable_desc = {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write, "Joliet path table" }; +struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write, "Joliet directory tree" }; diff --git a/genisoimage/jte.c b/genisoimage/jte.c new file mode 100644 index 0000000..0dff289 --- /dev/null +++ b/genisoimage/jte.c @@ -0,0 +1,1042 @@ +/* + * jte.c + * + * Copyright (c) 2004-2006 Steve McIntyre <steve@einval.com> + * + * Implementation of the Jigdo Template Engine - make jigdo files + * directly when making ISO images + * + * GNU GPL v2 + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <timedefs.h> +#include <fctldefs.h> +#include <zlib.h> +#include <bzlib.h> +#include <regex.h> +#ifdef SORTING +#include "match.h" +#endif /* SORTING */ +#include <errno.h> +#include <schily.h> +#ifdef DVD_VIDEO +#include "dvd_reader.h" +#include "dvd_file.h" +#include "ifo_read.h" +#include "endianconv.h" +#include "checksum.h" +#endif +#ifdef APPLE_HYB +#include <ctype.h> +#endif + +#ifdef VMS +#include "vms.h" +#endif + +/* Different types used in building our state list below */ +#define JTET_FILE_MATCH 1 +#define JTET_NOMATCH 2 + +#define JTE_VER_MAJOR 0x0001 +#define JTE_VER_MINOR 0x0013 +#define JTE_NAME "JTE" +#define JTE_COMMENT "JTE at http://www.einval.com/~steve/software/JTE/ ; jigdo at http://atterer.org/jigdo/" + +#define JIGDO_TEMPLATE_VERSION "1.1" + +/* + Simple list to hold the results of -jigdo-exclude and + -jigdo-force-match command line options. Seems easiest to do this + using regexps. +*/ +struct path_match +{ + regex_t match_pattern; + char *match_rule; + struct path_match *next; +}; + +/* List of mappings e.g. Debian=/mirror/debian */ +struct path_mapping +{ + char *from; + char *to; + struct path_mapping *next; +}; + +FILE *jtjigdo = NULL; /* File handle used throughout for the jigdo file */ +FILE *jttemplate = NULL; /* File handle used throughout for the template file */ +char *jjigdo_out = NULL; /* Output name for jigdo .jigdo file; NULL means don't do it */ +char *jtemplate_out = NULL; /* Output name for jigdo template file; NULL means don't do it */ +char *jmd5_list = NULL; /* Name of file to use for MD5 checking */ +int jte_min_size = MIN_JIGDO_FILE_SIZE; +jtc_t jte_template_compression = JTE_TEMP_GZIP; +struct path_match *exclude_list = NULL; +struct path_match *include_list = NULL; +struct path_mapping *map_list = NULL; +unsigned long long template_size = 0; +unsigned long long image_size = 0; +int checksum_algo_iso = (CHECK_MD5_USED | \ + CHECK_SHA1_USED | \ + CHECK_SHA256_USED | \ + CHECK_SHA512_USED); +int checksum_algo_tmpl = CHECK_MD5_USED; + +static checksum_context_t *iso_context = NULL; +static checksum_context_t *template_context = NULL; + +/* List of files that we've seen, ready to write into the template and + jigdo files */ +typedef struct _file_entry +{ + unsigned char md5[16]; + off_t file_length; + unsigned long long rsyncsum; + char *filename; +} file_entry_t; + +typedef struct _unmatched_entry +{ + off_t uncompressed_length; +} unmatched_entry_t; + +typedef struct _entry +{ + int entry_type; /* JTET_TYPE as above */ + struct _entry *next; + union + { + file_entry_t file; + unmatched_entry_t chunk; + } data; +} entry_t; + +typedef struct _jigdo_file_entry +{ + unsigned char type; + unsigned char fileLen[6]; + unsigned char fileRsync[8]; + unsigned char fileMD5[16]; +} jigdo_file_entry_t; + +typedef struct _jigdo_chunk_entry +{ + unsigned char type; + unsigned char skipLen[6]; +} jigdo_chunk_entry_t; + +typedef struct _jigdo_image_entry +{ + unsigned char type; + unsigned char imageLen[6]; + unsigned char imageMD5[16]; + unsigned char blockLen[4]; +} jigdo_image_entry_t; + +typedef struct _md5_list_entry +{ + struct _md5_list_entry *next; + unsigned char MD5[16]; + unsigned long long size; + char *filename; +} md5_list_entry_t; + +entry_t *entry_list = NULL; +entry_t *entry_last = NULL; +FILE *t_file = NULL; +FILE *j_file = NULL; +int num_matches = 0; +int num_chunks = 0; +md5_list_entry_t *md5_list = NULL; +md5_list_entry_t *md5_last = NULL; + +/* Grab the file component from a full path */ +static char *file_base_name(char *path) +{ + char *endptr = path; + char *ptr = path; + + while (*ptr != '\0') + { + if ('/' == *ptr) + endptr = ++ptr; + else + ++ptr; + } + return endptr; +} + +/* Build the list of exclusion regexps */ +extern int jte_add_exclude(char *pattern) +{ + struct path_match *new = NULL; + + new = malloc(sizeof *new); + if (!new) + return ENOMEM; + + regcomp(&new->match_pattern, pattern, REG_NEWLINE); + new->match_rule = pattern; + + /* Order on the exclude list doesn't matter! */ + new->next = exclude_list; + + exclude_list = new; + return 0; +} + +/* Check if the file should be excluded because of a filename match. 1 + means exclude, 0 means not */ +static int check_exclude_by_name(char *filename, char **matched) +{ + struct path_match *ptr = exclude_list; + regmatch_t pmatch[1]; + int i = 0; + + while (ptr) + { + if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0)) + { + *matched = ptr->match_rule; + return 1; + } + ptr = ptr->next; + } + + /* Not matched, so return 0 */ + return 0; +} + +/* Build the list of required inclusion regexps */ +extern int jte_add_include(char *pattern) +{ + struct path_match *new = NULL; + + new = malloc(sizeof *new); + if (!new) + return ENOMEM; + + regcomp(&new->match_pattern, pattern, REG_NEWLINE); + new->match_rule = pattern; + + /* Order on the include list doesn't matter! */ + new->next = include_list; + + include_list = new; + return 0; +} + +/* Check if a file has to be MD5-matched to be valid. If we get called + here, we've failed to match any of the MD5 entries we were + given. If the path to the filename matches one of the paths in our + list, clearly it must have been corrupted. Abort with an error. */ +static void check_md5_file_match(char *filename) +{ + struct path_match *ptr = include_list; + regmatch_t pmatch[1]; + int i = 0; + + while (ptr) + { + if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0)) + { +#ifdef USE_LIBSCHILY + comerr("File %s should have matched an MD5 entry, but didn't! (Rule '%s')\n", filename, ptr->match_rule); +#else + fprintf(stderr, "File %s should have matched an MD5 entry, but didn't! (Rule '%s')\n", filename, ptr->match_rule); + exit(1); +#endif + } + ptr = ptr->next; + } +} + +/* Should we list a file separately in the jigdo output, or should we + just dump it into the template file as binary data? Three things + cases to look for here: + + 1. Small files are better simply folded in, as they take less space that way. + + 2. Files in /doc (for example) may change in the archive all the + time and it's better to not have to fetch snapshot copies if we + can avoid it. + + 3. Files living in specified paths *must* match an entry in the + md5-list, or they must have been corrupted. If we find a corrupt + file, bail out with an error. + +*/ +extern int list_file_in_jigdo(char *filename, off_t size, char **realname, unsigned char md5[16]) +{ + char *matched_rule; + md5_list_entry_t *entry = md5_list; + int md5sum_done = 0; + + if (!jtemplate_out) + return 0; + + memset(md5, 0, sizeof(md5)); + + /* Cheaper to check file size first */ + if (size < jte_min_size) + { + if (verbose > 1) + fprintf(stderr, "Jigdo-ignoring file %s; it's too small\n", filename); + return 0; + } + + /* Now check the excluded list by name */ + if (check_exclude_by_name(filename, &matched_rule)) + { + if (verbose > 1) + fprintf(stderr, "Jigdo-ignoring file %s; it's covered in the exclude list by \"%s\"\n", filename, matched_rule); + return 0; + } + + /* Check to see if the file is in our md5 list. Check three things: + + 1. the size + 2. the filename + 3. (only if the first 2 match) the md5sum + + If we get a match for all three, include the file and return + the full path to the file that we have gleaned from the mirror. + */ + + while (entry) + { + if (size == entry->size) + { + if (!strcmp(file_base_name(filename), file_base_name(entry->filename))) + { + if (!md5sum_done) + { + calculate_md5sum(filename, size, md5); + md5sum_done = 1; + } + if (!memcmp(md5, entry->MD5, sizeof(entry->MD5))) + { + *realname = entry->filename; + return 1; + } + } + } + entry = entry->next; + } + + /* We haven't found an entry in our MD5 list to match this + * file. If we should have done, complain and bail out. */ + check_md5_file_match(filename); + return 0; +} + +/* Add a mapping of pathnames (e.g. Debian=/mirror/debian). We should + be passed TO=FROM here */ +extern int jte_add_mapping(char *arg) +{ + int error = 0; + struct path_mapping *new = NULL; + struct path_mapping *entry = NULL; + char *p = arg; + char *from = NULL; + char *to = NULL; + + /* Find the "=" in the string passed. Set it to NULL and we can + use the string in-place */ + while (*p) + { + if ('=' == *p) + { + *p = 0; + p++; + to = arg; + from = p; + } + p++; + } + if (!from || !strlen(from) || !to || !strlen(to)) + return EINVAL; + + new = malloc(sizeof(*new)); + if (!new) + return ENOMEM; + + new->from = from; + new->to = to; + new->next = NULL; + + if (verbose > 0) + fprintf(stderr, "Adding mapping from %s to %s for the jigdo file\n", from, to); + if (!map_list) + map_list = new; + else + { + /* Order is important; add to the end of the list */ + entry = map_list; + while (NULL != entry->next) + entry = entry->next; + entry->next = new; + } + return 0; +} + +/* Check if the filename should be remapped; if so map it, otherwise + return the original name. */ +static char *remap_filename(char *filename) +{ + char *new_name = filename; + struct path_mapping *entry = map_list; + + while (entry) + { + if (!strncmp(filename, entry->from, strlen(entry->from))) + { + new_name = calloc(1, 2 + strlen(filename) + strlen(entry->to) - strlen(entry->from)); + if (!new_name) + { + fprintf(stderr, "Failed to malloc new filename; abort!\n"); + exit(1); + } + sprintf(new_name, "%s:%s", entry->to, &filename[strlen(entry->from)]); + return new_name; + } + entry = entry->next; + } + + /* No mapping in effect */ + return strdup(filename); +} + +/* Write data to the template file and update the MD5 sum */ +static size_t template_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + checksum_update(template_context, ptr, size * nmemb); + template_size += (unsigned long long)size * nmemb; + return fwrite(ptr, size, nmemb, stream); +} + +/* Create a new template file and initialise it */ +static void write_template_header() +{ + char buf[2048]; + int i = 0; + char *p = buf; + + memset(buf, 0, sizeof(buf)); + + template_context = checksum_init_context(checksum_algo_tmpl, "template"); + if (!template_context) + { +#ifdef USE_LIBSCHILY + comerr("cannot allocate template checksum contexts\n"); +#else + fprintf(stderr, "cannot allocate template checksum contexts\n"); + exit(1); +#endif + } + + i += sprintf(p, "JigsawDownload template %s %s/%d.%d \r\n", + JIGDO_TEMPLATE_VERSION, JTE_NAME, JTE_VER_MAJOR, JTE_VER_MINOR); + p = &buf[i]; + + i += sprintf(p, "%s \r\n", JTE_COMMENT); + p = &buf[i]; + + i += sprintf(p, "\r\n"); + template_fwrite(buf, i, 1, t_file); +} + +/* Read the MD5 list and build a list in memory for us to use later */ +static void add_md5_entry(unsigned char *md5, unsigned long long size, char *filename) +{ + int error = 0; + md5_list_entry_t *new = NULL; + + new = calloc(1, sizeof(md5_list_entry_t)); + memcpy(new->MD5, md5, sizeof(new->MD5)); + new->size = size; + new->filename = strdup(filename); + + /* Add to the end of the list */ + if (NULL == md5_last) + { + md5_last = new; + md5_list = new; + } + else + { + md5_last->next = new; + md5_last = new; + } +} + +/* Parse a 12-digit decimal number */ +static unsigned long long parse_number(unsigned char in[12]) +{ + unsigned long long size = 0; + int i = 0; + + for (i = 0; i < 12; i++) + { + size *= 10; + if (isdigit(in[i])) + size += (in[i] - '0'); + } + + return size; +} + +/* Read the MD5 list and build a list in memory for us to use later + MD5 list format: + + <---MD5---> <--Size--> <--Filename--> + 32 12 remaining +*/ +static void parse_md5_list(void) +{ + FILE *md5_file = NULL; + unsigned char buf[1024]; + unsigned char md5[16]; + char *filename = NULL; + unsigned char *numbuf = NULL; + int num_files = 0; + unsigned long long size = 0; + + md5_file = fopen(jmd5_list, "rb"); + if (!md5_file) + { +#ifdef USE_LIBSCHILY + comerr("cannot read from MD5 list file '%s'\n", jmd5_list); +#else + fprintf(stderr, "cannot read from MD5 list file '%s'\n", jmd5_list); + exit(1); +#endif + } + + memset(buf, 0, sizeof(buf)); + while (fgets((char *)buf, sizeof(buf), md5_file)) + { + numbuf = &buf[34]; + filename = (char *)&buf[48]; + /* Lose the trailing \n from the fgets() call */ + if (buf[strlen((char *)buf)-1] == '\n') + buf[strlen((char *)buf)-1] = 0; + + if (mk_MD5Parse(buf, md5)) + { +#ifdef USE_LIBSCHILY + comerr("cannot parse MD5 file '%s'\n", jmd5_list); +#else + fprintf(stderr, "cannot parse MD5 file '%s'\n", jmd5_list); + exit(1); +#endif + } + size = parse_number(numbuf); + add_md5_entry(md5, size, filename); + memset(buf, 0, sizeof(buf)); + num_files++; + } + if (verbose > 0) + fprintf(stderr, "parse_md5_list: added MD5 checksums for %d files\n", num_files); + fclose(md5_file); +} + +/* Initialise state and start the jigdo template file */ +void write_jt_header(FILE *template_file, FILE *jigdo_file) +{ + t_file = template_file; + j_file = jigdo_file; + + /* Start checksum work for the image */ + iso_context = checksum_init_context(checksum_algo_iso, "iso"); + if (!iso_context) + { +#ifdef USE_LIBSCHILY + comerr("cannot allocate iso checksum contexts\n"); +#else + fprintf(stderr, "cannot allocate iso checksum contexts\n"); + exit(1); +#endif + } + + /* Start the template file */ + write_template_header(); + + /* Load up the MD5 list if we've been given one */ + if (jmd5_list) + parse_md5_list(); +} + +/* Compress and flush out a buffer full of template data */ +static void flush_gzip_chunk(void *buffer, off_t size) +{ + z_stream c_stream; /* compression stream */ + unsigned char comp_size_out[6]; + unsigned char uncomp_size_out[6]; + off_t compressed_size_out = 0; + int err = 0; + unsigned char *comp_buf = NULL; + + c_stream.zalloc = NULL; + c_stream.zfree = NULL; + c_stream.opaque = NULL; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + comp_buf = malloc(2 * size); /* Worst case */ + c_stream.next_out = comp_buf; + c_stream.avail_out = 2 * size; + c_stream.next_in = buffer; + c_stream.avail_in = size; + + err = deflate(&c_stream, Z_NO_FLUSH); + err = deflate(&c_stream, Z_FINISH); + + compressed_size_out = c_stream.total_out + 16; + err = deflateEnd(&c_stream); + + template_fwrite("DATA", 4, 1, t_file); + + write_le48(compressed_size_out, &comp_size_out[0]); + template_fwrite(comp_size_out, sizeof(comp_size_out), 1, t_file); + + write_le48(size, &uncomp_size_out[0]); + template_fwrite(uncomp_size_out, sizeof(uncomp_size_out), 1, t_file); + + template_fwrite(comp_buf, c_stream.total_out, 1, t_file); + free(comp_buf); +} + +/* Compress and flush out a buffer full of template data */ +static void flush_bz2_chunk(void *buffer, off_t size) +{ + bz_stream c_stream; /* compression stream */ + unsigned char comp_size_out[6]; + unsigned char uncomp_size_out[6]; + off_t compressed_size_out = 0; + int err = 0; + unsigned char *comp_buf = NULL; + + c_stream.bzalloc = NULL; + c_stream.bzfree = NULL; + c_stream.opaque = NULL; + + err = BZ2_bzCompressInit(&c_stream, 9, 0, 0); + comp_buf = malloc(2 * size); /* Worst case */ + c_stream.next_out = comp_buf; + c_stream.avail_out = 2 * size; + c_stream.next_in = buffer; + c_stream.avail_in = size; + + err = BZ2_bzCompress(&c_stream, BZ_FINISH); + + compressed_size_out = c_stream.total_out_lo32 + 16; + err = BZ2_bzCompressEnd(&c_stream); + + template_fwrite("BZIP", 4, 1, t_file); + + write_le48(compressed_size_out, &comp_size_out[0]); + template_fwrite(comp_size_out, sizeof(comp_size_out), 1, t_file); + + write_le48(size, &uncomp_size_out[0]); + template_fwrite(uncomp_size_out, sizeof(uncomp_size_out), 1, t_file); + + template_fwrite(comp_buf, c_stream.total_out_lo32, 1, t_file); + free(comp_buf); +} + +static void flush_compressed_chunk(void *buffer, off_t size) +{ + if (jte_template_compression == JTE_TEMP_BZIP2) + flush_bz2_chunk(buffer, size); + else + flush_gzip_chunk(buffer, size); +} + +/* Append to an existing data buffer, and compress/flush it if + necessary */ +static void write_compressed_chunk(unsigned char *buffer, size_t size) +{ + static unsigned char *uncomp_buf = NULL; + static size_t uncomp_size = 0; + static size_t uncomp_buf_used = 0; + + if (!uncomp_buf) + { + if (jte_template_compression == JTE_TEMP_BZIP2) + uncomp_size = 900 * 1024; + else + uncomp_size = 1024 * 1024; + uncomp_buf = malloc(uncomp_size); + if (!uncomp_buf) + { +#ifdef USE_LIBSCHILY + comerr("failed to allocate %d bytes for template compression buffer\n", uncomp_size); +#else + fprintf(stderr, "failed to allocate %d bytes for template compression buffer\n", uncomp_size); + exit(1); +#endif + } + } + + if ((uncomp_buf_used + size) > uncomp_size) + { + flush_compressed_chunk(uncomp_buf, uncomp_buf_used); + uncomp_buf_used = 0; + } + + if (!size) /* Signal a flush before we start writing the DESC entry */ + { + flush_compressed_chunk(uncomp_buf, uncomp_buf_used); + return; + } + + if (!uncomp_buf_used) + memset(uncomp_buf, 0, uncomp_size); + + while (size > uncomp_size) + { + flush_compressed_chunk(buffer, uncomp_size); + buffer += uncomp_size; + size -= uncomp_size; + } + memcpy(&uncomp_buf[uncomp_buf_used], buffer, size); + uncomp_buf_used += size; +} + +/* Loop through the list of DESC entries that we've built up and + append them to the template file */ +static void write_template_desc_entries(off_t image_len) +{ + entry_t *entry = entry_list; + off_t desc_len = 0; + unsigned char out_len[6]; + jigdo_image_entry_t jimage; + + desc_len = 16 /* DESC + length twice */ + + (sizeof(jigdo_file_entry_t) * num_matches) + + (sizeof(jigdo_chunk_entry_t) * num_chunks) + + sizeof(jigdo_image_entry_t); + + write_le48(desc_len, &out_len[0]); + write_compressed_chunk(NULL, 0); + template_fwrite("DESC", 4, 1, t_file); + template_fwrite(out_len, sizeof(out_len), 1, t_file); + + while (entry) + { + switch (entry->entry_type) + { + case JTET_FILE_MATCH: + { + jigdo_file_entry_t jfile; + jfile.type = 6; /* Matched file */ + write_le48(entry->data.file.file_length, &jfile.fileLen[0]); + write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]); + memcpy(jfile.fileMD5, entry->data.file.md5, sizeof(jfile.fileMD5)); + template_fwrite(&jfile, sizeof(jfile), 1, t_file); + break; + } + case JTET_NOMATCH: + { + jigdo_chunk_entry_t jchunk; + jchunk.type = 2; /* Raw data, compressed */ + write_le48(entry->data.chunk.uncompressed_length, &jchunk.skipLen[0]); + template_fwrite(&jchunk, sizeof(jchunk), 1, t_file); + break; + } + } + entry = entry->next; + } + + jimage.type = 5; + write_le48(image_len, &jimage.imageLen[0]); + checksum_copy(iso_context, CHECK_MD5, &jimage.imageMD5[0]); + write_le32(MIN_JIGDO_FILE_SIZE, &jimage.blockLen[0]); + template_fwrite(&jimage, sizeof(jimage), 1, t_file); + template_fwrite(out_len, sizeof(out_len), 1, t_file); +} + +/* Dump a buffer in jigdo-style "base64" */ +static char *base64_dump(unsigned char *buf, size_t buf_size) +{ + const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + int value = 0; + unsigned int i; + int bits = 0; + static char output_buffer[2048]; + char *p = output_buffer; + + memset(output_buffer, 0, sizeof(output_buffer)); + if (buf_size >= (sizeof(output_buffer) * 6/8)) + { + fprintf(stderr, "base64_dump: Buffer too small!\n"); + exit(1); + } + + for (i = 0; i < buf_size ; i++) + { + value = (value << 8) | buf[i]; + bits += 2; + p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]); + if (bits >= 6) { + bits -= 6; + p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]); + } + } + if (bits > 0) + { + value <<= 6 - bits; + p += sprintf(p, "%c", b64_enc[value & 63U]); + } + return output_buffer; +} + +/* Write the .jigdo file to match the .template we've just finished. */ +static void write_jigdo_file(void) +{ + unsigned char template_md5sum[16]; + entry_t *entry = entry_list; + struct path_mapping *map = map_list; + int i = 0; + struct checksum_info *info = NULL; + + checksum_final(template_context); + checksum_copy(template_context, CHECK_MD5, &template_md5sum[0]); + + fprintf(j_file, "# JigsawDownload\n"); + fprintf(j_file, "# See <http://atterer.org/jigdo/> for details about jigdo\n"); + fprintf(j_file, "# See <http://www.einval.com/~steve/software/CD/JTE/> for details about JTE\n\n"); + + fprintf(j_file, "[Jigdo]\n"); + fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION); + fprintf(j_file, "Generator=%s/%d.%d\n\n", JTE_NAME, JTE_VER_MAJOR, JTE_VER_MINOR); + + fprintf(j_file, "[Image]\n"); + fprintf(j_file, "Filename=%s\n", file_base_name(outfile)); + fprintf(j_file, "Template=http://localhost/%s\n", jtemplate_out); + + fprintf(j_file, "Template-MD5Sum=%s \n", + base64_dump(&template_md5sum[0], sizeof(template_md5sum))); + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + if (checksum_algo_tmpl & (1 << i)) + { + info = checksum_information(i); + fprintf(j_file, "# Template Hex %sSum %s\n", info->name, checksum_hex(template_context, i)); + } + } + fprintf(j_file, "# Template size %lld bytes\n", template_size); + + for (i = 0; i < NUM_CHECKSUMS; i++) + { + if (checksum_algo_iso & (1 << i)) + { + info = checksum_information(i); + fprintf(j_file, "# Image Hex %sSum %s\n", info->name, checksum_hex(iso_context, i)); + } + } + + fprintf(j_file, "# Image size %lld bytes\n\n", image_size); + + fprintf(j_file, "[Parts]\n"); + while (entry) + { + if (JTET_FILE_MATCH == entry->entry_type) + { + char *new_name = remap_filename(entry->data.file.filename); + fprintf(j_file, "%s=%s\n", + base64_dump(&entry->data.file.md5[0], sizeof(entry->data.file.md5)), + new_name); + free(new_name); + } + entry = entry->next; + } + + fprintf(j_file, "\n[Servers]\n"); + fflush(j_file); +} + +/* Finish and flush state; for now: + + 1. Dump the DESC blocks and the footer information in the jigdo template file + 2. Write the jigdo .jigdo file containing file pointers +*/ +void write_jt_footer(void) +{ + /* Finish calculating the image's checksum */ + checksum_final(iso_context); + + /* And calculate the image size */ + image_size = (unsigned long long)SECTOR_SIZE * last_extent_written; + + write_template_desc_entries(image_size); + + write_jigdo_file(); +} + +/* Add a raw data entry to the list of extents; no file to match */ +static void add_unmatched_entry(int uncompressed_length) +{ + entry_t *new_entry = NULL; + + /* Can we extend a previous non-match entry? */ + if (entry_last && (JTET_NOMATCH == entry_last->entry_type)) + { + entry_last->data.chunk.uncompressed_length += uncompressed_length; + return; + } + + new_entry = calloc(1, sizeof(entry_t)); + new_entry->entry_type = JTET_NOMATCH; + new_entry->next = NULL; + new_entry->data.chunk.uncompressed_length = uncompressed_length; + + /* Add to the end of the list */ + if (NULL == entry_last) + { + entry_last = new_entry; + entry_list = new_entry; + } + else + { + entry_last->next = new_entry; + entry_last = new_entry; + } + num_chunks++; +} + +/* Add a file match entry to the list of extents */ +static void add_file_entry(char *filename, off_t size, unsigned char *md5, + unsigned long long rsyncsum) +{ + entry_t *new_entry = NULL; + + new_entry = calloc(1, sizeof(entry_t)); + new_entry->entry_type = JTET_FILE_MATCH; + new_entry->next = NULL; + memcpy(new_entry->data.file.md5, md5, sizeof(new_entry->data.file.md5)); + new_entry->data.file.file_length = size; + new_entry->data.file.rsyncsum = rsyncsum; + new_entry->data.file.filename = strdup(filename); + + /* Add to the end of the list */ + if (NULL == entry_last) + { + entry_last = new_entry; + entry_list = new_entry; + } + else + { + entry_last->next = new_entry; + entry_last = new_entry; + } + num_matches++; +} + +/* Cope with an unmatched block in the .iso file: + + 1. Write a compressed data chunk in the jigdo template file + 2. Add an entry in our list of unmatched chunks for later */ +void jtwrite(buffer, size, count, submode, islast) + void *buffer; + int size; + int count; + int submode; + BOOL islast; +{ +#ifdef JTWRITE_DEBUG + if (count != 1 || (size % 2048) != 0) + error("Count: %d, size: %d\n", count, size); +#endif + + if (!jtemplate_out) + return; + + /* Update the global image checksum */ + checksum_update(iso_context, buffer, size * count); +// mk_MD5Update(&iso_context, buffer, size*count); + + /* Write a compressed version of the data to the template file, + and add a reference on the state list so we can write that + later. */ + write_compressed_chunk(buffer, size*count); + add_unmatched_entry(size*count); +} + +/* Cope with a file entry in the .iso file: + + 1. Read the file for the image's md5 checksum + 2. Add an entry in our list of files to be written into the .jigdo later +*/ +void write_jt_match_record(char *filename, char *mirror_name, int sector_size, off_t size, unsigned char md5[16]) +{ + unsigned long long tmp_size = 0; + char buf[32768]; + off_t remain = size; + FILE *infile = NULL; + int use = 0; + unsigned long long rsync64_sum = 0; + int first_block = 1; + + memset(buf, 0, sizeof(buf)); + + if ((infile = fopen(filename, "rb")) == NULL) { +#ifdef USE_LIBSCHILY + comerr("cannot open '%s'\n", filename); +#else +#ifndef HAVE_STRERROR + fprintf(stderr, "cannot open '%s': (%d)\n", + filename, errno); +#else + fprintf(stderr, "cannot open '%s': %s\n", + filename, strerror(errno)); +#endif + exit(1); +#endif + } + + while (remain > 0) + { + use = remain; + if (remain > sizeof(buf)) + use = sizeof(buf); + if (fread(buf, 1, use, infile) == 0) + { +#ifdef USE_LIBSCHILY + comerr("cannot read from '%s'\n", filename); +#else + fprintf(stderr, "cannot read from '%s'\n", filename); + exit(1); +#endif + } + if (first_block) + rsync64_sum = rsync64(buf, MIN_JIGDO_FILE_SIZE); + checksum_update(iso_context, buf, use); +// mk_MD5Update(&iso_context, buf, use); + remain -= use; + first_block = 0; + } + + fclose(infile); + + /* Update the image checksum with any necessary padding data */ + if (size % sector_size) + { + int pad_size = sector_size - (size % sector_size); + memset(buf, 0, pad_size); + checksum_update(iso_context, buf, pad_size); +// mk_MD5Update(&iso_context, buf, pad_size); + } + + add_file_entry(mirror_name, size, &md5[0], rsync64_sum); + if (size % sector_size) + { + int pad_size = sector_size - (size % sector_size); + write_compressed_chunk(buf, pad_size); + add_unmatched_entry(pad_size); + } +} diff --git a/genisoimage/jte.h b/genisoimage/jte.h new file mode 100644 index 0000000..4469452 --- /dev/null +++ b/genisoimage/jte.h @@ -0,0 +1,39 @@ +/* + * jte.c + * + * Copyright (c) 2004-2006 Steve McIntyre <steve@einval.com> + * + * Prototypes and declarations for JTE + * + * GNU GPL v2 + */ + +extern char *jtemplate_out; +extern char *jjigdo_out; +extern char *jmd5_list; +extern FILE *jthelper; +extern FILE *jtjigdo; +extern FILE *jttemplate; +extern int jte_min_size; +extern int checksum_algo_iso; +extern int checksum_algo_tmpl; + +extern void write_jt_header(FILE *template_file, FILE *jigdo_file); +extern void write_jt_footer(void); +extern void jtwrite(void *buffer, int size, int count, int submode, BOOL islast); +extern void write_jt_match_record(char *filename, char *mirror_name, int sector_size, off_t size, unsigned char md5[16]); +extern int list_file_in_jigdo(char *filename, off_t size, char **realname, unsigned char md5[16]); +extern int jte_add_exclude(char *pattern); +extern int jte_add_include(char *pattern); +extern int jte_add_mapping(char *arg); + +typedef enum _jtc_e +{ + JTE_TEMP_GZIP = 0, + JTE_TEMP_BZIP2 +} jtc_t; + +extern jtc_t jte_template_compression; + + +#define MIN_JIGDO_FILE_SIZE 1024 diff --git a/genisoimage/mac_label.c b/genisoimage/mac_label.c new file mode 100644 index 0000000..f43aafc --- /dev/null +++ b/genisoimage/mac_label.c @@ -0,0 +1,425 @@ +/* + * 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. + * + */ + +/* @(#)mac_label.c 1.9 04/03/05 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 James Pearson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * mac_label.c: generate Mactintosh partition maps and label + * + * Taken from "mkisofs 1.05 PLUS" by Andy Polyakov <appro@fy.chalmers.se> + * (see http://fy.chalmers.se/~appro/mkisofs_plus.html for details) + * + * The format of the HFS driver file: + * + * HFS CD Label Block 512 bytes + * Driver Partition Map (for 2048 byte blocks) 512 bytes + * Driver Partition Map (for 512 byte blocks) 512 bytes + * Empty 512 bytes + * Driver Partition N x 2048 bytes + * HFS Partition Boot Block 1024 bytes + * + * File of the above format can be extracted from a CD using + * apple_driver.c + * + * James Pearson 16/5/98 + */ + +/* PREP_BOOT Troy Benjegerdes 2/4/99 */ + +#include <mconfig.h> +#include "genisoimage.h" +#include "mac_label.h" +#include "apple.h" + +#ifdef PREP_BOOT +void gen_prepboot_label(unsigned char *ml); + +#endif /* PREP_BOOT */ +int gen_mac_label(defer * mac_boot); +int autostart(void); + +#ifdef PREP_BOOT +void +gen_prepboot_label(unsigned char *ml) +{ + struct directory_entry *de; + int i = 0; + int block; + int size; + MacLabel *mac_label = (MacLabel *) ml; + + if (verbose > 1) { + fprintf(stderr, "Creating %d PReP boot partition(s)\n", + use_prep_boot + use_chrp_boot); + } + mac_label->fdiskMagic[0] = fdiskMagic0; + mac_label->fdiskMagic[1] = fdiskMagic1; + + if (use_chrp_boot) { + fprintf(stderr, "CHRP boot partition 1\n"); + + mac_label->image[i].boot = 0x80; + + mac_label->image[i].CHSstart[0] = 0xff; + mac_label->image[i].CHSstart[1] = 0xff; + mac_label->image[i].CHSstart[2] = 0xff; + + mac_label->image[i].type = chrpPartType; /* 0x96 */ + + mac_label->image[i].CHSend[0] = 0xff; + mac_label->image[i].CHSend[1] = 0xff; + mac_label->image[i].CHSend[2] = 0xff; + + mac_label->image[i].startSect[0] = 0; + mac_label->image[i].startSect[1] = 0; + mac_label->image[i].startSect[2] = 0; + mac_label->image[i].startSect[3] = 0; + + size = (last_extent - session_start) * 2048 / 512; + mac_label->image[i].size[0] = size & 0xff; + mac_label->image[i].size[1] = (size >> 8) & 0xff; + mac_label->image[i].size[2] = (size >> 16) & 0xff; + mac_label->image[i].size[3] = (size >> 24) & 0xff; + + i++; + } + + for (; i < use_prep_boot + use_chrp_boot; i++) { + de = search_tree_file(root, prep_boot_image[i - use_chrp_boot]); + if (!de) { + fprintf(stderr, + "Uh oh, I cant find the boot image \"%s\"!\n", + prep_boot_image[i - use_chrp_boot]); + exit(1); + } + /* get size and block in 512-byte blocks */ + block = get_733(de->isorec.extent) * 2048 / 512; + size = get_733(de->isorec.size) / 512 + 1; + fprintf(stderr, "PReP boot partition %d is \"%s\"\n", + i + 1, prep_boot_image[i - use_chrp_boot]); + + mac_label->image[i].boot = 0x80; + + mac_label->image[i].CHSstart[0] = 0xff; + mac_label->image[i].CHSstart[1] = 0xff; + mac_label->image[i].CHSstart[2] = 0xff; + + mac_label->image[i].type = prepPartType; /* 0x41 */ + + mac_label->image[i].CHSend[0] = 0xff; + mac_label->image[i].CHSend[1] = 0xff; + mac_label->image[i].CHSend[2] = 0xff; + + /* deal with endianess */ + mac_label->image[i].startSect[0] = block & 0xff; + mac_label->image[i].startSect[1] = (block >> 8) & 0xff; + mac_label->image[i].startSect[2] = (block >> 16) & 0xff; + mac_label->image[i].startSect[3] = (block >> 24) & 0xff; + + mac_label->image[i].size[0] = size & 0xff; + mac_label->image[i].size[1] = (size >> 8) & 0xff; + mac_label->image[i].size[2] = (size >> 16) & 0xff; + mac_label->image[i].size[3] = (size >> 24) & 0xff; + } + for (; i < 4; i++) { + mac_label->image[i].CHSstart[0] = 0xff; + mac_label->image[i].CHSstart[1] = 0xff; + mac_label->image[i].CHSstart[2] = 0xff; + + mac_label->image[i].CHSend[0] = 0xff; + mac_label->image[i].CHSend[1] = 0xff; + mac_label->image[i].CHSend[2] = 0xff; + } +} + +#endif /* PREP_BOOT */ + +int +gen_mac_label(defer *mac_boot) +{ + FILE *fp; + MacLabel *mac_label; + MacPart *mac_part; + char *buffer = (char *) hce->hfs_map; + int block_size; + int have_hfs_boot = 0; + char tmp[SECTOR_SIZE]; + struct stat stat_buf; + mac_partition_table mpm[2]; + int mpc = 0; + int i; + + /* If we have a boot file, then open and check it */ + if (mac_boot->name) { + if (stat(mac_boot->name, &stat_buf) < 0) { + sprintf(hce->error, "unable to stat HFS boot file %s", + mac_boot->name); + return (-1); + } + if ((fp = fopen(mac_boot->name, "rb")) == NULL) { + sprintf(hce->error, "unable to open HFS boot file %s", + mac_boot->name); + return (-1); + } + if (fread(tmp, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) { + sprintf(hce->error, "unable to read HFS boot file %s", + mac_boot->name); + return (-1); + } + /* check we have a bootable partition */ + mac_part = (MacPart *) (tmp + HFS_BLOCKSZ); + + if (!(IS_MAC_PART(mac_part) && + strncmp((char *) mac_part->pmPartType, pmPartType_2, 12) == 0)) { + sprintf(hce->error, "%s is not a HFS boot file", + mac_boot->name); + return (-1); + } + /* check we have a boot block as well - last 2 blocks of file */ + + if (fseek(fp, (off_t)-2 * HFS_BLOCKSZ, SEEK_END) != 0) { + sprintf(hce->error, "unable to seek HFS boot file %s", + mac_boot->name); + return (-1); + } + /* overwrite (empty) boot block for our HFS volume */ + if (fread(hce->hfs_hdr, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) { + sprintf(hce->error, "unable to read HFS boot block %s", + mac_boot->name); + return (-1); + } + fclose(fp); + + /* check boot block is valid */ + if (d_getw((unsigned char *) hce->hfs_hdr) != HFS_BB_SIGWORD) { + sprintf(hce->error, + "%s does not contain a valid boot block", + mac_boot->name); + return (-1); + } + /* + * collect info about boot file for later user + * - skip over the bootfile header + */ + mac_boot->size = stat_buf.st_size - SECTOR_SIZE - 2*HFS_BLOCKSZ; + mac_boot->off = SECTOR_SIZE; + mac_boot->pad = 0; + + /* + * get size in SECTOR_SIZE blocks + * - shouldn't need to round up + */ + mpm[mpc].size = ISO_BLOCKS(mac_boot->size); + + mpm[mpc].ntype = PM2; + mpm[mpc].type = (char *) mac_part->pmPartType; + mpm[mpc].start = mac_boot->extent = last_extent; + mpm[mpc].name = 0; + + /* flag that we have a boot file */ + have_hfs_boot++; + + /* add boot file size to the total size */ + last_extent += mpm[mpc].size; + hfs_extra += mpm[mpc].size; + + mpc++; + } + /* set info about our hybrid volume */ + mpm[mpc].ntype = PM4; + mpm[mpc].type = pmPartType_4; + mpm[mpc].start = hce->hfs_map_size / HFS_BLK_CONV; + mpm[mpc].size = last_extent - mpm[mpc].start - + ISO_BLOCKS(mac_boot->size); + mpm[mpc].name = volume_id; + + mpc++; + + if (verbose > 1) + fprintf(stderr, "Creating HFS Label %s %s\n", mac_boot->name ? + "with boot file" : "", + mac_boot->name ? mac_boot->name : ""); + + /* for a bootable CD, block size is SECTOR_SIZE */ + block_size = have_hfs_boot ? SECTOR_SIZE : HFS_BLOCKSZ; + + /* create the CD label */ + mac_label = (MacLabel *) buffer; + mac_label->sbSig[0] = 'E'; + mac_label->sbSig[1] = 'R'; + set_722((char *) mac_label->sbBlkSize, block_size); + set_732((char *) mac_label->sbBlkCount, + last_extent * (SECTOR_SIZE / block_size)); + set_722((char *) mac_label->sbDevType, 1); + set_722((char *) mac_label->sbDevId, 1); + + /* create the partition map entry */ + mac_part = (MacPart *) (buffer + block_size); + mac_part->pmSig[0] = 'P'; + mac_part->pmSig[1] = 'M'; + set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); + set_732((char *) mac_part->pmPyPartStart, 1); + set_732((char *) mac_part->pmPartBlkCnt, mpc + 1); + strncpy((char *) mac_part->pmPartName, "Apple", + sizeof (mac_part->pmPartName)); + strncpy((char *) mac_part->pmPartType, "Apple_partition_map", + sizeof (mac_part->pmPartType)); + set_732((char *) mac_part->pmLgDataStart, 0); + set_732((char *) mac_part->pmDataCnt, mpc + 1); + set_732((char *) mac_part->pmPartStatus, PM_STAT_DEFAULT); + + /* create partition map entries for our partitions */ + for (i = 0; i < mpc; i++) { + mac_part = (MacPart *) (buffer + (i + 2) * block_size); + if (mpm[i].ntype == PM2) { + /* get driver label and patch it */ + memcpy((char *) mac_label, tmp, HFS_BLOCKSZ); + set_732((char *) mac_label->sbBlkCount, + last_extent * (SECTOR_SIZE / block_size)); + set_732((char *) mac_label->ddBlock, + (mpm[i].start) * (SECTOR_SIZE / block_size)); + memcpy((char *) mac_part, tmp + HFS_BLOCKSZ, + HFS_BLOCKSZ); + set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); + set_732((char *) mac_part->pmPyPartStart, + (mpm[i].start) * (SECTOR_SIZE / block_size)); + } else { + mac_part->pmSig[0] = 'P'; + mac_part->pmSig[1] = 'M'; + set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); + set_732((char *) mac_part->pmPyPartStart, + mpm[i].start * (SECTOR_SIZE / HFS_BLOCKSZ)); + set_732((char *) mac_part->pmPartBlkCnt, + mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); + strncpy((char *) mac_part->pmPartName, mpm[i].name, + sizeof (mac_part->pmPartName)); + strncpy((char *) mac_part->pmPartType, mpm[i].type, + sizeof (mac_part->pmPartType)); + set_732((char *) mac_part->pmLgDataStart, 0); + set_732((char *) mac_part->pmDataCnt, + mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); + set_732((char *) mac_part->pmPartStatus, + PM_STAT_DEFAULT); + } + } + + if (have_hfs_boot) { /* generate 512 partition table as well */ + mac_part = (MacPart *) (buffer + HFS_BLOCKSZ); + if (mpc < 3) { /* don't have to interleave with 2048 table */ + mac_part->pmSig[0] = 'P'; + mac_part->pmSig[1] = 'M'; + set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); + set_732((char *) mac_part->pmPyPartStart, 1); + set_732((char *) mac_part->pmPartBlkCnt, mpc + 1); + strncpy((char *) mac_part->pmPartName, "Apple", + sizeof (mac_part->pmPartName)); + strncpy((char *) mac_part->pmPartType, + "Apple_partition_map", + sizeof (mac_part->pmPartType)); + set_732((char *) mac_part->pmLgDataStart, 0); + set_732((char *) mac_part->pmDataCnt, mpc + 1); + set_732((char *) mac_part->pmPartStatus, + PM_STAT_DEFAULT); + mac_part++; /* +HFS_BLOCKSZ */ + } + for (i = 0; i < mpc; i++, mac_part++) { + if (mac_part == (MacPart *) (buffer + SECTOR_SIZE)) + mac_part++; /* jump over 2048 partition */ + /* entry */ + if (mpm[i].ntype == PM2) { + memcpy((char *) mac_part, tmp + HFS_BLOCKSZ * 2, + HFS_BLOCKSZ); + if (!IS_MAC_PART(mac_part)) { + mac_part--; + continue; + } + set_732((char *) mac_part->pmMapBlkCnt, mpc+1); + set_732((char *) mac_part->pmPyPartStart, + mpm[i].start * (SECTOR_SIZE / HFS_BLOCKSZ)); + } else { + mac_part->pmSig[0] = 'P'; + mac_part->pmSig[1] = 'M'; + set_732((char *) mac_part->pmMapBlkCnt, mpc+1); + set_732((char *) mac_part->pmPyPartStart, + mpm[i].start * (SECTOR_SIZE / HFS_BLOCKSZ)); + set_732((char *) mac_part->pmPartBlkCnt, + mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); + strncpy((char *) mac_part->pmPartName, + mpm[i].name, sizeof (mac_part->pmPartName)); + strncpy((char *) mac_part->pmPartType, + mpm[i].type, sizeof (mac_part->pmPartType)); + set_732((char *) mac_part->pmLgDataStart, 0); + set_732((char *) mac_part->pmDataCnt, + mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); + set_732((char *) mac_part->pmPartStatus, + PM_STAT_DEFAULT); + } + } + } + return (0); +} + +/* + * autostart: make the HFS CD use the QuickTime 2.0 Autostart feature. + * + * based on information from Eric Eisenhart <eric@sonic.net> and + * http://developer.apple.com/qa/qtpc/qtpc12.html and + * http://developer.apple.com/dev/techsupport/develop/issue26/macqa.html + * + * The name of the AutoStart file is stored in the area allocated for + * the Clipboard name. This area begins 106 bytes into the sector of + * block 0, with the first four bytes at that offset containing the + * hex value 0x006A7068. This value indicates that an AutoStart + * filename follows. After this 4-byte tag, 12 bytes remain, starting + * at offset 110. In these 12 bytes, the name of the AutoStart file is + * stored as a Pascal string, giving you up to 11 characters to identify + * the file. The file must reside in the root directory of the HFS + * volume or partition. + */ + +int +autostart() +{ + int len; + int i; + + if ((len = strlen(autoname)) > 11) + return (-1); + + hce->hfs_hdr[106] = 0x00; + hce->hfs_hdr[107] = 0x6A; + hce->hfs_hdr[108] = 0x70; + hce->hfs_hdr[109] = 0x68; + hce->hfs_hdr[110] = len; + + for (i = 0; i < len; i++) + hce->hfs_hdr[111 + i] = autoname[i]; + + return (0); +} diff --git a/genisoimage/mac_label.h b/genisoimage/mac_label.h new file mode 100644 index 0000000..ada860f --- /dev/null +++ b/genisoimage/mac_label.h @@ -0,0 +1,169 @@ +/* + * 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. + * + */ + +/* @(#)mac_label.h 1.3 04/03/01 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 James Pearson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * mac_label.h: defines Macintosh partition maps and label + * + * Taken from "genisoimage 1.05 PLUS" by Andy Polyakov <appro@fy.chalmers.se> + * (see http://fy.chalmers.se/~appro/genisoimage_plus.html for details) + * + * Much of this is already defined in the libhfs code, but to keep + * things simple we stick with these. + */ + +#ifndef _MAC_LABEL_H +#define _MAC_LABEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PREP_BOOT +struct fdiskPartition { +#define prepPartType 0x41 +#define chrpPartType 0x96 + unsigned char boot; /* bootable flag; not used */ + unsigned char CHSstart[3]; /* start CHS; not used */ + unsigned char type; /* Partition type, = 0x41 (PReP bootable) */ + unsigned char CHSend[3]; /* end CHS; not used */ + unsigned char startSect[4]; /* start sector (really start of boot image on CD */ + unsigned char size[4]; /* size of partition (or boot image ;) ) */ +}; +typedef struct fdiskPartition fdiskPartition; +#endif + +/* Driver Descriptor Map */ +#define sbSigMagic "ER" +struct MacLabel { + unsigned char sbSig[2]; /* unique value for SCSI block 0 */ + unsigned char sbBlkSize[2]; /* block size of device */ + unsigned char sbBlkCount[4]; /* number of blocks on device */ + unsigned char sbDevType[2]; /* device type */ + unsigned char sbDevId[2]; /* device id */ + unsigned char sbData[4]; /* not used */ + unsigned char sbDrvrCount[2]; /* driver descriptor count */ + unsigned char ddBlock[4]; /* 1st driver's starting block */ + unsigned char ddSize[2]; /* size of 1st driver (512-byte blks) */ + unsigned char ddType[2]; /* system type (1 for Mac+) */ +#ifndef PREP_BOOT + unsigned char ddPad[486]; /* ARRAY[0..242] OF INTEGER; not used */ +#else +#define fdiskMagic0 0x55 +#define fdiskMagic1 0xAA + unsigned char pad1[420]; /* not used */ + fdiskPartition image[4]; /* heh heh heh, we can have up to 4 */ + /* different boot images */ + unsigned char fdiskMagic[2]; /* PReP uses fdisk partition map */ +#endif /* PREP_BOOT */ +}; +typedef struct MacLabel MacLabel; + +#define IS_MAC_LABEL(d) (((MacLabel*)(d))->sbSig[0] == 'E' && \ + ((MacLabel*)(d))->sbSig[1] == 'R') + +/* Partition Map Entry */ +#define pmSigMagic "PM" + +#define pmPartType_1 "Apple_partition_map" +#define pmPartName_11 "Apple" + +#define pmPartType_2 "Apple_Driver" +#define pmPartType_21 "Apple_Driver43" + +#define pmPartType_3 "Apple_UNIX_SVR2" +#define pmPartName_31 "A/UX Root" +#define pmPartName_32 "A/UX Usr" +#define pmPartName_33 "Random A/UX fs" +#define pmPartName_34 "Swap" + +#define pmPartType_4 "Apple_HFS" +#define pmPartName_41 "MacOS" + +#define pmPartType_5 "Apple_Free" +#define pmPartName_51 "Extra" + +#define PM2 2 +#define PM4 4 + +struct MacPart { + unsigned char pmSig[2]; /* unique value for map entry blk */ + unsigned char pmSigPad[2]; /* currently unused */ + unsigned char pmMapBlkCnt[4]; /* # of blks in partition map */ + unsigned char pmPyPartStart[4]; /* physical start blk of partition */ + unsigned char pmPartBlkCnt[4]; /* # of blks in this partition */ + unsigned char pmPartName[32]; /* ASCII partition name */ + unsigned char pmPartType[32]; /* ASCII partition type */ + unsigned char pmLgDataStart[4]; /* log. # of partition's 1st data blk */ + unsigned char pmDataCnt[4]; /* # of blks in partition's data area */ + unsigned char pmPartStatus[4]; /* bit field for partition status */ + unsigned char pmLgBootStart[4]; /* log. blk of partition's boot code */ + unsigned char pmBootSize[4]; /* number of bytes in boot code */ + unsigned char pmBootAddr[4]; /* memory load address of boot code */ + unsigned char pmBootAddr2[4]; /* currently unused */ + unsigned char pmBootEntry[4]; /* entry point of boot code */ + unsigned char pmBootEntry2[4]; /* currently unused */ + unsigned char pmBootCksum[4]; /* checksum of boot code */ + unsigned char pmProcessor[16]; /* ASCII for the processor type */ + unsigned char pmPad[376]; /* ARRAY[0..187] OF INTEGER; not used */ +}; +typedef struct MacPart MacPart; + +#define IS_MAC_PART(d) (((MacPart*)(d))->pmSig[0] == 'P' && \ + ((MacPart*)(d))->pmSig[1] == 'M') + +#define PM_STAT_VALID 0x01 /* Set if a valid partition map entry */ +#define PM_STAT_ALLOC 0x02 /* Set if partition is already allocated; clear if available */ +#define PM_STAT_INUSE 0x04 /* Set if partition is in use; may be cleared after a system reset */ +#define PM_STAT_BOOTABLE 0x08 /* Set if partition contains valid boot information */ +#define PM_STAT_READABLE 0x10 /* Set if partition allows reading */ +#define PM_STAT_WRITABLE 0x20 /* Set if partition allows writing */ +#define PM_STAT_BOOT_PIC 0x40 /* Set if boot code is position-independent */ +#define PM_STAT_UNUSED 0x80 /* Unused */ +#define PM_STAT_DEFAULT PM_STAT_VALID|PM_STAT_ALLOC|PM_STAT_READABLE|PM_STAT_WRITABLE + +typedef struct { + char *name; /* Partition name */ + char *type; /* Partition type */ + int ntype; /* Partition type (numeric) */ + int start; /* start extent (SECTOR_SIZE blocks) */ + int size; /* extents (SECTOR_SIZE blocks) */ +} mac_partition_table; + +/* from libhfs */ +#define HFS_BB_SIGWORD 0x4c4b + +typedef struct deferred_write defer; + +#ifdef __cplusplus +} +#endif + +#endif /* _MAC_LABEL_H */ diff --git a/genisoimage/mactypes.h b/genisoimage/mactypes.h new file mode 100644 index 0000000..01e1085 --- /dev/null +++ b/genisoimage/mactypes.h @@ -0,0 +1,65 @@ +/* + * 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. + * + */ + +/* @(#)mactypes.h 1.3 04/03/01 joerg */ + +#ifndef _MACTYPES_H +#define _MACTYPES_H + +/* + * Various types of HFS files stored on Unix systems + */ +#define TYPE_NONE 0 /* Unknown file type (ordinary Unix file) */ +#define TYPE_CAP 1 /* AUFS CAP */ +#define TYPE_NETA 2 /* Netatalk */ +#define TYPE_DBL 3 /* AppleDouble */ +#define TYPE_ESH 4 /* Helios EtherShare */ +#define TYPE_FEU 5 /* PC Exchange (Upper case) */ +#define TYPE_FEL 6 /* PC Exchange (Lower case) */ +#define TYPE_SGI 7 /* SGI */ +#define TYPE_MBIN 8 /* MacBinary */ +#define TYPE_SGL 9 /* AppleSingle */ +#define TYPE_DAVE 10 /* DAVE (AppleDouble type) */ +#define TYPE_SFM 11 /* NTFS Services for Macintosh */ +#define TYPE_XDBL 12 /* MacOS X AppleDouble */ +#define TYPE_XHFS 13 /* MacOS X HFS */ + +/* + * above encoded in a bit map + */ +#define DO_NONE (1 << TYPE_NONE) +#define DO_CAP (1 << TYPE_CAP) +#define DO_NETA (1 << TYPE_NETA) +#define DO_DBL (1 << TYPE_DBL) +#define DO_ESH (1 << TYPE_ESH) +#define DO_FEU (1 << TYPE_FEU) +#define DO_FEL (1 << TYPE_FEL) +#define DO_SGI (1 << TYPE_SGI) +#define DO_MBIN (1 << TYPE_MBIN) +#define DO_SGL (1 << TYPE_SGL) +#define DO_DAVE (1 << TYPE_DAVE) +#define DO_SFM (1 << TYPE_SFM) +#define DO_XDBL (1 << TYPE_XDBL) +#define DO_XHFS (1 << TYPE_XHFS) + +/* + * flags describing how the data/rsrc/info files are stored + * in the whole file name + */ +#define INSERT 0x0 /* rsrc/info is inserted in name (default) */ +#define PROBE 0x1 /* need to probe file for type */ +#define NOPEND 0x2 /* info data in one file for all files */ +#define APPEND 0x4 /* rsrc/info appended to file name */ +#define NORSRC 0x8 /* rsrc for file may not exist */ +#define NOINFO 0x10 /* info file dosen't exist */ + +#endif /* _MACTYPES_H */ diff --git a/genisoimage/magic b/genisoimage/magic new file mode 100644 index 0000000..387727c --- /dev/null +++ b/genisoimage/magic @@ -0,0 +1,81 @@ +# +# Example magic file for mkhybrid +# +# The "message" for the offset MUST be 4 characters for the CREATOR +# and 4 characters for the TYPE - white space is optional between them. +# Any other characters on this line are ignored. Continuation lines (starting +# with '>') are also ignored i.e. only the initial offset lines are used. +# +# The continuation lines are given here, but they do not need to exist. + +# +# James Pearson 20/5/98 + +# off type test message + +# GIF +0 string GIF8 8BIM GIFf +>4 string 7a \b, version 8%s, +>4 string 9a \b, version 8%s, +>6 leshort >0 %hd x +>8 leshort >0 %hd, +#>10 byte &0x80 color mapped, +#>10 byte&0x07 =0x00 2 colors +#>10 byte&0x07 =0x01 4 colors +#>10 byte&0x07 =0x02 8 colors +#>10 byte&0x07 =0x03 16 colors +#>10 byte&0x07 =0x04 32 colors +#>10 byte&0x07 =0x05 64 colors +#>10 byte&0x07 =0x06 128 colors +#>10 byte&0x07 =0x07 256 colors + +# JPEG images +# +0 ubeshort 0xffd8 8BIM JPEG image data + +# StuffIt +# +0 string SIT! SIT!SIT! + +# standard unix compress +0 string \037\235 LZIV ZIVU +>2 byte&0x80 >0 block compressed +>2 byte&0x1f x %d bits + +# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver) +0 string \037\213 GNUz ZIVU gzip compressed data +>2 byte <8 \b, reserved method, +>2 byte 8 \b, deflated, +>3 byte &0x01 ASCII, +>3 byte &0x02 continuation, +>3 byte &0x04 extra field, +>3 byte &0x08 original filename, +>3 byte &0x10 comment, +>3 byte &0x20 encrypted, +>4 ledate x last modified: %s, +>8 byte 2 max compression, +>8 byte 4 max speed, +>9 byte =0x00 os: MS-DOS +>9 byte =0x01 os: Amiga +>9 byte =0x02 os: VMS +>9 byte =0x03 os: Unix +>9 byte =0x05 os: Atari +>9 byte =0x06 os: OS/2 +>9 byte =0x07 os: MacOS +>9 byte =0x0A os: Tops/20 +>9 byte =0x0B os: Win/32 + +# Postscript +0 string %! ASPSTEXT +>2 string PS-Adobe- conforming +>>11 string >\0 at level %.3s +>>>15 string EPS - type %s +>>>15 string Query - type %s +>>>15 string ExitServer - type %s +# Some PCs have the annoying habit of adding a ^D as a document separator +0 string \004%! ASPS TEXT PostScript document text +>3 string PS-Adobe- conforming +>>12 string >\0 at level %.3s +>>>16 string EPS - type %s +>>>16 string Query - type %s +>>>16 string ExitServer - type %s diff --git a/genisoimage/mapping b/genisoimage/mapping new file mode 100644 index 0000000..c108a44 --- /dev/null +++ b/genisoimage/mapping @@ -0,0 +1,8 @@ +# Example filename mapping file +# +# EXTN XLate CREATOR TYPE Comment +.tif Raw '8BIM' 'TIFF' "Photoshop TIFF image" +.hqx Ascii 'BnHq' 'TEXT' "BinHex file" +.doc Raw 'MSWD' 'WDBN' "Word file" +.mov Raw 'TVOD' 'MooV' "QuickTime Movie" +* Ascii 'ttxt' 'TEXT' "Text file" diff --git a/genisoimage/match.c b/genisoimage/match.c new file mode 100644 index 0000000..6762e89 --- /dev/null +++ b/genisoimage/match.c @@ -0,0 +1,290 @@ +/* + * 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. + * + */ + +/* @(#)match.c 1.18 04/05/23 joerg */ +/* + * 27-Mar-96: Jan-Piet Mens <jpm@mens.de> + * added 'match' option (-m) to specify regular expressions NOT to be included + * in the CD image. + * + * Re-written 13-Apr-2000 James Pearson + * now uses a generic set of routines + */ + +#include <mconfig.h> +#include <stdio.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <standard.h> +#include <schily.h> +#include <libport.h> +#include "match.h" + +struct match { + struct match *next; + char *name; +}; + +typedef struct match match; + +static match *mats[MAX_MAT]; + +static char *mesg[MAX_MAT] = { + "excluded", + "excluded ISO-9660", + "excluded Joliet", + "hidden attribute ISO-9660", +#ifdef APPLE_HYB + "excluded HFS", +#endif /* APPLE_HYB */ +}; + +#ifdef SORTING +struct sort_match { + struct sort_match *next; + char *name; + int val; +}; + +typedef struct sort_match sort_match; + +static sort_match *s_mats; + +int +add_sort_match(char *fn, int val) +{ + sort_match *s_mat; + + s_mat = (sort_match *)malloc(sizeof (sort_match)); + if (s_mat == NULL) { +#ifdef USE_LIBSCHILY + errmsg("Can't allocate memory for sort filename\n"); +#else + fprintf(stderr, "Can't allocate memory for sort filename\n"); +#endif + return (0); + } + + if ((s_mat->name = strdup(fn)) == NULL) { +#ifdef USE_LIBSCHILY + errmsg("Can't allocate memory for sort filename\n"); +#else + fprintf(stderr, "Can't allocate memory for sort filename\n"); +#endif + return (0); + } + + /* need to reserve the minimum value for other uses */ + if (val == NOT_SORTED) + val++; + + s_mat->val = val; + s_mat->next = s_mats; + s_mats = s_mat; + + return (1); +} + +void +add_sort_list(char *file) +{ + FILE *fp; + char name[4096]; + char *p; + int val; + + if ((fp = fopen(file, "r")) == NULL) { +#ifdef USE_LIBSCHILY + comerr("Can't open sort file list %s\n", file); +#else + fprintf(stderr, "Can't open hidden/exclude file list %s\n", file); + exit(1); +#endif + } + + while (fgets(name, sizeof (name), fp) != NULL) { + /* + * look for the last space or tab character + */ + if ((p = strrchr(name, ' ')) == NULL) + p = strrchr(name, '\t'); + else if (strrchr(p, '\t') != NULL) /* Tab after space? */ + p = strrchr(p, '\t'); + + if (p == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Incorrect sort file format\n\t%s", name); +#else + fprintf(stderr, "Incorrect sort file format\n\t%s", name); +#endif + continue; + } else { + *p = '\0'; + val = atoi(++p); + } + if (!add_sort_match(name, val)) { + fclose(fp); + return; + } + } + + fclose(fp); +} + +int +sort_matches(char *fn, int val) +{ + register sort_match *s_mat; + + for (s_mat = s_mats; s_mat; s_mat = s_mat->next) { + if (fnmatch(s_mat->name, fn, FNM_FILE_NAME) != FNM_NOMATCH) { + return (s_mat->val); /* found sort value */ + } + } + return (val); /* not found - default sort value */ +} + +void +del_sort() +{ + register sort_match * s_mat, *s_mat1; + + s_mat = s_mats; + while (s_mat) { + s_mat1 = s_mat->next; + + free(s_mat->name); + free(s_mat); + + s_mat = s_mat1; + } + + s_mats = 0; +} + +#endif /* SORTING */ + + +int +gen_add_match(char *fn, int n) +{ + match *mat; + + if (n >= MAX_MAT) + return (0); + + mat = (match *)malloc(sizeof (match)); + if (mat == NULL) { +#ifdef USE_LIBSCHILY + errmsg("Can't allocate memory for %s filename\n", mesg[n]); +#else + fprintf(stderr, "Can't allocate memory for %s filename\n", mesg[n]); +#endif + return (0); + } + + if ((mat->name = strdup(fn)) == NULL) { +#ifdef USE_LIBSCHILY + errmsg("Can't allocate memory for %s filename\n", mesg[n]); +#else + fprintf(stderr, "Can't allocate memory for %s filename\n", mesg[n]); +#endif + return (0); + } + + mat->next = mats[n]; + mats[n] = mat; + + return (1); +} + +void +gen_add_list(char *file, int n) +{ + FILE *fp; + char name[4096]; + int len; + + if ((fp = fopen(file, "r")) == NULL) { +#ifdef USE_LIBSCHILY + comerr("Can't open %s file list %s\n", mesg[n], file); +#else + fprintf(stderr, "Can't open %s file list %s\n", mesg[n], file); + exit(1); +#endif + } + + while (fgets(name, sizeof (name), fp) != NULL) { + /* + * strip of '\n' + */ + len = strlen(name); + if (name[len - 1] == '\n') { + name[len - 1] = '\0'; + } + if (!gen_add_match(name, n)) { + fclose(fp); + return; + } + } + + fclose(fp); +} + +int +gen_matches(char *fn, int n) +{ + register match * mat; + + if (n >= MAX_MAT) + return (0); + + for (mat = mats[n]; mat; mat = mat->next) { + if (fnmatch(mat->name, fn, FNM_FILE_NAME) != FNM_NOMATCH) { + return (1); /* found -> excluded filename */ + } + } + return (0); /* not found -> not excluded */ +} + +int +gen_ishidden(int n) +{ + if (n >= MAX_MAT) + return (0); + + return ((int)(mats[n] != 0)); +} + +void +gen_del_match(int n) +{ + register match *mat; + register match *mat1; + + if (n >= MAX_MAT) + return; + + mat = mats[n]; + + while (mat) { + mat1 = mat->next; + + free(mat->name); + free(mat); + + mat = mat1; + } + + mats[n] = 0; +} diff --git a/genisoimage/match.h b/genisoimage/match.h new file mode 100644 index 0000000..2894af9 --- /dev/null +++ b/genisoimage/match.h @@ -0,0 +1,91 @@ +/* + * 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. + * + */ + +/* @(#)match.h 1.9 04/05/23 joerg */ +/* + * 27th March 1996. Added by Jan-Piet Mens for matching regular expressions + * in paths. + * + */ + +#include "fnmatch.h" + +#ifdef SORTING +#include <limits.h> +#define NOT_SORTED INT_MIN + +#ifdef MAX /* May be defined in param.h */ +#undef MAX +#endif +#define MAX(A, B) (A) > (B) ? (A) : (B) +#endif + +#define EXCLUDE 0 /* Exclude file completely */ +#define I_HIDE 1 /* ISO9660/Rock Ridge hide */ +#define J_HIDE 2 /* Joliet hide */ +#define H_HIDE 3 /* ISO9660 hidden bit set */ + +#ifdef APPLE_HYB +#define HFS_HIDE 4 /* HFS hide */ +#define MAX_MAT 5 +#else +#define MAX_MAT 4 +#endif /* APPLE_HYB */ + +extern int gen_add_match(char *fn, int n); +extern int gen_matches(char *fn, int n); +extern void gen_add_list(char *fn, int n); +extern int gen_ishidden(int n); +extern void gen_del_match(int n); + +#ifdef SORTING +extern int add_sort_match(char *fn, int val); +extern void add_sort_list(char *fn); +extern int sort_matches(char *fn, int val); +extern void del_sort(void); +#endif /* SORTING */ + +/* + * The following are for compatiblity with the separate routines - the + * main code should be changed to call the generic routines directly + */ + +/* filenames to be excluded */ +#define add_match(FN) gen_add_match((FN), EXCLUDE) +#define add_list(FN) gen_add_list((FN), EXCLUDE) +#define matches(FN) gen_matches((FN), EXCLUDE) + +/* ISO9660/Rock Ridge filenames to be hidden */ +#define i_add_match(FN) gen_add_match((FN), I_HIDE) +#define i_add_list(FN) gen_add_list((FN), I_HIDE) +#define i_matches(FN) gen_matches((FN), I_HIDE) +#define i_ishidden() gen_ishidden(I_HIDE) + +/* Joliet filenames to be hidden */ +#define j_add_match(FN) gen_add_match((FN), J_HIDE) +#define j_add_list(FN) gen_add_list((FN), J_HIDE) +#define j_matches(FN) gen_matches((FN), J_HIDE) +#define j_ishidden() gen_ishidden(J_HIDE) + +/* ISO9660 "hidden" files */ +#define h_add_match(FN) gen_add_match((FN), H_HIDE) +#define h_add_list(FN) gen_add_list((FN), H_HIDE) +#define h_matches(FN) gen_matches((FN), H_HIDE) +#define h_ishidden() gen_ishidden(H_HIDE) + +#ifdef APPLE_HYB +/* HFS filenames to be hidden */ +#define hfs_add_match(FN) gen_add_match((FN), HFS_HIDE) +#define hfs_add_list(FN) gen_add_list((FN), HFS_HIDE) +#define hfs_matches(FN) gen_matches((FN), HFS_HIDE) +#define hfs_ishidden() gen_ishidden(HFS_HIDE) +#endif /* APPLE_HYB */ diff --git a/genisoimage/md5.c b/genisoimage/md5.c new file mode 100644 index 0000000..353ae5a --- /dev/null +++ b/genisoimage/md5.c @@ -0,0 +1,401 @@ +/* + * 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. + * + */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to + not require an integer type which is exactly 32 bits. This work + draws on the changes for the same purpose by Tatu Ylonen + <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use + that code, there is no copyright issue. I hereby disclaim + copyright in any changes I have made; this code remains in the + public domain. */ + +/* Note regarding cvs_* namespace: this avoids potential conflicts + with libraries such as some versions of Kerberos. No particular + need to worry about whether the system supplies an MD5 library, as + this file is only about 3k of object code. */ + +/* Steve McIntyre, 2004/05/31: borrowed this code from the CVS + library. s/cvs_/mk_/ across the source */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> /* for memcpy() and memset() */ +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +#include "md5.h" + +/* Little-endian byte-swapping routines. Note that these do not + depend on the size of datatypes such as mk_uint32, nor do they require + us to detect the endianness of the machine we are running on. It + is possible they should be macros for speed, but I would be + surprised if they were a performance bottleneck for MD5. */ + +static mk_uint32 +getu32 (const unsigned char *addr) +{ + return (((((unsigned long)addr[3] << 8) | addr[2]) << 8) + | addr[1]) << 8 | addr[0]; +} + +static void +putu32 (mk_uint32 data, unsigned char *addr) +{ + addr[0] = (unsigned char)data; + addr[1] = (unsigned char)(data >> 8); + addr[2] = (unsigned char)(data >> 16); + addr[3] = (unsigned char)(data >> 24); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +mk_MD5Init (struct mk_MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +mk_MD5Update (struct mk_MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + mk_uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = (t + ((mk_uint32)len << 3)) & 0xffffffff) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if ( t ) { + unsigned char *p = ctx->in + t; + + t = 64-t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + mk_MD5Transform (ctx->buf, ctx->in); + buf += t; + len -= t; + } + + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + mk_MD5Transform (ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +mk_MD5Final (unsigned char digest[16], struct mk_MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + mk_MD5Transform (ctx->buf, ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count-8); + } + + /* Append length in bits and transform */ + putu32(ctx->bits[0], ctx->in + 56); + putu32(ctx->bits[1], ctx->in + 60); + + mk_MD5Transform (ctx->buf, ctx->in); + putu32(ctx->buf[0], digest); + putu32(ctx->buf[1], digest + 4); + putu32(ctx->buf[2], digest + 8); + putu32(ctx->buf[3], digest + 12); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +mk_MD5Transform (mk_uint32 buf[4], const unsigned char inraw[64]) +{ + register mk_uint32 a, b, c, d; + mk_uint32 in[16]; + int i; + + for (i = 0; i < 16; ++i) + in[i] = getu32 (inraw + 4 * i); + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* Read in a hex-dumped MD5 sum and parse it */ +int mk_MD5Parse(unsigned char in[33], unsigned char out[16]) +{ + int i = 0; + + for (i = 0; i < 16; i++) + { + if (in[2*i] >= '0' && in[2*i] <= '9') + in[2*i] -= '0'; + else if (in[2*i] >= 'A' && in[2*i] <= 'F') + in[2*i] += 10 - 'A'; + else if (in[2*i] >= 'a' && in[2*i] <= 'f') + in[2*i] += 10 - 'a'; + else + return 1; + if (in[1+(2*i)] >= '0' && in[1+(2*i)] <= '9') + in[1+(2*i)] -= '0'; + else if (in[1+(2*i)] >= 'A' && in[1+(2*i)] <= 'F') + in[1+(2*i)] += 10 - 'A'; + else if (in[1+(2*i)] >= 'a' && in[1+(2*i)] <= 'f') + in[1+(2*i)] += 10 - 'a'; + else + return 1; + out[i] = in[2*i] << 4 | in[1+(2*i)]; + } + return 0; +} + +/* Calculate the MD5sum of the specified file */ +int calculate_md5sum(char *filename, unsigned long long size, unsigned char out[16]) +{ + char buffer[32768]; + int i = 0; + FILE *infile = NULL; + unsigned long long remain = 0; + int use; + struct mk_MD5Context file_context; + + /* Start MD5 work for the file */ + mk_MD5Init(&file_context); + + infile = fopen(filename, "rb"); + if (!infile) + { +#ifndef HAVE_STRERROR + fprintf(stderr, "cannot open '%s': (%d)\n", + filename, errno); +#else + fprintf(stderr, "cannot open '%s': %s\n", + filename, strerror(errno)); +#endif + exit(1); + } + + remain = size; + while (remain > 0) + { + use = (remain > sizeof(buffer) ? sizeof(buffer) : remain); + if (fread(buffer, 1, use, infile) == 0) + { + fprintf(stderr, "cannot read from '%s'\n", filename); + exit(1); + } + /* Update the checksum */ + mk_MD5Update(&file_context, (unsigned char *)buffer, use); + remain -= use; + } + fclose(infile); + mk_MD5Final(&out[0], &file_context); + + return 0; +} + + +#ifdef TEST +/* Simple test program. Can use it to manually run the tests from + RFC1321 for example. */ +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + struct mk_MD5Context context; + unsigned char checksum[16]; + int i; + int j; + + if (argc < 2) + { + fprintf (stderr, "usage: %s string-to-hash\n", argv[0]); + exit (1); + } + for (j = 1; j < argc; ++j) + { + printf ("MD5 (\"%s\") = ", argv[j]); + mk_MD5Init (&context); + mk_MD5Update (&context, argv[j], strlen (argv[j])); + mk_MD5Final (checksum, &context); + for (i = 0; i < 16; i++) + { + printf ("%02x", (unsigned int) checksum[i]); + } + printf ("\n"); + } + return 0; +} +#endif /* TEST */ diff --git a/genisoimage/md5.h b/genisoimage/md5.h new file mode 100644 index 0000000..b48c05c --- /dev/null +++ b/genisoimage/md5.h @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +/* See md5.c for explanation and copyright information. */ + +#ifndef MD5_H +#define MD5_H + +/* Unlike previous versions of this code, uint32 need not be exactly + 32 bits, merely 32 bits or more. Choosing a data type which is 32 + bits instead of 64 is not important; speed is considerably more + important. ANSI guarantees that "unsigned long" will be big enough, + and always using it seems to have few disadvantages. */ +typedef unsigned long mk_uint32; + +struct mk_MD5Context { + mk_uint32 buf[4]; + mk_uint32 bits[2]; + unsigned char in[64]; +}; + +void mk_MD5Init (struct mk_MD5Context *context); +void mk_MD5Update (struct mk_MD5Context *context, + unsigned char const *buf, unsigned len); +void mk_MD5Final (unsigned char digest[16], + struct mk_MD5Context *context); +void mk_MD5Transform (mk_uint32 buf[4], const unsigned char in[64]); +int mk_MD5Parse(unsigned char in[33], unsigned char out[16]); +int calculate_md5sum(char *filename, unsigned long long size, unsigned char out[16]); + + +#endif /* !MD5_H */ diff --git a/genisoimage/mkhybrid.8 b/genisoimage/mkhybrid.8 new file mode 100644 index 0000000..075bc0a --- /dev/null +++ b/genisoimage/mkhybrid.8 @@ -0,0 +1,2 @@ +.so man8/genisoimage.8 +.\" %Z%%M% %I% %E% joerg diff --git a/genisoimage/more.mapping b/genisoimage/more.mapping new file mode 100644 index 0000000..a18daa3 --- /dev/null +++ b/genisoimage/more.mapping @@ -0,0 +1,282 @@ +# +# Mapping file converted from Internet Config +# by Bob Nestor <rnestor@metronet.com> +# +# EXTN Xlate Creator Type Application - description (mime type) +# +.1st Ascii 'ttxt' 'TEXT' "SimpleText - Text Readme (application/text)" +.669 Raw 'SNPL' '6669' "PlayerPro - 669 MOD Music" +.8med Raw 'SCPL' 'STrk' "SoundApp - Amiga OctaMed music" +.8svx Raw 'SCPL' '8SVX' "SoundApp - Amiga 8-bit sound" +.a Ascii 'MPS ' 'TEXT' "MPW Shell - Assembly Source" +.aif Raw 'SCPL' 'AIFF' "SoundApp - AIFF Sound (audio/x-aiff)" +.aifc Raw 'SCPL' 'AIFC' "SoundApp - AIFF Sound Compressed (audio/x-aiff)" +.aiff Raw 'SCPL' 'AIFF' "SoundApp - AIFF Sound (audio/x-aiff)" +.al Raw 'SCPL' 'ALAW' "SoundApp - ALAW Sound" +.ani Raw 'GKON' 'ANIi' "GraphicConverter - Animated NeoChrome" +.apd Ascii 'ALD3' 'TEXT' "Aldus PageMaker - Aldus Printer Description" +.arc Raw 'arc*' 'mArc' "ArcMac - PC ARChive" +.arj Raw 'DArj' 'BINA' "DeArj - ARJ Archive" +.arr Raw 'GKON' 'ARR ' "GraphicConverter - Amber ARR image" +.art Raw 'GKON' 'ART ' "GraphicConverter - First Publisher" +.asc Ascii 'ttxt' 'TEXT' "SimpleText - ASCII Text (text/plain)" +.ascii Ascii 'ttxt' 'TEXT' "SimpleText - ASCII Text (text/plain)" +.asm Ascii 'MPS ' 'TEXT' "MPW Shell - Assembly Source" +.au Raw 'SCPL' 'ULAW' "SoundApp - Sun Sound (audio/basic)" +.avi Raw 'AVIC' 'VfW ' "AVI to QT Utility - AVI Movie (video/avi)" +.bar Raw 'S691' 'BARF' "SunTar - Unix BAR Archive" +.bas Ascii 'TBB6' 'TEXT' "TexEdit - BASIC Source" +.bat Ascii 'ttxt' 'TEXT' "SimpleText - MS-DOS Batch File" +.bga Raw 'JVWR' 'BMPp' "JPEGView - OS/2 Bitmap" +.bib Ascii '*TEX' 'TEXT' "Textures - BibTex Bibliography" +.bin Raw 'MB2P' 'BINA' "MacBinary II+ - MacBinary (application/macbinary)" +.binary Raw 'hDmp' 'BINA' "HexEdit - Untyped Binary Data (application/octet-stream)" +.bmp Raw 'JVWR' 'BMPp' "JPEGView - Windows Bitmap" +.boo Ascii 'TBB6' 'TEXT' "TexEdit - BOO encoded" +.bst Ascii '*TEX' 'TEXT' "Textures - BibTex Style" +.bw Raw 'GKON' 'SGI ' "GraphicConverter - SGI Image" +.c Ascii 'CWIE' 'TEXT' "CodeWarrior - C Source" +.cgm Raw 'GKON' 'CGMm' "GraphicConverter - Computer Graphics Meta" +.class Raw 'CWIE' 'Clss' "CodeWarrior - Java Class File" +.clp Raw 'GKON' 'CLPp' "GraphicConverter - Windows Clipboard" +.cmd Ascii 'ttxt' 'TEXT' "SimpleText - OS/2 Batch File" +.com Raw 'SWIN' 'PCFA' "SoftWindows - MS-DOS Executable" +.cp Ascii 'CWIE' 'TEXT' "CodeWarrior - C++ Source" +.cpp Ascii 'CWIE' 'TEXT' "CodeWarrior - C++ Source" +.cpt Raw 'CPCT' 'PACT' "Compact Pro - Compact Pro Archive" +.csv Ascii 'XCEL' 'TEXT' "Excel - Comma Separated Vars" +.ct Raw 'GKON' '..CT' "GraphicConverter - Scitex-CT" +.cut Raw 'GKON' 'Halo' "GraphicConverter - Dr Halo Image" +.cvs Raw 'DAD2' 'drw2' "Canvas - Canvas Drawing" +.dbf Raw 'FOX+' 'COMP' "FoxBase+ - DBase Document" +.dcx Raw 'GKON' 'DCXx' "GraphicConverter - Some PCX Images" +.dif Ascii 'XCEL' 'TEXT' "Excel - Data Interchange Format" +.diz Ascii 'TBB6' 'TEXT' "TexEdit - BBS Descriptive Text" +.dl Raw 'AnVw' 'DL ' "MacAnim Viewer - DL Animation" +.dll Raw 'SWIN' 'PCFL' "SoftWindows - Windows DLL" +.doc Raw 'MSWD' 'WDBN' "Microsoft Word - Word Document (application/msword)" +.dot Raw 'MSWD' 'sDBN' "Microsoft Word - Word for Windows Template" +.dvi Raw 'OTEX' 'ODVI' "OzTeX - TeX DVI Document (application/x-dvi)" +.dxf Ascii 'SWVL' 'TEXT' "Swivel Pro - AutoCAD 3D Data" +.eps Raw 'vgrd' 'EPSF' "LaserWriter 8 - Postscript (application/postscript)" +.epsf Raw 'vgrd' 'EPSF' "LaserWriter 8 - Postscript (application/postscript)" +.etx Ascii 'ezVu' 'TEXT' "Easy View - SEText (text/x-setext)" +.evy Raw 'ENVY' 'EVYD' "Envoy - Envoy Document" +.exe Raw 'SWIN' 'PCFA' "SoftWindows - MS-DOS Executable" +.faq Ascii 'TBB6' 'TEXT' "TexEdit - ASCII Text (text/x-usenet-faq)" +.fit Raw 'GKON' 'FITS' "GraphicConverter - Flexible Image Transport (image/x-fits)" +.flc Raw 'AnVw' 'FLI ' "MacAnim Viewer - FLIC Animation" +.fli Raw 'AnVw' 'FLI ' "MacAnim Viewer - FLI Animation" +.fm Raw 'FMPR' 'FMPR' "FileMaker Pro - FileMaker Pro Database" +.for Ascii 'MPS ' 'TEXT' "MPW Shell - Fortran Source" +.fts Raw 'GKON' 'FITS' "GraphicConverter - Flexible Image Transport" +.gem Raw 'GKON' 'GEM-' "GraphicConverter - GEM Metafile" +.gif Raw 'JVWR' 'GIFf' "JPEGView - GIF Picture (image/gif)" +.gl Raw 'AnVw' 'GL ' "MacAnim Viewer - GL Animation" +.grp Raw 'GKON' 'GRPp' "GraphicConverter - GRP Image" +.gz Raw 'Gzip' 'Gzip' "MacGzip - Gnu ZIP Archive (application/x-gzip)" +.h Ascii 'CWIE' 'TEXT' "CodeWarrior - C Include File" +.hcom Raw 'SCPL' 'FSSD' "SoundApp - SoundEdit Sound ex SOX" +.hp Ascii 'CWIE' 'TEXT' "CodeWarrior - C Include File" +.hpgl Raw 'GKON' 'HPGL' "GraphicConverter - HP GL/2" +.hpp Ascii 'CWIE' 'TEXT' "CodeWarrior - C Include File" +.hqx Ascii 'TBB6' 'TEXT' "TexEdit - BinHex (application/mac-binhex40)" +.htm Ascii 'Um6' 'TEXT' "HTML Pro - HyperText (text/html)" +.html Ascii 'Um6' 'TEXT' "HTML Pro - HyperText (text/html)" +.i3 Ascii 'TBB6' 'TEXT' "TexEdit - Modula 3 Interface" +.ic1 Raw 'GKON' 'IMAG' "GraphicConverter - Atari Image" +.ic2 Raw 'GKON' 'IMAG' "GraphicConverter - Atari Image" +.ic3 Raw 'GKON' 'IMAG' "GraphicConverter - Atari Image" +.icn Raw 'GKON' 'ICO ' "GraphicConverter - Windows Icon" +.ico Raw 'GKON' 'ICO ' "GraphicConverter - Windows Icon" +.ief Raw 'GKON' 'IEF ' "GraphicConverter - IEF image (image/ief)" +.iff Raw 'GKON' 'ILBM' "GraphicConverter - Amiga IFF Image" +.ilbm Raw 'GKON' 'ILBM' "GraphicConverter - Amiga ILBM Image" +.image Raw 'dCpy' 'dImg' "DiskCopy - Apple DiskCopy Image" +.img Raw 'GKON' 'IMGg' "GraphicConverter - GEM bit image/XIMG" +.img Raw 'GKON' 'KONT' "GraphicConverter - KONTRON Image" +.ini Ascii 'ttxt' 'TEXT' "SimpleText - Windows INI File" +.java Ascii 'CWIE' 'TEXT' "CodeWarrior - Java Source File" +.jfif Raw 'JVWR' 'JFIF' "JPEGView - JFIF Image" +.jpe Raw 'JVWR' 'JPEG' "JPEGView - JPEG Picture (image/jpeg)" +.jpeg Raw 'JVWR' 'JPEG' "JPEGView - JPEG Picture (image/jpeg)" +.jpg Raw 'JVWR' 'JPEG' "JPEGView - JPEG Picture (image/jpeg)" +.latex Ascii 'OTEX' 'TEXT' "OzTex - Latex (application/x-latex)" +.lbm Raw 'GKON' 'ILBM' "GraphicConverter - Amiga IFF Image" +.lha Raw 'LARC' 'LHA ' "MacLHA - LHArc Archive" +.lzh Raw 'LARC' 'LHA ' "MacLHA - LHArc Archive" +.m1a Raw 'KAU1' 'MPEG' "MPEG/CD - MPEG-1 audiostream (audio/x-mpeg)" +.m1s Raw 'MPsp' 'MPEG' "MPEGSplitter - MPEG-1 systemstream" +.m1v Raw 'mMPG' 'M1V ' "Sparkle - MPEG-1 IPB videostream (video/mpeg)" +.m2 Ascii 'TBB6' 'TEXT' "TexEdit - Modula 2 Source" +.m2v Raw 'MPG2' 'MPG2' "MPEG2decoder - MPEG-2 IPB videostream" +.m3 Ascii 'TBB6' 'TEXT' "TexEdit - Modula 3 Source" +.mac Raw 'ttxt' 'PICT' "SimpleText - PICT Picture (image/x-pict)" +.mak Ascii 'TBB6' 'TEXT' "TexEdit - Makefile" +.mcw Raw 'MSWD' 'WDBN' "Microsoft Word - Mac Word Document" +.me Ascii 'ttxt' 'TEXT' "SimpleText - Text Readme" +.med Raw 'SCPL' 'STrk' "SoundApp - Amiga MED Sound" +.mf Ascii '*MF*' 'TEXT' "Metafont - Metafont" +.mid Raw 'ttxt' 'Midi' "SimpleText - MIDI Music" +.midi Raw 'ttxt' 'Midi' "SimpleText - MIDI Music" +.mif Ascii 'Fram' 'TEXT' "FrameMaker - FrameMaker MIF (application/x-mif)" +.mif Ascii 'Fram' 'TEXT' "FrameMaker - FrameMaker MIF (application/x-framemaker)" +.mime Ascii 'mPAK' 'TEXT' "Mpack - MIME Message (message/rfc822)" +.ml Ascii 'TBB6' 'TEXT' "TexEdit - ML Source" +.mod Raw 'SCPL' 'STrk' "SoundApp - MOD Music" +.mol Ascii 'RSML' 'TEXT' "RasMac - MDL Molfile" +.moov Raw 'ttxt' 'MooV' "SimpleText - QuickTime Movie (video/quicktime)" +.mov Raw 'ttxt' 'MooV' "SimpleText - QuickTime Movie (video/quicktime)" +.mp2 Raw 'KAU1' 'MPEG' "MPEG/CD - MPEG-1 audiostream (audio/x-mpeg)" +.mpa Raw 'KAU1' 'MPEG' "MPEG/CD - MPEG-1 audiostream (audio/x-mpeg)" +.mpe Raw 'mMPG' 'MPEG' "Sparkle - MPEG Movie of some sort (video/mpeg)" +.mpeg Raw 'mMPG' 'MPEG' "Sparkle - MPEG Movie of some sort (video/mpeg)" +.mpg Raw 'mMPG' 'MPEG' "Sparkle - MPEG Movie of some sort (video/mpeg)" +.msp Raw 'GKON' 'MSPp' "GraphicConverter - Microsoft Paint" +.mtm Raw 'SNPL' 'MTM ' "PlayerPro - MultiMOD Music" +.mw Raw 'MWII' 'MW2D' "MacWrite II - MacWrite Document (application/macwriteii)" +.mwii Raw 'MWII' 'MW2D' "MacWrite II - MacWrite Document (application/macwriteii)" +.neo Raw 'GKON' 'NeoC' "GraphicConverter - Atari NeoChrome" +.nfo Ascii 'ttxt' 'TEXT' "SimpleText - Info Text (application/text)" +.nst Raw 'SCPL' 'STrk' "SoundApp - MOD Music" +.obj Raw 'SWIN' 'PCFL' "SoftWindows - Object (DOS/Windows)" +.oda Raw 'ODA ' 'ODIF' "MacODA XTND Translator - ODA Document (application/oda)" +.okt Raw 'SCPL' 'OKTA' "SoundApp - Oktalyser MOD Music" +.out Raw 'hDmp' 'BINA' "HexEdit - Output File" +.ovl Raw 'SWIN' 'PCFL' "SoftWindows - Overlay (DOS/Windows)" +.p Ascii 'CWIE' 'TEXT' "CodeWarrior - Pascal Source" +.pac Raw 'GKON' 'STAD' "GraphicConverter - Atari STAD Image" +.pas Ascii 'CWIE' 'TEXT' "CodeWarrior - Pascal Source" +.pbm Raw 'GKON' 'PPGM' "GraphicConverter - Portable Bitmap (image/x-pbm)" +.pbm Raw 'GKON' 'PPGM' "GraphicConverter - Portable Bitmap (image/x-portable-bitmap)" +.pc1 Raw 'GKON' 'Dega' "GraphicConverter - Atari Degas Image" +.pc2 Raw 'GKON' 'Dega' "GraphicConverter - Atari Degas Image" +.pc3 Raw 'GKON' 'Dega' "GraphicConverter - Atari Degas Image" +.pcs Raw 'GKON' 'PICS' "GraphicConverter - Animated PICTs" +.pct Raw 'ttxt' 'PICT' "SimpleText - PICT Picture (image/x-pict)" +.pcx Raw 'GKON' 'PCXx' "GraphicConverter - PC PaintBrush" +.pdb Ascii 'RSML' 'TEXT' "RasMac - Brookhaven PDB file" +.pdf Raw 'CARO' 'PDF ' "Acrobat Reader - Portable Document Format (application/pdf)" +.pdx Ascii 'ALD5' 'TEXT' "PageMaker - Printer Description" +.pgm Raw 'GKON' 'PPGM' "GraphicConverter - Portable Graymap (image/x-pgm)" +.pgm Raw 'GKON' 'PPGM' "GraphicConverter - Portable Graymap (image/x-portable-graymap)" +.pi1 Raw 'GKON' 'Dega' "GraphicConverter - Atari Degas Image" +.pi2 Raw 'GKON' 'Dega' "GraphicConverter - Atari Degas Image" +.pi3 Raw 'GKON' 'Dega' "GraphicConverter - Atari Degas Image" +.pic Raw 'ttxt' 'PICT' "SimpleText - PICT Picture (image/x-pict)" +.pict Raw 'ttxt' 'PICT' "SimpleText - PICT Picture (image/x-macpict)" +.pit Raw 'SITx' 'PIT ' "StuffIt Expander - PackIt Archive" +.pkg Raw 'GEOL' 'HBSF' "AppleLink - AppleLink Package" +.pl Ascii 'McPL' 'TEXT' "MacPerl - Perl Source" +.plt Raw 'GKON' 'HPGL' "GraphicConverter - HP GL/2" +.pm Raw 'GKON' 'PMpm' "GraphicConverter - Bitmap from xv" +.pm3 Raw 'ALD3' 'ALB3' "PageMaker - PageMaker 3 Document" +.pm4 Raw 'ALD4' 'ALB4' "PageMaker - PageMaker 4 Document" +.pm5 Raw 'ALD5' 'ALB5' "PageMaker - PageMaker 5 Document" +.png Raw 'GKON' 'PNG ' "GraphicConverter - Portable Network Graphic" +.pntg Raw 'GKON' 'PNTG' "GraphicConverter - Macintosh Painting" +.ppd Ascii 'ALD5' 'TEXT' "PageMaker - Printer Description" +.ppm Raw 'GKON' 'PPGM' "GraphicConverter - Portable Pixmap (image/x-ppm)" +.ppm Raw 'GKON' 'PPGM' "GraphicConverter - Portable Pixmap (image/x-portable-pixmap)" +.prn Ascii 'TBB6' 'TEXT' "TexEdit - Printer Output File" +.ps Ascii 'vgrd' 'TEXT' "LaserWriter 8 - PostScript (application/postscript)" +.psd Raw '8BIM' '8BPS' "Photoshop - PhotoShop Document" +.pt4 Raw 'ALD4' 'ALT4' "PageMaker - PageMaker 4 Template" +.pt5 Raw 'ALD5' 'ALT5' "PageMaker - PageMaker 5 Template" +.pxr Raw '8BIM' 'PXR ' "Photoshop - Pixar Image" +.qdv Raw 'GKON' 'QDVf' "GraphicConverter - QDV image" +.qt Raw 'ttxt' 'MooV' "SimpleText - QuickTime Movie (video/quicktime)" +.qxd Raw 'XPR3' 'XDOC' "QuarkXpress - QuarkXpress Document" +.qxt Raw 'XPR3' 'XTMP' "QuarkXpress - QuarkXpress Template" +.ram Ascii '????' 'TEXT' "Unknown - Real Audio (audio/x-pn-realaudio)" +.raw Raw 'GKON' 'BINA' "GraphicConverter - Raw Image" +.readme Ascii 'TBB6' 'TEXT' "TexEdit - Text Readme (application/text)" +.rgb Raw 'GKON' 'SGI ' "GraphicConverter - SGI Image (image/x-rgb)" +.rgba Raw 'GKON' 'SGI ' "GraphicConverter - SGI Image (image/x-rgb)" +.rib Ascii 'RINI' 'TEXT' "Renderman - Renderman 3D Data" +.rif Raw 'GKON' 'RIFF' "GraphicConverter - RIFF Graphic" +.rle Raw 'GKON' 'RLE ' "GraphicConverter - RLE image" +.rme Ascii 'ttxt' 'TEXT' "SimpleText - Text Readme" +.rpl Raw 'REP!' 'FRL!' "Replica - Replica Document" +.rsc Raw 'RSED' 'rsrc' "ResEdit - Resource File" +.rsrc Raw 'RSED' 'rsrc' "ResEdit - Resource File" +.rtf Ascii 'MSWD' 'TEXT' "Microsoft Word - Rich Text Format (application/rtf)" +.rtx Ascii 'TBB6' 'TEXT' "TexEdit - Rich Text (text/richtext)" +.s3m Raw 'SNPL' 'S3M ' "PlayerPro - ScreamTracker 3 MOD" +.scc Raw 'GKON' 'MSX ' "GraphicConverter - MSX pitcure" +.usal Raw 'GKON' 'RIX3' "GraphicConverter - ColoRIX" +.sci Raw 'GKON' 'RIX3' "GraphicConverter - ColoRIX" +.scp Raw 'GKON' 'RIX3' "GraphicConverter - ColoRIX" +.scr Raw 'GKON' 'RIX3' "GraphicConverter - ColoRIX" +.scu Raw 'GKON' 'RIX3' "GraphicConverter - ColoRIX" +.sea Raw '????' 'APPL' "Self Extracting Archive - Self-Extracting Archive" +.sf Raw 'SDHK' 'IRCM' "SoundHack - IRCAM Sound" +.sgi Raw 'GKON' 'SGI ' "GraphicConverter - SGI Image" +.sha Ascii 'UnSh' 'TEXT' "UnShar - Unix Shell Archive (application/x-shar)" +.shar Ascii 'UnSh' 'TEXT' "UnShar - Unix Shell Archive (application/x-shar)" +.shp Raw 'GKON' 'SHPp' "GraphicConverter - Printmaster Icon Library" +.sit Raw 'SIT!' 'SITD' "StuffIt - StuffIt Archive" +.sithqx Ascii 'TBB6' 'TEXT' "TexEdit - BinHexed StuffIt Archive (application/mac-binhex40)" +.six Raw 'GKON' 'SIXE' "GraphicConverter - SIXEL image" +.slk Ascii 'XCEL' 'TEXT' "Excel - SYLK Spreadsheet" +.snd Raw 'SCPL' 'BINA' "SoundApp - Sound of various types" +.spc Raw 'GKON' 'Spec' "GraphicConverter - Atari Spectrum 512" +.sr Raw 'GKON' 'SUNn' "GraphicConverter - Sun Raster Image" +.sty Ascii '*TEX' 'TEXT' "Textures - TeX Style" +.sun Raw 'GKON' 'SUNn' "GraphicConverter - Sun Raster Image" +.sup Raw 'GKON' 'SCRN' "GraphicConverter - StartupScreen" +.svx Raw 'SCPL' '8SVX' "SoundApp - Amiga IFF Sound" +.syk Ascii 'XCEL' 'TEXT' "Excel - SYLK Spreadsheet" +.sylk Ascii 'XCEL' 'TEXT' "Excel - SYLK Spreadsheet" +.tar Raw 'S691' 'TARF' "SunTar - Unix Tape ARchive (application/x-tar)" +.targa Raw 'GKON' 'TPIC' "GraphicConverter - Truevision Image" +.taz Raw 'SITx' 'ZIVU' "StuffIt Expander - Compressed Tape ARchive (application/x-compress)" +.tex Ascii 'OTEX' 'TEXT' "OzTeX - TeX Document (application/x-tex)" +.texi Ascii 'OTEX' 'TEXT' "OzTeX - TeX Document" +.texinfo Ascii 'OTEX' 'TEXT' "OzTeX - TeX Document (application/x-texinfo)" +.text Ascii 'ttxt' 'TEXT' "SimpleText - ASCII Text (text/plain)" +.tga Raw 'GKON' 'TPIC' "GraphicConverter - Truevision Image" +.tgz Raw 'Gzip' 'Gzip' "MacGzip - Gnu ZIPed Tape ARchive (application/x-gzip)" +.tif Raw 'JVWR' 'TIFF' "JPEGView - TIFF Picture (image/tiff)" +.tiff Raw 'JVWR' 'TIFF' "JPEGView - TIFF Picture (image/tiff)" +.tny Raw 'GKON' 'TINY' "GraphicConverter - Atari TINY Bitmap" +.tsv Ascii 'XCEL' 'TEXT' "Excel - Tab Separated Values (text/tab-separated-values)" +.tx8 Ascii 'ttxt' 'TEXT' "SimpleText - 8-bit ASCII Text" +.txt Ascii 'ttxt' 'TEXT' "SimpleText - ASCII Text (text/plain)" +.ul Raw 'SCPL' 'ULAW' "SoundApp - Mu-Law Sound (audio/basic)" +.url Raw 'Arch' 'AURL' "Anarchie - URL Bookmark (message/external-body)" +.uu Ascii 'TBB6' 'TEXT' "TexEdit - UUEncode" +.uue Ascii 'TBB6' 'TEXT' "TexEdit - UUEncode" +.vff Raw 'GKON' 'VFFf' "GraphicConverter - DESR VFF Greyscale Image" +.vga Raw 'JVWR' 'BMPp' "JPEGView - OS/2 Bitmap" +.voc Raw 'SCPL' 'VOC ' "SoundApp - VOC Sound" +.w51 Raw 'WPC2' '.WP5' "WordPerfect - WordPerfect PC 5.1 Doc (application/wordperfect5.1)" +.wav Raw 'SCPL' 'WAVE' "SoundApp - Windows WAV Sound (audio/x-wav)" +.wk1 Raw 'XCEL' 'XLBN' "Excel - Lotus Spreadsheet r2.1" +.wks Raw 'XCEL' 'XLBN' "Excel - Lotus Spreadsheet r1.x" +.wmf Raw 'GKON' 'WMF ' "GraphicConverter - Windows Metafile" +.wp Raw 'WPC2' '.WP5' "WordPerfect - WordPerfect PC 5.1 Doc (application/wordperfect5.1)" +.wp4 Raw 'WPC2' '.WP4' "WordPerfect - WordPerfect PC 4.2 Doc" +.wp5 Raw 'WPC2' '.WP5' "WordPerfect - WordPerfect PC 5.x Doc (application/wordperfect5.1)" +.wp6 Raw 'WPC2' '.WP6' "WordPerfect - WordPerfect PC 6.x Doc" +.wpg Raw 'GKON' 'WPGf' "GraphicConverter - WordPerfect Graphic" +.wpm Raw 'WPC2' 'WPD1' "WordPerfect - WordPerfect Mac" +.wri Raw 'MSWD' 'WDBN' "Microsoft Word - MS Write/Windows" +.wve Raw 'SCPL' 'BINA' "SoundApp - PSION sound" +.x10 Raw 'GKON' 'XWDd' "GraphicConverter - X-Windows Dump (image/x-xwd)" +.x11 Raw 'GKON' 'XWDd' "GraphicConverter - X-Windows Dump (image/x-xwd)" +.xbm Raw 'GKON' 'XBM ' "GraphicConverter - X-Windows Bitmap (image/x-xbm)" +.xbm Raw 'GKON' 'XBM ' "GraphicConverter - X-Windows Bitmap (image/x-xbitmap)" +.xl Raw 'XCEL' 'XLS ' "Excel - Excel Spreadsheet" +.xlc Raw 'XCEL' 'XLC ' "Excel - Excel Chart" +.xlm Raw 'XCEL' 'XLM ' "Excel - Excel Macro" +.xls Raw 'XCEL' 'XLS ' "Excel - Excel Spreadsheet" +.xlw Raw 'XCEL' 'XLW ' "Excel - Excel Workspace" +.xm Raw 'SNPL' 'XM ' "PlayerPro - FastTracker MOD Music" +.xpm Raw 'GKON' 'XPM ' "GraphicConverter - X-Windows Pixmap (image/x-xpm)" +.xpm Raw 'GKON' 'XPM ' "GraphicConverter - X-Windows Pixmap (image/x-xpixmap)" +.xwd Raw 'GKON' 'XWDd' "GraphicConverter - X-Windows Dump (image/x-xwd)" +# +# Add the default translation for anything not recognized +# +* Ascii 'ttxt' 'TEXT' "SimpleText - Text file" diff --git a/genisoimage/multi.c b/genisoimage/multi.c new file mode 100644 index 0000000..e069c91 --- /dev/null +++ b/genisoimage/multi.c @@ -0,0 +1,1912 @@ +/* + * 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. + * + */ + +/* @(#)multi.c 1.68 05/05/15 joerg */ +/* + * File multi.c - scan existing iso9660 image and merge into + * iso9660 filesystem. Used for multisession support. + * + * Written by Eric Youngdale (1996). + * Copyright (c) 1999-2003 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <timedefs.h> +#include <errno.h> +#include <utypes.h> +#include <schily.h> +#include <ctype.h> /* Needed for printasc() */ + +#ifdef VMS + +#include <sys/file.h> +#include <vms/fabdef.h> +#include "vms.h" +#endif + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +/* + * Cannot debug memset() with gdb on Linux, so use fillbytes() + */ +/*#define memset(s, c, n) fillbytes(s, n, c)*/ + +#define TF_CREATE 1 +#define TF_MODIFY 2 +#define TF_ACCESS 4 +#define TF_ATTRIBUTES 8 + +static int isonum_711(unsigned char *p); +static int isonum_721(unsigned char *p); +static int isonum_723(unsigned char *p); +static int isonum_731(unsigned char *p); + +static void printasc(char *txt, unsigned char *p, int len); +static void prbytes(char *txt, unsigned char *p, int len); +unsigned char *parse_xa(unsigned char *pnt, int *lenp, + struct directory_entry *dpnt); +int rr_flags(struct iso_directory_record *idr); +static int parse_rrflags(Uchar *pnt, int len, int cont_flag); +static BOOL find_rr(struct iso_directory_record *idr, Uchar **pntp, + int *lenp); +static int parse_rr(unsigned char *pnt, int len, + struct directory_entry *dpnt); +static int check_rr_dates(struct directory_entry *dpnt, + struct directory_entry *current, + struct stat *statbuf, + struct stat *lstatbuf); +static struct directory_entry ** + read_merging_directory(struct iso_directory_record *, int *); +static int free_mdinfo(struct directory_entry **, int len); +static void free_directory_entry(struct directory_entry * dirp); +static void merge_remaining_entries(struct directory *, + struct directory_entry **, int); + +static int merge_old_directory_into_tree(struct directory_entry *, + struct directory *); +static void check_rr_relocation(struct directory_entry *de); + +static int +isonum_711(unsigned char *p) +{ + return (*p & 0xff); +} + +static int +isonum_721(unsigned char *p) +{ + return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); +} + +static int +isonum_723(unsigned char *p) +{ +#if 0 + if (p[0] != p[3] || p[1] != p[2]) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "invalid format 7.2.3 number\n"); +#else + fprintf(stderr, "invalid format 7.2.3 number\n"); + exit(1); +#endif + } +#endif + return (isonum_721(p)); +} + +static int +isonum_731(unsigned char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +int +isonum_733(unsigned char *p) +{ + return (isonum_731(p)); +} + +FILE *in_image = NULL; + +#ifndef USE_SCG +/* + * Don't define readsecs if genisoimage is linked with + * the SCSI library. + * readsecs() will be implemented as SCSI command in this case. + * + * Use global var in_image directly in readsecs() + * the SCSI equivalent will not use a FILE* for I/O. + * + * The main point of this pointless abstraction is that Solaris won't let + * you read 2K sectors from the cdrom driver. The fact that 99.9% of the + * discs out there have a 2K sectorsize doesn't seem to matter that much. + * Anyways, this allows the use of a scsi-generics type of interface on + * Solaris. + */ +static int +readsecs(int startsecno, void *buffer, int sectorcount) +{ + int f = fileno(in_image); + + if (lseek(f, (off_t) startsecno * SECTOR_SIZE, SEEK_SET) == (off_t) - 1) { +#ifdef USE_LIBSCHILY + comerr(" Seek error on old image\n"); +#else + fprintf(stderr, " Seek error on old image\n"); + exit(10); +#endif + } + if (read(f, buffer, (sectorcount * SECTOR_SIZE)) + != (sectorcount * SECTOR_SIZE)) { +#ifdef USE_LIBSCHILY + comerr(" Read error on old image\n"); +#else + fprintf(stderr, " Read error on old image\n"); + exit(10); +#endif + } + return (sectorcount * SECTOR_SIZE); +} + +#endif + +static void +printasc(char *txt, unsigned char *p, int len) +{ + int i; + + fprintf(stderr, "%s ", txt); + for (i = 0; i < len; i++) { + if (isprint(p[i])) + fprintf(stderr, "%c", p[i]); + else + fprintf(stderr, "."); + } + fprintf(stderr, "\n"); +} + +static void +prbytes(char *txt, register Uchar *p, register int len) +{ + fprintf(stderr, "%s", txt); + while (--len >= 0) + fprintf(stderr, " %02X", *p++); + fprintf(stderr, "\n"); +} + +unsigned char * +parse_xa(unsigned char *pnt, int *lenp, struct directory_entry *dpnt) +{ + struct iso_xa_dir_record *xadp; + int len = *lenp; +static int did_xa = 0; + +/*fprintf(stderr, "len: %d\n", len);*/ + + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + +/* if (dpnt) prbytes("XA ", pnt, len);*/ + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + *lenp = len; + if (!did_xa) { + did_xa = 1; + errmsgno(EX_BAD, "Found XA directory extension record.\n"); + } + } else if (pnt[2] == 0) { + char *cp = NULL; + + if (dpnt) + cp = (char *)&dpnt->isorec; + if (cp) { + prbytes("ISOREC:", (Uchar *)cp, 33+cp[32]); + printasc("ISOREC:", (Uchar *)cp, 33+cp[32]); + prbytes("XA REC:", pnt, len); + printasc("XA REC:", pnt, len); + } + if (no_rr == 0) { + errmsgno(EX_BAD, "Disabling RR / XA / AA.\n"); + no_rr = 1; + } + *lenp = 0; + if (cp) { + errmsgno(EX_BAD, "Problems with old ISO directory entry for file: '%s'.\n", &cp[33]); + } + errmsgno(EX_BAD, "Illegal extended directory attributes found (bad XA disk?).\n"); +/* errmsgno(EX_BAD, "Disabling Rock Ridge for old session.\n");*/ + comerrno(EX_BAD, "Try again using the -no-rr option.\n"); + } + } + if (len >= 4 && pnt[3] != 1 && pnt[3] != 2) { + prbytes("BAD RR ATTRIBUTES:", pnt, len); + printasc("BAD RR ATTRIBUTES:", pnt, len); + } + return (pnt); +} + +static BOOL +find_rr(struct iso_directory_record *idr, Uchar **pntp, int *lenp) +{ + struct iso_xa_dir_record *xadp; + int len; + unsigned char *pnt; + BOOL ret = FALSE; + + len = idr->length[0] & 0xff; + len -= sizeof (struct iso_directory_record); + len += sizeof (idr->name); + len -= idr->name_len[0]; + + pnt = (unsigned char *) idr; + pnt += sizeof (struct iso_directory_record); + pnt -= sizeof (idr->name); + pnt += idr->name_len[0]; + if ((idr->name_len[0] & 1) == 0) { + pnt++; + len--; + } + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + ret = TRUE; + } + } + *pntp = pnt; + *lenp = len; + return (ret); +} + +static int +parse_rrflags(Uchar *pnt, int len, int cont_flag) +{ + int ncount; + int cont_extent; + int cont_offset; + int cont_size; + int flag1; + int flag2; + + cont_extent = cont_offset = cont_size = 0; + + ncount = 0; + flag1 = flag2 = 0; + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#endif + return (0); /* JS ??? Is this right ??? */ + } + ncount++; + if (pnt[0] == 'R' && pnt[1] == 'R') + flag1 = pnt[4] & 0xff; + + if (strncmp((char *) pnt, "PX", 2) == 0) /* POSIX attributes */ + flag2 |= 1; + if (strncmp((char *) pnt, "PN", 2) == 0) /* POSIX device number */ + flag2 |= 2; + if (strncmp((char *) pnt, "SL", 2) == 0) /* Symlink */ + flag2 |= 4; + if (strncmp((char *) pnt, "NM", 2) == 0) /* Alternate Name */ + flag2 |= 8; + if (strncmp((char *) pnt, "CL", 2) == 0) /* Child link */ + flag2 |= 16; + if (strncmp((char *) pnt, "PL", 2) == 0) /* Parent link */ + flag2 |= 32; + if (strncmp((char *) pnt, "RE", 2) == 0) /* Relocated Direcotry */ + flag2 |= 64; + if (strncmp((char *) pnt, "TF", 2) == 0) /* Time stamp */ + flag2 |= 128; + if (strncmp((char *) pnt, "SP", 2) == 0) { /* SUSP record */ + flag2 |= 1024; +/* su_version = pnt[3] & 0xff;*/ + } + if (strncmp((char *) pnt, "AA", 2) == 0) { /* Apple Signature record */ + flag2 |= 2048; +/* aa_version = pnt[3] & 0xff;*/ + } + + if (strncmp((char *)pnt, "CE", 2) == 0) { /* Continuation Area */ + cont_extent = isonum_733(pnt+4); + cont_offset = isonum_733(pnt+12); + cont_size = isonum_733(pnt+20); + } + + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + unsigned char sector[SECTOR_SIZE]; + + readsecs(cont_extent, sector, 1); + flag2 |= parse_rrflags(§or[cont_offset], cont_size, 1); + } + } + return (flag2); +} + +int +rr_flags(struct iso_directory_record *idr) +{ + int len; + unsigned char *pnt; + int ret = 0; + + if (find_rr(idr, &pnt, &len)) + ret |= 4096; + ret |= parse_rrflags(pnt, len, 0); + return (ret); +} + +/* + * Parse the RR attributes so we can find the file name. + */ +static int +parse_rr(unsigned char *pnt, int len, struct directory_entry *dpnt) +{ + int cont_extent; + int cont_offset; + int cont_size; + char name_buf[256]; + + cont_extent = cont_offset = cont_size = 0; + + pnt = parse_xa(pnt, &len, dpnt /* 0 */); + + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#endif + return (-1); + } + if (strncmp((char *) pnt, "NM", 2) == 0) { + strncpy(name_buf, (char *) pnt + 5, pnt[2] - 5); + name_buf[pnt[2] - 5] = 0; + if (dpnt->name) { + size_t nlen = strlen(dpnt->name); + + /* + * append to name from previous NM records + */ + dpnt->name = realloc(dpnt->name, nlen + + strlen(name_buf) + 1); + strcpy(dpnt->name + nlen, name_buf); + } else { + dpnt->name = strdup(name_buf); + dpnt->got_rr_name = 1; + } + /* continue searching for more NM records */ + } else if (strncmp((char *) pnt, "CE", 2) == 0) { + cont_extent = isonum_733(pnt + 4); + cont_offset = isonum_733(pnt + 12); + cont_size = isonum_733(pnt + 20); + } + + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + unsigned char sector[SECTOR_SIZE]; + + readsecs(cont_extent, sector, 1); + if (parse_rr(§or[cont_offset], + cont_size, dpnt) == -1) + return (-1); + } + } + + /* Fall back to the iso name if no RR name found */ + if (dpnt->name == NULL) { + char *cp; + + strcpy(name_buf, dpnt->isorec.name); + cp = strchr(name_buf, ';'); + if (cp != NULL) { + *cp = '\0'; + } + dpnt->name = strdup(name_buf); + } + return (0); +}/* parse_rr */ + + +/* + * Returns 1 if the two files are identical + * Returns 0 if the two files differ + */ +static int +check_rr_dates(struct directory_entry *dpnt, + struct directory_entry *current, + struct stat *statbuf, + struct stat *lstatbuf) +{ + int cont_extent; + int cont_offset; + int cont_size; + int offset; + unsigned char *pnt; + int len; + int same_file; + int same_file_type; + mode_t mode; + char time_buf[7]; + + + cont_extent = cont_offset = cont_size = 0; + same_file = 1; + same_file_type = 1; + + pnt = dpnt->rr_attributes; + len = dpnt->rr_attr_size; + /* + * We basically need to parse the rr attributes again, and dig out the + * dates and file types. + */ + pnt = parse_xa(pnt, &len, /* dpnt */ 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#endif + return (-1); + } + + /* + * If we have POSIX file modes, make sure that the file type is + * the same. If it isn't, then we must always write the new + * file. + */ + if (strncmp((char *) pnt, "PX", 2) == 0) { + mode = isonum_733(pnt + 4); + if ((lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT)) { + same_file_type = 0; + same_file = 0; + } + } + if (strncmp((char *) pnt, "TF", 2) == 0) { + offset = 5; + if (pnt[4] & TF_CREATE) { + iso9660_date((char *) time_buf, + lstatbuf->st_ctime); + if (memcmp(time_buf, pnt + offset, 7) != 0) + same_file = 0; + offset += 7; + } + if (pnt[4] & TF_MODIFY) { + iso9660_date((char *) time_buf, + lstatbuf->st_mtime); + if (memcmp(time_buf, pnt + offset, 7) != 0) + same_file = 0; + offset += 7; + } + } + if (strncmp((char *) pnt, "CE", 2) == 0) { + cont_extent = isonum_733(pnt + 4); + cont_offset = isonum_733(pnt + 12); + cont_size = isonum_733(pnt + 20); + } + + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + unsigned char sector[SECTOR_SIZE]; + + readsecs(cont_extent, sector, 1); + /* + * Continue to scan the extension record. + * Note that this has not been tested yet, but it is + * definitely more correct that calling parse_rr() + * as done in Eric's old code. + */ + pnt = §or[cont_offset]; + len = cont_size; + /* + * Clear the "pending extension record" state as + * we did already read it now. + */ + cont_extent = cont_offset = cont_size = 0; + } + } + + /* + * If we have the same fundamental file type, then it is clearly safe + * to reuse the TRANS.TBL entry. + */ + if (same_file_type) { + current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + } + return (same_file); +} + +static struct directory_entry ** +read_merging_directory(struct iso_directory_record *mrootp, int *nentp) +{ + unsigned char *cpnt; + unsigned char *cpnt1; + char *p; + char *dirbuff; + int i; + struct iso_directory_record *idr; + int len; + int nbytes; + int nent; + struct directory_entry **pnt; + int rlen; + struct directory_entry **rtn; + int seen_rockridge; + unsigned char *tt_buf; + int tt_extent; + int tt_size; + + static int warning_given = 0; + + /* + * This is the number of sectors we will need to read. We need to + * round up to get the last fractional sector - we are asking for the + * data in terms of a number of sectors. + */ + nbytes = roundup(isonum_733((unsigned char *) mrootp->size), + SECTOR_SIZE); + + /* + * First, allocate a buffer large enough to read in the entire + * directory. + */ + dirbuff = (char *) e_malloc(nbytes); + + readsecs(isonum_733((unsigned char *) mrootp->extent), dirbuff, + nbytes / SECTOR_SIZE); + + /* + * Next look over the directory, and count up how many entries we have. + */ + len = isonum_733((unsigned char *) mrootp->size); + i = 0; + *nentp = 0; + nent = 0; + while (i < len) { + idr = (struct iso_directory_record *) & dirbuff[i]; + if (idr->length[0] == 0) { + i = ISO_ROUND_UP(i); + continue; + } + nent++; + i += idr->length[0]; + } + + /* + * Now allocate the buffer which will hold the array we are about to + * return. + */ + rtn = (struct directory_entry **) e_malloc(nent * sizeof (*rtn)); + + /* + * Finally, scan the directory one last time, and pick out the relevant + * bits of information, and store it in the relevant bits of the + * structure. + */ + i = 0; + pnt = rtn; + tt_extent = 0; + seen_rockridge = 0; + tt_size = 0; + while (i < len) { + idr = (struct iso_directory_record *) & dirbuff[i]; + if (idr->length[0] == 0) { + i = ISO_ROUND_UP(i); + continue; + } + *pnt = (struct directory_entry *) e_malloc(sizeof (**rtn)); + (*pnt)->next = NULL; +#ifdef DEBUG + fprintf(stderr, "IDR name: '%s' ist: %d soll: %d\n", + idr->name, strlen(idr->name), idr->name_len[0]); +#endif + (*pnt)->isorec = *idr; + (*pnt)->starting_block = + isonum_733((unsigned char *) idr->extent); + (*pnt)->size = isonum_733((unsigned char *) idr->size); + (*pnt)->priority = 0; + (*pnt)->name = NULL; + (*pnt)->got_rr_name = 0; + (*pnt)->table = NULL; + (*pnt)->whole_name = NULL; + (*pnt)->filedir = NULL; + (*pnt)->parent_rec = NULL; + /* + * Set this information so that we correctly cache previous + * session bits of information. + */ + (*pnt)->inode = (*pnt)->starting_block; + (*pnt)->dev = PREV_SESS_DEV; + (*pnt)->rr_attributes = NULL; + (*pnt)->rr_attr_size = 0; + (*pnt)->total_rr_attr_size = 0; + (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY; +#ifdef APPLE_HYB + (*pnt)->assoc = NULL; + (*pnt)->hfs_ent = NULL; +#endif /* APPLE_HYB */ + + /* + * Check for and parse any RR attributes for the file. All we + * are really looking for here is the original name of the + * file. + */ + rlen = idr->length[0] & 0xff; + cpnt = (unsigned char *) idr; + + rlen -= offsetof(struct iso_directory_record, name[0]); + cpnt += offsetof(struct iso_directory_record, name[0]); + + rlen -= idr->name_len[0]; + cpnt += idr->name_len[0]; + + if ((idr->name_len[0] & 1) == 0) { + cpnt++; + rlen--; + } + + if (no_rr) + rlen = 0; + if (rlen > 0) { + (*pnt)->total_rr_attr_size = + (*pnt)->rr_attr_size = rlen; + (*pnt)->rr_attributes = e_malloc(rlen); + memcpy((*pnt)->rr_attributes, cpnt, rlen); + seen_rockridge = 1; + } +#ifdef DEBUG + fprintf(stderr, "INT name: '%s' ist: %d soll: %d\n", + (*pnt)->isorec.name, strlen((*pnt)->isorec.name), + idr->name_len[0]); +#endif + + if (idr->name_len[0] < sizeof ((*pnt)->isorec.name)) { + /* + * Now zero out the remainder of the name field. + */ + cpnt = (unsigned char *) (*pnt)->isorec.name; + cpnt += idr->name_len[0]; + memset(cpnt, 0, + sizeof ((*pnt)->isorec.name) - idr->name_len[0]); + } else { + /* + * Simple sanity work to make sure that we have no + * illegal data structures in our tree. + */ + (*pnt)->isorec.name[MAX_ISONAME] = '\0'; + (*pnt)->isorec.name_len[0] = MAX_ISONAME; + } + /* + * If the filename len from the old session is more + * then 31 chars, there is a high risk of hard violations + * if the ISO9660 standard. + * Run it through our name canonication machine.... + */ + if (idr->name_len[0] > LEN_ISONAME || check_oldnames) { + iso9660_check(idr, *pnt); + } + + if (parse_rr((*pnt)->rr_attributes, rlen, *pnt) == -1) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Cannot parse Rock Ridge attributes for '%s'.\n", + idr->name); +#else + fprintf(stderr, + "Cannot parse Rock Ridge attributes for '%s'.\n", + idr->name); + exit(1); +#endif + } + if (((*pnt)->isorec.name_len[0] == 1) && + (((*pnt)->isorec.name[0] == 0) || /* "." entry */ + ((*pnt)->isorec.name[0] == 1))) { /* ".." entry */ + + if ((*pnt)->name != NULL) { + free((*pnt)->name); + } + if ((*pnt)->whole_name != NULL) { + free((*pnt)->whole_name); + } + if ((*pnt)->isorec.name[0] == 0) { + (*pnt)->name = strdup("."); + } else { + (*pnt)->name = strdup(".."); + } + } +#ifdef DEBUG + fprintf(stderr, "got DE name: %s\n", (*pnt)->name); +#endif + + if (strncmp(idr->name, trans_tbl, strlen(trans_tbl)) == 0) { + if ((*pnt)->name != NULL) { + free((*pnt)->name); + } + if ((*pnt)->whole_name != NULL) { + free((*pnt)->whole_name); + } +/* (*pnt)->name = strdup("<translation table>");*/ + (*pnt)->name = strdup(trans_tbl); + tt_extent = isonum_733((unsigned char *) idr->extent); + tt_size = isonum_733((unsigned char *) idr->size); + if (tt_extent == 0) + tt_size = 0; + } + pnt++; + i += idr->length[0]; + } +#ifdef APPLE_HYB + /* + * If we find an associated file, check if there is a file + * with same ISO name and link it to this entry + */ + for (pnt = rtn, i = 0; i < nent; i++, pnt++) { + int j; + + rlen = isonum_711((*pnt)->isorec.name_len); + if ((*pnt)->isorec.flags[0] & ISO_ASSOCIATED) { + for (j = 0; j < nent; j++) { + if (strncmp(rtn[j]->isorec.name, + (*pnt)->isorec.name, rlen) == 0 && + (rtn[j]->isorec.flags[0] & ISO_ASSOCIATED) == 0) { + rtn[j]->assoc = *pnt; + + /* + * don't want this entry to be + * in the Joliet tree + */ + (*pnt)->de_flags |= INHIBIT_JOLIET_ENTRY; + + /* + * as we have associated files, then + * assume we are are dealing with + * Apple's extensions - if not already + * set + */ + if (apple_both == 0) { + apple_both = apple_ext = 1; + } + break; + } + } + } + } +#endif /* APPLE_HYB */ + + /* + * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it + * to get the filenames of the files. Also, save the table info, just + * in case we need to use it. + * + * The entries look something like: F ISODUMP.;1 isodump + */ + if (tt_extent != 0 && tt_size != 0) { + nbytes = roundup(tt_size, SECTOR_SIZE); + tt_buf = (unsigned char *) e_malloc(nbytes); + readsecs(tt_extent, tt_buf, nbytes / SECTOR_SIZE); + + /* + * Loop through the file, examine each entry, and attempt to + * attach it to the correct entry. + */ + cpnt = tt_buf; + cpnt1 = tt_buf; + while (cpnt - tt_buf < tt_size) { + /* Skip to a line terminator, or end of the file. */ + while ((cpnt1 - tt_buf < tt_size) && + (*cpnt1 != '\n') && + (*cpnt1 != '\0')) { + cpnt1++; + } + /* Zero terminate this particular line. */ + if (cpnt1 - tt_buf < tt_size) { + *cpnt1 = '\0'; + } + /* + * Now dig through the actual directories, and try and + * find the attachment for this particular filename. + */ + for (pnt = rtn, i = 0; i < nent; i++, pnt++) { + rlen = isonum_711((*pnt)->isorec.name_len); + + /* + * If this filename is so long that it would + * extend past the end of the file, it cannot + * be the one we want. + */ + if (cpnt + 2 + rlen - tt_buf >= tt_size) { + continue; + } + /* + * Now actually compare the name, and make sure + * that the character at the end is a ' '. + */ + if (strncmp((char *) cpnt + 2, + (*pnt)->isorec.name, rlen) == 0 && + cpnt[2 + rlen] == ' ' && + (p = strchr((char *)&cpnt[2 + rlen], '\t'))) { + p++; + /* + * This is a keeper. Now determine the + * correct table entry that we will + * use on the new image. + */ + if (strlen(p) > 0) { + (*pnt)->table = + e_malloc(strlen(p) + 4); + sprintf((*pnt)->table, + "%c\t%s\n", + *cpnt, p); + } + if (!(*pnt)->got_rr_name) { + if ((*pnt)->name != NULL) { + free((*pnt)->name); + } + (*pnt)->name = strdup(p); + } + break; + } + } + cpnt = cpnt1 + 1; + cpnt1 = cpnt; + } + + free(tt_buf); + } else if (!seen_rockridge && !warning_given) { + /* + * Warn the user that iso-9660 names were used because neither + * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were + * found. + */ + fprintf(stderr, + "Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) \n"); + fprintf(stderr, + "name translations were found on previous session.\n"); + fprintf(stderr, + "ISO-9660 file names have been used instead.\n"); + warning_given = 1; + } + if (dirbuff != NULL) { + free(dirbuff); + } + *nentp = nent; + return (rtn); +}/* read_merging_directory */ + +/* + * Free any associated data related to the structures. + */ +static int +free_mdinfo(struct directory_entry **ptr, int len) +{ + int i; + struct directory_entry **p; + + p = ptr; + for (i = 0; i < len; i++, p++) { + /* + * If the tree-handling code decided that it needed an entry, it + * will have removed it from the list. Thus we must allow for + * null pointers here. + */ + if (*p == NULL) { + continue; + } + free_directory_entry(*p); + } + + free(ptr); + return (0); +} + +static void +free_directory_entry(struct directory_entry *dirp) +{ + if (dirp->name != NULL) + free(dirp->name); + + if (dirp->whole_name != NULL) + free(dirp->whole_name); + + if (dirp->rr_attributes != NULL) + free(dirp->rr_attributes); + + if (dirp->table != NULL) + free(dirp->table); + + free(dirp); +} + +/* + * Search the list to see if we have any entries from the previous + * session that match this entry. If so, copy the extent number + * over so we don't bother to write it out to the new session. + */ +int +check_prev_session(struct directory_entry **ptr, int len, + struct directory_entry *curr_entry, + struct stat *statbuf, + struct stat *lstatbuf, + struct directory_entry **odpnt) +{ + int i; + int rr; + int retcode = 0; /* Default not found */ + + for (i = 0; i < len; i++) { + if (ptr[i] == NULL) { /* Used or empty entry skip */ + continue; + } +#if 0 + if (ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 && + ptr[i]->name[0] == '\0') { + continue; + } + if (ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 && + ptr[i]->name[0] == 1) { + continue; + } +#else + if (ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0) { + continue; + } + if (ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0) { + continue; + } +#endif + + if (ptr[i]->name != NULL && + strcmp(ptr[i]->name, curr_entry->name) != 0) { + /* Not the same name continue */ + continue; + } + /* + * It's a directory so we must always merge it with the new + * session. Never ever reuse directory extents. See comments + * in tree.c for an explaination of why this must be the case. + */ + if ((curr_entry->isorec.flags[0] & ISO_DIRECTORY) != 0) { + retcode = 2; /* Flag directory case */ + goto found_it; + } + /* + * We know that the files have the same name. If they also + * have the same file type (i.e. file, dir, block, etc), then + * we can safely reuse the TRANS.TBL entry for this file. The + * check_rr_dates() function will do this for us. + * + * Verify that the file type and dates are consistent. If not, + * we probably have a different file, and we need to write it + * out again. + */ + retcode = 1; /* We found a non directory */ + + if (ptr[i]->rr_attributes != NULL) { + if ((rr = check_rr_dates(ptr[i], curr_entry, statbuf, + lstatbuf)) == -1) + return (-1); + + if (rr == 0) { /* Different files */ + goto found_it; + } + } + /* + * Verify size and timestamp. If rock ridge is in use, we + * need to compare dates from RR too. Directories are special, + * we calculate their size later. + */ + if (ptr[i]->size != curr_entry->size) { + /* Different files */ + goto found_it; + } + if (memcmp(ptr[i]->isorec.date, + curr_entry->isorec.date, 7) != 0) { + /* Different files */ + goto found_it; + } + /* We found it and we can reuse the extent */ + memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8); + curr_entry->starting_block = isonum_733((unsigned char *)ptr[i]->isorec.extent); + curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + goto found_it; + } + return (retcode); + +found_it: + if (odpnt != NULL) { + *odpnt = ptr[i]; + } else { + free(ptr[i]); + } + ptr[i] = NULL; + return (retcode); +} + +/* + * open_merge_image: Open an existing image. + */ +int +open_merge_image(char *path) +{ +#ifndef USE_SCG + in_image = fopen(path, "rb"); + if (in_image == NULL) { + return (-1); + } +#else + in_image = fopen(path, "rb"); + if (in_image == NULL) { + if (scsidev_open(path) < 0) + return (-1); + } +#endif + return (0); +} + +/* + * close_merge_image: Close an existing image. + */ +int +close_merge_image() +{ +#ifdef USE_SCG + return (scsidev_close()); +#else + return (fclose(in_image)); +#endif +} + +/* + * merge_isofs: Scan an existing image, and return a pointer + * to the root directory for this image. + */ +struct iso_directory_record * +merge_isofs(char *path) +{ + char buffer[SECTOR_SIZE]; + int file_addr; + int i; + struct iso_primary_descriptor *pri = NULL; + struct iso_directory_record *rootp; + struct iso_volume_descriptor *vdp; + + /* + * Start by searching for the volume header. Ultimately, we need to + * search for volume headers in multiple places because we might be + * starting with a multisession image. FIXME(eric). + */ + get_session_start(&file_addr); + + for (i = 0; i < 100; i++) { + if (readsecs(file_addr, buffer, + sizeof (buffer) / SECTOR_SIZE) != sizeof (buffer)) { +#ifdef USE_LIBSCHILY + comerr(" Read error on old image %s\n", path); +#else + fprintf(stderr, " Read error on old image %s\n", path); + exit(10); +#endif + } + vdp = (struct iso_volume_descriptor *) buffer; + + if ((strncmp(vdp->id, ISO_STANDARD_ID, sizeof (vdp->id)) == 0) && + (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY)) { + break; + } + file_addr += 1; + } + + if (i == 100) { + return (NULL); + } + pri = (struct iso_primary_descriptor *) vdp; + + /* Check the blocksize of the image to make sure it is compatible. */ + if (isonum_723((unsigned char *) pri->logical_block_size) != SECTOR_SIZE) { + errmsgno(EX_BAD, + "Previous session has incompatible sector size %d.\n", + isonum_723((unsigned char *) pri->logical_block_size)); + return (NULL); + } + if (isonum_723((unsigned char *) pri->volume_set_size) != 1) { + errmsgno(EX_BAD, + "Previous session has volume set size %d (must be 1).\n", + isonum_723((unsigned char *) pri->volume_set_size)); + return (NULL); + } + /* Get the location and size of the root directory. */ + rootp = (struct iso_directory_record *) + e_malloc(sizeof (struct iso_directory_record)); + + memcpy(rootp, pri->root_directory_record, sizeof (*rootp)); + + return (rootp); +} + +static void +merge_remaining_entries(struct directory *this_dir, + struct directory_entry **pnt, int n_orig) +{ + int i; + struct directory_entry *s_entry; + unsigned int ttbl_extent = 0; + unsigned int ttbl_index = 0; + char whole_path[PATH_MAX]; + + /* + * Whatever is leftover in the list needs to get merged back into the + * directory. + */ + for (i = 0; i < n_orig; i++) { + if (pnt[i] == NULL) { + continue; + } + if (pnt[i]->name != NULL && pnt[i]->whole_name == NULL) { + /* Set the name for this directory. */ + strcpy(whole_path, this_dir->de_name); + strcat(whole_path, SPATH_SEPARATOR); + strcat(whole_path, pnt[i]->name); + + pnt[i]->whole_name = strdup(whole_path); + } + if (pnt[i]->name != NULL && +/* strcmp(pnt[i]->name, "<translation table>") == 0 )*/ + strcmp(pnt[i]->name, trans_tbl) == 0) { + ttbl_extent = + isonum_733((unsigned char *)pnt[i]->isorec.extent); + ttbl_index = i; + continue; + } + + /* + * Skip directories for now - these need to be treated + * differently. + */ + if ((pnt[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) { + /* + * FIXME - we need to insert this directory into the + * tree, so that the path tables we generate will be + * correct. + */ + if ((strcmp(pnt[i]->name, ".") == 0) || + (strcmp(pnt[i]->name, "..") == 0)) { + free_directory_entry(pnt[i]); + pnt[i] = NULL; + continue; + } else { + merge_old_directory_into_tree(pnt[i], this_dir); + } + } + pnt[i]->next = this_dir->contents; + pnt[i]->filedir = this_dir; + this_dir->contents = pnt[i]; + pnt[i] = NULL; + } + + + /* + * If we don't have an entry for the translation table, then don't + * bother trying to copy the starting extent over. Note that it is + * possible that if we are copying the entire directory, the entry for + * the translation table will have already been inserted into the + * linked list and removed from the old entries list, in which case we + * want to leave the extent number as it was before. + */ + if (ttbl_extent == 0) { + return; + } + /* + * Finally, check the directory we are creating to see whether there + * are any new entries in it. If there are not, we can reuse the same + * translation table. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + /* + * Don't care about '.' or '..'. They are never in the table + * anyways. + */ + if (s_entry->name != NULL && strcmp(s_entry->name, ".") == 0) { + continue; + } + if (s_entry->name != NULL && strcmp(s_entry->name, "..") == 0) { + continue; + } +/* if (strcmp(s_entry->name, "<translation table>") == 0)*/ + if (strcmp(s_entry->name, trans_tbl) == 0) { + continue; + } + if ((s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0) { + return; + } + } + + /* + * Locate the translation table, and re-use the same extent. It isn't + * clear that there should ever be one in there already so for now we + * try and muddle through the best we can. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { +/* if (strcmp(s_entry->name, "<translation table>") == 0)*/ + if (strcmp(s_entry->name, trans_tbl) == 0) { + fprintf(stderr, "Should never get here\n"); + set_733(s_entry->isorec.extent, ttbl_extent); + return; + } + } + + pnt[ttbl_index]->next = this_dir->contents; + pnt[ttbl_index]->filedir = this_dir; + this_dir->contents = pnt[ttbl_index]; + pnt[ttbl_index] = NULL; +} + + +/* + * Here we have a case of a directory that has completely disappeared from + * the face of the earth on the tree we are mastering from. Go through and + * merge it into the tree, as well as everything beneath it. + * + * Note that if a directory has been moved for some reason, this will + * incorrectly pick it up and attempt to merge it back into the old + * location. FIXME(eric). + */ +static int +merge_old_directory_into_tree(struct directory_entry *dpnt, + struct directory *parent) +{ + struct directory_entry **contents = NULL; + int i; + int n_orig; + struct directory *this_dir, + *next_brother; + char whole_path[PATH_MAX]; + + this_dir = (struct directory *) e_malloc(sizeof (struct directory)); + memset(this_dir, 0, sizeof (struct directory)); + this_dir->next = NULL; + this_dir->subdir = NULL; + this_dir->self = dpnt; + this_dir->contents = NULL; + this_dir->size = 0; + this_dir->extent = 0; + this_dir->depth = parent->depth + 1; + this_dir->parent = parent; + if (!parent->subdir) + parent->subdir = this_dir; + else { + next_brother = parent->subdir; + while (next_brother->next) + next_brother = next_brother->next; + next_brother->next = this_dir; + } + + /* Set the name for this directory. */ + strcpy(whole_path, parent->de_name); + strcat(whole_path, SPATH_SEPARATOR); + strcat(whole_path, dpnt->name); + this_dir->de_name = strdup(whole_path); + this_dir->whole_name = strdup(whole_path); + + /* + * Now fill this directory using information from the previous session. + */ + contents = read_merging_directory(&dpnt->isorec, &n_orig); + /* + * Start by simply copying the '.', '..' and non-directory entries to + * this directory. Technically we could let merge_remaining_entries + * handle this, but it gets rather confused by the '.' and '..' entries + */ + for (i = 0; i < n_orig; i++) { + /* + * We can always reuse the TRANS.TBL in this particular case. + */ + contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; + + if (((contents[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) && + (i >= 2)) { + continue; + } + /* If we have a directory, don't reuse the extent number. */ + if ((contents[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) { + memset(contents[i]->isorec.extent, 0, 8); + + if (strcmp(contents[i]->name, ".") == 0) + this_dir->dir_flags |= DIR_HAS_DOT; + + if (strcmp(contents[i]->name, "..") == 0) + this_dir->dir_flags |= DIR_HAS_DOTDOT; + } + /* + * for regilar files, we do it here. + * If it has CL or RE attributes, remember its extent + */ + check_rr_relocation(contents[i]); + + /* + * Set the whole name for this file. + */ + strcpy(whole_path, this_dir->whole_name); + strcat(whole_path, SPATH_SEPARATOR); + strcat(whole_path, contents[i]->name); + + contents[i]->whole_name = strdup(whole_path); + + contents[i]->next = this_dir->contents; + contents[i]->filedir = this_dir; + this_dir->contents = contents[i]; + contents[i] = NULL; + } + + /* + * and for directories, we do it here. + * If it has CL or RE attributes, remember its extent + */ + check_rr_relocation(dpnt); + + /* + * Zero the extent number for ourselves. + */ + memset(dpnt->isorec.extent, 0, 8); + + /* + * Anything that is left are other subdirectories that need to be + * merged. + */ + merge_remaining_entries(this_dir, contents, n_orig); + free_mdinfo(contents, n_orig); +#if 0 + /* + * This is no longer required. The post-scan sort will handle all of + * this for us. + */ + sort_n_finish(this_dir); +#endif + + return (0); +} + + +char *cdrecord_data = NULL; + +int +get_session_start(int *file_addr) +{ + char *pnt; + +#ifdef CDRECORD_DETERMINES_FIRST_WRITABLE_ADDRESS + /* + * FIXME(eric). We need to coordinate with cdrecord to obtain the + * parameters. For now, we assume we are writing the 2nd session, so + * we start from the session that starts at 0. + */ + if (file_addr != NULL) + *file_addr = 16; + + /* + * We need to coordinate with cdrecord to get the next writable address + * from the device. Here is where we use it. + */ + session_start = last_extent = last_extent_written = cdrecord_result(); +#else + + if (file_addr != NULL) + *file_addr = 0L; + session_start = last_extent = last_extent_written = 0L; + if (check_session && cdrecord_data == NULL) + return (0); + + if (cdrecord_data == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Special parameters for cdrecord not specified with -C\n"); +#else + fprintf(stderr, + "Special parameters for cdrecord not specified with -C\n"); + exit(1); +#endif + } + /* + * Next try and find the ',' in there which delimits the two numbers. + */ + pnt = strchr(cdrecord_data, ','); + if (pnt == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Malformed cdrecord parameters\n"); +#else + fprintf(stderr, "Malformed cdrecord parameters\n"); + exit(1); +#endif + } + + *pnt = '\0'; + if (file_addr != NULL) { + *file_addr = atol(cdrecord_data); + } + pnt++; + + session_start = last_extent = last_extent_written = atol(pnt); + + pnt--; + *pnt = ','; + +#endif + return (0); +} + +/* + * This function scans the directory tree, looking for files, and it makes + * note of everything that is found. We also begin to construct the ISO9660 + * directory entries, so that we can determine how large each directory is. + */ +int +merge_previous_session(struct directory *this_dir, + struct iso_directory_record *mrootp, + char *reloc_root, + char *reloc_old_root) +{ + struct directory_entry **orig_contents = NULL; + struct directory_entry *odpnt = NULL; + int n_orig; + struct directory_entry *s_entry; + int status; + int lstatus; + struct stat statbuf, + lstatbuf; + int retcode; + + /* skip leading slash */ + while (reloc_old_root && reloc_old_root[0] == PATH_SEPARATOR) { + reloc_old_root++; + } + while (reloc_root && reloc_root[0] == PATH_SEPARATOR) { + reloc_root++; + } + + /* + * Parse the same directory in the image that we are merging for + * multisession stuff. + */ + orig_contents = read_merging_directory(mrootp, &n_orig); + if (orig_contents == NULL) { + if (reloc_old_root) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Reading old session failed, cannot execute -old-root.\n"); +#else + fprintf(stderr, + "Reading old session failed, cannot execute -old-root.\n"); + exit(1); +#endif + } + return (0); + } + + if (reloc_old_root && reloc_old_root[0]) { + struct directory_entry **new_orig_contents = orig_contents; + int new_n_orig = n_orig; + + /* decend until we reach the original root */ + while (reloc_old_root[0]) { + int i; + char *next; + int last; + + for (next = reloc_old_root; *next && *next != PATH_SEPARATOR; next++); + if (*next) { + last = 0; + *next = 0; + next++; + } else { + last = 1; + } + while (*next == PATH_SEPARATOR) { + next++; + } + + for (i = 0; i < new_n_orig; i++) { + struct iso_directory_record subroot; + + if (new_orig_contents[i]->name != NULL && + strcmp(new_orig_contents[i]->name, reloc_old_root) != 0) { + /* Not the same name continue */ + continue; + } + /* + * enter directory, free old one only if not the top level, + * which is still needed + */ + subroot = new_orig_contents[i]->isorec; + if (new_orig_contents != orig_contents) { + free_mdinfo(new_orig_contents, new_n_orig); + } + new_orig_contents = read_merging_directory(&subroot, &new_n_orig); + + if (!new_orig_contents) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Reading directory %s in old session failed, cannot execute -old-root.\n", + reloc_old_root); +#else + fprintf(stderr, + "Reading directory %s in old session failed, cannot execute -old-root.\n", + reloc_old_root); + exit(1); +#endif + } + i = -1; + break; + } + + if (i == new_n_orig) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "-old-root (sub)directory %s not found in old session.\n", + reloc_old_root); +#else + fprintf(stderr, + "-old-root (sub)directory %s not found in old session.\n", + reloc_old_root); + exit(1); +#endif + } + + /* restore string, proceed to next sub directory */ + if (!last) { + reloc_old_root[strlen(reloc_old_root)] = PATH_SEPARATOR; + } + reloc_old_root = next; + } + + /* + * preserve the old session, skipping those dirs/files that are found again + * in the new root + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + status = stat_filter(s_entry->whole_name, &statbuf); + lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); + + /* + * check_prev_session() will search for s_entry and remove it from + * orig_contents if found + */ + retcode = check_prev_session(orig_contents, n_orig, s_entry, + &statbuf, &lstatbuf, NULL); + if (retcode == -1) + return (-1); + } + merge_remaining_entries(this_dir, orig_contents, n_orig); + + /* use new directory */ + free_mdinfo(orig_contents, n_orig); + orig_contents = new_orig_contents; + n_orig = new_n_orig; + + if (reloc_root && reloc_root[0]) { + /* also decend into new root before searching for files */ + this_dir = find_or_create_directory(this_dir, reloc_root, NULL, TRUE, NULL); + if (!this_dir) { + return (-1); + } + } + } + + + /* + * Now we scan the directory itself, and look at what is inside of it. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + status = stat_filter(s_entry->whole_name, &statbuf); + lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); + + /* + * We always should create an entirely new directory tree + * whenever we generate a new session, unless there were + * *no* changes whatsoever to any of the directories, in which + * case it would be kind of pointless to generate a new + * session. + * I believe it is possible to rigorously prove that any change + * anywhere in the filesystem will force the entire tree to be + * regenerated because the modified directory will get a new + * extent number. Since each subdirectory of the changed + * directory has a '..' entry, all of them will need to be + * rewritten too, and since the parent directory of the + * modified directory will have an extent pointer to the + * directory it too will need to be rewritten. Thus we will + * never be able to reuse any directory information when + * writing new sessions. + * + * We still check the previous session so we can mark off the + * equivalent entry in the list we got from the original disc, + * however. + */ + + /* + * The check_prev_session function looks for an identical + * entry in the previous session. If we see it, then we copy + * the extent number to s_entry, and cross it off the list. + * It returns 2 if it's a directory + */ + retcode = check_prev_session(orig_contents, n_orig, s_entry, + &statbuf, &lstatbuf, &odpnt); + if (retcode == -1) + return (-1); + + if (retcode == 2 && odpnt != NULL) { + int dflag; + + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { + struct directory *child; + + /* + * XXX It seems that the tree that has been + * XXX read from the previous session does not + * XXX carry whole_name entries. We provide a + * XXX hack in + * XXX multi.c:find_or_create_directory() + * XXX that should be removed when a + * XXX reasonable method could be found. + */ + child = find_or_create_directory(this_dir, + s_entry->whole_name, + s_entry, 1, NULL); + dflag = merge_previous_session(child, + &odpnt->isorec, + NULL, reloc_old_root); + if (dflag == -1) { + return (-1); + } + free(odpnt); + odpnt = NULL; + } + } + } + + if (!reloc_old_root) { + /* + * Whatever is left over, are things which are no longer in the tree on + * disk. We need to also merge these into the tree. + */ + merge_remaining_entries(this_dir, orig_contents, n_orig); + } + free_mdinfo(orig_contents, n_orig); + return (1); +} + +/* + * This code deals with relocated directories which may exist + * in the previous session. + */ +struct dir_extent_link { + unsigned int extent; + struct directory_entry *de; + struct dir_extent_link *next; +}; + +static struct dir_extent_link *cl_dirs = NULL; +static struct dir_extent_link *re_dirs = NULL; + +static void +check_rr_relocation(struct directory_entry *de) +{ + unsigned char sector[SECTOR_SIZE]; + unsigned char *pnt = de->rr_attributes; + int len = de->rr_attr_size; + int cont_extent = 0, + cont_offset = 0, + cont_size = 0; + + pnt = parse_xa(pnt, &len, /* dpnt */ 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]); +#endif + } + if (strncmp((char *) pnt, "CL", 2) == 0) { + struct dir_extent_link *dlink = e_malloc(sizeof (*dlink)); + + dlink->extent = isonum_733(pnt + 4); + dlink->de = de; + dlink->next = cl_dirs; + cl_dirs = dlink; + + } else if (strncmp((char *) pnt, "RE", 2) == 0) { + struct dir_extent_link *dlink = e_malloc(sizeof (*dlink)); + + dlink->extent = de->starting_block; + dlink->de = de; + dlink->next = re_dirs; + re_dirs = dlink; + + } else if (strncmp((char *) pnt, "CE", 2) == 0) { + cont_extent = isonum_733(pnt + 4); + cont_offset = isonum_733(pnt + 12); + cont_size = isonum_733(pnt + 20); + + } else if (strncmp((char *) pnt, "ST", 2) == 0) { + len = pnt[2]; + } + len -= pnt[2]; + pnt += pnt[2]; + if (len <= 3 && cont_extent) { + /* ??? What if cont_offset+cont_size > SECTOR_SIZE */ + readsecs(cont_extent, sector, 1); + pnt = sector + cont_offset; + len = cont_size; + cont_extent = cont_offset = cont_size = 0; + } + } + +} + +void +match_cl_re_entries() +{ + struct dir_extent_link *re = re_dirs; + + /* for each relocated directory */ + for (; re; re = re->next) { + struct dir_extent_link *cl = cl_dirs; + + for (; cl; cl = cl->next) { + /* find a place where it was relocated from */ + if (cl->extent == re->extent) { + /* set link to that place */ + re->de->parent_rec = cl->de; + re->de->filedir = cl->de->filedir; + + /* + * see if it is in rr_moved + */ + if (reloc_dir != NULL) { + struct directory_entry *rr_moved_e = reloc_dir->contents; + + for (; rr_moved_e; rr_moved_e = rr_moved_e->next) { + /* yes it is */ + if (re->de == rr_moved_e) { + /* forget it */ + re->de = NULL; + } + } + } + break; + } + } + } +} + +void +finish_cl_pl_for_prev_session() +{ + struct dir_extent_link *re = re_dirs; + + /* for those that were relocated, but NOT to rr_moved */ + re = re_dirs; + for (; re; re = re->next) { + if (re->de != NULL) { + /* + * here we have hypothetical case when previous session + * was not created by genisoimage and contains relocations + */ + struct directory_entry *s_entry = re->de; + struct directory_entry *s_entry1; + struct directory *d_entry = reloc_dir->subdir; + + /* do the same as finish_cl_pl_entries */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + continue; + } + while (d_entry) { + if (d_entry->self == s_entry) + break; + d_entry = d_entry->next; + } + if (!d_entry) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Unable to locate directory parent\n"); +#else + fprintf(stderr, "Unable to locate directory parent\n"); + exit(1); +#endif + } + + if (s_entry->filedir != NULL && s_entry->parent_rec != NULL) { + char *rr_attr; + + /* + * First fix the PL pointer in the directory in the + * rr_reloc dir + */ + s_entry1 = d_entry->contents->next; + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "PL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, s_entry->filedir->extent); + + /* Now fix the CL pointer */ + s_entry1 = s_entry->parent_rec; + + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "CL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, d_entry->extent); + } + } + } + /* free memory */ + re = re_dirs; + while (re) { + struct dir_extent_link *next = re->next; + + free(re); + re = next; + } + re = cl_dirs; + while (re) { + struct dir_extent_link *next = re->next; + + free(re); + re = next; + } +} diff --git a/genisoimage/name.c b/genisoimage/name.c new file mode 100644 index 0000000..c2faeb6 --- /dev/null +++ b/genisoimage/name.c @@ -0,0 +1,531 @@ +/* + * 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. + * + */ + +/* @(#)name.c 1.28 04/03/05 joerg */ +/* + * File name.c - map full Unix file names to unique 8.3 names that + * would be valid on DOS. + * + * + * Written by Eric Youngdale (1993). + * Almost totally rewritten by J. Schilling (2000). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <standard.h> +#include <schily.h> +#include <ctype.h> + +void iso9660_check(struct iso_directory_record *idr, + struct directory_entry *ndr); +int iso9660_file_length(const char *name, + struct directory_entry *sresult, + int dirflag); + +void +iso9660_check(struct iso_directory_record *idr, + struct directory_entry *ndr) +{ + int nlen; + char schar; + char *p; + char *np; + + nlen = idr->name_len[0]; + schar = idr->name[nlen]; + + if (nlen == 1 && (idr->name[0] == '\0' || idr->name[0] == '\001')) + return; + + idr->name[nlen] = '\0'; /* Make it null terminated */ + if ((p = strrchr(idr->name, ';')) != NULL) { + *p = '\0'; /* Strip off old version # */ + } + iso9660_file_length(idr->name, ndr, + (idr->flags[0] & ISO_DIRECTORY) != 0); + + if ((np = strrchr(ndr->isorec.name, ';')) != NULL) { + *np = '\0'; /* Strip off new version # */ + } + if (strcmp(idr->name, ndr->isorec.name)) { + if (p) + *p = ';'; /* Restore old version # */ + if (np) + *np = ';'; /* Restore new version # */ + errmsgno(EX_BAD, + "Old session has illegal name '%.*s' length %d\n", + idr->name_len[0], + idr->name, + idr->name_len[0]); + errmsgno(EX_BAD, + "New session will use name '%s'\n", + ndr->isorec.name); + } + if (p) + *p = ';'; /* Restore old version # */ + if (np) + *np = ';'; /* Restore new version # */ + idr->name[nlen] = schar; /* Restore old iso record*/ +} + +/* + * Function: iso9660_file_length + * + * Purpose: Map file name to 8.3 format, return length + * of result. + * + * Arguments: name file name we need to map. + * sresult directory entry structure to contain mapped name. + * dirflag flag indicating whether this is a directory or not. + * + * Note: name being const * is a bug introduced by Eric but hard to + * fix without going through the whole source. + */ +int +iso9660_file_length(const char *name /* Not really const !!! */, + struct directory_entry *sresult, int dirflag) +{ + char c; + char *cp; + int before_dot = 8; + int after_dot = 3; + int chars_after_dot = 0; + int chars_before_dot = 0; + int current_length = 0; + int extra = 0; + int ignore = 0; + char *last_dot; + const char *pnt; + int priority = 32767; + char *result; + int ochars_after_dot; + int ochars_before_dot; + int seen_dot = 0; + int seen_semic = 0; + int tildes = 0; + + result = sresult->isorec.name; + + if (sresult->priority) + priority = sresult->priority; + + /* + * For the '.' entry, generate the correct record, and return 1 for + * the length. + */ + if (strcmp(name, ".") == 0) { + *result = 0; + return (1); + } + /* + * For the '..' entry, generate the correct record, and return 1 + * for the length. + */ + if (strcmp(name, "..") == 0) { + *result++ = 1; + *result++ = 0; + return (1); + } + /* + * Now scan the directory one character at a time, and figure out + * what to do. + */ + pnt = name; + + /* + * Find the '.' that we intend to use for the extension. + * Usually this is the last dot, but if we have . followed by nothing + * or a ~, we would consider this to be unsatisfactory, and we keep + * searching. + */ + last_dot = strrchr(pnt, '.'); + if ((last_dot != NULL) && + ((last_dot[1] == '~') || (last_dot[1] == '\0'))) { + cp = last_dot; + *cp = '\0'; + last_dot = strrchr(pnt, '.'); + *cp = '.'; + /* + * If we found no better '.' back up to the last match. + */ + if (last_dot == NULL) + last_dot = cp; + } + + if (last_dot != NULL) { + ochars_after_dot = strlen(last_dot); /* dot counts */ + ochars_before_dot = last_dot - pnt; + } else { + ochars_before_dot = 128; + ochars_after_dot = 0; + } + /* + * If we have full names, the names we generate will not work + * on a DOS machine, since they are not guaranteed to be 8.3. + * Nonetheless, in many cases this is a useful option. We + * still only allow one '.' character in the name, however. + */ + if (full_iso9660_filenames || iso9660_level > 1) { + before_dot = iso9660_namelen; + after_dot = before_dot - 1; + + if (!dirflag) { + if (ochars_after_dot > ((iso9660_namelen/2)+1)) { + /* + * The minimum number of characters before + * the dot is 3 to allow renaming. + * Let us allow to have 15 characters after + * dot to give more rational filenames. + */ + before_dot = iso9660_namelen/2; + after_dot = ochars_after_dot; + } else { + before_dot -= ochars_after_dot; /* dot counts */ + after_dot = ochars_after_dot; + } + } + } + + while (*pnt) { +#ifdef VMS + if (strcmp(pnt, ".DIR;1") == 0) { + break; + } +#endif + +#ifdef Eric_code_does_not_work + /* + * XXX If we make this code active we get corrupted direcrory + * XXX trees with infinite loops. + */ + /* + * This character indicates a Unix style of backup file + * generated by some editors. Lower the priority of the file. + */ + if (iso_translate && *pnt == '#') { + priority = 1; + pnt++; + continue; + } + /* + * This character indicates a Unix style of backup file + * generated by some editors. Lower the priority of the file. + */ + if (iso_translate && *pnt == '~') { + priority = 1; + tildes++; + pnt++; + continue; + } +#endif + /* + * This might come up if we had some joker already try and put + * iso9660 version numbers into the file names. This would be + * a silly thing to do on a Unix box, but we check for it + * anyways. If we see this, then we don't have to add our own + * version number at the end. UNLESS the ';' is part of the + * filename and no valid version number is following. + */ + if (use_fileversion && *pnt == ';' && seen_dot) { + /* + * Check if a valid version number follows. + * The maximum valid version number is 32767. + */ + for (c = 1, cp = (char *)&pnt[1]; c < 6 && *cp; c++, cp++) { + if (*cp < '0' || *cp > '9') + break; + } + if (c <= 6 && *cp == '\0' && atoi(&pnt[1]) <= 32767) + seen_semic++; + } + /* + * If we have a name with multiple '.' characters, we ignore + * everything after we have gotten the extension. + */ + if (ignore) { + pnt++; + continue; + } + if (current_length >= iso9660_namelen) { +#ifdef nono + /* + * Does not work as we may truncate before the dot. + */ + fprintf(stderr, "Truncating '%s' to '%.*s'.\n", + name, + current_length, sresult->isorec.name); + ignore++; +#endif + pnt++; + continue; + } + /* Spin past any iso9660 version number we might have. */ + if (seen_semic) { + if (seen_semic == 1) { + seen_semic++; + *result++ = ';'; + } + if (*pnt >= '0' && *pnt <= '9') { + *result++ = *pnt; + } + extra++; + pnt++; + continue; + } + + if (*pnt == '.') { + if (!allow_multidot) { + if (strcmp(pnt, ".tar.gz") == 0) + pnt = last_dot = ".tgz"; + if (strcmp(pnt, ".ps.gz") == 0) + pnt = last_dot = ".psz"; + } + + if (!chars_before_dot && !allow_leading_dots) { + /* + * DOS can't read files with dot first + */ + chars_before_dot++; + *result++ = '_'; /* Substitute underscore */ + + } else if (pnt == last_dot) { + if (seen_dot) { + ignore++; + continue; + } + *result++ = '.'; + seen_dot++; + } else if (allow_multidot) { + if (chars_before_dot < before_dot) { + chars_before_dot++; + *result++ = '.'; + } + } else { + /* + * If this isn't the dot that we use + * for the extension, then change the + * character into a '_' instead. + */ + if (chars_before_dot < before_dot) { + chars_before_dot++; + *result++ = '_'; + } + } + } else { + if ((seen_dot && (chars_after_dot < after_dot) && + ++chars_after_dot) || + (!seen_dot && (chars_before_dot < before_dot) && + ++chars_before_dot)) { + + c = *pnt; + if (c & 0x80) { + /* + * We allow 8 bit chars if -iso-level + * is at least 4 + * + * XXX We should check if the output + * XXX character set is a 7 Bit ASCI + * extension. + */ + if (iso9660_level >= 4) { + c = conv_charset(c, in_nls, out_nls); + } else { + c = '_'; + } + } else if (!allow_lowercase) { + c = islower((unsigned char)c) ? + toupper((unsigned char)c) : c; + } + if (relaxed_filenames) { + /* + * Here we allow a more relaxed syntax. + */ + if (c == '/') + c = '_'; + *result++ = c; + } else switch (c) { + /* + * Dos style filenames. + * We really restrict the names here. + */ + + default: + *result++ = c; + break; + + /* + * Descriptions of DOS's 'Parse Filename' + * (function 29H) describes V1 and V2.0+ + * separator and terminator characters. These + * characters in a DOS name make the file + * visible but un-manipulable (all useful + * operations error off. + */ + /* separators */ + case '+': + case '=': + case '%': /* not legal DOS */ + /* filename */ + case ':': + case ';': /* already handled */ + case '.': /* already handled */ + case ',': /* already handled */ + case '\t': + case ' ': + /* V1 only separators */ + case '/': + case '"': + case '[': + case ']': + /* terminators */ + case '>': + case '<': + case '|': + /* + * Other characters that are not valid ISO-9660 + * characters. + */ + case '!': +/* case '#':*/ + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': +/* case '-':*/ + case '?': + case '@': + case '\\': + case '^': + case '`': + case '{': + case '}': +/* case '~':*/ + /* + * All characters below 32 (space) are not + * allowed too. + */ + case 1: case 2: case 3: case 4: + case 5: case 6: case 7: case 8: + /* case 9: */ + case 10: case 11: case 12: + case 13: case 14: case 15: + case 16: case 17: case 18: + case 19: case 20: case 21: + case 22: case 23: case 24: + case 25: case 26: case 27: + case 28: case 29: case 30: + case 31: + + /* + * Hmm - what to do here? Skip? Win95 + * looks like it substitutes '_' + */ + *result++ = '_'; + break; + + case '#': + case '-': + case '~': + /* + * Check if we should allow these + * illegal characters used by + * Microsoft. + */ + if (iso_translate) + *result++ = '_'; + else + *result++ = c; + break; + } /* switch (*pnt) */ + } else { /* if (chars_{after,before}_dot) ... */ + pnt++; + continue; + } + } /* else *pnt == '.' */ + current_length++; + pnt++; + } /* while (*pnt) */ + + /* + * OK, that wraps up the scan of the name. Now tidy up a few other + * things. + * Look for emacs style of numbered backups, like foo.c.~3~. If we + * see this, convert the version number into the priority number. + * In case of name conflicts, this is what would end up being used as + * the 'extension'. + */ + if (tildes == 2) { + int prio1 = 0; + + pnt = name; + while (*pnt && *pnt != '~') { + pnt++; + } + if (*pnt) { + pnt++; + } + while (*pnt && *pnt != '~') { + prio1 = 10 * prio1 + *pnt - '0'; + pnt++; + } + priority = prio1; + } + /* + * If this is not a directory, force a '.' in case we haven't seen one, + * and add a version number if we haven't seen one of those either. + */ + if (!dirflag) { + if (!seen_dot && !omit_period) { + if (chars_before_dot >= (iso9660_namelen-1)) { + chars_before_dot--; + result--; + } + *result++ = '.'; + extra++; + } + if (!omit_version_number && !seen_semic) { + *result++ = ';'; + *result++ = '1'; + extra += 2; + } + } + *result++ = 0; + sresult->priority = priority; + +/*#define DEBBUG*/ +#ifdef DEBBUG + fprintf(stderr, "NAME: '%s'\n", sresult->isorec.name); + fprintf(stderr, "chars_before_dot %d chars_after_dot %d seen_dot %d extra %d\n", + chars_before_dot, chars_after_dot, seen_dot, extra); +#endif + return (chars_before_dot + chars_after_dot + seen_dot + extra); +} diff --git a/genisoimage/rock.c b/genisoimage/rock.c new file mode 100644 index 0000000..7565bae --- /dev/null +++ b/genisoimage/rock.c @@ -0,0 +1,864 @@ +/* + * 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. + * + */ + +/* @(#)rock.c 1.43 05/05/01 joerg */ +/* + * File rock.c - generate RRIP records for iso9660 filesystems. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2003 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <device.h> +#include <schily.h> + +#define SU_VERSION 1 + +#define SL_ROOT 8 +#define SL_PARENT 4 +#define SL_CURRENT 2 +#define SL_CONTINUE 1 + +#define CE_SIZE 28 /* SUSP Continuation aerea */ +#define CL_SIZE 12 /* RR Child Link for deep dir relocation */ +#define ER_SIZE 8 /* RR Extension record for RR signature */ +#define NM_SIZE 5 /* RR Real name */ +#define PL_SIZE 12 /* RR Paren Link for deep dir relocation */ +#define PN_SIZE 20 /* RR POSIX device modes (Major/Minor) */ +#define PX_SIZE 36 /* RR POSIX Extensions (mode/nlink(uid/gid) */ +#define RE_SIZE 4 /* RR Relocated directory */ +#define RR_SIZE 5 /* RR RR Signature in every file */ +#define SL_SIZE 20 /* RR Symlink */ +#define ZF_SIZE 16 /* RR* Linux compression extension */ +#ifdef APPLE_HYB +#define AA_SIZE 14 /* size of Apple extension */ +#endif /* APPLE_HYB */ +#if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */ +#define TF_SIZE (5 + 4 * 7) /* RR Time field */ +#else +#define TF_SIZE (5 + 3 * 7) +#endif + +static void rstrncpy(char *t, char *f, int c, + struct unls_table *inls, + struct unls_table *onls); +static void add_CE_entry(char *field, int line); +static int gen_xa_attr(mode_t attr); +static void gen_xa(struct stat *lstatbuf); +int generate_xa_rr_attributes(char *whole_name, char *name, + struct directory_entry *s_entry, + struct stat *statbuf, + struct stat *lstatbuf, + int deep_opt); +char *generate_rr_extension_record(char *id, char *descriptor, char *source, + int *size); +/* + * If we need to store this number of bytes, make sure we + * do not box ourselves in so that we do not have room for + * a CE entry for the continuation record + */ +#define RR_CUR_USE (CE_SIZE + currlen + (ipnt - recstart)) + +#define MAYBE_ADD_CE_ENTRY(BYTES) \ + (((int)(BYTES)) + CE_SIZE + currlen + (ipnt - recstart) > reclimit ? 1 : 0) + +/* + * Buffer to build RR attributes + */ +static Uchar Rock[16384]; +static Uchar symlink_buff[PATH_MAX+1]; +static int ipnt = 0; /* Current "write" offset in Rock[] */ +static int recstart = 0; /* Start offset in Rock[] for this area */ +static int currlen = 0; /* # of non RR bytes used in this area */ +static int mainrec = 0; /* # of RR bytes use in main dir area */ +static int reclimit; /* Max. # of bytes usable in this area */ + +/* if we are using converted filenames, we don't want the '/' character */ +static void +rstrncpy(char *t, char *f, int c, struct unls_table *inls, + struct unls_table *onls) +{ + while (c-- && *f) { + *t = conv_charset(*f, inls, onls); + if (*t == '/') { + *t = '_'; + } + t++; + f++; + } +} + +static void +add_CE_entry(char *field, int line) +{ + if (MAYBE_ADD_CE_ENTRY(0)) { + errmsgno(EX_BAD, + "Panic: no space, cannot add RR CE entry (%d bytes mising) for %s line %d.\n", + (CE_SIZE + currlen + (ipnt - recstart) - reclimit), + field, line); + errmsgno(EX_BAD, "currlen: %d ipnt: %d, recstart: %d\n", + currlen, ipnt, recstart); + errmsgno(EX_BAD, "Send bug report to the maintainer.\n"); + comerrno(EX_BAD, "Aborting.\n"); + } + + if (recstart) + set_733((char *) Rock + recstart - 8, ipnt + 28 - recstart); + Rock[ipnt++] = 'C'; + Rock[ipnt++] = 'E'; + Rock[ipnt++] = CE_SIZE; + Rock[ipnt++] = SU_VERSION; + set_733((char *) Rock + ipnt, 0); + ipnt += 8; + set_733((char *) Rock + ipnt, 0); + ipnt += 8; + set_733((char *) Rock + ipnt, 0); + ipnt += 8; + recstart = ipnt; + currlen = 0; + if (!mainrec) + mainrec = ipnt; + reclimit = SECTOR_SIZE - 8; /* Limit to one sector */ +} + +static int +gen_xa_attr(mode_t attr) +{ + int ret = 0; + + if (attr & S_IRUSR) + ret |= XA_O_READ; + if (attr & S_IXUSR) + ret |= XA_O_EXEC; + + if (attr & S_IRGRP) + ret |= XA_G_READ; + if (attr & S_IXGRP) + ret |= XA_G_EXEC; + + if (attr & S_IROTH) + ret |= XA_W_READ; + if (attr & S_IXOTH) + ret |= XA_W_EXEC; + + ret |= XA_FORM1; + + if (S_ISDIR(attr)) + ret |= XA_DIR; + + return (ret); +} + +static void +gen_xa(struct stat *lstatbuf) +{ + /* + * Group ID + */ + set_722((char *) Rock + ipnt, lstatbuf->st_gid); + ipnt += 2; + /* + * User ID + */ + set_722((char *) Rock + ipnt, lstatbuf->st_uid); + ipnt += 2; + /* + * Attributes + */ + set_722((char *) Rock + ipnt, gen_xa_attr(lstatbuf->st_mode)); + ipnt += 2; + + Rock[ipnt++] = 'X'; /* XA Signature */ + Rock[ipnt++] = 'A'; + Rock[ipnt++] = 0; /* File number (we always use '0' */ + + Rock[ipnt++] = 0; /* Reserved (5 Byte) */ + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; + Rock[ipnt++] = 0; + +} + +int +generate_xa_rr_attributes(char *whole_name, char *name, + struct directory_entry *s_entry, + struct stat *statbuf, + struct stat *lstatbuf, + int deep_opt) +{ + int flagpos; + int flagval; + int need_ce; + + statbuf = statbuf; /* this shuts up unreferenced compiler */ + /* warnings */ + mainrec = recstart = ipnt = 0; + + if (use_XA) { + gen_xa(lstatbuf); + } + +/* reclimit = 0xf8; XXX we now use 254 == 0xfe */ + reclimit = MAX_ISODIR; + + /* no need to fill in the RR stuff if we won't see the file */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + return (0); + + /* + * Obtain the amount of space that is currently used for the directory + * record. We may safely use the current name length; because if name + * confilcts force us to change the ISO-9660 name later, the name will + * never become longer than now. + */ + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + s_entry->isorec.name_len[0] = 1; + } else { + s_entry->isorec.name_len[0] = strlen(s_entry->isorec.name); + } + currlen = s_entry->isorec.length[0] = s_entry->isorec.name_len[0] + + offsetof(struct iso_directory_record, name[0]); + if (currlen & 1) + s_entry->isorec.length[0] = ++currlen; + + if (currlen < 33+37) { + /* + * If the ISO-9660 name length is less than 37, we may use + * ISO-9660:1988 name rules and for this reason, the name len + * may later increase from adding e.g. ".;1"; in this case + * just use the upper limit. + */ + currlen = 33+37; + } + +#ifdef APPLE_HYB + /* if we have regular file, then add Apple extensions */ + if (S_ISREG(lstatbuf->st_mode) && apple_ext && s_entry->hfs_ent) { + if (MAYBE_ADD_CE_ENTRY(AA_SIZE)) + add_CE_entry("AA", __LINE__); + Rock[ipnt++] = 'A'; /* AppleSignature */ + Rock[ipnt++] = 'A'; + Rock[ipnt++] = AA_SIZE; /* includes AppleSignature bytes */ + Rock[ipnt++] = 0x02; /* SystemUseID */ + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[0]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[1]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[2]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.type[3]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[0]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[1]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[2]; + Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[3]; + Rock[ipnt++] = (s_entry->hfs_ent->fdflags >> 8) & 0xff; + Rock[ipnt++] = s_entry->hfs_ent->fdflags & 0xff; + } +#endif /* APPLE_HYB */ + + if (!use_RockRidge) + goto xa_only; + + /* Identify that we are using the SUSP protocol */ + if (deep_opt & NEED_SP) { + /* + * We may not use a CE record here but we never will need to + * do so, as this SP record is only used for the "." entry + * of the root directory. + */ + Rock[ipnt++] = 'S'; + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 7; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = 0xbe; + Rock[ipnt++] = 0xef; + if (use_XA) + Rock[ipnt++] = sizeof (struct iso_xa_dir_record); + else + Rock[ipnt++] = 0; + } + + /* First build the posix name field */ + if (MAYBE_ADD_CE_ENTRY(RR_SIZE)) + add_CE_entry("RR", __LINE__); + Rock[ipnt++] = 'R'; + Rock[ipnt++] = 'R'; + Rock[ipnt++] = 5; + Rock[ipnt++] = SU_VERSION; + flagpos = ipnt; + flagval = 0; + Rock[ipnt++] = 0; /* We go back and fix this later */ + + if (strcmp(name, ".") && strcmp(name, "..")) { + char *npnt; + int remain; /* Remaining name length */ + int use; /* Current name part used */ + +#ifdef APPLE_HYB + /* use the HFS name if it exists */ + if (USE_MAC_NAME(s_entry)) { + remain = strlen(s_entry->hfs_ent->name); + npnt = s_entry->hfs_ent->name; + } else { +#endif /* APPLE_HYB */ + + remain = strlen(name); + npnt = name; +#ifdef APPLE_HYB + } +#endif /* APPLE_HYB */ + + if (MAYBE_ADD_CE_ENTRY(NM_SIZE+1)) + add_CE_entry("NM", __LINE__); + while (remain) { + use = remain; + need_ce = 0; + /* Can we fit this SUSP and a CE entry? */ + if (MAYBE_ADD_CE_ENTRY(NM_SIZE+use)) { + use = reclimit - NM_SIZE - RR_CUR_USE; + need_ce++; + } + /* Only room for 256 per SUSP field */ + if (use > 0xf8) { + use = 0xf8; + need_ce++; + } + if (use < 0) { + comerrno(EX_BAD, + "Negative RR name length residual: %d\n", + use); + } + + /* First build the posix name field */ + Rock[ipnt++] = 'N'; + Rock[ipnt++] = 'M'; + Rock[ipnt++] = NM_SIZE + use; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = (remain != use ? 1 : 0); + flagval |= (1 << 3); + + /* convert charsets as required */ +#ifdef APPLE_HYB + if (USE_MAC_NAME(s_entry)) + rstrncpy((char *) &Rock[ipnt], npnt, use, + hfs_inls, out_nls); + else +#endif /* APPLE_HYB */ + rstrncpy((char *) &Rock[ipnt], npnt, use, + in_nls, out_nls); + npnt += use; + ipnt += use; + remain -= use; + if (remain && need_ce) + add_CE_entry("NM", __LINE__); + } + } + + /* Add the posix modes */ + if (MAYBE_ADD_CE_ENTRY(PX_SIZE)) + add_CE_entry("PX", __LINE__); + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 'X'; + Rock[ipnt++] = PX_SIZE; + Rock[ipnt++] = SU_VERSION; + flagval |= (1 << 0); + set_733((char *) Rock + ipnt, lstatbuf->st_mode); + ipnt += 8; + set_733((char *) Rock + ipnt, lstatbuf->st_nlink); + ipnt += 8; + set_733((char *) Rock + ipnt, lstatbuf->st_uid); + ipnt += 8; + set_733((char *) Rock + ipnt, lstatbuf->st_gid); + ipnt += 8; + + /* Check for special devices */ +#if defined(S_IFCHR) || defined(S_IFBLK) + /* + * The code in this if statement used to be #ifdef'd with NON_UNIXFS. + * But as statdefs.h always provides the macros S_ISCHR() & S_ISBLK() + * and device.h always provides major()/minor() it is not needed + * anymore. + */ + if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { + if (MAYBE_ADD_CE_ENTRY(PN_SIZE)) + add_CE_entry("PN", __LINE__); + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 'N'; + Rock[ipnt++] = PN_SIZE; + Rock[ipnt++] = SU_VERSION; + flagval |= (1 << 1); +#if 1 + /* This is the new and only code which uses <device.h> */ + set_733((char *) Rock + ipnt, major(lstatbuf->st_rdev)); + ipnt += 8; + set_733((char *) Rock + ipnt, minor(lstatbuf->st_rdev)); + ipnt += 8; +#else + /* + * If we don't have sysmacros.h, then we have to guess as to + * how best to pick apart the device number for major/minor. + * Note: this may very well be wrong for many systems, so it + * is always best to use the major/minor macros if the system + * supports it. + */ + if (sizeof (dev_t) <= 2) { + set_733((char *)Rock + ipnt, (lstatbuf->st_rdev >> 8)); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_rdev & 0xff); + ipnt += 8; + } else if (sizeof (dev_t) <= 4) { + set_733((char *)Rock + ipnt, + (lstatbuf->st_rdev >> 8) >> 8); + ipnt += 8; + set_733((char *)Rock + ipnt, + lstatbuf->st_rdev & 0xffff); + ipnt += 8; + } else { + set_733((char *)Rock + ipnt, + (lstatbuf->st_rdev >> 16)>>16); + ipnt += 8; + set_733((char *)Rock + ipnt, lstatbuf->st_rdev); + ipnt += 8; + } +#endif + } +#endif /* defined(S_IFCHR) || defined(S_IFBLK) */ + + /* Check for and symbolic links. VMS does not have these. */ +#ifdef S_IFLNK + if (S_ISLNK(lstatbuf->st_mode)) { + int lenpos; + int lenval; + int j0; + int j1; + int nchar; + Uchar *cpnt; + Uchar *cpnt1; + +#ifdef HAVE_READLINK + nchar = readlink(whole_name, (char *)symlink_buff, + sizeof (symlink_buff)-1); +#else + nchar = -1; +#endif /* HAVE_READLINK */ + symlink_buff[nchar < 0 ? 0 : nchar] = 0; + nchar = strlen((char *) symlink_buff); + set_733(s_entry->isorec.size, 0); + cpnt = &symlink_buff[0]; + flagval |= (1 << 2); + + if (!split_SL_field) { + int sl_bytes = 0; + + for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) { + if (*cpnt1 == '/') { + sl_bytes += 4; + } else { + sl_bytes += 1; + } + } + if (sl_bytes > 250) { + /* + * the symbolic link won't fit into one + * SL System Use Field print an error message + * and continue with splited one + */ + fprintf(stderr, + "symbolic link ``%s'' to long for one SL System Use Field, splitting", + cpnt); + } + if (MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) + add_CE_entry("SL+", __LINE__); + } + while (nchar) { + if (MAYBE_ADD_CE_ENTRY(SL_SIZE)) + add_CE_entry("SL", __LINE__); + Rock[ipnt++] = 'S'; + Rock[ipnt++] = 'L'; + lenpos = ipnt; + Rock[ipnt++] = SL_SIZE; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = 0; /* Flags */ + lenval = 5; + while (*cpnt) { + cpnt1 = (Uchar *) + strchr((char *)cpnt, '/'); + if (cpnt1) { + nchar--; + *cpnt1 = 0; + } + + /* + * We treat certain components in a special + * way. + */ + if (cpnt[0] == '.' && cpnt[1] == '.' && + cpnt[2] == 0) { + if (MAYBE_ADD_CE_ENTRY(2)) { + add_CE_entry("SL-parent", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + Rock[ipnt++] = SL_PARENT; + Rock[ipnt++] = 0; /* length is zero */ + lenval += 2; + nchar -= 2; + } else if (cpnt[0] == '.' && cpnt[1] == 0) { + if (MAYBE_ADD_CE_ENTRY(2)) { + add_CE_entry("SL-current", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + Rock[ipnt++] = SL_CURRENT; + Rock[ipnt++] = 0; /* length is zero */ + lenval += 2; + nchar -= 1; + } else if (cpnt[0] == 0) { + if (MAYBE_ADD_CE_ENTRY(2)) { + add_CE_entry("SL-root", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + Rock[ipnt++] = SL_ROOT; + Rock[ipnt++] = 0; /* length is zero */ + lenval += 2; + } else { + /* + * If we do not have enough room for a + * component, start a new continuations + * segment now + */ + if (split_SL_component ? + MAYBE_ADD_CE_ENTRY(6) : + MAYBE_ADD_CE_ENTRY(6 + strlen((char *) cpnt))) { + add_CE_entry("SL++", __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so that we + * can restart properly + */ + cpnt1 = NULL; + } + break; + } + j0 = strlen((char *) cpnt); + while (j0) { + j1 = j0; + if (j1 > 0xf8) + j1 = 0xf8; + need_ce = 0; + if (j1 + currlen + 2 + CE_SIZE + + (ipnt - recstart) > + reclimit) { + + j1 = reclimit - + (currlen + 2) - + CE_SIZE - + (ipnt - recstart); + need_ce++; + } + Rock[ipnt++] = + (j1 != j0 ? + SL_CONTINUE : 0); + Rock[ipnt++] = j1; + strncpy((char *)Rock + ipnt, + (char *) cpnt, j1); + ipnt += j1; + lenval += j1 + 2; + cpnt += j1; + /* + * Number we processed + * this time + */ + nchar -= j1; + j0 -= j1; + if (need_ce) { + add_CE_entry( + "SL-path-split", + __LINE__); + if (cpnt1) { + *cpnt1 = '/'; + nchar++; + /* + * A kluge so + * that we can + * restart + * properly + */ + cpnt1 = NULL; + } + break; + } + } + } + if (cpnt1) { + cpnt = cpnt1 + 1; + } else + break; + } + Rock[lenpos] = lenval; + if (nchar) { + /* We need another SL entry */ + Rock[lenpos + 2] = SL_CONTINUE; + } + } /* while nchar */ + } /* Is a symbolic link */ +#endif /* S_IFLNK */ + + /* Add in the Rock Ridge TF time field */ + if (MAYBE_ADD_CE_ENTRY(TF_SIZE)) + add_CE_entry("TF", __LINE__); + Rock[ipnt++] = 'T'; + Rock[ipnt++] = 'F'; + Rock[ipnt++] = TF_SIZE; + Rock[ipnt++] = SU_VERSION; +#if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */ + Rock[ipnt++] = 0x0f; +#else + Rock[ipnt++] = 0x0e; +#endif + flagval |= (1 << 7); + +#if defined(__QNX__) && !defined(__QNXNTO__) /* Not on Neutrino! never OK? */ + iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime); + ipnt += 7; +#endif + iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime); + ipnt += 7; + iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime); + ipnt += 7; + iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime); + ipnt += 7; + + /* Add in the Rock Ridge RE (relocated dir) field */ + if (deep_opt & NEED_RE) { + if (MAYBE_ADD_CE_ENTRY(RE_SIZE)) + add_CE_entry("RE", __LINE__); + Rock[ipnt++] = 'R'; + Rock[ipnt++] = 'E'; + Rock[ipnt++] = RE_SIZE; + Rock[ipnt++] = SU_VERSION; + flagval |= (1 << 6); + } + /* Add in the Rock Ridge PL record, if required. */ + if (deep_opt & NEED_PL) { + if (MAYBE_ADD_CE_ENTRY(PL_SIZE)) + add_CE_entry("PL", __LINE__); + Rock[ipnt++] = 'P'; + Rock[ipnt++] = 'L'; + Rock[ipnt++] = PL_SIZE; + Rock[ipnt++] = SU_VERSION; + set_733((char *) Rock + ipnt, 0); + ipnt += 8; + flagval |= (1 << 5); + } + + /* Add in the Rock Ridge CL field, if required. */ + if (deep_opt & NEED_CL) { + if (MAYBE_ADD_CE_ENTRY(CL_SIZE)) + add_CE_entry("CL", __LINE__); + Rock[ipnt++] = 'C'; + Rock[ipnt++] = 'L'; + Rock[ipnt++] = CL_SIZE; + Rock[ipnt++] = SU_VERSION; + set_733((char *) Rock + ipnt, 0); + ipnt += 8; + flagval |= (1 << 4); + } + +#ifndef VMS + /* + * If transparent compression was requested, fill in the correct field + * for this file, if (and only if) it is actually a compressed file! + * This relies only on magic number, but it should in general not + * be an issue since if you're using -z odds are most of your + * files are already compressed. + * + * In the future it would be nice if genisoimage actually did the + * compression. + */ + if (transparent_compression && S_ISREG(lstatbuf->st_mode)) { + static const Uchar zisofs_magic[8] = + { 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 }; + FILE *zffile; + unsigned int file_size; + Uchar header[16]; + int OK_flag; + int blocksize; + int headersize; + + /* + * First open file and verify that the correct algorithm was + * used + */ + file_size = 0; + OK_flag = 1; + + memset(header, 0, sizeof (header)); + + zffile = fopen(whole_name, "rb"); + if (zffile != NULL) { + if (fread(header, 1, sizeof (header), zffile) != sizeof (header)) + OK_flag = 0; + + /* Check magic number */ + if (memcmp(header, zisofs_magic, sizeof (zisofs_magic))) + OK_flag = 0; + + /* Get the real size of the file */ + file_size = get_731((char *)header+8); + + /* Get the header size (>> 2) */ + headersize = header[12]; + + /* Get the block size (log2) */ + blocksize = header[13]; + + fclose(zffile); + } else { + OK_flag = 0; + blocksize = headersize = 0; /* Make silly GCC quiet */ + } + + if (OK_flag) { + if (MAYBE_ADD_CE_ENTRY(ZF_SIZE)) + add_CE_entry("ZF", __LINE__); + Rock[ipnt++] = 'Z'; + Rock[ipnt++] = 'F'; + Rock[ipnt++] = ZF_SIZE; + Rock[ipnt++] = SU_VERSION; + Rock[ipnt++] = 'p'; /* Algorithm: "paged zlib" */ + Rock[ipnt++] = 'z'; + /* 2 bytes for algorithm-specific information */ + Rock[ipnt++] = headersize; + Rock[ipnt++] = blocksize; + set_733((char *) Rock + ipnt, file_size); /* Real file size */ + ipnt += 8; + } + } +#endif + /* + * Add in the Rock Ridge CE field, if required. We use this for the + * extension record that is stored in the root directory. + */ + if (deep_opt & NEED_CE) + add_CE_entry("ER", __LINE__); + + /* + * Done filling in all of the fields. Now copy it back to a buffer + * for the file in question. + */ + /* Now copy this back to the buffer for the file */ + Rock[flagpos] = flagval; + + /* If there was a CE, fill in the size field */ + if (recstart) + set_733((char *) Rock + recstart - 8, ipnt - recstart); + +xa_only: + s_entry->rr_attributes = (Uchar *) e_malloc(ipnt); + s_entry->total_rr_attr_size = ipnt; + s_entry->rr_attr_size = (mainrec ? mainrec : ipnt); + memcpy(s_entry->rr_attributes, Rock, ipnt); + return (ipnt); +} + +/* + * Guaranteed to return a single sector with the relevant info + */ +char * +generate_rr_extension_record(char *id, char *descriptor, char *source, + int *size) +{ + int lipnt = 0; + char *pnt; + int len_id; + int len_des; + int len_src; + + len_id = strlen(id); + len_des = strlen(descriptor); + len_src = strlen(source); + Rock[lipnt++] = 'E'; + Rock[lipnt++] = 'R'; + Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src; + Rock[lipnt++] = 1; + Rock[lipnt++] = len_id; + Rock[lipnt++] = len_des; + Rock[lipnt++] = len_src; + Rock[lipnt++] = 1; + + memcpy(Rock + lipnt, id, len_id); + lipnt += len_id; + + memcpy(Rock + lipnt, descriptor, len_des); + lipnt += len_des; + + memcpy(Rock + lipnt, source, len_src); + lipnt += len_src; + + if (lipnt > SECTOR_SIZE) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Extension record too long\n"); +#else + fprintf(stderr, "Extension record too long\n"); + exit(1); +#endif + } + pnt = (char *) e_malloc(SECTOR_SIZE); + memset(pnt, 0, SECTOR_SIZE); + memcpy(pnt, Rock, lipnt); + *size = lipnt; + return (pnt); +} diff --git a/genisoimage/rsync.c b/genisoimage/rsync.c new file mode 100644 index 0000000..3f7e416 --- /dev/null +++ b/genisoimage/rsync.c @@ -0,0 +1,112 @@ +/* + * 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. + * + */ + +#include "genisoimage.h" +#include "utypes.h" +#include <ctype.h> +#include <mconfig.h> + +/* Borrowed from jigdo; original notice: + + These are purely random, no patterns or anything... (I hope) + + I do not claim copyright for the actual numbers below, you may use them + for a re-implementation of the algorithm under a license of your choice. + -- Richard Atterer. */ +static UInt32_t charTable[256] = { + 0x51d65c0f, 0x083cd94b, 0x77f73dd8, 0xa0187d36, + 0x29803d07, 0x7ea8ac0e, 0xea4c16c9, 0xfc576443, + 0x6213df29, 0x1c012392, 0xb38946ae, 0x2e20ca31, + 0xe4dc532f, 0xcb281c47, 0x8508b6a5, 0xb93c210d, + 0xef02b5f3, 0x66548c74, 0x9ae2deab, 0x3b59f472, + 0x4e546447, 0x45232d1f, 0x0ac0a4b1, 0x6c4c264b, + 0x5d24ce84, 0x0f2752cc, 0xa35c7ac7, 0x3e31af51, + 0x79675a59, 0x581f0e81, 0x49053122, 0x7339c9d8, + 0xf9833565, 0xa3dbe5b3, 0xcc06eeb9, 0x92d0671c, + 0x3eb220a7, 0x64864eae, 0xca100872, 0xc50977a1, + 0xd90378e1, 0x7a36cab9, 0x15c15f4b, 0x8b9ef749, + 0xcc1432dc, 0x1ec578ed, 0x27e6e092, 0xbb06db8f, + 0x67f661ac, 0x8dd1a3db, 0x2a0ca16b, 0xb229ab84, + 0x127a3337, 0x347d846f, 0xe1ea4b50, 0x008dbb91, + 0x414c1426, 0xd2be76f0, 0x08789a39, 0xb4d93e30, + 0x61667760, 0x8871bee9, 0xab7da12d, 0xe3c58620, + 0xe9fdfbbe, 0x64fb04f7, 0x8cc5bbf0, 0xf5272d30, + 0x8f161b50, 0x11122b05, 0x7695e72e, 0xa1c5d169, + 0x1bfd0e20, 0xef7e6169, 0xf652d08e, 0xa9d0f139, + 0x2f70aa04, 0xae2c7d6d, 0xa3cb9241, 0x3ae7d364, + 0x348788f8, 0xf483b8f1, 0x55a011da, 0x189719dc, + 0xb0c5d723, 0x8b344e33, 0x300d46eb, 0xd44fe34f, + 0x1a2016c1, 0x66ce4cd7, 0xa45ea5e3, 0x55cb708a, + 0xbce430df, 0xb01ae6e0, 0x3551163b, 0x2c5b157a, + 0x574c4209, 0x430fd0e4, 0x3387e4a5, 0xee1d7451, + 0xa9635623, 0x873ab89b, 0xb96bc6aa, 0x59898937, + 0xe646c6e7, 0xb79f8792, 0x3f3235d8, 0xef1b5acf, + 0xd975b22b, 0x427acce6, 0xe47a2411, 0x75f8c1e8, + 0xa63f799d, 0x53886ad8, 0x9b2d6d32, 0xea822016, + 0xcdee2254, 0xd98bcd98, 0x2933a544, 0x961f379f, + 0x49219792, 0xc61c360f, 0x77cc0c64, 0x7b872046, + 0xb91c7c12, 0x7577154b, 0x196573be, 0xf788813f, + 0x41e2e56a, 0xec3cd244, 0x8c7401f1, 0xc2e805fe, + 0xe8872fbe, 0x9e2faf7d, 0x6766456b, 0x888e2197, + 0x28535c6d, 0x2ce45f3f, 0x24261d2a, 0xd6faab8b, + 0x7a7b42b8, 0x15f0f6fa, 0xfe1711df, 0x7e5685a6, + 0x00930268, 0x74755331, 0x1998912c, 0x7b60498b, + 0x501a5786, 0x92ace0f6, 0x1d9752fe, 0x5a731add, + 0x5b3b44fc, 0x473673f9, 0xa42c0321, 0xd82f9f18, + 0xb4b225da, 0xfc89ece2, 0x072e1130, 0x5772aae3, + 0x29010857, 0x542c970c, 0x94f67fe5, 0x71209e9b, + 0xdb97ea39, 0x2689b41b, 0xae815804, 0xfc5e2651, + 0xd4521674, 0x48ed979a, 0x2f617da3, 0xc350353d, + 0xc3accd94, 0xbd8d313a, 0xc61a8e77, 0xf34940a4, + 0x8d2c6b0f, 0x0f0e7225, 0x39e183db, 0xd19ebba9, + 0x6a0f37b9, 0xd18922f3, 0x106420c5, 0xaa5a640b, + 0x7cf0d273, 0xcf3238a7, 0x3b33204f, 0x476be7bb, + 0x09d23bca, 0xbe84b2f7, 0xb7a3bace, 0x2528cee1, + 0x3dcaa1dd, 0x900ad31a, 0xf21dea6d, 0x9ce51463, + 0xf1540bba, 0x0fab1bdd, 0x89cfb79a, 0x01a2a6e6, + 0x6f85d67c, 0xd1669ec4, 0x355db722, 0x00ebd5c4, + 0x926eb385, 0x69ead869, 0x0da2b122, 0x402779fe, + 0xdaed92d0, 0x57e9aabb, 0x3df64854, 0xfcc774b5, + 0x2e1740ed, 0xa615e024, 0xf7bac938, 0x377dfd1a, + 0xd0559d66, 0x25499be8, 0x2d8f2006, 0xfaa9e486, + 0x95e980e7, 0x82aeba67, 0x5a7f2561, 0xbc60dff6, + 0x6c8739a2, 0x7ec59a8b, 0x9998f265, 0xdfe37e5e, + 0xb47cee1e, 0x4dd8bc9e, 0x35c57e09, 0x07850b63, + 0x06eadbcb, 0x6c1f2956, 0x01685c2c, 0xf5725eef, + 0xf13b98b5, 0xaab739c2, 0x200b1da2, 0xa716b98b, + 0xd9ee3058, 0x76acf20b, 0x2f259e04, 0xed11658b, + 0x1532b331, 0x0ab43204, 0xf0beb023, 0xb1685483, + 0x58cbdc4f, 0x079384d3, 0x049b141c, 0xc38184b9, + 0xaf551d9a, 0x66222560, 0x059deeca, 0x535f99e2 +}; + +unsigned long long rsync64(unsigned char *mem, size_t size) +{ + UInt32_t a = 0; + UInt32_t b = 0; + unsigned char *limit = mem + size; + unsigned long long result = 0; + + while (mem < limit) + { + a += charTable[*mem++]; + b += a; + } + + a = a & 0xffffffff; /* Just in case uint32 can be 64 bits */ + b = b & 0xffffffff; + + result = ((unsigned long long)b << 32) | a; + + return result; +} + diff --git a/genisoimage/scsi.c b/genisoimage/scsi.c new file mode 100644 index 0000000..179cc33 --- /dev/null +++ b/genisoimage/scsi.c @@ -0,0 +1,195 @@ +/* + * 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. + * + */ + +/* @(#)scsi.c 1.20 05/05/01 Copyright 1997 J. Schilling */ +/* + * Copyright (c) 1997 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. + */ + +#ifdef USE_SCG +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <schily.h> + +#include "genisoimage.h" +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "wodim.h" +#include "../wodim/defaults.h" + +/* + * NOTICE: You should not make BUF_SIZE more than + * the buffer size of the CD-Recorder. + * + * Do not set BUF_SIZE to be more than 126 KBytes + * if you are running cdrecord on a sun4c machine. + * + * WARNING: Philips CDD 521 dies if BUF_SIZE is to big. + */ +#define BUF_SIZE (62*1024) /* Must be a multiple of 2048 */ + +static SCSI *usalp; +static long bufsize; /* The size of the transfer buffer */ + +int readsecs(int startsecno, void *buffer, int sectorcount); +int scsidev_open(char *path); +int scsidev_close(void); + +int +readsecs(int startsecno, void *buffer, int sectorcount) +{ + int f; + int secsize; /* The drive's SCSI sector size */ + long amount; /* The number of bytes to be transfered */ + long secno; /* The sector number to read from */ + long secnum; /* The number of sectors to read */ + char *bp; + long amt; + + if (in_image == NULL) { + /* + * We are using the standard CD-ROM sectorsize of 2048 bytes + * while the drive may be switched to 512 bytes per sector. + * + * XXX We assume that secsize is no more than SECTOR_SIZE + * XXX and that SECTOR_SIZE / secsize is not a fraction. + */ + secsize = usalp->cap->c_bsize; + amount = sectorcount * SECTOR_SIZE; + secno = startsecno * (SECTOR_SIZE / secsize); + bp = buffer; + + while (amount > 0) { + amt = amount; + if (amount > bufsize) + amt = bufsize; + secnum = amt / secsize; + + if (read_scsi(usalp, bp, secno, secnum) < 0 || + usal_getresid(usalp) != 0) { +#ifdef OLD + return (-1); +#else + comerr("Read error on old image\n"); +#endif + } + + amount -= secnum * secsize; + bp += secnum * secsize; + secno += secnum; + } + return (SECTOR_SIZE * sectorcount); + } + + f = fileno(in_image); + + if (lseek(f, (off_t)startsecno * SECTOR_SIZE, SEEK_SET) == (off_t)-1) { +#ifdef USE_LIBSCHILY + comerr("Seek error on old image\n"); +#else + fprintf(stderr, "Seek error on old image\n"); + exit(10); +#endif + } + if ((amt = read(f, buffer, (sectorcount * SECTOR_SIZE))) + != (sectorcount * SECTOR_SIZE)) { +#ifdef USE_LIBSCHILY + if (amt < 0) + comerr("Read error on old image\n"); + comerrno(EX_BAD, "Short read on old image\n"); /* < secnt aber > 0 */ +#else + if (amt < 0) + fprintf(stderr, "Read error on old image\n"); + else + fprintf(stderr, "Short read on old image\n"); + + exit(10); +#endif + } + return (sectorcount * SECTOR_SIZE); +} + +int +scsidev_open(char *path) +{ + char errstr[80]; + char *buf; /* ignored, bit OS/2 ASPI layer needs memory which */ + /* has been allocated by scsi_getbuf() */ + + /* + * Call usal_remote() to force loading the remote SCSI transport library + * code that is located in librusal instead of the dummy remote routines + * that are located inside libusal. + */ + usal_remote(); + + cdr_defaults(&path, NULL, NULL, NULL); + /* path, debug, verboseopen */ + usalp = usal_open(path, errstr, sizeof (errstr), 0, 0); + if (usalp == 0) { + errmsg("%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":""); + return (-1); + } + + bufsize = usal_bufsize(usalp, BUF_SIZE); + if ((buf = usal_getbuf(usalp, bufsize)) == NULL) { + errmsg("Cannot get SCSI I/O buffer.\n"); + usal_close(usalp); + return (-1); + } + + bufsize = (bufsize / SECTOR_SIZE) * SECTOR_SIZE; + + allow_atapi(usalp, TRUE); + + if (!wait_unit_ready(usalp, 60)) { /* Eat Unit att / Wait for drive */ + usalp->silent--; + return (-1); + } + + usalp->silent++; + read_capacity(usalp); /* Set Capacity/Sectorsize for I/O */ + usalp->silent--; + + return (1); +} + +int +scsidev_close() +{ + if (in_image == NULL) { + return (usal_close(usalp)); + } else { + return (fclose(in_image)); + } +} + +#endif /* USE_SCG */ diff --git a/genisoimage/scsi.h b/genisoimage/scsi.h new file mode 100644 index 0000000..58fc342 --- /dev/null +++ b/genisoimage/scsi.h @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +/* @(#)scsi.h 1.1 04/05/27 Copyright 1997-2004 J. Schilling */ +/* + * Copyright (c) 1997-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. + */ + +#ifndef _SCSI_H +#define _SCSI_H + +#ifdef USE_SCG +extern int readsecs(int startsecno, void *buffer, int sectorcount); +extern int scsidev_open(char *path); +extern int scsidev_close(void); +#endif + +#endif /* _SCSI_H */ diff --git a/genisoimage/sha1.c b/genisoimage/sha1.c new file mode 100644 index 0000000..ae410ac --- /dev/null +++ b/genisoimage/sha1.c @@ -0,0 +1,415 @@ +/* sha1.c - Functions to compute SHA1 message digest of files or + memory blocks according to the NIST specification FIPS-180-1. + + Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Scott G. Miller + Credits: + Robert Klep <robert@ilse.nl> -- Expansion function fix +*/ + +#include "sha1.h" + +#include <stddef.h> +#include <string.h> + +/* SWAP does an endian swap on architectures that are little-endian, + as SHA1 needs some data in a big-endian form. */ + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) (n) +#else +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#endif + +#define BLOCKSIZE 4096 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* + Takes a pointer to a 160 bit block of data (five 32 bit ints) and + intializes it to the start constants of the SHA1 algorithm. This + must be called before using hash in the call to sha1_hash. +*/ +void +sha1_init_ctx (struct sha1_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + ctx->E = 0xc3d2e1f0; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 20 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) +{ + ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); + ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); + ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); + ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); + ((md5_uint32 *) resbuf)[4] = SWAP (ctx->E); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + md5_uint32 bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3); + *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + sha1_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return sha1_read_ctx (ctx, resbuf); +} + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +sha1_stream (FILE *stream, void *resblock) +{ + struct sha1_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + sha1_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + sha1_process_block (buffer, BLOCKSIZE, &ctx); + } + + process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + sha1_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + sha1_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +sha1_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha1_ctx ctx; + + /* Initialize the computation context. */ + sha1_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + sha1_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha1_finish_ctx (&ctx, resblock); +} + +void +sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +# define alignof(type) offsetof (struct { char c; type x; }, x) +# define UNALIGNED_P(p) (((size_t) p) % alignof (md5_uint32) != 0) + if (UNALIGNED_P (buffer)) + while (len > 64) + { + sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + sha1_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + sha1_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[64], left_over); + } + ctx->buflen = left_over; + } +} + +/* --- Code below is the primary difference between md5.c and sha1.c --- */ + +/* SHA1 round constants */ +#define K1 0x5a827999L +#define K2 0x6ed9eba1L +#define K3 0x8f1bbcdcL +#define K4 0xca62c1d6L + +/* Round functions. Note that F2 is the same as F4. */ +#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) +#define F2(B,C,D) (B ^ C ^ D) +#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) +#define F4(B,C,D) (B ^ C ^ D) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. + Most of this code comes from GnuPG's cipher/sha1.c. */ + +void +sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) +{ + const md5_uint32 *words = buffer; + size_t nwords = len / sizeof (md5_uint32); + const md5_uint32 *endp = words + nwords; + md5_uint32 x[16]; + md5_uint32 a = ctx->A; + md5_uint32 b = ctx->B; + md5_uint32 c = ctx->C; + md5_uint32 d = ctx->D; + md5_uint32 e = ctx->E; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + +#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ + ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ + , (x[I&0x0f] = rol(tm, 1)) ) + +#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ + + F( B, C, D ) \ + + K \ + + M; \ + B = rol( B, 30 ); \ + } while(0) + + while (words < endp) + { + md5_uint32 tm; + int t; + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + R( a, b, c, d, e, F1, K1, x[ 0] ); + R( e, a, b, c, d, F1, K1, x[ 1] ); + R( d, e, a, b, c, F1, K1, x[ 2] ); + R( c, d, e, a, b, F1, K1, x[ 3] ); + R( b, c, d, e, a, F1, K1, x[ 4] ); + R( a, b, c, d, e, F1, K1, x[ 5] ); + R( e, a, b, c, d, F1, K1, x[ 6] ); + R( d, e, a, b, c, F1, K1, x[ 7] ); + R( c, d, e, a, b, F1, K1, x[ 8] ); + R( b, c, d, e, a, F1, K1, x[ 9] ); + R( a, b, c, d, e, F1, K1, x[10] ); + R( e, a, b, c, d, F1, K1, x[11] ); + R( d, e, a, b, c, F1, K1, x[12] ); + R( c, d, e, a, b, F1, K1, x[13] ); + R( b, c, d, e, a, F1, K1, x[14] ); + R( a, b, c, d, e, F1, K1, x[15] ); + R( e, a, b, c, d, F1, K1, M(16) ); + R( d, e, a, b, c, F1, K1, M(17) ); + R( c, d, e, a, b, F1, K1, M(18) ); + R( b, c, d, e, a, F1, K1, M(19) ); + R( a, b, c, d, e, F2, K2, M(20) ); + R( e, a, b, c, d, F2, K2, M(21) ); + R( d, e, a, b, c, F2, K2, M(22) ); + R( c, d, e, a, b, F2, K2, M(23) ); + R( b, c, d, e, a, F2, K2, M(24) ); + R( a, b, c, d, e, F2, K2, M(25) ); + R( e, a, b, c, d, F2, K2, M(26) ); + R( d, e, a, b, c, F2, K2, M(27) ); + R( c, d, e, a, b, F2, K2, M(28) ); + R( b, c, d, e, a, F2, K2, M(29) ); + R( a, b, c, d, e, F2, K2, M(30) ); + R( e, a, b, c, d, F2, K2, M(31) ); + R( d, e, a, b, c, F2, K2, M(32) ); + R( c, d, e, a, b, F2, K2, M(33) ); + R( b, c, d, e, a, F2, K2, M(34) ); + R( a, b, c, d, e, F2, K2, M(35) ); + R( e, a, b, c, d, F2, K2, M(36) ); + R( d, e, a, b, c, F2, K2, M(37) ); + R( c, d, e, a, b, F2, K2, M(38) ); + R( b, c, d, e, a, F2, K2, M(39) ); + R( a, b, c, d, e, F3, K3, M(40) ); + R( e, a, b, c, d, F3, K3, M(41) ); + R( d, e, a, b, c, F3, K3, M(42) ); + R( c, d, e, a, b, F3, K3, M(43) ); + R( b, c, d, e, a, F3, K3, M(44) ); + R( a, b, c, d, e, F3, K3, M(45) ); + R( e, a, b, c, d, F3, K3, M(46) ); + R( d, e, a, b, c, F3, K3, M(47) ); + R( c, d, e, a, b, F3, K3, M(48) ); + R( b, c, d, e, a, F3, K3, M(49) ); + R( a, b, c, d, e, F3, K3, M(50) ); + R( e, a, b, c, d, F3, K3, M(51) ); + R( d, e, a, b, c, F3, K3, M(52) ); + R( c, d, e, a, b, F3, K3, M(53) ); + R( b, c, d, e, a, F3, K3, M(54) ); + R( a, b, c, d, e, F3, K3, M(55) ); + R( e, a, b, c, d, F3, K3, M(56) ); + R( d, e, a, b, c, F3, K3, M(57) ); + R( c, d, e, a, b, F3, K3, M(58) ); + R( b, c, d, e, a, F3, K3, M(59) ); + R( a, b, c, d, e, F4, K4, M(60) ); + R( e, a, b, c, d, F4, K4, M(61) ); + R( d, e, a, b, c, F4, K4, M(62) ); + R( c, d, e, a, b, F4, K4, M(63) ); + R( b, c, d, e, a, F4, K4, M(64) ); + R( a, b, c, d, e, F4, K4, M(65) ); + R( e, a, b, c, d, F4, K4, M(66) ); + R( d, e, a, b, c, F4, K4, M(67) ); + R( c, d, e, a, b, F4, K4, M(68) ); + R( b, c, d, e, a, F4, K4, M(69) ); + R( a, b, c, d, e, F4, K4, M(70) ); + R( e, a, b, c, d, F4, K4, M(71) ); + R( d, e, a, b, c, F4, K4, M(72) ); + R( c, d, e, a, b, F4, K4, M(73) ); + R( b, c, d, e, a, F4, K4, M(74) ); + R( a, b, c, d, e, F4, K4, M(75) ); + R( e, a, b, c, d, F4, K4, M(76) ); + R( d, e, a, b, c, F4, K4, M(77) ); + R( c, d, e, a, b, F4, K4, M(78) ); + R( b, c, d, e, a, F4, K4, M(79) ); + + a = ctx->A += a; + b = ctx->B += b; + c = ctx->C += c; + d = ctx->D += d; + e = ctx->E += e; + } +} diff --git a/genisoimage/sha1.h b/genisoimage/sha1.h new file mode 100644 index 0000000..51891d0 --- /dev/null +++ b/genisoimage/sha1.h @@ -0,0 +1,88 @@ +/* Declarations of functions and data types used for SHA1 sum + library functions. + Copyright (C) 2000, 2001, 2003, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef SHA1_H +# define SHA1_H 1 + +# include <stdio.h> + +typedef unsigned int md5_uint32; + +/* Structure to save state of computation between the single steps. */ +struct sha1_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; + md5_uint32 E; + + md5_uint32 total[2]; + md5_uint32 buflen; + char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32)))); +}; + + +/* Initialize structure containing state of computation. */ +extern void sha1_init_ctx (struct sha1_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void sha1_process_block (const void *buffer, size_t len, + struct sha1_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void sha1_process_bytes (const void *buffer, size_t len, + struct sha1_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 20 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF be correctly + aligned for a 32 bits value. */ +extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 20 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf); + + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 20 bytes + beginning at RESBLOCK. */ +extern int sha1_stream (FILE *stream, void *resblock); + +/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *sha1_buffer (const char *buffer, size_t len, void *resblock); + +#endif diff --git a/genisoimage/sha256.c b/genisoimage/sha256.c new file mode 100644 index 0000000..f7558b2 --- /dev/null +++ b/genisoimage/sha256.c @@ -0,0 +1,307 @@ +/* Functions to compute SHA256 message digest of files or memory blocks. + according to the definition of SHA256 in FIPS 180-2. + Copyright (C) 2007 Free Software Foundation, Inc. + + Copied here from the GNU C Library version 2.7 on the 10 May 2009 + by Steve McIntyre <93sam@debian.org>. This code was under LGPL v2.1 + in glibc, and that license gives us the option to use and + distribute the code under the terms of the GPL v2 instead. I'm + taking that option. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Ulrich Drepper <drepper@redhat.com>, 2007. */ + +#include <endian.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#include "sha256.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# ifdef _LIBC +# include <byteswap.h> +# define SWAP(n) bswap_32 (n) +# else +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +# endif +#else +# define SWAP(n) (n) +#endif + + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (FIPS 180-2:5.1.1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Constants for SHA256 from FIPS 180-2:4.2.2. */ +static const uint32_t K[64] = + { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ +static void +sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) +{ + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + uint32_t a = ctx->H[0]; + uint32_t b = ctx->H[1]; + uint32_t c = ctx->H[2]; + uint32_t d = ctx->H[3]; + uint32_t e = ctx->H[4]; + uint32_t f = ctx->H[5]; + uint32_t g = ctx->H[6]; + uint32_t h = ctx->H[7]; + + /* First increment the byte count. FIPS 180-2 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (nwords > 0) + { + uint32_t W[64]; + uint32_t a_save = a; + uint32_t b_save = b; + uint32_t c_save = c; + uint32_t d_save = d; + uint32_t e_save = e; + uint32_t f_save = f; + uint32_t g_save = g; + uint32_t h_save = h; + + unsigned int t; + + /* Operators defined in FIPS 180-2:4.1.2. */ +#define Ch(x, y, z) ((x & y) ^ (~x & z)) +#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) +#define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22)) +#define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25)) +#define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3)) +#define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10)) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) ((w >> s) | (w << (32 - s))) + + /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ + for (t = 0; t < 16; ++t) + { + W[t] = SWAP (*words); + ++words; + } + for (t = 16; t < 64; ++t) + W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; + + /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ + for (t = 0; t < 64; ++t) + { + uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; + uint32_t T2 = S0 (a) + Maj (a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + /* Add the starting values of the context according to FIPS 180-2:6.2.2 + step 4. */ + a += a_save; + b += b_save; + c += c_save; + d += d_save; + e += e_save; + f += f_save; + g += g_save; + h += h_save; + + /* Prepare for the next round. */ + nwords -= 16; + } + + /* Put checksum in context given as argument. */ + ctx->H[0] = a; + ctx->H[1] = b; + ctx->H[2] = c; + ctx->H[3] = d; + ctx->H[4] = e; + ctx->H[5] = f; + ctx->H[6] = g; + ctx->H[7] = h; +} + + +/* Initialize structure containing state of computation. + (FIPS 180-2:5.3.2) */ +void +sha256_init_ctx (ctx) + struct sha256_ctx *ctx; +{ + ctx->H[0] = 0x6a09e667; + ctx->H[1] = 0xbb67ae85; + ctx->H[2] = 0x3c6ef372; + ctx->H[3] = 0xa54ff53a; + ctx->H[4] = 0x510e527f; + ctx->H[5] = 0x9b05688c; + ctx->H[6] = 0x1f83d9ab; + ctx->H[7] = 0x5be0cd19; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +sha256_finish_ctx (ctx, resbuf) + struct sha256_ctx *ctx; + void *resbuf; +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t pad; + unsigned int i; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3); + *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + sha256_process_block (ctx->buffer, bytes + pad + 8, ctx); + + /* Put result from CTX in first 32 bytes following RESBUF. */ + for (i = 0; i < 8; ++i) + ((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]); + + return resbuf; +} + + +void +sha256_process_bytes (buffer, len, ctx) + const void *buffer; + size_t len; + struct sha256_ctx *ctx; +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0) +# else +# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + sha256_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes into internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + sha256_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[64], left_over); + } + ctx->buflen = left_over; + } +} diff --git a/genisoimage/sha256.h b/genisoimage/sha256.h new file mode 100644 index 0000000..e7f4cb9 --- /dev/null +++ b/genisoimage/sha256.h @@ -0,0 +1,62 @@ +/* Declaration of functions and data types used for SHA256 sum computing + library functions. + Copyright (C) 2007 Free Software Foundation, Inc. + + Copied here from the GNU C Library version 2.7 on the 10 May 2009 + by Steve McIntyre <93sam@debian.org>. This code was under GPL v2.1 + in glibc, and that license gives us the option to use and + distribute the code under the terms of the GPL v2 instead. I'm + taking that option. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _SHA256_H +#define _SHA256_H 1 + +#include <limits.h> +#include <stdint.h> +#include <stdio.h> + + +/* Structure to save state of computation between the single steps. */ +struct sha256_ctx +{ + uint32_t H[8]; + + uint32_t total[2]; + uint32_t buflen; + char buffer[128] __attribute__ ((__aligned__ (__alignof__ (uint32_t)))); +}; + +/* Initialize structure containing state of computation. + (FIPS 180-2: 5.3.2) */ +extern void sha256_init_ctx (struct sha256_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void sha256_process_bytes (const void *buffer, size_t len, + struct sha256_ctx *ctx) __THROW; + +/* Process the remaining bytes in the buffer and put result from CTX + in first 32 bytes following RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) + __THROW; + +#endif /* sha256.h */ diff --git a/genisoimage/sha512.c b/genisoimage/sha512.c new file mode 100644 index 0000000..c4987ce --- /dev/null +++ b/genisoimage/sha512.c @@ -0,0 +1,338 @@ +/* Functions to compute SHA512 message digest of files or memory blocks. + according to the definition of SHA512 in FIPS 180-2. + Copyright (C) 2007 Free Software Foundation, Inc. + + Copied here from the GNU C Library version 2.7 on the 10 May 2009 + by Steve McIntyre <93sam@debian.org>. This code was under LGPL v2.1 + in glibc, and that license gives us the option to use and + distribute the code under the terms of the GPL v2 instead. I'm + taking that option. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Ulrich Drepper <drepper@redhat.com>, 2007. */ + +#include <endian.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#include "sha512.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# ifdef _LIBC +# include <byteswap.h> +# define SWAP(n) bswap_64 (n) +# else +# define SWAP(n) \ + (((n) << 56) \ + | (((n) & 0xff00) << 40) \ + | (((n) & 0xff0000) << 24) \ + | (((n) & 0xff000000) << 8) \ + | (((n) >> 8) & 0xff000000) \ + | (((n) >> 24) & 0xff0000) \ + | (((n) >> 40) & 0xff00) \ + | ((n) >> 56)) +# endif +#else +# define SWAP(n) (n) +#endif + + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (FIPS 180-2:5.1.2) */ +static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Constants for SHA512 from FIPS 180-2:4.2.3. */ +static const uint64_t K[80] = + { + UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd), + UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc), + UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019), + UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118), + UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe), + UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2), + UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1), + UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694), + UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3), + UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65), + UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483), + UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5), + UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210), + UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4), + UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725), + UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70), + UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926), + UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df), + UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8), + UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b), + UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001), + UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30), + UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910), + UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8), + UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53), + UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8), + UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb), + UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3), + UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60), + UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec), + UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9), + UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b), + UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207), + UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178), + UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6), + UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b), + UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493), + UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c), + UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a), + UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817) + }; + + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 128 == 0. */ +static void +sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) +{ + const uint64_t *words = buffer; + size_t nwords = len / sizeof (uint64_t); + uint64_t a = ctx->H[0]; + uint64_t b = ctx->H[1]; + uint64_t c = ctx->H[2]; + uint64_t d = ctx->H[3]; + uint64_t e = ctx->H[4]; + uint64_t f = ctx->H[5]; + uint64_t g = ctx->H[6]; + uint64_t h = ctx->H[7]; + + /* First increment the byte count. FIPS 180-2 specifies the possible + length of the file up to 2^128 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 128 bytes in each round of + the loop. */ + while (nwords > 0) + { + uint64_t W[80]; + uint64_t a_save = a; + uint64_t b_save = b; + uint64_t c_save = c; + uint64_t d_save = d; + uint64_t e_save = e; + uint64_t f_save = f; + uint64_t g_save = g; + uint64_t h_save = h; + unsigned int t; + + /* Operators defined in FIPS 180-2:4.1.2. */ +#define Ch(x, y, z) ((x & y) ^ (~x & z)) +#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) +#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39)) +#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41)) +#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7)) +#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6)) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) ((w >> s) | (w << (64 - s))) + + /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ + for (t = 0; t < 16; ++t) + { + W[t] = SWAP (*words); + ++words; + } + for (t = 16; t < 80; ++t) + W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; + + /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ + for (t = 0; t < 80; ++t) + { + uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; + uint64_t T2 = S0 (a) + Maj (a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + /* Add the starting values of the context according to FIPS 180-2:6.3.2 + step 4. */ + a += a_save; + b += b_save; + c += c_save; + d += d_save; + e += e_save; + f += f_save; + g += g_save; + h += h_save; + + /* Prepare for the next round. */ + nwords -= 16; + } + + /* Put checksum in context given as argument. */ + ctx->H[0] = a; + ctx->H[1] = b; + ctx->H[2] = c; + ctx->H[3] = d; + ctx->H[4] = e; + ctx->H[5] = f; + ctx->H[6] = g; + ctx->H[7] = h; +} + + +/* Initialize structure containing state of computation. + (FIPS 180-2:5.3.3) */ +void +sha512_init_ctx (ctx) + struct sha512_ctx *ctx; +{ + ctx->H[0] = UINT64_C (0x6a09e667f3bcc908); + ctx->H[1] = UINT64_C (0xbb67ae8584caa73b); + ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b); + ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1); + ctx->H[4] = UINT64_C (0x510e527fade682d1); + ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f); + ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b); + ctx->H[7] = UINT64_C (0x5be0cd19137e2179); + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +sha512_finish_ctx (ctx, resbuf) + struct sha512_ctx *ctx; + void *resbuf; +{ + /* Take yet unprocessed bytes into account. */ + uint64_t bytes = ctx->buflen; + size_t pad; + unsigned int i; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 128-bit file length in *bits* at the end of the buffer. */ + *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP (ctx->total[0] << 3); + *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 61)); + + /* Process last bytes. */ + sha512_process_block (ctx->buffer, bytes + pad + 16, ctx); + + /* Put result from CTX in first 64 bytes following RESBUF. */ + for (i = 0; i < 8; ++i) + ((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]); + + return resbuf; +} + + +void +sha512_process_bytes (buffer, len, ctx) + const void *buffer; + size_t len; + struct sha512_ctx *ctx; +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 256 - left_over > len ? len : 256 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 128) + { + sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx); + + ctx->buflen &= 127; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 128) + { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0) +# else +# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 128) + { + sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, + ctx); + buffer = (const char *) buffer + 128; + len -= 128; + } + else +#endif + { + sha512_process_block (buffer, len & ~127, ctx); + buffer = (const char *) buffer + (len & ~127); + len &= 127; + } + } + + /* Move remaining bytes into internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 128) + { + sha512_process_block (ctx->buffer, 128, ctx); + left_over -= 128; + memcpy (ctx->buffer, &ctx->buffer[128], left_over); + } + ctx->buflen = left_over; + } +} diff --git a/genisoimage/sha512.h b/genisoimage/sha512.h new file mode 100644 index 0000000..7298355 --- /dev/null +++ b/genisoimage/sha512.h @@ -0,0 +1,62 @@ +/* Declaration of functions and data types used for SHA512 sum computing + library functions. + Copyright (C) 2007 Free Software Foundation, Inc. + + Copied here from the GNU C Library version 2.7 on the 10 May 2009 + by Steve McIntyre <93sam@debian.org>. This code was under GPL v2.1 + in glibc, and that license gives us the option to use and + distribute the code under the terms of the GPL v2 instead. I'm + taking that option. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _SHA512_H +#define _SHA512_H 1 + +#include <limits.h> +#include <stdint.h> +#include <stdio.h> + + +/* Structure to save state of computation between the single steps. */ +struct sha512_ctx +{ + uint64_t H[8]; + + uint64_t total[2]; + uint64_t buflen; + char buffer[256] __attribute__ ((__aligned__ (__alignof__ (uint64_t)))); +}; + +/* Initialize structure containing state of computation. + (FIPS 180-2: 5.3.3) */ +extern void sha512_init_ctx (struct sha512_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 128. */ +extern void sha512_process_bytes (const void *buffer, size_t len, + struct sha512_ctx *ctx) __THROW; + +/* Process the remaining bytes in the buffer and put result from CTX + in first 64 bytes following RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 64 bits value. */ +extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) + __THROW; + +#endif /* sha512.h */ diff --git a/genisoimage/stream.c b/genisoimage/stream.c new file mode 100644 index 0000000..f59c1e3 --- /dev/null +++ b/genisoimage/stream.c @@ -0,0 +1,272 @@ +/* + * 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. + * + */ + +/* @(#)stream.c 1.3 04/03/04 Copyright 2002-2003 J. Schilling */ +/* Parts from @(#)stream.c 1.9 07/02/17 Copyright 2002-2007 J. Schilling */ +/* + * ISO-9660 stream (pipe) file module for genisoimage + * + * Copyright (c) 2002-2003 J. Schilling + * Implemented after an idea from M.H. Voase + */ +/* + * 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 "genisoimage.h" +#include "iso9660.h" + +static int size_str_file(int starting_extent); +static int size_str_dir(int starting_extent); +static int size_str_path(int starting_extent); + +static int gen_str_path(void); + +static int write_str_file(FILE *outfile); +static int write_str_dir(FILE *outfile); +static int write_str_path(FILE *outfile); + +extern struct directory *root; +extern unsigned int session_start; +extern int stream_media_size; +extern char *stream_filename; +extern time_t begun; +extern int volume_sequence_number; + +static unsigned int avail_extent; +static unsigned int stream_extent; +static unsigned int stream_size; +static unsigned int stream_pad; +static char *l_path; +static char *m_path; +static struct iso_directory_record s_dir; +static int stream_finished = 0; + +/* + * Compute the size of the file + */ +static int +size_str_file(int starting_extent) +{ + int n; +extern int dopad; + + stream_extent = last_extent; /* Start of stream file content */ + + avail_extent = stream_media_size; + n = last_extent; /* Room for FS blocks before file */ + n += 1; /* Room for the directory block */ + stream_pad = 0; + if (n < 50) { + stream_pad = 50 - n; + n = 50; /* Make net. size easy to compute */ + } + if (dopad) + n += 150; /* Room for final padding */ + avail_extent -= n; + + last_extent += avail_extent + stream_pad; + + return (0); +} + +/* + * The size of the directory record - one sector + */ +static int +size_str_dir(int starting_extent) +{ + root->extent = last_extent; + last_extent += 1; + return (0); +} + +/* + * The size of the path tables - two sectors + */ +static int +size_str_path(int starting_extent) +{ + path_table[0] = starting_extent; + path_table[1] = 0; + path_table[2] = path_table[0] + 1; + path_table[3] = 0; + last_extent += 2 * 1; + return (0); +} + +/* + * Generate the path table data + */ +static int +gen_str_path() +{ + /* + * Basically add the root directory entry + */ + l_path = (char *)e_malloc(SECTOR_SIZE); + m_path = (char *)e_malloc(SECTOR_SIZE); + memset(l_path, 0, SECTOR_SIZE); + memset(m_path, 0, SECTOR_SIZE); + l_path[0] = 1; + m_path[0] = 1; + set_731(l_path + 2, root->extent); + set_732(m_path + 2, root->extent); + set_721(l_path + 6, 1); + set_722(m_path + 6, 1); + l_path[8] = '\0'; l_path[9] = '\0'; + m_path[8] = '\0'; m_path[9] = '\0'; + return (0); +} + +/* + * Write the file content + */ +static int +write_str_file(FILE *outfile) +{ + unsigned int idx = 0; + unsigned int iso_blocks; + int count; + char *buf; + + buf = e_malloc(SECTOR_SIZE); + stream_size = 0; + while ((idx + SECTOR_SIZE) < (avail_extent * SECTOR_SIZE)) { + memset(buf, 0, SECTOR_SIZE); + count = fread(buf, 1, SECTOR_SIZE, stdin); + if (count <= 0) { + stream_finished = 1; + break; + } + idx += count; + jtwrite(buf, count, 1, 0, FALSE); + xfwrite(buf, count, 1, outfile, 0, FALSE); + } + + stream_size = idx; + iso_blocks = ISO_BLOCKS(idx); + memset(buf, 0, SECTOR_SIZE); + if (SECTOR_SIZE * iso_blocks - idx) + { + jtwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE * iso_blocks - idx, 1, outfile, 0, FALSE); + } + /* + * If we didn't fill the available area, pad to directory block + */ + for (count = 0; count < (avail_extent - iso_blocks); count++) + { + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + } + for (count = 0; count < stream_pad; count++) + { + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + } + + last_extent_written += avail_extent + stream_pad; + return (0); +} + +/* + * Generate and write the directory record data + */ +static int +write_str_dir(FILE *outfile) +{ + int to_write; + char *buf; + + buf = e_malloc(SECTOR_SIZE); memset(buf, 0, SECTOR_SIZE); + memset(&s_dir, 0, sizeof (struct iso_directory_record)); + s_dir.length[0] = 34; /* BAD: Hardcoded - Will fix, MHV */ + s_dir.ext_attr_length[0] = 0; + set_733((char *)s_dir.extent, root->extent); + set_733((char *)s_dir.size, SECTOR_SIZE); + iso9660_date(s_dir.date, begun); + s_dir.flags[0] = ISO_DIRECTORY; + s_dir.file_unit_size[0] = 0; + s_dir.interleave[0] = 0; + set_723((char *)s_dir.volume_sequence_number, volume_sequence_number); + s_dir.name_len[0] = 1; + s_dir.name[0] = 0; /* "." */ + jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE); + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE); + s_dir.name[0] = 1; /* ".." */ + jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, 0, FALSE); + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + 1, 1, outfile, 0, FALSE); + memset(&s_dir, 0, sizeof (struct iso_directory_record)); + s_dir.length[0] = 34 + strlen(stream_filename); + s_dir.ext_attr_length[0] = 0; + set_733((char *) s_dir.extent, stream_extent); + set_733((char *) s_dir.size, stream_size); + iso9660_date(s_dir.date, begun); + s_dir.flags[0] = 0; + s_dir.file_unit_size[0] = 0; + set_723((char *)s_dir.volume_sequence_number, volume_sequence_number); + s_dir.name_len[0] = strlen(stream_filename); + memcpy(s_dir.name, stream_filename, s_dir.name_len[0]); + jtwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + + s_dir.name_len[0], 1, 0, FALSE); + xfwrite(&s_dir, offsetof(struct iso_directory_record, name[0]) + + s_dir.name_len[0], 1, outfile, 0, FALSE); + + /* + * This calc is: 2 single char directory entries (34) + an additional entry + * with filename length stream_filename + round up for even lenght count + */ + to_write = (s_dir.name_len[0] % 2) ? 0 : 1; + jtwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) + + to_write, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE - ((3 * 34) + s_dir.name_len[0]) + + to_write, 1, outfile, 0, FALSE); + free(buf); + last_extent_written++; + return (0); +} + +/* + * Generate the path table data + */ +static int +write_str_path(FILE *outfile) +{ + jtwrite(l_path, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(l_path, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + jtwrite(m_path, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(m_path, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + free(l_path); + free(m_path); + path_table_l = NULL; + path_table_m = NULL; + return (0); +} + +struct output_fragment strfile_desc = { NULL, size_str_file, NULL, write_str_file, "Stream File" }; +struct output_fragment strdir_desc = { NULL, size_str_dir, NULL, write_str_dir, "Stream File Directory" }; +struct output_fragment strpath_desc = { NULL, size_str_path, gen_str_path, write_str_path, "Stream File Path table" }; diff --git a/genisoimage/sunlabel.h b/genisoimage/sunlabel.h new file mode 100644 index 0000000..243e9bb --- /dev/null +++ b/genisoimage/sunlabel.h @@ -0,0 +1,206 @@ +/* + * 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. + * + */ + +/* @(#)sunlabel.h 1.5 03/12/28 Copyright 1999-2003 J. Schilling */ +/* + * Support for Sun disk label + * + * Copyright (c) 1999-2003 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. + */ + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#define NDKMAP 8 /* # of sparc partitions */ +#define NX86MAP 16 /* # if x86 partitions */ +#define DKL_MAGIC 0xDABE /* magic number */ +#define DKL_MAGIC_0 0xDA /* magic number high byte */ +#define DKL_MAGIC_1 0xBE /* magic number low byte */ + +#define CD_DEFLABEL "CD-ROM Disc with Sun sparc boot created by genisoimage" +#define CD_X86LABEL "CD-ROM Disc with Sun x86 boot created by genisoimage" + +/* + * Define a virtual geometry for the CD disk label. + * The current values are stolen from Sun install disks and do not seem to be + * a good idea as they limit the size of the CD to 327680 sectors which is less + * than 74 minutes. + * There are 84 minute CD's with 378000 sectors and there will be DVD's with + * even more. + */ +#define CD_RPM 350 +#define CD_PCYL 2048 +#define CD_APC 0 +#define CD_INTRLV 1 +#define CD_NCYL 2048 +#define CD_ACYL 0 +#define CD_NHEAD 1 +#define CD_NSECT 640 + +/* + * NOTE: The virtual cylinder size on CD must be a mutiple of 2048. + * This is true if CD_NSECT is a multiple of 4. + */ +#define CD_CYLSIZE (CD_NSECT*CD_NHEAD*512) + +#define V_VERSION 1 /* The VTOC version */ +#define VTOC_SANE 0x600DDEEE /* Indicates a sane VTOC */ + +#define V_ROOT 0x02 /* Root partiton */ +#define V_USR 0x04 /* Usr partiton */ + +#define V_RONLY 0x10 /* Read only */ + +/* + * The Sun sparc disk label (at offset 0 on a disk) + */ +struct sun_label { + char dkl_ascilabel[128]; + struct dk_vtoc { + Uchar v_version[4]; /* layout version */ + char v_volume[8]; /* volume name */ + Uchar v_nparts[2]; /* number of partitions */ + struct dk_map2 { + Uchar p_tag[2]; /* ID tag of partition */ + Uchar p_flag[2]; /* permission flag */ + + } v_part[NDKMAP]; + Uchar v_xxpad[2]; /* To come over Sun's alignement problem */ + Uchar v_bootinfo[3*4]; /* info for mboot */ + Uchar v_sanity[4]; /* to verify vtoc sanity */ + Uchar v_reserved[10*4]; + Uchar v_timestamp[NDKMAP*4]; + + } dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ + char dkl_pad[512-(128+sizeof (struct dk_vtoc)+NDKMAP*8+14*2)]; + Uchar dkl_rpm[2]; /* rotations per minute */ + Uchar dkl_pcyl[2]; /* # physical cylinders */ + Uchar dkl_apc[2]; /* alternates per cylinder */ + Uchar dkl_obs1[2]; /* obsolete */ + Uchar dkl_obs2[2]; /* obsolete */ + Uchar dkl_intrlv[2]; /* interleave factor */ + Uchar dkl_ncyl[2]; /* # of data cylinders */ + Uchar dkl_acyl[2]; /* # of alternate cylinders */ + Uchar dkl_nhead[2]; /* # of heads in this partition */ + Uchar dkl_nsect[2]; /* # of 512 byte sectors per track */ + Uchar dkl_obs3[2]; /* obsolete */ + Uchar dkl_obs4[2]; /* obsolete */ + + struct dk_map { /* logical partitions */ + Uchar dkl_cylno[4]; /* starting cylinder */ + Uchar dkl_nblk[4]; /* number of blocks */ + } dkl_map[NDKMAP]; /* logical partition headers */ + + Uchar dkl_magic[2]; /* identifies this label format */ + Uchar dkl_cksum[2]; /* xor checksum of sector */ +}; + +/* + * The Sun x86 / AT&T disk label (at offset 512 on a fdisk partition) + */ +struct x86_label { + struct x86_vtoc { + Uchar v_bootinfo[3*4]; /* unsupported */ + Uchar v_sanity[4]; /* to verify vtoc sanity */ + Uchar v_version[4]; /* layout version */ + char v_volume[8]; /* volume name */ + Uchar v_sectorsz[2]; /* # of bytes in a sector */ + Uchar v_nparts[2]; /* # of partitions */ + Uchar v_reserved[10*4]; + struct dkl_partition { + Uchar p_tag[2]; /* ID tag of partition */ + Uchar p_flag[2]; /* permission flag */ + Uchar p_start[4]; /* starting sector */ + Uchar p_size[4]; /* number of blocks */ + } v_part[NX86MAP]; + Uchar timestamp[NX86MAP][4]; + char v_asciilabel[128]; + } dkl_vtoc; /* vtoc inclusions from AT&T SVr4 */ + Uchar dkl_pcyl[4]; /* # physical cylinders */ + Uchar dkl_ncyl[4]; /* # of data cylinders */ + Uchar dkl_acyl[2]; /* # of alternate cylinders */ + Uchar dkl_bcyl[2]; + Uchar dkl_nhead[4]; /* # of heads in this partition */ + Uchar dkl_nsect[4]; /* # of 512 byte sectors per track */ + Uchar dkl_intrlv[2]; /* interleave factor */ + Uchar dkl_skew[2]; + Uchar dkl_apc[2]; /* alternates per cylinder */ + Uchar dkl_rpm[2]; /* rotations per minute */ + Uchar dkl_write_reinstruct[2]; + Uchar dkl_read_reinstruct[2]; + Uchar dkl_extra[4*2]; /* for later expansions */ + char dkl_pad[512-(sizeof (struct x86_vtoc)+4*4+14*2)]; + Uchar dkl_magic[2]; /* identifies this label format */ + Uchar dkl_cksum[2]; /* xor checksum of sector */ +}; + +/* + * One x86 PC fdisk partition record. + */ +struct pc_pr { + Uchar pr_status; /* Boot status */ + Uchar pr_head; /* Starting head # */ + char pr_sec_cyl[2]; /* Starting sec+cyl # */ + Uchar pr_type; /* Partition type */ + Uchar pr_e_head; /* Ending head # */ + char pr_e_sec_cyl[2]; /* Ending sec+cyl # */ + char pr_partoff[4]; /* Partition start sector # */ + char pr_nsect[4]; /* # of sectors in partition */ +}; + +/* + * Flags and macros for above partition record. + */ +#define SEC_MASK 0x3F +#define GET_SEC(a) ((a) & SEC_MASK) +#define GET_CYL(a) ((((a) & 0xFF) >> 8) | (((a) & 0xC0) << 2)) + +#define STATUS_INACT 0 /* Marked non bootable */ +#define STATUS_ACTIVE 0x80 /* Marked as bootable */ + +#define TYPE_FREE 0 /* Unused partition */ +#define TYPE_DOS12 0x01 /* FAT12 fileystem */ +#define TYPE_XENIX 0x02 /* XENIX root */ +#define TYPE_XENIX2 0x03 /* XENIX usr */ +#define TYPE_DOS16 0x04 /* FAT16 filesystem */ +#define TYPE_XDOS 0x05 /* Extended DOS part */ +#define TYPE_DOS4 0x06 /* FAT16 >= 32 MB */ +#define TYPE_SOLARIS 0x82 /* Solaris x86 */ +#define TYPE_SOLARIS_BOOT 0xBE /* Solaris boot */ +#define TYPE_CDOS4 0xDB /* CPM */ + +/* + * The first sector on a disk from a x86 PC (at offset 0 on a disk) + */ +struct pc_part { + char bootcode[0x1BE]; /* Master boot record */ + struct pc_pr part[4]; /* The 4 primary partitions */ + Uchar magic[2]; /* Fixed at 0x55 0xAA */ +}; diff --git a/genisoimage/tree.c b/genisoimage/tree.c new file mode 100644 index 0000000..7805888 --- /dev/null +++ b/genisoimage/tree.c @@ -0,0 +1,2696 @@ +/* + * 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. + * + */ + +/* @(#)tree.c 1.82 04/06/12 joerg */ +/* + * File tree.c - scan directory tree and build memory structures for iso9660 + * filesystem + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-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 as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +#include <mconfig.h> +#include "genisoimage.h" +#include "match.h" +#include "udf.h" +#include "exclude.h" +#include <timedefs.h> +#include <errno.h> +#include <fctldefs.h> +#include <device.h> +#include <schily.h> + +extern int allow_limited_size; + +#ifdef VMS +#include <sys/file.h> +#include <vms/fabdef.h> +#include "vms.h" +#endif + +/* + * Autoconf should be able to figure this one out for us and let us know + * whether the system has memmove or not. + */ +#ifndef HAVE_MEMMOVE +#define memmove(d, s, n) bcopy((s), (d), (n)) +#endif + +static Uchar symlink_buff[PATH_MAX+1]; + +static char *filetype(int t); +static char *rstr(char *s1, char *s2); +static void stat_fix(struct stat * st); +int stat_filter(char *path, struct stat *st); +int lstat_filter(char *path, struct stat *st); +static int sort_n_finish(struct directory *this_dir); +static void generate_reloc_directory(void); +static void attach_dot_entries(struct directory *dirnode, struct stat *dir_stat, + struct stat *parent_stat); +static void update_nlink(struct directory_entry *s_entry, int value); +static void increment_nlink(struct directory_entry *s_entry); +char *find_rr_attribute(unsigned char *pnt, int len, char *attr_type); +void finish_cl_pl_entries(void); +int scan_directory_tree(struct directory *this_dir, char *path, + struct directory_entry *de); +#ifdef APPLE_HYB +int insert_file_entry(struct directory *this_dir, + char *whole_path, + char *short_name, + int have_rsrc); +#else +int insert_file_entry(struct directory *this_dir, + char *whole_path, + char *short_name); +#endif +void generate_iso9660_directories(struct directory *node, + FILE *outfile); +struct directory *find_or_create_directory(struct directory *parent, + const char *path, + struct directory_entry *de, + int flag, + struct stat* stat_template); +static void delete_directory(struct directory *parent, + struct directory *child); +int sort_tree(struct directory *node); +void dump_tree(struct directory *node); +void update_nlink_field(struct directory *node); +struct directory_entry *search_tree_file(struct directory *node, + char *filename); +void init_fstatbuf(void); + +extern int verbose; +struct stat fstatbuf; /* We use this for the artificial */ + /* entries we create */ +struct stat root_statbuf; /* Stat buffer for root directory */ +struct directory *reloc_dir; + +static char * +filetype(int t) +{ + static char unkn[32]; + + if (S_ISFIFO(t)) /* 1 */ + return ("fifo"); + if (S_ISCHR(t)) /* 2 */ + return ("chr"); + if (S_ISMPC(t)) /* 3 */ + return ("multiplexed chr"); + if (S_ISDIR(t)) /* 4 */ + return ("dir"); + if (S_ISNAM(t)) /* 5 */ + return ("named file"); + if (S_ISBLK(t)) /* 6 */ + return ("blk"); + if (S_ISMPB(t)) /* 7 */ + return ("multiplexed blk"); + if (S_ISREG(t)) /* 8 */ + return ("regular file"); + if (S_ISCNT(t)) /* 9 */ + return ("contiguous file"); + if (S_ISLNK(t)) /* 10 */ + return ("symlink"); + if (S_ISSHAD(t)) /* 11 */ + return ("Solaris shadow inode"); + if (S_ISSOCK(t)) /* 12 */ + return ("socket"); + if (S_ISDOOR(t)) /* 13 */ + return ("door"); + if (S_ISWHT(t)) /* 14 */ + return ("whiteout"); + if (S_ISEVC(t)) /* 15 */ + return ("event count"); + + /* + * Needs to be last in case somebody makes this + * a supported file type. + */ + if ((t & S_IFMT) == 0) /* 0 (unallocated) */ + return ("unallocated"); + + sprintf(unkn, "octal '%o'", t & S_IFMT); + return (unkn); +} + +/* + * Check if s1 ends in strings s2 + */ +static char * +rstr(char *s1, char *s2) +{ + int l1; + int l2; + + l1 = strlen(s1); + l2 = strlen(s2); + if (l2 > l1) + return ((char *) NULL); + + if (strcmp(&s1[l1 - l2], s2) == 0) + return (&s1[l1 - l2]); + return ((char *) NULL); +} + +static void +stat_fix(struct stat *st) +{ + int adjust_modes = 0; + + if (S_ISREG(st->st_mode)) + adjust_modes = rationalize_filemode; + else if (S_ISDIR(st->st_mode)) + adjust_modes = rationalize_dirmode; + else + adjust_modes = (rationalize_filemode || rationalize_dirmode); + + /* + * If rationalizing, override the uid and gid, since the + * originals will only be useful on the author's system. + */ + if (rationalize_uid) + st->st_uid = uid_to_use; + if (rationalize_gid) + st->st_gid = gid_to_use; + + if (adjust_modes) { + + if (S_ISREG(st->st_mode) && (filemode_to_use != 0)) { + st->st_mode = filemode_to_use | S_IFREG; + } else if (S_ISDIR(st->st_mode) && (dirmode_to_use != 0)) { + st->st_mode = dirmode_to_use | S_IFDIR; + } else { + /* + * Make sure the file modes make sense. Turn + * on all read bits. Turn on all exec/search + * bits if any exec/search bit is set. Turn + * off all write bits, and all special mode + * bits (on a r/o fs lock bits are useless, + * and with uid+gid 0 don't want set-id bits, + * either). + */ + + st->st_mode |= 0444; +#if !defined(_WIN32) && !defined(__DJGPP__) /* make all file "executable" */ + if (st->st_mode & 0111) +#endif + st->st_mode |= 0111; + st->st_mode &= ~07222; + } + } +} + +int +stat_filter(char *path, struct stat *st) +{ + int result = stat(path, st); + + if (result >= 0 && rationalize) + stat_fix(st); + return (result); +} + +int +lstat_filter(char *path, struct stat *st) +{ + int result = lstat(path, st); + + if (result >= 0 && rationalize) + stat_fix(st); + return (result); +} + +static int +sort_n_finish(struct directory *this_dir) +{ + struct directory_entry *s_entry; + struct directory_entry *s_entry1; + struct directory_entry *table; + int count; + int d1; + int d2; + int d3; + register int new_reclen; + char *c; + int status = 0; + int tablesize = 0; + char newname[MAX_ISONAME+1]; + char rootname[MAX_ISONAME+1]; + char extname[MAX_ISONAME+1]; + + /* + * Here we can take the opportunity to toss duplicate entries from the + * directory. + */ + /* ignore if it's hidden */ + if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { + return (0); + } + table = NULL; + + init_fstatbuf(); + + /* + * If we had artificially created this directory, then we might be + * missing the required '.' entries. Create these now if we need + * them. + */ + if ((this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != + (DIR_HAS_DOT | DIR_HAS_DOTDOT)) { + fstatbuf.st_mode = new_dir_mode | S_IFDIR; + fstatbuf.st_nlink = 2; + attach_dot_entries(this_dir, &fstatbuf, &fstatbuf); + } + flush_file_hash(); + s_entry = this_dir->contents; + while (s_entry) { + /* ignore if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + s_entry = s_entry->next; + continue; + } + /* First assume no conflict, and handle this case */ + if (!(s_entry1 = find_file_hash(s_entry->isorec.name))) { + add_file_hash(s_entry); + s_entry = s_entry->next; + continue; + } +#ifdef APPLE_HYB + /* + * if the pair are associated, then skip (as they have the + * same name!) + */ + if (apple_both && s_entry1->assoc && + s_entry1->assoc == s_entry) { + s_entry = s_entry->next; + continue; + } +#endif /* APPLE_HYB */ + + if (s_entry1 == s_entry) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Fatal goof, file '%s' already in hash table.\n", + s_entry->isorec.name); +#else + fprintf(stderr, + "Fatal goof, file '%s' already in hash table.\n", + s_entry->isorec.name); + exit(1); +#endif + } + /* + * OK, handle the conflicts. Try substitute names until we + * come up with a winner + */ + strcpy(rootname, s_entry->isorec.name); + /* + * Strip off the non-significant part of the name so that we + * are left with a sensible root filename. If we don't find + * a '.', then try a ';'. + */ + c = strchr(rootname, '.'); + /* + * In case we ever allow more than on dot, only modify the + * section past the last dot if the file name starts with a + * dot. + */ + if (c != NULL && c == rootname && c != strrchr(rootname, '.')) { + c = strrchr(rootname, '.'); + } + extname[0] = '\0'; /* In case we have no ext. */ + if (c) { + strcpy(extname, c); + *c = 0; /* Cut off complete ext. */ + } else { + /* + * Could not find any '.'. + */ + c = strchr(rootname, ';'); + if (c) { + *c = 0; /* Cut off version number */ + } + } + c = strchr(extname, ';'); + if (c) { + *c = 0; /* Cut off version number */ + } + d1 = strlen(rootname); + if (full_iso9660_filenames || iso9660_level > 1) { + d2 = strlen(extname); + /* + * 31/37 chars minus the 3 characters we are + * appending below to create unique filenames. + */ + if ((d1 + d2) > (iso9660_namelen - 3)) + rootname[iso9660_namelen - 3 - d2] = 0; + } else { + if (d1 > 5) + rootname[5] = 0; + } + new_reclen = strlen(rootname); + sprintf(newname, "%s000%s%s", + rootname, + extname, + ((s_entry->isorec.flags[0] & ISO_DIRECTORY) || + omit_version_number ? "" : ";1")); + + for (d1 = 0; d1 < 36; d1++) { + for (d2 = 0; d2 < 36; d2++) { + for (d3 = 0; d3 < 36; d3++) { + newname[new_reclen + 0] = + (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10); + newname[new_reclen + 1] = + (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10); + newname[new_reclen + 2] = + (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10); + if (debug) + fprintf(stderr, "NEW name '%s'\n", newname); + +#ifdef VMS + /* Sigh. VAXCRTL seems to be broken here */ + { + int ijk = 0; + + while (newname[ijk]) { + if (newname[ijk] == ' ') + newname[ijk] = '0'; + ijk++; + } + } +#endif + + if (!find_file_hash(newname)) + goto got_valid_name; + } + } + } + + /* If we fell off the bottom here, we were in real trouble. */ +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to generate unique name for file %s\n", + s_entry->name); +#else + fprintf(stderr, + "Unable to generate unique name for file %s\n", + s_entry->name); + exit(1); +#endif + +got_valid_name: + /* + * OK, now we have a good replacement name. Now decide which + * one of these two beasts should get the name changed + */ + if (s_entry->priority < s_entry1->priority) { + if (verbose > 0) { + fprintf(stderr, "Using %s for %s%s%s (%s)\n", + newname, + this_dir->whole_name, SPATH_SEPARATOR, + s_entry->name, s_entry1->name); + } + s_entry->isorec.name_len[0] = strlen(newname); + new_reclen = offsetof(struct iso_directory_record, + name[0]) + + strlen(newname); + if (use_XA || use_RockRidge) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += s_entry->rr_attr_size; + } + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + s_entry->isorec.length[0] = new_reclen; + strcpy(s_entry->isorec.name, newname); +#ifdef APPLE_HYB + /* has resource fork - needs new name */ + if (apple_both && s_entry->assoc) { + struct directory_entry *s_entry2 = + s_entry->assoc; + + /* + * resource fork name *should* be the same as + * the data fork + */ + s_entry2->isorec.name_len[0] = + s_entry->isorec.name_len[0]; + strcpy(s_entry2->isorec.name, + s_entry->isorec.name); + s_entry2->isorec.length[0] = new_reclen; + } +#endif /* APPLE_HYB */ + } else { + delete_file_hash(s_entry1); + if (verbose > 0) { + fprintf(stderr, "Using %s for %s%s%s (%s)\n", + newname, + this_dir->whole_name, SPATH_SEPARATOR, + s_entry1->name, s_entry->name); + } + s_entry1->isorec.name_len[0] = strlen(newname); + new_reclen = offsetof(struct iso_directory_record, + name[0]) + + strlen(newname); + if (use_XA || use_RockRidge) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += s_entry1->rr_attr_size; + } + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + s_entry1->isorec.length[0] = new_reclen; + strcpy(s_entry1->isorec.name, newname); + add_file_hash(s_entry1); +#ifdef APPLE_HYB + /* has resource fork - needs new name */ + if (apple_both && s_entry1->assoc) { + struct directory_entry *s_entry2 = + s_entry1->assoc; + + /* + * resource fork name *should* be the same as + * the data fork + */ + s_entry2->isorec.name_len[0] = + s_entry1->isorec.name_len[0]; + strcpy(s_entry2->isorec.name, + s_entry1->isorec.name); + s_entry2->isorec.length[0] = new_reclen; + } +#endif /* APPLE_HYB */ + } + add_file_hash(s_entry); + s_entry = s_entry->next; + } + + if (generate_tables && + !find_file_hash(trans_tbl) && + (reloc_dir != this_dir) && + (this_dir->extent == 0)) { + /* First we need to figure out how big this table is */ + for (s_entry = this_dir->contents; s_entry; + s_entry = s_entry->next) { + if (strcmp(s_entry->name, ".") == 0 || + strcmp(s_entry->name, "..") == 0) + continue; +#ifdef APPLE_HYB + /* skip table entry for the resource fork */ + if (apple_both && + (s_entry->isorec.flags[0] & ISO_ASSOCIATED)) + continue; +#endif /* APPLE_HYB */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + continue; + if (s_entry->table) { + /* + * Max namelen, a space before and a space + * after the iso filename. + */ + tablesize += MAX_ISONAME + 2 + + strlen(s_entry->table); + } + } + } + if (tablesize > 0) { + table = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(table, 0, sizeof (struct directory_entry)); + table->table = NULL; + table->next = this_dir->contents; + this_dir->contents = table; + + table->filedir = root; + table->isorec.flags[0] = ISO_FILE; + table->priority = 32768; + iso9660_date(table->isorec.date, fstatbuf.st_mtime); + table->inode = TABLE_INODE; + table->dev = (dev_t) UNCACHED_DEVICE; + set_723(table->isorec.volume_sequence_number, + volume_sequence_number); + set_733((char *) table->isorec.size, tablesize); + table->realsize = tablesize; + table->size = tablesize; + table->filedir = this_dir; + if (jhide_trans_tbl) + table->de_flags |= INHIBIT_JOLIET_ENTRY; +/* table->name = strdup("<translation table>");*/ + table->name = strdup(trans_tbl); + /* + * We use sprintf() to create the strings, for this reason + * we need to add one byte for the null character at the + * end of the string even though we don't use it. + */ + table->table = (char *) e_malloc(ISO_ROUND_UP(tablesize)+1); + memset(table->table, 0, ISO_ROUND_UP(tablesize)+1); + iso9660_file_length(trans_tbl, table, 0); + + if (use_XA || use_RockRidge) { + fstatbuf.st_mode = 0444 | S_IFREG; + fstatbuf.st_nlink = 1; + generate_xa_rr_attributes("", + trans_tbl, table, + &fstatbuf, &fstatbuf, 0); + } + } + /* + * We have now chosen the 8.3 names and we should now know the length + * of every entry in the directory. + */ + for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + continue; + } + new_reclen = strlen(s_entry->isorec.name); + + /* First update the path table sizes for directories. */ + if (s_entry->isorec.flags[0] & ISO_DIRECTORY) { + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { + path_table_size += new_reclen + + offsetof(struct iso_path_table, + name[0]); + if (new_reclen & 1) + path_table_size++; + } else { + new_reclen = 1; + if (this_dir == root && strlen(s_entry->name) + == 1) { + path_table_size += new_reclen + + offsetof(struct iso_path_table, + name[0]); + } + } + } + if (path_table_size & 1) + path_table_size++; /* For odd lengths we pad */ + s_entry->isorec.name_len[0] = new_reclen; + + new_reclen += offsetof(struct iso_directory_record, name[0]); + + if (new_reclen & 1) + new_reclen++; + + new_reclen += s_entry->rr_attr_size; + + if (new_reclen & 1) + new_reclen++; + + if (new_reclen > 0xff) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Fatal error - RR overflow (reclen %d) for file %s\n", + new_reclen, + s_entry->name); +#else + fprintf(stderr, + "Fatal error - RR overflow (reclen %d) for file %s\n", + new_reclen, + s_entry->name); + exit(1); +#endif + } + s_entry->isorec.length[0] = new_reclen; + } + + status = sort_directory(&this_dir->contents, (reloc_dir == this_dir)); + if (status > 0) { + fprintf(stderr, "Unable to sort directory %s\n", + this_dir->whole_name); + if(merge_warn_msg) + fprintf(stderr, merge_warn_msg); + exit(1); + } + /* + * If we are filling out a TRANS.TBL, generate the entries that will + * go in the thing. + */ + if (table) { + count = 0; + for (s_entry = this_dir->contents; s_entry; + s_entry = s_entry->next) { + if (s_entry == table) + continue; + if (!s_entry->table) + continue; + if (strcmp(s_entry->name, ".") == 0 || + strcmp(s_entry->name, "..") == 0) + continue; +#ifdef APPLE_HYB + /* skip table entry for the resource fork */ + if (apple_both && + (s_entry->isorec.flags[0] & ISO_ASSOCIATED)) + continue; +#endif /* APPLE_HYB */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + continue; + /* + * Warning: we cannot use the return value of sprintf + * because old BSD based sprintf() implementations + * will return a pointer to the result instead of a + * count. + * Old mkiofs introduced a space after the iso + * filename to make parsing TRANS.TBL easier. + */ + sprintf(table->table + count, "%c %-*s%s", + s_entry->table[0], + MAX_ISONAME + 1, + s_entry->isorec.name, s_entry->table + 1); + count += strlen(table->table + count); + free(s_entry->table); + /* + * for a memory file, set s_entry->table to the + * correct data - which is stored in + * s_entry->whole_name + */ + if (s_entry->de_flags & MEMORY_FILE) { + s_entry->table = s_entry->whole_name; + s_entry->whole_name = NULL; + } else { + s_entry->table = NULL; + } + } + + if (count != tablesize) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Translation table size mismatch %d %d\n", + count, tablesize); +#else + fprintf(stderr, + "Translation table size mismatch %d %d\n", + count, tablesize); + exit(1); +#endif + } + } + /* + * Now go through the directory and figure out how large this one will + * be. Do not split a directory entry across a sector boundary + */ + s_entry = this_dir->contents; + this_dir->ce_bytes = 0; + while (s_entry) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + s_entry = s_entry->next; + continue; + } + new_reclen = s_entry->isorec.length[0]; + if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen + >= SECTOR_SIZE) + + this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & + ~(SECTOR_SIZE - 1); + this_dir->size += new_reclen; + + /* See if continuation entries were used on disc */ + if (use_RockRidge && + s_entry->rr_attr_size != s_entry->total_rr_attr_size) { + unsigned char *pnt; + int len; + int nbytes; + + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + pnt = parse_xa(pnt, &len, 0); +/* pnt = parse_xa(pnt, &len, s_entry);*/ + + /* + * We make sure that each continuation entry record is + * not split across sectors, but each file could in + * theory have more than one CE, so we scan through + * and figure out what we need. + */ + while (len > 3) { + if (pnt[0] == 'C' && pnt[1] == 'E') { + nbytes = get_733((char *) pnt + 20); + + if ((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= + SECTOR_SIZE) + this_dir->ce_bytes = + ISO_ROUND_UP(this_dir->ce_bytes); + /* + * Now store the block in the + * ce buffer + */ + this_dir->ce_bytes += nbytes; + if (this_dir->ce_bytes & 1) + this_dir->ce_bytes++; + } + len -= pnt[2]; + pnt += pnt[2]; + } + } + s_entry = s_entry->next; + } + return (status); +} + +static void +generate_reloc_directory() +{ + time_t current_time; + struct directory_entry *s_entry; + + /* Create an entry for our internal tree */ + time(¤t_time); + reloc_dir = (struct directory *) + e_malloc(sizeof (struct directory)); + memset(reloc_dir, 0, sizeof (struct directory)); + reloc_dir->parent = root; + reloc_dir->next = root->subdir; + root->subdir = reloc_dir; + reloc_dir->depth = 1; + if (hide_rr_moved) { + reloc_dir->whole_name = strdup("./.rr_moved"); + reloc_dir->de_name = strdup(".rr_moved"); + } else { + reloc_dir->whole_name = strdup("./rr_moved"); + reloc_dir->de_name = strdup("rr_moved"); + } + reloc_dir->extent = 0; + + + /* Now create an actual directory entry */ + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = root->contents; + reloc_dir->self = s_entry; + + /* The rr_moved entry will not appear in the Joliet tree. */ + reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + + /* Hiding RR_MOVED seems not to be possible..... */ +#ifdef HIDE_RR + reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; +#endif + + root->contents = s_entry; + root->contents->name = strdup(reloc_dir->de_name); + root->contents->filedir = root; + root->contents->isorec.flags[0] = ISO_DIRECTORY; + root->contents->priority = 32768; + iso9660_date(root->contents->isorec.date, current_time); + root->contents->inode = UNCACHED_INODE; + root->contents->dev = (dev_t) UNCACHED_DEVICE; + set_723(root->contents->isorec.volume_sequence_number, + volume_sequence_number); + iso9660_file_length(reloc_dir->de_name, root->contents, 1); + + init_fstatbuf(); + + if (use_XA || use_RockRidge) { + fstatbuf.st_mode = 0555 | S_IFDIR; + fstatbuf.st_nlink = 2; + generate_xa_rr_attributes("", + hide_rr_moved ? ".rr_moved" : "rr_moved", + s_entry, &fstatbuf, &fstatbuf, 0); + }; + + /* Now create the . and .. entries in rr_moved */ + /* Now create an actual directory entry */ + memset(&root_statbuf, 0x0, sizeof(struct stat)); /* be sure */ + attach_dot_entries(reloc_dir, &fstatbuf, &root_statbuf); +} + +/* + * Function: attach_dot_entries + * + * Purpose: Create . and .. entries for a new directory. + * + * Arguments: dir_stat contains the ownership/permission information + * for dirnode, and parent_stat contains + * ownership/permission information for its parent + * + * + * Notes: Only used for artificial directories that + * we are creating. + */ +static void +attach_dot_entries(struct directory *dirnode, struct stat *dir_stat, + struct stat *parent_stat) +{ + struct directory_entry *s_entry; + struct directory_entry *orig_contents; + int deep_flag = 0; + + init_fstatbuf(); + + orig_contents = dirnode->contents; + + if ((dirnode->dir_flags & DIR_HAS_DOTDOT) == 0) { + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry, dirnode->self, + sizeof (struct directory_entry)); +#ifdef APPLE_HYB + if (dirnode->self->hfs_ent) { + s_entry->hfs_ent = (hfsdirent *) + e_malloc(sizeof (hfsdirent)); + memcpy(s_entry->hfs_ent, dirnode->self->hfs_ent, + sizeof (hfsdirent)); + } +#endif + s_entry->name = strdup(".."); + s_entry->whole_name = NULL; + s_entry->isorec.name_len[0] = 1; + s_entry->isorec.flags[0] = ISO_DIRECTORY; + iso9660_file_length("..", s_entry, 1); + iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733(s_entry->isorec.size, SECTOR_SIZE); + s_entry->realsize = SECTOR_SIZE; + memset(s_entry->isorec.extent, 0, 8); + s_entry->filedir = dirnode->parent; + + dirnode->contents = s_entry; + dirnode->contents->next = orig_contents; + orig_contents = s_entry; + + if (use_XA || use_RockRidge) { + generate_xa_rr_attributes("", + "..", s_entry, + parent_stat, + parent_stat, 0); + } + dirnode->dir_flags |= DIR_HAS_DOTDOT; + } + if ((dirnode->dir_flags & DIR_HAS_DOT) == 0) { + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry, dirnode->self, + sizeof (struct directory_entry)); +#ifdef APPLE_HYB + if (dirnode->self->hfs_ent) { + s_entry->hfs_ent = (hfsdirent *) + e_malloc(sizeof (hfsdirent)); + memcpy(s_entry->hfs_ent, dirnode->self->hfs_ent, + sizeof (hfsdirent)); + } +#endif + s_entry->name = strdup("."); + s_entry->whole_name = NULL; + s_entry->isorec.name_len[0] = 1; + s_entry->isorec.flags[0] = ISO_DIRECTORY; + iso9660_file_length(".", s_entry, 1); + iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733(s_entry->isorec.size, SECTOR_SIZE); + s_entry->realsize=SECTOR_SIZE; + memset(s_entry->isorec.extent, 0, 8); + s_entry->filedir = dirnode; + + dirnode->contents = s_entry; + dirnode->contents->next = orig_contents; + + if (use_XA || use_RockRidge) { + + if (dirnode == root) { + deep_flag |= NEED_CE | NEED_SP; /* For extension record */ + } + generate_xa_rr_attributes("", ".", s_entry, + dir_stat, dir_stat, deep_flag); + } + dirnode->dir_flags |= DIR_HAS_DOT; + } +} + +static void +update_nlink(struct directory_entry *s_entry, int value) +{ + unsigned char *pnt; + int len; + + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + pnt = parse_xa(pnt, &len, 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#endif + } + if (pnt[0] == 'P' && pnt[1] == 'X') { + set_733((char *) pnt + 12, value); + break; + } + len -= pnt[2]; + pnt += pnt[2]; + } +} + +static void +increment_nlink(struct directory_entry *s_entry) +{ + unsigned char *pnt; + int len, + nlink; + + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + pnt = parse_xa(pnt, &len, 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#endif + } + if (pnt[0] == 'P' && pnt[1] == 'X') { + nlink = get_733((char *) pnt + 12); + set_733((char *) pnt + 12, nlink + 1); + break; + } + len -= pnt[2]; + pnt += pnt[2]; + } +} + +char * +find_rr_attribute(unsigned char *pnt, int len, char *attr_type) +{ + pnt = parse_xa(pnt, &len, 0); + while (len >= 4) { + if (pnt[3] != 1 && pnt[3] != 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#else + fprintf(stderr, + "**BAD RRVERSION (%d) for %c%c\n", + pnt[3], pnt[0], pnt[1]); +#endif + } + if (strncmp((char *) pnt, attr_type, 2) == 0) + return ((char *) pnt); + else if (strncmp((char *) pnt, "ST", 2) == 0) + return (NULL); + len -= pnt[2]; + pnt += pnt[2]; + } + return (NULL); +} + +void +finish_cl_pl_entries() +{ + struct directory_entry *s_entry; + struct directory_entry *s_entry1; + struct directory *d_entry; + + /* if the reloc_dir is hidden (empty), then return */ + if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY) + return; + + s_entry = reloc_dir->contents; + s_entry = s_entry->next->next; /* Skip past . and .. */ + for (; s_entry; s_entry = s_entry->next) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + continue; + } + d_entry = reloc_dir->subdir; + while (d_entry) { + if (d_entry->self == s_entry) + break; + d_entry = d_entry->next; + }; + if (!d_entry) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to locate directory parent\n"); +#else + fprintf(stderr, "Unable to locate directory parent\n"); + exit(1); +#endif + }; + + if (s_entry->filedir != NULL && s_entry->parent_rec != NULL) { + char *rr_attr; + + /* + * First fix the PL pointer in the directory in the + * rr_reloc dir + */ + s_entry1 = d_entry->contents->next; + +/* set_733((char *) s_entry1->rr_attributes +*/ +/* s_entry1->total_rr_attr_size - 8,*/ +/* s_entry->filedir->extent); */ + /* + * The line above won't work when entry was read from + * the previous session, because if total_rr_attr_size + * was odd when recording previous session, now we have + * total_rr_attr_size off by 1 due to padding. + * + * So, just search for the attributes by name + */ + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "PL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, s_entry->filedir->extent); + + + /* Now fix the CL pointer */ + s_entry1 = s_entry->parent_rec; + +/* set_733((char *) s_entry1->rr_attributes +*/ +/* s_entry1->total_rr_attr_size - 8, d_entry->extent); */ + rr_attr = find_rr_attribute(s_entry1->rr_attributes, + s_entry1->total_rr_attr_size, "CL"); + if (rr_attr != NULL) + set_733(rr_attr + 4, d_entry->extent); + } + s_entry->filedir = reloc_dir; /* Now we can fix this */ + } + /* + * Next we need to modify the NLINK terms in the assorted root + * directory records to account for the presence of the RR_MOVED + * directory + */ + increment_nlink(root->self); + increment_nlink(root->self->next); + d_entry = root->subdir; + while (d_entry) { + increment_nlink(d_entry->contents->next); + d_entry = d_entry->next; + }; + + finish_cl_pl_for_prev_session(); +} + +/* + * Function: scan_directory_tree + * + * Purpose: Walk through a directory on the local machine + * filter those things we don't want to include + * and build our representation of a dir. + * + * Notes: + */ +int +scan_directory_tree(struct directory *this_dir, char *path, + struct directory_entry *de) +{ + DIR *current_dir; + char whole_path[PATH_MAX]; + struct dirent *d_entry; + struct directory *parent; + int dflag; + char *old_path; + + if (verbose > 1) { + fprintf(stderr, "Scanning %s\n", path); + } +/*#define check_needed*/ +#ifdef check_needed + /* + * Trying to use this to avoid directory loops from hard links + * or followed symlinks does not work. It would prevent us from + * implementing merge directories. + */ + if (this_dir->dir_flags & DIR_WAS_SCANNED) { + fprintf(stderr, "Already scanned directory %s\n", path); + return (1); /* It's a directory */ + } +#endif + this_dir->dir_flags |= DIR_WAS_SCANNED; + + errno = 0; /* Paranoia */ + current_dir = opendir(path); + d_entry = NULL; + + /* + * Apparently NFS sometimes allows you to open the directory, but then + * refuses to allow you to read the contents. Allow for this + */ + old_path = path; + + if (current_dir) { + errno = 0; + d_entry = readdir(current_dir); + } + + if (!current_dir || !d_entry) { + int ret = 1; + +#ifdef USE_LIBSCHILY + errmsg("Unable to open directory %s\n", path); +#else + fprintf(stderr, "Unable to open directory %s\n", path); +#endif + if (errno == ENOTDIR) { + /* Mark as not a directory */ + de->isorec.flags[0] &= ~ISO_DIRECTORY; + ret = 0; + } + if (current_dir) + closedir(current_dir); + return (ret); + } +#ifdef ABORT_DEEP_ISO_ONLY + if ((this_dir->depth > RR_relocation_depth) && !use_RockRidge) { + static BOOL did_hint = FALSE; + + errmsgno(EX_BAD, + "Directories too deep for '%s' (%d) max is %d; ignored - continuing.\n", + path, this_dir->depth, RR_relocation_depth); + if (!did_hint) { + did_hint = TRUE; + errmsgno(EX_BAD, "To include the complete directory tree,\n"); + errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n"); + errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n"); + } + closedir(current_dir); + return (1); + } +#endif + + parent = de->filedir; + /* + * Set up the struct for the current directory, and insert it into + * the tree + */ +#ifdef VMS + vms_path_fixup(path); +#endif + + /* + * if entry for this sub-directory is hidden, then hide this directory + */ + if (de->de_flags & INHIBIT_ISO9660_ENTRY) + this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; + + if (de->de_flags & INHIBIT_JOLIET_ENTRY) + this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; + +#ifdef SORTING + /* + * set any sort weighting from it's own directory entry - if a + * directory is given a weighting, then all the contents will use + * this as the default weighting + */ + this_dir->sort = de->sort; +#endif /* SORTING */ + + /* + * Now we scan the directory itself, and look at what is inside of it. + */ + dflag = 0; + while (1 == 1) { + + /* + * The first time through, skip this, since we already asked + * for the first entry when we opened the directory. + */ + if (dflag) + d_entry = readdir(current_dir); + dflag++; + + if (!d_entry) + break; + + /* OK, got a valid entry */ + + /* If we do not want all files, then pitch the backups. */ + if (!all_files) { + if (strchr(d_entry->d_name, '~') || + strchr(d_entry->d_name, '#') || + rstr(d_entry->d_name, ".bak")) { + if (verbose > 0) { + fprintf(stderr, + "Ignoring file %s\n", + d_entry->d_name); + } + continue; + } + } +#ifdef APPLE_HYB + if (apple_both) { + /* + * exclude certain HFS type files/directories for the + * time being + */ + if (hfs_exclude(d_entry->d_name)) + continue; + } +#endif /* APPLE_HYB */ + + if (strlen(path) + strlen(d_entry->d_name) + 2 > + sizeof (whole_path)) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, "Path name %s/%s too long.\n", + path, d_entry->d_name); + comerrno(EX_BAD, "Overflow of stat buffer\n"); +#else + fprintf(stderr, "Path name %s/%s too long.\n", + path, d_entry->d_name); + fprintf(stderr, "Overflow of stat buffer\n"); + exit(1); +#endif + }; + + /* Generate the complete ASCII path for this file */ + strcpy(whole_path, path); +#ifndef VMS + if (whole_path[strlen(whole_path) - 1] != '/') + strcat(whole_path, "/"); +#endif + strcat(whole_path, d_entry->d_name); + + /** Should we exclude this file ? */ + if (matches(d_entry->d_name) || matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + "Excluded by match: %s\n", whole_path); + } + continue; + } + if (generate_tables && + strcmp(d_entry->d_name, trans_tbl) == 0) { + /* + * Ignore this entry. We are going to be generating + * new versions of these files, and we need to ignore + * any originals that we might have found. + */ + if (verbose > 1) { + fprintf(stderr, "Excluded: %s\n", whole_path); + } + continue; + } + /* + * If we already have a '.' or a '..' entry, then don't insert + * new ones. + */ + if (strcmp(d_entry->d_name, ".") == 0 && + this_dir->dir_flags & DIR_HAS_DOT) { + continue; + } + if (strcmp(d_entry->d_name, "..") == 0 && + this_dir->dir_flags & DIR_HAS_DOTDOT) { + continue; + } +#if 0 + if (verbose > 1) + fprintf(stderr, "%s\n", whole_path); +#endif + /* This actually adds the entry to the directory in question.*/ +#ifdef APPLE_HYB + insert_file_entry(this_dir, whole_path, d_entry->d_name, 0); +#else + insert_file_entry(this_dir, whole_path, d_entry->d_name); +#endif /* APPLE_HYB */ + } + closedir(current_dir); + +#ifdef APPLE_HYB + /* + * if we cached the HFS info stuff for this directory, then delete it + */ + if (this_dir->hfs_info) { + del_hfs_info(this_dir->hfs_info); + this_dir->hfs_info = 0; + } +#endif /* APPLE_HYB */ + + return (1); +} + + +/* + * Function: insert_file_entry + * + * Purpose: Insert one entry into our directory node. + * + * Note: + * This function inserts a single entry into the directory. It + * is assumed that all filtering and decision making regarding what + * we want to include has already been made, so the purpose of this + * is to insert one entry (file, link, dir, etc), into this directory. + * Note that if the entry is a dir (or if we are following links, + * and the thing it points to is a dir), then we will scan those + * trees before we return. + */ +#ifdef APPLE_HYB +int +insert_file_entry(struct directory *this_dir, char *whole_path, + char *short_name, int have_rsrc) +#else +int +insert_file_entry(struct directory *this_dir, char *whole_path, + char *short_name) +#endif /* APPLE_HYB */ +{ + struct stat statbuf, + lstatbuf; + struct directory_entry *s_entry, + *s_entry1; + int lstatus; + int status; + int deep_flag; + int no_scandir = 0; + +#ifdef APPLE_HYB + int x_hfs = 0; + int htype = TYPE_NONE; + +#endif /* APPLE_HYB */ + + status = stat_filter(whole_path, &statbuf); + + lstatus = lstat_filter(whole_path, &lstatbuf); + + if ((status == -1) && (lstatus == -1)) { + /* + * This means that the file doesn't exist, or isn't accessible. + * Sometimes this is because of NFS permissions problems. + */ +#ifdef USE_LIBSCHILY + errmsg("Non-existent or inaccessible: %s\n", whole_path); +#else + fprintf(stderr, "Non-existent or inaccessible: %s\n", + whole_path); +#endif + return (0); + } + if (this_dir == root && strcmp(short_name, ".") == 0) + root_statbuf = statbuf; /* Save this for later on */ + + /* We do this to make sure that the root entries are consistent */ + if (this_dir == root && strcmp(short_name, "..") == 0) { + statbuf = root_statbuf; + lstatbuf = root_statbuf; + } + if (S_ISLNK(lstatbuf.st_mode)) { + + /* + * Here we decide how to handle the symbolic links. Here we + * handle the general case - if we are not following links or + * there is an error, then we must change something. If RR + * is in use, it is easy, we let RR describe the file. If + * not, then we punt the file. + */ + if ((status || !follow_links)) { + if (use_RockRidge) { + status = 0; + statbuf.st_size = (off_t)0; + STAT_INODE(statbuf) = UNCACHED_INODE; + statbuf.st_dev = (dev_t) UNCACHED_DEVICE; + statbuf.st_mode = + (statbuf.st_mode & ~S_IFMT) | S_IFREG; + } else { + if (follow_links) { +#ifdef USE_LIBSCHILY + /* XXX errno may be wrong! */ + errmsg("Unable to stat file %s - ignoring and continuing.\n", + whole_path); +#else + fprintf(stderr, + "Unable to stat file %s - ignoring and continuing.\n", + whole_path); +#endif + } else { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Symlink %s ignored - continuing.\n", + whole_path); +#else + fprintf(stderr, + "Symlink %s ignored - continuing.\n", + whole_path); +#endif + return (0); /* Non Rock Ridge discs */ + /* - ignore all symlinks */ + } + } + } + /* + * Here we handle a different kind of case. Here we have a + * symlink, but we want to follow symlinks. If we run across + * a directory loop, then we need to pretend that we are not + * following symlinks for this file. If this is the first + * time we have seen this, then make this seem as if there was + * no symlink there in the first place + */ + if (follow_links && + S_ISDIR(statbuf.st_mode)) { + if (strcmp(short_name, ".") && + strcmp(short_name, "..")) { + if (find_directory_hash(statbuf.st_dev, + STAT_INODE(statbuf))) { + if (!use_RockRidge) { + fprintf(stderr, + "Already cached directory seen (%s)\n", + whole_path); + return (0); + } + lstatbuf = statbuf; + /* + * XXX when this line was active, + * XXX genisoimage did not include all + * XXX files if it was called with '-f' + * XXX (follow symlinks). + * XXX Now scan_directory_tree() + * XXX checks if the directory has + * XXX already been scanned via the + * XXX DIR_WAS_SCANNED flag. + */ +/* no_scandir = 1;*/ + } else { + lstatbuf = statbuf; + add_directory_hash(statbuf.st_dev, + STAT_INODE(statbuf)); + } + } + } + /* + * For non-directories, we just copy the stat information over + * so we correctly include this file. + */ + if (follow_links && + !S_ISDIR(statbuf.st_mode)) { + lstatbuf = statbuf; + } + } + /* + * Add directories to the cache so that we don't waste space even if + * we are supposed to be following symlinks. + */ + if (follow_links && + strcmp(short_name, ".") && + strcmp(short_name, "..") && + S_ISDIR(statbuf.st_mode)) { + add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); + } +#ifdef VMS + if (!S_ISDIR(lstatbuf.st_mode) && (statbuf.st_fab_rfm != FAB$C_FIX && + statbuf.st_fab_rfm != FAB$C_STMLF)) { + fprintf(stderr, + "Warning - file %s has an unsupported VMS record" + " format (%d)\n", + whole_path, statbuf.st_fab_rfm); + } +#endif + + if (S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))) { +#ifdef USE_LIBSCHILY + errmsg("File %s is not readable - ignoring\n", + whole_path); +#else + fprintf(stderr, + "File %s is not readable (errno = %d) - ignoring\n", + whole_path, errno); +#endif + return (0); + } + /* print a warning but don't spam too much */ + if (S_ISREG(lstatbuf.st_mode) && (lstatbuf.st_size >= (off_t)0xFFFFFFFF)) { + static int udf_warned; + + if( !allow_limited_size || verbose>1) + fprintf(stderr, "File %s is larger than 4GiB-1.\n", whole_path); + if( !allow_limited_size) + { + fprintf(stderr, "-allow-limited-size was not specified. There is no way do represent this file size. Aborting.\n"); + exit(1); + } + if(verbose>=1 && ! udf_warned ) { + udf_warned++; + fprintf(stderr, "This size can only be represented in the UDF filesystem.\n" + "Make sure that your clients support and use it.\n" + "ISO9660, Joliet, RockRidge, HFS will display incorrect size.\n"); + } + } + /* + * Add this so that we can detect directory loops with hard links. + * If we are set up to follow symlinks, then we skip this checking. + */ + if (!follow_links && + S_ISDIR(lstatbuf.st_mode) && + strcmp(short_name, ".") && + strcmp(short_name, "..")) { + if (find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) { +#ifdef USE_LIBSCHILY +/* comerrno(EX_BAD,*/ +/* "Directory loop - fatal goof (%s %lx %lu).\n",*/ + errmsgno(EX_BAD, + "Warning: Directory loop (%s dev: %lx ino: %lu).\n", + whole_path, (unsigned long) statbuf.st_dev, + (unsigned long) STAT_INODE(statbuf)); +#else +/* fprintf(stderr,*/ +/* "Directory loop - fatal goof (%s %lx %lu).\n",*/ + fprintf(stderr, + "Warning: Directory loop (%s dev: %lx ino: %lu).\n", + whole_path, (unsigned long) statbuf.st_dev, + (unsigned long) STAT_INODE(statbuf)); +#endif + } + add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); + } + if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && + !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) && + !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && + !S_ISDIR(lstatbuf.st_mode)) { + if ( ! (this_dir == root && strcmp(short_name, "..") == 0)) { + fprintf(stderr, + "Unknown file type (%s) %s - ignoring and continuing.\n", + filetype((int) lstatbuf.st_mode), whole_path); + } + return (0); + } + /* Who knows what trash this is - ignore and continue */ + + if (status) { +#ifdef USE_LIBSCHILY + errmsg("Unable to stat file %s - ignoring and continuing.\n", + whole_path); +#else + fprintf(stderr, + "Unable to stat file %s - ignoring and continuing.\n", + whole_path); +#endif + return (0); + } + /* + * Check to see if we have already seen this directory node. If so, + * then we don't create a new entry for it, but we do want to recurse + * beneath it and add any new files we do find. + */ + if (S_ISDIR(statbuf.st_mode)) { + int dflag; + + for (s_entry = this_dir->contents; s_entry; + s_entry = s_entry->next) { + if (strcmp(s_entry->name, short_name) == 0) { + break; + } + } + if (s_entry != NULL && + strcmp(short_name, ".") && + strcmp(short_name, "..")) { + struct directory *child; + + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + for (s_entry = reloc_dir->contents; s_entry; + s_entry = s_entry->next) { + if (strcmp(s_entry->name, short_name) + == 0) { + break; + } + } + child = find_or_create_directory(reloc_dir, + whole_path, + s_entry, 1, NULL); + } else { + child = find_or_create_directory(this_dir, + whole_path, + s_entry, 1, NULL); + /* + * If unable to scan directory, mark this as a + * non-directory + */ + } +/* if (no_scandir)*/ + if (0) + dflag = 1; + else + dflag = scan_directory_tree(child, + whole_path, s_entry); + if (!dflag) { + lstatbuf.st_mode = + (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; + } + return (0); + } + } +#ifdef APPLE_HYB + /* Should we exclude this HFS file ? - only works with -hfs */ + if (!have_rsrc && apple_hyb && strcmp(short_name, ".") && + strcmp(short_name, "..")) { + if ((x_hfs = (hfs_matches(short_name) || + hfs_matches(whole_path))) == 1) { + if (verbose > 1) { + fprintf(stderr, "Hidden from HFS tree: %s\n", + whole_path); + } + } + } + /* + * check we are a file, using Apple extensions and have a .resource + * part and not excluded + */ + if (S_ISREG(lstatbuf.st_mode) && !have_rsrc && apple_both && !x_hfs) { + char rsrc_path[PATH_MAX]; /* rsrc fork filename */ + + /* construct the resource full path */ + htype = get_hfs_rname(whole_path, short_name, rsrc_path); + /* check we can read the resouce fork */ + if (htype) { + struct stat rstatbuf, + rlstatbuf; + + /* some further checks on the file */ + status = stat_filter(rsrc_path, &rstatbuf); + + lstatus = lstat_filter(rsrc_path, &rlstatbuf); + +/* if (!status && !lstatus && S_ISREG(rlstatbuf.st_mode)*/ +/* && rlstatbuf.st_size > (off_t)0) { */ + if (!status && !lstatus && S_ISREG(rstatbuf.st_mode) && + rstatbuf.st_size > (off_t)0) { + + /* + * have a resource file - insert it into the + * current directory but flag that we have a + * resource fork + */ + insert_file_entry(this_dir, rsrc_path, + short_name, htype); + } + } + } +#endif /* APPLE_HYB */ + + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + /* memset the whole struct, not just the isorec.extent part JCP */ + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = this_dir->contents; +/* memset(s_entry->isorec.extent, 0, 8); */ + this_dir->contents = s_entry; + deep_flag = 0; + s_entry->table = NULL; + + s_entry->name = strdup(short_name); + s_entry->whole_name = strdup(whole_path); + + s_entry->de_flags = 0; + + /* + * If the current directory is hidden, then hide all it's members + * otherwise check if this entry needs to be hidden as well + */ + if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; + } else if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") + != 0) { + if (i_matches(short_name) || i_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + "Hidden from ISO9660 tree: %s\n", + whole_path); + } + s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; + } + if (h_matches(short_name) || h_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + "Hidden ISO9660 attribute: %s\n", + whole_path); + } + s_entry->de_flags |= HIDDEN_FILE; + } + } + if (this_dir != reloc_dir && + this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + } else if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") + != 0) { + if (j_matches(short_name) || j_matches(whole_path)) { + if (verbose > 1) { + fprintf(stderr, + "Hidden from Joliet tree: %s\n", + whole_path); + } + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + } + } + +#ifdef SORTING + /* inherit any sort weight from parent directory */ + s_entry->sort = this_dir->sort; + +#ifdef DVD_VIDEO + /* + * No use at all to do a sort if we don't make a dvd video/audio + */ + /* + * Assign special weights to VIDEO_TS and AUDIO_TS files. + * This can't be done with sort_matches for two reasons: + * first, we need to match against the destination (DVD) + * path rather than the source path, and second, there are + * about 2400 different file names to check, each needing + * a different priority, and adding that many patterns to + * sort_matches would slow things to a crawl. + */ + + if (dvd_video) { + s_entry->sort = assign_dvd_weights(s_entry->name, this_dir, s_entry->sort); + /* turn on sorting if necessary, regardless of cmd-line options */ + if ((s_entry->sort != this_dir->sort) && do_sort == 0) + do_sort++; + } +#endif + + /* see if this entry should have a new weighting */ + if (do_sort && strcmp(short_name, ".") != 0 && + strcmp(short_name, "..") != 0) { + s_entry->sort = sort_matches(whole_path, s_entry->sort); + } +#endif /* SORTING */ + + s_entry->filedir = this_dir; + s_entry->isorec.flags[0] = ISO_FILE; + if (s_entry->de_flags & HIDDEN_FILE) + s_entry->isorec.flags[0] |= ISO_EXISTENCE; + s_entry->isorec.ext_attr_length[0] = 0; + iso9660_date(s_entry->isorec.date, statbuf.st_mtime); + s_entry->isorec.file_unit_size[0] = 0; + s_entry->isorec.interleave[0] = 0; + +#ifdef APPLE_HYB + if (apple_both && !x_hfs) { + s_entry->hfs_ent = NULL; + s_entry->assoc = NULL; + s_entry->hfs_off = (off_t)0; + s_entry->hfs_type = htype; + if (have_rsrc) { + /* associated (rsrc) file */ + s_entry->isorec.flags[0] |= ISO_ASSOCIATED; + /* set the type of HFS file */ + s_entry->hfs_type = have_rsrc; + /* + * don't want the rsrc file to be included in any + * Joliet tree + */ + s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; + } else if (s_entry->next) { + /* + * if previous entry is an associated file, + * then "link" it to this file i.e. we have a + * data/resource pair + */ + if (s_entry->next->isorec.flags[0] & ISO_ASSOCIATED) { + s_entry->assoc = s_entry->next; + /* share the same HFS parameters */ + s_entry->hfs_ent = s_entry->next->hfs_ent; + s_entry->hfs_type = s_entry->next->hfs_type; + } + } + /* allocate HFS entry if required */ + if (apple_both && strcmp(short_name, ".") && + strcmp(short_name, "..")) { + if (!s_entry->hfs_ent) { + hfsdirent *hfs_ent; + + hfs_ent = + (hfsdirent *) e_malloc(sizeof (hfsdirent)); + + /* fill in the defaults */ + memset(hfs_ent, 0, sizeof (hfsdirent)); + + s_entry->hfs_ent = hfs_ent; + } + /* + * the resource fork is processed first, but the + * data fork's time info is used in preference + * i.e. time info is set from the resource fork + * initially, then it is set from the data fork + */ + if (have_rsrc) { + /* set rsrc size */ + s_entry->hfs_ent->u.file.rsize = lstatbuf.st_size; + /* + * this will be overwritten - but might as + * well set it here ... + */ + s_entry->hfs_ent->crdate = lstatbuf.st_ctime; + s_entry->hfs_ent->mddate = lstatbuf.st_mtime; + } else { + /* set data size */ + s_entry->hfs_ent->u.file.dsize = lstatbuf.st_size; + s_entry->hfs_ent->crdate = lstatbuf.st_ctime; + s_entry->hfs_ent->mddate = lstatbuf.st_mtime; + } + } + } +#endif /* APPLE_HYB */ + + if (strcmp(short_name, ".") == 0) { + this_dir->dir_flags |= DIR_HAS_DOT; + } + if (strcmp(short_name, "..") == 0) { + this_dir->dir_flags |= DIR_HAS_DOTDOT; + } + if (this_dir->parent && + this_dir->parent == reloc_dir && + strcmp(short_name, "..") == 0) { + s_entry->inode = UNCACHED_INODE; + s_entry->dev = (dev_t) UNCACHED_DEVICE; + deep_flag = NEED_PL; + } else +#ifdef APPLE_HYB + if (have_rsrc) { + /* don't want rsrc files to be cached */ + s_entry->inode = UNCACHED_INODE; + s_entry->dev = (dev_t) UNCACHED_DEVICE; + } else +#endif /* APPLE_HYB */ + { + s_entry->inode = STAT_INODE(statbuf); + s_entry->dev = statbuf.st_dev; + } + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode)); + s_entry->rr_attr_size = 0; + s_entry->total_rr_attr_size = 0; + s_entry->rr_attributes = NULL; + + /* Directories are assigned sizes later on */ + if (!S_ISDIR(statbuf.st_mode)) { + if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || + S_ISFIFO(lstatbuf.st_mode) || + S_ISSOCK(lstatbuf.st_mode) || + S_ISLNK(lstatbuf.st_mode)) { + s_entry->size = (off_t)0; + statbuf.st_size = (off_t)0; + } else { + s_entry->size = statbuf.st_size; + } + + set_733((char *) s_entry->isorec.size, statbuf.st_size); + s_entry->realsize = statbuf.st_size; + } else { + s_entry->isorec.flags[0] |= ISO_DIRECTORY; + } +#ifdef APPLE_HYB + /* if the directory is HFS excluded, then we don't have an hfs_ent */ + if (apple_both && s_entry->hfs_ent && + (s_entry->isorec.flags[0] & ISO_DIRECTORY)) { + /* get the Mac directory name */ + get_hfs_dir(whole_path, short_name, s_entry); + + /* if required, set ISO directory name from HFS name */ + if (use_mac_name) + iso9660_file_length(s_entry->hfs_ent->name, s_entry, 1); + } +#endif /* APPLE_HYB */ + + if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") != 0 && + S_ISDIR(statbuf.st_mode) && + this_dir->depth > RR_relocation_depth) { + struct directory *child; + + if (!reloc_dir) + generate_reloc_directory(); + + /* + * Replicate the entry for this directory. The old one will + * stay where it is, and it will be neutered so that it no + * longer looks like a directory. The new one will look like + * a directory, and it will be put in the reloc_dir. + */ + s_entry1 = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memcpy(s_entry1, s_entry, sizeof (struct directory_entry)); + s_entry1->table = NULL; + s_entry1->name = strdup(this_dir->contents->name); + s_entry1->whole_name = strdup(this_dir->contents->whole_name); + s_entry1->next = reloc_dir->contents; + reloc_dir->contents = s_entry1; + s_entry1->priority = 32768; + s_entry1->parent_rec = this_dir->contents; + set_723(s_entry1->isorec.volume_sequence_number, + volume_sequence_number); + + deep_flag = NEED_RE; + + if (use_XA || use_RockRidge) { + generate_xa_rr_attributes(whole_path, + short_name, s_entry1, + &statbuf, &lstatbuf, deep_flag); + } + deep_flag = 0; + + /* + * We need to set this temporarily so that the parent to this + * is correctly determined. + */ + s_entry1->filedir = reloc_dir; + child = find_or_create_directory(reloc_dir, whole_path, + s_entry1, 0, NULL); +/* if (!no_scandir)*/ + if (!0) + scan_directory_tree(child, whole_path, s_entry1); + s_entry1->filedir = this_dir; + + statbuf.st_size = (off_t)0; + statbuf.st_mode &= 0777; + set_733((char *) s_entry->isorec.size, 0); + s_entry->realsize=0; + s_entry->size = 0; + s_entry->isorec.flags[0] = ISO_FILE; + s_entry->inode = UNCACHED_INODE; + s_entry->de_flags |= RELOCATED_DIRECTORY; + deep_flag = NEED_CL; + } + if (generate_tables && + strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0) { + + char buffer[SECTOR_SIZE]; + int nchar; + + switch (lstatbuf.st_mode & S_IFMT) { + case S_IFDIR: + sprintf(buffer, "D\t%s\n", + s_entry->name); + break; + +/* + * extra for WIN32 - if it doesn't have the major/minor defined, then + * S_IFBLK and S_IFCHR type files are unlikely to exist anyway ... + * code similar to that in rock.c + */ +#if 0 +/* + * Use the device handling code from <device.h> + */ +#ifndef major +#define major(dev) (sizeof (dev_t) <= 2 ? ((dev) >> 8) : \ + (sizeof (dev_t) <= 4 ? (((dev) >> 8) >> 8) : \ + (((dev) >> 16) >> 16))) +#define minor(dev) (sizeof (dev_t) <= 2 ? (dev) & 0xff : \ + (sizeof (dev_t) <= 4 ? (dev) & 0xffff : \ + (dev) & 0xffffffff)) +#endif +#endif + +#ifdef S_IFBLK + case S_IFBLK: + sprintf(buffer, "B\t%s\t%lu %lu\n", + s_entry->name, + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); + break; +#endif +#ifdef S_IFIFO + case S_IFIFO: + sprintf(buffer, "P\t%s\n", + s_entry->name); + break; +#endif +#ifdef S_IFCHR + case S_IFCHR: + sprintf(buffer, "C\t%s\t%lu %lu\n", + s_entry->name, + (unsigned long) major(statbuf.st_rdev), + (unsigned long) minor(statbuf.st_rdev)); + break; +#endif +#ifdef S_IFLNK + case S_IFLNK: +#ifdef HAVE_READLINK + nchar = readlink(whole_path, + (char *) symlink_buff, + sizeof (symlink_buff)-1); +#else + nchar = -1; +#endif + symlink_buff[nchar < 0 ? 0 : nchar] = 0; + sprintf(buffer, "L\t%s\t%s\n", + s_entry->name, symlink_buff); + break; +#endif +#ifdef S_IFSOCK + case S_IFSOCK: + sprintf(buffer, "S\t%s\n", + s_entry->name); + break; +#endif + case S_IFREG: + default: + sprintf(buffer, "F\t%s\n", + s_entry->name); + break; + }; + s_entry->table = strdup(buffer); + } + if (S_ISDIR(statbuf.st_mode)) { + int dflag; + + if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") + != 0) { + struct directory *child; + + child = find_or_create_directory(this_dir, whole_path, + s_entry, 1, NULL); + if (no_scandir) + dflag = 1; + else + dflag = scan_directory_tree(child, whole_path, + s_entry); + + if (!dflag) { + lstatbuf.st_mode = + (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; + if (child->contents == NULL) { + delete_directory(this_dir, child); + } + } + } + /* If unable to scan directory, mark this as a non-directory */ + } + if (use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") + == 0) { + deep_flag |= NEED_CE | NEED_SP; /* For extension record */ + } + /* Now figure out how much room this file will take in the directory */ + +#ifdef APPLE_HYB + /* if the file is HFS excluded, then we don't have an hfs_ent */ + if (apple_both && !have_rsrc && s_entry->hfs_ent) { + if (S_ISREG(lstatbuf.st_mode)) { /* it's a regular file */ + + /* fill in the rest of the HFS entry */ + get_hfs_info(whole_path, short_name, s_entry); + + /* if required, set ISO directory name from HFS name */ + if (use_mac_name) + iso9660_file_length(s_entry->hfs_ent->name, + s_entry, 0); + + /* print details about the HFS file */ + if (verbose > 2) + print_hfs_info(s_entry); + + /* + * copy the new ISO9660 name to the rsrc fork + * - if it exists + */ + if (s_entry->assoc) + strcpy(s_entry->assoc->isorec.name, + s_entry->isorec.name); + + /* + * we can't handle hard links in the hybrid case, so we + * "uncache" the file. The downside to this is that + * hard linked files are added to the output image + * more than once (we've already done this for rsrc + * files) + */ + if (apple_hyb) { + s_entry->inode = UNCACHED_INODE; + s_entry->dev = (dev_t) UNCACHED_DEVICE; + } + } else if (!(s_entry->isorec.flags[0] & ISO_DIRECTORY)) { + /* not a directory .. */ + + /* + * no mac equivalent, so ignore - have to be careful + * here, the hfs_ent may be also be for a relocated + * directory + */ + if (s_entry->hfs_ent && + !(s_entry->de_flags & RELOCATED_DIRECTORY)) + free(s_entry->hfs_ent); + s_entry->hfs_ent = NULL; + } + /* + * if the rsrc size is zero, then we don't need the entry, so + * we might as well delete it - this will only happen if we + * didn't know the rsrc size from the rsrc file size + */ + if (s_entry->assoc && s_entry->assoc->size == 0) + delete_rsrc_ent(s_entry); + } + if (apple_ext && s_entry->assoc) { + /* need Apple extensions for the resource fork as well */ + generate_xa_rr_attributes(whole_path, + short_name, s_entry->assoc, + &statbuf, &lstatbuf, deep_flag); + } + /* leave out resource fork for the time being */ + /* + * XXX This is most likely wrong and should just be: + * XXX if (use_XA || use_RockRidge) { + */ +/* if ((use_XA || use_RockRidge) && !have_rsrc) {*/ + if (use_XA || use_RockRidge) { +#else + if (use_XA || use_RockRidge) { +#endif /* APPLE_HYB */ + generate_xa_rr_attributes(whole_path, + short_name, s_entry, + &statbuf, &lstatbuf, deep_flag); + + } + return (1); +} + + +void +generate_iso9660_directories(struct directory *node, FILE *outfile) +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + if (dpnt->extent > session_start) { + generate_one_directory(dpnt, outfile); + } + if (dpnt->subdir) + generate_iso9660_directories(dpnt->subdir, outfile); + dpnt = dpnt->next; + } +} + +/* + * Function: find_or_create_directory + * + * Purpose: Locate a directory entry in the tree, create if needed. + * If a directory is created and stat_template is non-null, + * create the directory with ownership, permissions, etc., + * from stat_template, otherwise use fallback defaults. + * + * Arguments: parent & de are never NULL at the same time. + */ +struct directory * +find_or_create_directory(struct directory *parent, + const char *path, + struct directory_entry *de, + int flag, + struct stat *stat_template) +{ + struct directory *dpnt; + struct directory_entry *orig_de; + struct directory *next_brother; + const char *cpnt; + const char *pnt; + struct stat my_statbuf; + + orig_de = de; + + /* + * XXX It seems that the tree that has been read from the + * XXX previous session does not carry whole_name entries. + * XXX We provide a hack in multi.c:find_or_create_directory() + * XXX that should be removed when a reasonable method could + * XXX be found. + */ + if (path == NULL) { + fprintf(stderr, "Warning: missing whole name for: '%s'\n", de->name); + path = de->name; + } + pnt = strrchr(path, PATH_SEPARATOR); + if (pnt == NULL) { + pnt = path; + } else { + pnt++; + } + + if (parent != NULL) { + dpnt = parent->subdir; + + while (dpnt) { + /* + * Weird hack time - if there are two directories by + * the same name in the reloc_dir, they are not + * treated as the same thing unless the entire path + * matches completely. + */ + if (flag && strcmp(dpnt->de_name, pnt) == 0) { + return (dpnt); + } + dpnt = dpnt->next; + } + } + /* + * We don't know if we have a valid directory entry for this one yet. + * If not, we need to create one. + */ + if (de == NULL) { + de = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(de, 0, sizeof (struct directory_entry)); + de->next = parent->contents; + parent->contents = de; + de->name = strdup(pnt); + de->whole_name = strdup(path); + de->filedir = parent; + de->isorec.flags[0] = ISO_DIRECTORY; + de->priority = 32768; + de->inode = UNCACHED_INODE; + de->dev = (dev_t) UNCACHED_DEVICE; + set_723(de->isorec.volume_sequence_number, + volume_sequence_number); + iso9660_file_length(pnt, de, 1); + + /* + * If we were given a stat template, use it for + * ownership/permissions, otherwise use fallback defaults. + */ + init_fstatbuf(); + if (stat_template) { + my_statbuf = *stat_template; + } else { + my_statbuf = fstatbuf; /* defaults */ + my_statbuf.st_mode = new_dir_mode; + } + my_statbuf.st_mode &= ~S_IFMT; /* zero out file type */ + my_statbuf.st_mode |= S_IFDIR; /* force to be a directory */ + my_statbuf.st_nlink = 2; + + /* + * Apply attributes from my_statbuf to the new directory. + */ + if (use_XA || use_RockRidge) { + generate_xa_rr_attributes("", (char *) pnt, de, + &my_statbuf, &my_statbuf, 0); + } + iso9660_date(de->isorec.date, fstatbuf.st_mtime); +#ifdef APPLE_HYB + if (apple_both) { + /* give the directory an HFS entry */ + hfsdirent *hfs_ent; + + hfs_ent = (hfsdirent *) e_malloc(sizeof (hfsdirent)); + + /* fill in the defaults */ + memset(hfs_ent, 0, sizeof (hfsdirent)); + hfs_ent->crdate = my_statbuf.st_ctime; + hfs_ent->mddate = my_statbuf.st_mtime; + + de->hfs_ent = hfs_ent; + + /* get the Mac directory name */ + get_hfs_dir((char *) path, (char *) pnt, de); + } +#endif /* APPLE_HYB */ + } + /* + * If we don't have a directory for this one yet, then allocate it now, + * and patch it into the tree in the appropriate place. + */ + dpnt = (struct directory *) e_malloc(sizeof (struct directory)); + memset(dpnt, 0, sizeof (struct directory)); + dpnt->next = NULL; + dpnt->subdir = NULL; + dpnt->self = de; + dpnt->contents = NULL; + dpnt->whole_name = strdup(path); + cpnt = strrchr(path, PATH_SEPARATOR); + if (cpnt) + cpnt++; + else + cpnt = path; + dpnt->de_name = strdup(cpnt); + dpnt->size = 0; + dpnt->extent = 0; + dpnt->jextent = 0; + dpnt->jsize = 0; +#ifdef APPLE_HYB + dpnt->hfs_ent = de->hfs_ent; +#endif /* APPLE_HYB */ + + if (orig_de == NULL) { + struct stat xstatbuf; + struct stat parent_statbuf; + int sts; + + /* + * Now add a . and .. entry in the directory itself. This is a + * little tricky - if the real directory exists, we need to + * stat it first. Otherwise, we use the fictitious fstatbuf + * which points to the time at which genisoimage was started. + */ + if (parent == NULL || parent->whole_name[0] == '\0') + sts = -1; + else + sts = stat_filter(parent->whole_name, &parent_statbuf); + + if (sts != 0) { + parent_statbuf = fstatbuf; + parent_statbuf.st_mode = new_dir_mode | S_IFDIR; + parent_statbuf.st_nlink = 2; + } + + if (debug && parent) { + fprintf(stderr, "stat parent->whole_name: '%s' -> %d.\n", + parent->whole_name, sts); + } + attach_dot_entries(dpnt, &my_statbuf, &parent_statbuf); + } + if (!parent || parent == root) { + if (!root) { + root = dpnt; /* First time through for root */ + /* directory only */ + root->depth = 0; + root->parent = root; + } else { + dpnt->depth = 1; + if (!root->subdir) { + root->subdir = dpnt; + } else { + next_brother = root->subdir; + while (next_brother->next) + next_brother = next_brother->next; + next_brother->next = dpnt; + } + dpnt->parent = parent; + } + } else { + /* Come through here for normal traversal of tree */ +#ifdef DEBUG + fprintf(stderr, "%s(%d) ", path, dpnt->depth); +#endif + if (parent->depth > RR_relocation_depth) { + /* + * XXX to prevent this, we would need to add + * XXX support for RR directory relocation + * XXX to find_or_create_directory() + */ +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Directories too deep for '%s' (%d) max is %d.\n", + path, parent->depth, RR_relocation_depth); +#else + fprintf(stderr, + "Directories too deep for '%s' (%d) max is %d.\n", + path, parent->depth, RR_relocation_depth); + exit(1); +#endif + } + dpnt->parent = parent; + dpnt->depth = parent->depth + 1; + + if (!parent->subdir) { + parent->subdir = dpnt; + } else { + next_brother = parent->subdir; + while (next_brother->next) + next_brother = next_brother->next; + next_brother->next = dpnt; + } + } + + return (dpnt); +} + +/* + * Function: delete_directory + * + * Purpose: Locate a directory entry in the tree, create if needed. + * + * Arguments: + */ +static void +delete_directory(parent, child) + struct directory *parent; + struct directory *child; +{ + struct directory *tdir; + + if (child->contents != NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Unable to delete non-empty directory\n"); +#else + fprintf(stderr, "Unable to delete non-empty directory\n"); + exit(1); +#endif + } + free(child->whole_name); + child->whole_name = NULL; + + free(child->de_name); + child->de_name = NULL; + +#ifdef APPLE_HYB + if (apple_both && child->hfs_ent) + free(child->hfs_ent); +#endif /* APPLE_HYB */ + + if (parent->subdir == child) { + parent->subdir = child->next; + } else { + for (tdir = parent->subdir; tdir->next != NULL; + tdir = tdir->next) { + if (tdir->next == child) { + tdir->next = child->next; + break; + } + } + if (tdir == NULL) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to locate child directory in parent list\n"); +#else + fprintf(stderr, + "Unable to locate child directory in parent list\n"); + exit(1); +#endif + } + } + free(child); +} + +int +sort_tree(struct directory *node) +{ + struct directory *dpnt; + int ret = 0; + + dpnt = node; + + while (dpnt) { + ret = sort_n_finish(dpnt); + if (ret) { + break; + } + if (dpnt->subdir) + sort_tree(dpnt->subdir); + dpnt = dpnt->next; + } + return (ret); +} + +void +dump_tree(struct directory *node) +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + fprintf(stderr, "%4d %5d %s\n", + dpnt->extent, dpnt->size, dpnt->de_name); + if (dpnt->subdir) + dump_tree(dpnt->subdir); + dpnt = dpnt->next; + } +} + +void +update_nlink_field(struct directory *node) +{ + struct directory *dpnt; + struct directory *xpnt; + struct directory_entry *s_entry; + int i; + + dpnt = node; + + while (dpnt) { + if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { + dpnt = dpnt->next; + continue; + } + /* + * First, count up the number of subdirectories this guy has. + */ + for (i = 0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) + if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) + i++; + /* + * Next check to see if we have any relocated directories in + * this directory. The nlink field will include these as + * real directories when they are properly relocated. + * In the non-rockridge disk, the relocated entries appear as + * zero length files. + */ + for (s_entry = dpnt->contents; s_entry; + s_entry = s_entry->next) { + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0 && + (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == + 0) { + i++; + } + } + /* Now update the field in the Rock Ridge entry. */ + update_nlink(dpnt->self, i + 2); + + /* Update the '.' entry for this directory. */ + update_nlink(dpnt->contents, i + 2); + + /* Update all of the '..' entries that point to this guy. */ + for (xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) + update_nlink(xpnt->contents->next, i + 2); + + if (dpnt->subdir) + update_nlink_field(dpnt->subdir); + dpnt = dpnt->next; + } +} + +/* + * something quick and dirty to locate a file given a path + * recursively walks down path in filename until it finds the + * directory entry for the desired file + */ +struct directory_entry * +search_tree_file(struct directory *node, char *filename) +{ + struct directory_entry *depnt; + struct directory *dpnt; + char *p1; + char *rest; + char *subdir; + + /* strip off next directory name from filename */ + subdir = strdup(filename); + + if ((p1 = strchr(subdir, '/')) == subdir) { + fprintf(stderr, + "call to search_tree_file with an absolute path, stripping\n"); + fprintf(stderr, + "initial path separator. Hope this was intended...\n"); + memmove(subdir, subdir + 1, strlen(subdir) - 1); + p1 = strchr(subdir, '/'); + } + /* do we need to find a subdirectory */ + if (p1) { + *p1 = '\0'; + +#ifdef DEBUG_TORITO + fprintf(stderr, "Looking for subdir called %s\n", p1); +#endif + + rest = p1 + 1; + +#ifdef DEBUG_TORITO + fprintf(stderr, "Remainder of path name is now %s\n", rest); +#endif + + dpnt = node->subdir; + while (dpnt) { +#ifdef DEBUG_TORITO + fprintf(stderr, + "%4d %5d %s\n", dpnt->extent, dpnt->size, + dpnt->de_name); +#endif + if (strcmp(subdir, dpnt->de_name) == 0) { +#ifdef DEBUG_TORITO + fprintf(stderr, + "Calling next level with filename = %s", rest); +#endif + return (search_tree_file(dpnt, rest)); + } + dpnt = dpnt->next; + } + + /* if we got here means we couldnt find the subdir */ + return (NULL); + } else { + /* look for a normal file now */ + depnt = node->contents; + while (depnt) { +#ifdef DEBUG_TORITO + fprintf(stderr, "%4d %5d %s\n", depnt->isorec.extent, + depnt->size, depnt->name); +#endif + if (strcmp(filename, depnt->name) == 0) { +#ifdef DEBUG_TORITO + fprintf(stderr, "Found our file %s", filename); +#endif + return (depnt); + } + depnt = depnt->next; + } + /* if we got here means we couldnt find the subdir */ + return (NULL); + } +#ifdef ERIC_FUN + fprintf(stderr, "We cant get here in search_tree_file :-/ \n"); +#endif +} + +void +init_fstatbuf() +{ + time_t current_time; + + if (fstatbuf.st_ctime == 0) { + time(¤t_time); + if (rationalize_uid) + fstatbuf.st_uid = uid_to_use; + else + fstatbuf.st_uid = getuid(); + if (rationalize_gid) + fstatbuf.st_gid = gid_to_use; + else + fstatbuf.st_gid = getgid(); + fstatbuf.st_ctime = current_time; + fstatbuf.st_mtime = current_time; + fstatbuf.st_atime = current_time; + } +} diff --git a/genisoimage/udf.c b/genisoimage/udf.c new file mode 100644 index 0000000..c63d372 --- /dev/null +++ b/genisoimage/udf.c @@ -0,0 +1,1213 @@ +/* + * 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. + * + */ + +/* @(#)udf.c 1.14 04/04/15 Copyright 2001 J. Schilling */ +/* + * udf.c - UDF support for genisoimage + * + * Written by Ben Rudiak-Gould (2001). + * + * Copyright 2001 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. + */ + +/* + * Some remaining issues: + * + * - Do not forget to edit joliet.c and remove the VIDEO_TS lines after + * we did implement a decent own file name handling for UDF. + * + * - UDF supports UNIX-style file permissions and uid/gid, but currently + * this code just sets them to default values and ignores their Rock + * Ridge counterparts. This would be easy to fix. + * + * - There's no support for symlinks, Mac type/creator, or Mac resource + * forks. Hard links and followed symlinks may work, but if so, it's + * only by accident. + * + * - The file system mirrors the Joliet file system, so files excluded + * from Joliet will also be excluded from UDF, the -jcharset option + * also applies to UDF, file names too long for Joliet will also be + * truncated on UDF, and characters not allowed by Joliet will also + * be translated on UDF. (Fortunately, Joliet is pretty lenient.) + * + * - convert_to_unicode is always called with in_nls, not hfs_nls. This + * may lead to incorrect name conversion sometimes when using a Mac + * filesystem. See joliet.c for an example of what's supposed to be + * done. + * + * - DVD-Video discs are supposed to have Copyright Management Information + * in both the ISO and UDF filesystems. This is not implemented in ISO, + * and the code to do it in UDF is currently #ifdef'd out. I'm not sure + * whether discs without this information are actually DVD-Video + * compliant. The Copyright Management Information is described in ECMA + * Technical Report TR/71. + * + * - Most of the space before sector 256 on the disc (~480K) is wasted, + * because UDF Bridge requires a pointer block at sector 256. ISO 9660 + * structures could be moved below sector 256 if they're small enough, but + * this would be ugly to implement since it breaks the output_fragment + * abstraction. + * + * - Each file must have a File Entry, and each File Entry seems to + * require its own 2K sector. As a result, there is an overhead of more + * than 2K *per file* when using UDF. I couldn't see any way to avoid + * this. + * + * - Read performance would probably be improved by placing the File Entry + * for each file just before the file itself, instead of at the beginning + * of the disc. But this would not work for DVD-Video files, which have + * to be stored contiguously. So there would have to be an override + * mechanism to handle this case. I don't know if it's worth the trouble. + */ + +#ifdef UDF + +#include "config.h" +#include "genisoimage.h" +#include <timedefs.h> +#include <schily.h> + +#include "udf.h" +#include "udf_fs.h" + +extern int use_sparcboot; + +extern struct directory *root; +extern time_t begun; + +static unsigned lba_main_seq; +static unsigned lba_main_seq_copy; +static unsigned lba_integ_seq; +static unsigned lba_udf_partition_start; +static unsigned lba_last_file_entry; +static unsigned lba_end_anchor_vol_desc; + +static unsigned num_udf_files; +static unsigned num_udf_directories; + +static unsigned volume_set_id[2]; + +#define UDF_MAIN_SEQ_LENGTH (16) +#define UDF_INTEG_SEQ_LENGTH (2) + +/* only works for granularity a power of 2! */ +#define PAD(val, granularity) (((val)+(granularity)-1)&~((granularity)-1)) + +#define read_733(field) ((0[field]&255)+(1[field]&255)*256+(2[field]&255)*65536+(3[field]&255)*16777216) + + +/**************** SIZE ****************/ + +static int set_file_ident_desc(unsigned char *, unsigned, char *, int, + unsigned, unsigned); + +static unsigned +directory_size(struct directory *dpnt) +{ + unsigned size_in_bytes; + struct directory_entry *de; + Uchar dummy_buf[SECTOR_SIZE]; + + /* parent directory */ + size_in_bytes = set_file_ident_desc(dummy_buf, 0, 0, 0, 0, 0); + + /* directory contents */ + for (de = dpnt->jcontents; de; de = de->jnext) { + if (!(de->de_flags & INHIBIT_JOLIET_ENTRY)) { + char *name = USE_MAC_NAME(de) ? de->hfs_ent->name : de->name; + /* skip . and .. */ + if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + continue; + size_in_bytes += set_file_ident_desc(dummy_buf, 0, name, 0, 0, 0); + } + } + return (size_in_bytes); +} + +static void +assign_udf_directory_addresses(struct directory *dpnt) +{ + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { + dpnt->self->udf_file_entry_sector = last_extent; + last_extent += 1 + ISO_BLOCKS(directory_size(dpnt)); + ++num_udf_directories; + } + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) { + for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { + assign_udf_directory_addresses(dpnt); + } + } +} + +static void +assign_udf_file_entry_addresses(struct directory *dpnt) +{ + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { + struct directory_entry *de; + for (de = dpnt->jcontents; de; de = de->jnext) { + if (!(de->de_flags & RELOCATED_DIRECTORY) && + !(de->isorec.flags[0] & ISO_DIRECTORY)) { + de->udf_file_entry_sector = last_extent++; + ++num_udf_files; + } + } + } + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) { + for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { + assign_udf_file_entry_addresses(dpnt); + } + } +} + +/****************************/ + +static int +udf_vol_recognition_area_size(int starting_extent) +{ + last_extent = starting_extent+3; + return (0); +} + +static int +udf_main_seq_size(int starting_extent) +{ + lba_main_seq = starting_extent; + last_extent = starting_extent + UDF_MAIN_SEQ_LENGTH; + return (0); +} + +static int +udf_main_seq_copy_size(int starting_extent) +{ + lba_main_seq_copy = starting_extent; + last_extent = starting_extent + UDF_MAIN_SEQ_LENGTH; + return (0); +} + +static int +udf_integ_seq_size(int starting_extent) +{ + lba_integ_seq = starting_extent; + last_extent = starting_extent + UDF_INTEG_SEQ_LENGTH; + return (0); +} + +static int +udf_end_anchor_vol_desc_size(int starting_extent) +{ + lba_end_anchor_vol_desc = starting_extent; + last_extent = starting_extent+1; + return (0); +} + +static int +udf_file_set_desc_size(int starting_extent) +{ + lba_udf_partition_start = starting_extent; + last_extent = starting_extent+2; + return (0); +} + +static int +udf_dirtree_size(int starting_extent) +{ + num_udf_directories = 0; + assign_udf_directory_addresses(root); + return (0); +} + +static int +udf_file_entries_size(int starting_extent) +{ + num_udf_files = 0; + assign_udf_file_entry_addresses(root); + lba_last_file_entry = last_extent-1; + return (0); +} + +static int +udf_pad_to_sector_32_size(int starting_extent) +{ + if (last_extent < session_start+32) + last_extent = session_start+32; + return (0); +} + +static int +udf_pad_to_sector_256_size(int starting_extent) +{ + if (last_extent < session_start+256) + last_extent = session_start+256; + return (0); +} + +static int +udf_padend_avdp_size(int starting_extent) +{ + lba_end_anchor_vol_desc = starting_extent; + + /* add at least 16 and at most 31 sectors, ending at a mult. of 16 */ + last_extent = (starting_extent+31) & ~15; + if (!use_sparcboot) + last_extent = starting_extent + 150; + return (0); +} + +extern int oneblock_size(int); + +/**************** WRITE ****************/ + +static unsigned +crc_ccitt(unsigned char *buf, unsigned len) +{ + const unsigned poly = 0x11021; + static unsigned short lookup[256]; + unsigned int r; + unsigned int i; + + if (lookup[1] == 0) { + unsigned int j, k; + for (j = 0; j < 256; ++j) { + unsigned int temp = j << 8; + for (k = 0; k < 8; ++k) { + unsigned int hibit = temp & 32768; + temp <<= 1; + if (hibit) + temp ^= poly; + } + lookup[j] = temp; + } + } + + r = 0; + for (i = 0; i < len; ++i) { + r = (r << 8) ^ lookup[((r >> 8) ^ buf[i]) & 255]; + } + + return (r & 65535); +} + +#define set8(dst, src) do { *(dst) = (src); } while (0) + +static void +set16(udf_Uint16 *dst, unsigned int src) +{ + dst->l = (char)(src); + dst->h = (char)(src>>8); +} + +static void +set32(udf_Uint32 *dst, unsigned src) +{ + dst->l = (char)(src); + dst->ml = (char)(src>>8); + dst->mh = (char)(src>>16); + dst->h = (char)(src>>24); +} + +static void +set64(udf_Uint64 *dst, uint64_t src) +{ + set32(&dst->l, src); + set32(&dst->h, src>>32); +} + +static int +set_ostaunicode(unsigned char *dst, int dst_size, char *src) +{ + unsigned char buf[1024]; + int i; + int expanded_length; + + expanded_length = joliet_strlen(src, in_nls); + if (expanded_length > 1024) + expanded_length = 1024; + if (expanded_length > (dst_size-1)*2) + expanded_length = (dst_size-1)*2; + + convert_to_unicode(buf, expanded_length, src, in_nls); + dst[0] = 8; /* use 8-bit representation by default */ + for (i = 0; i < (expanded_length>>1); ++i) { + dst[i + 1] = buf[i*2+1]; + if (buf[i*2] != 0) { + /* + * There's a Unicode character with value >=256. + * Use 16-bit representation instead. + */ + int length_to_copy = (dst_size-1) & ~1; + if (length_to_copy > expanded_length) + length_to_copy = expanded_length; + dst[0] = 16; + memcpy(dst+1, buf, length_to_copy); + return (length_to_copy + 1); + } + } + return ((expanded_length>>1) + 1); +} + +static void +set_extent(udf_extent_ad *ext, unsigned lba, unsigned length_bytes) +{ + set32(&ext->extent_length, length_bytes); + set32(&ext->extent_location, lba); +} + +static void +set_dstring(udf_dstring *dst, char *src, int n) +{ + dst[n-1] = set_ostaunicode((Uchar *)dst, n-1, src); +} + +static void +set_charspec(udf_charspec *dst) +{ + /*set8(&dst->character_set_type, 0);*/ + memcpy(dst->character_set_info, "OSTA Compressed Unicode", 23); +} + +static void +set_impl_ident(udf_EntityID *ent) +{ + strcpy((char *)ent->ident, "*genisoimage"); +} + +static void +set_tag(udf_tag *t, unsigned tid, unsigned lba, int crc_length) +{ + unsigned char checksum; + int i; + + set16(&t->tag_ident, tid); + set16(&t->desc_version, 2); + set16(&t->desc_crc, crc_ccitt((unsigned char *)t+16, crc_length-16)); + set16(&t->desc_crc_length, crc_length-16); + set32(&t->tag_location, lba); + set8(&t->tag_checksum, 0); + checksum = 0; + for (i = 0; i < 16; ++i) + checksum += ((unsigned char *)t)[i]; + set8(&t->tag_checksum, checksum); +} + +static void +set_timestamp_from_iso_date(udf_timestamp *ts, const char *iso_date_raw) +{ + struct { + unsigned char years_since_1900; + unsigned char month, day; + unsigned char hour, minute, second; + signed char offset_from_gmt; + } *iso_date = (void *)iso_date_raw; + + set16(&ts->type_and_time_zone, + 4096 + ((iso_date->offset_from_gmt * 15) & 4095)); + set16(&ts->year, 1900 + iso_date->years_since_1900); + set8(&ts->month, iso_date->month); + set8(&ts->day, iso_date->day); + set8(&ts->hour, iso_date->hour); + set8(&ts->minute, iso_date->minute); + set8(&ts->second, iso_date->second); + /*set8(&ts->centiseconds, 0);*/ + /*set8(&ts->hundreds_of_microseconds, 0);*/ + /*set8(&ts->microseconds, 0);*/ +} + +static void +set_timestamp_from_time_t(udf_timestamp *ts, time_t t) +{ + char iso_date[7]; + iso9660_date(iso_date, t); + set_timestamp_from_iso_date(ts, iso_date); +} + + +static void +set_anchor_volume_desc_pointer(unsigned char *buf, unsigned lba) +{ + udf_anchor_volume_desc_ptr *avdp = (udf_anchor_volume_desc_ptr *)buf; + set_extent(&avdp->main_volume_desc_seq_extent, + lba_main_seq, SECTOR_SIZE*UDF_MAIN_SEQ_LENGTH); + set_extent(&avdp->reserve_volume_desc_seq_extent, + lba_main_seq_copy, SECTOR_SIZE*UDF_MAIN_SEQ_LENGTH); + set_tag(&avdp->desc_tag, UDF_TAGID_ANCHOR_VOLUME_DESC_PTR, lba, 512); +} + +static void +set_primary_vol_desc(unsigned char *buf, unsigned lba) +{ + char temp[17]; + + udf_primary_volume_desc *pvd = (udf_primary_volume_desc *)buf; + /*set32(&pvd->volume_desc_seq_number, 0);*/ + /*set32(&pvd->primary_volume_desc_number, 0);*/ + set_dstring(pvd->volume_ident, volume_id, sizeof (pvd->volume_ident)); + set16(&pvd->volume_seq_number, 1); + set16(&pvd->maximum_volume_seq_number, 1); + set16(&pvd->interchange_level, 2); + set16(&pvd->maximum_interchange_level, 2); + set32(&pvd->character_set_list, 1); + set32(&pvd->maximum_character_set_list, 1); + sprintf(temp, "%08X%08X", volume_set_id[0], volume_set_id[1]); + set_dstring(pvd->volume_set_ident, temp, + sizeof (pvd->volume_set_ident)); + set_charspec(&pvd->desc_character_set); + set_charspec(&pvd->explanatory_character_set); + /*pvd->volume_abstract;*/ + /*pvd->volume_copyright_notice;*/ + /*pvd->application_ident;*/ + set_timestamp_from_time_t(&pvd->recording_date_and_time, begun); + set_impl_ident(&pvd->impl_ident); + set_tag(&pvd->desc_tag, UDF_TAGID_PRIMARY_VOLUME_DESC, lba, 512); +} + +static void +set_impl_use_vol_desc(unsigned char *buf, unsigned lba) +{ + udf_impl_use_volume_desc *iuvd = (udf_impl_use_volume_desc *)buf; + set32(&iuvd->volume_desc_seq_number, 1); + strcpy((char *)iuvd->impl_ident.ident, "*UDF LV Info"); + iuvd->impl_ident.ident_suffix[0] = 2; + iuvd->impl_ident.ident_suffix[1] = 1; + set_charspec(&iuvd->impl_use.lvi_charset); + set_dstring(iuvd->impl_use.logical_volume_ident, volume_id, + sizeof (iuvd->impl_use.logical_volume_ident)); + /*set_dstring(iuvd->impl_use.lv_info1, "", sizeof (iuvd->impl_use.lv_info1));*/ + /*set_dstring(iuvd->impl_use.lv_info2, "", sizeof (iuvd->impl_use.lv_info2));*/ + /*set_dstring(iuvd->impl_use.lv_info3, "", sizeof (iuvd->impl_use.lv_info3));*/ + set_impl_ident(&iuvd->impl_use.impl_id); + set_tag(&iuvd->desc_tag, UDF_TAGID_IMPL_USE_VOLUME_DESC, lba, 512); +} + +static void +set_partition_desc(unsigned char *buf, unsigned lba) +{ + udf_partition_desc *pd = (udf_partition_desc *)buf; + set32(&pd->volume_desc_seq_number, 2); + set16(&pd->partition_flags, UDF_PARTITION_FLAG_ALLOCATED); + /*set16(&pd->partition_number, 0);*/ + set8(&pd->partition_contents.flags, UDF_ENTITYID_FLAG_PROTECTED); /*???*/ + strcpy((char *)pd->partition_contents.ident, "+NSR02"); + set32(&pd->access_type, UDF_ACCESSTYPE_READONLY); + set32(&pd->partition_starting_location, lba_udf_partition_start); + set32(&pd->partition_length, + lba_end_anchor_vol_desc - lba_udf_partition_start); + set_impl_ident(&pd->impl_ident); + set_tag(&pd->desc_tag, UDF_TAGID_PARTITION_DESC, lba, 512); +} + +static void +set_domain_ident(udf_EntityID *ent) +{ + strcpy((char *)ent->ident, "*OSTA UDF Compliant"); + memcpy(ent->ident_suffix, "\002\001\003", 3); +} + +static void +set_logical_vol_desc(unsigned char *buf, unsigned lba) +{ + udf_logical_volume_desc *lvd = (udf_logical_volume_desc *)buf; + set32(&lvd->volume_desc_seq_number, 3); + set_charspec(&lvd->desc_character_set); + set_dstring(lvd->logical_volume_ident, volume_id, + sizeof (lvd->logical_volume_ident)); + set32(&lvd->logical_block_size, SECTOR_SIZE); + set_domain_ident(&lvd->domain_ident); + set32(&lvd->logical_volume_contents_use.extent_length, 2*SECTOR_SIZE); + /*set32(&lvd->logical_volume_contents_use.extent_location.logical_block_number, 0);*/ + /*set16(&lvd->logical_volume_contents_use.extent_location.partition_reference_number, 0);*/ + set32(&lvd->map_table_length, 6); + set32(&lvd->number_of_partition_maps, 1); + set_impl_ident(&lvd->impl_ident); + set_extent(&lvd->integrity_seq_extent, lba_integ_seq, + SECTOR_SIZE*UDF_INTEG_SEQ_LENGTH); + set8(&lvd->partition_map[0].partition_map_type, + UDF_PARTITION_MAP_TYPE_1); + set8(&lvd->partition_map[0].partition_map_length, 6); + set16(&lvd->partition_map[0].volume_seq_number, 1); + /*set16(&lvd->partition_map[0].partition_number, 0);*/ + set_tag(&lvd->desc_tag, UDF_TAGID_LOGICAL_VOLUME_DESC, lba, 446); +} + +static void +set_unallocated_space_desc(unsigned char *buf, unsigned lba) +{ + udf_unallocated_space_desc *usd = (udf_unallocated_space_desc *)buf; + set32(&usd->volume_desc_seq_number, 4); + /*set32(&usd->number_of_allocation_descs, 0);*/ + set_tag(&usd->desc_tag, UDF_TAGID_UNALLOCATED_SPACE_DESC, lba, 24); +} + +static void +set_terminating_desc(unsigned char *buf, unsigned lba) +{ + udf_terminating_desc *td = (udf_terminating_desc *)buf; + set_tag(&td->desc_tag, UDF_TAGID_TERMINATING_DESC, lba, 512); +} + +static void +set_logical_vol_integrity_desc(unsigned char *buf, unsigned lba) +{ + udf_logical_volume_integrity_desc *lvid = + (udf_logical_volume_integrity_desc *)buf; + + set_timestamp_from_time_t(&lvid->recording_date, begun); + set32(&lvid->integrity_type, UDF_INTEGRITY_TYPE_CLOSE); + /*lvid->next_integrity_extent;*/ + set64(&lvid->logical_volume_contents_use.unique_id, + lba_last_file_entry+1); + set32(&lvid->number_of_partitions, 1); + set32(&lvid->length_of_impl_use, 46); + /*set32(&lvid->free_space_table, 0);*/ + set32(&lvid->size_table, + lba_end_anchor_vol_desc - lba_udf_partition_start); + set_impl_ident(&lvid->impl_use.impl_id); + set32(&lvid->impl_use.number_of_files, num_udf_files); + set32(&lvid->impl_use.number_of_directories, num_udf_directories); + set16(&lvid->impl_use.minimum_udf_read_revision, 0x102); + set16(&lvid->impl_use.minimum_udf_write_revision, 0x102); + set16(&lvid->impl_use.maximum_udf_write_revision, 0x102); + set_tag(&lvid->desc_tag, UDF_TAGID_LOGICAL_VOLUME_INTEGRITY_DESC, + lba, 88+46); +} + +static void +set_file_set_desc(unsigned char *buf, unsigned rba) +{ + udf_file_set_desc *fsd = (udf_file_set_desc *)buf; + + set_timestamp_from_time_t(&fsd->recording_date_and_time, begun); + set16(&fsd->interchange_level, 3); + set16(&fsd->maximum_interchange_level, 3); + set32(&fsd->character_set_list, 1); + set32(&fsd->maximum_character_set_list, 1); + /*set32(&fsd->file_set_number, 0);*/ + /*set32(&fsd->file_set_desc_number, 0);*/ + set_charspec(&fsd->logical_volume_ident_character_set); + set_dstring(fsd->logical_volume_ident, volume_id, + sizeof (fsd->logical_volume_ident)); + set_charspec(&fsd->file_set_character_set); + set_dstring(fsd->file_set_ident, volume_id, + sizeof (fsd->file_set_ident)); + /*fsd->copyright_file_ident;*/ + /*fsd->abstract_file_ident;*/ + set32(&fsd->root_directory_icb.extent_length, SECTOR_SIZE); + set32(&fsd->root_directory_icb.extent_location.logical_block_number, + root->self->udf_file_entry_sector - lba_udf_partition_start); + set_domain_ident(&fsd->domain_ident); + /*fsd->next_extent;*/ + set_tag(&fsd->desc_tag, UDF_TAGID_FILE_SET_DESC, rba, 512); +} + +static int +set_file_ident_desc(unsigned char *buf, unsigned rba, char *name, + int is_directory, unsigned file_entry_rba, + unsigned unique_id) +{ + udf_file_ident_desc *fid = (udf_file_ident_desc *)buf; + int length_of_file_ident, length, padded_length; + set16(&fid->file_version_number, 1); + set8(&fid->file_characteristics, + (is_directory ? UDF_FILE_CHARACTERISTIC_DIRECTORY : 0) + + (name == 0) * UDF_FILE_CHARACTERISTIC_PARENT); + set32(&fid->icb.extent_length, SECTOR_SIZE); + set32(&fid->icb.extent_location.logical_block_number, file_entry_rba); + set16(&fid->icb.extent_location.partition_reference_number, 0); + set32(&fid->icb.impl_use.unique_id, unique_id); + set16(&fid->length_of_impl_use, 0); + if (name) { + length_of_file_ident = + set_ostaunicode((Uchar *)fid->file_ident, 512, name); + } else { + length_of_file_ident = 0; + } + set8(&fid->length_of_file_ident, length_of_file_ident); + length = 38 + length_of_file_ident; + padded_length = PAD(length, 4); + while (length < padded_length) { + buf[length++] = 0; + } + set_tag(&fid->desc_tag, UDF_TAGID_FILE_IDENT_DESC, rba, length); + return (length); +} + +static void +set_file_entry(unsigned char *buf, unsigned rba, unsigned file_rba, + uint64_t length, const char *iso_date, int is_directory, + unsigned link_count, unsigned unique_id) +{ + udf_short_ad *allocation_desc; + unsigned chunk; + + udf_file_entry *fe = (udf_file_entry *)buf; + + /*set32(&fe->icb_tag.prior_recorded_number_of_direct_entries, 0);*/ + set16(&fe->icb_tag.strategy_type, 4); + /*set16(&fe->icb_tag.strategy_parameter, 0);*/ + set16(&fe->icb_tag.maximum_number_of_entries, 1); + set8(&fe->icb_tag.file_type, is_directory + ? UDF_ICBTAG_FILETYPE_DIRECTORY : UDF_ICBTAG_FILETYPE_BYTESEQ); + /*fe->icb_tag.parent_icb_location;*/ + set16(&fe->icb_tag.flags, UDF_ICBTAG_FLAG_NONRELOCATABLE + | UDF_ICBTAG_FLAG_ARCHIVE | UDF_ICBTAG_FLAG_CONTIGUOUS); + if (rationalize_uid) + set32(&fe->uid, uid_to_use); + else + set32(&fe->uid, -1); + if (rationalize_gid) + set32(&fe->gid, gid_to_use); + else + set32(&fe->gid, -1); + if (is_directory) { + set32(&fe->permissions, + UDF_FILEENTRY_PERMISSION_OR | UDF_FILEENTRY_PERMISSION_OX | + UDF_FILEENTRY_PERMISSION_GR | UDF_FILEENTRY_PERMISSION_GX | + UDF_FILEENTRY_PERMISSION_UR | UDF_FILEENTRY_PERMISSION_UX); + } else { + set32(&fe->permissions, UDF_FILEENTRY_PERMISSION_OR + | UDF_FILEENTRY_PERMISSION_GR | UDF_FILEENTRY_PERMISSION_UR); + } + set16(&fe->file_link_count, link_count); + /*fe->record_format;*/ + /*fe->record_display_attributes;*/ + /*fe->record_length;*/ + set64(&fe->info_length, length); + set64(&fe->logical_blocks_recorded, ISO_BLOCKS(length)); + if (iso_date) { + set_timestamp_from_iso_date(&fe->access_time, iso_date); + fe->modification_time = fe->access_time; + fe->attribute_time = fe->access_time; + } + set32(&fe->checkpoint, 1); + /*fe->ext_attribute_icb;*/ + set_impl_ident(&fe->impl_ident); + set64(&fe->unique_id, unique_id); + /* + * Extended attributes that may (?) be required for DVD-Video + * compliance + */ +#if 0 + set32(&fe->length_of_ext_attributes, 24+52+56); + set32(&fe->ext_attribute_header.impl_attributes_location, 24); + set32(&fe->ext_attribute_header.application_attributes_location, + 24+52+56); + set_tag(&fe->ext_attribute_header.desc_tag, + UDF_TAGID_EXT_ATTRIBUTE_HEADER_DESC, rba, 24 /*???*/); + set32(&fe->ext_attribute_free_ea_space.attribute_type, SECTOR_SIZE); + set8(&fe->ext_attribute_free_ea_space.attribute_subtype, 1); + set32(&fe->ext_attribute_free_ea_space.attribute_length, 52); + set32(&fe->ext_attribute_free_ea_space.impl_use_length, 4); + strcpy((char *)fe->ext_attribute_free_ea_space.impl_ident.ident, + "*UDF FreeAppEASpace"); + set32(&fe->ext_attribute_dvd_cgms_info.attribute_type, SECTOR_SIZE); + set8(&fe->ext_attribute_dvd_cgms_info.attribute_subtype, 1); + set32(&fe->ext_attribute_dvd_cgms_info.attribute_length, 56); + set32(&fe->ext_attribute_dvd_cgms_info.impl_use_length, 8); + strcpy((char *)fe->ext_attribute_free_ea_space.impl_ident.ident, + "*UDF DVD CGMS Info"); + fe->ext_attribute_free_ea_space.impl_ident.ident_suffix[0] = 2; + fe->ext_attribute_free_ea_space.impl_ident.ident_suffix[1] = 1; +#else + /*set32(&fe->length_of_ext_attributes, 0);*/ +#endif + + allocation_desc = &fe->allocation_desc; + /* + * Only a file size less than 1GB can be expressed by a single + * AllocationDescriptor. When the size of a file is larger than 1GB, + * 2 or more AllocationDescriptors should be used. We don't know + * whether a singl 8-byte AllocationDescriptor should be written or no + * one should be written if the size of a file is 0 byte. - FIXME. + * + * XXX We get called with buf[2048]. This allows a max. file size of + * XXX 234 GB. With more we would cause a buffer overflow. + * XXX We need to check whether UDF would allow files > 234 GB. + */ + for (; length > 0; length -= chunk) { + chunk = (length > 0x3ffff800) ? 0x3ffff800 : length; + set32(&allocation_desc->extent_length, chunk); + set32(&allocation_desc->extent_position, file_rba); + file_rba += chunk >> 11; + allocation_desc++; + } + set32(&fe->length_of_allocation_descs, + (unsigned char *) allocation_desc - + (unsigned char *) &fe->allocation_desc); + set_tag(&fe->desc_tag, UDF_TAGID_FILE_ENTRY, rba, + (unsigned char *) allocation_desc - buf); +} + +static unsigned +directory_link_count(struct directory *dpnt) +{ + /* + * The link count is equal to 1 (for the parent) plus the + * number of subdirectories. + */ + unsigned link_count = 1; + struct directory_entry *de; + + /* count relocated subdirectories */ + for (de = dpnt->jcontents; de; de = de->jnext) { + if ((de->de_flags & + (INHIBIT_JOLIET_ENTRY | RELOCATED_DIRECTORY)) == + RELOCATED_DIRECTORY) { + link_count++; + } + } + /* count ordinary subdirectories */ + for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { + link_count++; + } + } + return (link_count); +} + +static void +write_one_udf_directory(struct directory *dpnt, FILE *outfile) +{ + unsigned size_in_bytes, padded_size_in_bytes; + struct directory_entry *de; + unsigned ident_size; + unsigned base_sector; + struct directory *parent; + Uchar buf[SECTOR_SIZE]; + + memset(buf, 0, SECTOR_SIZE); + set_file_entry( + buf, + last_extent_written - lba_udf_partition_start, + last_extent_written+1 - lba_udf_partition_start, + directory_size(dpnt), + dpnt->self->isorec.date, + 1, /* is_directory */ + directory_link_count(dpnt), + (dpnt == root) ? 0 : dpnt->self->udf_file_entry_sector); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + + base_sector = last_extent_written - lba_udf_partition_start; + + /* parent directory */ + parent = dpnt->parent; + if (parent == reloc_dir) { + parent = dpnt->self->parent_rec->filedir; + } + ident_size = set_file_ident_desc( + buf, + base_sector, + 0, + 1, + parent->self->udf_file_entry_sector - lba_udf_partition_start, + (parent == root) ? 0 : parent->self->udf_file_entry_sector); + jtwrite(buf, ident_size, 1, 0, FALSE); + xfwrite(buf, ident_size, 1, outfile, 0, FALSE); + size_in_bytes = ident_size; + + /* directory contents */ + for (de = dpnt->jcontents; de; de = de->jnext) { + char *name; + struct directory_entry *de1; + + if (de->de_flags & INHIBIT_JOLIET_ENTRY) + continue; + + name = USE_MAC_NAME(de) ? de->hfs_ent->name : de->name; + + /* skip . and .. */ + if (name[0] == '.' && (name[1] == 0 || + (name[1] == '.' && name[2] == 0))) + continue; + + /* look in RR_MOVED for relocated directories */ + de1 = de; + if (de->de_flags & RELOCATED_DIRECTORY) { + for (de1 = reloc_dir->contents; de1; de1 = de1->next) { + if (de1->parent_rec == de) { + break; + } + } + if (!de1) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to locate relocated directory\n"); +#else + fprintf(stderr, + "Unable to locate relocated directory\n"); + exit(1); +#endif + } + } + + ident_size = set_file_ident_desc( + buf, + base_sector + (size_in_bytes / SECTOR_SIZE), + name, + !!(de1->isorec.flags[0] & ISO_DIRECTORY), + de1->udf_file_entry_sector - lba_udf_partition_start, + de1->udf_file_entry_sector); + jtwrite(buf, ident_size, 1, 0, FALSE); + xfwrite(buf, ident_size, 1, outfile, 0, FALSE); + size_in_bytes += ident_size; + } + + padded_size_in_bytes = PAD(size_in_bytes, SECTOR_SIZE); + if (size_in_bytes < padded_size_in_bytes) { + memset(buf, 0, padded_size_in_bytes - size_in_bytes); + jtwrite(buf, padded_size_in_bytes - size_in_bytes, 1, 0, FALSE); + xfwrite(buf, padded_size_in_bytes - size_in_bytes, 1, outfile, 0, FALSE); + } + + last_extent_written += padded_size_in_bytes / SECTOR_SIZE; +} + +static void +write_udf_directories(struct directory *dpnt, FILE *outfile) +{ + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { + write_one_udf_directory(dpnt, outfile); + } + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) { + for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { + write_udf_directories(dpnt, outfile); + } + } +} + +static void +write_udf_file_entries(struct directory *dpnt, FILE *outfile) +{ + Uchar buf[SECTOR_SIZE]; + + memset(buf, 0, SECTOR_SIZE); + + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { + struct directory_entry *de; + for (de = dpnt->jcontents; de; de = de->jnext) { + if (!(de->de_flags & RELOCATED_DIRECTORY) && + !(de->isorec.flags[0] & ISO_DIRECTORY)) { + + memset(buf, 0, 512); + set_file_entry( + buf, + (last_extent_written++) - lba_udf_partition_start, + read_733(de->isorec.extent) - lba_udf_partition_start, + de->realsize, + de->isorec.date, + 0, /* is_directory */ + 1, /* link_count */ + de->udf_file_entry_sector); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE); + } + } + } + if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) { + for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { + write_udf_file_entries(dpnt, outfile); + } + } +} + +/****************************/ + +static int +udf_vol_recognition_area_write(FILE *out) +{ + static const char *identifiers[3] = { "BEA01", "NSR02", "TEA01" }; + int i; + char buf[SECTOR_SIZE]; + udf_volume_recognition_desc *vsd = (udf_volume_recognition_desc *)buf; + + memset(buf, 0, sizeof (buf)); + /*set8(&vsd->structure_type, 0);*/ + set8(&vsd->structure_version, 1); + for (i = 0; i < 3; ++i) { + memcpy(vsd->standard_identifier, identifiers[i], 5); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + } + last_extent_written += 3; + return (0); +} + +static int +udf_main_seq_write(FILE *out) +{ + Uchar buf[SECTOR_SIZE]; + int i; + + /* + * volume_set_id needs to be set to a (64-bit) "unique" number. + * This will have to do for now. + */ + volume_set_id[0] = begun; + volume_set_id[1] = (unsigned)clock(); /* XXX Maybe non-portable */ + + memset(buf, 0, sizeof (buf)); + set_primary_vol_desc(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + + memset(buf, 0, sizeof (buf)); + set_impl_use_vol_desc(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + + memset(buf, 0, sizeof (buf)); + set_partition_desc(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + + memset(buf, 0, sizeof (buf)); + set_logical_vol_desc(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + + memset(buf, 0, sizeof (buf)); + set_unallocated_space_desc(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + + memset(buf, 0, sizeof (buf)); + set_terminating_desc(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + + memset(buf, 0, sizeof (buf)); + for (i = 6; i < UDF_MAIN_SEQ_LENGTH; ++i) { + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + last_extent_written++; + } + + return (0); +} + +static int +udf_integ_seq_write(FILE *out) +{ + Uchar buf[SECTOR_SIZE*UDF_INTEG_SEQ_LENGTH]; + + memset(buf, 0, sizeof (buf)); + + set_logical_vol_integrity_desc(buf+0*SECTOR_SIZE, + last_extent_written++); + set_terminating_desc(buf+1*SECTOR_SIZE, last_extent_written++); + + jtwrite(buf, SECTOR_SIZE, UDF_INTEG_SEQ_LENGTH, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, UDF_INTEG_SEQ_LENGTH, out, 0, FALSE); + return (0); +} + +static int +udf_anchor_vol_desc_write(FILE *out) +{ + Uchar buf[SECTOR_SIZE]; + + memset(buf, 0, sizeof (buf)); + set_anchor_volume_desc_pointer(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + return (0); +} + +static int +udf_file_set_desc_write(FILE *out) +{ + Uchar buf[SECTOR_SIZE*2]; + + memset(buf, 0, sizeof (buf)); + + set_file_set_desc(buf+0*SECTOR_SIZE, + (last_extent_written++) - lba_udf_partition_start); + set_terminating_desc(buf+1*SECTOR_SIZE, + (last_extent_written++) - lba_udf_partition_start); + + jtwrite(buf, SECTOR_SIZE, 2, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 2, out, 0, FALSE); + + return (0); +} + +static int +udf_dirtree_write(FILE *out) +{ + write_udf_directories(root, out); + return (0); +} + +static int +udf_file_entries_write(FILE *out) +{ + write_udf_file_entries(root, out); + return (0); +} + +static int +pad_to(unsigned last_extent_to_write, FILE *out) +{ + char buf[SECTOR_SIZE]; + memset(buf, 0, sizeof (buf)); + while (last_extent_written < last_extent_to_write) { + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + ++last_extent_written; + } + return (0); +} + +static int +udf_pad_to_sector_32_write(FILE *out) +{ + return (pad_to(session_start+32, out)); +} + +static int +udf_pad_to_sector_256_write(FILE *out) +{ + return (pad_to(session_start+256, out)); +} + +static int +udf_padend_avdp_write(FILE *out) +{ + Uchar buf[SECTOR_SIZE]; + unsigned last_extent_to_write = (last_extent_written+31) & ~15; + + if (!use_sparcboot) + last_extent_to_write = last_extent_written + 150; + + memset(buf, 0, sizeof (buf)); + while (last_extent_written < last_extent_to_write) { + set_anchor_volume_desc_pointer(buf, last_extent_written++); + jtwrite(buf, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE); + } + return (0); +} + + +struct output_fragment udf_vol_recognition_area_frag = { NULL, udf_vol_recognition_area_size, NULL, udf_vol_recognition_area_write, "UDF volume recognition area" }; +struct output_fragment udf_main_seq_frag = { NULL, udf_main_seq_size, NULL, udf_main_seq_write, "UDF main seq" }; +struct output_fragment udf_main_seq_copy_frag = { NULL, udf_main_seq_copy_size, NULL, udf_main_seq_write, "UDF second seq" }; +struct output_fragment udf_integ_seq_frag = { NULL, udf_integ_seq_size, NULL, udf_integ_seq_write, "UDF integ seq" }; +struct output_fragment udf_anchor_vol_desc_frag = { NULL, oneblock_size, NULL, udf_anchor_vol_desc_write, "UDF Anchor volume" }; +struct output_fragment udf_file_set_desc_frag = { NULL, udf_file_set_desc_size, NULL, udf_file_set_desc_write, "UDF file set" }; +struct output_fragment udf_dirtree_frag = { NULL, udf_dirtree_size, NULL, udf_dirtree_write, "UDF directory tree" }; +struct output_fragment udf_file_entries_frag = { NULL, udf_file_entries_size, NULL, udf_file_entries_write, "UDF file entries" }; +struct output_fragment udf_end_anchor_vol_desc_frag = { NULL, udf_end_anchor_vol_desc_size, NULL, udf_anchor_vol_desc_write, "UDF Anchor end volume" }; + +struct output_fragment udf_pad_to_sector_32_frag = { NULL, udf_pad_to_sector_32_size, NULL, udf_pad_to_sector_32_write, "UDF pad to sector 32" }; +struct output_fragment udf_pad_to_sector_256_frag = { NULL, udf_pad_to_sector_256_size, NULL, udf_pad_to_sector_256_write, "UDF pad to sector 256" }; +struct output_fragment udf_padend_avdp_frag = { NULL, udf_padend_avdp_size, NULL, udf_padend_avdp_write, "UDF Pad end" }; + +/* + * This function assigns weights as follows: + * + * /VIDEO_TS/VIDEO_TS.IFO 11199 + * /VIDEO_TS/VIDEO_TS.VOB 11198 + * /VIDEO_TS/VIDEO_TS.BUP 11188 + * /VIDEO_TS/VTS_01_0.IFO 11187 + * /VIDEO_TS/VTS_01_0.VOB 11186 + * : : + * /VIDEO_TS/VTS_01_9.VOB 11177 + * /VIDEO_TS/VTS_01_0.BUP 11176 + * : : + * /VIDEO_TS/VTS_99_0.BUP 10000 + * + * This ensures that DVD-Video files are laid out properly on the disc. + * The same thing is done for AUDIO_TS files, except in the 20000 range + * instead of the 10000 range. + * + * Question: what about JACKET_P files? + * + * Answer: At least as far as I know :) + * JACKET_P files are still images (single frame mpeg video .i.e mp2 + * format). The DVD Jacket pictures will be displayed on the TV screen + * when the player is in a stop/resume mode. + * The location is not dependent on IFO information and the only must + * as far as I know is that they are in upper case (both dir and files). + * This sparce information makes me conclude that they don't need any + * weight. This obviously needs to be tested. + */ +int +assign_dvd_weights(char *name, struct directory *this_dir, int val) +{ + int ts_number; + int segment; + int audio; + + if (name[0] != 'A' && name[0] != 'V') + return (val); + + if (memcmp(name, "VIDEO_TS", 8) == 0) { + ts_number = 0; + audio = 0; + } else if (memcmp(name, "VTS_", 4) == 0) { + ts_number = 1; + audio = 0; + } else if (memcmp(name, "AUDIO_TS", 8) == 0) { + ts_number = 0; + audio = 1; + } else if (memcmp(name, "ATS_", 4) == 0) { + ts_number = 1; + audio = 1; + } else { + return (val); + } + + if (this_dir->parent != root || + strcmp(this_dir->de_name, "VIDEO_TS") != 0) + return (val); + + if (ts_number == 0) { + segment = 0; + } else { + if (name[4] >= '0' && name[4] <= '9' && + name[5] >= '0' && name[5] <= '9' && + name[6] == '_' && + name[7] >= '0' && name[7] <= '9') { + ts_number = name[4] * 10 + name[5] - ('0' * 11); + segment = name[7] - '0'; + } else { + return (val); + } + } + + if (strcmp(name+8, audio ? ".AOB" : ".VOB") == 0) { + return (audio * 10000 - ts_number * 12 - segment + 11198); + } else if (strcmp(name+8, ".IFO") == 0) { + return (audio * 10000 - ts_number * 12 + 11199); + } else if (strcmp(name+8, ".BUP") == 0) { + return (audio * 10000 - ts_number * 12 + 11188); + } else { + return (val); + } +} + +#endif /* UDF */ diff --git a/genisoimage/udf.h b/genisoimage/udf.h new file mode 100644 index 0000000..dc7bb94 --- /dev/null +++ b/genisoimage/udf.h @@ -0,0 +1,55 @@ +/* + * 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. + * + */ + +/* @(#)udf.h 1.2 04/03/01 Copyright 2001-2004 J. Schilling */ +/* + * UDF external definitions for genisoimage + * + * Copyright (c) 2001-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. + */ + +#ifndef _UDF_H +#define _UDF_H + +extern struct output_fragment udf_vol_recognition_area_frag; +extern struct output_fragment udf_main_seq_frag; +extern struct output_fragment udf_main_seq_copy_frag; +extern struct output_fragment udf_integ_seq_frag; +extern struct output_fragment udf_anchor_vol_desc_frag; +extern struct output_fragment udf_file_set_desc_frag; +extern struct output_fragment udf_dirtree_frag; +extern struct output_fragment udf_file_entries_frag; +extern struct output_fragment udf_end_anchor_vol_desc_frag; + +extern struct output_fragment udf_pad_to_sector_32_frag; +extern struct output_fragment udf_pad_to_sector_256_frag; +extern struct output_fragment udf_padend_avdp_frag; + +int assign_dvd_weights(char *name, struct directory *this_dir, int val); + +extern int use_udf; + +#endif /* _UDF_H */ diff --git a/genisoimage/udf_fs.h b/genisoimage/udf_fs.h new file mode 100644 index 0000000..850a3cc --- /dev/null +++ b/genisoimage/udf_fs.h @@ -0,0 +1,462 @@ +/* + * 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. + * + */ + +/* @(#)udf_fs.h 1.2 04/03/01 Copyright 2001-2004 J. Schilling */ +/* + * udf_fs.h - UDF structure definitions for genisoimage + * + * Written by Ben Rudiak-Gould (2001). + * + * Copyright 2001-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. + */ + +#ifndef _UDF_FS_H +#define _UDF_FS_H + +/* + * Abbreviations: + * + * ad allocation descriptor + * desc descriptor + * ext extended + * ident identifier + * impl implementation + * info information + * ptr pointer + * seq sequence + */ + +typedef char udf_Uint8; +typedef char udf_dchar; +typedef char udf_dstring; +typedef char udf_byte; +typedef char udf_zerobyte; + +/* Is this safe? Are there compilers so perverse as to pad these structs? */ +typedef struct udf_Uint16_ { + char l; + char h; +} udf_Uint16; + +typedef struct udf_Uint32_ { + char l; + char ml; + char mh; + char h; +} udf_Uint32; +typedef struct udf_Uint64_ { + udf_Uint32 l; + udf_Uint32 h; +} udf_Uint64; + +typedef struct udf_tag_ { /* ECMA-167 3/7.2 */ +/* 0*/ udf_Uint16 tag_ident; +/* 2*/ udf_Uint16 desc_version; +/* 4*/ udf_Uint8 tag_checksum; +/* 5*/ udf_zerobyte reserved; +/* 6*/ udf_Uint16 tag_serial_number; +/* 8*/ udf_Uint16 desc_crc; +/*10*/ udf_Uint16 desc_crc_length; +/*12*/ udf_Uint32 tag_location; +/*16*/ +} udf_tag; + +#define UDF_TAGID_PRIMARY_VOLUME_DESC 1 +#define UDF_TAGID_ANCHOR_VOLUME_DESC_PTR 2 +#define UDF_TAGID_IMPL_USE_VOLUME_DESC 4 +#define UDF_TAGID_PARTITION_DESC 5 +#define UDF_TAGID_LOGICAL_VOLUME_DESC 6 +#define UDF_TAGID_UNALLOCATED_SPACE_DESC 7 +#define UDF_TAGID_TERMINATING_DESC 8 +#define UDF_TAGID_LOGICAL_VOLUME_INTEGRITY_DESC 9 +#define UDF_TAGID_FILE_SET_DESC 256 +#define UDF_TAGID_FILE_IDENT_DESC 257 +#define UDF_TAGID_FILE_ENTRY 261 +#define UDF_TAGID_EXT_ATTRIBUTE_HEADER_DESC 262 + +typedef struct udf_extent_ad_ { /* ECMA-167 3/7.1 */ +/*0*/ udf_Uint32 extent_length; +/*4*/ udf_Uint32 extent_location; +/*8*/ +} udf_extent_ad; + +typedef struct udf_charspec_ { /* ECMA-167 1/7.2.1 */ +/* 0*/ udf_Uint8 character_set_type; +/* 1*/ udf_byte character_set_info[63]; +/*64*/ +} udf_charspec; + +typedef struct udf_EntityID_ { /* ECMA-167 1/7.4 */ +/* 0*/ udf_Uint8 flags; +/* 1*/ udf_byte ident[23]; +/*24*/ udf_byte ident_suffix[8]; +/*32*/ +} udf_EntityID; + +#define UDF_ENTITYID_FLAG_PROTECTED 2 /* ECMA-167 1/7.4.1 */ + +typedef struct udf_lb_addr_ { /* ECMA-167 4/7.1 */ +/*0*/ udf_Uint32 logical_block_number; +/*4*/ udf_Uint16 partition_reference_number; +/*6*/ +} udf_lb_addr; + +typedef struct udf_short_ad_ { /* ECMA-167 4/14.14.1 */ +/*0*/ udf_Uint32 extent_length; +/*4*/ udf_Uint32 extent_position; +/*8*/ +} udf_short_ad; + +typedef struct udf_long_ad_impl_use_field_ { /* UDF 2.01 2.3.4.3 */ +/*0*/ udf_Uint16 flags; +/*2*/ udf_Uint32 unique_id; +/*6*/ +} udf_long_ad_impl_use_field; + +typedef struct udf_long_ad_ { /* ECMA-167 4/14.14.2 */ +/* 0*/ udf_Uint32 extent_length; +/* 4*/ udf_lb_addr extent_location; +/*10*/ udf_long_ad_impl_use_field impl_use; +/*16*/ +} udf_long_ad; + +typedef struct udf_timestamp_ { /* TR/71 1.5.4 */ +/* 0*/ udf_Uint16 type_and_time_zone; +/* 2*/ udf_Uint16 year; +/* 4*/ udf_Uint8 month; +/* 5*/ udf_Uint8 day; +/* 6*/ udf_Uint8 hour; +/* 7*/ udf_Uint8 minute; +/* 8*/ udf_Uint8 second; +/* 9*/ udf_Uint8 centiseconds; +/*10*/ udf_Uint8 hundreds_of_microseconds; +/*11*/ udf_Uint8 microseconds; +/*12*/ +} udf_timestamp; + +typedef struct udf_volume_recognition_desc_ { /* TR/71 2.4.{1,2,3} */ + udf_Uint8 structure_type; + udf_byte standard_identifier[5]; + udf_Uint8 structure_version; + udf_zerobyte structure_data[2041]; +} udf_volume_recognition_desc; + +typedef struct udf_anchor_volume_desc_ptr_ { /* TR/71 2.5.1 */ +/* 0*/ udf_tag desc_tag; +/* 16*/ udf_extent_ad main_volume_desc_seq_extent; +/* 24*/ udf_extent_ad reserve_volume_desc_seq_extent; +/* 32*/ udf_zerobyte reserved[480]; +/*512*/ +} udf_anchor_volume_desc_ptr; + +typedef struct udf_primary_volume_desc_ { /* TR/71 2.6.1 */ +/* 0*/ udf_tag desc_tag; +/* 16*/ udf_Uint32 volume_desc_seq_number; +/* 20*/ udf_Uint32 primary_volume_desc_number; +/* 24*/ udf_dstring volume_ident[32]; +/* 56*/ udf_Uint16 volume_seq_number; +/* 58*/ udf_Uint16 maximum_volume_seq_number; +/* 60*/ udf_Uint16 interchange_level; +/* 62*/ udf_Uint16 maximum_interchange_level; +/* 64*/ udf_Uint32 character_set_list; +/* 68*/ udf_Uint32 maximum_character_set_list; +/* 72*/ udf_dstring volume_set_ident[128]; +/*200*/ udf_charspec desc_character_set; +/*264*/ udf_charspec explanatory_character_set; +/*328*/ udf_extent_ad volume_abstract; +/*336*/ udf_extent_ad volume_copyright_notice; +/*344*/ udf_EntityID application_ident; +/*376*/ udf_timestamp recording_date_and_time; +/*388*/ udf_EntityID impl_ident; +/*420*/ udf_byte impl_use[64]; +/*484*/ udf_Uint32 predecessor_volume_desc_seq_location; +/*488*/ udf_Uint16 flags; +/*490*/ udf_zerobyte reserved[22]; +/*512*/ +} udf_primary_volume_desc; + +typedef struct udf_impl_use_volume_desc_impl_use_field_ { /* TR/71 2.6.3 */ +/* 0*/ udf_charspec lvi_charset; +/* 64*/ udf_dstring logical_volume_ident[128]; +/*192*/ udf_dstring lv_info1[36]; +/*228*/ udf_dstring lv_info2[36]; +/*264*/ udf_dstring lv_info3[36]; +/*300*/ udf_EntityID impl_id; +/*332*/ udf_byte impl_use[128]; +/*460*/ +} udf_impl_use_volume_desc_impl_use_field; + +typedef struct udf_impl_use_volume_desc_ { /* TR/71 2.6.2 */ +/* 0*/ udf_tag desc_tag; +/* 16*/ udf_Uint32 volume_desc_seq_number; +/* 20*/ udf_EntityID impl_ident; +/* 52*/ udf_impl_use_volume_desc_impl_use_field impl_use; +/*512*/ +} udf_impl_use_volume_desc; + +typedef struct udf_partition_desc_ { /* TR/71 2.6.4 */ +/* 0*/ udf_tag desc_tag; +/* 16*/ udf_Uint32 volume_desc_seq_number; +/* 20*/ udf_Uint16 partition_flags; +/* 22*/ udf_Uint16 partition_number; +/* 24*/ udf_EntityID partition_contents; +/* 56*/ udf_byte partition_contents_use[128]; +/*184*/ udf_Uint32 access_type; +/*188*/ udf_Uint32 partition_starting_location; +/*192*/ udf_Uint32 partition_length; +/*196*/ udf_EntityID impl_ident; +/*228*/ udf_byte impl_use[128]; +/*356*/ udf_zerobyte reserved[156]; +/*512*/ +} udf_partition_desc; + +#define UDF_PARTITION_FLAG_ALLOCATED 1 /* ECMA-167 3/10.5.3 */ +#define UDF_ACCESSTYPE_READONLY 1 /* ECMA-167 3/10.5.7 */ + +typedef struct udf_type_1_partition_map_ { /* TR/71 2.6.8 */ +/*0*/ udf_Uint8 partition_map_type; +/*1*/ udf_Uint8 partition_map_length; +/*2*/ udf_Uint16 volume_seq_number; +/*4*/ udf_Uint16 partition_number; +/*6*/ +} udf_type_1_partition_map; + +#define UDF_PARTITION_MAP_TYPE_1 1 + +typedef struct udf_logical_volume_desc_ { /* TR/71 2.6.7 */ +/* 0*/ udf_tag desc_tag; +/* 16*/ udf_Uint32 volume_desc_seq_number; +/* 20*/ udf_charspec desc_character_set; +/* 84*/ udf_dstring logical_volume_ident[128]; +/*212*/ udf_Uint32 logical_block_size; +/*216*/ udf_EntityID domain_ident; +/*248*/ udf_long_ad logical_volume_contents_use; +/*264*/ udf_Uint32 map_table_length; +/*268*/ udf_Uint32 number_of_partition_maps; +/*272*/ udf_EntityID impl_ident; +/*304*/ udf_byte impl_use[128]; +/*432*/ udf_extent_ad integrity_seq_extent; +/*440*/ udf_type_1_partition_map partition_map[1]; +/*446*/ +} udf_logical_volume_desc; + +typedef struct udf_unallocated_space_desc_ { /* TR/71 2.6.9 */ +/* 0*/ udf_tag desc_tag; +/*16*/ udf_Uint32 volume_desc_seq_number; +/*20*/ udf_Uint32 number_of_allocation_descs; +/*24*/ /*udf_extent_ad allocation_descs[0];*/ +} udf_unallocated_space_desc; + +typedef struct udf_terminating_desc_ { /* TR/71 2.6.10 */ +/* 0*/ udf_tag desc_tag; +/* 16*/ udf_zerobyte reserved[496]; +/*512*/ +} udf_terminating_desc; + +typedef struct udf_logical_volume_integrity_desc_impl_use_field_ { /* TR/71 2.7.3 */ +/* 0*/ udf_EntityID impl_id; +/*32*/ udf_Uint32 number_of_files; +/*36*/ udf_Uint32 number_of_directories; +/*40*/ udf_Uint16 minimum_udf_read_revision; +/*42*/ udf_Uint16 minimum_udf_write_revision; +/*44*/ udf_Uint16 maximum_udf_write_revision; +/*46*/ /*udf_byte impl_use[0];*/ +} udf_logical_volume_integrity_desc_impl_use_field; + +typedef struct udf_logical_volume_integrity_desc_contents_use_field_ { /* TR/71 2.7.2 */ + udf_Uint64 unique_id; + udf_zerobyte reserved[24]; +} udf_logical_volume_integrity_desc_contents_use_field; + +typedef struct udf_logical_volume_integrity_desc_ { /* TR/71 2.7.1 */ +/* 0*/ udf_tag desc_tag; +/*16*/ udf_timestamp recording_date; +/*28*/ udf_Uint32 integrity_type; +/*32*/ udf_extent_ad next_integrity_extent; +/*40*/ udf_logical_volume_integrity_desc_contents_use_field logical_volume_contents_use; +/*72*/ udf_Uint32 number_of_partitions; +/*76*/ udf_Uint32 length_of_impl_use; +/*80*/ udf_Uint32 free_space_table; +/*84*/ udf_Uint32 size_table; +/*88*/ udf_logical_volume_integrity_desc_impl_use_field impl_use; +} udf_logical_volume_integrity_desc; + +#define UDF_INTEGRITY_TYPE_CLOSE 1 /* ECMA-167 3/10.10.3 */ + +typedef struct udf_file_set_desc_ { /* TR/71 3.3.1 */ +/* 0*/ udf_tag desc_tag; +/*16*/ udf_timestamp recording_date_and_time; +/*28*/ udf_Uint16 interchange_level; +/*30*/ udf_Uint16 maximum_interchange_level; +/*32*/ udf_Uint32 character_set_list; +/*36*/ udf_Uint32 maximum_character_set_list; +/*40*/ udf_Uint32 file_set_number; +/*44*/ udf_Uint32 file_set_desc_number; +/*48*/ udf_charspec logical_volume_ident_character_set; +/*112*/ udf_dstring logical_volume_ident[128]; +/*240*/ udf_charspec file_set_character_set; +/*304*/ udf_dstring file_set_ident[32]; +/*336*/ udf_dstring copyright_file_ident[32]; +/*368*/ udf_dstring abstract_file_ident[32]; +/*400*/ udf_long_ad root_directory_icb; +/*416*/ udf_EntityID domain_ident; +/*448*/ udf_long_ad next_extent; +/*464*/ udf_zerobyte reserved[48]; +/*512*/ +} udf_file_set_desc; + +typedef struct udf_file_ident_desc_ { /* TR/71 3.4.1 */ +/* 0*/ udf_tag desc_tag; +/*16*/ udf_Uint16 file_version_number; +/*18*/ udf_Uint8 file_characteristics; +/*19*/ udf_Uint8 length_of_file_ident; +/*20*/ udf_long_ad icb; +/*36*/ udf_Uint16 length_of_impl_use; +/*38*/ /*udf_EntityID impl_use;*/ +/*38*/ udf_dchar file_ident[1]; + /*udf_zerobyte padding[0/1/2/3];*/ +} udf_file_ident_desc; + +#define UDF_FILE_CHARACTERISTIC_HIDDEN 1 /* ECMA-167 4/14.4.3 */ +#define UDF_FILE_CHARACTERISTIC_DIRECTORY 2 +#define UDF_FILE_CHARACTERISTIC_DELETED 4 +#define UDF_FILE_CHARACTERISTIC_PARENT 8 + +typedef struct udf_icbtag_ { /* TR/71 3.5.2 */ +/* 0*/ udf_Uint32 prior_recorded_number_of_direct_entries; +/* 4*/ udf_Uint16 strategy_type; +/* 6*/ udf_Uint16 strategy_parameter; +/* 8*/ udf_Uint16 maximum_number_of_entries; +/*10*/ udf_zerobyte reserved; +/*11*/ udf_Uint8 file_type; +/*12*/ udf_lb_addr parent_icb_location; +/*18*/ udf_Uint16 flags; +/*20*/ +} udf_icbtag; + +#define UDF_ICBTAG_FILETYPE_DIRECTORY 4 /* ECMA-167 4/14.6.6 */ +#define UDF_ICBTAG_FILETYPE_BYTESEQ 5 + +#define UDF_ICBTAG_FLAG_MASK_AD_TYPE 7 /* TR/71 3.5.3 */ +#define UDF_ICBTAG_FLAG_SHORT_AD 0 +#define UDF_ICBTAG_FLAG_DIRECTORY_SORT 8 +#define UDF_ICBTAG_FLAG_NONRELOCATABLE 16 +#define UDF_ICBTAG_FLAG_ARCHIVE 32 +#define UDF_ICBTAG_FLAG_SETUID 64 +#define UDF_ICBTAG_FLAG_SETGID 128 +#define UDF_ICBTAG_FLAG_STICKY 256 +#define UDF_ICBTAG_FLAG_CONTIGUOUS 512 +#define UDF_ICBTAG_FLAG_SYSTEM 1024 +#define UDF_ICBTAG_FLAG_TRANSFORMED 2048 +#define UDF_ICBTAG_FLAG_MULTI_VERSIONS 4096 + +typedef struct udf_ext_attribute_header_desc_ { /* TR/71 3.6.1 */ +/* 0*/ udf_tag desc_tag; +/*16*/ udf_Uint32 impl_attributes_location; +/*20*/ udf_Uint32 application_attributes_location; +/*24*/ +} udf_ext_attribute_header_desc; + +typedef struct udf_ext_attribute_free_ea_space_ { /* TR/71 3.6.{2,3} */ +/* 0*/ udf_Uint32 attribute_type; /* = 2048 */ +/* 4*/ udf_Uint8 attribute_subtype; /* = 1 */ +/* 5*/ udf_zerobyte reserved[3]; +/* 8*/ udf_Uint32 attribute_length; /* = 52 */ +/*12*/ udf_Uint32 impl_use_length; /* = 4 */ +/*16*/ udf_EntityID impl_ident; /* "*UDF FreeEASpace" */ +/*48*/ udf_Uint16 header_checksum; +/*50*/ udf_Uint16 free_ea_space; /* = 0 */ +/*52*/ +} udf_ext_attribute_free_ea_space; + +typedef struct udf_ext_attribute_dvd_cgms_info_ { /* TR/71 3.6.{2,4} */ +/* 0*/ udf_Uint32 attribute_type; /* = 2048 */ +/* 4*/ udf_Uint8 attribute_subtype; /* = 1 */ +/* 5*/ udf_zerobyte reserved[3]; +/* 8*/ udf_Uint32 attribute_length; /* = 56 */ +/*12*/ udf_Uint32 impl_use_length; /* = 8 */ +/*16*/ udf_EntityID impl_ident; /* "*UDF DVD CGMS Info" */ +/*48*/ udf_Uint16 header_checksum; +/*50*/ udf_byte cgms_info; +/*51*/ udf_Uint8 data_structure_type; +/*52*/ udf_byte protection_system_info[4]; +/*56*/ +} udf_ext_attribute_dvd_cgms_info; + +#define UDF_CGMSINFO_NO_COPIES 48 /* TR/71 3.6.4 */ +#define UDF_CGMSINFO_ONE_GENERATION 32 +#define UDF_CGMSINFO_UNLIMITED_COPIES 0 +#define UDF_CGMSINFO_FLAG_COPYRIGHTED_MATERIAL 128 + +typedef struct udf_file_entry_ { /* TR/71 3.5.1 */ +/* 0*/ udf_tag desc_tag; +/*16*/ udf_icbtag icb_tag; +/*36*/ udf_Uint32 uid; +/*40*/ udf_Uint32 gid; +/*44*/ udf_Uint32 permissions; +/*48*/ udf_Uint16 file_link_count; +/*50*/ udf_Uint8 record_format; +/*51*/ udf_Uint8 record_display_attributes; +/*52*/ udf_Uint32 record_length; +/*56*/ udf_Uint64 info_length; +/*64*/ udf_Uint64 logical_blocks_recorded; +/*72*/ udf_timestamp access_time; +/*84*/ udf_timestamp modification_time; +/*96*/ udf_timestamp attribute_time; +/*108*/ udf_Uint32 checkpoint; +/*112*/ udf_long_ad ext_attribute_icb; +/*128*/ udf_EntityID impl_ident; +/*160*/ udf_Uint64 unique_id; +/*168*/ udf_Uint32 length_of_ext_attributes; +/*172*/ udf_Uint32 length_of_allocation_descs; +#if 0 +/*176*/ udf_ext_attribute_header_desc ext_attribute_header; +/*200*/ udf_ext_attribute_free_ea_space ext_attribute_free_ea_space; +/*252*/ udf_ext_attribute_dvd_cgms_info ext_attribute_dvd_cgms_info; +/*308*/ udf_short_ad allocation_desc; +/*316*/ +#else +/*176*/ udf_short_ad allocation_desc; +/*184*/ +#endif +} udf_file_entry; + +/* + * (U,G,O) = (owner, group, other) + * (X,R) = (execute, read) + * + * There are Write, Change Attribute and Delete permissions also, + * but it is not permitted to set them on DVD Read-Only media. + */ +#define UDF_FILEENTRY_PERMISSION_OX 1 /* TR/71 3.5.4 */ +#define UDF_FILEENTRY_PERMISSION_OR 4 +#define UDF_FILEENTRY_PERMISSION_GX 32 +#define UDF_FILEENTRY_PERMISSION_GR 128 +#define UDF_FILEENTRY_PERMISSION_UX 1024 +#define UDF_FILEENTRY_PERMISSION_UR 4096 + + +#endif /* _UDF_FS_H */ diff --git a/genisoimage/vms.c b/genisoimage/vms.c new file mode 100644 index 0000000..9f1c885 --- /dev/null +++ b/genisoimage/vms.c @@ -0,0 +1,320 @@ +/* + * 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. + * + */ + +/* @(#)vms.c 1.9 04/03/04 joerg */ +/* + * File vms.c - assorted bletcherous hacks for VMS. + * + * Written by Eric Youngdale (1993). + * + */ + +#include <mconfig.h> +#ifdef VMS +#define opendir fake_opendir +#include "genisoimage.h" +#undef opendir +#include <rms.h> +#include <descrip.h> +#include <ssdef.h> + +static struct RAB *rab; /* used for external mailfiles */ +static int rms_status; + +static +error_exit(char *text) +{ + fprintf(stderr, "%s\n", text); + exit(33); +} + + +char *strrchr(const char *, char); + +int +VMS_stat(char *path, struct stat * spnt) +{ + char *spath; + char sbuffer[255]; + char *pnt, + *ppnt; + char *pnt1; + + ppnt = strrchr(path, ']'); + if (ppnt) + ppnt++; + else + ppnt = path; + + spath = path; + + if (strcmp(ppnt, ".") == 0 || strcmp(ppnt, "..") == 0) { + strcpy(sbuffer, path); + + /* Find end of actual name */ + pnt = strrchr(sbuffer, ']'); + if (!pnt) + return (0); + + pnt1 = pnt; + while (*pnt1 != '[' && *pnt1 != '.') + pnt1--; + + if (*pnt1 != '[' && strcmp(ppnt, "..") == 0) { + pnt1--; + while (*pnt1 != '[' && *pnt1 != '.') + pnt1--; + }; + + if (*pnt1 == '.') { + *pnt1 = ']'; + pnt = pnt1; + while (*pnt != '.' && *pnt != ']') + pnt++; + *pnt++ = ']'; + while (*pnt != '.' && *pnt != ']') + pnt++; + *pnt = 0; + strcat(sbuffer, ".DIR;1"); + }; + + if (*pnt1 == '[') { + pnt1++; + *pnt1 = 0; + strcat(pnt1, "000000]"); + pnt1 = strrchr(path, '[') + 1; + pnt = sbuffer + strlen(sbuffer); + while (*pnt1 && *pnt1 != '.' && *pnt1 != ']') + *pnt++ = *pnt1++; + *pnt = 0; + strcat(sbuffer, ".DIR;1"); + }; + + spath = sbuffer; + }; + return (stat_filter(spath, spnt)); +} + +static int dircontext[32] = {0, }; +static char *searchpath[32]; +static struct direct d_entry[32]; + +int optind = 0; +char *optarg; + +int +getopt(int argc, char *argv[], char *flags) +{ + char *pnt; + char c; + + optind++; + if (*argv[optind] != '-') + return (EOF); + optarg = 0; + + c = *(argv[optind] + 1); + pnt = (char *) strchr(flags, c); + if (!pnt) + return (c); /* Not found */ + if (pnt[1] == ':') { + optind++; + optarg = argv[optind]; + }; + return (c); +} + +void +vms_path_fixup(char *name) +{ + char *pnt1; + + pnt1 = name + strlen(name) - 6; + + /* First strip the .DIR;1 */ + if (strcmp(pnt1, ".DIR;1") == 0) + *pnt1 = 0; + + pnt1 = (char *) strrchr(name, ']'); + if (pnt1) { + if (pnt1[1] == 0) + return; + *pnt1 = '.'; + strcat(name, "]"); + return; + }; + pnt1 = (char *) strrchr(name, '>'); + if (pnt1) { + if (pnt1[1] == 0) + return; + *pnt1 = '.'; + strcat(name, ">"); + return; + }; +} + +int +opendir(char *path) +{ + int i; + + for (i = 1; i < 32; i++) { + if (dircontext[i] == 0) { + dircontext[i] = -1; + searchpath[i] = (char *) e_malloc(strlen(path) + 6); + strcpy(searchpath[i], path); + vms_path_fixup(searchpath[i]); + strcat(searchpath[i], "*.*.*"); + return (i); + }; + }; + exit(0); +} + +struct direct * +readdir(int context) +{ + int i; + char cresult[100]; + char *pnt; + int status; + + $DESCRIPTOR(dpath, searchpath[context]); + $DESCRIPTOR(result, cresult); + + if (dircontext[context] == -1) { + dircontext[context] = -2; + strcpy(d_entry[context].d_name, "."); + return (&d_entry[context]); + }; + + if (dircontext[context] == -2) { + dircontext[context] = -3; + strcpy(d_entry[context].d_name, ".."); + return (&d_entry[context]); + }; + + if (dircontext[context] == -3) + dircontext[context] = 0; + + dpath.dsc$w_length = strlen(searchpath[context]); + lib$find_file(&dpath, &result, &dircontext[context], + 0, 0, &status, 0); + + if (status == SS$_NOMOREFILES) + return (0); + + /* Now trim trailing spaces from the name */ + i = result.dsc$w_length - 1; + while (i && cresult[i] == ' ') + i--; + cresult[i + 1] = 0; + + /* Now locate the actual portion of the file we want */ + + pnt = (char *) strrchr(cresult, ']'); + if (pnt) + pnt++; + else + pnt = cresult; + + strcpy(d_entry[context].d_name, pnt); + return (&d_entry[context]); +} + +void +closedir(int context) +{ + lib$find_file_end(&dircontext[context]); + free(searchpath[context]); + searchpath[context] = (char *) 0; + dircontext[context] = 0; +} + +static +open_file(char *fn) +{ + /* + * this routine initializes a rab and fab required to get the + * correct definition of the external data file used by mail + */ + struct FAB *fab; + + rab = (struct RAB *) e_malloc(sizeof (struct RAB)); + fab = (struct FAB *) e_malloc(sizeof (struct FAB)); + + *rab = cc$rms_rab; /* initialize RAB */ + rab->rab$l_fab = fab; + + *fab = cc$rms_fab; /* initialize FAB */ + fab->fab$l_fna = fn; + fab->fab$b_fns = strlen(fn); + fab->fab$w_mrs = 512; + fab->fab$b_fac = FAB$M_BIO | FAB$M_GET; + fab->fab$b_org = FAB$C_SEQ; + fab->fab$b_rfm = FAB$C_FIX; + fab->fab$l_xab = (char *) 0; + + rms_status = sys$open(rab->rab$l_fab); + if (rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED) + error_exit("$OPEN"); + rms_status = sys$connect(rab); + if (rms_status != RMS$_NORMAL) + error_exit("$CONNECT"); + return (1); +} + +static +close_file(struct RAB * prab) +{ + rms_status = sys$close(prab->rab$l_fab); + free(prab->rab$l_fab); + free(prab); + if (rms_status != RMS$_NORMAL) + error_exit("$CLOSE"); +} + +#define NSECT 16 +extern unsigned int last_extent_written; + +int +vms_write_one_file(char *filename, off_t size, FILE * outfile) +{ + int status, + i; + char buffer[SECTOR_SIZE * NSECT]; + int count; + int use; + off_t remain; + + open_file(filename); + + remain = size; + + while (remain > 0) { + use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT * SECTOR_SIZE : remain); + use = ROUND_UP(use); /* Round up to nearest sector boundary */ + memset(buffer, 0, use); + rab->rab$l_ubf = buffer; + rab->rab$w_usz = sizeof (buffer); + status = sys$read(rab); + fwrite(buffer, 1, use, outfile); + last_extent_written += use / SECTOR_SIZE; + if ((last_extent_written % 1000) < use / SECTOR_SIZE) + fprintf(stderr, "%d..", last_extent_written); + remain -= use; + }; + + close_file(rab); +} + +#endif diff --git a/genisoimage/vms.h b/genisoimage/vms.h new file mode 100644 index 0000000..722fb82 --- /dev/null +++ b/genisoimage/vms.h @@ -0,0 +1,29 @@ +/* + * 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. + * + */ + +/* @(#)vms.h 1.3 04/03/01 eric */ +/* + * Header file genisoimage.h - assorted structure definitions and typecasts. + * + * Written by Eric Youngdale (1993). + */ + +#ifdef VMS +#define stat(X, Y) VMS_stat(X, Y) +#define lstat VMS_stat + +/* gmtime not available under VMS - make it look like we are in Greenwich */ +#define gmtime localtime + +extern int vms_write_one_file(char *filename, off_t size, FILE * outfile); + +#endif diff --git a/genisoimage/volume.c b/genisoimage/volume.c new file mode 100644 index 0000000..dd45336 --- /dev/null +++ b/genisoimage/volume.c @@ -0,0 +1,728 @@ +/* + * 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. + * + */ + +/* @(#)volume.c 1.14 04/07/09 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 James Pearson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * volume.c: prepare HFS volume for mkhybrid + * + * James Pearson 17/7/97 + * modified JCP 29/7/97 to improve allocation sizes to cut + * down on wasted space. Now uses the HFS "allocation" size rounded + * up to the nearest 2048 bytes. Savings can be significant with + * a large volume containing lots of smallish files. + * + * Updated for v1.12 - now uses the built in RELOCATED_DIRECTORY + * flag for finding the real directory location JCP 8/1/97 + */ + +#ifdef APPLE_HYB + +#include <mconfig.h> +#include "genisoimage.h" +#include <errno.h> + +#define HFS_MIN_SIZE 1600 /* 800k == 1600 HFS blocks */ + +static hfsvol *vol_save = 0; /* used to "destroy" an HFS volume */ + +static int AlcSiz(Ulong); +static int XClpSiz(Ulong); +static int get_vol_size(int); +int write_fork(hfsfile * hfp, long tot); +int make_mac_volume(struct directory *, int); +static int copy_to_mac_vol(hfsvol *, struct directory *); +static void set_dir_info(hfsvol *, struct directory *); + +/* + * AlcSiz: find allocation size for given volume size + */ +static int +AlcSiz(Ulong vlen) +{ + int lpa, + drAlBlkSiz; + + /* code extracted from hfs_format() */ + lpa = 1 + vlen / 65536; + drAlBlkSiz = lpa * HFS_BLOCKSZ; + + /* + * now set our "allocation size" to the allocation block rounded up to + * the nearest SECTOR_SIZE (2048 bytes) + */ + drAlBlkSiz = ROUND_UP(drAlBlkSiz, SECTOR_SIZE); + + return (drAlBlkSiz); +} + +/* + * XClpSiz: find the default size of the catalog/extent file + */ +static int +XClpSiz(Ulong vlen) +{ + int olpa, + lpa, + drNmAlBlks, + drAlBlkSiz; + int vbmsz, + drXTClpSiz; + + /* code extracted from hfs_format() */ + + /* get the lpa from our calculated allocation block size */ + drAlBlkSiz = AlcSiz(vlen); + lpa = drAlBlkSiz / HFS_BLOCKSZ; + + vbmsz = (vlen / lpa + 4095) / 4096; + drNmAlBlks = (vlen - 5 - vbmsz) / lpa; + drXTClpSiz = drNmAlBlks / 128 * drAlBlkSiz; + + /* override the drXTClpSiz size for large volumes */ + if (drXTClpSiz > hce->max_XTCsize) { + drXTClpSiz = hce->max_XTCsize; + } else { + /* + * make allowances because we have possibly rounded up the + * allocation size get the "original" lpa " + */ + olpa = 1 + vlen / 65536; + + /* adjust size upwards */ + drXTClpSiz = ((Ullong)drXTClpSiz * lpa) / olpa; + } + + /* round up to the nearest allocation size */ + drXTClpSiz = ROUND_UP(drXTClpSiz, drAlBlkSiz); + + return (drXTClpSiz); +} + +/* + * get_vol_size: get the size of the volume including the extent/catalog + */ +static int +get_vol_size(int vblen) +{ + int drXTClpSiz; + int drAlBlkSiz; + int new_vblen; + + /* + * try to estimate a "volume size" based on the code in hfs_format + * - we need the size of the catalog/extents and Desktop files included + * in the volume, as we add this to the end of the ISO volume + */ + drXTClpSiz = XClpSiz(vblen); + drAlBlkSiz = AlcSiz(vblen); + + /* + * catalog file is set at CTC times (default twice) the extents + * file size - hence the (ctc_size + 1) below. The Desktop starts of + * the same size as the "clump size" == 4 x drAlBlkSiz, + * plus a spare drAlBlkSiz for the alternative MDB + */ + new_vblen = vblen + + ((hce->ctc_size + 1) * drXTClpSiz + 5 * drAlBlkSiz) / HFS_BLOCKSZ; + + return (new_vblen); +} + +/* + * write_fork: "write" file data to the volume + * + * This is used to update the HFS file internal structures + * but no data is actually written (it's trapped deep down in + * libhfs). + */ +int +write_fork(hfsfile *hfp, long tot) +{ + char blk[HFS_BLOCKSZ]; + unsigned short start; + long len; + + len = tot; + /* we need to know where this fork starts */ + start = hfs_get_drAllocPtr(hfp); + + /* loop through the data a block at a time */ + while (len >= HFS_BLOCKSZ) { + if (hfs_write(hfp, blk, HFS_BLOCKSZ) < 0) + return (-1); + len -= HFS_BLOCKSZ; + } + /* write out anything left */ + if (len) + if (hfs_write(hfp, blk, len) < 0) + return (-1); + + /* + * set the start of the allocation search to be immediately after + * this fork + */ + hfs_set_drAllocPtr(hfp, start, tot); + + return (0); +} + +/* + * make_mac_volume: "create" an HFS volume using the ISO data + * + * The HFS volume structures are set up (but no data is written yet). + * + * ISO volumes have a allocation size of 2048 bytes - regardless + * of the size of the volume. HFS allocation size is depends on volume + * size, so we may have to update the ISO structures to add in any + * padding. + */ +int +make_mac_volume(struct directory *dpnt, int start_extent) +{ + char vol_name[HFS_MAX_VLEN + 1]; /* Mac volume name */ + hfsvol *vol; /* Mac volume */ + int vblen; /* vol length (HFS blocks) */ + int Csize, + lastCsize; /* allocation sizes */ + int ret = 0; /* return value */ + int loop = 1; + + /* umount volume if we have had a previous attempt */ + if (vol_save) + if (hfs_umount(vol_save, 0, hfs_lock) < 0) + return (-1); + + /* set the default clump size to the ISO block size */ + Csize = lastCsize = SECTOR_SIZE; + + if (verbose > 1) + fprintf(stderr, "Creating HFS Volume info\n"); + + /* name or copy ISO volume name to Mac Volume name */ + strncpy(vol_name, hfs_volume_id ? hfs_volume_id : volume_id, + HFS_MAX_VLEN); + vol_name[HFS_MAX_VLEN] = '\0'; + + /* get initial size of HFS volume (size of current ISO volume) */ + vblen = (last_extent - session_start) * HFS_BLK_CONV; + + /* make sure volume is at least 800k */ + if (vblen < HFS_MIN_SIZE) + vblen += insert_padding_file(HFS_MIN_SIZE - vblen); + + /* + * add on size of extents/catalog file, but this may mean the + * allocation size will change, so loop round until the + * allocation size doesn't change + */ + while (loop) { + hce->XTCsize = XClpSiz(vblen); + vblen = get_vol_size(vblen); + Csize = AlcSiz(vblen); + + if (Csize == lastCsize) { + /* allocation size hasn't changed, so carry on */ + loop = 0; + } else { + /* + * allocation size has changed, so update + * ISO volume size + */ + if ((vblen = get_adj_size(Csize)) < 0) { + sprintf(hce->error, + "too many files for HFS volume"); + return (-1); + } + vblen += + ROUND_UP((start_extent - session_start) * + HFS_BLK_CONV, Csize); + lastCsize = Csize; + } + } + + /* take off the label/map size */ + vblen -= hce->hfs_map_size; + + hce->hfs_vol_size = vblen; + + /* set the default allocation size for libhfs */ + hce->Csize = Csize; + + /* format and mount the "volume" */ + if (hfs_format(hce, 0, vol_name) < 0) { + sprintf(hce->error, "can't HFS format %s", vol_name); + return (-1); + } + /* + * update the ISO structures with new start extents and any + * padding required + */ + if (Csize != SECTOR_SIZE) { + last_extent = adj_size(Csize, start_extent, + hce->hfs_hdr_size + hce->hfs_map_size); + adj_size_other(dpnt); + } + if ((vol = hfs_mount(hce, 0, 0)) == 0) { + sprintf(hce->error, "can't HFS mount %s", vol_name); + return (-1); + } + /* save the volume for possible later use */ + vol_save = vol; + + /* + * Recursively "copy" the files to the volume + * - we need to know the first allocation block in the volume as + * starting blocks of files are relative to this. + */ + ret = copy_to_mac_vol(vol, dpnt); + if (ret < 0) + return (ret); + + /* + * make the Desktop files - I *think* this stops the Mac rebuilding the + * desktop when the CD is mounted on a Mac These will be ignored if they + * already exist + */ + if (create_dt) + ret = make_desktop(vol, + (last_extent - session_start) * HFS_BLK_CONV); + if (ret < 0) + return (ret); + + /* close the volume */ + if (hfs_flush(vol) < 0) + return (-1); + + /* unmount and set the start blocks for the catalog/extents files */ + if (hfs_umount(vol, (last_extent - session_start) * HFS_BLK_CONV, hfs_lock) < 0) + return (-1); + + return (Csize); +} + +#define TEN 10 /* well, it is! */ +#define LCHAR "_" + +/* + * copy_to_mac_vol: copy all files in a directory to corresponding + * Mac folder. + * + * Files are copied recursively to corresponding folders on the Mac + * volume. The caller routine needs to do a hfs_chdir before calling this + * routine. + */ +static int +copy_to_mac_vol(hfsvol *vol, struct directory *node) +{ + struct directory_entry *s_entry; /* ISO directory entry */ + struct directory_entry *s_entry1; /* tmp ISO directory entry */ + struct directory *dpnt; /* ISO directory */ + + hfsfile *hfp; /* HFS file */ + hfsdirent *ent; /* HFS file entities */ + long id; /* current HFS folder */ + long dext, + rext; /* real data/rsrc start blk */ + int ret; /* result code */ + int new_name; /* HFS file has modified name */ + + int tens; + int digits; + int i; + + /* store the current HFS directory ID */ + if ((id = hfs_getcwd(vol)) == 0) + return (-1); + + if (verbose > 1) + fprintf(stderr, "HFS scanning %s\n", node->whole_name); + + /* loop through the ISO directory entries and process files */ + for (s_entry = node->contents; s_entry; s_entry = s_entry->next) { + /* ignore directory and associated (rsrc) files */ + if (s_entry->isorec.flags[0] & (ISO_DIRECTORY|ISO_ASSOCIATED)) + continue; + + /* ignore any non-Mac type file */ + if (!s_entry->hfs_ent) + continue; + + /* + * ignore if from a previous session + * - should be trapped above + */ + if (s_entry->starting_block < session_start) + continue; + +#ifdef DEBUG + fprintf(stderr, " Name = %s", s_entry->whole_name); + fprintf(stderr, " Startb = %d\n", s_entry->starting_block); +#endif /* DEBUG */ + + ent = s_entry->hfs_ent; + + /* create file */ + i = HFS_MAX_FLEN - strlen(ent->name); + new_name = 0; + tens = TEN; + digits = 1; + + while (1) { + /* + * try to open file - if it exists, + * then append '_' to the name and try again + */ + errno = 0; + if ((hfs_create(vol, ent->name, ent->u.file.type, + ent->u.file.creator)) < 0) { + if (errno != EEXIST) { + /* + * not an "exist" error, or we can't + * append as the filename is already + * HFS_MAX_FLEN chars + */ + sprintf(hce->error, + "can't HFS create file %s", + s_entry->whole_name); + return (-1); + } else if (i == 0) { + /* + * File name at max HFS length + * - make unique name + */ + if (!new_name) + new_name++; + + sprintf(ent->name + + HFS_MAX_FLEN - digits - 1, + "%s%d", LCHAR, new_name); + new_name++; + if (new_name == tens) { + tens *= TEN; + digits++; + } + } else { + /* append '_' to get new name */ + strcat(ent->name, LCHAR); + i--; + new_name = 1; + } + } else + break; + } + + /* warn that we have a new name */ + if (new_name && verbose > 0) { + fprintf(stderr, "Using HFS name: %s for %s\n", + ent->name, + s_entry->whole_name); + } + /* open file */ + if ((hfp = hfs_open(vol, ent->name)) == 0) { + sprintf(hce->error, "can't HFS open %s", + s_entry->whole_name); + return (-1); + } + /* if it has a data fork, then "write" it out */ + if (ent->u.file.dsize) + write_fork(hfp, ent->u.file.dsize); + + /* if it has a resource fork, set the fork and "write" it out */ + if (ent->u.file.rsize) { + if ((hfs_setfork(hfp, 1)) < 0) + return (-1); + write_fork(hfp, ent->u.file.rsize); + } + + /* make file invisible if ISO9660 hidden */ + if (s_entry->de_flags & HIDDEN_FILE) + ent->fdflags |= HFS_FNDR_ISINVISIBLE; + + /* update any HFS file attributes */ + if ((hfs_fsetattr(hfp, ent)) < 0) { + sprintf(hce->error, "can't HFS set attributes %s", + s_entry->whole_name); + return (-1); + } + /* + * get the ISO starting block of data fork (may be zero) + * and convert to the equivalent HFS block + */ + if (ent->u.file.dsize) { + dext = (s_entry->starting_block - session_start) * + HFS_BLK_CONV; + } else { + dext = 0; + } + + /* + * if the file has a resource fork (associated file), + * get it's ISO starting block and convert as above + */ + if (s_entry->assoc && ent->u.file.rsize) { + rext = + (s_entry->assoc->starting_block - session_start) * + HFS_BLK_CONV; + } else { + rext = 0; + } + + /* close the file and update the starting blocks */ + if (hfs_close(hfp, dext, rext) < 0) { + sprintf(hce->error, "can't HFS close file %s", + s_entry->whole_name); + return (-1); + } + } + + /* set folder info and custom icon (if it exists) */ + set_dir_info(vol, node); + + /* + * process sub-directories - have a slight problem here, + * if the directory had been relocated, then we need to find the + * real directory - we do this by first finding the + * real directory_entry, and then finding it's directory info + */ + + /* following code taken from joliet.c */ + for (s_entry = node->contents; s_entry; s_entry = s_entry->next) { + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { + /* + * if the directory has been reloacted, then search the + * relocated directory for the real entry + */ + for (s_entry1 = reloc_dir->contents; s_entry1; + s_entry1 = s_entry1->next) { + if (s_entry1->parent_rec == s_entry) + break; + } + + /* have a problem - can't find the real directory */ + if (s_entry1 == NULL) { + sprintf(hce->error, + "can't locate relocated directory %s", + s_entry->whole_name); + return (-1); + } + } else + s_entry1 = s_entry; + + /* now have the correct entry - now find the actual directory */ + if ((s_entry1->isorec.flags[0] & ISO_DIRECTORY) && + strcmp(s_entry1->name, ".") && + strcmp(s_entry1->name, "..")) { + if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) + dpnt = reloc_dir->subdir; + else + dpnt = node->subdir; + + while (1) { + if (dpnt->self == s_entry1) + break; + dpnt = dpnt->next; + if (!dpnt) { + sprintf(hce->error, + "can't find directory location %s", + s_entry1->whole_name); + return (-1); + } + } + /* + * now have the correct directory + * - so do the HFS stuff + */ + ent = dpnt->hfs_ent; + + /* + * if we don't have hfs entries, then this is a "deep" + * directory - this will be processed later + */ + if (!ent) + continue; + + /* make sub-folder */ + i = HFS_MAX_FLEN - strlen(ent->name); + new_name = 0; + tens = TEN; + digits = 1; + + while (1) { + /* + * try to create new directory + * - if it exists, then append '_' to the name + * and try again + */ + errno = 0; + if (hfs_mkdir(vol, ent->name) < 0) { + if (errno != EEXIST) { + /* + * not an "exist" error, + * or we can't append as the + * filename is already + * HFS_MAX_FLEN chars + */ + sprintf(hce->error, + "can't HFS create folder %s", + s_entry->whole_name); + return (-1); + } else if (i == 0) { + /* + * File name at max HFS length + * - make unique name + */ + if (!new_name) + new_name++; + + sprintf(ent->name + + HFS_MAX_FLEN - digits - 1, + "%s%d", LCHAR, new_name); + new_name++; + if (new_name == tens) { + tens *= TEN; + digits++; + } + } else { + /* append '_' to get new name */ + strcat(ent->name, LCHAR); + i--; + new_name = 1; + } + } else + break; + } + + /* warn that we have a new name */ + if (new_name && verbose > 0) { + fprintf(stderr, "Using HFS name: %s for %s\n", + ent->name, + s_entry->whole_name); + } + /* see if we need to "bless" this folder */ + if (hfs_bless && strcmp(s_entry->whole_name, hfs_bless) + == 0) { + hfs_stat(vol, ent->name, ent); + hfs_vsetbless(vol, ent->cnid); + if (verbose > 0) { + fprintf(stderr, "Blessing %s (%s)\n", + ent->name, + s_entry->whole_name); + } + /* stop any further checks */ + hfs_bless = NULL; + } + /* change to sub-folder */ + if (hfs_chdir(vol, ent->name) < 0) + return (-1); + + /* recursively copy files ... */ + ret = copy_to_mac_vol(vol, dpnt); + if (ret < 0) + return (ret); + + /* change back to this folder */ + if (hfs_setcwd(vol, id) < 0) + return (-1); + } + } + + return (0); +} + +/* + * set_dir_info: Set directory info for a file - also use a custom + * Icon - if it exists. + * + * Sets folder' layout (window layout, view, scroll bars etc) + * + * Set the 'HFS_FNDR_HASCUSTOMICON' bit of the folder flags + * if a file called 'Icon\r' exists in the folder + * + * Also makes sure the Icon file is invisible + * Don't worry if any of this fails ... + * + * Thanks to Rob Leslie <rob@mars.org> for how to do this. + */ + +#define ICON "Icon" + +static void +set_dir_info(hfsvol *vol, struct directory *de) +{ + hfsdirent *ent = de->hfs_ent; + hfsdirent ent1; + char name[HFS_MAX_FLEN + 1]; + unsigned short flags = 0; + + memset(&ent1, 0, sizeof (hfsdirent)); + + sprintf(name, "%s\r", ICON); + + /* get the attributes for the Icon file */ + if (hfs_stat(vol, name, &ent1) == 0) { + + /* make sure it is invisible */ + ent1.fdflags |= HFS_FNDR_ISINVISIBLE; + + /* set the new attributes for the Icon file */ + hfs_setattr(vol, name, &ent1); + + /* flag the folder as having a custom icon */ + flags |= HFS_FNDR_HASCUSTOMICON; + } + + /* make the current folder invisible if ISO9660 hidden */ + if (de->self->de_flags & HIDDEN_FILE) { + flags |= HFS_FNDR_ISINVISIBLE; + } + + /* may not have an hfs_ent for this directory */ + if (ent == NULL) { + ent = &ent1; + memset(ent, 0, sizeof (hfsdirent)); + + /* get the attributes for the folder */ + if (hfs_stat(vol, ":", ent) < 0) + return; + } + + /* set HFS_FNDR_HASCUSTOMICON/HFS_FNDR_ISINVISIBLE if needed */ + ent->fdflags |= flags; + + /* set the new attributes for the folder */ + if (hfs_setattr(vol, ":", ent) < 0) { + /* + * Only needed if we add things after this if statement. + */ +/* return;*/ + } +} + +#endif /* APPLE_HYB */ diff --git a/genisoimage/write.c b/genisoimage/write.c new file mode 100644 index 0000000..a423ab1 --- /dev/null +++ b/genisoimage/write.c @@ -0,0 +1,2840 @@ +/* + * 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. + * + */ + +/* @(#)write.c 1.88 06/02/01 joerg */ +/* Parts from @(#)write.c 1.106 07/02/17 joerg */ +/* + * Program write.c - dump memory structures to file for iso9660 filesystem. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999-2003 J. Schilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */ + +#include <mconfig.h> +#include "genisoimage.h" +#include <timedefs.h> +#include <fctldefs.h> +#ifdef SORTING +#include "match.h" +#endif /* SORTING */ +#include <errno.h> +#include <schily.h> +#ifdef DVD_VIDEO +#include "dvd_reader.h" +#include "dvd_file.h" +#include "ifo_read.h" +#endif +#ifdef APPLE_HYB +#include <ctype.h> +#endif + +#ifdef VMS +#include "vms.h" +#endif + +/* Max number of sectors we will write at one time */ +#define NSECT 16 + +/* Counters for statistics */ + +static int table_size = 0; +static int total_dir_size = 0; +static int rockridge_size = 0; +static struct directory **pathlist; +static int next_path_index = 1; +static int sort_goof; + +static int is_rr_dir = 0; + +struct output_fragment *out_tail; +struct output_fragment *out_list; + +struct iso_primary_descriptor vol_desc; + +void set_721(char *pnt, unsigned int i); +void set_722(char *pnt, unsigned int i); +void set_723(char *pnt, unsigned int i); +void set_731(char *pnt, unsigned int i); +void set_732(char *pnt, unsigned int i); +void set_733(char *pnt, unsigned int i); +int get_731(char *p); +int get_732(char *p); +int get_733(char *p); +static int xawrite(void *buffer, int size, int count, FILE *file, + int submode, BOOL islast); +void xfwrite(void *buffer, int size, int count, FILE *file, int submode, + BOOL islast); +static int assign_directory_addresses(struct directory *node); +#ifdef APPLE_HYB +static void write_one_file(char *filename, off_t size, FILE *outfile, + off_t off); +#else +static void write_one_file(char *filename, off_t size, FILE *outfile); +#endif +static void write_files(FILE *outfile); +#if 0 +static void dump_filelist __PR((void)); +#endif +static int compare_dirs(const void *rr, const void *ll); +int sort_directory(struct directory_entry **sort_dir, int rr); +static int root_gen(void); +static BOOL assign_file_addresses(struct directory *dpnt, BOOL isnest); +static void free_one_directory(struct directory *dpnt); +static void free_directories(struct directory *dpnt); +void generate_one_directory(struct directory *dpnt, FILE *outfile); +static void build_pathlist(struct directory *node); +static int compare_paths(void const *r, void const *l); +static int generate_path_tables(void); +void memcpy_max(char *to, char *from, int max); +void outputlist_insert(struct output_fragment *frag); +static int file_write(FILE *outfile); +static int pvd_write(FILE *outfile); +static int xpvd_write(FILE *outfile); +static int evd_write(FILE *outfile); +static int vers_write(FILE *outfile); +static int graftcp(char *to, char *from, char *ep); +static int pathcp(char *to, char *from, char *ep); +static int pathtab_write(FILE *outfile); +static int exten_write(FILE *outfile); +int oneblock_size(int starting_extent); +static int pathtab_size(int starting_extent); +static int startpad_size(int starting_extent); +static int interpad_size(int starting_extent); +static int endpad_size(int starting_extent); +static int file_gen(void); +static int dirtree_dump(void); +static int dirtree_fixup(int starting_extent); +static int dirtree_size(int starting_extent); +static int ext_size(int starting_extent); +static int dirtree_write(FILE *outfile); +static int dirtree_cleanup(FILE *outfile); +static int startpad_write(FILE *outfile); +static int interpad_write(FILE *outfile); +static int endpad_write(FILE *outfile); +#ifdef APPLE_HYB +static int hfs_pad; +static int hfs_get_parms(char *key); +static void hfs_file_gen(int start_extent); +static void gen_prepboot(void); +Ulong get_adj_size(int Csize); +int adj_size(int Csize, int start_extent, int extra); +void adj_size_other(struct directory *dpnt); +static int hfs_hce_write(FILE * outfile); +int insert_padding_file(int size); +#endif /* APPLE_HYB */ + +#ifdef SORTING +static int compare_sort(const void * rr, const void * ll); +static void reassign_link_addresses(struct directory * dpnt); +static int sort_file_addresses(void); +#endif /* SORTING */ + +/* + * Routines to actually write the disc. We write sequentially so that + * we could write a tape, or write the disc directly + */ +#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof (vol_desc.X)) + +void +set_721(char *pnt, unsigned int i) +{ + pnt[0] = i & 0xff; + pnt[1] = (i >> 8) & 0xff; +} + +void +set_722(char *pnt, unsigned int i) +{ + pnt[0] = (i >> 8) & 0xff; + pnt[1] = i & 0xff; +} + +void +set_723(char *pnt, unsigned int i) +{ + pnt[3] = pnt[0] = i & 0xff; + pnt[2] = pnt[1] = (i >> 8) & 0xff; +} + +void +set_731(char *pnt, unsigned int i) +{ + pnt[0] = i & 0xff; + pnt[1] = (i >> 8) & 0xff; + pnt[2] = (i >> 16) & 0xff; + pnt[3] = (i >> 24) & 0xff; +} + +void +set_732(char *pnt, unsigned int i) +{ + pnt[3] = i & 0xff; + pnt[2] = (i >> 8) & 0xff; + pnt[1] = (i >> 16) & 0xff; + pnt[0] = (i >> 24) & 0xff; +} + +void +set_733(char *pnt, unsigned int i) +{ + pnt[7] = pnt[0] = i & 0xff; + pnt[6] = pnt[1] = (i >> 8) & 0xff; + pnt[5] = pnt[2] = (i >> 16) & 0xff; + pnt[4] = pnt[3] = (i >> 24) & 0xff; +} + +int +get_731(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +int +get_732(char *p) +{ + return ((p[3] & 0xff) + | ((p[2] & 0xff) << 8) + | ((p[1] & 0xff) << 16) + | ((p[0] & 0xff) << 24)); +} + +int +get_733(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +void +xfwrite(void *buffer, int size, int count, FILE *file, int submode, BOOL islast) +{ + /* + * This is a hack that could be made better. + * XXXIs this the only place? + * It is definitely needed on Operating Systems that do not allow to + * write files that are > 2GB. If the system is fast enough to be able + * to feed 1400 KB/s writing speed of a DVD-R drive, use stdout. + * If the system cannot do this reliable, you need to use this hacky + * option. + */ + static int idx = 0; + +#ifdef XFWRITE_DEBUG + if (count != 1 || (size % 2048) != 0) + fprintf(stderr, "Count: %d, size: %d\n", count, size); +#endif + + if (split_output != 0 && + (idx == 0 || ftell(file) >= ((off_t)1024 * 1024 * 1024))) { + char nbuf[512]; + extern char *outfile; + + if (idx == 0) + unlink(outfile); + sprintf(nbuf, "%s_%02d", outfile, idx++); + file = freopen(nbuf, "wb", file); + if (file == NULL) { +#ifdef USE_LIBSCHILY + comerr("Cannot open '%s'.\n", nbuf); +#else + fprintf(stderr, "Cannot open '%s'.\n", nbuf); + exit(1); +#endif + } + } + while (count) { + int got; + + seterrno(0); + if (osecsize != 0) + got = xawrite(buffer, size, count, file, submode, islast); + else + got = fwrite(buffer, size, count, file); + + if (got <= 0) { +#ifdef USE_LIBSCHILY + comerr("cannot fwrite %d*%d\n", size, count); +#else + fprintf(stderr, "cannot fwrite %d*%d\n", size, count); + exit(1); +#endif + } + /* + * This comment is in hope to prevent silly people from + * e.g. SuSE (who did not yet learn C but believe that + * they need to patch other peoples code) from changing the + * next cast into an illegal lhs cast expression. + * The cast below is the correct way to handle the problem. + * The (void *) cast is to avoid a GCC warning like: + * "warning: dereferencing type-punned pointer will break \ + * strict-aliasing rules" + * which is wrong this code. (void *) introduces a compatible + * intermediate type in the cast list. + */ + count -= got; + buffer = (void *)(((char *)buffer) + size * got); + } +} + +static int +xawrite(void *buffer, int size, int count, FILE *file, int submode, BOOL islast) +{ + register char *p = buffer; + register int amt = size * count; + register int n; + struct xa_subhdr subhdr[2]; + + if (osecsize == 2048) + return (fwrite(buffer, size, count, file)); + + if (amt % 2048) + comerrno(EX_BAD, + "Trying to write %d bytes (not a multiple of 2048).\n", + amt); + + subhdr[0].file_number = subhdr[1].file_number = 0; + subhdr[0].channel_number = subhdr[1].channel_number = 0; + subhdr[0].coding = subhdr[1].coding = 0; + + while (amt > 0) { +#ifdef LATER + if (submode < 0) + subhdr[0].sub_mode = subhdr[1].sub_mode = XA_SUBH_DATA; + else + subhdr[0].sub_mode = subhdr[1].sub_mode = submode; +#else + subhdr[0].sub_mode = subhdr[1].sub_mode = XA_SUBH_DATA; +#endif + + if ((amt <= 2048) && islast) { + subhdr[0].sub_mode = subhdr[1].sub_mode + |= (XA_SUBH_EOR|XA_SUBH_EOF); + } + n = fwrite(&subhdr, sizeof (subhdr), 1, file); + if (n <= 0) + return (n); + + n = fwrite(p, 2048, 1, file); + if (n <= 0) + return (n); + + p += 2048; + amt -= 2048; + } + return (1); +} + +#ifdef APPLE_HYB +/* + * use the deferred_write struct to store info about the hfs_boot_file + */ +static struct deferred_write mac_boot; + +#endif /* APPLE_HYB */ +static struct deferred_write *dw_head = NULL, + *dw_tail = NULL; + +unsigned int last_extent_written = 0; +static Uint path_table_index; +time_t begun; + +/* + * We recursively walk through all of the directories and assign extent + * numbers to them. We have already assigned extent numbers to everything that + * goes in front of them + */ +static int +assign_directory_addresses(struct directory *node) +{ + int dir_size; + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + /* skip if it's hidden */ + if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { + dpnt = dpnt->next; + continue; + } + /* + * If we already have an extent for this (i.e. it came from a + * multisession disc), then don't reassign a new extent. + */ + dpnt->path_index = next_path_index++; + if (dpnt->extent == 0) { + dpnt->extent = last_extent; + dir_size = ISO_BLOCKS(dpnt->size); + + last_extent += dir_size; + + /* + * Leave room for the CE entries for this directory. + * Keep them close to the reference directory so that + * access will be quick. + */ + if (dpnt->ce_bytes) { + last_extent += ISO_BLOCKS(dpnt->ce_bytes); + } + } + if (dpnt->subdir) { + assign_directory_addresses(dpnt->subdir); + } + dpnt = dpnt->next; + } + return (0); +} + +#ifdef APPLE_HYB +static void +write_one_file(char *filename, off_t size, FILE *outfile, off_t off) +#else +static void +write_one_file(char *filename, off_t size, FILE *outfile) +#endif /* APPLE_HYB */ +{ + /* + * It seems that there are still stone age C-compilers + * around. + * The Metrowerks C found on BeOS/PPC does not allow + * more than 32kB of local vars. + * As we do not need to call write_one_file() recursively + * we make buffer static. + */ +static char buffer[SECTOR_SIZE * NSECT]; + FILE *infile; + off_t remain; + int use; + + char *mirror_name; + unsigned char md5[16]; + int include_in_jigdo = list_file_in_jigdo(filename, size, &mirror_name, md5); + + if ((infile = fopen(filename, "rb")) == NULL) { +#ifdef USE_LIBSCHILY + comerr("cannot open '%s'\n", filename); +#else +#ifndef HAVE_STRERROR + fprintf(stderr, "cannot open '%s': (%d)\n", + filename, errno); +#else + fprintf(stderr, "cannot open '%s': %s\n", + filename, strerror(errno)); +#endif + exit(1); +#endif + } +#ifdef APPLE_HYB + fseek(infile, off, SEEK_SET); +#endif /* APPLE_HYB */ + remain = size; + + if (include_in_jigdo) + write_jt_match_record(filename, mirror_name, SECTOR_SIZE, size, md5); + + while (remain > 0) { + int amt; + + use = (remain > SECTOR_SIZE * NSECT - 1 ? + NSECT * SECTOR_SIZE : remain); + use = ISO_ROUND_UP(use); /* Round up to nearest sector */ + /* boundary */ + memset(buffer, 0, use); + seterrno(0); + amt = fread(buffer, 1, use, infile); + if (amt < use && amt < remain) { + /* + * Note that genisoimage is not star and no 100% archiver. + * We only detect file growth if the new size does not + * match 'use' at the last read. + */ + if (geterrno() == 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "File '%s' did shrink.\n" + "Files must not be changed while genisoimage runs!\n", + filename); +#else + fprintf(stderr, + "File '%s' did shrink.\n" + "Files must not be changed while genisoimage runs!\n", + filename); + exit(EX_BAD); +#endif + } +#ifdef USE_LIBSCHILY + comerr("Cannot read from '%s'\n", filename); +#else + fprintf(stderr, "Cannot read from '%s'\n", filename); + exit(1); +#endif + } + if (!include_in_jigdo) + jtwrite(buffer, use, 1, + XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT)); + xfwrite(buffer, use, 1, outfile, + XA_SUBH_DATA, remain <= (SECTOR_SIZE * NSECT)); + last_extent_written += use / SECTOR_SIZE; +#if 0 + if ((last_extent_written % 1000) < use / SECTOR_SIZE) { + fprintf(stderr, "%d..", last_extent_written); + } +#else + if (verbose > 0 && + (int)(last_extent_written % (gui ? 500 : 5000)) < + use / SECTOR_SIZE) { + time_t now; + time_t the_end; + double frac; + + time(&now); + frac = last_extent_written / (1.0 * last_extent); + the_end = begun + (now - begun) / frac; +#ifndef NO_FLOATINGPOINT + fprintf(stderr, "%6.2f%% done, estimate finish %s", + frac * 100., ctime(&the_end)); +#else + fprintf(stderr, "%3d.%-02d%% done, estimate finish %s", + (int)(frac * 100.), + (int)((frac+.00005) * 10000.)%100, + ctime(&the_end)); +#endif + fflush(stderr); + } +#endif + remain -= use; + } + fclose(infile); +}/* write_one_file(... */ + +static void +write_files(FILE *outfile) +{ + struct deferred_write *dwpnt, + *dwnext; + + dwpnt = dw_head; + while (dwpnt) { +/*#define DEBUG*/ +#ifdef DEBUG + fprintf(stderr, + "The file name is %s and pad is %d, size is %lld and extent is %d\n", + dwpnt->name, dwpnt->pad, + (Llong)dwpnt->size, dwpnt->extent); +#endif + if (dwpnt->table) { + jtwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1, XA_SUBH_DATA, TRUE); + xfwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1, + outfile, + XA_SUBH_DATA, TRUE); + last_extent_written += ISO_BLOCKS(dwpnt->size); + table_size += dwpnt->size; +/* fprintf(stderr, "Size %lld ", (Llong)dwpnt->size); */ + free(dwpnt->table); + dwpnt->table = NULL; + } else { + +#ifdef VMS + vms_write_one_file(dwpnt->name, dwpnt->size, outfile); +#else +#ifdef APPLE_HYB + write_one_file(dwpnt->name, dwpnt->size, outfile, + dwpnt->off); +#else + write_one_file(dwpnt->name, dwpnt->size, outfile); +#endif /* APPLE_HYB */ +#endif + free(dwpnt->name); + dwpnt->name = NULL; + } + + +#ifndef DVD_VIDEO +#define dvd_video 0 +#endif + +#ifndef APPLE_HYB +#define apple_hyb 0 +#endif + +#if defined(APPLE_HYB) || defined(DVD_VIDEO) + + if (apple_hyb || dvd_video) { + /* + * we may have to pad out ISO files to work with HFS + * clump sizes + */ + char blk[SECTOR_SIZE]; + Uint i; + + for (i = 0; i < dwpnt->pad; i++) { + jtwrite(blk, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(blk, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + } + } +#endif /* APPLE_HYB || DVD_VIDEO */ + + + dwnext = dwpnt; + dwpnt = dwpnt->next; + free(dwnext); + dwnext = NULL; + } +}/* write_files(... */ + +#if 0 +static void +dump_filelist() +{ + struct deferred_write *dwpnt; + + dwpnt = dw_head; + while (dwpnt) { + fprintf(stderr, "File %s\n", dwpnt->name); + dwpnt = dwpnt->next; + } + fprintf(stderr, "\n"); +} + +#endif + +static int +compare_dirs(const void *rr, const void *ll) +{ + char *rpnt, + *lpnt; + struct directory_entry **r, + **l; + + r = (struct directory_entry **) rr; + l = (struct directory_entry **) ll; + rpnt = (*r)->isorec.name; + lpnt = (*l)->isorec.name; + +#ifdef APPLE_HYB + /* + * resource fork MUST (not sure if this is true for HFS volumes) be + * before the data fork - so force it here + */ + if ((*r)->assoc && (*r)->assoc == (*l)) + return (1); + if ((*l)->assoc && (*l)->assoc == (*r)) + return (-1); +#endif /* APPLE_HYB */ + + /* If the entries are the same, this is an error. */ + if (strcmp(rpnt, lpnt) == 0) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Error: '%s' and '%s' have the same ISO9660 name '%s'.\n", + (*r)->whole_name, (*l)->whole_name, + rpnt); +#else + fprintf(stderr, + "Error: '%s' and '%s' have the same ISO9660 name '%s'.\n", + (*r)->whole_name, (*l)->whole_name, + rpnt); +#endif + sort_goof++; + } + /* Check we don't have the same RR name */ + if (use_RockRidge && !is_rr_dir) { + /* + * entries *can* have the same RR name in the "rr_moved" + * directory so skip checks if we're in reloc_dir + */ + if (!(strcmp((*r)->name, (*l)->name))) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Error: '%s' and '%s' have the same Rock Ridge name '%s'.\n", + (*r)->whole_name, (*l)->whole_name, + (*r)->name); +#else + fprintf(stderr, + "Error: '%s' and '%s' have the same Rock Ridge name '%s'.\n", + (*r)->whole_name, (*l)->whole_name, + (*r)->name); +#endif + sort_goof++; + } + } + /* + * Put the '.' and '..' entries on the head of the sorted list. For + * normal ASCII, this always happens to be the case, but out of band + * characters cause this not to be the case sometimes. + * FIXME(eric) - these tests seem redundant, in that the name is never + * assigned these values. It will instead be \000 or \001, and thus + * should always be sorted correctly. I need to figure out why I + * thought I needed this in the first place. + */ +#if 0 + if (strcmp(rpnt, ".") == 0) + return (-1); + if (strcmp(lpnt, ".") == 0) + return (1); + + if (strcmp(rpnt, "..") == 0) + return (-1); + if (strcmp(lpnt, "..") == 0) + return (1); +#else + /* + * The code above is wrong (as explained in Eric's comment), leading to + * incorrect sort order iff the -L option ("allow leading dots") is in + * effect and a directory contains entries that start with a dot. + * (TF, Tue Dec 29 13:49:24 CET 1998) + */ + if ((*r)->isorec.name_len[0] == 1 && *rpnt == 0) + return (-1); /* '.' */ + if ((*l)->isorec.name_len[0] == 1 && *lpnt == 0) + return (1); + + if ((*r)->isorec.name_len[0] == 1 && *rpnt == 1) + return (-1); /* '..' */ + if ((*l)->isorec.name_len[0] == 1 && *lpnt == 1) + return (1); +#endif + + while (*rpnt && *lpnt) { + if (*rpnt == ';' && *lpnt != ';') + return (-1); + if (*rpnt != ';' && *lpnt == ';') + return (1); + + if (*rpnt == ';' && *lpnt == ';') + return (0); + + if (*rpnt == '.' && *lpnt != '.') + return (-1); + if (*rpnt != '.' && *lpnt == '.') + return (1); + + if ((unsigned char) *rpnt < (unsigned char) *lpnt) + return (-1); + if ((unsigned char) *rpnt > (unsigned char) *lpnt) + return (1); + rpnt++; + lpnt++; + } + if (*rpnt) + return (1); + if (*lpnt) + return (-1); + return (0); +} + +/* + * Function: sort_directory + * + * Purpose: Sort the directory in the appropriate ISO9660 + * order. + * + * Notes: Returns 0 if OK, returns > 0 if an error occurred. + */ +int +sort_directory(struct directory_entry **sort_dir, int rr) +{ + int dcount = 0; + int xcount = 0; + int j; + int i, + len; + struct directory_entry *s_entry; + struct directory_entry **sortlist; + + /* need to keep a count of how many entries are hidden */ + s_entry = *sort_dir; + while (s_entry) { + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + xcount++; + dcount++; + s_entry = s_entry->next; + } + + if (dcount == 0) { + return (0); + } + /* OK, now we know how many there are. Build a vector for sorting. */ + sortlist = (struct directory_entry **) + e_malloc(sizeof (struct directory_entry *) * dcount); + + j = dcount - 1; + dcount = 0; + s_entry = *sort_dir; + while (s_entry) { + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + /* put any hidden entries at the end of the vector */ + sortlist[j--] = s_entry; + } else { + sortlist[dcount] = s_entry; + dcount++; + } + len = s_entry->isorec.name_len[0]; + s_entry->isorec.name[len] = 0; + s_entry = s_entry->next; + } + + /* Each directory is required to contain at least . and .. */ + if (dcount < 2) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Directory size too small (. or .. missing ??%s)\n", + "?"); /* Try to avoid a GCC trigraph warning */ +#else + fprintf(stderr, + "Directory size too small (. or .. missing ??%s)\n", + "?"); /* Try to avoid a GCC trigraph warning */ +#endif + sort_goof = 1; + + } else { + /* only sort the non-hidden entries */ + sort_goof = 0; + is_rr_dir = rr; +#ifdef PROTOTYPES + qsort(sortlist, dcount, sizeof (struct directory_entry *), + (int (*) (const void *, const void *)) compare_dirs); +#else + qsort(sortlist, dcount, sizeof (struct directory_entry *), + compare_dirs); +#endif + + /* + * Now reassemble the linked list in the proper sorted order + * We still need the hidden entries, as they may be used in + * the Joliet tree. + */ + for (i = 0; i < dcount + xcount - 1; i++) { + sortlist[i]->next = sortlist[i + 1]; + } + + sortlist[dcount + xcount - 1]->next = NULL; + *sort_dir = sortlist[0]; + } + + free(sortlist); + sortlist = NULL; + return (sort_goof); +} + +static int +root_gen() +{ + init_fstatbuf(); + + root_record.length[0] = 1 + + offsetof(struct iso_directory_record, name[0]); + root_record.ext_attr_length[0] = 0; + set_733((char *) root_record.extent, root->extent); + set_733((char *) root_record.size, ISO_ROUND_UP(root->size)); + iso9660_date(root_record.date, root_statbuf.st_mtime); + root_record.flags[0] = ISO_DIRECTORY; + root_record.file_unit_size[0] = 0; + root_record.interleave[0] = 0; + set_723(root_record.volume_sequence_number, volume_sequence_number); + root_record.name_len[0] = 1; + return (0); +} + +#ifdef SORTING +/* + * sorts deferred_write entries based on the sort weight + */ +static int +compare_sort(const void *rr, const void *ll) +{ + struct deferred_write **r; + struct deferred_write **l; + int r_sort; + int l_sort; + + r = (struct deferred_write **) rr; + l = (struct deferred_write **) ll; + r_sort = (*r)->s_entry->sort; + l_sort = (*l)->s_entry->sort; + + if (r_sort != l_sort) + return (r_sort < l_sort ? 1 : -1); + else + return ((*r)->extent - (*l)->extent); +} + +/* + * reassign start extents to files that are "hard links" to + * files that may have been sorted + */ +static void +reassign_link_addresses(struct directory *dpnt) +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) { + /* link files have already been given the weight NOT_SORTED */ + if (s_entry->sort == NOT_SORTED) + { + /* update the start extent */ + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + set_733((char *) s_entry->isorec.extent, + s_hash->starting_block); + s_entry->starting_block = s_hash->starting_block; + } + } + + if (verbose > 2 && s_entry->size != 0) { + fprintf(stderr, "%8u %8u ", + s_entry->starting_block, + (unsigned int)(s_entry->starting_block + ISO_BLOCKS(s_entry->size) - 1)); + + if (s_entry->inode != TABLE_INODE) { + fprintf(stderr, "%s\n", s_entry->whole_name); + } else { + fprintf(stderr, "%s%s%s\n", + s_entry->filedir->whole_name, + SPATH_SEPARATOR, trans_tbl); + } + } + } + if (dpnt->subdir) { + reassign_link_addresses(dpnt->subdir); + } + + dpnt = dpnt->next; + } +} + +/* + * sort files in order of the given sort weight + */ +static int +sort_file_addresses() +{ + struct deferred_write *dwpnt; + struct deferred_write **sortlist; + struct directory_entry *s_entry; + int start_extent; + int num = 0; + int i; + + /* need to store start extents for linked files */ + flush_hash(); + + /* find out how many files we have */ + dwpnt = dw_head; + while (dwpnt) { + num++; + dwpnt = dwpnt->next; + } + + /* return if we have none */ + if (num == 0) { + return (1); + } + + /* save the start extent of the first file */ + start_extent = dw_head->extent; + + /* set up vector to store entries */ + sortlist = (struct deferred_write **) + e_malloc(sizeof (struct deferred_write *) * num); + + for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next) + sortlist[i] = dwpnt; + + /* sort the list */ +#ifdef PROTOTYPES + qsort(sortlist, num, sizeof (struct deferred_write *), + (int (*)(const void *, const void *))compare_sort); +#else + qsort(sortlist, num, sizeof (struct deferred_write *), compare_sort); +#endif + + /* reconstruct the linked list */ + for (i = 0; i < num-1; i++) { + sortlist[i]->next = sortlist[i+1]; + } + + sortlist[num-1]->next = NULL; + dw_head = sortlist[0]; + + free(sortlist); + + /* set the new start extents for the sorted list */ + for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next) { + s_entry = dwpnt->s_entry; + dwpnt->extent = s_entry->starting_block = start_extent; + set_733((char *) s_entry->isorec.extent, start_extent); + + start_extent += ISO_BLOCKS(s_entry->size); +#ifdef DVD_VIDEO + /* + * Shouldn't this be done for every type of sort? Otherwise + * we will loose every pad info we add if we sort the files + */ + if (dvd_video) { + start_extent += dwpnt->pad; + } +#endif /* DVD_VIDEO */ + + /* cache start extents for any linked files */ + add_hash(s_entry); + } + + return (0); +} +#endif /* SORTING */ + + + +static BOOL +assign_file_addresses(struct directory *dpnt, BOOL isnest) +{ + struct directory *finddir; + struct directory_entry *s_entry; + struct file_hash *s_hash; + struct deferred_write *dwpnt; + char whole_path[PATH_MAX]; +#ifdef DVD_VIDEO + char dvd_path[PATH_MAX]; + title_set_info_t * title_set_info = NULL; + char *p; +#endif + BOOL ret = FALSE; + + while (dpnt) { +#ifdef DVD_VIDEO + if (dvd_video && root == dpnt->parent && + ((p = strstr(dpnt->whole_name, "VIDEO_TS")) != 0)&& + strcmp(p, "VIDEO_TS") == 0) { + + int maxlen = strlen(dpnt->whole_name)-8; + if (maxlen > (sizeof (dvd_path)-1)) + maxlen = sizeof (dvd_path)-1; + strncpy(dvd_path, dpnt->whole_name, maxlen); + dvd_path[maxlen] = '\0'; + +#ifdef DEBUG + fprintf(stderr, "Found 'VIDEO_TS', the path is %s \n", dvd_path); +#endif + title_set_info = DVDGetFileSet(dvd_path); + if (title_set_info == 0) { + /* + * Do not switch off -dvd-video but let is fail later. + */ +/* dvd_video = 0;*/ + errmsgno(EX_BAD, "Unable to parse DVD-Video structures.\n"); + } else { + ret = TRUE; + } + } +#endif /* DVD_VIDEO */ + + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; + s_entry = s_entry->next) { + /* + * If we already have an extent for this entry, then + * don't assign a new one. It must have come from a + * previous session on the disc. Note that we don't + * end up scheduling the thing for writing either. + */ + if (get_733(s_entry->isorec.extent) != 0) { + continue; + } + /* + * This saves some space if there are symlinks present + */ + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + if (verbose > 2) { + fprintf(stderr, "Cache hit for '%s%s%s'\n", s_entry->filedir->de_name, + SPATH_SEPARATOR, + s_entry->name); + } + set_733((char *) s_entry->isorec.extent, + s_hash->starting_block); + set_733((char *) s_entry->isorec.size, + s_hash->size); +#ifdef SORTING + /* check for non-directory files */ + if (do_sort && ((s_entry->isorec.flags[0] & ISO_DIRECTORY) == 0)) { + /* make sure the real file has the highest weighting */ + s_hash->de->sort = MAX(s_entry->sort, s_hash->de->sort); + /* flag this as a potential non-sorted file */ + s_entry->sort = NOT_SORTED; + } +#endif /* SORTING */ + continue; + } + /* + * If this is for a directory that is not a . or + * a .. entry, then look up the information for the + * entry. We have already assigned extents for + * directories, so we just need to fill in the blanks + * here. + */ + if (strcmp(s_entry->name, ".") != 0 && + strcmp(s_entry->name, "..") != 0 && + s_entry->isorec.flags[0] & ISO_DIRECTORY) { + finddir = dpnt->subdir; + while (1 == 1) { + if (finddir->self == s_entry) + break; + finddir = finddir->next; + if (!finddir) { +#ifdef DVD_VIDEO + if (title_set_info != 0) { + DVDFreeFileSet(title_set_info); + } +#endif + comerrno(EX_BAD, + "Fatal goof - could not find dir entry for '%s'\n", + s_entry->name); + } + } + set_733((char *) s_entry->isorec.extent, + finddir->extent); + s_entry->starting_block = finddir->extent; + s_entry->size = ISO_ROUND_UP(finddir->size); + total_dir_size += s_entry->size; + add_hash(s_entry); + set_733((char *) s_entry->isorec.size, + ISO_ROUND_UP(finddir->size)); + continue; + } + /* + * If this is . or .., then look up the relevant info + * from the tables. + */ + if (strcmp(s_entry->name, ".") == 0) { + set_733((char *) s_entry->isorec.extent, + dpnt->extent); + + /* + * Set these so that the hash table has the + * correct information + */ + s_entry->starting_block = dpnt->extent; + s_entry->size = ISO_ROUND_UP(dpnt->size); + + add_hash(s_entry); + s_entry->starting_block = dpnt->extent; + set_733((char *) s_entry->isorec.size, + ISO_ROUND_UP(dpnt->size)); + continue; + } + if (strcmp(s_entry->name, "..") == 0) { + if (dpnt == root) { + total_dir_size += root->size; + } + set_733((char *) s_entry->isorec.extent, + dpnt->parent->extent); + + /* + * Set these so that the hash table has the + * correct information + */ + s_entry->starting_block = dpnt->parent->extent; + s_entry->size = + ISO_ROUND_UP(dpnt->parent->size); + + add_hash(s_entry); + s_entry->starting_block = dpnt->parent->extent; + set_733((char *) s_entry->isorec.size, + ISO_ROUND_UP(dpnt->parent->size)); + continue; + } + /* + * Some ordinary non-directory file. Just schedule + * the file to be written. This is all quite + * straightforward, just make a list and assign + * extents as we go. Once we get through writing all + * of the directories, we should be ready write out + * these files + */ + if (s_entry->size) { + dwpnt = (struct deferred_write *) + e_malloc(sizeof (struct deferred_write)); + /* save this directory entry for later use */ + dwpnt->s_entry = s_entry; + /* set the initial padding to zero */ + dwpnt->pad = 0; +#ifdef DVD_VIDEO + if (dvd_video && (title_set_info != 0)) { + int pad; + + pad = DVDGetFilePad(title_set_info, s_entry->name); + if (pad < 0) { + errmsgno(EX_BAD, + "Implementation botch. Video pad for file %s is %d\n", + s_entry->name, pad), + comerrno(EX_BAD, + "Either the *.IFO file is bad or you found a genisoimage bug.\n"); + } + dwpnt->pad = pad; + if (verbose > 0 && pad != 0) { + fprintf(stderr, + "The pad was %d for file %s\n", dwpnt->pad, s_entry->name); + } + } +#endif /* DVD_VIDEO */ +#ifdef APPLE_HYB + /* + * maybe an offset to start of the real + * file/fork + */ + dwpnt->off = s_entry->hfs_off; +#else + dwpnt->off = (off_t)0; +#endif /* APPLE_HYB */ + if (dw_tail) { + dw_tail->next = dwpnt; + dw_tail = dwpnt; + } else { + dw_head = dwpnt; + dw_tail = dwpnt; + } + if (s_entry->inode == TABLE_INODE) { + dwpnt->table = s_entry->table; + dwpnt->name = NULL; + sprintf(whole_path, "%s%s%s", + s_entry->filedir->whole_name, + SPATH_SEPARATOR, trans_tbl); + } else { + dwpnt->table = NULL; + strcpy(whole_path, s_entry->whole_name); + dwpnt->name = strdup(whole_path); + } + dwpnt->next = NULL; + dwpnt->size = s_entry->size; + dwpnt->extent = last_extent; + set_733((char *) s_entry->isorec.extent, + last_extent); + s_entry->starting_block = last_extent; + add_hash(s_entry); + last_extent += ISO_BLOCKS(s_entry->size); +#ifdef DVD_VIDEO + /* Shouldn't we always add the pad info? */ + if (dvd_video) { + last_extent += dwpnt->pad; + } +#endif /* DVD_VIDEO */ + if (verbose > 2 && !do_sort) { + fprintf(stderr, "%8d %8u %s\n", + s_entry->starting_block, + last_extent - 1, whole_path); + } +#ifdef DBG_ISO + if (ISO_BLOCKS(s_entry->size) > 500) { + fprintf(stderr, + "Warning: large file '%s'\n", + whole_path); + fprintf(stderr, + "Starting block is %d\n", + s_entry->starting_block); + fprintf(stderr, + "Reported file size is %lld\n", + (Llong)s_entry->size); + + } +#endif +#ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */ + + if (last_extent > (800000000 >> 11)) { + /* More than 800Mb? Punt */ + fprintf(stderr, + "Extent overflow processing file '%s'\n", + whole_path); + fprintf(stderr, + "Starting block is %d\n", + s_entry->starting_block); + fprintf(stderr, + "Reported file size is %lld\n", + (Llong)s_entry->size); + exit(1); + } +#endif + continue; + } + /* + * This is for zero-length files. If we leave the + * extent 0, then we get screwed, because many readers + * simply drop files that have an extent of zero. + * Thus we leave the size 0, and just assign the + * extent number. + */ + set_733((char *) s_entry->isorec.extent, last_extent); + } + if (dpnt->subdir) { + if (assign_file_addresses(dpnt->subdir, TRUE)) + ret = TRUE; + } + dpnt = dpnt->next; + } +#ifdef DVD_VIDEO + if (title_set_info != NULL) { + DVDFreeFileSet(title_set_info); + } + if (dvd_video && !ret && !isnest) { + errmsgno(EX_BAD, + "Could not find correct 'VIDEO_TS' directory.\n"); + } +#endif /* DVD_VIDEO */ + return (ret); +} /* assign_file_addresses(... */ + +static void +free_one_directory(struct directory *dpnt) +{ + struct directory_entry *s_entry; + struct directory_entry *s_entry_d; + + s_entry = dpnt->contents; + while (s_entry) { + s_entry_d = s_entry; + s_entry = s_entry->next; + + if (s_entry_d->rr_attributes) { + free(s_entry_d->rr_attributes); + s_entry_d->rr_attributes = NULL; + } + if (s_entry_d->name != NULL) { + free(s_entry_d->name); + s_entry_d->name = NULL; + } + if (s_entry_d->whole_name != NULL) { + free(s_entry_d->whole_name); + s_entry_d->whole_name = NULL; + } +#ifdef APPLE_HYB + if (apple_both && s_entry_d->hfs_ent && !s_entry_d->assoc) + free(s_entry_d->hfs_ent); +#endif /* APPLE_HYB */ + + free(s_entry_d); + s_entry_d = NULL; + } + dpnt->contents = NULL; +}/* free_one_directory(... */ + +static void +free_directories(struct directory *dpnt) +{ + while (dpnt) { + free_one_directory(dpnt); + if (dpnt->subdir) + free_directories(dpnt->subdir); + dpnt = dpnt->next; + } +} + +void +generate_one_directory(struct directory *dpnt, FILE *outfile) +{ + unsigned int ce_address = 0; + char *ce_buffer; + unsigned int ce_index = 0; + unsigned int ce_size; + unsigned int dir_index; + char *directory_buffer; + int new_reclen; + struct directory_entry *s_entry; + struct directory_entry *s_entry_d; + unsigned int total_size; + + total_size = ISO_ROUND_UP(dpnt->size); + directory_buffer = (char *) e_malloc(total_size); + memset(directory_buffer, 0, total_size); + dir_index = 0; + + ce_size = ISO_ROUND_UP(dpnt->ce_bytes); + ce_buffer = NULL; + + if (ce_size > 0) { + ce_buffer = (char *) e_malloc(ce_size); + memset(ce_buffer, 0, ce_size); + + ce_index = 0; + + /* Absolute byte address of CE entries for this directory */ + ce_address = last_extent_written + (total_size >> 11); + ce_address = ce_address << 11; + } + s_entry = dpnt->contents; + while (s_entry) { + /* skip if it's hidden */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { + s_entry = s_entry->next; + continue; + } + /* + * We do not allow directory entries to cross sector + * boundaries. Simply pad, and then start the next entry at + * the next sector + */ + new_reclen = s_entry->isorec.length[0]; + if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >= + SECTOR_SIZE) { + dir_index = ISO_ROUND_UP(dir_index); + } + memcpy(directory_buffer + dir_index, &s_entry->isorec, + offsetof(struct iso_directory_record, name[0]) + + s_entry->isorec.name_len[0]); + dir_index += offsetof(struct iso_directory_record, name[0]) + + s_entry->isorec.name_len[0]; + + /* Add the Rock Ridge attributes, if present */ + if (s_entry->rr_attr_size) { + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + /* + * If the RR attributes were too long, then write the + * CE records, as required. + */ + if (s_entry->rr_attr_size != s_entry->total_rr_attr_size) { + struct iso_xa_dir_record *xadp; + unsigned char *pnt; + int len, + nbytes; + + /* + * Go through the entire record, first skip + * the XA record and then fix up the + * CE entries so that the extent and offset + * are correct + */ + pnt = s_entry->rr_attributes; + len = s_entry->total_rr_attr_size; + + if (len >= 14) { + xadp = (struct iso_xa_dir_record *)pnt; + + if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' && + xadp->reserved[0] == '\0') { + len -= 14; + pnt += 14; + } + } + + while (len > 3) { +#ifdef DEBUG + if (ce_size <= 0) { + fprintf(stderr, + "Warning: ce_index(%d) && ce_address(%d) not initialized\n", + ce_index, ce_address); + } +#endif + + if (pnt[0] == 'C' && pnt[1] == 'E') { + nbytes = get_733((char *) pnt + 20); + + if ((ce_index & (SECTOR_SIZE - 1)) + nbytes >= + SECTOR_SIZE) { + ce_index = ISO_ROUND_UP(ce_index); + } + set_733((char *) pnt + 4, + (ce_address + ce_index) >> 11); + set_733((char *) pnt + 12, + (ce_address + ce_index) & (SECTOR_SIZE - 1)); + + + /* + * Now store the block in the + * ce buffer + */ + memcpy(ce_buffer + ce_index, + pnt + pnt[2], nbytes); + ce_index += nbytes; + if (ce_index & 1) { + ce_index++; + } + } + len -= pnt[2]; + pnt += pnt[2]; + } + + } + rockridge_size += s_entry->total_rr_attr_size; + memcpy(directory_buffer + dir_index, + s_entry->rr_attributes, + s_entry->rr_attr_size); + dir_index += s_entry->rr_attr_size; + } + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + s_entry_d = s_entry; + s_entry = s_entry->next; + + /* + * Joliet doesn't use the Rock Ridge attributes, so we free + * it here. + */ + if (s_entry_d->rr_attributes) { + free(s_entry_d->rr_attributes); + s_entry_d->rr_attributes = NULL; + } + } + + if (dpnt->size != dir_index) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Unexpected directory length %lld expected: %d '%s'\n", + (Llong)dpnt->size, + dir_index, dpnt->de_name); +#else + fprintf(stderr, + "Unexpected directory length %lld expected: %d '%s'\n", + (Llong)dpnt->size, + dir_index, dpnt->de_name); +#endif + } + jtwrite(directory_buffer, total_size, 1, 0, FALSE); + xfwrite(directory_buffer, total_size, 1, outfile, 0, FALSE); + last_extent_written += total_size >> 11; + free(directory_buffer); + directory_buffer = NULL; + + if (ce_size > 0) { + if (ce_index != dpnt->ce_bytes) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Continuation entry record length mismatch %d expected: %d.\n", + ce_index, dpnt->ce_bytes); +#else + fprintf(stderr, + "Continuation entry record length mismatch %d expected: %d.\n", + ce_index, dpnt->ce_bytes); +#endif + } + jtwrite(ce_buffer, ce_size, 1, 0, FALSE); + xfwrite(ce_buffer, ce_size, 1, outfile, 0, FALSE); + last_extent_written += ce_size >> 11; + free(ce_buffer); + ce_buffer = NULL; + } +}/* generate_one_directory(... */ + +static void +build_pathlist(struct directory *node) +{ + struct directory *dpnt; + + dpnt = node; + + while (dpnt) { + /* skip if it's hidden */ + if ((dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) + pathlist[dpnt->path_index] = dpnt; + + if (dpnt->subdir) + build_pathlist(dpnt->subdir); + dpnt = dpnt->next; + } +}/* build_pathlist(... */ + +static int +compare_paths(void const *r, void const *l) +{ + struct directory const *ll = *(struct directory * const *) l; + struct directory const *rr = *(struct directory * const *) r; + + if (rr->parent->path_index < ll->parent->path_index) { + return (-1); + } + if (rr->parent->path_index > ll->parent->path_index) { + return (1); + } + return (strcmp(rr->self->isorec.name, ll->self->isorec.name)); + +}/* compare_paths(... */ + +static int +generate_path_tables() +{ + struct directory_entry *de = NULL; + struct directory *dpnt; + int fix; + int i; + int j; + int namelen; + char *npnt; + char *npnt1; + int tablesize; + + /* First allocate memory for the tables and initialize the memory */ + tablesize = path_blocks << 11; + path_table_m = (char *) e_malloc(tablesize); + path_table_l = (char *) e_malloc(tablesize); + memset(path_table_l, 0, tablesize); + memset(path_table_m, 0, tablesize); + + /* + * Now start filling in the path tables. Start with root directory + */ + + path_table_index = 0; + pathlist = (struct directory **) e_malloc(sizeof (struct directory *) + * next_path_index); + memset(pathlist, 0, sizeof (struct directory *) * next_path_index); + build_pathlist(root); + + do { + fix = 0; +#ifdef PROTOTYPES + qsort(&pathlist[1], next_path_index - 1, + sizeof (struct directory *), + (int (*) (const void *, const void *)) compare_paths); +#else + qsort(&pathlist[1], next_path_index - 1, + sizeof (struct directory *), + compare_paths); +#endif + + for (j = 1; j < next_path_index; j++) { + if (pathlist[j]->path_index != j) { + pathlist[j]->path_index = j; + fix++; + } + } + } while (fix); + + for (j = 1; j < next_path_index; j++) { + dpnt = pathlist[j]; + if (!dpnt) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Entry %d not in path tables\n", j); +#else + fprintf(stderr, "Entry %d not in path tables\n", j); + exit(1); +#endif + } + npnt = dpnt->de_name; + + /* So the root comes out OK */ + if ((*npnt == 0) || (dpnt == root)) { + npnt = "."; + } + npnt1 = strrchr(npnt, PATH_SEPARATOR); + if (npnt1) { + npnt = npnt1 + 1; + } + de = dpnt->self; + if (!de) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Fatal ISO9660 goof - directory has amnesia\n"); +#else + fprintf(stderr, + "Fatal ISO9660 goof - directory has amnesia\n"); + exit(1); +#endif + } + namelen = de->isorec.name_len[0]; + + path_table_l[path_table_index] = namelen; + path_table_m[path_table_index] = namelen; + path_table_index += 2; + + set_731(path_table_l + path_table_index, dpnt->extent); + set_732(path_table_m + path_table_index, dpnt->extent); + path_table_index += 4; + + if (dpnt->parent->path_index > 0xffff) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Unable to generate sane path tables - too many directories (%d)\n", + dpnt->parent->path_index); +#else + fprintf(stderr, + "Unable to generate sane path tables - too many directories (%d)\n", + dpnt->parent->path_index); + exit(1); +#endif + } + + set_721(path_table_l + path_table_index, + dpnt->parent->path_index); + set_722(path_table_m + path_table_index, + dpnt->parent->path_index); + path_table_index += 2; + + for (i = 0; i < namelen; i++) { + path_table_l[path_table_index] = de->isorec.name[i]; + path_table_m[path_table_index] = de->isorec.name[i]; + path_table_index++; + } + if (path_table_index & 1) { + path_table_index++; /* For odd lengths we pad */ + } + } + + free(pathlist); + pathlist = NULL; + if (path_table_index != path_table_size) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Path table lengths do not match %d expected: %d\n", + path_table_index, + path_table_size); +#else + fprintf(stderr, + "Path table lengths do not match %d expected: %d\n", + path_table_index, + path_table_size); +#endif + } + return (0); +}/* generate_path_tables(... */ + +void +memcpy_max(char *to, char *from, int max) +{ + int n = strlen(from); + + if (n > max) { + n = max; + } + memcpy(to, from, n); + +}/* memcpy_max(... */ + +void +outputlist_insert(struct output_fragment *frag) +{ + struct output_fragment *nfrag; + + nfrag = e_malloc(sizeof (*frag)); + movebytes(frag, nfrag, sizeof (*frag)); + nfrag->of_start_extent = 0; + + if (out_tail == NULL) { + out_list = out_tail = nfrag; + } else { + out_tail->of_next = nfrag; + out_tail = nfrag; + } +} + +static int +file_write(FILE *outfile) +{ + Uint should_write; + +#ifdef APPLE_HYB + char buffer[SECTOR_SIZE]; + + memset(buffer, 0, sizeof (buffer)); + + if (apple_hyb) { + + int i; + + /* + * write out padding to round up to HFS allocation block + */ + for (i = 0; i < hfs_pad; i++) { + jtwrite(buffer, sizeof (buffer), 1, 0, FALSE); + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + last_extent_written++; + } + } +#endif /* APPLE_HYB */ + + /* + * OK, all done with that crap. Now write out the directories. This is + * where the fur starts to fly, because we need to keep track of each + * file as we find it and keep track of where we put it. + */ + should_write = last_extent - session_start; + + if (verbose > 2) { +#ifdef DBG_ISO + fprintf(stderr, + "Total directory extents being written = %d\n", + last_extent); +#endif + +#ifdef APPLE_HYB + if (apple_hyb) + fprintf(stderr, + "Total extents scheduled to be written (inc HFS) = %d\n", + last_extent - session_start); + else +#endif /* APPLE_HYB */ + + fprintf(stderr, + "Total extents scheduled to be written = %u\n", + last_extent - session_start); + } + /* Now write all of the files that we need. */ + write_files(outfile); + +#ifdef APPLE_HYB + /* write out extents/catalog/dt file */ + if (apple_hyb) { + + jtwrite(hce->hfs_ce, HFS_BLOCKSZ, hce->hfs_tot_size, 0, FALSE); + xfwrite(hce->hfs_ce, HFS_BLOCKSZ, hce->hfs_tot_size, outfile, 0, FALSE); + + /* round up to a whole CD block */ + if (HFS_ROUND_UP(hce->hfs_tot_size) - + hce->hfs_tot_size * HFS_BLOCKSZ) { + jtwrite(buffer, + HFS_ROUND_UP(hce->hfs_tot_size) - + hce->hfs_tot_size * HFS_BLOCKSZ, 1, 0, FALSE); + xfwrite(buffer, + HFS_ROUND_UP(hce->hfs_tot_size) - + hce->hfs_tot_size * HFS_BLOCKSZ, 1, outfile, 0, FALSE); + } + last_extent_written += ISO_ROUND_UP(hce->hfs_tot_size * + HFS_BLOCKSZ) / SECTOR_SIZE; + + /* write out HFS boot block */ + if (mac_boot.name) + write_one_file(mac_boot.name, mac_boot.size, outfile, + mac_boot.off); + } +#endif /* APPLE_HYB */ + + /* The rest is just fluff. */ + if (verbose == 0) { + return (0); + } +#ifdef APPLE_HYB + if (apple_hyb) { + fprintf(stderr, + "Total extents actually written (inc HFS) = %d\n", + last_extent_written - session_start); + fprintf(stderr, "(Size of ISO volume = %d, HFS extra = %d)\n", + last_extent_written - session_start - hfs_extra, + hfs_extra); + } else +#else + fprintf(stderr, "Total extents actually written = %d\n", + last_extent_written - session_start); +#endif /* APPLE_HYB */ + + /* Hard links throw us off here */ + if (should_write != (last_extent - session_start)) { + fprintf(stderr, + "Number of extents written not what was predicted. Please fix.\n"); + fprintf(stderr, "Predicted = %d, written = %d\n", + should_write, last_extent); + } + fprintf(stderr, "Total translation table size: %d\n", table_size); + fprintf(stderr, "Total rockridge attributes bytes: %d\n", + rockridge_size); + fprintf(stderr, "Total directory bytes: %d\n", total_dir_size); + fprintf(stderr, "Path table size(bytes): %d\n", path_table_size); + +#ifdef DEBUG + fprintf(stderr, + "next extent, last_extent, last_extent_written %d %d %d\n", + next_extent, last_extent, last_extent_written); +#endif + + return (0); + +}/* iso_write(... */ + +/* + * Function to write the PVD for the disc. + */ +static int +pvd_write(FILE *outfile) +{ + char iso_time[17]; + int should_write; + struct tm local; + struct tm gmt; + + + time(&begun); + + local = *localtime(&begun); + gmt = *gmtime(&begun); + + /* + * There was a comment here about breaking in the year 2000. + * That's not true, in 2000 tm_year == 100, so 1900+tm_year == 2000. + */ + sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", + 1900 + local.tm_year, + local.tm_mon + 1, local.tm_mday, + local.tm_hour, local.tm_min, local.tm_sec); + + local.tm_min -= gmt.tm_min; + local.tm_hour -= gmt.tm_hour; + local.tm_yday -= gmt.tm_yday; + if (local.tm_yday < -2) /* Hit new-year limit */ + local.tm_yday = 1; /* Local is GMT + 1 day */ + iso_time[16] = (local.tm_min + 60 * + (local.tm_hour + 24 * local.tm_yday)) / 15; + + /* Next we write out the primary descriptor for the disc */ + memset(&vol_desc, 0, sizeof (vol_desc)); + vol_desc.type[0] = ISO_VD_PRIMARY; + memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof (ISO_STANDARD_ID)); + vol_desc.version[0] = 1; + + memset(vol_desc.system_id, ' ', sizeof (vol_desc.system_id)); + memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); + + memset(vol_desc.volume_id, ' ', sizeof (vol_desc.volume_id)); + memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); + + should_write = last_extent - session_start; + set_733((char *) vol_desc.volume_space_size, should_write); + set_723(vol_desc.volume_set_size, volume_set_size); + set_723(vol_desc.volume_sequence_number, volume_sequence_number); + set_723(vol_desc.logical_block_size, SECTOR_SIZE); + + /* + * The path tables are used by DOS based machines to cache directory + * locations + */ + set_733((char *) vol_desc.path_table_size, path_table_size); + set_731(vol_desc.type_l_path_table, path_table[0]); + set_731(vol_desc.opt_type_l_path_table, path_table[1]); + set_732(vol_desc.type_m_path_table, path_table[2]); + set_732(vol_desc.opt_type_m_path_table, path_table[3]); + + /* Now we copy the actual root directory record */ + memcpy(vol_desc.root_directory_record, &root_record, + offsetof(struct iso_directory_record, name[0]) + 1); + + /* + * The rest is just fluff. It looks nice to fill in many of these + * fields, though. + */ + FILL_SPACE(volume_set_id); + if (volset_id) + memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id)); + + FILL_SPACE(publisher_id); + if (publisher) + memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher)); + + FILL_SPACE(preparer_id); + if (preparer) + memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer)); + + FILL_SPACE(application_id); + if (appid) + memcpy_max(vol_desc.application_id, appid, strlen(appid)); + + FILL_SPACE(copyright_file_id); + if (copyright) + memcpy_max(vol_desc.copyright_file_id, copyright, + strlen(copyright)); + + FILL_SPACE(abstract_file_id); + if (abstract) + memcpy_max(vol_desc.abstract_file_id, abstract, + strlen(abstract)); + + FILL_SPACE(bibliographic_file_id); + if (biblio) + memcpy_max(vol_desc.bibliographic_file_id, biblio, + strlen(biblio)); + + FILL_SPACE(creation_date); + FILL_SPACE(modification_date); + FILL_SPACE(expiration_date); + FILL_SPACE(effective_date); + vol_desc.file_structure_version[0] = 1; + FILL_SPACE(application_data); + + memcpy(vol_desc.creation_date, iso_time, 17); + memcpy(vol_desc.modification_date, iso_time, 17); + memcpy(vol_desc.expiration_date, "0000000000000000", 17); + memcpy(vol_desc.effective_date, iso_time, 17); + + if (use_XA) { + char *xap = &((char *)&vol_desc)[1024]; + + memcpy(&xap[0], "CD-XA001", 8); /* XA Sign. */ + memcpy(&xap[8], "\0\0", 2); /* XA flags */ + memcpy(&xap[10], "\0\0\0\0\0\0\0\0", 8); /* Start dir */ + memcpy(&xap[18], "\0\0\0\0\0\0\0\0", 8); /* Reserved */ + } + + /* if not a bootable cd do it the old way */ + jtwrite(&vol_desc, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(&vol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Function to write the Extended PVD for the disc. + */ +static int +xpvd_write(FILE *outfile) +{ + vol_desc.type[0] = ISO_VD_SUPPLEMENTARY; + vol_desc.version[0] = 2; + vol_desc.file_structure_version[0] = 2; + + /* if not a bootable cd do it the old way */ + jtwrite(&vol_desc, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(&vol_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Function to write the EVD for the disc. + */ +static int +evd_write(FILE *outfile) +{ + struct iso_primary_descriptor evol_desc; + + /* + * Now write the end volume descriptor. Much simpler than the other + * one + */ + memset(&evol_desc, 0, sizeof (evol_desc)); + evol_desc.type[0] = (unsigned char) ISO_VD_END; + memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof (ISO_STANDARD_ID)); + evol_desc.version[0] = 1; + jtwrite(&evol_desc, SECTOR_SIZE, 1, 0, TRUE); + xfwrite(&evol_desc, SECTOR_SIZE, 1, outfile, 0, TRUE); + last_extent_written += 1; + return (0); +} + +/* + * Function to write the version information for the disc. + */ +static int +vers_write(FILE *outfile) +{ + char vers[SECTOR_SIZE+1]; + int X_ac; + char **X_av; + char *cp; + int i; + int idx = 4; + int len; + extern char version_string[]; + extern int path_ind; + + /* Now write the version descriptor. */ + memset(vers, 0, sizeof (vers)); + strcpy(vers, "MKI "); + + cp = vers; + X_ac = saved_ac(); + X_av = saved_av(); + strcpy(&cp[idx], ctime(&begun)); + idx += 25; + strcpy(&cp[idx], version_string); + idx += strlen(version_string); + for (i = 1; i < X_ac; i++) { + len = strlen(X_av[i]); + if ((idx + len + 2) >= SECTOR_SIZE) + break; + cp[idx++] = ' '; + /* + * Do not give away secret information when not in debug mode. + */ + if (debug) + strcpy(&cp[idx], X_av[i]); + else if (i >= path_ind) + len = graftcp(&cp[idx], X_av[i], &vers[SECTOR_SIZE-1]); + else if (X_av[i][0] == '/') + len = pathcp(&cp[idx], X_av[i], &vers[SECTOR_SIZE-1]); + else + strcpy(&cp[idx], X_av[i]); + idx += len; + } + + cp[SECTOR_SIZE - 1] = '\0'; + /* Per default: keep privacy. Blackout the version and arguments. */ + if(getenv("ISODEBUG")) { + jtwrite(vers, SECTOR_SIZE, 1, 0, TRUE); + xfwrite(vers, SECTOR_SIZE, 1, outfile, 0, TRUE); + } else { + jtwrite(calloc(SECTOR_SIZE, 1), SECTOR_SIZE, 1, 0, TRUE); + xfwrite(calloc(SECTOR_SIZE, 1), SECTOR_SIZE, 1, outfile, 0, TRUE); + } + last_extent_written += 1; + return (0); +} + +/* + * Avoid to write unwanted information into the version info string. + */ +static int +graftcp(char *to, char *from, char *ep) +{ + int len = strlen(from); + char *node = NULL; + + if (use_graft_ptrs) + node = findgequal(from); + + if (node == NULL) { + len = 0; + node = from; + } else { + len = node - from; + *node = '\0'; + strncpy(to, from, ep - to); + *node++ = '='; + to += len++; + *to++ = '='; + } + return (len + pathcp(to, node, ep)); +} + +static int +pathcp(char *to, char *from, char *ep) +{ + int len = strlen(from); + char *p; + + p = strrchr(from, '/'); + if (p == NULL) { + strncpy(to, from, ep - to); + } else { + if (p[1] == '\0') { + --p; + while (p > from && *p != '/') + --p; + } + len = 0; + if (*p == '/') { + strncpy(to, "...", ep - to); + to += 3; + len = 3; + } + if (to < ep) { + strncpy(to, p, ep - to); + len += strlen(to); + } + } + return (len); +} + + +/* + * Function to write the path table for the disc. + */ +static int +pathtab_write(FILE *outfile) +{ + /* Next we write the path tables */ + jtwrite(path_table_l, path_blocks << 11, 1, 0, FALSE); + xfwrite(path_table_l, path_blocks << 11, 1, outfile, 0, FALSE); + last_extent_written += path_blocks; + jtwrite(path_table_m, path_blocks << 11, 1, 0, FALSE); + xfwrite(path_table_m, path_blocks << 11, 1, outfile, 0, FALSE); + last_extent_written += path_blocks; + free(path_table_l); + free(path_table_m); + path_table_l = NULL; + path_table_m = NULL; + return (0); +} + +static int +exten_write(FILE *outfile) +{ + jtwrite(extension_record, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(extension_record, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +/* + * Functions to describe padding block at the start of the disc. + */ +int +oneblock_size(int starting_extent) +{ + last_extent++; + return (0); +} + +/* + * Functions to describe path table size. + */ +static int +pathtab_size(int starting_extent) +{ + path_table[0] = starting_extent; + + path_table[1] = 0; + path_table[2] = path_table[0] + path_blocks; + path_table[3] = 0; + last_extent += 2 * path_blocks; + return (0); +} + +/* + * Functions to describe padding blocks before PVD. + */ +static int +startpad_size(int starting_extent) +{ + last_extent = session_start + 16; + return (0); +} + +/* + * Functions to describe padding blocks between sections. + */ +static int +interpad_size(int starting_extent) +{ + int emod = 0; + +#ifdef needed + starting_extent += 16; /* First add 16 pad blocks */ +#endif + if ((emod = starting_extent % 16) != 0) { + starting_extent += 16 - emod; /* Now pad to mod 16 # */ + } + last_extent = starting_extent; + return (0); +} + +/* + * Functions to describe padding blocks at end of disk. + */ +static int +endpad_size(int starting_extent) +{ + starting_extent += 150; /* 150 pad blocks (post gap) */ + last_extent = starting_extent; + return (0); +} + +static int +file_gen() +{ +#ifdef APPLE_HYB + int start_extent = last_extent; /* orig ISO files start */ + +#endif /* APPLE_HYB */ + + if (!assign_file_addresses(root, FALSE)) { +#ifdef DVD_VIDEO + if (dvd_video) { + comerrno(EX_BAD, "Unable to make a DVD-Video image.\n" + "Possible reasons:\n" + " - VIDEO_TS subdirectory was not found on specified location\n" + " - VIDEO_TS has invalid contents\n" + ); + } +#else + ; /* EMPTY */ +#endif + } + + +#ifdef SORTING + if (do_sort) { + if (sort_file_addresses() == 0) + reassign_link_addresses(root); + } +#endif /* SORTING */ + +#ifdef APPLE_HYB + /* + * put this here for the time being - may when I've worked out how to + * use Eric's new system for creating/writing parts of the image it + * may move to it's own routine + */ + if (apple_hyb) + hfs_file_gen(start_extent); +#ifdef PREP_BOOT + else if (use_prep_boot || use_chrp_boot) + gen_prepboot(); +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + + return (0); +} + +static int +dirtree_dump() +{ + if (verbose > 2) { + dump_tree(root); + } + return (0); +} + +static int +dirtree_fixup(int starting_extent) +{ + if (use_RockRidge && reloc_dir) + finish_cl_pl_entries(); + + if (use_RockRidge) + update_nlink_field(root); + return (0); +} + +static int +dirtree_size(int starting_extent) +{ + assign_directory_addresses(root); + return (0); +} + +static int +ext_size(int starting_extent) +{ + extern int extension_record_size; + struct directory_entry *s_entry; + + extension_record_extent = starting_extent; + s_entry = root->contents; + set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24, + extension_record_extent); + set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8, + extension_record_size); + last_extent++; + return (0); +} + +static int +dirtree_write(FILE *outfile) +{ + generate_iso9660_directories(root, outfile); + return (0); +} + +static int +dirtree_cleanup(FILE *outfile) +{ + free_directories(root); + return (0); +} + +static int +startpad_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + int i; + int npad; + + memset(buffer, 0, sizeof (buffer)); + + npad = session_start + 16 - last_extent_written; + + for (i = 0; i < npad; i++) { + jtwrite(buffer, sizeof (buffer), 1, 0, FALSE); + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + last_extent_written++; + } + + return (0); +} + +static int +interpad_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + int i; + int npad = 0; + + memset(buffer, 0, sizeof (buffer)); + +#ifdef needed + npad = 16; +#endif + if ((i = last_extent_written % 16) != 0) + npad += 16 - i; + + for (i = 0; i < npad; i++) { + jtwrite(buffer, sizeof (buffer), 1, 0, FALSE); + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + last_extent_written++; + } + + return (0); +} + +static int +endpad_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + int i; + + memset(buffer, 0, sizeof (buffer)); + + for (i = 0; i < 150; i++) { + jtwrite(buffer, sizeof (buffer), 1, 0, FALSE); + xfwrite(buffer, sizeof (buffer), 1, outfile, 0, FALSE); + last_extent_written++; + } + + return (0); +} + +#ifdef APPLE_HYB + +/* + * hfs_get_parms: get HFS parameters from the command line + */ + +static int +hfs_get_parms(char *key) +{ + int ret = 0; + char *p; + + if (hfs_parms == NULL) + return (ret); + + if ((p = strstr(hfs_parms, key)) != NULL) { + p += strlen(key) + 1; + sscanf(p, "%d", &ret); + } + + return (ret); +} + +/* + * hfs_file_gen: set up "fake" HFS volume using the ISO9660 tree + */ +static void +hfs_file_gen(int start_extent) +{ + int Csize; /* clump size for HFS vol */ + int loop; + int last_extent_save = last_extent; + char *p; + + /* allocate memory for the libhfs/genisoimage extra info */ + hce = (hce_mem *) e_malloc(sizeof (hce_mem)); + + hce->error = (char *) e_malloc(1024); + + /* mark as unallocated for use later */ + hce->hfs_ce = hce->hfs_hdr = hce->hfs_map = 0; + + /* reserve space for the label partition - if it is needed */ +#ifdef PREP_BOOT + /* a PReP bootable partition needs the map.. */ + if (gen_pt || use_prep_boot || use_chrp_boot) +#else + if (gen_pt) +#endif /* PREP_BOOT */ + hce->hfs_map_size = HFS_MAP_SIZE; + else + hce->hfs_map_size = 0; + + /* set the HFS parameter string to upper case */ + if (hfs_parms) { + for (p = hfs_parms; *p; p++) + *p = toupper(*p); + } + + /* set the initial factor to increase Catalog file size */ + if ((hce->ctc_size = hfs_get_parms("CTC")) == 0) + hce->ctc_size = CTC; + + /* set the max size of the Catalog file */ + if ((hce->max_XTCsize = hfs_get_parms("MAX_XTCSIZE")) == 0) + hce->max_XTCsize = MAX_XTCSIZE; + + /* set the number of time to try to make an HFS volume */ + if ((loop = hfs_get_parms("CTC_LOOP")) == 0) + loop = CTC_LOOP; + + /* + * "create" the HFS volume (just the header, catalog/extents files) if + * there's a problem with the Catalog file being too small, we keep on + * increasing the size (up to CTC_LOOP) times and try again. + * Unfortunately I don't know enough about the inner workings of HFS, + * so I can't workout the size of the Catalog file in advance (and I + * don't want to "grow" as is is normally allowed to), therefore, this + * approach is a bit over the top as it involves throwing away the + * "volume" we have created and trying again ... + */ + do { + hce->error[0] = '\0'; + + /* attempt to create the Mac volume */ + Csize = make_mac_volume(root, start_extent); + + /* if we have a problem ... */ + if (Csize < 0) { + /* + * we've made too many attempts, or got some other + * error + */ + if (loop == 0 || errno != HCE_ERROR) { + /* HCE_ERROR is not a valid errno value */ + if (errno == HCE_ERROR) + errno = 0; + + /* exit with the error */ + if (*hce->error) + fprintf(stderr, "%s\n", hce->error); + perr(hfs_error); + } else { + /* increase Catalog file size factor */ + hce->ctc_size *= CTC; + + /* + * reset the initial "last_extent" and try + * again + */ + last_extent = last_extent_save; + } + } else { + /* everything OK - just carry on ... */ + loop = 0; + } + } + while (loop--); + + hfs_extra = HFS_ROUND_UP(hce->hfs_tot_size) / SECTOR_SIZE; + + last_extent += hfs_extra; + + /* generate the Mac label and HFS partition maps */ + mac_boot.name = hfs_boot_file; + + /* + * only generate the partition tables etc. if we are making a bootable + * CD - or if the -part option is given + */ + if (gen_pt) { + if (gen_mac_label(&mac_boot)) { + if (*hce->error) + fprintf(stderr, "%s\n", hce->error); + perr(hfs_error); + } + } + /* set Autostart filename if required */ + if (autoname) { + if (autostart()) + perr("Autostart filename must less than 12 characters"); + } + /* finished with any HFS type errors */ + free(hce->error); + hce->error = 0; + + /* + * the ISO files need to start on a multiple of the HFS allocation + * blocks, so find out how much padding we need + */ + + /* + * take in accout alignment of files wrt HFS volume start - remove any + * previous session as well + */ + start_extent -= session_start; + hfs_pad = ROUND_UP(start_extent*SECTOR_SIZE + + (hce->hfs_hdr_size + hce->hfs_map_size) * HFS_BLOCKSZ, + Csize) / SECTOR_SIZE; + + hfs_pad -= (start_extent + (hce->hfs_hdr_size + hce->hfs_map_size) / + HFS_BLK_CONV); + +#ifdef PREP_BOOT + gen_prepboot_label(hce->hfs_map); +#endif /* PREP_BOOT */ + +} + +#ifdef PREP_BOOT +static void +gen_prepboot() +{ + /* + * we need to allocate the hce struct since hce->hfs_map is used to + * generate the fdisk partition map required for PReP booting + */ + hce = (hce_mem *) e_malloc(sizeof (hce_mem)); + + /* mark as unallocated for use later */ + hce->hfs_ce = hce->hfs_hdr = hce->hfs_map = 0; + + /* reserve space for the label partition - if it is needed */ + hce->hfs_map_size = HFS_MAP_SIZE; + + hce->hfs_map = (unsigned char *) e_malloc(hce->hfs_map_size * HFS_BLOCKSZ); + gen_prepboot_label(hce->hfs_map); +} + +#endif /* PREP_BOOT */ + +/* + * get_adj_size: get the ajusted size of the volume with the HFS + * allocation block size for each file + */ +Ulong +get_adj_size(int Csize) +{ + struct deferred_write *dw; + Ulong size = 0; + int count = 0; + + /* loop through all the files finding the new total size */ + for (dw = dw_head; dw; dw = dw->next) { + size += (ROUND_UP(dw->size, Csize)/HFS_BLOCKSZ); + count++; + } + + /* + * crude attempt to prevent overflows - HFS can only cope with a + * maximum of about 65536 forks (actually less) - this will trap cases + * when we have far too many files + */ + + if (count >= 65536) + return (-1); + else + return (size); +} + +/* + * adj_size: adjust the ISO record entries for all files + * based on the HFS allocation block size + */ +int +adj_size(int Csize, int start_extent, int extra) +{ + struct deferred_write *dw; + struct directory_entry *s_entry; + int size; + + /* get the adjusted start_extent (with padding) */ + /* take in accout alignment of files wrt HFS volume start */ + + start_extent -= session_start; + + start_extent = ROUND_UP(start_extent*SECTOR_SIZE + extra*HFS_BLOCKSZ, + Csize) / SECTOR_SIZE; + + start_extent -= (extra / HFS_BLK_CONV); + + start_extent += session_start; + + /* initialise file hash */ + flush_hash(); + + /* + * loop through all files changing their starting blocks and finding + * any padding needed to written out latter + */ + for (dw = dw_head; dw; dw = dw->next) { + s_entry = dw->s_entry; + s_entry->starting_block = dw->extent = start_extent; + set_733((char *) s_entry->isorec.extent, start_extent); + size = ROUND_UP(dw->size, Csize) / SECTOR_SIZE; + dw->pad = size - ISO_ROUND_UP(dw->size) / SECTOR_SIZE; + + /* + * cache non-HFS files - as there may be multiple links to + * these files (HFS files can't have multiple links). We will + * need to change the starting extent of the other links later + */ + if (!s_entry->hfs_ent) + add_hash(s_entry); + + start_extent += size; + } + + return (start_extent); +} + +/* + * adj_size_other: adjust any non-HFS files that may be linked + * to an existing file (i.e. not have a deferred_write + * entry of it's own + */ +void +adj_size_other(struct directory *dpnt) +{ + struct directory_entry *s_entry; + struct file_hash *s_hash; + + while (dpnt) { + s_entry = dpnt->contents; + for (s_entry = dpnt->contents; s_entry; + s_entry = s_entry->next) { + /* + * if it's an HFS file or a directory - then ignore + * (we're after non-HFS files) + */ + if (s_entry->hfs_ent || + (s_entry->isorec.flags[0] & ISO_DIRECTORY)) + continue; + + /* + * find any cached entry and assign new starting + * extent + */ + s_hash = find_hash(s_entry->dev, s_entry->inode); + if (s_hash) { + set_733((char *) s_entry->isorec.extent, + s_hash->starting_block); + /* not vital - but tidy */ + s_entry->starting_block = + s_hash->starting_block; + } + } + if (dpnt->subdir) { + adj_size_other(dpnt->subdir); + } + dpnt = dpnt->next; + } + + /* clear file hash */ + flush_hash(); +} + +/* + * hfs_hce_write: write out the HFS header stuff + */ +static int +hfs_hce_write(FILE *outfile) +{ + char buffer[SECTOR_SIZE]; + int n = 0; + int r; /* HFS hdr output */ + int tot_size = hce->hfs_map_size + hce->hfs_hdr_size; + + memset(buffer, 0, sizeof (buffer)); + + /* + * hack time ... if the tot_size is greater than 32Kb then + * it won't fit in the first 16 blank SECTORS (64 512 byte + * blocks, as most of this is padding, we just truncate this + * data to 64x4xHFS_BLOCKSZ ... hope this is OK ... + */ + + if (tot_size > 64) tot_size = 64; + + /* get size in CD blocks == 4xHFS_BLOCKSZ == 2048 */ + n = tot_size / HFS_BLK_CONV; + r = tot_size % HFS_BLK_CONV; + + /* write out HFS volume header info */ + jtwrite(hce->hfs_map, HFS_BLOCKSZ, tot_size, 0, FALSE); + xfwrite(hce->hfs_map, HFS_BLOCKSZ, tot_size, outfile, 0, FALSE); + + /* fill up to a complete CD block */ + if (r) { + jtwrite(buffer, HFS_BLOCKSZ, HFS_BLK_CONV - r, 0, FALSE); + xfwrite(buffer, HFS_BLOCKSZ, HFS_BLK_CONV - r, outfile, 0, FALSE); + n++; + } + last_extent_written += n; + return (0); +} + +/* + * insert_padding_file : insert a dumy file to make volume at least + * 800k + * + * XXX If we ever need to write more then 2 GB, make size off_t + */ +int +insert_padding_file(int size) +{ + struct deferred_write *dwpnt; + + /* get the size in bytes */ + size *= HFS_BLOCKSZ; + + dwpnt = (struct deferred_write *) + e_malloc(sizeof (struct deferred_write)); + dwpnt->s_entry = 0; + /* set the padding to zero */ + dwpnt->pad = 0; + /* set offset to zero */ + dwpnt->off = (off_t)0; + + /* + * don't need to wory about the s_entry stuff as it won't be touched# + * at this point onwards + */ + + /* insert the entry in the list */ + if (dw_tail) { + dw_tail->next = dwpnt; + dw_tail = dwpnt; + } else { + dw_head = dwpnt; + dw_tail = dwpnt; + } + + /* aloocate memory as a "Table" file */ + dwpnt->table = e_malloc(size); + dwpnt->name = NULL; + + dwpnt->next = NULL; + dwpnt->size = size; + dwpnt->extent = last_extent; + last_extent += ISO_BLOCKS(size); + + /* retune the size in HFS blocks */ + return (ISO_ROUND_UP(size) / HFS_BLOCKSZ); +} + +struct output_fragment hfs_desc = {NULL, NULL, NULL, hfs_hce_write, "HFS volume header"}; + +#endif /* APPLE_HYB */ + +struct output_fragment startpad_desc = {NULL, startpad_size, NULL, startpad_write, "Initial Padblock"}; +struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write, "Primary Volume Descriptor"}; +struct output_fragment xvoldesc_desc = {NULL, oneblock_size, NULL, xpvd_write, "Enhanced Volume Descriptor"}; +struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write, "End Volume Descriptor" }; +struct output_fragment version_desc = {NULL, oneblock_size, NULL, vers_write, "Version block" }; +struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write, "Path table"}; +struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write, "Directory tree" }; +struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup, "Directory tree cleanup" }; +struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write, "Extension record" }; +struct output_fragment files_desc = {NULL, NULL, file_gen, file_write, "The File(s)"}; +struct output_fragment interpad_desc = {NULL, interpad_size, NULL, interpad_write, "Intermediate Padblock"}; +struct output_fragment endpad_desc = {NULL, endpad_size, NULL, endpad_write, "Ending Padblock"}; diff --git a/icedax/CMakeLists.txt b/icedax/CMakeLists.txt new file mode 100644 index 0000000..54c2e7d --- /dev/null +++ b/icedax/CMakeLists.txt @@ -0,0 +1,34 @@ +PROJECT (icedax C) +INCLUDE_DIRECTORIES(../include ../wodim ../libparanoia ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +include(../include/AddScgBits.cmake) +include(../include/AddSchilyBits.cmake) +include(../include/AddNetworkBits.cmake) + +FIND_FILE (HAVE_SYS_SOUNDCARD_H sys/soundcard.h) +IF(HAVE_SYS_SOUNDCARD_H) + ADD_DEFINITIONS(-DHAVE_SYS_SOUNDCARD_H) +ENDIF(HAVE_SYS_SOUNDCARD_H) +FIND_FILE (HAVE_LINUX_SOUNDCARD_H linux/soundcard.h) +IF(HAVE_LINUX_SOUNDCARD_H) + ADD_DEFINITIONS(-DHAVE_LINUX_SOUNDCARD_H) +ENDIF(HAVE_LINUX_SOUNDCARD_H) + +FIND_LIBRARY(HAVE_LIBOSSAUDIO "ossaudio") +IF(HAVE_LIBOSSAUDIO) + LIST(APPEND EXTRA_LIBS "ossaudio") +ENDIF(HAVE_LIBOSSAUDIO) + +LIST(APPEND EXTRA_LIBS paranoia) +IF (WIN32) + LIST(APPEND EXTRA_LIBS winmm) +ENDIF (WIN32) + +LINK_DIRECTORIES(../librols ../libusal ../libparanoia) +ADD_EXECUTABLE (icedax aifc.c aiff.c base64.c icedax.c interface.c ioctl.c raw.c resample.c ringbuff.c scsi_cmds.c semshm.c setuid.c sha_func.c sndconfig.c sun.c toc.c wav.c) +TARGET_LINK_LIBRARIES(icedax wodimstuff ${EXTRA_LIBS}) +SET_TARGET_PROPERTIES(icedax PROPERTIES SKIP_BUILD_RPATH TRUE) + +INSTALL(TARGETS icedax DESTINATION bin) +INSTALL(PROGRAMS pitchplay readmult cdda2mp3 cdda2ogg DESTINATION bin) +INSTALL(FILES cdda2ogg.1 icedax.1 pitchplay.1 readmult.1 list_audio_tracks.1 DESTINATION ${MANSUBDIR}/man1) + diff --git a/icedax/Changelog b/icedax/Changelog new file mode 100644 index 0000000..e57a8c1 --- /dev/null +++ b/icedax/Changelog @@ -0,0 +1,570 @@ +210 Einträge +Fri Apr 6 15:58:32 2001 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.16 + bugfix symbolic constant 'linux' -> 'LINUX', code cleanup + +Sun Mar 11 17:55:25 2001 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.11 + schily changes + +Sun Mar 11 17:25:14 2001 Heiko Eissfeldt <heiko@colossus.escape.de> + * semshm.c 1.6 + change to new shared memory scheme. + +Mon Dec 25 11:13:42 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * config.h 1.3 + get rid of PRETEND_TO_USE, use ARGSUSED instead + +Sun Dec 10 16:49:56 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.10 + Large file type fix: u_char -> Uchar + +Sat Dec 9 23:41:42 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * Makefile 1.2 + add libraries for remote scsi + +Sat Dec 9 23:39:59 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.9 + read toc in msf AND lba format. Use mins,secs,frms fields. + +Sat Dec 9 23:38:25 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.h 1.6 + portability fix: change signed char to int for mins,secs,frms + +Sat Dec 9 23:37:18 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.9 + change mins, secs, frms to type int; use conversion function lba_2_msf + +Sat Dec 9 23:35:43 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.15 + add conversion function lba_2_msf + +Fri Dec 1 14:37:10 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.15 + change ReadToc_sim to define new toc struc members mins, secs, frms. + +Fri Dec 1 14:36:22 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.8 + change ReadToc to read in MSF as well as in LBA format. Store seperately. + +Fri Dec 1 14:35:04 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.h 1.5 + add seperate fields in toc structure: mins, secs, frms for + msf can hold different data than lba (as seen by dvds) + +Mon Nov 6 21:14:11 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.23 + fix from Joerg Schilling for better Cygwin old/new compatibility + +Wed Oct 25 23:48:02 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.22 + don't try to get cd text info on discs with data tracks only + +Wed Oct 25 23:47:20 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.14 + disable Read TOC cd text for Sony CRX100E reported by George Fisher (fisher@ssl.berkeley.edu) + +Tue Sep 19 21:30:57 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.21 + fix from js for wait() declarations + +Fri Sep 15 12:51:43 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.20 + adapt for Cygwin 1.0 header files + +Wed Sep 13 23:06:25 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.19 + * interface.c 1.13 + * scsi_cmds.c 1.7 + (r)scsi interface changes + +Sun Aug 20 17:29:02 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.6 + * cdda2wav.c 1.18 + * interface.c 1.12 + adapt for new libscsi + +Sat Jun 24 07:57:38 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.17 + use setpriority if available before nice + +Sat Jun 24 07:56:40 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.14 + ISRC hardening II + +Fri Jun 16 00:12:21 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * mycdrom.h 1.4 + bugfix: FreeBSD should get the ioctl interface again + +Fri Jun 16 00:11:39 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.8 + bugfix: FreeBSD ioctl should work again + +Sat Jun 10 22:27:43 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.13 + recorder id detection and extended character range for ISRC + +Fri Jun 2 08:56:22 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.11 + added schily header files + interface change for ReadCdRom* functions + now allocate always a SCSI structure for use of silent and verbose + thats it. + +Fri Jun 2 08:49:08 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.16 + added schily header files + major changes for cds with illegal leadout positions + moved nSamplesToDo into the shared memory segment + added exit wrapper for portability under Max-OS-X + cleaned up ring buffer handling + bugfix for silent mode (call DisplayToc and Read_MCN_ISRC was needed) + +Fri Jun 2 08:37:12 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.12 + added schily header files + made cd text detection more reliable for plextor/sony non-mmc drives + hardened cdda2wav against illegal ISRC codes + major changes for cds with illegal leadout positions + protected the index scan against illegal leadout positions + *** CHANGED *** 00/06/02 07:43:08 heiko + added schilys header files + +Fri Jun 2 08:33:44 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * aifc.c 1.4 + * aiff.c 1.4 + include schilys header files + +Fri Jun 2 08:32:28 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * semshm.c 1.5 + added schily headerfile + +Fri Jun 2 08:31:53 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.h 1.4 + interface change for ReadCdRom*. Return int instead of void + +Fri Jun 2 08:30:51 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.5 + interface change: Read* function do not exit the program, when + sectors could not be read. Instead they signal this through the return value. + +Fri Jun 2 08:28:37 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.h 1.3 + interface change: Read* functions now return number of sectors read + added myscsierr function for scsi result checking + +Fri Jun 2 08:26:46 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.7 + interface change: ReadCdrom and ReadCdromData return number of read sectors + schily include file added + default buffer size set to 8 sectors for ide on Linux + suppress errors when usalp->silent > 0 + +Fri Jun 2 07:39:55 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ringbuff.c 1.4 + added a pointer for the new shared memory reference eorecording + +Fri Jun 2 07:38:48 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ringbuff.h 1.4 + new variables in shared memory: + end_is_reached is set when the previously unknown leadout is encountered. + nSamplesToDo has been moved into shared memory to be visible for the writer. + +Fri Jun 2 07:36:11 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * local.cnf.in 1.3 + bugfixes: SunOS sound device, NetBSD inclusion of extralibs + +Fri Jun 2 07:34:37 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * configure.in 1.2 + bugfix. include detected libs in EXTRALIBS + +Fri Jun 2 07:29:12 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * global.h 1.4 + added two globals for detection of cds with illegal lead out positions + and one for a drive capability to read beyond the wrong leadout position. + +Tue May 2 21:41:40 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * resample.c 1.9 + fixed an signedness warning for buffer pointer for WriteSound() + +Thu Apr 27 23:53:49 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.15 + -t4+4 -B now records only one track +4 is interpreted as a limit + +Sat Apr 22 23:37:57 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * setuid.c 1.3 + fixed a drop root forever bug, when we were currently nonroot + +Mon Apr 17 08:27:51 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * resample.c 1.8 + fixed 'wait for signal' + +Mon Apr 17 08:27:23 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.14 + fixed info files generation, added warnings + +Mon Apr 17 08:26:37 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.11 + fixed empty title display + +Thu Apr 13 00:38:04 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.13 + added some consistency checks for info file generation + +Wed Apr 12 22:54:37 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.4 + fixed read cd text wrt reserved track/session field (now 0) + +Mon Apr 10 07:49:11 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * sndfile.h 1.3 + new interface methods for mp3 + +Thu Mar 30 00:03:38 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.10 + add isrc and mcn retrieval for cd-extra + +Wed Mar 29 23:12:09 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.9 + fixed a bug with gui-mode and quote() function usage + +Wed Mar 29 21:24:04 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.6 + allow for sun type ioctl even on non_suns (HAVE_SYS_CDIO_H) + +Wed Mar 29 21:21:51 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * mycdrom.h 1.3 + disable HAVE_IOCTL_INTERFACE even if HAVE_SYS_CDIO_H (for Mac OS X) + +Sun Mar 26 23:17:47 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * resample.c 1.7 + change write call for sndfile to new sndfile method WriteSound + +Sun Mar 26 23:14:47 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.12 + variable name change 'fill_buffer' -> 'he_fill_buffer' + prepare for new output format mp3 with lame (disabled with #ifdef USE_LAME) + +Sun Mar 26 23:10:19 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ringbuff.c 1.3 + * ringbuff.h 1.3 + variable name change to avoid collision with fill_buffer from lame + +Sun Mar 26 23:09:14 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.h 1.3 + mask SCSI depend declarations with NO_SCSI_STUFF define + +Sun Mar 26 23:08:27 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.8 + fix an unimportant typo in resolve_id not active + +Sun Mar 26 22:14:53 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * aifc.c 1.3 + * aiff.c 1.3 + * raw.c 1.3 + * sun.c 1.3 + * wav.c 1.3 + prepared sndfile interface for additional functions needed for mp3 + +Tue Mar 21 21:42:10 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.10 + added the DEC RRD47 drive as not mmc/readCD capable + +Tue Mar 21 20:25:44 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.11 + fixed an cd extra detection bug + disabled .cddb and .cdindex file generation with --gui + +Tue Mar 21 20:22:26 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * Makefile.man 1.1 + date and time created 00/03/21 20:22:26 by heiko + +Tue Mar 21 20:17:28 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.7 + added cactus data shield copy protection recognition + fixed display for cd extra (track times) + fix for sony crx140s (delivers Qsubchannel position data in bcd instead of hex) + fixed screen output during index scan cosmetically + +Tue Mar 21 20:06:19 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.5 + added rough debugging messages for -V + fixed index scanning for Linux and FreeBSD + +Tue Mar 21 18:45:30 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.9 + included inquiry message, added rough ioctl debugging messages + +Sun Feb 20 23:07:27 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * resample.c 1.6 + fixed a compiler warning + +Sun Feb 20 23:07:16 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.8 + fixed missing global.in_lendian substitutes + +Thu Feb 17 22:00:32 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.10 + made deemphasizing automatic + adjusted info files accordingly + allow non-root users to fail on realtimescheduling (and continue) + get shared memory initialization from interface.c now based on nsectors and + overlap values. + add more checks for buffers and nsectors. + increase buffers and nsectors, if necessary + +Thu Feb 17 21:56:22 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.7 + moved shared memory allocation to cdda2wav.c + open linux ioctl devices with O_NONBLOCK + +Thu Feb 17 21:52:15 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * resample.c 1.5 + fix synchronization with channel swaps or deemphasizing + +Thu Feb 17 21:50:59 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * scsi_cmds.c 1.3 + avoid error message, if speedselectMMC fails (is optional) + +Thu Feb 17 21:50:00 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.6 + fix compiler warnings, fix index scanning + +Thu Feb 17 21:48:43 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * semshm.c 1.4 + moved free_sem() in order to compile properly + +Thu Feb 17 21:47:04 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * global.h 1.3 + add input endianess variable for SCSI setup + +Wed Feb 16 21:26:40 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * semshm.c 1.3 + fixed comments and variable names for child/parent role swap + +Sun Feb 13 22:28:42 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * resample.c 1.4 + changed deemphasizing (now for marked tracks) + +Sun Feb 13 22:27:34 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.9 + automatic handling of -T (with index scanning) + +Sun Feb 13 22:26:38 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.h 1.4 + new get_current_track() function + +Sun Feb 13 22:21:04 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.1 1.5 + document new -T, cleanup + +Thu Feb 10 18:35:26 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.5 + implemented reading of cdplus/info.cdp through ISO file system + +Mon Feb 7 22:47:24 2000 root + * interface.c 1.6 + added Hitachi drive to mmc exception list + +Mon Feb 7 18:17:40 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.5 + explicitly let Toshiba ATAPI drives use the mmc command set. + +Sat Feb 5 11:47:00 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.8 + fixed percentage display for the 100% case + +Sat Feb 5 11:46:38 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.4 + extended simulation interface + +Thu Feb 3 20:59:12 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.c 1.4 + added the missing ascii to html character mapper + added check for valid cd extra + +Wed Feb 2 23:54:48 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.7 + fixed mixed mode multinaming + allow nonroot users , do not abort for failing prioctl() + +Tue Jan 25 18:57:39 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.h 1.3 + * toc.h 1.3 + prototype change with index scanning function + +Tue Jan 25 18:55:58 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.4 + fixed dumb warning + +Tue Jan 25 18:43:49 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * interface.c 1.3 + extend ioctl interface for FreeBSD-4.x atapi driver + +Sat Jan 22 21:24:16 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * ioctl.c 1.3 + fixed data reading for cd-Extra+ATAPI+Linux + +Tue Jan 11 23:16:11 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.6 + * toc.c 1.3 + + +Sun Jan 9 12:11:21 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.5 + index scanning limited to single tracks, if requested. + changed vfprintf() to Joerg Schillings error() for better portability. + modified error handling for wrong parameters. no more long usage listing. + + +Mon Jan 3 22:53:51 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.4 + * resample.c 1.3 + * mmsystem.h 1.4 + *_h -> *_H + +Sun Jan 2 23:22:23 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * mmsystem.h 1.3 + delete ctrl-m lineends + +Sun Jan 2 23:18:58 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.1 1.4 + new fix for SCCS (@(x)) + +Sun Jan 2 18:20:36 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.1 1.3 + fixed man page for SCCS header + +Sun Jan 2 18:07:17 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * mmsystem.h 1.2 + put under SCCS + +Sun Jan 2 18:02:48 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * lconfig.h.in 1.3 + * sndconfig.c 1.3 + OSS sound support added for NetBSD + +Sun Jan 2 17:56:13 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * mmsystem.h 1.1 + date and time created 00/01/02 17:56:13 by heiko + +Sun Jan 2 17:53:10 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * Makefile 1.1 + date and time created 00/01/02 17:53:10 by heiko + +Sun Jan 2 17:24:41 2000 Heiko Eissfeldt <heiko@colossus.escape.de> + * configure.in 1.1 + date and time created 00/01/02 17:24:41 by heiko + +Sun Dec 19 22:34:34 1999 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.c 1.3 + multiple file names + +Sun Dec 19 21:52:00 1999 Heiko Eissfeldt <heiko@colossus.escape.de> + * toc.h 1.2 + * wav.c 1.2 + * wav.h 1.2 + * sha_func.c 1.2 + * sndconfig.c 1.2 + * sndconfig.h 1.2 + * sndfile.h 1.2 + * sun.c 1.2 + * sun.h 1.2 + * toc.c 1.2 + * ringbuff.h 1.2 + * saveargs.h 1.2 + * scsi_cmds.c 1.2 + * scsi_cmds.h 1.2 + * semshm.c 1.2 + * semshm.h 1.2 + * setuid.c 1.2 + * setuid.h 1.2 + * sha.h 1.2 + * md5c.c 1.2 + * mycdrom.h 1.2 + * mytype.h 1.2 + * raw.c 1.2 + * raw.h 1.2 + * resample.c 1.2 + * resample.h 1.2 + * ringbuff.c 1.2 + * global.h 1.2 + * interface.c 1.2 + * interface.h 1.2 + * ioctl.c 1.2 + * ioctl.h 1.2 + * lconfig.h.in 1.2 + * local.cnf.in 1.2 + * lowlevel.h 1.2 + * md5.h 1.2 + * aiff.h 1.2 + * base64.c 1.2 + * base64.h 1.2 + * byteorder.h 1.2 + * cdda2wav.1 1.2 + * cdda2wav.c 1.2 + * cdda2wav.h 1.2 + * config.h 1.2 + * aifc.c 1.2 + * aifc.h 1.2 + * aiff.c 1.2 + first + +Sat Nov 13 19:30:21 1999 Heiko Eissfeldt <heiko@colossus.escape.de> + * cdda2wav.1 1.1 + date and time created 99/11/13 19:30:21 by heiko + +Sat Nov 13 19:25:02 1999 Heiko Eissfeldt <heiko@colossus.escape.de> + * lconfig.h.in 1.1 + * local.cnf.in 1.1 + date and time created 99/11/13 19:25:02 by heiko + +Sat Nov 13 19:24:29 1999 Heiko Eissfeldt <heiko@colossus.escape.de> + * aifc.h 1.1 + * aiff.h 1.1 + * base64.h 1.1 + * byteorder.h 1.1 + * cdda2wav.h 1.1 + * config.h 1.1 + * global.h 1.1 + * interface.h 1.1 + * ioctl.h 1.1 + * lowlevel.h 1.1 + * md5.h 1.1 + * mycdrom.h 1.1 + * mytype.h 1.1 + * raw.h 1.1 + * resample.h 1.1 + * ringbuff.h 1.1 + * saveargs.h 1.1 + * scsi_cmds.h 1.1 + * semshm.h 1.1 + * setuid.h 1.1 + * sha.h 1.1 + * sndconfig.h 1.1 + * sndfile.h 1.1 + * sun.h 1.1 + * toc.h 1.1 + * wav.c 1.1 + * wav.h 1.1 + date and time created 99/11/13 19:24:29 by heiko + +Sat Nov 13 19:24:28 1999 Heiko Eissfeldt <heiko@colossus.escape.de> + * aifc.c 1.1 + * aiff.c 1.1 + * base64.c 1.1 + * cdda2wav.c 1.1 + * interface.c 1.1 + * ioctl.c 1.1 + * md5c.c 1.1 + * raw.c 1.1 + * resample.c 1.1 + * ringbuff.c 1.1 + * scsi_cmds.c 1.1 + * semshm.c 1.1 + * setuid.c 1.1 + * sha_func.c 1.1 + * sndconfig.c 1.1 + * sun.c 1.1 + * toc.c 1.1 + date and time created 99/11/13 19:24:28 by heiko + diff --git a/icedax/GPL b/icedax/GPL new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/icedax/GPL @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/icedax/aifc.c b/icedax/aifc.c new file mode 100644 index 0000000..a1001c7 --- /dev/null +++ b/icedax/aifc.c @@ -0,0 +1,213 @@ +/* + * 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. + * + */ + +/* @(#)aifc.c 1.5 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Heiko Eissfeldt + * + * + * --------------------------------------------------------------------- + * definitions for aifc pcm output + * --------------------------------------------------------------------- + */ + +#include "config.h" +#include "mytype.h" +#include <stdio.h> +#include <standard.h> +#include <unixstd.h> +#include <strdefs.h> +#include <schily.h> +#include "byteorder.h" +#include "sndfile.h" + +typedef UINT4 FOURCC; /* a four character code */ +typedef struct CHUNKHDR { + FOURCC ckid; /* chunk ID */ + UINT4 dwSize; /* chunk size */ +} CHUNKHDR; + +#define mmioFOURCC(ch0, ch1, ch2, ch3) \ + ((UINT4)(unsigned char)(ch3) | ((UINT4)(unsigned char)(ch2) << 8) | \ + ((UINT4)(unsigned char)(ch1) << 16) | ((UINT4)(unsigned char)(ch0) << 24)) + +#define FOURCC_FORM mmioFOURCC ('F', 'O', 'R', 'M') +#define FOURCC_AIFC mmioFOURCC ('A', 'I', 'F', 'C') +#define FOURCC_FVER mmioFOURCC ('F', 'V', 'E', 'R') +#define FOURCC_COMM mmioFOURCC ('C', 'O', 'M', 'M') +#define FOURCC_NONE mmioFOURCC ('N', 'O', 'N', 'E') +#define FOURCC_SSND mmioFOURCC ('S', 'S', 'N', 'D') + +#define NO_COMPRESSION "not compressed" + +/* brain dead construction from apple involving bigendian 80-bit doubles. + Definitely designed not to be portable. Alignment is a nightmare too. */ +typedef struct AIFCHDR { + CHUNKHDR formChk; + FOURCC formType; + + CHUNKHDR fverChk; /* Version chunk */ + UINT4 timestamp; /* timestamp identifies version */ + + CHUNKHDR commChk; /* Common chunk */ + /* from now on, alignment prevents us from using the original types :-(( */ + unsigned char numChannels[2]; /* Audio Channels */ + unsigned char numSampleFrames[4]; /* # of samples */ + unsigned char samplesize[2]; /* bits per sample */ + unsigned char sample_rate[10]; /* sample rate in extended float */ + unsigned char compressionType[4]; /* AIFC extension */ + unsigned char compressionNameLen; /* AIFC extension */ + char compressionName[sizeof(NO_COMPRESSION)]; /* AIFC extension */ + + unsigned char ssndChkid[4]; /* Sound data chunk */ + unsigned char dwSize[4]; /* size of chunk */ + unsigned char offset[4]; /* start of 1st sample */ + unsigned char blocksize[4]; /* aligned sound data block size */ + +} AIFCHDR; + +static AIFCHDR AifcHdr; + +/* Prototypes */ +static int Format_samplerate(unsigned long rate, unsigned char the_rate[10]); +static int InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes ); +static int ExitSound(int audio, unsigned long nBytesDone); +static unsigned long GetHdrSize(void); +static unsigned long InSizeToOutSize(unsigned long BytesToDo); + +struct soundfile aifcsound = +{ + InitSound, /* init header method */ + ExitSound, /* exit header method */ + GetHdrSize, /* report header size method */ + /* get sound samples out */ + (int (*)(int audio, unsigned char *buf, unsigned long BytesToDo))write, + InSizeToOutSize, /* compressed? output file size */ + 1 /* needs big endian samples */ +}; + +/* format the sample rate into an + bigendian 10-byte IEEE-754 floating point number + */ +static int Format_samplerate(unsigned long rate, unsigned char the_rate[10]) +{ + int i; + + /* normalize rate */ + for (i = 0; (rate & 0xffff) != 0; rate <<= 1, i++) { + if ((rate & 0x8000) != 0) { + break; + } + } + + /* set exponent and sign */ + the_rate[1] = 14-i; + the_rate[0] = 0x40; /* LSB = sign */ + + /* 16-bit part of mantisse for sample rate */ + the_rate[3] = rate & 0xff; + the_rate[2] = (rate >> 8) & 0xff; + + /* initialize lower digits of mantisse */ + the_rate[4] = the_rate[5] = the_rate[6] = + the_rate[7] = the_rate[8] = the_rate[9] = 0; + + return 0; +} + + +static int InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes) +{ + UINT4 tmp; + + fillbytes(&AifcHdr, sizeof(AifcHdr), '\0'); + AifcHdr.formChk.ckid = cpu_to_be32(FOURCC_FORM); + AifcHdr.formChk.dwSize= cpu_to_be32(expected_bytes + + offset_of(AIFCHDR,blocksize)+sizeof(AifcHdr.blocksize) + - offsetof(AIFCHDR,commChk)); + AifcHdr.formType = cpu_to_be32(FOURCC_AIFC); + + AifcHdr.fverChk.ckid = cpu_to_be32(FOURCC_FVER); + AifcHdr.fverChk.dwSize= cpu_to_be32(offsetof(AIFCHDR,commChk) + - offsetof(AIFCHDR,timestamp)); + + AifcHdr.compressionType[0]='N'; + AifcHdr.compressionType[1]='O'; + AifcHdr.compressionType[2]='N'; + AifcHdr.compressionType[3]='E'; + AifcHdr.compressionNameLen = sizeof(NO_COMPRESSION)-1; + strcpy(AifcHdr.compressionName, NO_COMPRESSION); + AifcHdr.timestamp = cpu_to_be32(UINT4_C(0xA2805140)); /* AIFC Version 1 */ + + AifcHdr.commChk.ckid = cpu_to_be32(FOURCC_COMM); + AifcHdr.commChk.dwSize= cpu_to_be32(offset_of(AIFCHDR,ssndChkid) + - offset_of(AIFCHDR,numChannels)); + + AifcHdr.numChannels[1]= channels; + + tmp = cpu_to_be32(expected_bytes/(channels * (nBitsPerSample/8))); + AifcHdr.numSampleFrames[0] = tmp >> 24; + AifcHdr.numSampleFrames[1] = tmp >> 16; + AifcHdr.numSampleFrames[2] = tmp >> 8; + AifcHdr.numSampleFrames[3] = tmp >> 0; + AifcHdr.samplesize[1] = nBitsPerSample; + Format_samplerate(rate, AifcHdr.sample_rate); + + memcpy(AifcHdr.ssndChkid, "SSND", 4); + tmp = cpu_to_be32(expected_bytes + offset_of(AIFCHDR,blocksize)+sizeof(AifcHdr.blocksize) - offset_of(AIFCHDR, offset)); + AifcHdr.dwSize[0] = tmp >> 24; + AifcHdr.dwSize[1] = tmp >> 16; + AifcHdr.dwSize[2] = tmp >> 8; + AifcHdr.dwSize[3] = tmp >> 0; + + return write (audio, &AifcHdr, sizeof (AifcHdr)); +} + +static int ExitSound(int audio, unsigned long nBytesDone) +{ + UINT4 tmp; + + AifcHdr.formChk.dwSize= cpu_to_be32(nBytesDone + sizeof(AIFCHDR) + - offsetof(AIFCHDR,commChk)); + tmp = cpu_to_be32(nBytesDone/( + AifcHdr.numChannels[1] * AifcHdr.samplesize[1]/ULONG_C(8))); + AifcHdr.numSampleFrames[0] = tmp >> 24; + AifcHdr.numSampleFrames[1] = tmp >> 16; + AifcHdr.numSampleFrames[2] = tmp >> 8; + AifcHdr.numSampleFrames[3] = tmp >> 0; + + /* If an odd number of bytes has been written, + extend the chunk with one dummy byte. This is a requirement for AIFC. */ + if ((nBytesDone & 1) && (lseek(audio, 1L, SEEK_CUR) == -1)) { + return 0; + } + + /* goto beginning */ + if (lseek(audio, 0L, SEEK_SET) == -1) { + return 0; + } + return write (audio, &AifcHdr, sizeof (AifcHdr)); +} + +static unsigned long GetHdrSize() +{ + return sizeof( AifcHdr ); +} + +static unsigned long InSizeToOutSize(unsigned long BytesToDo) +{ + return BytesToDo; +} + diff --git a/icedax/aifc.h b/icedax/aifc.h new file mode 100644 index 0000000..f9a2c9d --- /dev/null +++ b/icedax/aifc.h @@ -0,0 +1,14 @@ +/* + * 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. + * + */ + +/* @(#)aifc.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +extern struct soundfile aifcsound; diff --git a/icedax/aiff.c b/icedax/aiff.c new file mode 100644 index 0000000..cd1d98d --- /dev/null +++ b/icedax/aiff.c @@ -0,0 +1,188 @@ +/* + * 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. + * + */ + +/* @(#)aiff.c 1.5 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Heiko Eissfeldt + * + * + * --------------------------------------------------------------------- + * definitions for aiff pcm output + * --------------------------------------------------------------------- + */ + +#include "config.h" +#include <stdio.h> +#include <unixstd.h> +#include <strdefs.h> +#include <standard.h> +#include <schily.h> +#include "mytype.h" +#include "byteorder.h" +#include "sndfile.h" + +typedef UINT4 FOURCC; /* a four character code */ +typedef struct CHUNKHDR { + FOURCC ckid; /* chunk ID */ + UINT4 dwSize; /* chunk size */ +} CHUNKHDR; + +#define mmioFOURCC(ch0, ch1, ch2, ch3) \ + ((UINT4)(unsigned char)(ch3) | ((UINT4)(unsigned char)(ch2) << 8) | \ + ((UINT4)(unsigned char)(ch1) << 16) | ((UINT4)(unsigned char)(ch0) << 24)) + +#define FOURCC_FORM mmioFOURCC ('F', 'O', 'R', 'M') +#define FOURCC_AIFF mmioFOURCC ('A', 'I', 'F', 'F') +#define FOURCC_COMM mmioFOURCC ('C', 'O', 'M', 'M') +#define FOURCC_SSND mmioFOURCC ('S', 'S', 'N', 'D') + +typedef struct AIFFHDR { + CHUNKHDR formChk; + FOURCC formType; + + CHUNKHDR commChk; /* Common chunk */ + /* from now on, alignment prevents us from using the original types :-(( */ + unsigned char numChannels[2]; /* Audio Channels */ + unsigned char numSampleFrames[4]; /* # of samples */ + unsigned char samplesize[2]; /* bits per sample */ + unsigned char sample_rate[10]; /* sample rate in extended float */ + + unsigned char ssndChkid[4]; /* Sound data chunk */ + unsigned char dwSize[4]; /* size of chunk */ + unsigned char offset[4]; /* start of 1st sample */ + unsigned char blocksize[4]; /* aligned sound data block size */ +} AIFFHDR; + +static AIFFHDR AiffHdr; + +/* Prototypes */ +static int Format_samplerate(unsigned long rate, unsigned char the_rate[10]); +static int InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes); +static int ExitSound(int audio, unsigned long nBytesDone); +static unsigned long GetHdrSize(void); +static unsigned long InSizeToOutSize(unsigned long BytesToDo); + + +/* format the sample rate into an + bigendian 10-byte IEEE-754 floating point number + */ +static int Format_samplerate(unsigned long rate, unsigned char the_rate[10]) +{ + int i; + + /* normalize rate */ + for (i = 0; (rate & 0xffff) != 0; rate <<= 1, i++) { + if ((rate & 0x8000) != 0) { + break; + } + } + + /* set exponent and sign */ + the_rate[1] = 14-i; + the_rate[0] = 0x40; /* LSB = sign */ + + /* 16-bit part of mantisse for sample rate */ + the_rate[3] = rate & 0xff; + the_rate[2] = (rate >> 8) & 0xff; + + /* initialize lower digits of mantisse */ + the_rate[4] = the_rate[5] = the_rate[6] = + the_rate[7] = the_rate[8] = the_rate[9] = 0; + + return 0; +} + +static int InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes) +{ + UINT4 tmp; + + fillbytes(&AiffHdr, sizeof(AiffHdr), '\0'); + AiffHdr.formChk.ckid = cpu_to_be32(FOURCC_FORM); + AiffHdr.formChk.dwSize= cpu_to_be32(expected_bytes + + offset_of(AIFFHDR,blocksize)+sizeof(AiffHdr.blocksize) + - offsetof(AIFFHDR,formType)); + AiffHdr.formType = cpu_to_be32(FOURCC_AIFF); + + AiffHdr.commChk.ckid = cpu_to_be32(FOURCC_COMM); + AiffHdr.commChk.dwSize= cpu_to_be32(offset_of(AIFFHDR,ssndChkid) + - offset_of(AIFFHDR,numChannels)); + + AiffHdr.numChannels[1]= channels; + tmp = cpu_to_be32(expected_bytes/(channels * (nBitsPerSample/8))); + AiffHdr.numSampleFrames[0] = tmp >> 24; + AiffHdr.numSampleFrames[1] = tmp >> 16; + AiffHdr.numSampleFrames[2] = tmp >> 8; + AiffHdr.numSampleFrames[3] = tmp >> 0; + AiffHdr.samplesize[1] = nBitsPerSample; + Format_samplerate(rate, AiffHdr.sample_rate); + + memcpy(AiffHdr.ssndChkid, "SSND", 4); + tmp = cpu_to_be32(expected_bytes + offset_of(AIFFHDR,blocksize)+sizeof(AiffHdr.blocksize) - offset_of(AIFFHDR, offset)); + AiffHdr.dwSize[0] = tmp >> 24; + AiffHdr.dwSize[1] = tmp >> 16; + AiffHdr.dwSize[2] = tmp >> 8; + AiffHdr.dwSize[3] = tmp >> 0; + + return write (audio, &AiffHdr, sizeof (AiffHdr)); +} + +static int ExitSound(int audio, unsigned long nBytesDone ) +{ + UINT4 tmp; + + AiffHdr.formChk.dwSize= cpu_to_be32(nBytesDone + sizeof(AIFFHDR) + - offsetof(AIFFHDR,commChk)); + tmp = cpu_to_be32(nBytesDone/( + AiffHdr.numChannels[1] * AiffHdr.samplesize[1]/ULONG_C(8))); + AiffHdr.numSampleFrames[0] = tmp >> 24; + AiffHdr.numSampleFrames[1] = tmp >> 16; + AiffHdr.numSampleFrames[2] = tmp >> 8; + AiffHdr.numSampleFrames[3] = tmp >> 0; + + /* If an odd number of bytes has been written, + extend the chunk with one dummy byte. This is a requirement for AIFF. */ + if ((nBytesDone & 1) && (lseek(audio, 1L, SEEK_CUR) == -1)) { + return 0; + } + + /* goto beginning */ + if (lseek(audio, 0L, SEEK_SET) == -1) { + return 0; + } + return write (audio, &AiffHdr, sizeof (AiffHdr)); +} + +static unsigned long GetHdrSize() +{ + return sizeof( AiffHdr ); +} + +static unsigned long InSizeToOutSize(unsigned long BytesToDo) +{ + return BytesToDo; +} + +struct soundfile aiffsound = +{ + InitSound, /* init header method */ + ExitSound, /* exit header method */ + GetHdrSize, /* report header size method */ + /* get sound samples out */ + (int (*)(int audio, unsigned char *buf, unsigned long BytesToDo))write, + InSizeToOutSize, /* compressed? output file size */ + 1 /* needs big endian samples */ +}; + + diff --git a/icedax/aiff.h b/icedax/aiff.h new file mode 100644 index 0000000..cc04849 --- /dev/null +++ b/icedax/aiff.h @@ -0,0 +1,14 @@ +/* + * 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. + * + */ + +/* @(#)aiff.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +extern struct soundfile aiffsound; diff --git a/icedax/base64.c b/icedax/base64.c new file mode 100644 index 0000000..69b75cb --- /dev/null +++ b/icedax/base64.c @@ -0,0 +1,121 @@ +/* + * 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. + * + */ + +/* @(#)base64.c 1.4 02/04/06 Copyright 1998,1999 Heiko Eissfeldt */ +/*____________________________________________________________________________ +// +// CD Index - The Internet CD Index +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id: base64.c,v 1.1.1.3 1999/04/29 00:57:14 marc Exp $ +//____________________________________________________________________________ +*/ +/* + * Program: RFC-822 routines (originally from SMTP) + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 27 July 1988 + * Last Edited: 10 September 1998 + * + * Sponsorship: The original version of this work was developed in the + * Symbolic Systems Resources Group of the Knowledge Systems + * Laboratory at Stanford University in 1987-88, and was funded + * by the Biomedical Research Technology Program of the National + * Institutes of Health under grant number RR-00785. + * + * Original version Copyright 1988 by The Leland Stanford Junior University + * Copyright 1998 by the University of Washington + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that both the + * above copyright notices and this permission notice appear in supporting + * documentation, and that the name of the University of Washington or The + * Leland Stanford Junior University not be used in advertising or publicity + * pertaining to distribution of the software without specific, written prior + * permission. This software is made available "as is", and + * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY + * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF + * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "config.h" +#include <stdio.h> +#include <stdxlib.h> + +#include "base64.h" + +/* NOTE: This is not true RFC822 anymore. The use of the characters +// '/', '+', and '=' is no bueno when the ID will be used as part of a URL. +// '_', '.', and '-' have been used instead +*/ + +/* Convert binary contents to BASE64 + * Accepts: source + * length of source + * pointer to return destination length + * Returns: destination as BASE64 + */ + +unsigned char *rfc822_binary(char *src, unsigned long srcl, unsigned long *len) +{ + unsigned char *ret,*d; + unsigned char *s = (unsigned char *) src; + char *v = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; + unsigned long i = ((srcl + 2) / 3) * 4; + *len = i += 2 * ((i / 60) + 1); + d = ret = malloc ((size_t) ++i); + for (i = 0; srcl; s += 3) { /* process tuplets */ + *d++ = v[s[0] >> 2]; /* byte 1: high 6 bits (1) */ + /* byte 2: low 2 bits (1), high 4 bits (2) */ + *d++ = v[((s[0] << 4) + (--srcl ? (s[1] >> 4) : 0)) & 0x3f]; + /* byte 3: low 4 bits (2), high 2 bits (3) */ + *d++ = srcl ? v[((s[1] << 2) + (--srcl ? (s[2] >> 6) : 0)) & 0x3f] : '-'; + /* byte 4: low 6 bits (3) */ + *d++ = srcl ? v[s[2] & 0x3f] : '-'; + if (srcl) srcl--; /* count third character if processed */ + if ((++i) == 15) { /* output 60 characters? */ + i = 0; /* restart line break count, insert CRLF */ + *d++ = '\015'; *d++ = '\012'; + } + } + *d = '\0'; /* tie off string */ + + return ret; /* return the resulting string */ +} diff --git a/icedax/base64.h b/icedax/base64.h new file mode 100644 index 0000000..5b8522c --- /dev/null +++ b/icedax/base64.h @@ -0,0 +1,83 @@ +/* + * 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. + * + */ + +/* @(#)base64.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +/*____________________________________________________________________________ +// +// CD Index - The Internet CD Index +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id: base64.h,v 1.1.1.2 1999/04/29 00:53:34 marc Exp $ +//____________________________________________________________________________ +*/ +/* + * Program: RFC-822 routines (originally from SMTP) + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 27 July 1988 + * Last Edited: 10 September 1998 + * + * Sponsorship: The original version of this work was developed in the + * Symbolic Systems Resources Group of the Knowledge Systems + * Laboratory at Stanford University in 1987-88, and was funded + * by the Biomedical Research Technology Program of the National + * Institutes of Health under grant number RR-00785. + * + * Original version Copyright 1988 by The Leland Stanford Junior University + * Copyright 1998 by the University of Washington + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that both the + * above copyright notices and this permission notice appear in supporting + * documentation, and that the name of the University of Washington or The + * Leland Stanford Junior University not be used in advertising or publicity + * pertaining to distribution of the software without specific, written prior + * permission. This software is made available "as is", and + * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY + * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF + * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef BASE64_H +#define BASE64_H + +unsigned char *rfc822_binary(char *src,unsigned long srcl,unsigned long *len); + +#endif diff --git a/icedax/byteorder.h b/icedax/byteorder.h new file mode 100644 index 0000000..0fa8eb6 --- /dev/null +++ b/icedax/byteorder.h @@ -0,0 +1,67 @@ +/* + * 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. + * + */ + +/* @(#)byteorder.h 1.3 03/07/20 Copyright 1998,1999 Heiko Eissfeldt */ +#ifndef MYBYTE_ORDER +#define MYBYTE_ORDER 1 +/* supply the byte order macros */ + +#if defined (WORDS_BIGENDIAN) +# define MY_BIG_ENDIAN 1 +# define MY_LITTLE_ENDIAN 0 +#else +# define MY_BIG_ENDIAN 0 +# define MY_LITTLE_ENDIAN 1 +#endif + +# undef cpu_to_le32 +# undef cpu_to_le16 +# undef cpu_to_be32 +# undef cpu_to_be16 +# undef le32_to_cpu +# undef le16_to_cpu +# undef be32_to_cpu +# undef be16_to_cpu + +# define revert4bytes(x) \ + ((unsigned long int)((((unsigned long int)(x) & ULONG_C(0x000000ff)) << 24) | \ + (((unsigned long int)(x) & ULONG_C(0x0000ff00)) << 8) | \ + (((unsigned long int)(x) & ULONG_C(0x00ff0000)) >> 8) | \ + (((unsigned long int)(x) & ULONG_C(0xff000000)) >> 24))) +# define revert2bytes(x) \ + ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ + (((unsigned short int)(x) & 0xff00) >> 8))) + +#if MY_BIG_ENDIAN == 1 +# define cpu_to_le32(x) revert4bytes(x) +# define cpu_to_le16(x) revert2bytes(x) +# define le32_to_cpu(x) cpu_to_le32(x) +# define le16_to_cpu(x) cpu_to_le16(x) +# define cpu_to_be32(x) (x) +# define cpu_to_be16(x) (x) +# define be32_to_cpu(x) (x) +# define be16_to_cpu(x) (x) +#else +# define cpu_to_be32(x) revert4bytes(x) +# define cpu_to_be16(x) revert2bytes(x) +# define be32_to_cpu(x) cpu_to_be32(x) +# define be16_to_cpu(x) cpu_to_be16(x) +# define cpu_to_le32(x) (x) +# define cpu_to_le16(x) (x) +# define le32_to_cpu(x) (x) +# define le16_to_cpu(x) (x) +#endif + +#define GET_LE_UINT_FROM_CHARP(p) ((unsigned int)((*(p+3))<<24)|((*(p+2))<<16)|((*(p+1))<<8)|(*(p))) +#define GET_BE_UINT_FROM_CHARP(p) ((unsigned int)((*(p))<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3))) + +#endif /* ifndef MYBYTE_ORDER */ diff --git a/icedax/cd_extra.c b/icedax/cd_extra.c new file mode 100644 index 0000000..fa17c5b --- /dev/null +++ b/icedax/cd_extra.c @@ -0,0 +1,417 @@ +/* + * 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. + * + */ + +/* @(#)cd_extra.c 1.8 02/11/21 Copyright 2000-2001 Heiko Eissfeldt */ + +/* This is an include file! */ +/**************** CD-Extra special treatment *********************************/ + +#include <ctype.h> + +static unsigned long Read_CD_Extra_File(unsigned char *Extra_buf, unsigned long sector); + +static unsigned long +Read_CD_Extra_File(unsigned char *Extra_buf, unsigned long sector) +{ + unsigned long mysec; + + /* read PVD */ + ReadCdRomData(get_scsi_p(), Extra_buf, sector+16, 1); + + /* check ISO signature */ + if (memcmp(Extra_buf, "\001CD001", 6) != 0) return 0; + + /* get path_table */ + mysec = Extra_buf[148] << 24; + mysec |= Extra_buf[149] << 16; + mysec |= Extra_buf[150] << 8; + mysec |= Extra_buf[151]; + + if (mysec <= sector) return 0; + + /* read path table */ + ReadCdRomData(get_scsi_p(), Extra_buf, mysec, 1); + + /* find cdplus subdirectory */ + { unsigned char * p = Extra_buf; + while (p+8 < Extra_buf + CD_FRAMESIZE_RAW) { + int namelength; + + namelength = p[0] | (p[1] << 8); + if (namelength == 6 && + !memcmp(p+8, "CDPLUS", 6)) break; + + p += 8 + namelength + (namelength & 1); + } + if (p+8 >= Extra_buf + CD_FRAMESIZE_RAW) return 0; + + /* get extent */ + mysec = p[2] << 24; + mysec |= p[3] << 16; + mysec |= p[4] << 8; + mysec |= p[5]; + } + + if (mysec <= sector) return 0; + + ReadCdRomData(get_scsi_p(), Extra_buf, mysec, 1); + + /* find file info.cdp */ + { unsigned char * p = Extra_buf; + while (p+33 < Extra_buf + CD_FRAMESIZE_RAW) { + int namelength; + + namelength = p[32]; + if (namelength == 10 && + !memcmp(p+33, "INFO.CDP;1", 10)) break; + + p += p[0]; + } + if (p+33 >= Extra_buf + CD_FRAMESIZE_RAW) return 0; + + /* get extent */ + mysec = p[6] << 24; + mysec |= p[7] << 16; + mysec |= p[8] << 8; + mysec |= p[9]; + } + + if (mysec <= sector) return 0; + + /* read file info.cdp */ + ReadCdRomData(get_scsi_p(), Extra_buf, mysec, 1); + + return mysec - sector; +} + +static unsigned char Extra_buffer[CD_FRAMESIZE_RAW]; + +/* + * Read the file cdplus/info.cdp from the cd extra disc. + * This file has to reside at exactly 75 sectors after start of + * the last session (according to Blue Book). + * Of course, there are a lot dubious cd extras, which don't care :-((( + * As an alternative method, we try reading through the iso9660 file system... + */ +static int Read_CD_Extra_Info(unsigned long sector); +static int Read_CD_Extra_Info(unsigned long sector) +{ + unsigned i; + static int offsets[] = { + 75 /* this is what blue book says */ + }; + + for (i = 0; i < sizeof(offsets)/sizeof(int); i++) { +#ifdef DEBUG_XTRA + fprintf(stderr, "debug: Read_CD_Extra_Info at sector %lu\n", sector+offsets[i]); +#endif + ReadCdRomData(get_scsi_p(), Extra_buffer, sector+offsets[i], 1); + + /* If we are unlucky the drive cannot handle XA sectors by default. + We try to compensate by ignoring the first eight bytes. + Of course then we lack the last 8 bytes of the sector... + */ + + if (Extra_buffer[0] == 0) + memmove(Extra_buffer, Extra_buffer +8, CD_FRAMESIZE - 8); + + /* check for cd extra */ + if (Extra_buffer[0] == 'C' && Extra_buffer[1] == 'D') + return sector+offsets[i]; + + /* + * CD is not conforming to BlueBook! + * Read the file through ISO9660 file system. + */ + { + unsigned long offset = Read_CD_Extra_File(Extra_buffer, sector); + + if (offset == 0) return 0; + + if (Extra_buffer[0] == 0) + memmove(Extra_buffer, Extra_buffer +8, CD_FRAMESIZE - 8); + + /* check for cd extra */ + if (Extra_buffer[0] == 'C' && Extra_buffer[1] == 'D') + return sector+offset; + } + } + + return 0; +} + +static void Read_Subinfo(unsigned pos, unsigned length); +static void Read_Subinfo(unsigned pos, unsigned length) +{ + unsigned num_infos, num; + unsigned char *Subp, *orgSubp; + unsigned this_track = 0xff; +#ifdef DEBUG_XTRA + unsigned char *up; + unsigned char *sp; + unsigned u; + unsigned short s; +#endif + + length += 8; + length = (length + CD_FRAMESIZE_RAW-1) / CD_FRAMESIZE_RAW; + length *= CD_FRAMESIZE_RAW; + orgSubp = Subp = malloc(length); + + if (Subp == NULL) { + fprintf(stderr, "Read_Subinfo no memory(%d)\n",length); + goto errorout; + } + + ReadCdRomData(get_scsi_p(), Subp, pos, 1); + + num_infos = Subp[45]+(Subp[44] << 8); +#ifdef DEBUG_XTRA + fprintf(stderr, "subinfo version %c%c.%c%c, %d info packets\n", + Subp[8], + Subp[9], + Subp[10], + Subp[11], + num_infos); +#endif + length -= 46; + Subp += 46; + for (num = 0; num < num_infos && length > 0; num++) { + unsigned id = *Subp; + unsigned len = *(Subp +1); +#define INFOPACKETTYPES 0x44 +#ifdef INFOPACKETSTRINGS + static const char *infopacketID[INFOPACKETTYPES] = { "0", + "track identifier", + "album title", + "universal product code", + "international standard book number", + "copyright", + "track title", + "notes", + "main interpret", + "secondary interpret", + "composer", + "original composer", + "creation date", + "release date", + "publisher", + "0f", + "isrc audio track", + "isrc lyrics", + "isrc pictures", + "isrc MIDI data", + "14", "15", "16", "17", "18", "19", + "copyright state SUB_INFO", + "copyright state intro lyrics", + "copyright state lyrics", + "copyright state MIDI data", + "1e", "1f", + "intro lyrics", + "pointer to lyrics text file and length", + "22", "23", "24", "25", "26", "27", "28", + "29", "2a", "2b", "2c", "2d", "2e", "2f", + "still picture descriptor", + "31", + "32", "33", "34", "35", "36", "37", "38", + "39", "3a", "3b", "3c", "3d", "3e", "3f", + "MIDI file descriptor", + "genre code", + "tempo", + "key" + }; +#endif + + if (id >= INFOPACKETTYPES) { + fprintf(stderr, "Off=%4d, ind=%2d/%2d, unknown Id=%2u, len=%2u ", + /* this pointer difference is assumed to be small enough for an int. */ + (int)(Subp - orgSubp) + , num, num_infos, id, len); + Subp += 2 + 1; + length -= 2 + 1; + break; + } +#ifdef DEBUG_XTRA + fprintf(stderr, "info packet %d\n", id); +#endif + + switch (id) { + case 1: /* track nummer or 0 */ + this_track = 10 * (*(Subp + 2) - '0') + (*(Subp + 3) - '0'); + break; + + case 0x02: /* album title */ + if (global.disctitle == NULL) { + global.disctitle = malloc(len + 1); + if (global.disctitle != NULL) { + memcpy(global.disctitle, Subp + 2, len); + global.disctitle[len] = '\0'; + } + } + break; + case 0x03: /* media catalog number */ + if (Get_MCN()[0] == '\0' && Subp[2] != '\0' && len >= 13) { + Set_MCN( Subp + 2); + } + break; + case 0x06: /* track title */ + if (this_track > 0 && this_track < 100 + && global.tracktitle[this_track] == NULL) { + global.tracktitle[this_track] = malloc(len + 1); + if (global.tracktitle[this_track] != NULL) { + memcpy(global.tracktitle[this_track], Subp + 2, len); + global.tracktitle[this_track][len] = '\0'; + } + } + break; + case 0x05: /* copyright message */ + if (global.copyright_message == NULL) { + global.copyright_message = malloc(len + 1); + if (global.copyright_message != NULL) { + memcpy(global.copyright_message, Subp + 2, len); + global.copyright_message[len] = '\0'; + } + } + break; + case 0x08: /* creator */ + if (global.creator == NULL) { + global.creator = malloc(len + 1); + if (global.creator != NULL) { + memcpy(global.creator, Subp + 2, len); + global.creator[len] = '\0'; + } + } + break; + case 0x10: /* isrc */ + if (this_track > 0 && this_track < 100 + && Get_ISRC(this_track)[0] == '\0' && Subp[2] != '\0' + && len >= 15) { + Set_ISRC(this_track, Subp + 2); + } + break; +#if 0 + case 0x04: + case 0x07: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: +#ifdef INFOPACKETSTRINGS + fprintf(stderr, "%s: %*.*s\n",infopacketID[id], (int) len, (int) len, (Subp +2)); +#endif + break; +#ifdef DEBUG_XTRA + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: +#ifdef INFOPACKETSTRINGS + fprintf(stderr, "%s %scopyrighted\n", infopacketID[id], *(Subp + 2) == 0 ? "not " : ""); +#endif + break; + + case 0x21: + fprintf(stderr, "lyrics file beginning at sector %u", + (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 2)); + if (len == 8) + fprintf(stderr, ", having length: %u\n", + (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 6)); + else + fputs("\n", stderr); + break; + + case 0x30: + sp = Subp + 2; + while (sp < Subp + 2 + len) { + /*while (len >= 10) {*/ + s = be16_to_cpu((*(sp)) | (*(sp) << 8)); + fprintf(stderr, "%04x, ", s); + sp += 2; + up = sp; + switch (s) { + case 0: + break; + case 4: + break; + case 5: + break; + case 6: + break; + } + u = GET_BE_UINT_FROM_CHARP(up); + fprintf(stderr, "%04lx, ", (long) u); + up += 4; + u = GET_BE_UINT_FROM_CHARP(up); + fprintf(stderr, "%04lx, ", (long) u); + up += 4; + sp += 8; + } + fputs("\n", stderr); + break; + + case 0x40: + fprintf(stderr, "MIDI file beginning at sector %u", + (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 2)); + if (len == 8) + fprintf(stderr, ", having length: %u\n", + (unsigned) GET_BE_UINT_FROM_CHARP(Subp + 6)); + else + fputs("\n", stderr); + break; + +#ifdef INFOPACKETSTRINGS + case 0x42: + fprintf(stderr, "%s: %d beats per minute\n",infopacketID[id], *(Subp + 2)); + break; + case 0x41: + if (len == 8) + fprintf(stderr, "%s: %x, %x, %x, %x, %x, %x, %x, %x\n", + infopacketID[id], + *(Subp + 2), + *(Subp + 3), + *(Subp + 4), + *(Subp + 5), + *(Subp + 6), + *(Subp + 7), + *(Subp + 8), + *(Subp + 9) + ); + else + fprintf(stderr, "%s:\n",infopacketID[id]); + break; + case 0x43: + fprintf(stderr, "%s: %x\n",infopacketID[id], *(Subp + 2)); + break; + default: + fprintf(stderr, "%s: %*.*s\n",infopacketID[id], (int) len, (int) len, (Subp +2)); +#endif +#endif +#endif + } + + if (len & 1) len++; + Subp += 2 + len; + length -= 2 + len; + } + +/* cleanup */ + + free(orgSubp); + +errorout: + return; + +} + diff --git a/icedax/cd_text.c b/icedax/cd_text.c new file mode 100644 index 0000000..6e93b13 --- /dev/null +++ b/icedax/cd_text.c @@ -0,0 +1,421 @@ +/* + * 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. + * + */ + +/* @(#)cd_text.c 1.5 03/12/31 Copyright 2000-2001 Heiko Eissfeldt */ + +/* This is an include file! */ +/**************** CD-Text special treatment **********************************/ + +typedef struct { + unsigned char headerfield[4]; + unsigned char textdatafield[12]; + unsigned char crcfield[2]; +} cdtextpackdata; + +static unsigned short crctab[1<<8] = { /* as calculated by initcrctab() */ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, + }; + +#define SUBSIZE 18*8 + +static unsigned short updcrc(unsigned int p_crc, register unsigned char *cp, + register size_t cnt); + +static unsigned short updcrc(unsigned int p_crc, register unsigned char *cp, + register size_t cnt) +{ + register unsigned short crc = (unsigned short)p_crc; + while( cnt-- ) { + crc = (crc<<8) ^ crctab[(crc>>(16-8)) ^ (*cp++)]; + } + return( crc ); +} + +static unsigned short calcCRC(unsigned char *buf, unsigned bsize); + +static unsigned short calcCRC(unsigned char *buf, unsigned bsize) +{ + return updcrc( 0x0, (unsigned char *)buf, bsize ); +} + +static unsigned char fliptab[8] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80, +}; + +static int flip_error_corr(unsigned char *b, int crc); + +static int flip_error_corr(unsigned char *b, int crc) +{ + if (crc != 0) { + int i; + for (i = 0; i < SUBSIZE; i++) { + char c; + + c = fliptab[i%8]; + b[i / 8] ^= c; + if ((crc = calcCRC(b, SUBSIZE/8)) == 0) { + return crc; + } + b[i / 8] ^= c; + } + } + return crc & 0xffff; +} + + +static int cdtext_crc_ok(cdtextpackdata *c); + +static int cdtext_crc_ok(cdtextpackdata *c) +{ + int crc; + int retval; + + c->crcfield[0] ^= 0xff; + c->crcfield[1] ^= 0xff; + crc = calcCRC(((unsigned char *)c), 18); + retval = (0 == flip_error_corr((unsigned char *)c, crc)); + c->crcfield[0] ^= 0xff; + c->crcfield[1] ^= 0xff; +#if 0 + fprintf(stderr, "%02x %02x %02x %02x ", + c->headerfield[0], c->headerfield[1], c->headerfield[2], c->headerfield[3]); + fprintf(stderr, +"%c %c %c %c %c %c %c %c %c %c %c %c " + , c->textdatafield[0] + , c->textdatafield[1] + , c->textdatafield[2] + , c->textdatafield[3] + , c->textdatafield[4] + , c->textdatafield[5] + , c->textdatafield[6] + , c->textdatafield[7] + , c->textdatafield[8] + , c->textdatafield[9] + , c->textdatafield[10] + , c->textdatafield[11] + ); + fprintf(stderr, "%02x %02x \n" + , c->crcfield[0] + , c->crcfield[1] + ); +#endif + return retval; +} + +#define DETAILED 0 + +#if DETAILED +static void dump_binary(cdtextpackdata *c); + +static void dump_binary(cdtextpackdata *c) +{ + fprintf(stderr, ": header fields %02x %02x %02x ", + c->headerfield[1], c->headerfield[2], c->headerfield[3]); + fprintf(stderr, +"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x" + , c->textdatafield[0] + , c->textdatafield[1] + , c->textdatafield[2] + , c->textdatafield[3] + , c->textdatafield[4] + , c->textdatafield[5] + , c->textdatafield[6] + , c->textdatafield[7] + , c->textdatafield[8] + , c->textdatafield[9] + , c->textdatafield[10] + , c->textdatafield[11] + ); +} +#endif + +static int process_header(cdtextpackdata *c, unsigned tracknr, int dbcc, + unsigned char *line); + +static int process_header(cdtextpackdata *c, unsigned tracknr, int dbcc, + unsigned char *line) +{ + switch ((int)c->headerfield[0]) { + + case 0x80: /* Title of album or track */ +#if DETAILED + fprintf (stderr, "Title"); +#endif + if (tracknr > 0 && tracknr < 100 + && global.tracktitle[tracknr] == NULL) { + unsigned len; + + len = strlen((char *)line); + + if (len > 0) + global.tracktitle[tracknr] = malloc(len + 1); + if (global.tracktitle[tracknr] != NULL) { + memcpy(global.tracktitle[tracknr], line, len); + global.tracktitle[tracknr][len] = '\0'; + } + } else + if (tracknr == 0 + && global.disctitle == NULL) { + unsigned len; + + len = strlen((char *)line); + + if (len > 0) + global.disctitle = malloc(len + 1); + if (global.disctitle != NULL) { + memcpy(global.disctitle, line, len); + global.disctitle[len] = '\0'; + } + } + break; + case 0x81: /* Name(s) of the performer(s) */ +#if DETAILED + fprintf(stderr, "Performer(s)"); +#endif + if (tracknr > 0 && tracknr < 100 + && global.trackcreator[tracknr] == NULL) { + unsigned len; + + len = strlen((char *)line); + + if (len > 0) + global.trackcreator[tracknr] = malloc(len + 1); + + if (global.trackcreator[tracknr] != NULL) { + memcpy(global.trackcreator[tracknr], line, len); + global.trackcreator[tracknr][len] = '\0'; + } + } else + if (tracknr == 0 + && global.creator == NULL) { + unsigned len; + + len = strlen((char *)line); + + if (len > 0) + global.creator = malloc(len + 1); + if (global.creator != NULL) { + memcpy(global.creator, line, len); + global.creator[len] = '\0'; + } + } + break; + case 0x82: /* Name(s) of the songwriter(s) */ +#if DETAILED + fprintf(stderr, "Songwriter(s)"); +#endif + break; + case 0x83: /* Name(s) of the composer(s) */ +#if DETAILED + fprintf(stderr, "Composer(s)"); +#endif + break; + case 0x84: /* Name(s) of the arranger(s) */ +#if DETAILED + fprintf(stderr, "Arranger(s)"); +#endif + break; + case 0x85: /* Message from content provider and/or artist */ +#if DETAILED + fprintf(stderr, "Message"); +#endif + break; + case 0x86: /* Disc Identification and information */ +#if DETAILED + fprintf(stderr, "Disc identification"); +#endif + if (tracknr == 0 && line[0] != '\0') { + fprintf(stderr, "Disc identification: %s\n", line); + } + break; + case 0x87: /* Genre Identification and information */ +#if DETAILED + fprintf(stderr, "Genre identification"); +#endif + break; + case 0x8e: /* UPC/EAN code or ISRC code */ +#if DETAILED + fprintf(stderr, "UPC or ISRC"); +#endif + if (tracknr > 0 && tracknr < 100) { + Set_ISRC(tracknr, line); + } else + if (tracknr == 0 && line[0] != '\0') { + Set_MCN(line); + } + break; + case 0x88: /* Table of Content information */ +#if DETAILED + fprintf(stderr, "Table of Content identification"); + dump_binary(c); +#endif + return 0; + case 0x89: /* Second Table of Content information */ +#if DETAILED + fprintf(stderr, "Second Table of Content identification"); + dump_binary(c); +#endif + return 0; + case 0x8f: /* Size information of the block */ +#if DETAILED == 0 + break; +#else + switch (tracknr) { + case 0: + fprintf(stderr, "first track is %d, last track is %d\n", + c->textdatafield[1], + c->textdatafield[2]); + if (c->textdatafield[3] & 0x80) { + fprintf(stderr, "Program Area CD Text information available\n"); + if (c->textdatafield[3] & 0x40) { + fprintf(stderr, "Program Area copy protection available\n"); + } + } + if (c->textdatafield[3] & 0x07) { + fprintf(stderr, "message information is %scopyrighted\n", + c->textdatafield[3] & 0x04 ? "": "not "); + fprintf(stderr, "Names of performer/songwriter/composer/arranger(s) are %scopyrighted\n", + c->textdatafield[3] & 0x02 ? "": "not "); + fprintf(stderr, "album and track names are %scopyrighted\n", + c->textdatafield[3] & 0x01 ? "": "not "); + } + fprintf(stderr, "%d packs with album/track names\n", c->textdatafield[4]); + fprintf(stderr, "%d packs with performer names\n", c->textdatafield[5]); + fprintf(stderr, "%d packs with songwriter names\n", c->textdatafield[6]); + fprintf(stderr, "%d packs with composer names\n", c->textdatafield[7]); + fprintf(stderr, "%d packs with arranger names\n", c->textdatafield[8]); + fprintf(stderr, "%d packs with artist or content provider messages\n", c->textdatafield[9]); + fprintf(stderr, "%d packs with disc identification information\n", c->textdatafield[10]); + fprintf(stderr, "%d packs with genre identification/information\n", c->textdatafield[11]); + break; + case 1: + fprintf(stderr, "%d packs with table of contents information\n", c->textdatafield[0]); + fprintf(stderr, "%d packs with second table of contents information\n", c->textdatafield[1]); + fprintf(stderr, "%d packs with reserved information\n", c->textdatafield[2]); + fprintf(stderr, "%d packs with reserved information\n", c->textdatafield[3]); + fprintf(stderr, "%d packs with reserved information\n", c->textdatafield[4]); + fprintf(stderr, "%d packs with closed information\n", c->textdatafield[5]); + fprintf(stderr, "%d packs with UPC/EAN ISRC information\n", c->textdatafield[6]); + fprintf(stderr, "%d packs with size information\n", c->textdatafield[7]); + fprintf(stderr, "last sequence numbers for blocks 1-8: %d %d %d %d " + ,c->textdatafield[8] + ,c->textdatafield[9] + ,c->textdatafield[10] + ,c->textdatafield[11] + ); + break; + case 2: + fprintf(stderr, "%d %d %d %d\n" + ,c->textdatafield[0] + ,c->textdatafield[1] + ,c->textdatafield[2] + ,c->textdatafield[3] + ); + fprintf(stderr, "Language codes for blocks 1-8: %d %d %d %d %d %d %d %d\n" + ,c->textdatafield[4] + ,c->textdatafield[5] + ,c->textdatafield[6] + ,c->textdatafield[7] + ,c->textdatafield[8] + ,c->textdatafield[9] + ,c->textdatafield[10] + ,c->textdatafield[11] + ); + break; + } + fprintf(stderr, "Blocksize"); + dump_binary(c); + return 0; +#if !defined DEBUG_CDTEXT + default: +#else + } +#endif + fprintf(stderr, ": header fields %02x %02x %02x ", + c->headerfield[1], c->headerfield[2], c->headerfield[3]); +#endif /* DETAILED */ + +#if !defined DEBUG_CDTEXT + } +#if DETAILED + if (tracknr == 0) { + fprintf(stderr, " for album : ->"); + } else { + fprintf(stderr, " for track %2u: ->", tracknr); + } + fputs ((char *) line, stderr); + fputs ("<-", stderr); +#endif + + if (dbcc != 0) { +#else + { +#endif + /* EMPTY */ +#if DETAILED + fprintf(stderr, +" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x" + , c->textdatafield[0] + , c->textdatafield[1] + , c->textdatafield[2] + , c->textdatafield[3] + , c->textdatafield[4] + , c->textdatafield[5] + , c->textdatafield[6] + , c->textdatafield[7] + , c->textdatafield[8] + , c->textdatafield[9] + , c->textdatafield[10] + , c->textdatafield[11] + ); +#endif + } + return 0; +} diff --git a/icedax/cdda2mp3 b/icedax/cdda2mp3 new file mode 120000 index 0000000..4a59876 --- /dev/null +++ b/icedax/cdda2mp3 @@ -0,0 +1 @@ +cdda2ogg
\ No newline at end of file diff --git a/icedax/cdda2mp3.new b/icedax/cdda2mp3.new new file mode 100644 index 0000000..ee51829 --- /dev/null +++ b/icedax/cdda2mp3.new @@ -0,0 +1,60 @@ +#!/bin/sh +# Demo script for processing all audio tracks with a mp3 encoder +# This variant creates temporary wav files. There is another +# variant of this script (cdda2mp3), which uses a named pipe +# instead. This variant needs more disk space than the other one. +# +# usage: cdda2mp3.new <name prefix for all mp3 files> +# +# list_audio_tracks is a (symbolic) link to cdda2wav +# and used to generate a list of audio track numbers and start +# sectors, which in turn are used in a loop to spawn cdda2wav +# and the post processor on a track by track basis. + +# +# feedback needed!!!!!!!!!!!!!!!!! +# + +# specify the audio track listing program and its options +LAT=list_audio_tracks +LAT_OPTIONS= + +# specify the sampling program and its options +# do not specify the track option here! +CDDA2WAV=cdda2wav +CDDA2WAV_OPTS='-Owav -H -P0 -q' + +# for normal use, comment out the next line with a # +#DEBUG='-d1' + +# specify the post processing program and its options +MP_CODER=l3enc +#MP_OPTIONS='2>/dev/null 1>/dev/null' +MP_OPTIONS='-br 128000' +#MP_OPTIONS='-hq' + +WAVFILE=$$".wav" + +FILEPREFIX=${1:-audiotrack} + +# clean up wav file on exit, abort, ... +trap "rm -rf $WAVFILE" 0 2 3 4 6 7 8 10 11 12 13 15 + +# feed track numbers and start sectors into loop +$LAT $LAT_OPTIONS | while read TRACK STARTSECTOR; +do + $CDDA2WAV $CDDA2WAV_OPTS -t$TRACK $DEBUG $WAVFILE +# echo n | $MP_CODER $WAVFILE $FILEPREFIX$TRACK.mp3 $MP_OPTIONS + $MP_CODER $WAVFILE $FILEPREFIX$TRACK.mp3 $MP_OPTIONS + + # check result code + RES=$? + if [ $RES = 0 ] ; then + echo File $FILEPREFIX$TRACK.mp3 finished successfully. + rm $WAVFILE + else + echo File $FILEPREFIX$TRACK.mp3 failed \(result $RES\). Aborted. >&2 + break + fi +done + diff --git a/icedax/cdda2ogg b/icedax/cdda2ogg new file mode 100755 index 0000000..0838384 --- /dev/null +++ b/icedax/cdda2ogg @@ -0,0 +1,82 @@ +#! /bin/sh +# Script for processing all audio tracks with an ogg or mp3 decoder +# based on a news article by Tom Kludy +# This variant uses named pipes in order to save space. +# usage: cdda2ogg <name prefix for all ogg/mp3 files> + +# specify the sampling program and its options +# do not specify the track option here! +CDDA2WAV=${CDDA2WAV:-icedax} +CDDA2WAV_OPTS=${CDDA2WAV_OPTS:-'-H -P0 -q'} + +# for normal use, comment out the next line +#DEBUG='-d1' + +# the post processor is fed through a pipe to avoid space waste +# specify the post processing program and its options +case $0 in + *ogg|*OGG|*Ogg) + # ensure the right suffix for suffixes later + suffix=ogg + missmsg="Encoder not found. Install one first! (eg. vorbis-tools)" + MP_CODER=${MP_CODER:-oggenc} + outopt="-o" + ;; + *mp3|*MP3|*mpeg3|*MPEG3|*Mp3) + suffix=mp3 + missmsg="Encoder not found. Install one first! (eg. lame)" + MP_CODER=${MP_CODER:-lame} + outopt="" + ;; + *) + echo Unknown target file type: $suffix. Valid names for this application are: cdda2mp3, cdda2ogg. + exit 1 + ;; +esac + +MP_OPTIONS=${MP_OPTIONS:-''} + +MP_CODER=$(which $MP_CODER 2>/dev/null) +if [ ! -x "$MP_CODER" ] ; then + echo $missmsg + exit 1 +fi + +CDDA_DEVICE=${CDDA_DEVICE:-/dev/cdrw} +export CDDA_DEVICE + +FILEPREFIX=${1:-audiotrack} + +if [ -e /etc/default/cdda2$suffix ]; then + . /etc/default/cdda2$suffix +fi + +if [ -z "$LIST" ] ; then + echo Looking for available tracks... + # could use list_audio_tracks instead but that would need an extra filter as + # well, and this way we do not depend on that symlink + LIST="$( $CDDA2WAV -J -vtoc -H 2>&1 | sed -e 's/^[^\ ].*//; s/\.([^)]*)/ /g;s/,//g;')" + if [ -z "$LIST" ] ; then + echo "ERROR: No valid audio tracks detected" + exit 1 + fi +fi + +echo Fetching `echo $LIST | wc -w` tracks from $CDDA_DEVICE, encoding with $MP_CODER. +echo Cancel with Ctrl-C, watch out for error messages. + +for TRACK in $LIST ; do + NAME="`printf "%02d" $TRACK`-$FILEPREFIX.$suffix" + echo + echo "############ Starting with Track Nr. $TRACK -> $NAME ############" + $CDDA2WAV $CDDA2WAV_OPTS -t$TRACK $DEBUG - | \ + $MP_CODER $MP_OPTIONS - $outopt "$NAME" + + # check result code + RES=$? + if [ $RES != 0 ] ; then + echo File $NAME failed \(result $RES\). Aborted. >&2 + break + fi +done + diff --git a/icedax/cdda2ogg.1 b/icedax/cdda2ogg.1 new file mode 100644 index 0000000..63ac041 --- /dev/null +++ b/icedax/cdda2ogg.1 @@ -0,0 +1,114 @@ +'\" +.TH "cdda2ogg" "1" +.SH "NAME" +cdda2ogg, cdda2mp3 \(em extract audio CD audio tracks and encode them +.SH "SYNOPSIS" +.PP +.B cdda2ogg +.PP +.B cdda2mp3 +.SH "DESCRIPTION" +.PP +.B cdda2ogg is a simple script that uses the +.B icedax <fileprefix> +command to extract all audio tracks with the +.B icedax <fileprefix> +command and encode them using the +.B ogg123 +respective +.I <censored> +MP3 +encoder. The scripts are not intended to be full-featured music archiving +programs, but only for quick storing of few audio data. +It does not use databases like CDDB or have any extra features. You may look +at +.B icedax +if you need them. +.PP +.B ogg123 +is provided by the +.B vorbis-tools +which needs to be installed separately. +See +.B www.ogg.org +for more information. + +.SH "CONFIGURATION" +.PP +.B cdda2ogg +and +.B cdda2mp3 +have predefined values for reading and labeling of the target files. +You can overwrite them with following environment variables: + +.IP "CDDA_DEVICE" 10 +Source device specification to get the data from. + +.IP "LIST" 10 +List of track numbers to be read, separated by spaces. + +.IP "CDDA2WAV" 10 +Defines the command to run the cdda2wav program + +.IP "CDDA2WAV_OPTS" 10 +Miscellaneous options passed to +.IR $CDDA2WAV . + +.IP "MP_CODER" 10 +The encoder program. + +.IP "MP_OPTIONS" 10 +Additional options passed to +.IR $MP_CODER . + +.IP "FILEPREFIX" 10 +The base part of the filename of resulting audio files. This can also be specified as the first argument to the script. + +.PP +See cdda2ogg (cdda2mp3) script file to get the default values +.PP +System administrator can also set default values by creating of a shell +include file, defining the variables for the POSIX shell, and storing them as +/etc/default/cdda2ogg (resp. cdda2mp3). +.SH "EXAMPLES" +.PP +.B CDDA_DEVICE=/dev/cdrom1 cdda2ogg +.br +just stores every track in this device in audiotrackNUMBER.ogg +.PP +.PP +.B LIST="1 5 7" cdda2ogg PartsOfBestOfFoo +.br +stores the selected tracks from the default cdrom device as 01-PartsOfBestOfFoo.ogg, 05-PartsOfBestOfFoo.ogg, 07-PartsOfBestOfFoo.ogg. + +.SH "SEE ALSO" +.BR icedax (1) +.SH "AUTHOR" +.PP +This manpage describes the program implementation of +.B +cdda2ogg +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program distributed by the cdrtools project. However, the cdrtools developers are not involved in the development of this spinoff and therefore shall not be made responsible for any problem caused by it. Do not try to get support for this program by contacting the original authors. +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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. +.PP +This manual page was written by Eduard Bloch +(blade@debian.org) for the +.B "Debian GNU/Linux system (but may be used by others). Permission is granted +to copy, distribute and/or modify this document under the terms of the GNU +General Public License, Version 2 as published by the Free Software Foundation. diff --git a/icedax/cdda2ogg.mk1 b/icedax/cdda2ogg.mk1 new file mode 100644 index 0000000..575933b --- /dev/null +++ b/icedax/cdda2ogg.mk1 @@ -0,0 +1,18 @@ +#ident @(#)Makefile.man 1.1 00/03/21 +########################################################################### +# Sample makefile for installing manual pages +########################################################################### +SRCROOT= .. +RULESDIR= RULES +include $(SRCROOT)/$(RULESDIR)/rules.top +########################################################################### + +MANDIR= man +TARGETMAN= cdda2ogg +MANSECT= $(MANSECT_CMD) +MANSUFFIX= $(MANSUFF_CMD) +MANFILE= cdda2ogg.1 + +########################################################################### +include $(SRCROOT)/$(RULESDIR)/rules.man +########################################################################### diff --git a/icedax/config.h b/icedax/config.h new file mode 100644 index 0000000..d08162e --- /dev/null +++ b/icedax/config.h @@ -0,0 +1,63 @@ +/* + * 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. + * + */ + +/* @(#)config.h 1.7 03/10/06 Copyright 1998-2003 Heiko Eissfeldt */ +/* + * a central configuration file + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> + +#if __STDC__-0 != 0 || (defined PROTOTYPES && defined STDC_HEADERS) +#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) +#define CONCAT(a,b) a/**/b +#endif + +#include "lconfig.h" + +/* temporary until a autoconf check is present */ +#ifdef __BEOS__ +#define HAVE_AREAS 1 +#endif + +#if defined HAVE_FORK && (defined (HAVE_SMMAP) || defined(HAVE_USGSHM) || defined(HAVE_DOSALLOCSHAREDMEM) || defined (HAVE_AREAS)) +#define HAVE_FORK_AND_SHAREDMEM +#undef FIFO +#define FIFO +#else +#undef FIFO +#endif +#if !defined HAVE_MEMMOVE +#define memmove(dst, src, size) movebytes((src), (dst), (size)) +#endif diff --git a/icedax/configure b/icedax/configure new file mode 100755 index 0000000..bbbb61f --- /dev/null +++ b/icedax/configure @@ -0,0 +1,1390 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -cc=* | --cc=* ) + CC="$ac_optarg" ; echo using $CC as compiler ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=cdda2wav.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:556: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + + +CDRTOOLS_VERSION=`sed -n -f ../../version.sed <../../../cdrecord/cdrecord.c` + + + +case "$host_os" in + solaris*|sunos*) +echo $ac_n "checking for sched_get_priority_max in -lposix4""... $ac_c" 1>&6 +echo "configure:584: checking for sched_get_priority_max in -lposix4" >&5 +ac_lib_var=`echo posix4'_'sched_get_priority_max | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lposix4 $LIBS" +cat > conftest.$ac_ext <<EOF +#line 592 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char sched_get_priority_max(); + +int main() { +sched_get_priority_max() +; return 0; } +EOF +if { (eval echo configure:603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo posix4 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lposix4 $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +;; +esac +echo $ac_n "checking for _oss_ioctl in -lossaudio""... $ac_c" 1>&6 +echo "configure:633: checking for _oss_ioctl in -lossaudio" >&5 +ac_lib_var=`echo ossaudio'_'_oss_ioctl | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lossaudio $LIBS" +cat > conftest.$ac_ext <<EOF +#line 641 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char _oss_ioctl(); + +int main() { +_oss_ioctl() +; return 0; } +EOF +if { (eval echo configure:652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo ossaudio | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lossaudio $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + +EXTRALIBS="$LIBS" + + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:685: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 700 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 717 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:723: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 734 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +for ac_hdr in sys/cdio.h sys/cdrio.h sundev/srreg.h sys/audioio.h sun/audioio.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:768: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 773 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in soundcard.h sys/soundcard.h linux/soundcard.h machine/soundcard.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:808: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 813 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:818: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in sys/asoundlib.h windows.h mmsystem.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:848: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 853 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:858: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in os2.h os2me.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:888: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 893 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +case "${ac_cv_header_sys_cdio_h}""${ac_cv_header_sundev_srreg_h}" in + *yes*) +HAVE_SUN_IOCTL=1 +;; + *) +HAVE_SUN_IOCTL= +;; +esac + + +case "${ac_cv_header_sys_audioio_h}""${ac_cv_header_sun_audioio_h}" in + *yes*) +HAVE_SUNSOUND=1 +;; + *) +HAVE_SUNSOUND= +;; +esac + + +case "${ac_cv_header_machine_soundcard_h}""${ac_cv_header_sys_soundcard_h}""${ac_cv_header_linux_soundcard_h}" in + *yes*) +HAVE_OSS=1 +;; + *) +HAVE_OSS= +;; +esac + + + + +case "${ac_cv_header_windows_h}""${ac_cv_header_mmsystem_h}" in + *yesyes*) +HAVE_WINSOUND=1 +;; + *) +HAVE_WINSOUND= +;; +esac + + +case "${ac_cv_header_os2_h}""${ac_cv_header_os2me_h}" in + *yesyes*) +HAVE_OS2SOUND=1 +;; + *) +HAVE_OS2SOUND= +;; +esac + + +for ac_func in strtoul +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:980: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 985 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "local.cnf lconfig.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@CDRTOOLS_VERSION@%$CDRTOOLS_VERSION%g +s%@EXTRALIBS@%$EXTRALIBS%g +s%@CPP@%$CPP%g +s%@HAVE_SUN_IOCTL@%$HAVE_SUN_IOCTL%g +s%@HAVE_SUNSOUND@%$HAVE_SUNSOUND%g +s%@HAVE_OSS@%$HAVE_OSS%g +s%@HAVE_SYS_ASOUNDLIB_H@%$HAVE_SYS_ASOUNDLIB_H%g +s%@HAVE_WINSOUND@%$HAVE_WINSOUND%g +s%@HAVE_OS2SOUND@%$HAVE_OS2SOUND%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"local.cnf"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="lconfig.h" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/icedax/configure.in b/icedax/configure.in new file mode 100644 index 0000000..5229ef9 --- /dev/null +++ b/icedax/configure.in @@ -0,0 +1,88 @@ +dnl @(#)configure.in 1.8 06/02/15 Copyright 1998-2003 Heiko Eißfeldt +dnl Process this file with autoconf to produce a configure script. +AC_INIT(cdda2wav.c) +AC_CONFIG_HEADER(lconfig.h) + +dnl get canonical host +AC_CANONICAL_HOST + +dnl extract cdrtools version from the cdrecord.c file +CDRTOOLS_VERSION=`sed -n -f ../../version.sed <../../../cdrecord/cdrecord.c` +AC_SUBST(CDRTOOLS_VERSION) + +dnl set object extension needed for AC_CHECK_HEADERS by autoconf 2.57 +dnl _AC_COMPILER_OBJEXT + +dnl check for posix4 library on Solaris or SunOS +case "$host_os" in + solaris*|sunos*) +AC_CHECK_LIB(posix4, sched_get_priority_max) +;; +esac +AC_CHECK_LIB(ossaudio, _oss_ioctl) + +EXTRALIBS="$LIBS" + +AC_SUBST(EXTRALIBS) + +dnl check header files +AC_CHECK_HEADERS(sys/cdio.h sys/cdrio.h sundev/srreg.h sys/audioio.h sun/audioio.h) +AC_CHECK_HEADERS(soundcard.h sys/soundcard.h linux/soundcard.h machine/soundcard.h) +AC_CHECK_HEADERS(sys/asoundlib.h windows.h mmsystem.h) +AC_CHECK_HEADERS(os2.h os2me.h) + +case "${ac_cv_header_sys_cdio_h}""${ac_cv_header_sundev_srreg_h}" in + *yes*) +HAVE_SUN_IOCTL=1 +;; + *) +HAVE_SUN_IOCTL= +;; +esac +AC_SUBST(HAVE_SUN_IOCTL) + +case "${ac_cv_header_sys_audioio_h}""${ac_cv_header_sun_audioio_h}" in + *yes*) +HAVE_SUNSOUND=1 +;; + *) +HAVE_SUNSOUND= +;; +esac +AC_SUBST(HAVE_SUNSOUND) + +case "${ac_cv_header_machine_soundcard_h}""${ac_cv_header_sys_soundcard_h}""${ac_cv_header_linux_soundcard_h}" in + *yes*) +HAVE_OSS=1 +;; + *) +HAVE_OSS= +;; +esac +AC_SUBST(HAVE_OSS) + +AC_SUBST(HAVE_SYS_ASOUNDLIB_H) + +case "${ac_cv_header_windows_h}""${ac_cv_header_mmsystem_h}" in + *yesyes*) +HAVE_WINSOUND=1 +;; + *) +HAVE_WINSOUND= +;; +esac +AC_SUBST(HAVE_WINSOUND) + +case "${ac_cv_header_os2_h}""${ac_cv_header_os2me_h}" in + *yesyes*) +HAVE_OS2SOUND=1 +;; + *) +HAVE_OS2SOUND= +;; +esac +AC_SUBST(HAVE_OS2SOUND) + +dnl Checks for library functions. +AC_CHECK_FUNCS(strtoul) +AC_OUTPUT(local.cnf) diff --git a/icedax/exitcodes.h b/icedax/exitcodes.h new file mode 100644 index 0000000..b75b171 --- /dev/null +++ b/icedax/exitcodes.h @@ -0,0 +1,37 @@ +/* + * 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. + * + */ + +/* @(#)exitcodes.h 1.1 02/11/21 Copyright 2002 Heiko Eissfeldt */ +/* header file for system wide exit codes. */ +#ifndef exitcodes_h +#define exitcodes_h + +#define NO_ERROR 0 +#define SYNTAX_ERROR 1 +#define PERM_ERROR 2 +#define READ_ERROR 3 +#define WRITE_ERROR 4 +#define SOUND_ERROR 5 +#define STAT_ERROR 6 +#define SIGPIPE_ERROR 7 +#define SETSIG_ERROR 8 +#define SHMMEM_ERROR 9 +#define NOMEM_ERROR 10 +#define MEDIA_ERROR 11 +#define DEVICEOPEN_ERROR 12 +#define RACE_ERROR 13 +#define DEVICE_ERROR 14 +#define INTERNAL_ERROR 15 +#define SEMAPHORE_ERROR 16 +#define SETUPSCSI_ERROR 17 +#define PIPE_ERROR 18 +#endif diff --git a/icedax/global.h b/icedax/global.h new file mode 100644 index 0000000..fc80c78 --- /dev/null +++ b/icedax/global.h @@ -0,0 +1,133 @@ +/* + * 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. + * + */ + +/* @(#)global.h 1.11 04/07/29 Copyright 1998-2004 Heiko Eissfeldt */ +/* Global Variables */ + +#ifdef MD5_SIGNATURES +#include "md5.h" +#endif +#ifdef USE_PARANOIA +#include "cdda_paranoia.h" +#endif + +typedef struct index_list +{ + struct index_list *next; + int frameoffset; +} +index_list; + +typedef struct global +{ + + char *dev_name; /* device name */ + char *aux_name; /* device name */ + char fname_base[200]; + + int have_forked; + int parent_died; + int audio; + struct soundfile *audio_out; + int cooked_fd; + int no_file; + int no_infofile; + int no_cddbfile; + int quiet; + int verbose; + int scsi_silent; + int scsi_verbose; + int scanbus; + int scandevs; + int multiname; + int sh_bits; + int Remainder; + int SkippedSamples; + int OutSampleSize; + int need_big_endian; + int need_hostorder; + int channels; + unsigned long iloop; + unsigned long nSamplesDoneInTrack; + unsigned overlap; + int useroverlap; + unsigned nsectors; + unsigned buffers; + unsigned shmsize; + long pagesize; + int in_lendian; + int outputendianess; + int findminmax; + int maxamp[2]; + int minamp[2]; + unsigned speed; + int userspeed; + int ismono; + int findmono; + int swapchannels; + int deemphasize; + int gui; + long playback_rate; + int target; /* SCSI Id to be used */ + int lun; /* SCSI Lun to be used */ + UINT4 cddb_id; + int cddbp; + char * cddbp_server; + char * cddbp_port; + unsigned cddb_revision; + int cddb_year; + char cddb_genre[60]; + int illleadout_cd; + int reads_illleadout; + unsigned char *cdindex_id; + unsigned char *creator; + unsigned char *copyright_message; + unsigned char *disctitle; + unsigned char *tracktitle[100]; + unsigned char *trackcreator[100]; + index_list *trackindexlist[100]; + + int paranoia_selected; +#ifdef USE_PARANOIA + cdrom_paranoia *cdp; + + struct paranoia_parms_t + { + Ucbit disable_paranoia:1; + Ucbit disable_extra_paranoia:1; + Ucbit disable_scratch_detect:1; + Ucbit disable_scratch_repair:1; + int retries; + int overlap; + int mindynoverlap; + int maxdynoverlap; + } + paranoia_parms; +#endif + + unsigned md5blocksize; +#ifdef MD5_SIGNATURES + int md5count; + MD5_CTX context; + unsigned char MD5_result[16]; +#endif + +#ifdef ECHO_TO_SOUNDCARD + int soundcard_fd; +#endif + int echo; + + int just_the_toc; +} +global_t; + +extern global_t global; diff --git a/icedax/icedax.1 b/icedax/icedax.1 new file mode 100644 index 0000000..d9daddb --- /dev/null +++ b/icedax/icedax.1 @@ -0,0 +1,1025 @@ +'\" t +.\" @(#)icedax.1 1.14 02/12/09 Copyright 1998,1999,2000 Heiko Eissfeldt +.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 +.if t .ds m \\(*m +.if n .ds m micro +.TH ICEDAX 1 +.SH NAME +icedax \- a sampling utility that dumps CD audio data into wav sound +files +.SH SYNOPSIS +.B icedax +.RB [ -c +.IR chans ] +.RB [ -s ] +.RB [ -m ] +.RB [ -b +.IR bits ] +.RB [ -r +.IR rate ] +.RB [ -a +.IR divider ] +.RB [ -t +.IR track [ +endtrack ]] +.RB [ -i +.IR index ] +.RB [ -o +.IR offset ] +.RB [ -d +.IR duration ] +.RB [ -x ] +.RB [ -q ] +.RB [ -w ] +.RB [ -v +.IR optlist ] +.RB [ -V ] +.RB [ -Q ] +.RB [ -J ] +.RB [ -L +.IR cddbmode ] +.RB [ -R ] +.RB [ -P +.IR sectors ] +.RB [ -F ] +.RB [ -G ] +.RB [ -T ] +.RB [ -e ] +.RB [ -p +.IR percentage ] +.RB [ -n +.IR sectors ] +.RB [ -l +.IR buffers ] +.RB [ -N ] +.RB [ -J ] +.RB [ -H ] +.RB [ -g ] +.RB [ -B ] +.RB [ -D +.IR device ] +.RB [ -A +.IR auxdevice ] +.RB [ -I +.IR interface ] +.RB [ -O +.IR audiotype ] +.RB [ -C +.IR input-endianess ] +.RB [ -E +.IR output-endianess ] +.RB [ -M +.IR count ] +.RB [ -S +.IR speed ] +.RB [ -paranoia ] +.RB [ cddbp-server=servername ] +.RB [ cddbp-port=portnumber ] +.RI [ filename(s) +or +.IR directories ] +.SH DESCRIPTION +.B icedax +stands for InCrEdible Digital Audio eXtractor. It can retrieve audio tracks +.RB ( CDDA ) +from CDROM drives +that are +capable of reading audio data digitally to the host +(see README for a list of drives). + +.SH OPTIONS +.TP +.BI dev= device +.TP +.BI \-D " device +.TP +.BI \-device " device +uses +.B device +as the source for CDDA reading. For example +.B /dev/cdrom +or +.B Bus,ID,Lun. +The device specification can also have influence on the selection of the driver interface (eg. on Linux). +See the +.B \-I +option for details. +.sp +The setting of the environment variable +.B CDDA_DEVICE +is overridden by this option. +.TP +.BI \-A " auxdevice +.TP +.BI \-auxdevice " auxdevice +uses +.B auxdevice +as CDROM drive for ioctl usage. +.TP +.BI \-I " interface +.TP +.BI \-interface " interface +specifies the interface for CDROM access: +.B generic_scsi +or (on Linux, and FreeBSD systems) +.BR cooked_ioctl . +.sp +Using the +.B cooked_ioctl +is not recommended as this makes +.B icedax +mainly depend on the audio extraction quality of the operating system +which is usually extremely bad. +.TP +.BI \-c " channels --channels" +uses +.B 1 +for mono, or +.B 2 +for stereo recording, +or +.B s +for stereo recording with both channels swapped. +.TP +.B \-s " --stereo" +sets to stereo recording. +.TP +.B \-m " --mono" +sets to mono recording. +.TP +.B \-x " --max" +sets maximum (CD) quality. +.TP +.BI \-b " bits --bits-per-sample" +sets bits per sample per channel: +.BR 8 , +.B 12 +or +.BR 16 . +.TP +.BI \-r " rate --rate" +sets rate in samples per second. Possible values are listed with the +.B \-R +option. +.TP +.BI \-a " divider --divider" +sets rate to 44100Hz / divider. Possible values are listed with the +.B \-R +option. +.TP +.B \-R " --dump-rates" +shows a list of all sample rates and their dividers. +.TP +.B \-P " sectors --set-overlap" +sets the initial number of overlap +.I sectors +for jitter correction. +.TP +.BI \-n " sectors --sectors-per-request" +reads +.I sectors +per request. +.TP +.BI \-l " buffers --buffers-in-ring" +uses a ring buffer with +.I buffers +total. +.TP +.BI \-t " track+endtrack --track" +selects the start track and optionally the end track. +.TP +.BI \-i " index --index" +selects the start index. +.TP +.BI \-o " offset --offset" +starts +.I offset +sectors behind start track (one sector equivalents 1/75 seconds). +.TP +.B \-O " audiotype --output-format" +can be +.I wav +(for wav files) or +.I aiff +(for apple/sgi aiff files) or +.I aifc +(for apple/sgi aifc files) or +.I au +or +.I sun +(for sun .au PCM files) or +.I cdr +or +.I raw +(for headerless files to be used for cd writers). +.TP +.BI \-C " endianess --cdrom-endianess" +sets endianess of the input samples to 'little', 'big' or 'guess' to override defaults. +.TP +.BI \-E " endianess --output-endianess" +sets endianess of the output samples to 'little' or 'big' to override defaults. +.TP +.BI \-d " duration --duration" +sets recording time in seconds or frames. +Frames (sectors) are indicated by a 'f' suffix (like 75f for 75 sectors). +.B 0 +sets the time for whole track. +.TP +.B \-B " --bulk --alltracks" +copies each track into a separate file. +.TP +.B \-w " --wait" +waits for signal, then start recording. +.TP +.B \-F " --find-extremes" +finds extreme amplitudes in samples. +.TP +.B \-G " --find-mono" +finds if input samples are in mono. +.TP +.B \-T " --deemphasize" +undo the effect of pre-emphasis in the input samples. +.TP +.B \-e " --echo" +copies audio data to sound device e.g. +.BR /dev/dsp . +.TP +.B \-p " percentage --set-pitch" +changes pitch of audio data copied to sound device. +.TP +.B \-v " itemlist --verbose-level" +prints verbose information about the CD. +.B Level +is a list of comma separated suboptions. Each suboption controls the type of information to be reported. +.TS H +allbox; +c cw(1i) +r l. +Suboption Description +disable no information is given, warnings appear however +all all information is given +toc show table of contents +summary show a summary of the recording parameters +indices determine and display index offsets +catalog retrieve and display the media catalog number MCN +trackid T{ +.na +retrieve and display all International Standard Recording Codes ISRC +T} +sectors T{ +.na +show the table of contents in start sector notation +T} +titles T{ +.na +show the table of contents with track titles (when available) +T} +.TE +.TP +.B \-N " --no-write" +does not write to a file, it just reads (for debugging purposes). +.TP +.B \-J " --info-only" +does not write to a file, it just gives information about the disc. +.TP +.B \-L " cddb mode --cddb" +does a cddbp album- and track title lookup based on the cddb id. +The parameter cddb mode defines how multiple entries shall be handled. +.TS H +allbox; +c cw(4i) +r l. +Parameter Description +0 T{ +.na +interactive mode. The user selects the entry to use. +T} +1 T{ +.na +first fit mode. The first entry is taken unconditionally. +T} +.TE +.TP +.B " cddbp-server=servername" +sets the server to be contacted for title lookups. +.TP +.B " cddbp-port=portnumber" +sets the port number to be used for title lookups. +.TP +.B \-H " --no-infofile" +does not write an info file and a cddb file. +.TP +.B \-g " --gui" +formats the output to be better parsable by gui frontends. +.TP +.B \-M " count --md5" +enables calculation of MD-5 checksum for 'count' bytes from a beginning of a +track. +.TP +.B \-S " speed --speed" +sets the cdrom device to one of the selectable speeds for reading. +.TP +.B \-q " --quiet" +quiet operation, no screen output. +.TP +.B \-V " --verbose-SCSI" +enable SCSI command logging to the console. This is mainly used for debugging. +.TP +.B \-Q " --silent-SCSI" +suppress SCSI command error reports to the console. This is mainly used for guis. +.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 +CD/DVD-Recorder on a system. +The numbers printed out as labels are computed by: +.B "bus * 100 + target +.TP +.B \-\-devices +Like \-scanbus but works in a more native way, respecting the device name +specification on the current operating system. See +.B wodim(1) +for details. +.TP +.B \-paranoia +use the paranoia library instead of icedax's routines for reading. +.TP +.B \-h " --help" +display version of icedax on standard output. +.TP +Defaults depend on the +.B Makefile +and +.B environment variable +settings (currently +.B CDDA_DEVICE +). +.SH "ENVIRONMENT VARIABLES" +.B CDDA_DEVICE +is used to set the device name. The device naming is compatible with the one +used by the wodim tool. +.TP +.B CDDBP_SERVER +is used for cddbp title lookups when supplied. +.TP +.B CDDBP_PORT +is used for cddbp title lookups when supplied. +.TP +.B RSH +If the +.B RSH +environment variable 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 icedax +to create a pipe to the +.B rsh(1) +program and disallows +.B icedax +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 variable 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 "RETURN VALUES" +.B icedax +uses the following exit codes to indicate various degrees of success: +.TS H +allbox; +c cw(1i) +r l. +Exitcode Description +0 no errors encountered, successful operation. +1 usage or syntax error. icedax got inconsistent arguments. +2 permission (un)set errors. permission changes failed. +3 read errors on the cdrom/burner device encountered. +4 T{ +.na +write errors while writing one of the output files encountered. +T} +5 errors with soundcard handling (initialization/write). +6 T{ +.na +errors with stat() system call on the read device (cooked ioctl). +T} +7 pipe communication errors encountered (in forked mode). +8 signal handler installation errors encountered. +9 allocation of shared memory failed (in forked mode). +10 dynamic heap memory allocation failed. +11 errors on the audio cd medium encountered. +12 device open error in ioctl handling detected. +13 race condition in ioctl interface handling detected. +14 error in ioctl() operation encountered. +15 internal error encountered. Please report back!!! +16 T{ +.na +error in semaphore operation encountered (install / request). +T} +17 could not get the scsi transfer buffer. +18 T{ +.na +could not create pipes for process communication (in forked mode). +T} +.TE +.SH "DISCUSSION" +.B icedax +is able to read parts of an +.B audio +CD or +.B multimedia +CDROM (containing audio parts) directly digitally. These parts can be +written to a file, a pipe, or to a sound device. +.PP +.B icedax +stands for +.B CDDA +to +.B WAV +(where +.B CDDA +stands for compact disc digital audio and +.B WAV +is a sound sample format introduced by MS Windows). It +allows copying +.B CDDA +audio data from the CDROM drive into a file in +.B WAV +or other formats. +.PP +The latest versions try to get higher real-time scheduling priorities to ensure +smooth (uninterrupted) operation. These priorities are available for super users +and are higher than those of 'normal' processes. Thus delays are minimized. +.PP +If your CDROM is on device +.B DEV +and it is loaded with an audio CD, you may simply invoke +.B icedax dev=DEV +and it will create the sound file +.B audio.wav +recording the whole track beginning with track 1 in stereo at 16 bit at 44100 +Hz sample rate, if your file system has enough space free. Otherwise +recording time will be limited. For details see files +.B README +and +.B README.INSTALL +. +.SH "HINTS ON OPTIONS" +.IP "Options" +Most of the options are used to control the format of the WAV file. In +the following text all of them are described. +.IP "Select Device" +.BI \-D " device" +selects the CDROM drive device to be used. +The specifier given should correspond to the selected interface (see below). +.B CHANGE! +For the cooked_ioctl interface this is the cdrom device descriptor as before. +.B The SCSI devices used with the generic SCSI interface however are now +.B addressed with their SCSI-Bus, SCSI-Id, and SCSI-Lun instead of the generic +.B SCSI device descriptor!!! +One example for a SCSI CDROM drive on bus 0 with SCSI ID 3 and lun 0 is -D0,3,0. +.IP "Select Auxiliary device" +.BI \-A " auxdevice" +is necessary for CD-Extra handling. For Non-SCSI-CDROM drives this is the +same device as given by -D (see above). For SCSI-CDROM drives it is the +CDROM drive (SCSI) device (i.e. +.B /dev/sr0 +) corresponding to the SCSI device (i.e. +.B 0,3,0 +). It has to match the device used for sampling. +.IP "Select Interface" +.BI \-I " interface" +selects the CDROM drive interface. For SCSI drives use generic_scsi +(cooked_ioctl may not yet be available for all devices): +.B generic_scsi +and +.BR cooked_ioctl . +The first uses the generic SCSI interface, the latter uses the ioctl of +the CDROM driver. The latter variant works only when the kernel driver supports +.B CDDA +reading. This entry has to match the selected CDROM device (see above). +.IP "Enable echo to soundcard" +.B \-e +copies audio data to the sound card while recording, so you hear it nearly +simultaneously. The soundcard gets the same data that is recorded. This +is time critical, so it works best with the +.B \-q +option. To use +.B icedax +as a pseudo CD player without recording in a file you could use +.B "icedax \-q \-e \-t2 \-d0 \-N" +to play the whole second track. This feature reduces the recording speed +to at most onefold speed. You cannot make better recordings than your sound card +can play (since the same data is used). +.IP "Change pitch of echoed audio" +.B "\-p percentage" +changes the pitch of all audio echoed to a sound card. Only the copy +to the soundcard is affected, the recorded audio samples in a file +remain the same. +Normal pitch, which is the default, is given by 100%. +Lower percentages correspond to lower pitches, i.e. +-p 50 transposes the audio output one octave lower. +See also the script +.B pitchplay +as an example. This option was contributed by Raul Sobon. +.IP "Select mono or stereo recording" +.B \-m +or +.B "\-c 1" +selects mono recording (both stereo channels are mixed), +.B \-s +or +.B "\-c 2" +or +.B "\-c s" +selects stereo recording. Parameter s +will swap both sound channels. +.IP "Select maximum quality" +.B \-x +will set stereo, 16 bits per sample at 44.1 KHz (full CD quality). Note +that other format options given later can change this setting. +.IP "Select sample quality" +.B "\-b 8" +specifies 8 bit (1 Byte) for each sample in each channel; +.B "\-b 12" +specifies 12 bit (2 Byte) for each sample in each channel; +.B "\-b 16" +specifies 16 bit (2 Byte) for each sample in each channel (Ensure that +your sample player or sound card is capable of playing 12-bit or 16-bit +samples). Selecting 12 or 16 bits doubles file size. 12-bit samples are +aligned to 16-bit samples, so they waste some disk space. +.IP "Select sample rate" +.BI \-r " samplerate" +selects a sample rate. +.I samplerate +can be in a range between 44100 and 900. Option +.B \-R +lists all available rates. +.IP "Select sample rate divider" +.BI \-a " divider" +selects a sample rate divider. +.I divider +can be minimally 1 and maximally 50.5 and everything between in steps of 0.5. +Option +.B \-R +lists all available rates. +.IP +To make the sound smoother at lower sampling rates, +.B icedax +sums over +.I n +samples (where +.I n +is the specific dividend). So for 22050 Hertz output we have to sum over +2 samples, for 900 Hertz we have to sum over 49 samples. This cancels +higher frequencies. Standard sector size of an audio CD (ignoring +additional information) is 2352 Bytes. In order to finish summing +for an output sample at sector boundaries the rates above have to be +chosen. Arbitrary sampling rates in high quality would require some +interpolation scheme, which needs much more sophisticated programming. +.IP "List a table of all sampling rates" +.BI \-R +shows a list of all sample rates and their dividers. Dividers can range +from 1 to 50.5 in steps of 0.5. +.IP "Select start track and optionally end track" +.BI \-t " n+m" +selects +.B n +as the start track and optionally +.B m +as the last track of a range to be recorded. +These tracks must be from the table of contents. This sets +the track where recording begins. Recording can advance through the +following tracks as well (limited by the optional end track or otherwise +depending on recording time). Whether one file or different files are +then created depends on the +.B \-B +option (see below). +.IP "Select start index" +.BI \-i " n" +selects the index to start recording with. Indices other than 1 will +invoke the index scanner, which will take some time to find the correct +start position. An offset may be given additionally (see below). +.IP "Set recording time" +.B \-d " n" +sets recording time to +.I n +seconds or set recording time for whole track if +.I n +is zero. In order to specify the duration in frames (sectors) also, the +argument can have an appended 'f'. Then the numerical argument is to be +taken as frames (sectors) rather than seconds. +Please note that if track ranges are being used they define the recording +time as well thus overriding any +.BR \-d " option" +specified times. +.IP +Recording time is defined as the time the generated sample will play (at +the defined sample rate). Since it's related to the amount of generated +samples, it's not the time of the sampling process itself (which can be +less or more). It's neither strictly coupled with the time information on +the audio CD (shown by your hifi CD player). +Differences can occur by the usage of the +.B \-o +option (see below). Notice that recording time will be shortened, unless +enough disk space exists. Recording can be aborted at anytime by +pressing the break character (signal SIGQUIT). + .IP "Record all tracks of a complete audio CD in separate files" +.B \-B +copies each track into a separate file. A base name can be given. File names +have an appended track number and an extension corresponding to the audio +format. To record all audio tracks of a CD, use a sufficient high duration +(i.e. -d99999). +.IP "Set start sector offset" +.BI \-o " sectors" +increments start sector of the track by +.IR sectors . +By this option you are able to skip a certain amount at the beginning of +a track so you can pick exactly the part you want. Each sector runs for 1/75 +seconds, so you have very fine control. If your offset is so high that +it would not fit into the current track, a warning message is issued +and the offset is ignored. Recording time is not reduced. (To skip +introductory quiet passages automagically, use the +.B \-w +option see below.) +.IP "Wait for signal option" +.B \-w +Turning on this option will suppress all silent output at startup, +reducing possibly file size. +.B icedax +will watch for any signal in the output signal and switches on writing +to file. +.IP "Find extreme samples" +.B \-F +Turning on this option will display the most negative and the most positive +sample value found during recording for both channels. This can be useful +for readjusting the volume. The values shown are not reset at track +boundaries, they cover the complete sampling process. They are taken from +the original samples and have the same format (i.e. they are independent +of the selected output format). +.IP "Find if input samples are in mono" +.B \-G +If this option is given, input samples for both channels will be compared. At +the end of the program the result is printed. Differences in the channels +indicate stereo, otherwise when both channels are equal it will indicate mono. +.IP "Undo the pre-emphasis in the input samples" +.B \-T +Some older audio CDs are recorded with a modified frequency response called +pre-emphasis. This is found mostly in classical recordings. The correction +can be seen in the flags of the Table Of Contents often. But there are +recordings, that show this setting only in the subchannels. If this option +is given, the index scanner will be started, which reads the q-subchannel +of each track. If pre-emphasis is indicated in the q-subchannel of a track, +but not in the TOC, pre-emphasis will be assumed to be present, and +subsequently a reverse filtering is done for this track before the samples +are written into the audio file. +.IP "Set audio format" +.B \-O " audiotype" +can be +.I wav +(for wav files) or +.I au +or +.I sun +(for sun PCM files) or +.I cdr +or +.I raw +(for headerless files to be used for cd writers). +All file samples are coded in linear pulse code modulation (as done +in the audio compact disc format). This holds for all audio formats. +Wav files are compatible to Wind*ws sound files, they have lsb,msb byte order +as being used on the audio cd. The default filename extension is '.wav'. +Sun type files are not like the older common logarithmically coded .au files, +but instead as mentioned above linear PCM is used. The byte order is msb,lsb +to be compatible. The default filename extension is '.au'. +The AIFF and the newer variant AIFC from the Apple/SGI world store their samples +in bigendian format (msb,lsb). In AIFC no compression is used. +Finally the easiest 'format', +the cdr aka raw format. It is done per default in msb,lsb byte order to satisfy +the order wanted by most cd writers. Since there is no header information in this +format, the sample parameters can only be identified by playing the samples +on a soundcard or similar. The default filename extension is '.cdr' or '.raw'. +.IP "Select cdrom drive reading speed" +.B \-S " speed" +allows to switch the cdrom drive to a certain level of speed in order to +reduce read errors. The argument is transfered verbatim to the drive. +Details depend very much on the cdrom drives. +An argument of 0 for example is often the default speed of the drive, +a value of 1 often selects single speed. +.IP "Enable MD5 checksums" +.B \-M " count" +enables calculation of MD-5 checksum for 'count' bytes from the beginning of a +track. This was introduced for quick comparisons of tracks. +.IP "Use Monty's libparanoia for reading of sectors" +.B \-paranoia +selects an alternate way of extracting audio sectors. Monty's library is used +with the following default options: +.sp +PARANOIA_MODE_FULL, but without PARANOIA_MODE_NEVERSKIP +.sp +for details see Monty's libparanoia documentation. +In this case the option +.B \-P +has no effect. +.IP "Do linear or overlapping reading of sectors" +(This applies unless option +.B \-paranoia +is used.) +.B \-P " sectors" +sets the given number of sectors for initial overlap sampling for jitter +correction. Two cases are to be distinguished. For nonzero values, +some sectors are read twice to enable icedax's jitter correction. +If an argument of zero is given, no overlap sampling will be used. +For nonzero overlap sectors icedax dynamically adjusts the setting during +sampling (like cdparanoia does). +If no match can be found, icedax retries the read with an increased overlap. +If the amount of jitter is lower than the current overlapped samples, icedax +reduces the overlap setting, resulting in a higher reading speed. +The argument given has to be lower than the total number of sectors per request +(see option +.I -n +below). +Icedax will check this setting and issues a error message otherwise. +The case of zero sectors is nice on low load situations or errorfree (perfect) +cdrom drives and perfect (not scratched) audio cds. +.IP "Set the transfer size" +.B \-n " sectors" +will set the transfer size to the specified sectors per request. +.IP "Set number of ring buffer elements" +.B \-l " buffers" +will allocate the specified number of ring buffer elements. +.IP "Set endianess of input samples" +.B \-C " endianess" +will override the default settings of the input format. +Endianess can be set explicitly to "little" or "big" or to the automatic +endianess detection based on voting with "guess". +.IP "Set endianess of output samples" +.B \-E " endianess" +(endianess can be "little" or "big") will override the default settings +of the output format. +.IP "Verbose option" +.B \-v " itemlist" +prints more information. A list allows selection of different +information items. +.sp +.B "disable" +keeps quiet +.sp +.B "toc" +displays the table of contents +.sp +.B "summary" +displays a summary of recording parameters +.sp +.B "indices" +invokes the index scanner and displays start positions of indices +.sp +.B "catalog" +retrieves and displays a media catalog number +.sp +.B "trackid" +retrieves and displays international standard recording codes +.sp +.B "sectors" +displays track start positions in absolute sector notation +.sp +To combine several requests just list the suboptions separated with commas. +.IP "The table of contents" +The display will show the table of contents with number of tracks and +total time (displayed in +.IR mm : ss . hh +format, +.IR mm =minutes, +.IR ss =seconds, +.IR hh "=rounded 1/100 seconds)." +The following list displays track number and track time for each entry. +The summary gives a line per track describing the type of the track. +.sp +.ce 1 +.B "track preemphasis copypermitted tracktype chans" +.sp +The +.B track +column holds the track number. +.B preemphasis +shows if that track has been given a non linear frequency response. +NOTE: You can undo this effect with the +.B \-T +option. +.B "copy-permitted" +indicates if this track is allowed to copy. +.B "tracktype" +can be data or audio. On multimedia CDs (except hidden track CDs) +both of them should be present. +.B "channels" +is defined for audio tracks only. There can be two or four channels. +.IP "No file output" +.B \-N +this debugging option switches off writing to a file. +.IP "No infofile generation" +.B \-H +this option switches off creation of an info file and a cddb file. +.IP "Generation of simple output for gui frontends" +.B \-g +this option switches on simple line formatting, which is needed to support +gui frontends (like xcd-roast). +.IP "Verbose SCSI logging" +.B \-V +this option switches on logging of SCSI commands. This will produce +a lot of output (when SCSI devices are being used). +This is needed for debugging purposes. The format +is the same as being used with the cdrecord program from J\*org Schilling or +the wodim tool. See there for details. +.IP "Quiet option" +.B \-q +suppresses all screen output except error messages. +That reduces cpu time resources. +.IP "Just show information option" +.B \-J +does not write a file, it only prints information about the disc (depending +on the +.B \-v +option). This is just for information purposes. +.SH "CDDBP support" +.IP "Lookup album and track titles option" +.B \-L " cddbp mode" +Icedax tries to retrieve performer, album-, and track titles from a cddbp +server. The default server right now is 'freedb.freedb.org'. +It is planned to have more control over the server handling later. +The parameter defines how multiple entries are handled: +.PP +0 interactive mode, the user chooses one of the entries. +.PP +1 take the first entry without asking. +.IP "Set server for title lookups" +.B cddbp-server " servername" +When using \-L or --cddb, the server being contacted can be set with +this option. +.IP "Set portnumber for title lookups" +.B cddbp-port " portnumber" +When using \-L or --cddb, the server port being contacted can be set with +this option. +.SH "HINTS ON USAGE" +Don't create samples you cannot read. First check your sample player +software and sound card hardware. I experienced problems with very low +sample rates (stereo <= 1575 Hz, mono <= 3675 Hz) when trying to play +them with standard WAV players for sound blaster (maybe they are not +legal in +.B WAV +format). Most CD-Writers insist on audio samples in a bigendian format. +Now icedax supports the +.B \-E " endianess" +option to control the endianess of the written samples. +.PP +If your hardware is fast enough to run icedax +uninterrupted and your CD drive is one of the 'perfect' ones, you will +gain speed when switching all overlap sampling off with the +.B \-P " 0" +option. Further fine tuning can be done with the +.B \-n " sectors" +option. You can specify how much sectors should be requested in one go. +.PP +Icedax supports +.B pipes +now. Use a filename of +.B \- +to let icedax output its samples to standard output. +.PP +Conversion to other sound formats can be done using the +.B sox +program package (although the use of +.B sox -x +to change the byte order of samples should be no more necessary; see option +.B \-E +to change the output byteorder). +.PP +If you want to sample more than one track into +different files in one run, this is currently possible with the +.B \-B +option. When recording time exceeds the track limit a new file will +be opened for the next track. +.SH FILES +Icedax can generate a lot of files for various purposes. +.sp +Audio files: +.sp +There are audio files containing samples with default extensions +.wav, .au, .aifc, .aiff, and .cdr according to the selected sound format. +These files are not generated when option (-N) is given. Multiple files may +be written when the bulk copy option (-B) is used. Individual file names +can be given as arguments. If the number of file names given is sufficient +to cover all included audio tracks, the file names will be used verbatim. +Otherwise, if there are less file names than files needed to write the +included tracks, the part of the file name before the extension is extended +with '_dd' where dd represents the current track number. +.sp +Cddb and Cdindex files: +.sp +If icedax detects cd-extra or cd-text (album/track) title information, +then .cddb and .cdindex files are generated unless suppressed by the +option -H. They contain suitable formatted entries for submission to +audio cd track title databases in the internet. The CDINDEX and CDDB(tm) +systems are currently supported. For more information please visit +www.musicbrainz.org and www.freedb.com. +.sp +Inf files: +.sp +The inf files are describing the sample files and the part from the audio cd, +it was taken from. They are a means to transfer information to a cd burning +program like wodim. For example, if the original audio cd had pre-emphasis +enabled, and icedax -T did remove the pre-emphasis, then the inf file has +pre-emphasis not set (since the audio file does not have it anymore), while +the .cddb and the .cdindex have pre-emphasis set as the original does. +.SH WARNING +.B IMPORTANT: +it is prohibited to sell copies of copyrighted material by noncopyright +holders. This program may not be used to circumvent copyrights. +The user acknowledges this constraint when using the software. +.SH BUGS +Generation of md5 checksums is currently broken. +.sp +Performance may not be optimal on slower systems. +.sp +The index scanner may give timeouts. +.sp +The resampling (rate conversion code) uses polynomial interpolation, which +is not optimal. +.sp +Icedax should use threads. +.sp +Icedax currently cannot sample hidden audio tracks (track 1 index 0). +.SH ACKNOWLEDGEMENTS +Thanks goto Project MODE (http://www.mode.net/) and Fraunhofer Institut f\*ur +integrierte Schaltungen (FhG-IIS) (http://www.iis.fhg.de/) for financial +support. +Plextor Europe and Ricoh Japan provided cdrom disk drives and cd burners +which helped a lot to develop this software. +Rammi has helped a lot with the debugging and showed a lot of stamina when +hearing 100 times the first 16 seconds of the first track of the Krupps CD. +Libparanoia contributed by Monty (Christopher Montgomery) xiphmont@mit.edu. +.SH AUTHOR +Heiko Eissfeldt heiko@colossus.escape.de +.PP +This manpage describes the program implementation of +.B +icedax +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program cdda2wav as distributed +in the cdrtools package [1]. However, the cdrtools developers are not involved +in the development of this spinoff and therefore shall not be made responsible +for any problem caused by it. Do not try to get support for this program by +contacting the original authors. +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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 DATE +26 Sep 2006 + +.SH SOURCES +.PP +.br +[1] Cdrtools 2.01.01a08 from May 2006, http://cdrecord.berlios.de + diff --git a/icedax/icedax.c b/icedax/icedax.c new file mode 100644 index 0000000..9ac5ee0 --- /dev/null +++ b/icedax/icedax.c @@ -0,0 +1,3059 @@ +/* + * 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. + * + */ + +/* @(#)cdda2wav.c 1.64 06/02/19 Copyright 1998-2004 Heiko Eissfeldt, Copyright 2004-2006 J. Schilling */ +#undef DEBUG_BUFFER_ADDRESSES +#undef GPROF +#undef DEBUG_FORKED +#undef DEBUG_CLEANUP +#undef DEBUG_DYN_OVERLAP +#undef DEBUG_READS +#define DEBUG_ILLLEADOUT 0 /* 0 disables, 1 enables */ +/* + * Copyright: GNU Public License 2 applies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/* + * parts (C) Peter Widow + * parts (C) Thomas Niederreiter + * parts (C) RSA Data Security, Inc. + * + * last changes: + * 18.12.93 - first version, OK + * 01.01.94 - generalized & clean up HE + * 10.06.94 - first linux version HE + * 12.06.94 - wav header alignment problem fixed HE + * 12.08.94 - open the cdrom device O_RDONLY makes more sense :-) + * no more floating point math + * change to sector size 2352 which is more common + * sub-q-channel information per kernel ioctl requested + * doesn't work as well as before + * some new options (-max -i) + * 01.02.95 - async i/o via semaphores and shared memory + * 03.02.95 - overlapped reading on sectors + * 03.02.95 - generalized sample rates. all integral divisors are legal + * 04.02.95 - sun format added + * more divisors: all integral halves >= 1 allowed + * floating point math needed again + * 06.02.95 - bugfix for last track and not d0 + * tested with photo-cd with audio tracks + * tested with xa disk + * 29.01.96 - new options for bulk transfer + * 01.06.96 - tested with enhanced cd + * 01.06.96 - tested with cd-plus + * 02.06.96 - support pipes + * 02.06.96 - support raw format + * 04.02.96 - security hole fixed + * 22.04.97 - large parts rewritten + * 28.04.97 - make file names DOS compatible + * 01.09.97 - add speed control + * 20.10.97 - add find mono option + * Jan/Feb 98 - conversion to use Joerg Schillings SCSI library + * see ChangeLog + */ + +#include "config.h" + +#include <unixstd.h> +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <schily.h> +#include <signal.h> +#include <math.h> +#include <fctldefs.h> +#include <timedefs.h> +#if defined (HAVE_LIMITS_H) +#include <limits.h> +#endif +#if defined (HAVE_SYS_IOCTL_H) +#include <sys/ioctl.h> +#endif +#include <errno.h> +#include <statdefs.h> +#include <waitdefs.h> +#if defined (HAVE_SETPRIORITY) +#include <sys/resource.h> +#endif +#include <vadefs.h> + +#include <usal/scsitransp.h> + +#ifdef HAVE_AREAS +#include <be/kernel/OS.h> +#endif + +#include "mytype.h" +#include "sndconfig.h" + +#include "semshm.h" /* semaphore functions */ +#include "sndfile.h" +#include "wav.h" /* wav file header structures */ +#include "sun.h" /* sun audio file header structures */ +#include "raw.h" /* raw file handling */ +#include "aiff.h" /* aiff file handling */ +#include "aifc.h" /* aifc file handling */ +#ifdef USE_LAME +#include "mp3.h" /* mp3 file handling */ +#endif +#include "interface.h" /* low level cdrom interfacing */ +#include "icedax.h" +#include "resample.h" +#include "toc.h" +#include "setuid.h" +#include "ringbuff.h" +#include "global.h" +#include "exitcodes.h" +#ifdef USE_PARANOIA +#include "cdda_paranoia.h" +#endif +#include "defaults.h" + +static void RestrictPlaybackRate(long newrate); +static void output_indices(FILE *fp, index_list *p, unsigned trackstart); +static int write_info_file(char *fname_baseval, unsigned int track, + unsigned long SamplesDone, int numbered); +static void CloseAudio(int channels_val, unsigned long nSamples, + struct soundfile *audio_out); +static void CloseAll(void); +static void OpenAudio(char *fname, double rate, long nBitsPerSample, + long channels_val, unsigned long expected_bytes, + struct soundfile*audio_out); +static void set_offset(myringbuff *p, int offset); +static int get_offset(myringbuff *p); +static void usage(void); +static void init_globals(void); +static int is_fifo(char *filename); + + +/* Rules: + * unique parameterless options first, + * unique parametrized option names next, + * ambigious parameterless option names next, + * ambigious string parametrized option names last + */ +static const char *opts = "paranoia,paraopts&,version,help,h,\ +no-write,N,dump-rates,R,bulk,B,alltracks,verbose-scsi+,V+,\ +find-extremes,F,find-mono,G,no-infofile,H,\ +deemphasize,T,info-only,J,silent-scsi,Q,\ +cddbp-server*,cddbp-port*,\ +scanbus,devices,device*,dev*,D*,auxdevice*,A*,interface*,I*,output-format*,O*,\ +output-endianess*,E*,cdrom-endianess*,C*,speed#,S#,\ +playback-realtime#L,p#L,md5#,M#,set-overlap#,P#,sound-device*,K*,\ +cddb#,L#,channels*,c*,bits-per-sample#,b#,rate#,r#,gui,g,\ +divider*,a*,track*,t*,index#,i#,duration*,d*,offset#,o#,\ +sectors-per-request#,n#,verbose-level&,v&,buffers-in-ring#,l#,\ +stereo,s,mono,m,wait,w,echo,e,quiet,q,max,x\ +"; + + +#ifdef NEED_O_BINARY +#include <io.h> /* for setmode() prototype */ +#endif + +/* global variables */ +global_t global; + +/* static variables */ +static unsigned long nSamplesDone = 0; + +static int child_pid = -2; + +static unsigned long *nSamplesToDo; +static unsigned int current_track; +static int bulk = 0; + +unsigned int get_current_track(void); + +unsigned int get_current_track() +{ + return current_track; +} + +static void RestrictPlaybackRate(long newrate) +{ + global.playback_rate = newrate; + + if ( global.playback_rate < 25 ) global.playback_rate = 25; /* filter out insane values */ + if ( global.playback_rate > 250 ) global.playback_rate = 250; + + if ( global.playback_rate < 100 ) + global.nsectors = (global.nsectors*global.playback_rate)/100; +} + + +long SamplesNeeded(long amount, long undersampling_val) +{ + long retval = ((undersampling_val * 2 + Halved)*amount)/2; + if (Halved && (*nSamplesToDo & 1)) + retval += 2; + return retval; +} + +static int argc2; +static int argc3; +static char **argv2; + +static void reset_name_iterator(void); +static void reset_name_iterator() +{ + argv2 -= argc3 - argc2; + argc2 = argc3; +} + +static char *get_next_name(void); +static char *get_next_name() +{ + if (argc2 > 0) { + argc2--; + return (*argv2++); + } else { + return NULL; + } +} + +static char *cut_extension(char *fname); + +static char *cut_extension(char *fname) +{ + char *pp; + + pp = strrchr(fname, '.'); + + if (pp == NULL) { + pp = fname + strlen(fname); + } + *pp = '\0'; + + return pp; +} + +#ifdef INFOFILES +static void output_indices(FILE *fp, index_list *p, unsigned trackstart) +{ + int ci; + + fprintf(fp, "Index=\t\t"); + + if (p == NULL) { + fprintf(fp, "0\n"); + return; + } + + for (ci = 1; p != NULL; ci++, p = p->next) { + int frameoff = p->frameoffset; + + if (p->next == NULL) + fputs("\nIndex0=\t\t", fp); +#if 0 + else if ( ci > 8 && (ci % 8) == 1) + fputs("\nIndex =\t\t", fp); +#endif + if (frameoff != -1) + fprintf(fp, "%d ", frameoff - trackstart); + else + fprintf(fp, "-1 "); + } + fputs("\n", fp); +} + +/* + * write information before the start of the sampling process + * + * + * uglyfied for Joerg Schillings ultra dumb line parser + */ +static int write_info_file(char *fname_baseval, unsigned int track, + unsigned long int SamplesDone, int numbered) +{ + FILE *info_fp; + char fname[200]; + char datetime[30]; + time_t utc_time; + struct tm *tmptr; + + /* write info file */ + if (!strcmp(fname_baseval,"-")) return 0; + + strncpy(fname, fname_baseval, sizeof(fname) -1); + fname[sizeof(fname) -1] = 0; + if (numbered) + sprintf(cut_extension(fname), "_%02u.inf", track); + else + strcpy(cut_extension(fname), ".inf"); + + info_fp = fopen (fname, "w"); + if (!info_fp) + return -1; + +#if 0 +#ifdef MD5_SIGNATURES + if (global.md5blocksize) + MD5Final (global.MD5_result, &global.context); +#endif +#endif + + utc_time = time(NULL); + tmptr = localtime(&utc_time); + if (tmptr) { + strftime(datetime, sizeof(datetime), "%x %X", tmptr); + } else { + strncpy(datetime, "unknown", sizeof(datetime)); + } + fprintf(info_fp, "#created by icedax %s %s\n#\n", VERSION + , datetime + ); + fprintf(info_fp, +"CDINDEX_DISCID=\t'%s'\n" , global.cdindex_id); + fprintf(info_fp, +"CDDB_DISCID=\t0x%08lx\n\ +MCN=\t\t%s\n\ +ISRC=\t\t%15.15s\n\ +#\n\ +Albumperformer=\t'%s'\n\ +Performer=\t'%s'\n\ +Albumtitle=\t'%s'\n" + , (unsigned long) global.cddb_id + , Get_MCN() + , Get_ISRC(track) + , global.creator != NULL ? global.creator : (const unsigned char *)"" + , global.trackcreator[track] != NULL ? global.trackcreator[track] : + (global.creator != NULL ? global.creator : (const unsigned char *)"") + , global.disctitle != NULL ? global.disctitle : (const unsigned char *)"" + ); + fprintf(info_fp, + "Tracktitle=\t'%s'\n" + , global.tracktitle[track] ? global.tracktitle[track] : (const unsigned char *)"" + ); + fprintf(info_fp, "Tracknumber=\t%u\n" + , track + ); + fprintf(info_fp, + "Trackstart=\t%ld\n" + , Get_AudioStartSector(track) + ); + fprintf(info_fp, + "# track length in sectors (1/75 seconds each), rest samples\nTracklength=\t%ld, %d\n" + , SamplesDone/588L,(int)(SamplesDone%588)); + fprintf(info_fp, + "Pre-emphasis=\t%s\n" + , Get_Preemphasis(track) && (global.deemphasize == 0) ? "yes" : "no"); + fprintf(info_fp, + "Channels=\t%d\n" + , Get_Channels(track) ? 4 : global.channels == 2 ? 2 : 1); + { int cr = Get_Copyright(track); + fputs("Copy_permitted=\t", info_fp); + switch (cr) { + case 0: + fputs("once (copyright protected)\n", info_fp); + break; + case 1: + fputs("no (SCMS first copy)\n", info_fp); + break; + case 2: + fputs("yes (not copyright protected)\n", info_fp); + break; + default: + fputs("unknown\n", info_fp); + } + } + fprintf(info_fp, + "Endianess=\t%s\n" + , global.need_big_endian ? "big" : "little" + ); + fprintf(info_fp, "# index list\n"); + output_indices(info_fp, global.trackindexlist[track], + Get_AudioStartSector(track)); +#if 0 +/* MD5 checksums in info files are currently broken. + * for on-the-fly-recording the generation of info files has been shifted + * before the recording starts, so there is no checksum at that point. + */ +#ifdef MD5_SIGNATURES + fprintf(info_fp, + "#(blocksize) checksum\nMD-5=\t\t(%d) %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n" + , global.md5blocksize + , global.MD5_result[0] + , global.MD5_result[1] + , global.MD5_result[2] + , global.MD5_result[3] + , global.MD5_result[4] + , global.MD5_result[5] + , global.MD5_result[6] + , global.MD5_result[7] + , global.MD5_result[8] + , global.MD5_result[9] + , global.MD5_result[10] + , global.MD5_result[11] + , global.MD5_result[12] + , global.MD5_result[13] + , global.MD5_result[14] + , global.MD5_result[15]); +#endif +#endif + fclose(info_fp); + return 0; +} +#endif + +static void CloseAudio(int channels_val, unsigned long nSamples, + struct soundfile *audio_out) +{ + /* define length */ + audio_out->ExitSound( global.audio, (nSamples-global.SkippedSamples)*global.OutSampleSize*channels_val ); + + close (global.audio); + global.audio = -1; +} + +static unsigned int track = 1; + +/* On terminating: + * define size-related entries in audio file header, update and close file */ +static void CloseAll() +{ + WAIT_T chld_return_status; + int amiparent; + + /* terminate child process first */ + amiparent = child_pid > 0; + + if (global.iloop > 0) { + /* set to zero */ + global.iloop = 0; + } + +#if defined HAVE_FORK_AND_SHAREDMEM +# ifdef DEBUG_CLEANUP + fprintf(stderr, "%s terminating, \n", amiparent ? + "Parent (READER)" : "Child (WRITER)"); +#endif +#else +# ifdef DEBUG_CLEANUP + fprintf(stderr, "icedax single process terminating, \n"); +# endif +#endif + + if (amiparent || child_pid < 0) { + /* switch to original mode and close device */ + EnableCdda (get_scsi_p(), 0, 0); + } + + if (!amiparent) { + /* do general clean up */ + + if (global.audio>=0) { + if (bulk) { + /* finish sample file for this track */ + CloseAudio(global.channels, + global.nSamplesDoneInTrack, global.audio_out); + } else { + /* finish sample file for this track */ + CloseAudio(global.channels, + (unsigned int) *nSamplesToDo, global.audio_out); + } + } + + /* tell minimum and maximum amplitudes, if required */ + if (global.findminmax) { + fprintf(stderr, + "Right channel: minimum amplitude :%d/-32768, maximum amplitude :%d/32767\n", + global.minamp[0], global.maxamp[0]); + fprintf(stderr, + "Left channel: minimum amplitude :%d/-32768, maximum amplitude :%d/32767\n", + global.minamp[1], global.maxamp[1]); + } + + /* tell mono or stereo recording, if required */ + if (global.findmono) { + fprintf(stderr, "Audio samples are originally %s.\n", global.ismono ? "mono" : "stereo"); + } + + return; /* end of child or single process */ + } + + + if (global.have_forked == 1) { +#ifdef DEBUG_CLEANUP + fprintf(stderr, "Parent wait for child death, \n"); +#endif + + /* wait for child to terminate */ + if (0 > wait(&chld_return_status)) { + perror(""); + } else { + if (WIFEXITED(chld_return_status)) { + if (WEXITSTATUS(chld_return_status)) { + fprintf(stderr, "\nW Child exited with %d\n", WEXITSTATUS(chld_return_status)); + } + } + if (WIFSIGNALED(chld_return_status)) { + fprintf(stderr, "\nW Child exited due to signal %d\n", WTERMSIG(chld_return_status)); + } + if (WIFSTOPPED(chld_return_status)) { + fprintf(stderr, "\nW Child is stopped due to signal %d\n", WSTOPSIG(chld_return_status)); + } + } + +#ifdef DEBUG_CLEANUP + fprintf(stderr, "\nW Parent child death, state:%d\n", chld_return_status); +#endif + } + +#ifdef GPROF + rename("gmon.out", "gmon.child"); +#endif +} + + +/* report a usage error and exit */ +#ifdef PROTOTYPES +static void usage2 (const char *szMessage, ...) +#else +static void usage2(const char *szMessage, va_dcl va_alist) +#endif +{ + va_list marker; + +#ifdef PROTOTYPES + va_start(marker, szMessage); +#else + va_start(marker); +#endif + + vfprintf(stderr, szMessage, marker); + + va_end(marker); + fprintf(stderr, "\nPlease use -help or consult the man page for help.\n"); + + exit (1); +} + + +/* report a fatal error, clean up and exit */ +#ifdef PROTOTYPES +void FatalError (const char *szMessage, ...) +#else +void FatalError(const char *szMessage, va_dcl va_alist) +#endif +{ + va_list marker; + +#ifdef PROTOTYPES + va_start(marker, szMessage); +#else + va_start(marker); +#endif + + vfprintf(stderr, szMessage, marker); + + va_end(marker); + + if (child_pid >= 0) { + if (child_pid == 0) { + pid_t ppid; + /* + * Kill the parent too if we are not orphaned. + */ + ppid = getppid(); + if (ppid > 1) + kill(ppid, SIGINT); + } else { + kill(child_pid, SIGINT); + } + } + exit (1); +} + + +/* open the audio output file and prepare the header. + * the header will be defined on terminating (when the size + * is known). So hitting the interrupt key leaves an intact + * file. + */ +static void OpenAudio(char *fname, double rate, long nBitsPerSample, + long channels_val, unsigned long expected_bytes, + struct soundfile *audio_out) +{ + if (global.audio == -1) { + + global.audio = open (fname, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY +#ifdef SYNCHRONOUS_WRITE + | O_SYNC +#endif + , 0666); + if (global.audio == -1) { + if (errno == EAGAIN && is_fifo(fname)) { + FatalError ("Could not open fifo %s. Probably no fifo reader present.\n", fname); + } + perror("open audio sample file"); + FatalError ("Could not open file %s\n", fname); + } + } + global.SkippedSamples = 0; + any_signal = 0; + audio_out->InitSound( global.audio, channels_val, (unsigned long)rate, nBitsPerSample, expected_bytes ); + +#ifdef MD5_SIGNATURES + if (global.md5blocksize) + MD5Init (&global.context); + global.md5count = global.md5blocksize; +#endif +} + +#include "scsi_cmds.h" + +static int RealEnd(SCSI *usalp, UINT4 *buff); + +static int RealEnd(SCSI *usalp, UINT4 *buff) +{ + if (usal_cmd_err(usalp) != 0) { + int c,k,q; + + k = usal_sense_key(usalp); + c = usal_sense_code(usalp); + q = usal_sense_qual(usalp); + if ((k == 0x05 /* ILLEGAL_REQUEST */ && + c == 0x21 /* lba out of range */ && + q == 0x00) || + (k == 0x05 /* ILLEGAL_REQUEST */ && + c == 0x63 /*end of user area encountered on this track*/ && + q == 0x00) || + (k == 0x08 /* BLANK_CHECK */ && + c == 0x64 /* illegal mode for this track */ && + q == 0x00)) { + return 1; + } + } + + if (usal_getresid(usalp) > 16) return 1; + + { + unsigned char *p; + /* Look into the subchannel data */ + buff += CD_FRAMESAMPLES; + p = (unsigned char *)buff; + if (p[0] == 0x21 && p[1] == 0xaa) { + return 1; + } + } + return 0; +} + +static void set_offset(myringbuff *p, int offset) +{ +#ifdef DEBUG_SHM + fprintf(stderr, "Write offset %d at %p\n", offset, &p->offset); +#endif + p->offset = offset; +} + + +static int get_offset(myringbuff *p) +{ +#ifdef DEBUG_SHM + fprintf(stderr, "Read offset %d from %p\n", p->offset, &p->offset); +#endif + return p->offset; +} + + +static void usage() +{ + fputs( +"usage: icedax [OPTIONS ...] [trackfilenames ...]\n\ +OPTIONS:\n\ + [-c chans] [-s] [-m] [-b bits] [-r rate] [-a divider] [-S speed] [-x]\n\ + [-t track[+endtrack]] [-i index] [-o offset] [-d duration] [-F] [-G]\n\ + [-q] [-w] [-v vopts] [-R] [-P overlap] [-B] [-T] [-C input-endianess]\n\ + [-e] [-n sectors] [-N] [-J] [-L cddbp-mode] [-H] [-g] [-l buffers] [-D cd-device]\n\ + [-I interface] [-K sound-device] [-O audiotype] [-E output-endianess]\n\ + [-A auxdevice] [-paranoia] [-cddbp-server=name] [-cddbp-port=port] [-version]\n", stderr); + fputs("\ + (-D) dev=device set the cdrom or scsi device (as Bus,Id,Lun).\n\ + (-A) auxdevice=device set the aux device (typically /dev/cdrom).\n\ + (-K) sound-device=device set the sound device to use for -e (typically /dev/dsp).\n\ + (-I) interface=interface specify the interface for cdrom access.\n\ + (generic_scsi or cooked_ioctl).\n\ + (-c) channels=channels set 1 for mono, 2 or s for stereo (s: channels swapped).\n\ + (-s) -stereo select stereo recording.\n\ + (-m) -mono select mono recording.\n\ + (-x) -max select maximum quality (stereo/16-bit/44.1 KHz).\n\ + (-b) bits=bits set bits per sample per channel (8, 12 or 16 bits).\n\ + (-r) rate=rate set rate in samples per second. -R gives all rates\n\ + (-a) divider=divider set rate to 44100Hz / divider. -R gives all rates\n\ + (-R) -dump-rates dump a table with all available sample rates\n\ + (-S) speed=speedfactor set the cdrom drive to a given speed during reading\n\ + (-P) set-overlap=sectors set amount of overlap sampling (default is 0)\n\ + (-n) sectors-per-request=secs read 'sectors' sectors per request.\n\ + (-l) buffers-in-ring=buffers use a ring buffer with 'buffers' elements.\n\ + (-t) track=track[+end track] select start track (option. end track).\n\ + (-i) index=index select start index.\n\ + (-o) offset=offset start at 'offset' sectors behind start track/index.\n\ + one sector equivalents 1/75 second.\n\ + (-O) output-format=audiotype set to wav, au (sun), cdr (raw), aiff or aifc format.\n\ + (-C) cdrom-endianess=endian set little, big or guess input sample endianess.\n\ + (-E) output-endianess=endian set little or big output sample endianess.\n\ + (-d) duration=seconds set recording time in seconds or 0 for whole track.\n\ + (-w) -wait wait for audio signal, then start recording.\n\ + (-F) -find-extremes find extrem amplitudes in samples.\n\ + (-G) -find-mono find if input samples are mono.\n\ + (-T) -deemphasize undo pre-emphasis in input samples.\n\ + (-e) -echo echo audio data to sound device (see -K) SOUND_DEV.\n\ + (-v) verbose-level=optlist controls verbosity (for a list use -vhelp).\n\ + (-N) -no-write do not create audio sample files.\n\ + (-J) -info-only give disc information only.\n\ + (-L) cddb=cddbpmode do cddbp title lookups.\n\ + resolve multiple entries according to cddbpmode: 0=interactive, 1=first entry\n\ + (-H) -no-infofile no info file generation.\n\ + (-g) -gui generate special output suitable for gui frontends.\n\ + (-Q) -silent-scsi do not print status of erreneous scsi-commands.\n\ + -scanbus scan the SCSI bus and exit\n\ + --devices scan for system devices and print with native names\n\ + (-M) md5=count calculate MD-5 checksum for blocks of 'count' bytes.\n\ + (-q) -quiet quiet operation, no screen output.\n\ + (-p) playback-realtime=perc play (echo) audio pitched at perc percent (50%-200%).\n\ + (-V) -verbose-scsi each option increases verbosity for SCSI commands.\n\ + (-h) -help show this help screen.\n\ + (-B) -alltracks, -bulk record each track into a seperate file.\n\ + -paranoia use the lib paranoia for reading.\n\ + -paraopts=opts set options for lib paranoia (see -paraopts=help).\n\ + -cddbp-server=servername set the cddbp server to use for title lookups.\n\ + -cddbp-port=portnumber set the cddbp port to use for title lookups.\n\ + -version print version information.\n\ +\n\ +Please note: some short options will be phased out soon (disappear)!\n\ +\n\ +parameters: (optional) one or more file names or - for standard output.\n\ +", stderr); + fputs("Version ", stderr); + fputs(VERSION, stderr); + fprintf(stderr, "\n\ +defaults %s, %d bit, %d.%02d Hz, track 1, no offset, one track,\n", + CHANNELS-1?"stereo":"mono", BITS_P_S, + 44100 / UNDERSAMPLING, + (4410000 / UNDERSAMPLING) % 100); + fprintf(stderr, "\ + type %s '%s', don't wait for signal, not quiet,\n", + AUDIOTYPE, FILENAME); + fprintf(stderr, "\ + use %s, device %s, aux %s\n", + DEF_INTERFACE, CD_DEVICE, AUX_DEVICE); + exit( SYNTAX_ERROR ); +} + +static void init_globals() +{ +#ifdef HISTORICAL_JUNK + global.dev_name = CD_DEVICE; /* device name */ +#endif + global.aux_name = AUX_DEVICE;/* auxiliary cdrom device */ + strncpy(global.fname_base, FILENAME, sizeof(global.fname_base));/* auxiliary cdrom device */ + global.have_forked = 0; /* state variable for clean up */ + global.parent_died = 0; /* state variable for clean up */ + global.audio = -1; /* audio file desc */ + global.cooked_fd = -1; /* cdrom file desc */ + global.no_file = 0; /* flag no_file */ + global.no_infofile = 0; /* flag no_infofile */ + global.no_cddbfile = 0; /* flag no_cddbfile */ + global.quiet = 0; /* flag quiet */ + global.verbose = SHOW_TOC + SHOW_SUMMARY + SHOW_STARTPOSITIONS + SHOW_TITLES; /* verbose level */ + global.scsi_silent = 0; + global.scsi_verbose = 0; /* SCSI verbose level */ + global.scanbus = 0; + global.scandevs = 0; + global.multiname = 0; /* multiple file names given */ + global.sh_bits = 0; /* sh_bits: sample bit shift */ + global.Remainder= 0; /* remainder */ + global.iloop = 0; /* todo counter */ + global.SkippedSamples = 0; /* skipped samples */ + global.OutSampleSize = 0; /* output sample size */ + global.channels = CHANNELS; /* output sound channels */ + global.nSamplesDoneInTrack = 0; /* written samples in current track */ + global.buffers = 4; /* buffers to use */ + global.nsectors = NSECTORS; /* sectors to read in one request */ + global.overlap = 1; /* amount of overlapping sectors */ + global.useroverlap = -1; /* amount of overlapping sectors user override */ + global.need_hostorder = 0; /* processing needs samples in host endianess */ + global.in_lendian = -1; /* input endianess from SetupSCSI() */ + global.outputendianess = NONE; /* user specified output endianess */ + global.findminmax = 0; /* flag find extrem amplitudes */ +#ifdef HAVE_LIMITS_H + global.maxamp[0] = INT_MIN; /* maximum amplitude */ + global.maxamp[1] = INT_MIN; /* maximum amplitude */ + global.minamp[0] = INT_MAX; /* minimum amplitude */ + global.minamp[1] = INT_MAX; /* minimum amplitude */ +#else + global.maxamp[0] = -32768; /* maximum amplitude */ + global.maxamp[1] = -32768; /* maximum amplitude */ + global.minamp[0] = 32767; /* minimum amplitude */ + global.minamp[1] = 32767; /* minimum amplitude */ +#endif + global.speed = DEFAULT_SPEED; /* use default */ + global.userspeed = -1; /* speed user override */ + global.findmono = 0; /* flag find if samples are mono */ + global.ismono = 1; /* flag if samples are mono */ + global.swapchannels = 0; /* flag if channels shall be swapped */ + global.deemphasize = 0; /* flag undo pre-emphasis in samples */ + global.playback_rate = 100; /* new fancy selectable sound output rate */ + global.gui = 0; /* flag plain formatting for guis */ + global.cddb_id = 0; /* disc identifying id for CDDB database */ + global.cddb_revision = 0; /* entry revision for CDDB database */ + global.cddb_year = 0; /* disc identifying year for CDDB database */ + global.cddb_genre[0] = '\0'; /* disc identifying genre for CDDB database */ + global.cddbp = 0; /* flag if titles shall be looked up from CDDBP */ + global.cddbp_server = 0; /* user supplied CDDBP server */ + global.cddbp_port = 0; /* user supplied CDDBP port */ + global.illleadout_cd = 0; /* flag if illegal leadout is present */ + global.reads_illleadout = 0; /* flag if cdrom drive reads cds with illegal leadouts */ + global.disctitle = NULL; + global.creator = NULL; + global.copyright_message = NULL; + memset(global.tracktitle, 0, sizeof(global.tracktitle)); + memset(global.trackindexlist, 0, sizeof(global.trackindexlist)); + + global.just_the_toc = 0; +#ifdef USE_PARANOIA + global.paranoia_parms.disable_paranoia = + global.paranoia_parms.disable_extra_paranoia = + global.paranoia_parms.disable_scratch_detect = + global.paranoia_parms.disable_scratch_repair = 0; + global.paranoia_parms.retries = 20; + global.paranoia_parms.overlap = -1; + global.paranoia_parms.mindynoverlap = -1; + global.paranoia_parms.maxdynoverlap = -1; +#endif +} + +#if !defined (HAVE_STRCASECMP) || (HAVE_STRCASECMP != 1) +#include <ctype.h> +static int strcasecmp(const char *s1, const char *s2); +static int strcasecmp(const char *s1, const char *s2) +{ + if (s1 && s2) { + while (*s1 && *s2 && (tolower(*s1) - tolower(*s2) == 0)) { + s1++; + s2++; + } + if (*s1 == '\0' && *s2 == '\0') return 0; + if (*s1 == '\0') return -1; + if (*s2 == '\0') return +1; + return tolower(*s1) - tolower(*s2); + } + return -1; +} +#endif + +static int is_fifo(char *filename) +{ +#if defined S_ISFIFO + struct stat statstruct; + + if (stat(filename, &statstruct)) { + /* maybe the output file does not exist. */ + if (errno == ENOENT) + return 0; + else comerr("Error during stat for output file\n"); + } else { + if (S_ISFIFO(statstruct.st_mode)) { + return 1; + } + } + return 0; +#else + return 0; +#endif +} + + +#if !defined (HAVE_STRTOUL) || (HAVE_STRTOUL != 1) +static unsigned int strtoul(const char *s1, char **s2, int base); +static unsigned int strtoul(const char *s1, char **s2, int base) +{ + long retval; + + if (base == 10) { + /* strip zeros in front */ + while (*s1 == '0') + s1++; + } + if (s2 != NULL) { + *s2 = astol(s1, &retval); + } else { + (void) astol(s1, &retval); + } + + return (unsigned long) retval; +} +#endif + +static unsigned long SectorBurst; +#if (SENTINEL > CD_FRAMESIZE_RAW) +error block size for overlap check has to be < sector size +#endif + + +static void +switch_to_realtime_priority(void); + +#ifdef HAVE_SYS_PRIOCNTL_H + +#include <sys/priocntl.h> +#include <sys/rtpriocntl.h> +static void switch_to_realtime_priority() +{ + pcinfo_t info; + pcparms_t param; + rtinfo_t rtinfo; + rtparms_t rtparam; + int pid; + + pid = getpid(); + + /* get info */ + strcpy(info.pc_clname, "RT"); + if (-1 == priocntl(P_PID, pid, PC_GETCID, (void *)&info)) { + errmsg("Cannot get priority class id priocntl(PC_GETCID)\n"); + goto prio_done; + } + + memmove(&rtinfo, info.pc_clinfo, sizeof(rtinfo_t)); + + /* set priority not to the max */ + rtparam.rt_pri = rtinfo.rt_maxpri - 2; + rtparam.rt_tqsecs = 0; + rtparam.rt_tqnsecs = RT_TQDEF; + param.pc_cid = info.pc_cid; + memmove(param.pc_clparms, &rtparam, sizeof(rtparms_t)); + priv_on(); + needroot(0); + if (-1 == priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m)) + errmsg("Cannot set priority class parameters priocntl(PC_SETPARMS)\n"); +prio_done: + priv_off(); + dontneedroot(); +} +#else +#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0 +#define USE_POSIX_PRIORITY_SCHEDULING +#endif +#ifdef USE_POSIX_PRIORITY_SCHEDULING +#include <sched.h> + +static void switch_to_realtime_priority() +{ +#ifdef _SC_PRIORITY_SCHEDULING + if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) { + errmsg("WARNING: RR-scheduler not available, disabling.\n"); + } else +#endif + { + int sched_fifo_min, sched_fifo_max; + struct sched_param sched_parms; + + sched_fifo_min = sched_get_priority_min(SCHED_FIFO); + sched_fifo_max = sched_get_priority_max(SCHED_FIFO); + sched_parms.sched_priority = sched_fifo_max - 1; + priv_on(); + needroot(0); + if (-1 == sched_setscheduler(getpid(), SCHED_FIFO, &sched_parms) + && global.quiet != 1) + errmsg("cannot set posix realtime scheduling policy\n"); + priv_off(); + dontneedroot(); + } +} +#else +#if defined(__CYGWIN32__) + +/* + * NOTE: Base.h from Cygwin-B20 has a second typedef for BOOL. + * We define BOOL to make all local code use BOOL + * from Windows.h and use the hidden __SBOOL for + * our global interfaces. + * + * NOTE: windows.h from Cygwin-1.x includes a structure field named sample, + * so me may not define our own 'sample' or need to #undef it now. + * With a few nasty exceptions, Microsoft assumes that any global + * defines or identifiers will begin with an Uppercase letter, so + * there may be more of these problems in the future. + * + * NOTE: windows.h defines interface as an alias for struct, this + * is used by COM/OLE2, I guess it is class on C++ + * We man need to #undef 'interface' + */ +#define BOOL WBOOL /* This is the Win BOOL */ +#define format __format /* Avoid format parameter hides global ... */ +#include <windows.h> +#undef format +#undef interface + +static void switch_to_realtime_priority() +{ + /* set priority class */ + if (FALSE == SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) { + fprintf(stderr, "No realtime priority possible.\n"); + return; + } + + /* set thread priority */ + if (FALSE == SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) { + fprintf(stderr, "Could not set realtime priority.\n"); + } +} +#else +static void switch_to_realtime_priority() +{ +} +#endif +#endif +#endif + +/* SCSI cleanup */ +int on_exitscsi(void *status); + +int on_exitscsi(void *status) +{ + exit((intptr_t)status); + return 0; +} + +/* wrapper for signal handler exit needed for Mac-OS-X */ +static void exit_wrapper(int status); + +static void exit_wrapper(int status) +{ +#if defined DEBUG_CLEANUP + fprintf( stderr, "Exit(%d) for %s\n", status, child_pid == 0 ? "Child" : "Parent"); + fflush(stderr); +#endif + + if (child_pid != 0) { + SCSI *usalp = get_scsi_p(); + if (usalp->running) { + usalp->cb_fun = on_exitscsi; + usalp->cb_arg = (void *) (uintptr_t) status; + } else { + on_exitscsi((void *) (intptr_t) status); + } + } else { + exit(status); + } +} + +/* signal handler for process communication */ +static void set_nonforked(int status); + +/* ARGSUSED */ +static void set_nonforked(int status) +{ + global.parent_died = 1; +#if defined DEBUG_CLEANUP +fprintf( stderr, "SIGPIPE received from %s\n.", child_pid == 0 ? "Child" : "Parent"); +#endif + if (child_pid == 0) { + pid_t ppid; + /* + * Kill the parent too if we are not orphaned. + */ + ppid = getppid(); + if (ppid > 1) + kill(ppid, SIGINT); + } else { + kill(child_pid, SIGINT); + } + exit(SIGPIPE_ERROR); +} + + + +#ifdef USE_PARANOIA +static struct paranoia_statistics +{ + long c_sector; + long v_sector; + int last_heartbeatstate; + long lasttime; + char heartbeat; + int minoverlap; + int curoverlap; + int maxoverlap; + int slevel; + int slastlevel; + int stimeout; + int rip_smile_level; + unsigned verifies; + unsigned reads; + unsigned fixup_edges; + unsigned fixup_atoms; + unsigned readerrs; + unsigned skips; + unsigned overlaps; + unsigned scratchs; + unsigned drifts; + unsigned fixup_droppeds; + unsigned fixup_dupeds; +} *para_stat; + + +static void paranoia_reset(void); +static void paranoia_reset() +{ + para_stat->c_sector = 0; + para_stat->v_sector = 0; + para_stat->last_heartbeatstate = 0; + para_stat->lasttime = 0; + para_stat->heartbeat = ' '; + para_stat->minoverlap = 0x7FFFFFFF; + para_stat->curoverlap = 0; + para_stat->maxoverlap = 0; + para_stat->slevel = 0; + para_stat->slastlevel = 0; + para_stat->stimeout = 0; + para_stat->rip_smile_level = 0; + para_stat->verifies = 0; + para_stat->reads = 0; + para_stat->readerrs = 0; + para_stat->fixup_edges = 0; + para_stat->fixup_atoms = 0; + para_stat->fixup_droppeds = 0; + para_stat->fixup_dupeds = 0; + para_stat->drifts = 0; + para_stat->scratchs = 0; + para_stat->overlaps = 0; + para_stat->skips = 0; +} + +static void paranoia_callback(long inpos, int function); + +static void paranoia_callback(long inpos, int function) +{ + struct timeval thistime; + long test; + + switch (function) { + case -2: + para_stat->v_sector = inpos / CD_FRAMEWORDS; + return; + case -1: + para_stat->last_heartbeatstate = 8; + para_stat->heartbeat = '*'; + para_stat->slevel = 0; + para_stat->v_sector = inpos / CD_FRAMEWORDS; + break; + case PARANOIA_CB_VERIFY: + if (para_stat->stimeout >= 30) { + if (para_stat->curoverlap > CD_FRAMEWORDS) { + para_stat->slevel = 2; + } else { + para_stat->slevel = 1; + } + } + para_stat->verifies++; + break; + case PARANOIA_CB_READ: + if (inpos / CD_FRAMEWORDS > para_stat->c_sector) { + para_stat->c_sector = inpos / CD_FRAMEWORDS; + } + para_stat->reads++; + break; + case PARANOIA_CB_FIXUP_EDGE: + if (para_stat->stimeout >= 5) { + if (para_stat->curoverlap > CD_FRAMEWORDS) { + para_stat->slevel = 2; + } else { + para_stat->slevel = 1; + } + } + para_stat->fixup_edges++; + break; + case PARANOIA_CB_FIXUP_ATOM: + if (para_stat->slevel < 3 || para_stat->stimeout > 5) { + para_stat->slevel = 3; + } + para_stat->fixup_atoms++; + break; + case PARANOIA_CB_READERR: + para_stat->slevel = 6; + para_stat->readerrs++; + break; + case PARANOIA_CB_SKIP: + para_stat->slevel = 8; + para_stat->skips++; + break; + case PARANOIA_CB_OVERLAP: + para_stat->curoverlap = inpos; + if (inpos > para_stat->maxoverlap) + para_stat->maxoverlap = inpos; + if (inpos < para_stat->minoverlap) + para_stat->minoverlap = inpos; + para_stat->overlaps++; + break; + case PARANOIA_CB_SCRATCH: + para_stat->slevel = 7; + para_stat->scratchs++; + break; + case PARANOIA_CB_DRIFT: + if (para_stat->slevel < 4 || para_stat->stimeout > 5) { + para_stat->slevel = 4; + } + para_stat->drifts++; + break; + case PARANOIA_CB_FIXUP_DROPPED: + para_stat->slevel = 5; + para_stat->fixup_droppeds++; + break; + case PARANOIA_CB_FIXUP_DUPED: + para_stat->slevel = 5; + para_stat->fixup_dupeds++; + break; + } + + gettimeofday(&thistime, NULL); + /* now in tenth of seconds. */ + test = thistime.tv_sec * 10 + thistime.tv_usec / 100000; + + if (para_stat->lasttime != test + || function == -1 + || para_stat->slastlevel != para_stat->slevel) { + + if (function == -1 + || para_stat->slastlevel != para_stat->slevel) { + + static const char hstates[] = " .o0O0o."; + + para_stat->lasttime = test; + para_stat->stimeout++; + + para_stat->last_heartbeatstate++; + if (para_stat->last_heartbeatstate > 7) { + para_stat->last_heartbeatstate = 0; + } + para_stat->heartbeat = hstates[para_stat->last_heartbeatstate]; + + if (function == -1) { + para_stat->heartbeat = '*'; + } + } + + if (para_stat->slastlevel != para_stat->slevel) { + para_stat->stimeout = 0; + } + para_stat->slastlevel = para_stat->slevel; + } + + if (para_stat->slevel < 8) { + para_stat->rip_smile_level = para_stat->slevel; + } else { + para_stat->rip_smile_level = 0; + } +} +#endif + +static long lSector; +static long lSector_p2; +static double rate = 44100.0 / UNDERSAMPLING; +static int bits = BITS_P_S; +static char fname[200]; +static const char *audio_type; +static long BeginAtSample; +static unsigned long SamplesToWrite; +static unsigned minover; +static unsigned maxover; + +static unsigned long calc_SectorBurst(void); +static unsigned long calc_SectorBurst() +{ + unsigned long SectorBurstVal; + + SectorBurstVal = min(global.nsectors, + (global.iloop + CD_FRAMESAMPLES-1) / CD_FRAMESAMPLES); + if ( lSector+(int)SectorBurst-1 >= lSector_p2 ) + SectorBurstVal = lSector_p2 - lSector; + return SectorBurstVal; +} + +/* if PERCENTAGE_PER_TRACK is defined, the percentage message will reach + * 100% every time a track end is reached or the time limit is reached. + * + * Otherwise if PERCENTAGE_PER_TRACK is not defined, the percentage message + * will reach 100% once at the very end of the last track. + */ +#define PERCENTAGE_PER_TRACK + +static int do_read(myringbuff *p, unsigned *total_unsuccessful_retries); +static int do_read(myringbuff *p, unsigned *total_unsuccessful_retries) +{ + unsigned char *newbuf; + int offset; + unsigned int added_size; + + /* how many sectors should be read */ + SectorBurst = calc_SectorBurst(); + +#ifdef USE_PARANOIA + if (global.paranoia_selected) { + int i; + + for (i = 0; i < SectorBurst; i++) { + void *dp; + + dp = paranoia_read_limited(global.cdp, paranoia_callback, + global.paranoia_parms.retries); +/* + { + char *err; + char *msg; + err = cdda_errors(global.cdp); + msg = cdda_messages(global.cdp); + if (err) { + fputs(err, stderr); + free(err); + } + if (msg) { + fputs(msg, stderr); + free(msg); + } + } +*/ + if (dp != NULL) { + memcpy(p->data + i*CD_FRAMESAMPLES, dp, + CD_FRAMESIZE_RAW); + } else { + fputs("E unrecoverable error!", stderr); + exit(READ_ERROR); + } + } + newbuf = (unsigned char *)p->data; + offset = 0; + set_offset(p,offset); + added_size = SectorBurst * CD_FRAMESAMPLES; + global.overlap = 0; + handle_inputendianess(p->data, added_size); + } else +#endif + { + unsigned int retry_count; +#define MAX_READRETRY 12 + + retry_count = 0; + do { + SCSI *usalp = get_scsi_p(); + int retval; +#ifdef DEBUG_READS +fprintf(stderr, "reading from %lu to %lu, overlap %u\n", lSector, lSector + SectorBurst -1, global.overlap); +#endif + +#ifdef DEBUG_BUFFER_ADDRESSES +fprintf(stderr, "%p %l\n", p->data, global.pagesize); +if (((unsigned)p->data) & (global.pagesize -1) != 0) { + fprintf(stderr, "Address %p is NOT page aligned!!\n", p->data); +} +#endif + + if (global.reads_illleadout != 0 && lSector > Get_StartSector(LastTrack())) { + int singles = 0; + UINT4 bufferSub[CD_FRAMESAMPLES + 24]; + + /* we switch to single sector reads, + * in order to handle the remaining sectors. */ + usalp->silent++; + do { + ReadCdRomSub( usalp, bufferSub, lSector+singles, 1 ); + *eorecording = RealEnd( usalp, bufferSub ); + if (*eorecording) { + break; + } + memcpy(p->data+singles*CD_FRAMESAMPLES, bufferSub, CD_FRAMESIZE_RAW); + singles++; + } while (singles < SectorBurst); + usalp->silent--; + + if ( *eorecording ) { + patch_real_end(lSector+singles); + SectorBurst = singles; +#if DEBUG_ILLLEADOUT +fprintf(stderr, "iloop=%11lu, nSamplesToDo=%11lu, end=%lu -->\n", +global.iloop, *nSamplesToDo, lSector+singles); +#endif + + *nSamplesToDo -= global.iloop - SectorBurst*CD_FRAMESAMPLES; + global.iloop = SectorBurst*CD_FRAMESAMPLES; +#if DEBUG_ILLLEADOUT +fprintf(stderr, "iloop=%11lu, nSamplesToDo=%11lu\n\n", +global.iloop, *nSamplesToDo); +#endif + + } + } else { + retval = ReadCdRom( usalp, p->data, lSector, SectorBurst ); + } + handle_inputendianess(p->data, SectorBurst * CD_FRAMESAMPLES); + if (NULL == + (newbuf = synchronize( p->data, SectorBurst*CD_FRAMESAMPLES, + *nSamplesToDo-global.iloop ))) { + /* could not synchronize! + * Try to invalidate the cdrom cache. + * Increase overlap setting, if possible. + */ + /*trash_cache(p->data, lSector, SectorBurst);*/ + if (global.overlap < global.nsectors - 1) { + global.overlap++; + lSector--; + SectorBurst = calc_SectorBurst(); +#ifdef DEBUG_DYN_OVERLAP +fprintf(stderr, "using increased overlap of %u\n", global.overlap); +#endif + } else { + lSector += global.overlap - 1; + global.overlap = 1; + SectorBurst = calc_SectorBurst(); + } + } else + break; + } while (++retry_count < MAX_READRETRY); + + if (retry_count == MAX_READRETRY && newbuf == NULL && global.verbose != 0) { + (*total_unsuccessful_retries)++; + } + + if (newbuf) { + offset = newbuf - ((unsigned char *)p->data); + } else { + offset = global.overlap * CD_FRAMESIZE_RAW; + } + set_offset(p,offset); + + /* how much has been added? */ + added_size = SectorBurst * CD_FRAMESAMPLES - offset/4; + + if (newbuf && *nSamplesToDo != global.iloop) { + minover = min(global.overlap, minover); + maxover = max(global.overlap, maxover); + + + /* should we reduce the overlap setting ? */ + if (offset > CD_FRAMESIZE_RAW && global.overlap > 1) { +#ifdef DEBUG_DYN_OVERLAP +fprintf(stderr, "decreasing overlap from %u to %u (jitter %d)\n", global.overlap, global.overlap-1, offset - (global.overlap)*CD_FRAMESIZE_RAW); +#endif + global.overlap--; + SectorBurst = calc_SectorBurst(); + } + } + } + if (global.iloop >= added_size) { + global.iloop -= added_size; + } else { + global.iloop = 0; + } + + lSector += SectorBurst - global.overlap; + +#if defined PERCENTAGE_PER_TRACK && defined HAVE_FORK_AND_SHAREDMEM + { + int as; + while ((as = Get_StartSector(current_track+1)) != -1 + && lSector >= as) { + current_track++; + } + } +#endif + + return offset; +} + +static void +print_percentage(unsigned *poper, int c_offset); + +static void print_percentage(unsigned *poper, int c_offset) +{ + unsigned per; +#ifdef PERCENTAGE_PER_TRACK + /* Thomas Niederreiter wants percentage per track */ + unsigned start_in_track = max(BeginAtSample, + Get_AudioStartSector(current_track)*CD_FRAMESAMPLES); + + per = min(BeginAtSample + (long)*nSamplesToDo, + Get_StartSector(current_track+1)*CD_FRAMESAMPLES) + - (long)start_in_track; + + per = (BeginAtSample+nSamplesDone + - start_in_track + )/(per/100); + +#else + per = global.iloop ? (nSamplesDone)/(*nSamplesToDo/100) : 100; +#endif + + if (global.overlap > 0) { + fprintf(stderr, "\r%2d/%2d/%2d/%7d %3d%%", + minover, maxover, global.overlap, + c_offset - global.overlap*CD_FRAMESIZE_RAW, + per); + } else if (*poper != per) { + fprintf(stderr, "\r%3d%%", per); + } + *poper = per; + fflush(stderr); +} + +static unsigned long do_write(myringbuff *p); +static unsigned long do_write(myringbuff *p) +{ + int current_offset; + unsigned int InSamples; + static unsigned oper = 200; + + current_offset = get_offset(p); + + /* how many bytes are available? */ + InSamples = global.nsectors*CD_FRAMESAMPLES - current_offset/4; + /* how many samples are wanted? */ + InSamples = min((*nSamplesToDo-nSamplesDone),InSamples); + + /* when track end is reached, close current file and start a new one */ + while ((nSamplesDone < *nSamplesToDo) && (InSamples != 0)) { + long unsigned int how_much = InSamples; + + long int left_in_track; + left_in_track = Get_StartSector(current_track+1)*CD_FRAMESAMPLES + - (int)(BeginAtSample+nSamplesDone); + + if (*eorecording != 0 && current_track == cdtracks+1 && + (*total_segments_read) == (*total_segments_written)+1) { + /* limit, if the actual end of the last track is + * not known from the toc. */ + left_in_track = InSamples; + } + +if (left_in_track < 0) { + fprintf(stderr, "internal error: negative left_in_track:%ld, current_track=%d\n",left_in_track, current_track); +} + + if (bulk) { + how_much = min(how_much, (unsigned long) left_in_track); + } + +#ifdef MD5_SIGNATURES + if (global.md5count) { + MD5Update (&global.context, ((unsigned char *)p->data) +current_offset, min(global.md5count,how_much)); + global.md5count -= min(global.md5count,how_much); + } +#endif + if ( SaveBuffer ( p->data + current_offset/4, + how_much, + &nSamplesDone) ) { + if (global.have_forked == 1) { + pid_t ppid; + /* + * Kill the parent too if we are not orphaned. + */ + ppid = getppid(); + if (ppid > 1) + kill(ppid, SIGINT); + } + exit(WRITE_ERROR); + } + + global.nSamplesDoneInTrack += how_much; + SamplesToWrite -= how_much; + + /* move residual samples upto buffer start */ + if (how_much < InSamples) { + memmove( + (char *)(p->data) + current_offset, + (char *)(p->data) + current_offset + how_much*4, + (InSamples - how_much) * 4); + } + + if ((unsigned long) left_in_track <= InSamples || SamplesToWrite == 0) { + /* the current portion to be handled is + the end of a track */ + + if (bulk) { + /* finish sample file for this track */ + CloseAudio(global.channels, + global.nSamplesDoneInTrack, global.audio_out); + } else if (SamplesToWrite == 0) { + /* finish sample file for this track */ + CloseAudio(global.channels, + (unsigned int) *nSamplesToDo, global.audio_out); + } + + if (global.verbose) { +#ifdef USE_PARANOIA + double f; +#endif + print_percentage(&oper, current_offset); + fputc(' ', stderr); +#ifndef THOMAS_SCHAU_MAL + if ((unsigned long)left_in_track > InSamples) { + fputs(" incomplete", stderr); + } +#endif + if (global.tracktitle[current_track] != NULL) { + fprintf( stderr, + " track %2u '%s' recorded", + current_track, + global.tracktitle[current_track]); + } else { + fprintf( stderr, + " track %2u recorded", + current_track); + } +#ifdef USE_PARANOIA + oper = para_stat->readerrs + para_stat->skips + + para_stat->fixup_edges + para_stat->fixup_atoms + + para_stat->fixup_droppeds + para_stat->fixup_dupeds + + para_stat->drifts; + f = (100.0 * oper) / (((double)global.nSamplesDoneInTrack)/588.0); + + if (para_stat->readerrs) { + fprintf(stderr, " with audible hard errors"); + } else if ((para_stat->skips) > 0) { + fprintf(stderr, " with %sretry/skip errors", + f < 2.0 ? "":"audible "); + } else if (oper > 0) { + oper = f; + + fprintf(stderr, " with "); + if (oper < 2) + fprintf(stderr, "minor"); + else if (oper < 10) + fprintf(stderr, "medium"); + else if (oper < 67) + fprintf(stderr, "noticable audible"); + else if (oper < 100) + fprintf(stderr, "major audible"); + else + fprintf(stderr, "extreme audible"); + fprintf(stderr, " problems"); + } else { + fprintf(stderr, " successfully"); + } + if (f >= 0.1) + fprintf(stderr, " (%.1f%% problem sectors)", f); +#else + fprintf(stderr, " successfully"); +#endif + + if (waitforsignal == 1) { + fprintf(stderr, ". %d silent samples omitted", global.SkippedSamples); + } + fputs("\n", stderr); + + if (global.reads_illleadout && *eorecording == 1) { + fprintf(stderr, "Real lead out at: %ld sectors\n", + (*nSamplesToDo+BeginAtSample)/CD_FRAMESAMPLES); + } +#ifdef USE_PARANOIA + if (global.paranoia_selected) { + oper = 200; /* force new output */ + print_percentage(&oper, current_offset); + if (para_stat->minoverlap == 0x7FFFFFFF) + para_stat->minoverlap = 0; + fprintf(stderr, " %u rderr, %u skip, %u atom, %u edge, %u drop, %u dup, %u drift\n" + ,para_stat->readerrs + ,para_stat->skips + ,para_stat->fixup_atoms + ,para_stat->fixup_edges + ,para_stat->fixup_droppeds + ,para_stat->fixup_dupeds + ,para_stat->drifts); + oper = 200; /* force new output */ + print_percentage(&oper, current_offset); + fprintf(stderr, " %u overlap(%.4g .. %.4g)\n", + para_stat->overlaps, + (float)para_stat->minoverlap / (2352.0/2.0), + (float)para_stat->maxoverlap / (2352.0/2.0)); + paranoia_reset(); + } +#endif + } + + global.nSamplesDoneInTrack = 0; + if ( bulk && SamplesToWrite > 0 ) { + if ( !global.no_file ) { + char *tmp_fname; + + /* build next filename */ + tmp_fname = get_next_name(); + if (tmp_fname != NULL) { + strncpy(global.fname_base, + tmp_fname, + sizeof global.fname_base); + global.fname_base[ + sizeof(global.fname_base)-1] = + '\0'; + } + + tmp_fname = cut_extension(global.fname_base); + tmp_fname[0] = '\0'; + + if (global.multiname == 0) { + sprintf(fname, "%s_%02u.%s", + global.fname_base, + current_track+1, + audio_type); + } else { + sprintf(fname, "%s.%s", + global.fname_base, + audio_type); + } + + OpenAudio( fname, rate, bits, global.channels, + (Get_AudioStartSector(current_track+1) - + Get_AudioStartSector(current_track)) + *CD_FRAMESIZE_RAW, + global.audio_out); + } /* global.nofile */ + } /* if ( bulk && SamplesToWrite > 0 ) */ + current_track++; + + } /* left_in_track <= InSamples */ + InSamples -= how_much; + + } /* end while */ + if (!global.quiet && *nSamplesToDo != nSamplesDone) { + print_percentage(&oper, current_offset); + } + return nSamplesDone; +} + +#define PRINT_OVERLAP_INIT \ + if (global.verbose) { \ + if (global.overlap > 0) \ + fprintf(stderr, "overlap:min/max/cur, jitter, percent_done:\n / / / 0%%"); \ + else \ + fputs("percent_done:\n 0%", stderr); \ + } + +#if defined HAVE_FORK_AND_SHAREDMEM +static void forked_read(void); + +/* This function does all audio cdrom reads + * until there is nothing more to do + */ +static void forked_read() +{ + unsigned total_unsuccessful_retries = 0; + +#if !defined(HAVE_SEMGET) || !defined(USE_SEMAPHORES) + init_child(); +#endif + + minover = global.nsectors; + + PRINT_OVERLAP_INIT + while (global.iloop) { + + do_read(get_next_buffer(), &total_unsuccessful_retries); + + define_buffer(); + + } /* while (global.iloop) */ + + if (total_unsuccessful_retries) { + fprintf(stderr,"%u unsuccessful matches while reading\n",total_unsuccessful_retries); + } +} + +static void forked_write(void); + +static void forked_write() +{ + + /* don't need these anymore. Good security policy says we get rid + of them ASAP */ + priv_off(); + neverneedroot(); + neverneedgroup(); + +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) +#else + init_parent(); +#endif + + for (;nSamplesDone < *nSamplesToDo;) { + if (*eorecording == 1 && (*total_segments_read) == (*total_segments_written)) break; + + /* get oldest buffers */ + + nSamplesDone = do_write(get_oldest_buffer()); + + drop_buffer(); + + } /* end for */ + +} +#endif + +/* This function implements the read and write calls in one loop (in case + * there is no fork/thread_create system call). + * This means reads and writes have to wait for each other to complete. + */ +static void nonforked_loop(void); + +static void nonforked_loop() +{ + unsigned total_unsuccessful_retries = 0; + + minover = global.nsectors; + + PRINT_OVERLAP_INIT + while (global.iloop) { + + do_read(get_next_buffer(), &total_unsuccessful_retries); + + do_write(get_oldest_buffer()); + + } + + if (total_unsuccessful_retries) { + fprintf(stderr,"%u unsuccessful matches while reading\n",total_unsuccessful_retries); + } + +} + +void verbose_usage(void); + +void verbose_usage() +{ + fputs("\ + help lists all verbose options.\n\ + disable disables verbose mode.\n\ + all enables all verbose options.\n\ + toc display the table of contents.\n\ + summary display a summary of track parameters.\n\ + indices retrieve/display index positions.\n\ + catalog retrieve/display media catalog number.\n\ + trackid retrieve/display international standard recording code.\n\ + sectors display the start sectors of each track.\n\ + titles display any known track titles.\n\ +", stderr); +} + +#ifdef USE_PARANOIA +void paranoia_usage(void); + +void paranoia_usage() +{ + fputs("\ + help lists all paranoia options.\n\ + disable disables paranoia mode. Paranoia is still being used.\n\ + no-verify switches verify off, and overlap on.\n\ + retries=amount set the number of maximum retries per sector.\n\ + overlap=amount set the number of sectors used for statical paranoia overlap.\n\ + minoverlap=amt set the min. number of sectors used for dynamic paranoia overlap.\n\ + maxoverlap=amt set the max. number of sectors used for dynamic paranoia overlap.\n\ +", stderr); +} +#endif + +int +handle_verbose_opts(char *optstr, long *flagp); + +int handle_verbose_opts(char *optstr, long *flagp) +{ + char *ep; + char *np; + int optlen; + + *flagp = 0; + while (*optstr) { + if ((ep = strchr(optstr, ',')) != NULL) { + optlen = ep - optstr; + np = ep + 1; + } else { + optlen = strlen(optstr); + np = optstr + optlen; + } + if (strncmp(optstr, "toc", optlen) == 0) { + *flagp |= SHOW_TOC; + } + else if (strncmp(optstr, "summary", optlen) == 0) { + *flagp |= SHOW_SUMMARY; + } + else if (strncmp(optstr, "indices", optlen) == 0) { + *flagp |= SHOW_INDICES; + } + else if (strncmp(optstr, "catalog", optlen) == 0) { + *flagp |= SHOW_MCN; + } + else if (strncmp(optstr, "trackid", optlen) == 0) { + *flagp |= SHOW_ISRC; + } + else if (strncmp(optstr, "sectors", optlen) == 0) { + *flagp |= SHOW_STARTPOSITIONS; + } + else if (strncmp(optstr, "titles", optlen) == 0) { + *flagp |= SHOW_TITLES; + } + else if (strncmp(optstr, "all", optlen) == 0) { + *flagp |= SHOW_MAX; + } + else if (strncmp(optstr, "disable", optlen) == 0) { + *flagp = 0; + } + else if (strncmp(optstr, "help", optlen) == 0) { + verbose_usage(); + exit(NO_ERROR); + } + else { + char *endptr; + unsigned arg = strtoul(optstr, &endptr, 10); + if (optstr != endptr + && arg <= SHOW_MAX) { + *flagp |= arg; + fprintf(stderr, "Warning: numerical parameters for -v are no more supported in the next releases!\n"); + } + else { + fprintf(stderr, "unknown option %s\n", optstr); + verbose_usage(); + exit(SYNTAX_ERROR); + } + } + optstr = np; + } + return 1; +} + + +int +handle_paranoia_opts(char *optstr, long *flagp); + +int handle_paranoia_opts(char *optstr, long *flagp) +{ +#ifdef USE_PARANOIA + char *ep; + char *np; + int optlen; + + while (*optstr) { + if ((ep = strchr(optstr, ',')) != NULL) { + optlen = ep - optstr; + np = ep + 1; + } else { + optlen = strlen(optstr); + np = optstr + optlen; + } + if (strncmp(optstr, "retries=", min(8,optlen)) == 0) { + char *eqp = strchr(optstr, '='); + int rets; + + astoi(eqp+1, &rets); + if (rets >= 0) { + global.paranoia_parms.retries = rets; + } + } + else if (strncmp(optstr, "overlap=", min(8, optlen)) == 0) { + char *eqp = strchr(optstr, '='); + int rets; + + astoi(eqp+1, &rets); + if (rets >= 0) { + global.paranoia_parms.overlap = rets; + } + } + else if (strncmp(optstr, "minoverlap=", min(11, optlen)) == 0) { + char *eqp = strchr(optstr, '='); + int rets; + + astoi(eqp+1, &rets); + if (rets >= 0) { + global.paranoia_parms.mindynoverlap = rets; + } + } + else if (strncmp(optstr, "maxoverlap=", min(11, optlen)) == 0) { + char *eqp = strchr(optstr, '='); + int rets; + + astoi(eqp+1, &rets); + if (rets >= 0) { + global.paranoia_parms.maxdynoverlap = rets; + } + } + else if (strncmp(optstr, "no-verify", optlen) == 0) { + global.paranoia_parms.disable_extra_paranoia = 1; + } + else if (strncmp(optstr, "disable", optlen) == 0) { + global.paranoia_parms.disable_paranoia = 1; + } + else if (strncmp(optstr, "help", optlen) == 0) { + paranoia_usage(); + exit(NO_ERROR); + } + else { + fprintf(stderr, "unknown option %s\n", optstr); + paranoia_usage(); + exit(SYNTAX_ERROR); + } + optstr = np; + } + return 1; +#else + fputs("lib paranoia support is not configured!\n", stderr); + return 0; +#endif +} + + +/* and finally: the MAIN program */ +int main(int argc, char *argv[]) +{ + long lSector_p1; + long sector_offset = 0; + unsigned long endtrack = 1; + double rectime = DURATION; + int cd_index = -1; + double int_part; + int littleendian = -1; + char *int_name; + static char *user_sound_device = ""; + char * env_p; + int tracks_included; + int moreargs; + + int_name = DEF_INTERFACE; + audio_type = AUDIOTYPE; + save_args(argc, argv); + + /* init global variables */ + init_globals(); +{ + int am_i_cdda2wav; + /* When being invoked as list_audio_tracks, just dump a list of + audio tracks. */ + am_i_cdda2wav = !(strlen(argv[0]) >= sizeof("list_audio_tracks")-1 + && !strcmp(argv[0]+strlen(argv[0])+1-sizeof("list_audio_tracks"),"list_audio_tracks")); + if (!am_i_cdda2wav) global.verbose = SHOW_JUSTAUDIOTRACKS; +} + /* Control those set-id privileges... */ + initsecurity(); + + env_p = getenv("CDDA_DEVICE"); + if (env_p != NULL) { + global.dev_name = env_p; + } + + env_p = getenv("CDDBP_SERVER"); + if (env_p != NULL) { + global.cddbp_server = env_p; + } + + env_p = getenv("CDDBP_PORT"); + if (env_p != NULL) { + global.cddbp_port = env_p; + } + +{ + int cac; + char *const*cav; + + BOOL version = FALSE; + BOOL help = FALSE; + char *channels = NULL; + int irate = -1; + char *divider = NULL; + char *trackspec = NULL; + char *duration = NULL; + + char *oendianess = NULL; + char *cendianess = NULL; + int cddbp = -1; + BOOL stereo = FALSE; + BOOL mono = FALSE; + BOOL domax = FALSE; + BOOL dump_rates = FALSE; + int userverbose = -1; + long paraopts = 0; + + cac = argc; + cav = argv; + cac--; + cav++; + if (getargs(&cac, &cav, opts + , &global.paranoia_selected + , handle_paranoia_opts, ¶opts + , &version + , &help, &help + + , &global.no_file, &global.no_file + , &dump_rates, &dump_rates + , &bulk, &bulk, &bulk + , &global.scsi_verbose, &global.scsi_verbose + + , &global.findminmax, &global.findminmax + , &global.findmono, &global.findmono + , &global.no_infofile, &global.no_infofile + + , &global.deemphasize, &global.deemphasize + , &global.just_the_toc, &global.just_the_toc + , &global.scsi_silent, &global.scsi_silent + + , &global.cddbp_server, &global.cddbp_port + , &global.scanbus + , &global.scandevs + , &global.dev_name, &global.dev_name, &global.dev_name + , &global.aux_name, &global.aux_name + , &int_name, &int_name + , &audio_type, &audio_type + + , &oendianess, &oendianess + , &cendianess, &cendianess + , &global.userspeed, &global.userspeed + + , &global.playback_rate, &global.playback_rate + , &global.md5blocksize, &global.md5blocksize + , &global.useroverlap, &global.useroverlap + , &user_sound_device, &user_sound_device + + , &cddbp, &cddbp + , &channels, &channels + , &bits, &bits + , &irate, &irate + , &global.gui, &global.gui + + , ÷r, ÷r + , &trackspec, &trackspec + , &cd_index, &cd_index + , &duration, &duration + , §or_offset, §or_offset + + , &global.nsectors, &global.nsectors + , handle_verbose_opts, &userverbose + , handle_verbose_opts, &userverbose + , &global.buffers, &global.buffers + + , &stereo, &stereo + , &mono, &mono + , &waitforsignal, &waitforsignal + , &global.echo, &global.echo + , &global.quiet, &global.quiet + , &domax, &domax + + ) < 0) { + errmsgno(EX_BAD, "Bad Option: %s.\n", cav[0]); + fputs ("use 'icedax -help' to get more information.\n", stderr); + exit (SYNTAX_ERROR); + } + if (getfiles(&cac, &cav, opts) == 0) + /* No more file type arguments */; + moreargs = cav - argv; + if (version) { + fprintf(stderr, "icedax " CDRKIT_VERSION "\n"); + exit(EXIT_SUCCESS); + } + if (help) { + usage(); + } + if (!global.scanbus) + cdr_defaults(&global.dev_name, NULL, NULL, NULL); + if (dump_rates) { /* list available rates */ + int ii; + + fputs("\ +Available rates are:\n\ +Rate Divider Rate Divider Rate Divider Rate Divider\n\ +" , stderr ); + for (ii = 1; ii <= 44100 / 880 / 2; ii++) { + long i2 = ii; + fprintf(stderr, "%7.1f %2ld %7.1f %2ld.5 ", + 44100.0/i2, i2, 44100.0/(i2+0.5), i2); + i2 += 25; + fprintf(stderr, "%7.1f %2ld %7.1f %2ld.5\n", + 44100.0/i2, i2, 44100.0/(i2+0.5), i2); + i2 -= 25; + } + exit(NO_ERROR); + } + if (channels) { + if (*channels == 's') { + global.channels = 2; + global.swapchannels = 1; + } else { + global.channels = strtol(channels, NULL, 10); + } + } + if (irate >= 0) { + rate = irate; + } + if (divider) { + double divider_d; + divider_d = strtod(divider , NULL); + if (divider_d > 0.0) { + rate = 44100.0 / divider_d; + } else { + fputs("E option -divider requires a nonzero, positive argument.\nSee -dump-rates.", stderr); + exit(SYNTAX_ERROR); + } + } + if (trackspec) { + char * endptr; + char * endptr2; + track = strtoul(trackspec, &endptr, 10 ); + endtrack = strtoul(endptr, &endptr2, 10 ); + if (endptr2 == endptr) { + endtrack = track; + } else if (track == endtrack) { + bulk = -1; + } + } + if (duration) { + char *end_ptr = NULL; + rectime = strtod(duration, &end_ptr ); + if (*end_ptr == 'f') { + rectime = rectime / 75.0; + /* TODO: add an absolute end of recording. */ +#if 0 + } else if (*end_ptr == 'F') { + rectime = rectime / 75.0; +#endif + } else if (*end_ptr != '\0') { + rectime = -1.0; + } + } + if (oendianess) { + if (strcasecmp(oendianess, "little") == 0) { + global.outputendianess = LITTLE; + } else if (strcasecmp(oendianess, "big") == 0) { + global.outputendianess = BIG; + } else { + usage2("wrong parameter '%s' for option -E", oendianess); + } + } + if (cendianess) { + if (strcasecmp(cendianess, "little") == 0) { + littleendian = 1; + } else if (strcasecmp(cendianess, "big") == 0) { + littleendian = 0; + } else if (strcasecmp(cendianess, "guess") == 0) { + littleendian = -2; + } else { + usage2("wrong parameter '%s' for option -C", cendianess); + } + } + if (cddbp >= 0) { + global.cddbp = 1 + cddbp; + } + if (stereo) { + global.channels = 2; + } + if (mono) { + global.channels = 1; + global.need_hostorder = 1; + } + if (global.echo) { +#ifdef ECHO_TO_SOUNDCARD + if (global.playback_rate != 100) { + RestrictPlaybackRate( global.playback_rate ); + } + global.need_hostorder = 1; +#else + fprintf(stderr, "There is no sound support compiled into %s.\n",argv[0]); + global.echo = 0; +#endif + } + if (global.quiet) { + global.verbose = 0; + } + if (domax) { + global.channels = 2; bits = 16; rate = 44100; + } + if (global.findminmax) { + global.need_hostorder = 1; + } + if (global.deemphasize) { + global.need_hostorder = 1; + } + if (global.just_the_toc) { + global.verbose = SHOW_MAX; + bulk = 1; + } + if (global.gui) { +#ifdef Thomas_will_es + global.no_file = 1; + global.no_infofile = 1; + global.verbose = SHOW_MAX; +#endif + global.no_cddbfile = 1; + } + if (global.no_file) { + global.no_infofile = 1; + global.no_cddbfile = 1; + } + if (global.no_infofile) { + global.no_cddbfile = 1; + } + if (global.md5blocksize) { +#ifdef MD5_SIGNATURES + fputs("MD5 signatures are currently broken! Sorry\n", stderr); +#else + fputs("MD5 signatures are currently broken! Sorry\n", stderr); +#endif + } + if (user_sound_device) { +#ifndef ECHO_TO_SOUNDCARD + fputs("There is no sound support configured!\n", stderr); +#endif + } + if (global.paranoia_selected) { + global.useroverlap = 0; + } + if (userverbose >= 0) { + global.verbose = userverbose; + } +} + + /* check all parameters */ + if (global.buffers < 1) { + usage2("Incorrect buffer setting: %d", global.buffers); + } + + if (global.nsectors < 1) { + usage2("Incorrect nsectors setting: %d", global.nsectors); + } + + if (global.verbose < 0 || global.verbose > SHOW_MAX) { + usage2("Incorrect verbose level setting: %d",global.verbose); + } + if (global.verbose == 0) global.quiet = 1; + + if ( rectime < 0.0 ) { + usage2("Incorrect recording time setting: %d.%02d", + (int)rectime, (int)(rectime*100+0.5) % 100); + } + + if ( global.channels != 1 && global.channels != 2 ) { + usage2("Incorrect channel setting: %d",global.channels); + } + + if ( bits != 8 && bits != 12 && bits != 16 ) { + usage2("Incorrect bits_per_sample setting: %d",bits); + } + + if ( rate < 827.0 || rate > 44100.0 ) { + usage2("Incorrect sample rate setting: %d.%02d", + (int)rate, ((int)rate*100) % 100); + } + + int_part = (double)(long) (2*44100.0 / rate); + + if (2*44100.0 / rate - int_part >= 0.5 ) { + int_part += 1.0; + fprintf( stderr, "Nearest available sample rate is %d.%02d Hertz\n", + 2*44100 / (int)int_part, + (2*4410000 / (int)int_part) % 100); + } + Halved = ((int) int_part) & 1; + rate = 2*44100.0 / int_part; + undersampling = (int) int_part / 2.0; + samples_to_do = undersampling; + + if (!strcmp((char *)int_name,"generic_scsi")) + interface = GENERIC_SCSI; + else if (!strcmp((char *)int_name,"cooked_ioctl")) + interface = COOKED_IOCTL; + else { + usage2("Incorrect interface setting: %s",int_name); + } + + /* check * init audio file */ + if (!strncmp(audio_type,"wav",3)) { + global.audio_out = &wavsound; + } else if (!strncmp(audio_type, "sun", 3) || !strncmp(audio_type, "au", 2)) { + /* Enhanced compatibility */ + audio_type = "au"; + global.audio_out = &sunsound; + } else if (!strncmp(audio_type, "cdr", 3) || + !strncmp(audio_type, "raw", 3)) { + global.audio_out = &rawsound; + } else if (!strncmp(audio_type, "aiff", 4)) { + global.audio_out = &aiffsound; + } else if (!strncmp(audio_type, "aifc", 4)) { + global.audio_out = &aifcsound; +#ifdef USE_LAME + } else if (!strncmp(audio_type, "mp3", 3)) { + global.audio_out = &mp3sound; + if (!global.quiet) { + unsigned char Lame_version[20]; + + fetch_lame_version(Lame_version); + fprintf(stderr, "Using LAME version %s.\n", Lame_version); + } + if (bits < 9) { + bits = 16; + fprintf(stderr, "Warning: sample size forced to 16 bit for MP3 format.\n"); + } +#endif /* USE_LAME */ + } else { + usage2("Incorrect audio type setting: %3s", audio_type); + } + + if (bulk == -1) bulk = 0; + + global.need_big_endian = global.audio_out->need_big_endian; + if (global.outputendianess != NONE) + global.need_big_endian = global.outputendianess == BIG; + + if (global.no_file) global.fname_base[0] = '\0'; + + if (!bulk) { + strcat(global.fname_base, "."); + strcat(global.fname_base, audio_type); + } + + /* If we need to calculate with samples or write them to a soundcard, + * we need a conversion to host byte order. + */ + if (global.channels != 2 + || bits != 16 + || rate != 44100) + global.need_hostorder = 1; + + /* Bad hack!! + * Remove for release 2.0 + * this is a bug compatibility feature. + */ + if (global.gui && global.verbose == SHOW_TOC) + global.verbose |= SHOW_STARTPOSITIONS | SHOW_SUMMARY | SHOW_TITLES; + + /* + * all options processed. + * Now a file name per track may follow + */ + argc2 = argc3 = argc - moreargs; + argv2 = argv + moreargs; + if ( moreargs < argc ) { + if (!strcmp(argv[moreargs],"-")) { +#ifdef NEED_O_BINARY + setmode(fileno(stdout), O_BINARY); +#endif + global.audio = dup (fileno(stdout)); + strncpy( global.fname_base, "standard_output", sizeof(global.fname_base) ); + global.fname_base[sizeof(global.fname_base)-1]=0; + } else if (!is_fifo(argv[moreargs])) { + /* we do have at least one argument */ + global.multiname = 1; + } + } + +#define SETSIGHAND(PROC, SIG, SIGNAME) if (signal(SIG, PROC) == SIG_ERR) \ + { fprintf(stderr, "cannot set signal %s handler\n", SIGNAME); exit(SETSIG_ERROR); } + SETSIGHAND(exit_wrapper, SIGINT, "SIGINT") + SETSIGHAND(exit_wrapper, SIGQUIT, "SIGQUIT") + SETSIGHAND(exit_wrapper, SIGTERM, "SIGTERM") + SETSIGHAND(exit_wrapper, SIGHUP, "SIGHUP") + + SETSIGHAND(set_nonforked, SIGPIPE, "SIGPIPE") + + /* setup interface and open cdrom device */ + /* request sychronization facilities and shared memory */ + SetupInterface( ); + + /* use global.useroverlap to set our overlap */ + if (global.useroverlap != -1) + global.overlap = global.useroverlap; + + /* check for more valid option combinations */ + + if (global.nsectors < 1+global.overlap) { + fprintf( stderr, "Warning: Setting #nsectors to minimum of %d, due to jitter correction!\n", global.overlap+1); + global.nsectors = global.overlap+1; + } + + if (global.overlap > 0 && global.buffers < 2) { + fprintf( stderr, "Warning: Setting #buffers to minimum of 2, due to jitter correction!\n"); + global.buffers = 2; + } + + /* Value of 'nsectors' must be defined here */ + + global.shmsize = 0; +#ifdef USE_PARANOIA + while (global.shmsize < sizeof (struct paranoia_statistics)) + global.shmsize += global.pagesize; +#endif + global.shmsize += 10*global.pagesize; /* XXX Der Speicherfehler ist nicht in libparanoia sondern in cdda2wav :-( */ + global.shmsize += HEADER_SIZE + ENTRY_SIZE_PAGE_AL * global.buffers; + +#if defined (HAVE_FORK_AND_SHAREDMEM) + /* + * The (void *) cast is to avoid a GCC warning like: + * warning: dereferencing type-punned pointer will break strict-aliasing rules + * which does not apply to this code. (void *) introduces a compatible + * intermediate type in the cast list. + */ + he_fill_buffer = request_shm_sem(global.shmsize, (unsigned char **)(void *)&he_fill_buffer); + if (he_fill_buffer == NULL) { + fprintf( stderr, "no shared memory available!\n"); + exit(SHMMEM_ERROR); + } +#else /* do not have fork() and shared memory */ + he_fill_buffer = malloc(global.shmsize); + if (he_fill_buffer == NULL) { + fprintf( stderr, "no buffer memory available!\n"); + exit(NOMEM_ERROR); + } +#endif +#ifdef USE_PARANOIA + { + int i = 0; + + para_stat = (struct paranoia_statistics *)he_fill_buffer; + while (i < sizeof (struct paranoia_statistics)) { + i += global.pagesize; + he_fill_buffer += global.pagesize; + global.shmsize -= global.pagesize; + } + } +#endif + + if (global.verbose != 0) + fprintf(stderr, + "%u bytes buffer memory requested, %d buffers, %d sectors\n", + global.shmsize, global.buffers, global.nsectors); + + /* initialize pointers into shared memory segment */ + last_buffer = he_fill_buffer + 1; + total_segments_read = (unsigned long *) (last_buffer + 1); + total_segments_written = total_segments_read + 1; + child_waits = (int *) (total_segments_written + 1); + parent_waits = child_waits + 1; + in_lendian = parent_waits + 1; + eorecording = in_lendian + 1; + *total_segments_read = *total_segments_written = 0; + nSamplesToDo = (unsigned long *)(eorecording + 1); + *eorecording = 0; + *in_lendian = global.in_lendian; + + set_total_buffers(global.buffers, sem_id); + + +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) + atexit ( free_sem ); +#endif + + /* + * set input endian default + */ + if (littleendian != -1) + *in_lendian = littleendian; + + /* get table of contents */ + cdtracks = ReadToc(); + if (cdtracks == 0) { + fprintf(stderr, "No track in table of contents! Aborting...\n"); + exit(MEDIA_ERROR); + } + + calc_cddb_id(); + calc_cdindex_id(); + +#if 1 + Check_Toc(); +#endif + + if (ReadTocText != NULL && FirstAudioTrack () != -1) { + ReadTocText(get_scsi_p()); + handle_cdtext(); + } + if ( global.verbose == SHOW_JUSTAUDIOTRACKS ) { + unsigned int z; + + for (z = 0; z < cdtracks; z++) + if (Get_Datatrack(z) == 0) + printf("%02d\t%06ld\n", Get_Tracknumber(z), Get_AudioStartSector(z)); + exit(NO_ERROR); + } + + if ( global.verbose != 0 ) { + fputs( "#icedax version ", stderr ); + fputs( VERSION, stderr ); +#if defined USE_POSIX_PRIORITY_SCHEDULING || defined HAVE_SYS_PRIOCNTL_H + fputs( ", real time sched.", stderr ); +#endif +#if defined ECHO_TO_SOUNDCARD + fputs( ", soundcard", stderr ); +#endif +#if defined USE_PARANOIA + fputs( ", libparanoia", stderr ); +#endif + fputs( " support\n", stderr ); + } + + FixupTOC(cdtracks + 1); + +#if 0 + if (!global.paranoia_selected) { + fprintf(stderr, "NICE\n"); + /* try to get some extra kicks */ + priv_on(); + needroot(0); +#if defined HAVE_SETPRIORITY + setpriority(PRIO_PROCESS, 0, -20); +#else +# if defined(HAVE_NICE) && (HAVE_NICE == 1) + nice(-20); +# endif +#endif + priv_off(); + dontneedroot(); + } +#endif + + /* switch cdrom to audio mode */ + EnableCdda (get_scsi_p(), 1, CD_FRAMESIZE_RAW); + + atexit ( CloseAll ); + + DisplayToc(); + if ( FirstAudioTrack () == -1 ) { + if (no_disguised_audiotracks()) { + FatalError ( "This disk has no audio tracks\n" ); + } + } + + Read_MCN_ISRC(); + + /* check if start track is in range */ + if ( track < 1 || track > cdtracks ) { + usage2("Incorrect start track setting: %d",track); + } + + /* check if end track is in range */ + if ( endtrack < track || endtrack > cdtracks ) { + usage2("Incorrect end track setting: %ld",endtrack); + } + + do { + lSector = Get_AudioStartSector ( track ); + lSector_p1 = Get_EndSector ( track ) + 1; + + if ( lSector < 0 ) { + if ( bulk == 0 ) { + FatalError ( "Track %d not found\n", track ); + } else { + fprintf(stderr, "Skipping data track %d...\n", track); + if (endtrack == track) endtrack++; + track++; + } + } + } while (bulk != 0 && track <= cdtracks && lSector < 0); + + if ((global.illleadout_cd == 0 || global.reads_illleadout != 0) && cd_index != -1) { + if (global.verbose && !global.quiet) { + global.verbose |= SHOW_INDICES; + } + sector_offset += ScanIndices( track, cd_index, bulk ); + } else { + cd_index = 1; + if (global.deemphasize || (global.verbose & SHOW_INDICES)) { + ScanIndices( track, cd_index, bulk ); + } + } + + lSector += sector_offset; + /* check against end sector of track */ + if ( lSector >= lSector_p1 ) { + fprintf(stderr, "W Sector offset %lu exceeds track size (ignored)\n", sector_offset ); + lSector -= sector_offset; + } + + if ( lSector < 0L ) { + fputs( "Negative start sector! Set to zero.\n", stderr ); + lSector = 0L; + } + + lSector_p2 = Get_LastSectorOnCd( track ); + if (bulk == 1 && track == endtrack && rectime == 0.0) + rectime = 99999.0; + if ( rectime == 0.0 ) { + /* set time to track time */ + *nSamplesToDo = (lSector_p1 - lSector) * CD_FRAMESAMPLES; + rectime = (lSector_p1 - lSector) / 75.0; + if (CheckTrackrange( track, endtrack) == 1) { + lSector_p2 = Get_EndSector ( endtrack ) + 1; + + if (lSector_p2 >= 0) { + rectime = (lSector_p2 - lSector) / 75.0; + *nSamplesToDo = (long)(rectime*44100.0 + 0.5); + } else { + fputs( "End track is no valid audio track (ignored)\n", stderr ); + } + } else { + fputs( "Track range does not consist of audio tracks only (ignored)\n", stderr ); + } + } else { + /* Prepare the maximum recording duration. + * It is defined as the biggest amount of + * adjacent audio sectors beginning with the + * specified track/index/offset. */ + + if ( rectime > (lSector_p2 - lSector) / 75.0 ) { + rectime = (lSector_p2 - lSector) / 75.0; + lSector_p1 = lSector_p2; + } + + /* calculate # of samples to read */ + *nSamplesToDo = (long)(rectime*44100.0 + 0.5); + } + + global.OutSampleSize = (1+bits/12); + if (*nSamplesToDo/undersampling == 0L) { + usage2("Time interval is too short. Choose a duration greater than %d.%02d secs!", + undersampling/44100, (int)(undersampling/44100) % 100); + } + if ( moreargs < argc ) { + if (!strcmp(argv[moreargs],"-") || is_fifo(argv[moreargs])) { + /* + * pipe mode + */ + if (bulk == 1) { + fprintf(stderr, "W Bulk mode is disabled while outputting to a %spipe\n", + is_fifo(argv[moreargs]) ? "named " : ""); + bulk = 0; + } + global.no_cddbfile = 1; + } + } + if (global.no_infofile == 0) { + global.no_infofile = 1; + if (global.channels == 1 || bits != 16 || rate != 44100) { + fprintf(stderr, "W Sample conversions disable generation of info files!\n"); + } else if (waitforsignal == 1) { + fprintf(stderr, "W Option -w 'wait for signal' disables generation of info files!\n"); + } else if (sector_offset != 0) { + fprintf(stderr, "W Using an start offset (option -o) disables generation of info files!\n"); + } else if (!bulk && + !((lSector == Get_AudioStartSector(track)) && + ((long)(lSector + rectime*75.0 + 0.5) == Get_EndSector(track) + 1))) { + fprintf(stderr, "W Duration is not set for complete tracks (option -d), this disables generation\n of info files!\n"); + } else { + global.no_infofile = 0; + } + } + + SamplesToWrite = *nSamplesToDo*2/(int)int_part; + + { + int first = FirstAudioTrack(); + tracks_included = Get_Track( + (unsigned) (lSector + *nSamplesToDo/CD_FRAMESAMPLES -1)) + - max((int)track,first) +1; + } + + if (global.multiname != 0 && moreargs + tracks_included > argc) { + global.multiname = 0; + } + + if ( !waitforsignal ) { + +#ifdef INFOFILES + if (!global.no_infofile) { + int i; + + for (i = track; i < (int)track + tracks_included; i++) { + unsigned minsec, maxsec; + char *tmp_fname; + + /* build next filename */ + + tmp_fname = get_next_name(); + if (tmp_fname != NULL) + strncpy( global.fname_base, tmp_fname, sizeof(global.fname_base)-8 ); + global.fname_base[sizeof(global.fname_base)-1]=0; + minsec = max(lSector, Get_AudioStartSector(i)); + maxsec = min(lSector + rectime*75.0 + 0.5, 1+Get_EndSector(i)); + if ((int)minsec == Get_AudioStartSector(i) && + (int)maxsec == 1+Get_EndSector(i)) { + write_info_file(global.fname_base,i,(maxsec-minsec)*CD_FRAMESAMPLES, bulk && global.multiname == 0); + } else { + fprintf(stderr, + "Partial length copy for track %d, no info file will be generated for this track!\n", i); + } + if (!bulk) break; + } + reset_name_iterator(); + } +#endif + + } + + if (global.just_the_toc) exit(NO_ERROR); + +#ifdef ECHO_TO_SOUNDCARD + if (user_sound_device[0] != '\0') { + set_snd_device(user_sound_device); + } + init_soundcard(rate, bits); +#endif /* ECHO_TO_SOUNDCARD */ + + if (global.userspeed > -1) + global.speed = global.userspeed; + + if (global.speed != 0 && SelectSpeed != NULL) { + SelectSpeed(get_scsi_p(), global.speed); + } + + current_track = track; + + if ( !global.no_file ) { + { + char *myfname; + + myfname = get_next_name(); + + if (myfname != NULL) { + strncpy( global.fname_base, myfname, sizeof(global.fname_base)-8 ); + global.fname_base[sizeof(global.fname_base)-1]=0; + } + } + + /* strip audio_type extension */ + { + char *cp = global.fname_base; + + cp = strrchr(cp, '.'); + if (cp == NULL) { + cp = global.fname_base + strlen(global.fname_base); + } + *cp = '\0'; + } + if (bulk && global.multiname == 0) { + sprintf(fname, "%s_%02u.%s",global.fname_base,current_track,audio_type); + } else { + sprintf(fname, "%s.%s",global.fname_base,audio_type); + } + + OpenAudio( fname, rate, bits, global.channels, + (unsigned)(SamplesToWrite*global.OutSampleSize*global.channels), + global.audio_out); + } + + global.Remainder = (75 % global.nsectors)+1; + + global.sh_bits = 16 - bits; /* shift counter */ + + global.iloop = *nSamplesToDo; + if (Halved && (global.iloop&1)) + global.iloop += 2; + + BeginAtSample = lSector * CD_FRAMESAMPLES; + +#if 1 + if ( (global.verbose & SHOW_SUMMARY) && !global.just_the_toc && + (global.reads_illleadout == 0 || + lSector+*nSamplesToDo/CD_FRAMESAMPLES + <= (unsigned) Get_AudioStartSector(cdtracks-1))) { + + fprintf(stderr, "samplefile size will be %lu bytes.\n", + global.audio_out->GetHdrSize() + + global.audio_out->InSizeToOutSize(SamplesToWrite*global.OutSampleSize*global.channels) ); + fprintf (stderr, "recording %d.%04d seconds %s with %d bits @ %5d.%01d Hz" + ,(int)rectime , (int)(rectime * 10000) % 10000, + global.channels == 1 ? "mono":"stereo", bits, (int)rate, (int)(rate*10)%10); + if (!global.no_file && *global.fname_base) + fprintf(stderr, " ->'%s'...", global.fname_base ); + fputs("\n", stderr); + } +#endif + +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) +#else + init_pipes(); +#endif + +#ifdef USE_PARANOIA + if (global.paranoia_selected) { + long paranoia_mode; + + global.cdp = paranoia_init(get_scsi_p(), global.nsectors); + + if (global.paranoia_parms.overlap >= 0) { + int overlap = global.paranoia_parms.overlap; + + if (overlap > global.nsectors - 1) + overlap = global.nsectors - 1; + paranoia_overlapset(global.cdp, overlap); + } + /* + * Default to a minimum of dynamic overlapping == 0.5 sectors. + * If we don't do this, we get the default from libparanoia + * which is approx. 0.1. + */ + if (global.paranoia_parms.mindynoverlap < 0) + paranoia_dynoverlapset(global.cdp, CD_FRAMEWORDS/2, -1); + paranoia_dynoverlapset(global.cdp, + global.paranoia_parms.mindynoverlap * CD_FRAMEWORDS, + global.paranoia_parms.maxdynoverlap * CD_FRAMEWORDS); + + paranoia_mode = PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP; + + if (global.paranoia_parms.disable_paranoia) { + paranoia_mode = PARANOIA_MODE_DISABLE; + } + if (global.paranoia_parms.disable_extra_paranoia) { + paranoia_mode |= PARANOIA_MODE_OVERLAP; + paranoia_mode &= ~PARANOIA_MODE_VERIFY; + } + /* not yet implemented */ + if (global.paranoia_parms.disable_scratch_detect) { + paranoia_mode &= ~(PARANOIA_MODE_SCRATCH|PARANOIA_MODE_REPAIR); + } + /* not yet implemented */ + if (global.paranoia_parms.disable_scratch_repair) { + paranoia_mode &= ~PARANOIA_MODE_REPAIR; + } + + paranoia_modeset(global.cdp, paranoia_mode); + if (global.verbose) + fprintf(stderr, "using lib paranoia for reading.\n"); + paranoia_seek(global.cdp, lSector, SEEK_SET); + paranoia_reset(); + } +#endif +#if defined(HAVE_FORK_AND_SHAREDMEM) + + /* Everything is set up. Now fork and let one process read cdda sectors + and let the other one store them in a wav file */ + + /* forking */ + child_pid = fork(); + if (child_pid > 0 && global.gui > 0 && global.verbose > 0) + fprintf( stderr, "child pid is %d\n", child_pid); + + /*********************** fork **************************************/ + if (child_pid == 0) { + /* child WRITER section */ + +#ifdef HAVE_AREAS + /* Under BeOS a fork() with shared memory does not work as + * it does under System V Rel. 4. The mapping of the child + * works with copy on write semantics, so changes do not propagate + * back and forth. The existing mapping has to be deleted + * and replaced by an clone without copy on write semantics. + * This is done with clone_area(...,B_CLONE_ADDRESS,...). + * Thanks to file support.c from the postgreSQL project. + */ + area_info inf; + int32 cook = 0; + /* iterate over all mappings to find our shared memory mapping. */ + while (get_next_area_info(0, &cook, &inf) == B_OK) + { + /* check the name of the mapping. */ + if (!strcmp(inf.name, AREA_NAME)) + { + void *area_address; + area_id area_parent; + + /* kill the cow mapping. */ + area_address = inf.address; + if (B_OK != delete_area(inf.area)) + { + fprintf(stderr, "delete_area: no valid area.\n"); + exit(SHMMEM_ERROR); + } + /* get the parent mapping. */ + area_parent = find_area(inf.name); + if (area_parent == B_NAME_NOT_FOUND) + { + fprintf(stderr, "find_area: no such area name.\n"); + exit(SHMMEM_ERROR); + } + /* clone the parent mapping without cow. */ + if (B_OK > clone_area("shm_child", &area_address, B_CLONE_ADDRESS, + B_READ_AREA | B_WRITE_AREA, area_parent)) + { + fprintf(stderr,"clone_area failed\n"); + exit(SHMMEM_ERROR); + } + } + } +#endif +#ifdef __EMX__ + if (DosGetSharedMem(he_fill_buffer, 3)) { + comerr("DosGetSharedMem() failed.\n"); + } +#endif + global.have_forked = 1; + forked_write(); +#ifdef __EMX__ + DosFreeMem(he_fill_buffer); + _exit(NO_ERROR); + /* NOTREACHED */ +#endif + exit_wrapper(NO_ERROR); + /* NOTREACHED */ + } else if (child_pid > 0) { + /* parent READER section */ + + global.have_forked = 1; + switch_to_realtime_priority(); + + forked_read(); +#ifdef HAVE_AREAS + { + area_id aid; + aid = find_area(AREA_NAME); + if (aid < B_OK) { + comerrno(aid, "find_area() failed.\n"); + } + delete_area(aid); + } +#endif +#ifdef __EMX__ + DosFreeMem(he_fill_buffer); +#endif + exit_wrapper(NO_ERROR); + /* NOTREACHED */ + } else + perror("fork error."); + +#endif + /* version without fork */ + { + global.have_forked = 0; +#if 0 + if (!global.paranoia_selected) { + fprintf(stderr, "REAL\n"); + switch_to_realtime_priority(); + } +#endif + fprintf(stderr, "a nonforking version is running...\n"); + nonforked_loop(); + exit_wrapper(NO_ERROR); + /* NOTREACHED */ + } +#ifdef USE_PARANOIA + if (global.paranoia_selected) + paranoia_free(global.cdp); +#endif + + return 0; +} diff --git a/icedax/icedax.h b/icedax/icedax.h new file mode 100644 index 0000000..9795aac --- /dev/null +++ b/icedax/icedax.h @@ -0,0 +1,150 @@ +/* + * 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. + * + */ + +/* @(#)icedax.h 1.4 00/02/13 Copyright 1998,1999,2000 Heiko Eissfeldt */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Heiko Eissfeldt + * + * prototypes from cdda2wav.c + */ + +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + + +/* verbose levels */ +#define SHOW_TOC 1 +#define SHOW_SUMMARY 2 +#define SHOW_INDICES 4 +#define SHOW_MCN 8 +#define SHOW_ISRC 16 +#define SHOW_STARTPOSITIONS 32 +#define SHOW_TITLES 64 +#define SHOW_JUSTAUDIOTRACKS 128 +#define SHOW_MAX 255 + +/* Endianess */ +#define GUESS (-2) +#define NONE (-1) +#define LITTLE 0 +#define BIG 1 + +void FatalError(const char *szMessage, ...); +void AnalyzeQchannel(unsigned frame); +long SamplesNeeded(long amount, long undersampling); +unsigned int get_current_track(void); + +#if defined (sun) && !defined(SVR4) +#define atexit(f) on_exit(f, 0) +#endif + +#ifndef _LINUX_CDROM_H +#define _LINUX_CDROM_H + +/* + * some fix numbers + */ +#define CD_MINS 74 /* max. minutes per CD, not really a limit */ +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ + +#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame, not transfered by the drive */ +#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */ +#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */ +#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */ +#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD)/* sync bytes + header of XA frame */ + +#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ +#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */ +/* most drives don't deliver everything: */ +#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /* 2340 */ +#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /* 2336 */ +/* Optics drive also has a 'read all' mode: */ +#define CD_FRAMESIZE_RAWER 2646 /* bytes per frame */ + +#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */ +#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */ +#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */ +#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */ + +#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */ +#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ + +#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */ +#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */ + +#define CD_FRAMESIZE_XA CD_FRAMESIZE_RAW1 /* obsolete name */ +#define CD_BLOCK_OFFSET CD_MSF_OFFSET /* obsolete name */ + +/* + * the raw frame layout: + * + * - audio (red): | audio_sample_bytes | + * | 2352 | + * + * - data (yellow, mode1): | sync - head - data - EDC - zero - ECC | + * | 12 - 4 - 2048 - 4 - 8 - 276 | + * + * - data (yellow, mode2): | sync - head - data | + * | 12 - 4 - 2336 | + * + * - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC | + * | 12 - 4 - 8 - 2048 - 4 - 276 | + * + * - XA data (green, mode2 form2): | sync - head - sub - data - EDC | + * | 12 - 4 - 8 - 2324 - 4 | + */ + + +/* + * CD-ROM address types (cdrom_tocentry.cdte_format) + */ +#if !defined CDROM_LBA +#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */ +#define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */ +#endif +/* + * bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) + */ +#define CDROM_DATA_TRACK 0x04 + +/* + * The leadout track is always 0xAA, regardless of # of tracks on disc + */ +#define CDROM_LEADOUT 0xAA + +/* + * audio states (from SCSI-2, but seen with other drives, too) + */ +#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */ +#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */ +#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */ +#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */ +#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */ +#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */ + +#ifdef FIVETWELVE +#define CDROM_MODE1_SIZE 512 +#else +#define CDROM_MODE1_SIZE 2048 +#endif /*FIVETWELVE*/ +#define CDROM_MODE2_SIZE 2336 + +#endif + diff --git a/icedax/inf2cdtext.pl b/icedax/inf2cdtext.pl new file mode 100755 index 0000000..483713f --- /dev/null +++ b/icedax/inf2cdtext.pl @@ -0,0 +1,241 @@ +#!/usr/bin/perl -w +# Copyright 2002 by Heiko Eißfeldt (Eissfeldt) +use strict; +use integer; + +# read all .inf files and generate the binary cdtext block +# for cdrecord. + +my @results; + +sub fill_packet +{ + my $ID = shift; + my $track = shift; + my $seq_nr = shift; + my $charpos = shift; + my $text = shift; + my $todo = shift; + + return if (!defined($$text)); + + my @packet = (); + push @packet, chr($ID); # track title, performer, ... + push @packet, chr($$track); + push @packet, chr($$seq_nr); + $$charpos = 15 if ($$charpos > 15); + push @packet, chr($$charpos); + + my $cp = 0; + my $tracks_inp = 0; + while (length($$text) + 1 < 12 - $cp) { + push @packet, split(//, $$text); + push @packet, chr(0); + $cp += length($$text) + 1; + $$charpos = 0; + $tracks_inp++; + + $$text = shift @$todo; + if ($#$todo < 1 && (!defined($$text) || $$text eq "") ) { + push @packet, (chr(0)) x (12 - $cp); + $$seq_nr++; + print_packet(@packet); + return; + } + $$text = "" if (!defined($$text)); + $$track++; + } + + # packet gets full + my $left = 12 - $cp; + if ($left > length($$text)) { + # title fits into packet + push @packet, split(//, $$text); + push @packet, chr(0); + $tracks_inp++; + print_packet(@packet); + + $$charpos = 0; + $$text = shift @$todo; + unless ((!defined($$text) || $$text eq "") && $#$todo < 1) { $$track++; } + $$seq_nr++; + } else { + # print current packet and more if more entries are present + push @packet, split(//, substr($$text, 0, $left)); + print_packet(@packet); + + $$text = substr($$text, $left); + $$charpos += $left; + $$seq_nr++; + } +} + +my @crctab =( + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +); + +sub add_crc +{ + # crc with polynomial: x^16 + x^12 + x^5 + 1 + # 1,0001,0000,0010,0001 + my $packref = shift; + my $crc = 0; + + foreach (@$packref) { + $crc = ($crc << 8) ^ $crctab[ + ( ($crc >> (16-8)) ^ ord($_) ) & 0xff + ]; + $crc &= 0xffff; + } + $$packref[16] = chr((($crc >> 8) & 0xff) ^ 0xff); + $$packref[17] = chr(($crc & 0xff) ^ 0xff); +} + +sub print_packet +{ + return if ($#_ < 1); + my @packet = (@_); + add_crc(\@packet); + if ($packet[0] ne chr(0x8f)) { + printf STDERR ("%02x "x4 ." "."%c "x12 ." "."%02x "x2), map( defined($_) ? ord($_) : "___undef", @packet ); + } else { + printf STDERR ("%02x "x4 ." "."%02x "x12 ." "."%02x "x2), map( defined($_) ? ord($_) : "___undef", @packet ); + } + printf STDERR "\n"; + push @results, @packet; +} + +my $defaultperformer = $ARGV[0] || die "usage: ", $^X, " defaultperformer_name\n"; +my $prefix = $ARGV[1] || "audio"; +@ARGV = glob("${prefix}_??.inf"); +my @albumtitles; +my @tracktitles; +my @performers; +my $ISRC; +my @ISRCs; +my $MCN; + +my $performer; +while (<>) { + if (/^Performer=\s+'(.*?)'$/) { + $performer = $1; + } + if (/^Albumtitle=\s+'(.*?)'$/) { + push @albumtitles, $1; + } + if (/^Tracktitle=\s+'(.*?)'$/) { + push @tracktitles, $1; + } + if (/^ISRC=\s+(\S+?)$/) { + $ISRC = $1; + } + if (/^MCN=\s+(\S+?)$/) { + $MCN = $1; + } + if (eof) { + close ARGV; + $performer = $defaultperformer if (!defined($performer)); + push @performers, $performer; + $performer = undef; + push @ISRCs, $ISRC; + $ISRC = undef; + } +} + +# +my $seq_nr = 0; + +my @todo; +my $text; +my $track; +my $charpos; + +# build cdtext packets + +# build track titles +@todo = ($albumtitles[0], @tracktitles); +$text = shift @todo; +$track = 0; +$charpos = 0; + +while ($#todo > 1 || defined($text)) { + fill_packet(0x80, \$track, \$seq_nr, \$charpos, \$text, \@todo); +} + +my $trackpacks = $seq_nr; # store for later reference +my $last_track = $track; + +# build performer entries +#@todo = ($performer) x (1 + scalar(@tracktitles)); +@todo = ($defaultperformer, @performers); +$text = shift @todo; +$track = 0; +$charpos = 0; + +while ($#todo > 1 || defined($text)) { + fill_packet(0x81, \$track, \$seq_nr, \$charpos, \$text, \@todo); +} + +my $perfpacks = $seq_nr - $trackpacks; # store for later reference + +# build ISRC entries +@todo = ($MCN, @ISRCs); +$text = shift @todo; +$track = 0; +$charpos = 0; + +while ($#todo > 1 || defined($text)) { + $text = "" if (!defined($text)); + fill_packet(0x8e, \$track, \$seq_nr, \$charpos, \$text, \@todo); +} + +my $isrcpacks = $seq_nr - $trackpacks - $perfpacks; # store for later reference + +# build size information blocks +my $size1 = chr(0) . chr(1) . chr($last_track) . chr(0) + . chr($trackpacks) . chr($perfpacks) . chr(0) x 5; +my $size2 = chr(0) x 6 . chr($isrcpacks) . chr(3) . chr($seq_nr+2) . chr(0) x 2; +my $size3 = chr(0) x 4 . chr(9); # hard coded language 09 = english +@todo = ($size1, $size2, $size3); +$text = shift @todo; +$track = 0; +$charpos = 0; + +while ((defined($text) && $text ne "") ) { + fill_packet(0x8f, \$track, \$seq_nr, \$charpos, \$text, \@todo); +} + +# write out the results +my $size = @results + 2; +print chr($size >> 8), chr($size & 0xff), chr(0), chr(0), @results; diff --git a/icedax/interface.c b/icedax/interface.c new file mode 100644 index 0000000..ef7278a --- /dev/null +++ b/icedax/interface.c @@ -0,0 +1,1050 @@ +/* + * 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. + * + */ + +/* @(#)interface.c 1.40 06/02/19 Copyright 1998-2002 Heiko Eissfeldt, Copyright 2006 J. Schilling */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) 1994-1997 Heiko Eissfeldt heiko@colossus.escape.de + * + * Interface module for cdrom drive access + * + * Two interfaces are possible. + * + * 1. using 'cooked' ioctls() (Linux only) + * : available for atapi, sbpcd and cdu31a drives only. + * + * 2. using the generic scsi device (for details see SCSI Prog. HOWTO). + * NOTE: a bug/misfeature in the kernel requires blocking signal + * SIGINT during SCSI command handling. Once this flaw has + * been removed, the sigprocmask SIG_BLOCK and SIG_UNBLOCK calls + * should removed, thus saving context switches. + * + * For testing purposes I have added a third simulation interface. + * + * Version 0.8: used experiences of Jochen Karrer. + * SparcLinux port fixes + * AlphaLinux port fixes + * + */ +#if 0 +#define SIM_CD +#endif + +#include "config.h" +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <errno.h> +#include <signal.h> +#include <fctldefs.h> +#include <assert.h> +#include <schily.h> +#include <device.h> + +#include <sys/ioctl.h> +#include <statdefs.h> + + +#include "mycdrom.h" +#include "lowlevel.h" +/* some include file locations have changed with newer kernels */ +#if defined (__linux__) +# if LINUX_VERSION_CODE > 0x10300 + 97 +# if LINUX_VERSION_CODE < 0x200ff +# include <linux/sbpcd.h> +# include <linux/ucdrom.h> +# endif +# if !defined(CDROM_SELECT_SPEED) +# include <linux/ucdrom.h> +# endif +# endif +#endif + +#include <usal/scsitransp.h> + +#include "mytype.h" +#include "byteorder.h" +#include "interface.h" +#include "icedax.h" +#include "semshm.h" +#include "setuid.h" +#include "ringbuff.h" +#include "toc.h" +#include "global.h" +#include "ioctl.h" +#include "exitcodes.h" +#include "scsi_cmds.h" + +#include <utypes.h> +#include <wodim.h> +#include "scsi_scan.h" + +unsigned interface; + +int trackindex_disp = 0; + +void priv_init(void); +void priv_on(void); +void priv_off(void); + +void (*EnableCdda)(SCSI *, int Switch, unsigned uSectorsize); +unsigned (*doReadToc)(SCSI *usalp); +void (*ReadTocText)(SCSI *usalp); +unsigned (*ReadLastAudio)(SCSI *usalp); +int (*ReadCdRom)(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +int (*ReadCdRomData)(SCSI *usalp, unsigned char *p, unsigned lSector, + unsigned SectorBurstVal); +int (*ReadCdRomSub)(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +subq_chnl *(*ReadSubChannels)(SCSI *usalp, unsigned lSector); +subq_chnl *(*ReadSubQ)(SCSI *usalp, unsigned char sq_format, + unsigned char track); +void (*SelectSpeed)(SCSI *usalp, unsigned speed); +int (*Play_at)(SCSI *usalp, unsigned int from_sector, unsigned int sectors); +int (*StopPlay)(SCSI *usalp); +void (*trash_cache)(UINT4 *p, unsigned lSector, unsigned SectorBurstVal); + +#if defined USE_PARANOIA +long cdda_read(void *d, void *buffer, long beginsector, long sectors); + +long cdda_read(void *d, void *buffer, long beginsector, long sectors) +{ + long ret = ReadCdRom(d, buffer, beginsector, sectors); + return ret; +} +#endif + +typedef struct string_len { + char *str; + unsigned int sl; +} mystring; + +static mystring drv_is_not_mmc[] = { + {"DEC RRD47 (C) DEC ",24}, +/* {"SONY CD-ROM CDU625 1.0",28}, */ + {NULL,0} /* must be last entry */ +}; + +static mystring drv_has_mmc_cdda[] = { + {"HITACHI CDR-7930",16}, +/* {"TOSHIBA CD-ROM XM-5402TA3605",28}, */ + {NULL,0} /* must be last entry */ +}; + +static int Is_a_Toshiba3401; + +int Toshiba3401(void); + +int Toshiba3401() +{ + return Is_a_Toshiba3401; +} + +/* hook */ +static void Dummy(void); +static void Dummy() +{ +} + +static SCSI *usalp; + +SCSI *get_scsi_p(void); + +SCSI *get_scsi_p() +{ + return usalp; +} + +#if !defined(SIM_CD) + +static void trash_cache_SCSI(UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); + +static void trash_cache_SCSI(UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + /* trash the cache */ + ReadCdRom(get_scsi_p(), p, find_an_off_sector(lSector, SectorBurstVal), min(global.nsectors,6)); +} + + + +static void Check_interface_for_device(struct stat *statstruct, + char *pdev_name); +static int OpenCdRom(char *pdev_name); + +static void SetupSCSI(void); + +static void SetupSCSI() +{ + unsigned char *p; + + if (interface != GENERIC_SCSI) { + /* unfortunately we have the wrong interface and are + * not able to change on the fly */ + fprintf(stderr, "The generic SCSI interface and devices are required\n"); + exit(SYNTAX_ERROR); + } + + /* do a test unit ready to 'init' the device. */ + TestForMedium(usalp); + + /* check for the correct type of unit. */ + p = Inquiry(usalp); + +#undef TYPE_ROM +#define TYPE_ROM 5 +#undef TYPE_WORM +#define TYPE_WORM 4 + if (p == NULL) { + fprintf(stderr, "Inquiry command failed. Aborting...\n"); + exit(DEVICE_ERROR); + } + + if ((*p != TYPE_ROM && *p != TYPE_WORM)) { + fprintf(stderr, "this is neither a scsi cdrom nor a worm device\n"); + exit(SYNTAX_ERROR); + } + + if (global.quiet == 0) { + fprintf(stderr, + "Type: %s, Vendor '%8.8s' Model '%16.16s' Revision '%4.4s' ", + *p == TYPE_ROM ? "ROM" : "WORM" + ,p+8 + ,p+16 + ,p+32); + } + /* generic Sony type defaults */ + density = 0x0; + accepts_fua_bit = -1; + EnableCdda = (void (*)(SCSI *, int, unsigned))Dummy; + ReadCdRom = ReadCdda12; + ReadCdRomSub = ReadCddaSubSony; + ReadCdRomData = (int (*)(SCSI *, unsigned char *, unsigned, unsigned))ReadStandardData; + ReadLastAudio = ReadFirstSessionTOCSony; + SelectSpeed = SpeedSelectSCSISony; + Play_at = Play_atSCSI; + StopPlay = StopPlaySCSI; + trash_cache = trash_cache_SCSI; + ReadTocText = ReadTocTextSCSIMMC; + doReadToc = ReadTocSCSI; + ReadSubQ = ReadSubQSCSI; + ReadSubChannels = NULL; + + /* check for brands and adjust special peculiaritites */ + + /* If your drive is not treated correctly, you can adjust some things + here: + + global.in_lendian: should be to 1, if the CDROM drive or CD-Writer + delivers the samples in the native byteorder of the audio cd + (LSB first). + HP CD-Writers need it set to 0. + NOTE: If you get correct wav files when using sox with the '-x' option, + the endianess is wrong. You can use the -C option to specify + the value of global.in_lendian. + + */ + + { + int mmc_code; + + usalp->silent ++; + allow_atapi(usalp, 1); + if (*p == TYPE_ROM) { + mmc_code = heiko_mmc(usalp); + } else { + mmc_code = 0; + } + usalp->silent --; + + /* Exceptions for drives that report incorrect MMC capability */ + if (mmc_code != 0) { + /* these drives are NOT capable of MMC commands */ + mystring *pp = drv_is_not_mmc; + while (pp->str != NULL) { + if (!strncmp(pp->str, (char *)p+8,pp->sl)) { + mmc_code = 0; + break; + } + pp++; + } + } + { + /* these drives flag themselves as non-MMC, but offer CDDA reading + only with a MMC method. */ + mystring *pp = drv_has_mmc_cdda; + while (pp->str != NULL) { + if (!strncmp(pp->str, (char *)p+8,pp->sl)) { + mmc_code = 1; + break; + } + pp++; + } + } + + switch (mmc_code) { + case 2: /* SCSI-3 cdrom drive with accurate audio stream */ + /* fall through */ + case 1: /* SCSI-3 cdrom drive with no accurate audio stream */ + /* fall through */ +lost_toshibas: + global.in_lendian = 1; + if (mmc_code == 2) + global.overlap = 0; + else + global.overlap = 1; + ReadCdRom = ReadCddaFallbackMMC; + ReadCdRomSub = ReadCddaSubSony; + ReadLastAudio = ReadFirstSessionTOCMMC; + SelectSpeed = SpeedSelectSCSIMMC; + ReadTocText = ReadTocTextSCSIMMC; + doReadToc = ReadTocMMC; + ReadSubChannels = ReadSubChannelsFallbackMMC; + if (!memcmp(p+8,"SONY CD-RW CRX100E 1.0", 27)) ReadTocText = NULL; + if (!global.quiet) fprintf(stderr, "MMC+CDDA\n"); + break; + case -1: /* "MMC drive does not support cdda reading, sorry\n." */ + doReadToc = ReadTocMMC; + if (!global.quiet) fprintf(stderr, "MMC-CDDA\n"); + /* FALLTHROUGH */ + case 0: /* non SCSI-3 cdrom drive */ + if (!global.quiet) fprintf(stderr, "no MMC\n"); + ReadLastAudio = NULL; + if (!memcmp(p+8,"TOSHIBA", 7) || + !memcmp(p+8,"IBM", 3) || + !memcmp(p+8,"DEC", 3)) { + /* + * older Toshiba ATAPI drives don't identify themselves as MMC. + * The last digit of the model number is '2' for ATAPI drives. + * These are treated as MMC. + */ + if (!memcmp(p+15, " CD-ROM XM-", 11) && p[29] == '2') { + goto lost_toshibas; + } + density = 0x82; + EnableCdda = EnableCddaModeSelect; + ReadSubChannels = ReadStandardSub; + ReadCdRom = ReadStandard; + SelectSpeed = SpeedSelectSCSIToshiba; + if (!memcmp(p+15, " CD-ROM XM-3401",15)) { + Is_a_Toshiba3401 = 1; + } + global.in_lendian = 1; + } else if (!memcmp(p+8,"IMS",3) || + !memcmp(p+8,"KODAK",5) || + !memcmp(p+8,"RICOH",5) || + !memcmp(p+8,"HP",2) || + !memcmp(p+8,"PHILIPS",7) || + !memcmp(p+8,"PLASMON",7) || + !memcmp(p+8,"GRUNDIG CDR100IPW",17) || + !memcmp(p+8,"MITSUMI CD-R ",13)) { + EnableCdda = EnableCddaModeSelect; + ReadCdRom = ReadStandard; + SelectSpeed = SpeedSelectSCSIPhilipsCDD2600; + + /* treat all of these as bigendian */ + global.in_lendian = 0; + + /* no overlap reading for cd-writers */ + global.overlap = 0; + } else if (!memcmp(p+8,"NRC",3)) { + SelectSpeed = NULL; + } else if (!memcmp(p+8,"YAMAHA",6)) { + EnableCdda = EnableCddaModeSelect; + SelectSpeed = SpeedSelectSCSIYamaha; + + /* no overlap reading for cd-writers */ + global.overlap = 0; + global.in_lendian = 1; + } else if (!memcmp(p+8,"PLEXTOR",7)) { + global.in_lendian = 1; + global.overlap = 0; + ReadLastAudio = ReadFirstSessionTOCSony; + ReadTocText = ReadTocTextSCSIMMC; + doReadToc = ReadTocSony; + ReadSubChannels = ReadSubChannelsSony; + } else if (!memcmp(p+8,"SONY",4)) { + global.in_lendian = 1; + if (!memcmp(p+16, "CD-ROM CDU55E",13)) { + ReadCdRom = ReadCddaMMC12; + } + ReadLastAudio = ReadFirstSessionTOCSony; + ReadTocText = ReadTocTextSCSIMMC; + doReadToc = ReadTocSony; + ReadSubChannels = ReadSubChannelsSony; + } else if (!memcmp(p+8,"NEC",3)) { + ReadCdRom = ReadCdda10; + ReadTocText = NULL; + SelectSpeed = SpeedSelectSCSINEC; + global.in_lendian = 1; + if (!memcmp(p+29,"5022.0r",3)) /* I assume all versions of the 502 require this? */ + global.overlap = 0; /* no overlap reading for NEC CD-ROM 502 */ + } else if (!memcmp(p+8,"MATSHITA",8)) { + ReadCdRom = ReadCdda12Matsushita; + global.in_lendian = 1; + } + } /* switch (get_mmc) */ + } + + + /* look if caddy is loaded */ + if (interface == GENERIC_SCSI) { + usalp->silent++; + while (!wait_unit_ready(usalp, 60)) { + fprintf(stderr,"load cdrom please and press enter"); + getchar(); + } + usalp->silent--; + } +} + +/* Check to see if the device will support SCSI generic commands. A + * better check than simply looking at the device name. Open the + * device, issue an inquiry. If they both succeed, there's a good + * chance that the device works... */ +#if defined(__linux__) +static int check_linux_scsi_interface(char *pdev_name) +{ + SCSI *dev = NULL; + unsigned char *p = NULL; + char errstr[80]; + + dev = usal_open(pdev_name, errstr, sizeof(errstr), 0, 0); + if (NULL == dev) + return EINVAL; + p = Inquiry(dev); + if (p) + { + usal_close(dev); + return 0; + } + usal_close(dev); + return EINVAL; +} +#endif + +/********************** General setup *******************************/ + +/* As the name implies, interfaces and devices are checked. We also + adjust nsectors, overlap, and interface for the first time here. + Any unnecessary privileges (setuid, setgid) are also dropped here. +*/ +static void Check_interface_for_device(struct stat *statstruct, char *pdev_name) +{ +#if defined(__linux__) + int is_scsi = 1; +#endif +#ifndef STAT_MACROS_BROKEN + if (!S_ISCHR(statstruct->st_mode) && + !S_ISBLK(statstruct->st_mode)) { + fprintf(stderr, "%s is not a device\n",pdev_name); + exit(SYNTAX_ERROR); + } +#endif + +/* Check what type of device we have */ +#if defined (__linux__) + if (check_linux_scsi_interface(pdev_name)) + is_scsi = 0; + if (interface == GENERIC_SCSI && !is_scsi) + { + fprintf(stderr, "device %s does not support generic_scsi; falling back to cooked_ioctl instead\n", pdev_name); + interface = COOKED_IOCTL; + } + if ((interface == COOKED_IOCTL) && + is_scsi && + (SCSI_GENERIC_MAJOR == major(statstruct->st_rdev))) + { + fprintf(stderr, "device %s is generic_scsi NOT cooked_ioctl\n", pdev_name); + interface = GENERIC_SCSI; + } +#else + +#if defined (HAVE_ST_RDEV) + switch (major(statstruct->st_rdev)) { +#if defined (__linux__) + case SCSI_GENERIC_MAJOR: /* generic */ +#else + default: /* ??? what is the proper value here */ +#endif +#ifndef STAT_MACROS_BROKEN +#if defined (__linux__) + if (!S_ISCHR(statstruct->st_mode)) { + fprintf(stderr, "%s is not a char device\n",pdev_name); + exit(SYNTAX_ERROR); + } + + if (interface != GENERIC_SCSI) { + fprintf(stderr, "wrong interface (cooked_ioctl) for this device (%s)\nset to generic_scsi\n", pdev_name); + interface = GENERIC_SCSI; + } +#endif +#else + default: /* ??? what is the proper value here */ +#endif + break; + +#if defined (__linux__) || defined (__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +#if defined (__linux__) + case SCSI_CDROM_MAJOR: /* scsi cd */ + default: /* for example ATAPI cds */ +#else +#if defined (__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +#if __FreeBSD_version >= 600021 + case 0: /* majors abandoned */ + /* FALLTHROUGH */ +#endif +#if __FreeBSD_version >= 501113 + case 4: /* GEOM */ + /* FALLTHROUGH */ +#endif + case 117: /* pre-GEOM atapi cd */ + if (!S_ISCHR(statstruct->st_mode)) { + fprintf(stderr, "%s is not a char device\n",pdev_name); + exit(SYNTAX_ERROR); + } + if (interface != COOKED_IOCTL) { + fprintf(stderr, +"cdrom device (%s) is not of type generic SCSI. \ +Setting interface to cooked_ioctl.\n", pdev_name); + interface = COOKED_IOCTL; + } + break; + case 19: /* first atapi cd */ +#endif +#endif + if (!S_ISBLK(statstruct->st_mode)) { + fprintf(stderr, "%s is not a block device\n",pdev_name); + exit(SYNTAX_ERROR); + } +#if defined (__linux__) +#if LINUX_VERSION_CODE >= 0x20600 + /* In Linux kernel 2.6 it is better to use the SCSI interface + * with the device. + */ + break; +#endif +#endif + if (interface != COOKED_IOCTL) { + fprintf(stderr, +"cdrom device (%s) is not of type generic SCSI. \ +Setting interface to cooked_ioctl.\n", pdev_name); + interface = COOKED_IOCTL; + } + + if (interface == COOKED_IOCTL) { + fprintf(stderr, "\nW: The cooked_ioctl interface is functionally very limited!!\n"); +#if defined (__linux__) + fprintf(stderr, "\nW: For good sampling quality simply use the generic SCSI interface!\n" + "For example dev=ATA:1,0,0\n"); +#endif + } + + break; +#endif + } +#endif +#endif + if (global.overlap >= global.nsectors) + global.overlap = global.nsectors-1; +} + +/* open the cdrom device */ +static int OpenCdRom(char *pdev_name) +{ + int retval = 0; + struct stat fstatstruct; + + /* The device (given by pdevname) can be: + a. an SCSI device specified with a /dev/xxx name, + b. an SCSI device specified with bus,target,lun numbers, + c. a non-SCSI device such as ATAPI or proprietary CDROM devices. + */ +#ifdef HAVE_IOCTL_INTERFACE + struct stat statstruct; + int have_named_device = 0; + + have_named_device = FALSE; + if (pdev_name) { + have_named_device = strchr(pdev_name, ':') == NULL + && memcmp(pdev_name, "/dev/", 5) == 0; + } + + if (have_named_device) { + if (stat(pdev_name, &statstruct)) { + fprintf(stderr, "cannot stat device %s\n", pdev_name); + exit(STAT_ERROR); + } else { + Check_interface_for_device( &statstruct, pdev_name ); + } + } +#endif + + if (interface == GENERIC_SCSI) { + char errstr[80]; + + priv_on(); + needroot(0); + needgroup(0); + /* + * Call usal_remote() to force loading the remote SCSI transport library + * code that is located in librusal instead of the dummy remote routines + * that are located inside libusal. + */ + usal_remote(); + if (pdev_name != NULL && + ((strncmp(pdev_name, "HELP", 4) == 0) || + (strncmp(pdev_name, "help", 4) == 0))) { + usal_help(stderr); + exit(NO_ERROR); + } + /* device name, debug, verboseopen */ + usalp = usal_open(pdev_name, errstr, sizeof(errstr), 0, 0); + + if (usalp == NULL) { + int err = geterrno(); + + errmsgno(err, "%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":""); + errmsgno(EX_BAD, "For possible targets try 'wodim -scanbus'.%s\n", + geteuid() ? " Make sure you are root.":""); + priv_off(); + dontneedgroup(); + dontneedroot(); +#if defined(sun) || defined(__sun) + fprintf(stderr, "On SunOS/Solaris make sure you have Joerg Schillings usal SCSI driver installed.\n"); +#endif +#if defined (__linux__) + fprintf(stderr, "Use the script scan_scsi.linux to find out more.\n"); +#endif + fprintf(stderr, "Probably you did not define your SCSI device.\n"); + fprintf(stderr, "Set the CDDA_DEVICE environment variable or use the -D option.\n"); + fprintf(stderr, "You can also define the default device in the Makefile.\n"); + fprintf(stderr, "For possible transport specifiers try 'wodim dev=help'.\n"); + exit(SYNTAX_ERROR); + } + usal_settimeout(usalp, 300); + usal_settimeout(usalp, 60); + usalp->silent = global.scsi_silent; + usalp->verbose = global.scsi_verbose; + + if (global.nsectors > (unsigned) usal_bufsize(usalp, 3*1024*1024)/CD_FRAMESIZE_RAW) + global.nsectors = usal_bufsize(usalp, 3*1024*1024)/CD_FRAMESIZE_RAW; + if (global.overlap >= global.nsectors) + global.overlap = global.nsectors-1; + + /* + * Newer versions of Linux seem to introduce an incompatible change + * and require root privileges or limit RLIMIT_MEMLOCK infinity + * in order to get a SCSI buffer in case we did call mlockall(MCL_FUTURE). + */ + init_scsibuf(usalp, global.nsectors*CD_FRAMESIZE_RAW); + priv_off(); + dontneedgroup(); + dontneedroot(); + + if (global.scandevs) { + list_devices(usalp, stdout, 0); + exit(0); + } + + if (global.scanbus) { + select_target(usalp, stdout); + exit(0); + } + } else { + needgroup(0); + retval = open(pdev_name,O_RDONLY +#ifdef linux + | O_NONBLOCK +#endif + ); + dontneedgroup(); + + if (retval < 0) { + fprintf(stderr, "while opening %s :", pdev_name); + perror(""); + exit(DEVICEOPEN_ERROR); + } + + /* Do final security checks here */ + if (fstat(retval, &fstatstruct)) { + fprintf(stderr, "Could not fstat %s (fd %d): ", pdev_name, retval); + perror(""); + exit(STAT_ERROR); + } + Check_interface_for_device( &fstatstruct, pdev_name ); + +#if defined HAVE_IOCTL_INTERFACE + /* Watch for race conditions */ + if (have_named_device + && (fstatstruct.st_dev != statstruct.st_dev || + fstatstruct.st_ino != statstruct.st_ino)) { + fprintf(stderr,"Race condition attempted in OpenCdRom. Exiting now.\n"); + exit(RACE_ERROR); + } +#endif + /* + * The structure looks like a desaster :-( + * We do this more than once as it is impossible to understand where + * the right place would be to do this.... + */ + if (usalp != NULL) { + usalp->verbose = global.scsi_verbose; + } + } + return retval; +} +#endif /* SIM_CD */ + +/******************* Simulation interface *****************/ +#if defined SIM_CD +#include "toc.h" +static unsigned long sim_pos=0; + +/* read 'SectorBurst' adjacent sectors of audio sectors + * to Buffer '*p' beginning at sector 'lSector' + */ +static int ReadCdRom_sim(SCSI *x, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +static int ReadCdRom_sim(SCSI *x, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + unsigned int loop=0; + Int16_t *q = (Int16_t *) p; + int joffset = 0; + + if (lSector > g_toc[cdtracks].dwStartSector || lSector + SectorBurstVal > g_toc[cdtracks].dwStartSector + 1) { + fprintf(stderr, "Read request out of bounds: %u - %u (%d - %d allowed)\n", + lSector, lSector + SectorBurstVal, 0, g_toc[cdtracks].dwStartSector); + } +#if 0 + /* jitter with a probability of jprob */ + if (random() <= jprob) { + /* jitter up to jmax samples */ + joffset = random(); + } +#endif + +#ifdef DEBUG_SHM + fprintf(stderr, ", last_b = %p\n", *last_buffer); +#endif + for (loop = lSector*CD_FRAMESAMPLES + joffset; + loop < (lSector+SectorBurstVal)*CD_FRAMESAMPLES + joffset; + loop++) { + *q++ = loop; + *q++ = ~loop; + } +#ifdef DEBUG_SHM + fprintf(stderr, "sim wrote from %p upto %p - 4 (%d), last_b = %p\n", + p, q, SectorBurstVal*CD_FRAMESAMPLES, *last_buffer); +#endif + sim_pos = (lSector+SectorBurstVal)*CD_FRAMESAMPLES + joffset; + return SectorBurstVal; +} + +static int Play_at_sim(SCSI *x, unsigned int from_sector, unsigned int sectors); +static int Play_at_sim(SCSI *x, unsigned int from_sector, unsigned int sectors) +{ + sim_pos = from_sector*CD_FRAMESAMPLES; + return 0; +} + +static unsigned sim_indices; + + +/* read the table of contents (toc) via the ioctl interface */ +static unsigned ReadToc_sim(SCSI *x, TOC *toc); +static unsigned ReadToc_sim(SCSI *x, TOC *toc) +{ + unsigned int scenario; + int scen[12][3] = { + {1,1,500}, + {1,2,500}, + {1,99,150*99}, + {2,1,500}, + {2,2,500}, + {2,99,150*99}, + {2,1,500}, + {5,2,500}, + {5,99,150*99}, + {99,1,1000}, + {99,2,1000}, + {99,99,150*99}, + }; + unsigned int i; + unsigned trcks; +#if 0 + fprintf(stderr, "select one of the following TOCs\n" + "0 : 1 track with 1 index\n" + "1 : 1 track with 2 indices\n" + "2 : 1 track with 99 indices\n" + "3 : 2 tracks with 1 index each\n" + "4 : 2 tracks with 2 indices each\n" + "5 : 2 tracks with 99 indices each\n" + "6 : 2 tracks (data and audio) with 1 index each\n" + "7 : 5 tracks with 2 indices each\n" + "8 : 5 tracks with 99 indices each\n" + "9 : 99 tracks with 1 index each\n" + "10: 99 tracks with 2 indices each\n" + "11: 99 tracks with 99 indices each\n" + ); + + do { + scanf("%u", &scenario); + } while (scenario > sizeof(scen)/2/sizeof(int)); +#else + scenario = 6; +#endif + /* build table of contents */ + +#if 0 + trcks = scen[scenario][0] + 1; + sim_indices = scen[scenario][1]; + + for (i = 0; i < trcks; i++) { + toc[i].bFlags = (scenario == 6 && i == 0) ? 0x40 : 0xb1; + toc[i].bTrack = i + 1; + toc[i].dwStartSector = i * scen[scenario][2]; + toc[i].mins = (toc[i].dwStartSector+150) / (60*75); + toc[i].secs = (toc[i].dwStartSector+150 / 75) % (60); + toc[i].frms = (toc[i].dwStartSector+150) % (75); + } + toc[i].bTrack = 0xaa; + toc[i].dwStartSector = i * scen[scenario][2]; + toc[i].mins = (toc[i].dwStartSector+150) / (60*75); + toc[i].secs = (toc[i].dwStartSector+150 / 75) % (60); + toc[i].frms = (toc[i].dwStartSector+150) % (75); +#else + { + int starts[15] = { 23625, 30115, 39050, 51777, 67507, + 88612, 112962, 116840, 143387, 162662, + 173990, 186427, 188077, 209757, 257120}; + trcks = 14 + 1; + sim_indices = 1; + + for (i = 0; i < trcks; i++) { + toc[i].bFlags = 0x0; + toc[i].bTrack = i + 1; + toc[i].dwStartSector = starts[i]; + toc[i].mins = (starts[i]+150) / (60*75); + toc[i].secs = (starts[i]+150 / 75) % (60); + toc[i].frms = (starts[i]+150) % (75); + } + toc[i].bTrack = 0xaa; + toc[i].dwStartSector = starts[i]; + toc[i].mins = (starts[i]) / (60*75); + toc[i].secs = (starts[i] / 75) % (60); + toc[i].frms = (starts[i]) % (75); + } +#endif + return --trcks; /* without lead-out */ +} + + +static subq_chnl *ReadSubQ_sim(SCSI *usalp, unsigned char sq_format, + unsigned char track); +/* request sub-q-channel information. This function may cause confusion + * for a drive, when called in the sampling process. + */ +static subq_chnl *ReadSubQ_sim(SCSI *usalp, unsigned char sq_format, + unsigned char track) +{ + subq_chnl *SQp = (subq_chnl *) (SubQbuffer); + subq_position *SQPp = (subq_position *) &SQp->data; + unsigned long sim_pos1; + unsigned long sim_pos2; + + if ( sq_format != GET_POSITIONDATA ) return NULL; /* not supported by sim */ + + /* simulate CDROMSUBCHNL ioctl */ + + /* copy to SubQbuffer */ + SQp->audio_status = 0; + SQp->format = 0xff; + SQp->control_adr = 0xff; + sim_pos1 = sim_pos/CD_FRAMESAMPLES; + sim_pos2 = sim_pos1 % 150; + SQp->track = (sim_pos1 / 5000) + 1; + SQp->index = ((sim_pos1 / 150) % sim_indices) + 1; + sim_pos1 += 150; + SQPp->abs_min = sim_pos1 / (75*60); + SQPp->abs_sec = (sim_pos1 / 75) % 60; + SQPp->abs_frame = sim_pos1 % 75; + SQPp->trel_min = sim_pos2 / (75*60); + SQPp->trel_sec = (sim_pos2 / 75) % 60; + SQPp->trel_frame = sim_pos2 % 75; + + return (subq_chnl *)(SubQbuffer); +} + +static void SelectSpeed_sim(SCSI *x, unsigned sp); +/* ARGSUSED */ +static void SelectSpeed_sim(SCSI *x, unsigned sp) +{ +} + +static void trash_cache_sim(UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); + +/* ARGSUSED */ +static void trash_cache_sim(UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ +} + +static void SetupSimCd(void); + +static void SetupSimCd() +{ + EnableCdda = (void (*)(SCSI *, int, unsigned))Dummy; + ReadCdRom = ReadCdRom_sim; + ReadCdRomData = (int (*)(SCSI *, unsigned char *, unsigned, unsigned))ReadCdRom_sim; + doReadToc = ReadToc_sim; + ReadTocText = NULL; + ReadSubQ = ReadSubQ_sim; + ReadSubChannels = NULL; + ReadLastAudio = NULL; + SelectSpeed = SelectSpeed_sim; + Play_at = Play_at_sim; + StopPlay = (int (*)(SCSI *))Dummy; + trash_cache = trash_cache_sim; + +} + +#endif /* def SIM_CD */ + +/* perform initialization depending on the interface used. */ +void SetupInterface() +{ +#if defined SIM_CD + fprintf( stderr, "SIMULATION MODE !!!!!!!!!!!\n"); +#else + /* ensure interface is setup correctly */ + global.cooked_fd = OpenCdRom ( global.dev_name ); +#endif + + global.pagesize = getpagesize(); + + /* request one sector for table of contents */ + bufferTOC = malloc( CD_FRAMESIZE_RAW + 96 ); /* assumes sufficient aligned addresses */ + /* SubQchannel buffer */ + SubQbuffer = malloc( 48 ); /* assumes sufficient aligned addresses */ + cmd = malloc( 18 ); /* assumes sufficient aligned addresses */ + if ( !bufferTOC || !SubQbuffer || !cmd ) { + fprintf( stderr, "Too low on memory. Giving up.\n"); + exit(NOMEM_ERROR); + } + +#if defined SIM_CD + usalp = malloc(sizeof(* usalp)); + if (usalp == NULL) { + FatalError("No memory for SCSI structure.\n"); + } + usalp->silent = 0; + SetupSimCd(); +#else + /* if drive is of type scsi, get vendor name */ + if (interface == GENERIC_SCSI) { + unsigned sector_size; + + SetupSCSI(); + sector_size = get_orig_sectorsize(usalp, &orgmode4, &orgmode10, &orgmode11); + if (!SCSI_emulated_ATAPI_on(usalp)) { + if ( sector_size != 2048 && set_sectorsize(usalp, 2048) ) { + fprintf( stderr, "Could not change sector size from %d to 2048\n", sector_size ); + } + } else { + sector_size = 2048; + } + + /* get cache setting */ + + /* set cache to zero */ + + } else { +#if defined (HAVE_IOCTL_INTERFACE) + usalp = malloc(sizeof(* usalp)); + if (usalp == NULL) { + FatalError("No memory for SCSI structure.\n"); + } + usalp->silent = 0; + SetupCookedIoctl( global.dev_name ); +#else + FatalError("Sorry, there is no known method to access the device.\n"); +#endif + } +#endif /* if def SIM_CD */ + /* + * The structure looks like a desaster :-( + * We do this more than once as it is impossible to understand where + * the right place would be to do this.... + */ + if (usalp != NULL) { + usalp->verbose = global.scsi_verbose; + } +} + +#ifdef HAVE_PRIV_H +#include <priv.h> +#endif + +void +priv_init() +{ +#ifdef HAVE_PRIV_SET + /* + * Give up privs we do not need anymore. + * We no longer need: + * file_dac_read,sys_devices,proc_priocntl,net_privaddr + */ + priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, PRIV_PROC_PRIOCNTL, + PRIV_NET_PRIVADDR, NULL); + priv_set(PRIV_OFF, PRIV_INHERITABLE, + PRIV_FILE_DAC_READ, PRIV_PROC_PRIOCNTL, + PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL); +#endif +} + +void +priv_on() +{ +#ifdef HAVE_PRIV_SET + /* + * Get back privs we may need now. + * We need: + * file_dac_read,sys_devices,proc_priocntl,net_privaddr + */ + priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, PRIV_PROC_PRIOCNTL, + PRIV_NET_PRIVADDR, NULL); +#endif +} + +void +priv_off() +{ +#ifdef HAVE_PRIV_SET + /* + * Give up privs we do not need anymore. + * We no longer need: + * file_dac_read,sys_devices,proc_priocntl,net_privaddr + */ + priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, PRIV_PROC_PRIOCNTL, + PRIV_NET_PRIVADDR, NULL); +#endif +} diff --git a/icedax/interface.h b/icedax/interface.h new file mode 100644 index 0000000..b285b71 --- /dev/null +++ b/icedax/interface.h @@ -0,0 +1,135 @@ +/* + * 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. + * + */ + +/* @(#)interface.h 1.14 06/02/19 Copyright 1998-2001 Heiko Eissfeldt, Copyright 2005-2006 J. Schilling */ + +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Heiko Eissfeldt + * + * header file interface.h for cdda2wav */ + +#ifndef CD_FRAMESIZE +#define CD_FRAMESIZE 2048 +#endif + +#ifndef CD_FRAMESIZE_RAW +#define CD_FRAMESIZE_RAW 2352 +#endif + +#define CD_FRAMESAMPLES (CD_FRAMESIZE_RAW / 4) + +extern unsigned interface; + +extern int trackindex_disp; +#ifndef NSECTORS +#define NSECTORS 75 +#endif + +/* interface types */ +#define GENERIC_SCSI 0 +#define COOKED_IOCTL 1 + +/* constants for sub-q-channel info */ +#define GET_ALL 0 +#define GET_POSITIONDATA 1 +#define GET_CATALOGNUMBER 2 +#define GET_TRACK_ISRC 3 + +typedef struct subq_chnl { + unsigned char reserved; + unsigned char audio_status; + unsigned short subq_length; + unsigned char format; + unsigned char control_adr; + unsigned char track; + unsigned char index; + unsigned char data[40]; /* this has subq_all, subq_position, + subq_catalog or subq_track_isrc format */ +} subq_chnl; + +typedef struct subq_all { + unsigned char abs_min; + unsigned char abs_sec; + unsigned char abs_frame; + unsigned char abs_reserved; + unsigned char trel_min; + unsigned char trel_sec; + unsigned char trel_frame; + unsigned char trel_reserved; + unsigned char mc_valid; /* MSB */ + unsigned char media_catalog_number[13]; + unsigned char zero; + unsigned char aframe; + unsigned char tc_valid; /* MSB */ + unsigned char track_ISRC[15]; +} subq_all; + +typedef struct subq_position { + unsigned char abs_reserved; + unsigned char abs_min; + unsigned char abs_sec; + unsigned char abs_frame; + unsigned char trel_reserved; + unsigned char trel_min; + unsigned char trel_sec; + unsigned char trel_frame; +} subq_position; + +typedef struct subq_catalog { + unsigned char mc_valid; /* MSB */ + unsigned char media_catalog_number[13]; + unsigned char zero; + unsigned char aframe; +} subq_catalog; + +typedef struct subq_track_isrc { + unsigned char tc_valid; /* MSB */ + unsigned char track_isrc[15]; +} subq_track_isrc; + +#if !defined NO_SCSI_STUFF + +struct TOC; + +/* cdrom access function pointer */ +extern void (*EnableCdda)(SCSI *usalp, int Switch, unsigned uSectorsize); +extern unsigned (*doReadToc)(SCSI *usalp); +extern void (*ReadTocText)(SCSI *usalp); +extern unsigned (*ReadLastAudio)(SCSI *usalp); +extern int (*ReadCdRom)(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +extern int (*ReadCdRomSub)(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +extern int (*ReadCdRomData)(SCSI *usalp, unsigned char *p, unsigned lSector, + unsigned SectorBurstVal); +extern subq_chnl *(*ReadSubQ)(SCSI *usalp, unsigned char sq_format, + unsigned char track); +extern subq_chnl *(*ReadSubChannels)(SCSI *usalp, unsigned lSector); +extern void (*SelectSpeed)(SCSI *usalp, unsigned speed); +extern int (*Play_at)(SCSI *usalp, unsigned from_sector, unsigned sectors); +extern int (*StopPlay)(SCSI *usalp); +extern void (*trash_cache)(UINT4 *p, unsigned lSector, unsigned SectorBurstVal); + +SCSI *get_scsi_p(void); +#endif + +extern unsigned char *bufferTOC; +extern subq_chnl *SubQbuffer; + + +void SetupInterface(void); +int Toshiba3401(void); + +void priv_init(void); +void priv_on(void); +void priv_off(void); diff --git a/icedax/ioctl.c b/icedax/ioctl.c new file mode 100644 index 0000000..c3bd627 --- /dev/null +++ b/icedax/ioctl.c @@ -0,0 +1,578 @@ +/* + * 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. + * + */ + +/* @(#)ioctl.c 1.22 06/02/19 Copyright 1998,1999,2000 Heiko Eissfeldt, Copyright 2006 J. Schilling */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) 1999 Heiko Eissfeldt heiko@colossus.escape.de + * + * Ioctl interface module for cdrom drive access + * + * Solaris ATAPI cdrom drives are untested! + * + */ +#include "config.h" +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <errno.h> +#include <signal.h> +#include <fctldefs.h> +#include <assert.h> + +#include <sys/ioctl.h> +#include <statdefs.h> +#include <schily.h> +#include <device.h> + +#include <usal/scsitransp.h> + +#include "mycdrom.h" +#include "lowlevel.h" +/* some include file locations have changed with newer kernels */ +#if defined (__linux__) +# if LINUX_VERSION_CODE > 0x10300 + 97 +# if LINUX_VERSION_CODE < 0x200ff +# include <linux/sbpcd.h> +# include <linux/ucdrom.h> +# endif +# if !defined(CDROM_SELECT_SPEED) +# include <linux/ucdrom.h> +# endif +# endif +#endif + +#include "mytype.h" +#include "byteorder.h" +#include "interface.h" +#include "toc.h" +#include "icedax.h" +#include "ioctl.h" +#include "global.h" +#include "exitcodes.h" + +#include <utypes.h> +#include <wodim.h> + +#if defined (HAVE_IOCTL_INTERFACE) +#if !defined(sun) && !defined(__sun) && !(defined(__FreeBSD__) && (__FreeBSD_version >= 501112)) +static struct cdrom_read_audio arg; +#endif + +#if (defined(__FreeBSD__) && __FreeBSD_version >= 400014) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +static unsigned sector_size; +#endif + +static int err; + +static void EnableCdda_cooked(SCSI *usalp, int fAudioMode, unsigned uSectorsize); +/* ARGSUSED */ +static void EnableCdda_cooked(SCSI *usalp, int fAudioMode, unsigned uSectorsize) +{ +#if (defined(__FreeBSD__) && __FreeBSD_version >= 400014) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + if (usalp && usalp->verbose) + fprintf(stderr, "EnableCdda_cooked (CDRIOCSETBLOCKSIZE)...\n"); + + if (fAudioMode) { + if (ioctl(global.cooked_fd, CDRIOCGETBLOCKSIZE, §or_size) ==-1) + sector_size = CD_FRAMESIZE; + ioctl(global.cooked_fd, CDRIOCSETBLOCKSIZE, &uSectorsize); + } else + ioctl(global.cooked_fd, CDRIOCSETBLOCKSIZE, §or_size); +#else +#if defined CDIOCSETCDDA + if (usalp && usalp->verbose) { + fprintf(stderr, "EnableCdda_cooked (CDIOCSETCDDA)...\n"); + if (uSectorsize != CD_FRAMESIZE_RAW) + fprintf(stderr, "non audio sector size is ignored.\n"); + } + + ioctl(global.cooked_fd, CDIOCSETCDDA, &fAudioMode); +#else + fprintf(stderr, "EnableCdda_cooked (CDIOCSETCDDA) is not available...\n"); +#endif +#endif + +} + + +static unsigned ReadToc_cooked(SCSI *x); + +/* read the table of contents (toc) via the ioctl interface */ +static unsigned ReadToc_cooked(SCSI *x) +{ + unsigned i; + unsigned tracks; + struct cdrom_tochdr hdr; + struct cdrom_tocentry entry[100]; + struct cdrom_tocentry entryMSF[100]; + + if (x && x->verbose) { + fprintf(stderr, "ReadToc_cooked (CDROMREADTOCHDR)...\n"); + } + + /* get TocHeader to find out how many entries there are */ + err = ioctl( global.cooked_fd, CDROMREADTOCHDR, &hdr ); + if ( err != 0 ) { + /* error handling */ + if (err == -1) { + if (errno == EPERM) + fprintf( stderr, "Please run this program setuid root.\n"); + perror("cooked: Read TOC "); + exit( DEVICE_ERROR ); + } else { + fprintf( stderr, "can't get TocHeader (error %d).\n", err ); + exit( MEDIA_ERROR ); + } + } + /* get all TocEntries */ + for ( i = 0; i < hdr.cdth_trk1; i++ ) { + entryMSF[i].cdte_track = 1+i; + entryMSF[i].cdte_format = CDROM_MSF; + err = ioctl( global.cooked_fd, CDROMREADTOCENTRY, &entryMSF[i] ); + if ( err != 0 ) { + /* error handling */ + fprintf( stderr, "can't get TocEntry #%d msf (error %d).\n", i+1, err ); + exit( MEDIA_ERROR ); + } + } + entryMSF[i].cdte_track = CDROM_LEADOUT; + entryMSF[i].cdte_format = CDROM_MSF; + err = ioctl( global.cooked_fd, CDROMREADTOCENTRY, &entryMSF[i] ); + if ( err != 0 ) { + /* error handling */ + fprintf( stderr, "can't get TocEntry LEADOUT msf (error %d).\n", err ); + exit( MEDIA_ERROR ); + } + tracks = hdr.cdth_trk1+1; +/* + for (i = 0; i < tracks; i++) { + toc[i].bFlags = (entry[i].cdte_adr << 4) | (entry[i].cdte_ctrl & 0x0f); + toc[i].bTrack = entry[i].cdte_track; + toc[i].mins = entry[i].cdte_addr.msf.minute; + toc[i].secs = entry[i].cdte_addr.msf.second; + toc[i].frms = entry[i].cdte_addr.msf.frame; + } +*/ + /* get all TocEntries now in lba format */ + for ( i = 0; i < hdr.cdth_trk1; i++ ) { + entry[i].cdte_track = 1+i; + entry[i].cdte_format = CDROM_LBA; + err = ioctl( global.cooked_fd, CDROMREADTOCENTRY, &entry[i] ); + if ( err != 0 ) { + /* error handling */ + fprintf( stderr, "can't get TocEntry #%d lba (error %d).\n", i+1, err ); + exit( MEDIA_ERROR ); + } +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + entry[i].cdte_addr.lba = be32_to_cpu(entry[i].cdte_addr.lba); +#endif + } + entry[i].cdte_track = CDROM_LEADOUT; + entry[i].cdte_format = CDROM_LBA; + err = ioctl( global.cooked_fd, CDROMREADTOCENTRY, &entry[i] ); + if ( err != 0 ) { + /* error handling */ + fprintf( stderr, "can't get TocEntry LEADOUT lba (error %d).\n", err ); + exit( MEDIA_ERROR ); + } +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + entry[i].cdte_addr.lba = be32_to_cpu(entry[i].cdte_addr.lba); +#endif + + for (i = 0; i < tracks; i++) { + toc_entry(i+1, + (entry[i].cdte_adr << 4) | (entry[i].cdte_ctrl & 0x0f), + entry[i].cdte_track, + NULL /* ISRC */, + entry[i].cdte_addr.lba, + entryMSF[i].cdte_addr.msf.minute, + entryMSF[i].cdte_addr.msf.second, + entryMSF[i].cdte_addr.msf.frame); + } + bufferTOC[0] = '\0'; + bufferTOC[1] = '\0'; + return --tracks; /* without lead-out */ +} + +static void trash_cache_cooked(UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); + +static void trash_cache_cooked(UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + /* trash the cache */ + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +#if defined(__FreeBSD__) && __FreeBSD_version >= 501112 + pread(global.cooked_fd, (void *) &p[0], 3*CD_FRAMESIZE_RAW, + find_an_off_sector(lSector, SectorBurstVal)*CD_FRAMESIZE_RAW); +#else + static struct cdrom_read_audio arg2; + + arg2.address.lba = find_an_off_sector(lSector, SectorBurstVal); + arg2.addr_format = CDROM_LBA; + arg2.nframes = 3; + arg2.buffer = (unsigned char *) &p[0]; + + ioctl(global.cooked_fd, CDROMREADAUDIO, &arg2); +#endif +#endif +#if defined __linux__ + static struct cdrom_read_audio arg2; + + arg2.addr.lba = find_an_off_sector(lSector, SectorBurstVal); + arg2.addr_format = CDROM_LBA; + arg2.nframes = 3; + arg2.buf = (unsigned char *) &p[0]; + + ioctl(global.cooked_fd, CDROMREADAUDIO, &arg2); +#endif +#if defined __sun || (defined HAVE_SYS_CDIO_H && defined CDROM_DA_NO_SUBCODE) + struct cdrom_cdda suncdda; + + suncdda.cdda_addr = lSector; + suncdda.cdda_length = SectorBurstVal*CD_FRAMESIZE_RAW; + suncdda.cdda_data = (char *) &p[0]; + suncdda.cdda_subcode = CDROM_DA_NO_SUBCODE; + + ioctl(global.cooked_fd, CDROMCDDA, &suncdda); +#endif +} + +static void ReadCdRomData_cooked(SCSI *x, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +/* read 'SectorBurst' adjacent sectors of data sectors + * to Buffer '*p' beginning at sector 'lSector' + */ +static void ReadCdRomData_cooked(SCSI *x, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + int retval; + + if (x && x->verbose) { + fprintf(stderr, "ReadCdRomData_cooked (lseek & read)...\n"); + } + + if ((retval = lseek(global.cooked_fd, lSector*CD_FRAMESIZE, SEEK_SET)) + != (int)lSector*CD_FRAMESIZE) { perror("cannot seek sector"); } + if ((retval = read(global.cooked_fd, p, SectorBurstVal*CD_FRAMESIZE)) + != (int)SectorBurstVal*CD_FRAMESIZE) { perror("cannot read sector"); } + + return; +} + +static int ReadCdRom_cooked(SCSI *x, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +/* read 'SectorBurst' adjacent sectors of audio sectors + * to Buffer '*p' beginning at sector 'lSector' + */ +static int ReadCdRom_cooked(SCSI *x, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + int retry_count=0; + static int nothing_read = 1; + +/* read 2352 bytes audio data */ +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +#if defined(__FreeBSD__) && __FreeBSD_version >= 501112 + if (x && x->verbose) { + fprintf(stderr, "ReadCdRom_cooked (pread)...\n"); + } + + do { + err = 0; + if (pread(global.cooked_fd, (void *) &p[0], SectorBurstVal*CD_FRAMESIZE_RAW, + lSector*CD_FRAMESIZE_RAW) == -1) + err = -1; +#else + arg.address.lba = lSector; + arg.addr_format = CDROM_LBA; + arg.nframes = SectorBurstVal; + arg.buffer = (unsigned char *) &p[0]; + + if (x && x->verbose) { + fprintf(stderr, "ReadCdRom_cooked (CDROMREADAUDIO)...\n"); + } + + do { + err = ioctl(global.cooked_fd, CDROMREADAUDIO, &arg); +#endif +#endif +#if defined __linux__ + arg.addr.lba = lSector; + arg.addr_format = CDROM_LBA; + arg.nframes = SectorBurstVal; + arg.buf = (unsigned char *) &p[0]; + + if (x && x->verbose) { + fprintf(stderr, "ReadCdRom_cooked (CDROMREADAUDIO)...\n"); + } + + do { + err = ioctl(global.cooked_fd, CDROMREADAUDIO, &arg); +#endif +#if defined __sun || (defined HAVE_SYS_CDIO_H && defined CDROM_DA_NO_SUBCODE) + struct cdrom_cdda suncdda; + + suncdda.cdda_addr = lSector; + suncdda.cdda_length = SectorBurstVal*CD_FRAMESIZE_RAW; + suncdda.cdda_data = (char *) &p[0]; + suncdda.cdda_subcode = CDROM_DA_NO_SUBCODE; + + if (x && x->verbose) { + fprintf(stderr, "ReadCdRom_cooked (CDROMCDDA)...\n"); + } + + do { + err = ioctl(global.cooked_fd, CDROMCDDA, &suncdda); +#endif + retry_count++; + + if (err) { + trash_cache_cooked(p, lSector, SectorBurstVal); + } + + } while ((err) && (retry_count < 30)); + if (err != 0) { + if (x->silent == 0) { + /* error handling */ + if (err == -1) { + if (nothing_read && (errno == EINVAL || errno == EIO)) + fprintf( stderr, "Sorry, this driver and/or drive does not support cdda reading.\n"); + perror("cooked: Read cdda "); + fprintf(stderr, " sector %u + %u, buffer %p + %x\n", lSector, SectorBurstVal, p, global.shmsize); + } else { + fprintf(stderr, "can't read frame #%u (error %d).\n", + lSector, err); + } + } + return SectorBurstVal - 1; + } else { + nothing_read = 0; + } + + return SectorBurstVal; +} + +static int StopPlay_cooked(SCSI *x); +static int StopPlay_cooked(SCSI *x) +{ + if (x && x->verbose) { + fprintf(stderr, "StopPlay_cooked (CDROMSTOP)...\n"); + } + + return ioctl( global.cooked_fd, CDROMSTOP, 0 ) ? 0 : -1; +} + +static int Play_at_cooked(SCSI *x, unsigned int from_sector, + unsigned int sectors); +static int Play_at_cooked(SCSI *x, unsigned int from_sector, + unsigned int sectors) +{ + struct cdrom_msf cmsf; + int retval; + + if (x && x->verbose) { + fprintf(stderr, "Play_at_cooked (CDROMSTART & CDROMPLAYMSF)... (%u-%u)", + from_sector, from_sector+sectors-1); + + fprintf(stderr, "\n"); + } + + cmsf.cdmsf_min0 = (from_sector + 150) / (60*75); + cmsf.cdmsf_sec0 = ((from_sector + 150) / 75) % 60; + cmsf.cdmsf_frame0 = (from_sector + 150) % 75; + cmsf.cdmsf_min1 = (from_sector + 150 + sectors) / (60*75); + cmsf.cdmsf_sec1 = ((from_sector + 150 + sectors) / 75) % 60; + cmsf.cdmsf_frame1 = (from_sector + 150 + sectors) % 75; + +#if 0 +/* makes index scanning under FreeBSD too slow */ + if (( retval = ioctl( global.cooked_fd, CDROMSTART, 0 )) != 0){ + perror(""); + } +#endif + if (( retval = ioctl( global.cooked_fd, CDROMPLAYMSF, &cmsf )) != 0){ + perror(""); + } + return retval; +} + +/* request sub-q-channel information. This function may cause confusion + * for a drive, when called in the sampling process. + */ +static subq_chnl *ReadSubQ_cooked(SCSI *x, unsigned char sq_format, + unsigned char track) +{ + struct cdrom_subchnl sub_ch; + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + struct cd_sub_channel_info sub_ch_info; + + if (x && x->verbose) { + fprintf(stderr, "ReadSubQ_cooked (CDROM_GET_MCN or CDROMSUBCHNL)...\n"); + } + + sub_ch.address_format = CD_MSF_FORMAT; + sub_ch.track = track; + sub_ch.data_len = sizeof(struct cd_sub_channel_info); + sub_ch.data = &sub_ch_info; + + switch (sq_format) { + case GET_CATALOGNUMBER: + sub_ch.data_format = CD_MEDIA_CATALOG; +#else + if (x && x->verbose) { + fprintf(stderr, "ReadSubQ_cooked (CDROM_GET_MCN or CDROMSUBCHNL)...\n"); + } + + switch (sq_format) { + case GET_CATALOGNUMBER: +#endif +#if defined CDROM_GET_MCN + if (!(err = ioctl(global.cooked_fd, CDROM_GET_MCN, (struct cdrom_mcn *) SubQbuffer))) { + subq_chnl *SQp = (subq_chnl *) SubQbuffer; + subq_catalog *SQPp = (subq_catalog *) &SQp->data; + + memmove(SQPp->media_catalog_number, SQp, sizeof (SQPp->media_catalog_number)); + SQPp->zero = 0; + SQPp->mc_valid = 0x80; + break; + } else +#endif + { + return NULL; + } + case GET_POSITIONDATA: +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + sub_ch.data_format = CD_CURRENT_POSITION; +#endif +#if defined (__linux__) + sub_ch.cdsc_format = CDROM_MSF; +#endif + if (!(err = ioctl(global.cooked_fd, CDROMSUBCHNL, &sub_ch))) { + /* copy to SubQbuffer */ + subq_chnl *SQp = (subq_chnl *) (SubQbuffer); + subq_position *SQPp = (subq_position *) SQp->data; + SQp->audio_status = sub_ch.cdsc_audiostatus; + SQp->format = sub_ch.cdsc_format; + SQp->control_adr = (sub_ch.cdsc_adr << 4) | (sub_ch.cdsc_ctrl & 0x0f); + SQp->track = sub_ch.cdsc_trk; + SQp->index = sub_ch.cdsc_ind; + SQPp->abs_min = sub_ch.cdsc_absaddr.msf.minute; + SQPp->abs_sec = sub_ch.cdsc_absaddr.msf.second; + SQPp->abs_frame = sub_ch.cdsc_absaddr.msf.frame; + SQPp->trel_min = sub_ch.cdsc_reladdr.msf.minute; + SQPp->trel_sec = sub_ch.cdsc_reladdr.msf.second; + SQPp->trel_frame = sub_ch.cdsc_reladdr.msf.frame; + } else { + if (err == -1) { + if (errno == EPERM) + fprintf( stderr, "Please run this program setuid root.\n"); + perror("cooked: Read subq "); + exit( DEVICE_ERROR ); + } else { + fprintf(stderr, "can't read sub q channel (error %d).\n", err); + exit( DEVICE_ERROR ); + } + } + break; + default: + return NULL; + } /* switch */ + return (subq_chnl *)(SubQbuffer); +} + +/* Speed control */ +static void SpeedSelect_cooked(SCSI *x, unsigned speed); +/* ARGSUSED */ +static void SpeedSelect_cooked(SCSI *x, unsigned speed) +{ + if (x && x->verbose) { + fprintf(stderr, "SpeedSelect_cooked (CDROM_SELECT_SPEED)...\n"); + } + +#ifdef CDROM_SELECT_SPEED + /* CAUTION!!!!! Non standard ioctl parameter types here!!!! */ + if ((err = ioctl(global.cooked_fd, CDROM_SELECT_SPEED, speed))) { + if (err == -1) { + if (errno == EPERM) + fprintf( stderr, "Please run this program setuid root.\n"); + perror("cooked: Speed select "); + /*exit( err ); */ + } else { + fprintf(stderr, "can't set speed %d (error %d).\n", speed, err); + exit( DEVICE_ERROR ); + } + } +#endif +} + +/* set function pointers to use the ioctl routines */ +void SetupCookedIoctl(char *pdev_name) +{ +#if (HAVE_ST_RDEV == 1) + struct stat statstruct; + + if (fstat(global.cooked_fd, &statstruct)) { + fprintf(stderr, "cannot stat cd %d (%s)\n",global.cooked_fd, pdev_name); + exit(STAT_ERROR); + } +#if defined __linux__ + switch (major(statstruct.st_rdev)) { + case CDU31A_CDROM_MAJOR: /* sony cdu-31a/33a */ + global.nsectors = 13; + if (global.nsectors >= 14) { + global.overlap = 10; + } + break; + case MATSUSHITA_CDROM_MAJOR: /* sbpcd 1 */ + case MATSUSHITA_CDROM2_MAJOR: /* sbpcd 2 */ + case MATSUSHITA_CDROM3_MAJOR: /* sbpcd 3 */ + case MATSUSHITA_CDROM4_MAJOR: /* sbpcd 4 */ + /* some are more compatible than others */ + global.nsectors = 13; + break; + default: + global.nsectors = 8; + break; + } + err = ioctl(global.cooked_fd, CDROMAUDIOBUFSIZ, global.nsectors); + + switch (major(statstruct.st_rdev)) { + case MATSUSHITA_CDROM_MAJOR: /* sbpcd 1 */ + case MATSUSHITA_CDROM2_MAJOR: /* sbpcd 2 */ + case MATSUSHITA_CDROM3_MAJOR: /* sbpcd 3 */ + case MATSUSHITA_CDROM4_MAJOR: /* sbpcd 4 */ + if (err == -1) { + perror("ioctl(CDROMAUDIOBUFSIZ)"); + } + } +#endif +#endif + EnableCdda = EnableCdda_cooked; + ReadCdRom = ReadCdRom_cooked; + ReadCdRomData = (int (*)(SCSI *, unsigned char *, unsigned, unsigned)) ReadCdRomData_cooked; + doReadToc = ReadToc_cooked; + ReadTocText = NULL; + ReadSubQ = ReadSubQ_cooked; + ReadSubChannels = NULL; + SelectSpeed = SpeedSelect_cooked; + Play_at = Play_at_cooked; + StopPlay = StopPlay_cooked; + trash_cache = trash_cache_cooked; + ReadLastAudio = NULL; +} +#endif diff --git a/icedax/ioctl.h b/icedax/ioctl.h new file mode 100644 index 0000000..0fc4e92 --- /dev/null +++ b/icedax/ioctl.h @@ -0,0 +1,14 @@ +/* + * 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. + * + */ + +/* @(#)ioctl.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +void SetupCookedIoctl(char *pdev_name); diff --git a/icedax/lconfig.h b/icedax/lconfig.h new file mode 100644 index 0000000..07326c8 --- /dev/null +++ b/icedax/lconfig.h @@ -0,0 +1,85 @@ +/* + * 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. + * + */ + +/* lconfig.h. Generated automatically by configure. */ +#if 0 +/* @(#)lconfig.h.in 1.5 03/09/04 Copyright 1998-2003 Heiko Eissfeldt */ +#endif +/* #undef HAVE_SYS_CDIO_H */ /* if we should use sys/cdio.h */ + +/* #undef HAVE_SUNDEV_SRREG_H */ /* if we should use sundev/srreg.h */ + +/* #undef HAVE_SYS_AUDIOIO_H */ /* if we should use sys/audioio.h */ + +/* #undef HAVE_SUN_AUDIOIO_H */ /* if we should use sun/audioio.h */ + +/* #undef HAVE_SOUNDCARD_H */ /* if we should use soundcard.h */ + +/* TESTED BY CMAKE */ +/*#define HAVE_SYS_SOUNDCARD_H 1 if we should use sys/soundcard.h */ +/*define HAVE_LINUX_SOUNDCARD_H 1 if we should use linux/soundcard.h */ + +/* #undef HAVE_MACHINE_SOUNDCARD_H */ /* if we should use machine/soundcard.h */ + +/* #undef HAVE_SYS_ASOUNDLIB_H */ /* if we should use sys/asoundlib.h */ + +/* #undef HAVE_WINDOWS_H */ /* if we should use windows.h */ + +/* #undef HAVE_MMSYSTEM_H */ /* if we should use mmsystem.h */ + +/* #undef HAVE_OS2_H */ /* if we should use os2.h */ + +/* #undef HAVE_OS2ME_H */ /* if we should use os2me.h */ + +#if defined HAVE_SOUNDCARD_H || defined HAVE_SYS_SOUNDCARD_H || defined HAVE_LINUX_SOUNDCARD_H || defined HAVE_MACHINE_SOUNDCARD_H +#define HAVE_OSS 1 +#endif + +/* +#if defined HAVE_WINDOWS_H && defined HAVE_MMSYSTEM_H +#define HAVE_WINSOUND 1 +#endif + +#if defined HAVE_OS2_H && defined HAVE_OS2ME_H +#define HAVE_OS2SOUND 1 +#endif +*/ + +#define HAVE_STRTOUL 1 + + +/* EB, some defaults, fixme + */ + +#define CD_DEVICE "/dev/cdrom" +#define FILENAME "audio" +#define UNDERSAMPLING 1 +#define VERSION CDRKIT_VERSION +#define BITS_P_S 16 +#define CHANNELS 2 +#define AUDIOTYPE "wav" +#define DURATION 0 +#define DEF_INTERFACE "generic_scsi" +#define USE_PARANOIA 1 +#define DEFAULT_SPEED 0 +#define CDINDEX_SUPPORT +#define CDDB_SUPPORT +#define CDDBHOST "freedb.freedb.org" +#define CDDBPORT 8880 +#define HAVE_IOCTL_INTERFACE +#define ECHO_TO_SOUNDCARD +#define SOUND_DEV "/dev/dsp" +#define NSECTORS 75 +#define INFOFILES +/* #undef MD5_SIGNATURES */ /* not implemented */ +#define AUX_DEVICE "/dev/cdrom" + diff --git a/icedax/lconfig.h.in b/icedax/lconfig.h.in new file mode 100644 index 0000000..9ef9230 --- /dev/null +++ b/icedax/lconfig.h.in @@ -0,0 +1,44 @@ +#if 0 +/* @(#)lconfig.h.in 1.6 06/02/15 Copyright 1998-2003 Heiko Eissfeldt */ +#endif +#undef HAVE_SYS_CDIO_H /* if we should use sys/cdio.h */ + +#undef HAVE_SYS_CDRIO_H /* if we should use sys/cdrio.h */ + +#undef HAVE_SUNDEV_SRREG_H /* if we should use sundev/srreg.h */ + +#undef HAVE_SYS_AUDIOIO_H /* if we should use sys/audioio.h */ + +#undef HAVE_SUN_AUDIOIO_H /* if we should use sun/audioio.h */ + +#undef HAVE_SOUNDCARD_H /* if we should use soundcard.h */ + +#undef HAVE_SYS_SOUNDCARD_H /* if we should use sys/soundcard.h */ + +#undef HAVE_LINUX_SOUNDCARD_H /* if we should use linux/soundcard.h */ + +#undef HAVE_MACHINE_SOUNDCARD_H /* if we should use machine/soundcard.h */ + +#undef HAVE_SYS_ASOUNDLIB_H /* if we should use sys/asoundlib.h */ + +#undef HAVE_WINDOWS_H /* if we should use windows.h */ + +#undef HAVE_MMSYSTEM_H /* if we should use mmsystem.h */ + +#undef HAVE_OS2_H /* if we should use os2.h */ + +#undef HAVE_OS2ME_H /* if we should use os2me.h */ + +#if defined HAVE_SOUNDCARD_H || defined HAVE_SYS_SOUNDCARD_H || defined HAVE_LINUX_SOUNDCARD_H || defined HAVE_MACHINE_SOUNDCARD_H +#define HAVE_OSS 1 +#endif + +#if defined HAVE_WINDOWS_H && defined HAVE_MMSYSTEM_H +#define HAVE_WINSOUND 1 +#endif + +#if defined HAVE_OS2_H && defined HAVE_OS2ME_H +#define HAVE_OS2SOUND 1 +#endif + +#undef HAVE_STRTOUL diff --git a/icedax/list_audio_tracks.1 b/icedax/list_audio_tracks.1 new file mode 100644 index 0000000..b4a1dd0 --- /dev/null +++ b/icedax/list_audio_tracks.1 @@ -0,0 +1,54 @@ +.TH "LIST_AUDIO_TRACKS" "1" "Tue Feb 15 13:03:51 MST 2005" "" "list_audio_tracks" + +.PP +.SH "NAME" +list_audio_tracks is an alias for icedax. +.PP +.SH "SYNOPSIS" +.PP +\fBlist_audio-tracks\fP +.PP +.SH "DESCRIPTION" +.PP +\fBlist_audio_tracks\fP equals to the invocation of icedax, so all the +arguments for the latter can be used. +.PP +.SH SEE ALSO +icedax(1) +.PP +.SH "AUTHOR" +.PP +\fBicedax\fP was written by Heiko Eissfeldt and others. +.PP +This manpage describes the program implementation of +.B +list_audio_tracks +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program called cdda2wav +distributed by the cdrtools project. However, the cdrtools developers are not +involved in the development of this spinoff and therefore shall not be made +responsible for any problem caused by it. Do not try to get support for this +program by contacting the original authors. +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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. +.PP +This manual page was written by Oleksandr Moskalenko +<malex@tagancha\&.org>, for +the Debian GNU/Linux system\&. It may be used by other distributions +without contacting the author\&. Any mistakes or omissions in the +manual page are my fault; inquiries about or corrections to this +manual page should be directed to me (and not to the primary author)\&. diff --git a/icedax/local.cnf.in b/icedax/local.cnf.in new file mode 100644 index 0000000..5c126a7 --- /dev/null +++ b/icedax/local.cnf.in @@ -0,0 +1,141 @@ +# @(#)local.cnf.in 1.6 03/09/04 Copyright 1998-2002 Heiko Eissfeldt +# +# Makefile for cdda2wav, a sampling utility. +# + +# ############ interface +# choose one of the following interfacing and device types. +# generic_scsi is for scsi cdrom devices. +# uncomment one INTERFACE and one DEF_DEVICE line +# (for details consult the README) +INTERFACE='"generic_scsi"' +#INTERFACE='"cooked_ioctl"' + +# set the default cdrom device +SUN_OS_DEFAULT_DEV= '"0,6,0"' +YOUR_DEFAULT_DEV= '"yourSCSI_Bus,yourSCSI_ID,yourSCSI_LUN"' + +_DEF_DEVICE= $(_UNIQ)$(HAVE_SUN_OS) +__DEF_DEVICE= $(_DEF_DEVICE:$(_UNIQ)=$(YOUR_DEFAULT_DEV)) +DEF_DEVICE= $(__DEF_DEVICE:$(_UNIQ)$(HAVE_SUN_OS)=$(SUN_OS_DEFAULT_DEV)) + +# optional matching device used for a MULTISESSION ioctl +LINUX_AUX_DEV= '"/dev/cdrom"' + +_AUX_DEVICE= $(_UNIQ)$(HAVE_LINUX) +__AUX_DEVICE= $(_AUX_DEVICE:$(_UNIQ)='""') +AUX_DEVICE= $(__AUX_DEVICE:$(_UNIQ)$(HAVE_LINUX)=$(LINUX_AUX_DEV)) + +# number of sectors to request +# under BSD better use < 128 K of shared memory +SECTORS=75 +BSD_SECTORS=27 + +_SECTORS= $(_UNIQ)$(HAVE_BSD_OS) +__SECTORS= $(_SECTORS:$(_UNIQ)=$(SECTORS)) +NSECTORS= $(__SECTORS:$(_UNIQ)$(HAVE_BSD_OS)=$(BSD_SECTORS)) + +# some architectures can use the ioctl() interface cooked_ioctl +HAVE_SUN_IOCTL= @HAVE_SUN_IOCTL@ +_HAVE_IOCTL= $(_UNIQ)$(HAVE_BSD_OS)$(HAVE_SUN_IOCTL)$(HAVE_LINUX) +__HAVE_IOCTL= $(_HAVE_IOCTL:$(_UNIQ)=) +HAVE_IOCTL= $(__HAVE_IOCTL:$(_UNIQ)$(HAVE_BSD_OS)$(HAVE_SUN_IOCTL)$(HAVE_LINUX)=-DHAVE_IOCTL_INTERFACE) + +############# Sound device support +#to disable sound support comment out the corresponding line with HAVE_SOUND +OSS_SOUND_DEV= '"/dev/dsp"' +SUN_SOUND_DEV= '"/dev/audio"' + +HAVE_OSS= @HAVE_OSS@ +HAVE_SUNSOUND= @HAVE_SUNSOUND@ +HAVE_WINSOUND= @HAVE_WINSOUND@ +HAVE_OS2SOUND= @HAVE_OS2SOUND@ +HAVE_QNXSOUND= @HAVE_SYS_ASOUNDLIB_H@ +#_HAVE_SOUND= $(_UNIQ)$(HAVE_OSS)$(HAVE_SUNSOUND) +_HAVE_SOUND= $(_UNIQ)$(HAVE_OSS)$(HAVE_SUNSOUND)$(HAVE_WINSOUND)$(HAVE_OS2SOUND)$(HAVE_QNXSOUND) +__HAVE_SOUND= $(_HAVE_SOUND:$(_UNIQ)=) +#HAVE_SOUND= $(__HAVE_SOUND:$(_UNIQ)$(HAVE_OSS)$(HAVE_SUNSOUND)=-DECHO_TO_SOUNDCARD) +HAVE_SOUND= $(__HAVE_SOUND:$(_UNIQ)$(HAVE_OSS)$(HAVE_SUNSOUND)$(HAVE_WINSOUND)$(HAVE_OS2SOUND)$(HAVE_QNXSOUND)=-DECHO_TO_SOUNDCARD) + +_SOUND_DEVICE= $(_UNIQ)$(HAVE_OSS)$(HAVE_SOUND)$(HAVE_SUNSOUND) +__SOUND_DEVICE= $(_SOUND_DEVICE:$(_UNIQ)='""') +___SOUND_DEVICE= $(__SOUND_DEVICE:$(_UNIQ)$(HAVE_OSS)$(HAVE_SOUND)=$(OSS_SOUND_DEV)) +____SOUND_DEVICE= $(___SOUND_DEVICE:$(_UNIQ)$(HAVE_SOUND)$(HAVE_SUNSOUND)=$(SUN_SOUND_DEV)) +SOUND_DEVICE= $(____SOUND_DEVICE:$(_UNIQ)$(HAVE_OSS)$(HAVE_SOUND)$(HAVE_SUNSOUND)=$(OSS_SOUND_DEV)) + +_EXTRALIB= $(_UNIQ)$(HAVE_WINSOUND)$(HAVE_OS2SOUND)$(HAVE_QNXSOUND) +__EXTRALIB= $(_EXTRALIB:$(_UNIQ)=@EXTRALIBS@) +___EXTRALIB= $(__EXTRALIB:$(_UNIQ)$(HAVE_WINSOUND)=@EXTRALIBS@ -lwinmm) +____EXTRALIB= $(___EXTRALIB:$(_UNIQ)$(HAVE_QNXSOUND)=@EXTRALIBS@ -lasound) +EXTRALIB= $(____EXTRALIB:$(_UNIQ)$(HAVE_OS2SOUND)=@EXTRALIBS@ -los2me) + +############# sound file defaults +# Defaults for wav/au/cdr output file formats +# default divider for 44.1 KHz +DEF_UNDERSAMPLING=1 + +# 16, 12 or 8 bits per sample +DEF_BITS=16 +# 1 = mono, 2 = stereo +DEF_CHANNELS=2 + +DEF_TIME=0 # number of seconds to record + +DEF_SPEED=0 # default reading speed +#DEF_SPEED=0xFFFF # default reading speed + +############## output file types: wav, aiff, aifc, sun au or cdr ########### +# enable one DEF_TYPE and one DEF_FILE +# first are for wav sound files, second are for sun au pcm sound files, +# third are for headerless sound files (raw samples in bigendian format) +# default audio file type + +_DEF_TYPE= $(_UNIQ)$(HAVE_SUN_OS) +__DEF_TYPE= $(_DEF_TYPE:$(_UNIQ)='"wav"') +DEF_TYPE= $(__DEF_TYPE:$(_UNIQ)$(HAVE_SUN_OS)='"au"') +#DEF_TYPE= "wav" +#DEF_TYPE= "au" +#DEF_TYPE= "cdr" +#DEF_TYPE= "aiff" +#DEF_TYPE= "aifc" + +# default file name for sound file +DEF_FILE='"audio"' + +############## enable/disable info files #################################### +# Info files contain date/time, track, recording time, ISRC, optional MD5 +# signature and more, each item in one line. These files are generated one +# per track. +# Comment out if you don't want this. +WANT_INFOFILES=-DINFOFILES + +############## enable/disable MD5 signatures in info files ################## +# Comment out if you don't want this. +WANT_MD5=-DMD5_SIGNATURES +MD5OBJECTS=md5c.o + +# CDINDEX server support +# Comment out if you don't want a disk description file for the cdindex server +WANT_CDINDEX_SUPPORT=-DCDINDEX_SUPPORT + +# CDDB server support +# Comment out if you don't want a network access to the cddb server +WANT_CDDB_SUPPORT=-DCDDB_SUPPORT +CDDB_SERVERHOST='"freedb.freedb.org"' +CDDB_SERVERPORT=8880 + +# end of tunable parameters +# +CDDA2WAVDEFS=-DCD_DEVICE=$(DEF_DEVICE) -DFILENAME=$(DEF_FILE) \ +-DUNDERSAMPLING=$(DEF_UNDERSAMPLING) -DVERSION=$(CUR_VERSION) \ +-DBITS_P_S=$(DEF_BITS) -DCHANNELS=$(DEF_CHANNELS) -DAUDIOTYPE=$(DEF_TYPE) \ +-DDURATION=$(DEF_TIME) -DDEF_INTERFACE=$(INTERFACE) -DUSE_PARANOIA=1 \ +-DDEFAULT_SPEED=$(DEF_SPEED) $(WANT_CDINDEX_SUPPORT) $(WANT_CDDB_SUPPORT) \ +-DCDDBHOST=$(CDDB_SERVERHOST) -DCDDBPORT=$(CDDB_SERVERPORT) $(HAVE_IOCTL) \ +$(HAVE_SOUND) -DSOUND_DEV=$(SOUND_DEVICE) -DNSECTORS=$(NSECTORS) \ +$(WANT_INFOFILES) $(WANT_MD5) -DAUX_DEVICE=$(AUX_DEVICE) + +LIBS += @LIBS@ + +VERSION_OS=@CDRTOOLS_VERSION@_$(O_ARCH)_$(OSREL)_$(K_ARCH)_$(P_ARCH) +CUR_VERSION='"$(VERSION_OS)"' diff --git a/icedax/lowlevel.h b/icedax/lowlevel.h new file mode 100644 index 0000000..084ef34 --- /dev/null +++ b/icedax/lowlevel.h @@ -0,0 +1,25 @@ +/* + * 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. + * + */ + +/* @(#)lowlevel.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +/* os dependent functions */ + +#ifndef LOWLEVEL +# define LOWLEVEL 1 + +# if defined(__linux__) +# include <linux/version.h> +# include <linux/major.h> + +# endif /* defined __linux__ */ + +#endif /* ifndef LOWLEVEL */ diff --git a/icedax/mycdrom.h b/icedax/mycdrom.h new file mode 100644 index 0000000..1819321 --- /dev/null +++ b/icedax/mycdrom.h @@ -0,0 +1,150 @@ +/* + * 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. + * + */ + +/* @(#)mycdrom.h 1.10 06/05/07 Copyright 1998,1999 Heiko Eissfeldt, Copyright 2005-2006 J. Schilling */ +#if defined(__linux__) +# include <linux/cdrom.h> +#else +# if defined HAVE_SYS_CDIO_H +# include <sys/cdio.h> +# if defined(__FreeBSD__) && __FreeBSD__ >= 2 +# include <osreldate.h> +# endif +# if defined HAVE_SYS_CDRIO_H /* Was: if __FreeBSD_version >= 400014 */ +# include <sys/cdrio.h> +# endif + +# if (defined (__sun) && defined (SVR4)) +# if 0 +/* just for info */ +/* Sun has this cdda reading ioctl: CDROMCDDA */ +/* + * Definition of CD-DA structure + */ +struct cdrom_cdda { + unsigned int cdda_addr; + unsigned int cdda_length; + caddr_t cdda_data; + unsigned char cdda_subcode; +}; +/* +To get the subcode information related to CD-DA data, the following values are + appropriate for the cdda_subcode field: + +CDROM_DA_NO_SUBCODE +CD-DA data with no subcode. + +CDROM_DA_SUBQ +CD-DA data with sub Q code. + +CDROM_DA_ALL_SUBCODE +CD-DA data with all subcode. + +CDROM_DA_SUBCODE_ONLY +All subcode only. + +To allocate the memory related to CD-DA and/or subcode data, the following + values are appropriate for each data block transferred: + +CD-DA data with no subcode +2352 bytes + +CD-DA data with sub Q code +2368 bytes + +CD-DA data with all subcode +2448 bytes + +All subcode only +96 bytes +*/ + +# endif /* if 0 */ +# else /* not Sun SVR4 */ +# if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __DragonFly__ || defined __OpenBSD__ +# if (defined(__FreeBSD__) && __FreeBSD_version < 228000) || !defined(CDIOCREADAUDIO) + /* + * FreeBSD_version >= 501112 has no CDIOCREADAUDIO but uses pread() + */ +# if !(defined(__FreeBSD__) && __FreeBSD_version >= 501112) +# undef HAVE_IOCTL_INTERFACE +# endif +# endif /* __FreeBSD_version < 228000 || !CDIOCREADAUDIO */ + +#ifdef HAVE_IOCTL_INTERFACE + +#define CDROM_LBA CD_LBA_FORMAT +#define CDROM_MSF CD_MSF_FORMAT +#define CDROM_DATA_TRACK 0x04 +#define CDROM_LEADOUT 0xAA + +#define CDROMSTOP CDIOCSTOP +#define CDROMSTART CDIOCSTART +#define CDROMREADTOCHDR CDIOREADTOCHEADER +#define CDROMREADTOCENTRY CDIOREADTOCENTRY +#define CDROMPLAYMSF CDIOCPLAYMSF +#define CDROMREADAUDIO CDIOCREADAUDIO +#define CDROM_GET_MCN CDIOCREADSUBCHANNEL +#define CDROMSUBCHNL CDIOCREADSUBCHANNEL + +#ifndef CDIOREADTOCENTRY +#define CDIOREADTOCENTRY CDIOREADTOCENTRYS +#endif + +#define cdrom_tochdr ioc_toc_header +#define cdth_trk0 starting_track +#define cdth_trk1 ending_track + +#define cdrom_tocentry ioc_read_toc_single_entry +#define cdte_track track +#define cdte_format address_format +#define cdte_adr entry.addr_type +#define cdte_ctrl entry.control +#define cdte_addr entry.addr + +#define cdrom_read_audio ioc_read_audio +#define addr_format address_format +#define buff buffer + +#define cdrom_msf ioc_play_msf +#define cdmsf_min0 start_m +#define cdmsf_sec0 start_s +#define cdmsf_frame0 start_f +#define cdmsf_min1 end_m +#define cdmsf_sec1 end_s +#define cdmsf_frame1 end_f + +#define cdrom_subchnl ioc_read_subchannel +#define cdsc_audiostatus data->header.audio_status +#define cdsc_format data->what.position.data_format +#define cdsc_adr data->what.position.addr_type +#define cdsc_ctrl data->what.position.control +#define cdsc_trk data->what.position.track_number +#define cdsc_ind data->what.position.index_number +#define cdsc_absaddr data->what.position.absaddr +#define cdsc_reladdr data->what.position.reladdr +# endif /* HAVE_IOCTL_INTERFACE */ +# else /* not *BSD */ +# undef HAVE_IOCTL_INTERFACE +# endif /* not *BSD */ +# endif /* not SUN SVR4 */ +# else /* HAVE_SYS_CDIO_H */ +# if defined HAVE_SUNDEV_SRREG_H +# include <sundev/srreg.h> +# if !defined CDROMCDDA +# undef HAVE_IOCTL_INTERFACE +# endif +# else +# undef HAVE_IOCTL_INTERFACE +# endif +# endif /* not HAVE_SYS_CDIO_H */ +#endif /* not linux */ diff --git a/icedax/mytype.h b/icedax/mytype.h new file mode 100644 index 0000000..189f1c9 --- /dev/null +++ b/icedax/mytype.h @@ -0,0 +1,39 @@ +/* + * 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. + * + */ + +/* @(#)mytype.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +#if 4 == SIZEOF_LONG_INT +#define UINT4 long unsigned int +#define UINT4_C ULONG_C +#else +#if 4 == SIZEOF_INT +#define UINT4 unsigned int +#define UINT4_C UINT_C +#else +#if 4 == SIZEOF_SHORT_INT +#define UINT4 short unsigned int +#define UINT4_C USHORT_C +#else +error need an integer type with 32 bits, but do not know one! +#endif +#endif +#endif +#define TRUE 1 +#define FALSE 0 + +#ifndef offset_of +#define offset_of(TYPE, MEMBER) ((size_t) ((TYPE *)0)->MEMBER) +#endif +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + diff --git a/icedax/pitchplay b/icedax/pitchplay new file mode 100755 index 0000000..a9f3dc2 --- /dev/null +++ b/icedax/pitchplay @@ -0,0 +1,39 @@ +#! /bin/sh +# +# Script to play audio tracks with different pitches +# through a soundcard (cdda2wav must have soundcard +# support enabled). +# +# Pitches are specified in percentage with 100% being +# the original pitch, 50% being one octave lower, 200% +# one octave higher. +# +# based on a script from Raul Sobon, who created the pitch +# feature. Thanks Raul. +# +# usage: pitchplay <track a> <pitch a> <track b> <pitch b> ... +# +# example: pitchplay 1 90 3 140 5 50 +# will play track 1 with a pitch of 90%, +# track 3 with a pitch of 140%, and +# track 5 with a pitch of 50%. +# +CDDA2WAV=icedax +#CDDA2WAVOPTS="-qeNP0 -n75" +CDDA2WAVOPTS="-qeNP0 -n40" + +if [ $(( $# % 2 )) -eq 0 ]; then + while [ $# -ge 2 ]; do + echo playing track $1 with a pitch of $2% + $CDDA2WAV $CDDA2WAVOPTS -t $1 -p $2 + RES=$? + if [ $RES -ne 0 ]; then + echo "$CDDA2WAV error, return value "$RES". Aborted." >&2 + break + fi + shift 2 + done +else + echo "usage: $0 [<Tracknr> <Pitch>] ..." >&2 +fi + diff --git a/icedax/pitchplay.1 b/icedax/pitchplay.1 new file mode 100644 index 0000000..dee13ea --- /dev/null +++ b/icedax/pitchplay.1 @@ -0,0 +1,59 @@ +.TH "PITCHPLAY" "1" "Tue Feb 15 12:53:23 MST 2005" "" "pitchplay" + +.PP +.SH "NAME" +pitchplay \- wrapper script to play audio tracks with cdda2wav with different +pitches through a soundcard (cdda2wav must have soundcard support enabled). +.PP +.SH "SYNOPSIS" +.PP +\fBpitchplay\fP <track a> <pitch a> <track b> <pitch b>... +.PP +.SH "DESCRIPTION" +.PP +\fBpitchplay\fP allows playback of audio tracks with cdda2wav with pitches +specified in percentage with 100% being the original pitch, 50% being one +octave lower, 200% one octave higher. +.PP +.SH "EXAMPLES" +.PP +\fBpitchplay\fP 1 90 3 140 5 50 +.br +will play track 1 with a pitch of 90%, track 3 with a pitch of 140%, and track 5 with a pitch of 50%. +.PP +.SH SEE ALSO +cdda2wav(1) +.PP +.SH "AUTHOR" +.PP +\fBcdda2was\fP was written by Joerg Schilling <js@cs\&.tu-berlin\&.de> and +others. +.PP +This manpage describes the program implementation of +.B +pitchplay +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program distributed by the cdrtools project. However, the cdrtools developers are not involved in the development of this spinoff and therefore shall not be made responsible for any problem caused by it. Do not try to get support for this program by contacting the original authors. +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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. +.PP +This manual page was written by Oleksandr Moskalenko +<malex@tagancha\&.org>, for +the Debian GNU/Linux system\&. It may be used by other distributions +without contacting the author\&. Any mistakes or omissions in the +manual page are my fault; inquiries about or corrections to this +manual page should be directed to me (and not to the primary author)\&. diff --git a/icedax/raw.c b/icedax/raw.c new file mode 100644 index 0000000..b56841e --- /dev/null +++ b/icedax/raw.c @@ -0,0 +1,61 @@ +/* + * 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. + * + */ + +/* @(#)raw.c 1.4 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */ +#include "config.h" +#include <unixstd.h> +#include "sndfile.h" + +static int InitSound(void); + +static int InitSound() +{ + return 0; +} + +static int ExitSound(void); + +static int ExitSound() +{ + return 0; +} + +static unsigned long GetHdrSize(void); + +static unsigned long GetHdrSize() +{ + return 0L; +} + +static unsigned long InSizeToOutSize(unsigned long BytesToDo); + +static unsigned long InSizeToOutSize(unsigned long BytesToDo) +{ + return BytesToDo; +} + +struct soundfile rawsound = +{ + (int (*)(int audio, long channels, + unsigned long myrate, long nBitsPerSample, + unsigned long expected_bytes)) InitSound, + + (int (*)(int audio, unsigned long nBytesDone)) ExitSound, + + GetHdrSize, + + (int (*)(int audio, unsigned char *buf, unsigned long BytesToDo)) write, /* get sound samples out */ + + InSizeToOutSize, /* compressed? output file size */ + + 1 /* needs big endian samples */ +}; diff --git a/icedax/raw.h b/icedax/raw.h new file mode 100644 index 0000000..2a9ef8b --- /dev/null +++ b/icedax/raw.h @@ -0,0 +1,14 @@ +/* + * 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. + * + */ + +/* @(#)raw.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +extern struct soundfile rawsound; diff --git a/icedax/readmult b/icedax/readmult new file mode 100755 index 0000000..6f0884e --- /dev/null +++ b/icedax/readmult @@ -0,0 +1,31 @@ +#! /bin/sh +# +# Script to read more than 1 song with icedax +# Each file gets an individual name from the command line +# +# based on a perl script from Matthias Schniedermeyer +# +# usage: readmult <track a> <title a> <track b> <title b> ... +# +# example: readmult 1 intro 3 lovesong 5 medley +# will produce a file named intro.wav for track 1, +# a file named lovesong.wav for track 3, and +# a file named medley.wav for track 5. +# +CDDA2WAV=icedax +CDDA2WAVOPTS="-P0" + +if [ $(( $# % 2 )) -eq 0 ]; then + while [ $# -ge 2 ]; do + $CDDA2WAV $CDDA2WAVOPTS -Owav -t $1 $PREFIX$2".wav" + RES=$? + if [ $RES -ne 0 ]; then + echo "$CDDA2WAV error, return value "$RES". Aborted." >&2 + break + fi + shift 2 + done +else + echo "usage: $0 [<Tracknr> <Filename>] ..." >&2 +fi + diff --git a/icedax/readmult.1 b/icedax/readmult.1 new file mode 100644 index 0000000..8801736 --- /dev/null +++ b/icedax/readmult.1 @@ -0,0 +1,52 @@ +.TH "READMULT" "1" "Tue Feb 15 12:34:06 MST 2005" "" "readmult" + +.PP +.SH "NAME" +readmult \- a multitrack wrapper for cdda2wav +.PP +.SH "SYNOPSIS" +.PP +\fBreadmult\fP <track a> <title a> <track b> <title b> ... +.PP +.SH "DESCRIPTION" +.PP +\fBreadmult\fP allows simultaneous extraction and naming of multiple tracks +with cdda2wav +.PP +.SH SEE ALSO +cdda2wav(1) +.PP +.SH "AUTHOR" +.PP +\fBcdda2was\fP was written by Joerg Schilling <js@cs\&.tu-berlin\&.de> and +others. +.PP +This describes the program as shipped with cdrkit, see +This manpage describes the program implementation of +.B +readmult +as shipped by the cdrkit distribution. See +.B +http://alioth.debian.org/projects/debburn/ +for details. It is a spinoff from the original program distributed by the cdrtools project. However, the cdrtools developers are not involved in the development of this spinoff and therefore shall not be made responsible for any problem caused by it. Do not try to get support for this program by contacting the original authors. +.PP +If you have support questions, send them to +.PP +.B +debburn-devel@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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. +.PP +This manual page was written by Oleksandr Moskalenko +<malex@tagancha\&.org>, for +the Debian GNU/Linux system\&. It may be used by other distributions +without contacting the author\&. Any mistakes or omissions in the +manual page are my fault; inquiries about or corrections to this +manual page should be directed to me (and not to the primary author)\&. diff --git a/icedax/resample.c b/icedax/resample.c new file mode 100644 index 0000000..3f5b5d0 --- /dev/null +++ b/icedax/resample.c @@ -0,0 +1,985 @@ +/* + * 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. + * + */ + +/* @(#)resample.c 1.15 02/11/21 Copyright 1998,1999,2000 Heiko Eissfeldt */ +/* resampling module + * + * The audio data has been read. Here are the + * functions to ensure a correct continuation + * of the output stream and to convert to a + * lower sample rate. + * + */ + +#undef DEBUG_VOTE_ENDIANESS +#undef DEBUG_SHIFTS /* simulate bad cdrom drives */ +#undef DEBUG_MATCHING +#undef SHOW_JITTER +#undef CHECK_MEM + +#include "config.h" +#include <timedefs.h> +#include <stdio.h> +#include <stdxlib.h> +#include <utypes.h> +#include <unixstd.h> +#include <standard.h> +#include <strdefs.h> +#include <limits.h> +#include <assert.h> +#include <math.h> + +#include <usal/scsitransp.h> + +#include "mytype.h" +#include "icedax.h" +#include "interface.h" +#include "byteorder.h" +#include "ringbuff.h" +#include "resample.h" +#include "toc.h" +#include "sndfile.h" +#include "sndconfig.h" +#include "global.h" +#include "exitcodes.h" + + +int waitforsignal = 0; /* flag: wait for any audio response */ +int any_signal = 0; + +short undersampling; /* conversion factor */ +short samples_to_do; /* loop variable for conversion */ +int Halved; /* interpolate due to non integral divider */ + +static long lsum = 0, rsum = 0; /* accumulator for left/right channel */ +static long ls2 = 0, rs2 = 0, ls3 = 0, rs3 = 0, auxl = 0, auxr = 0; + +static const unsigned char *my_symmemmem(const unsigned char *HAYSTACK, + const size_t HAYSTACK_LEN, + const unsigned char *const NEEDLE, + const size_t NEEDLE_LEN); +static const unsigned char *my_memmem(const unsigned char *HAYSTACK, + const size_t HAYSTACK_LEN, + const unsigned char *const NEEDLE, + const size_t NEEDLE_LEN); +static const unsigned char *my_memrmem(const unsigned char *HAYSTACK, + const size_t HAYSTACK_LEN, + const unsigned char *const NEEDLE, + const size_t NEEDLE_LEN); +static const unsigned char *sync_buffers(const unsigned char *const newbuf); +static long interpolate(long p1, long p2, long p3); +static void emit_sample(long lsumval, long rsumval, long channels); +static void change_endianness(UINT4 *pSam, unsigned int Samples); +static void swap_channels(UINT4 *pSam, unsigned int Samples); +static int guess_endianess(UINT4 *p, Int16_t *p2, unsigned int SamplesToDo); + + +#ifdef CHECK_MEM +static void check_mem(const unsigned char *p, unsigned long amount, + const unsigned char *q, unsigned line, char *file); + +static void check_mem(const unsigned char *p, unsigned long amount, + const unsigned char *q, unsigned line, char *file) +{ + if (p < q || p+amount > q + ENTRY_SIZE) { + fprintf(stderr, "file %s, line %u: invalid buffer range (%p - %p), allowed is (%p - %p)\n", + file,line,p, p+amount-1, q, q + ENTRY_SIZE-1); + exit(INTERNAL_ERROR); + } +} +#endif + + +#ifdef DEBUG_MATCHING +int memcmp(const void * a, const void * b, size_t c) +{ + return 1; +} +#endif + +static const unsigned char * +my_symmemmem(const unsigned char *HAYSTACK, const size_t HAYSTACK_LEN, + const unsigned char * const NEEDLE, const size_t NEEDLE_LEN) +{ + const unsigned char * const UPPER_LIMIT = HAYSTACK + HAYSTACK_LEN - NEEDLE_LEN - 1; + const unsigned char * HAYSTACK2 = HAYSTACK-1; + + while (HAYSTACK <= UPPER_LIMIT) { + if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) { + return HAYSTACK; + } else { + if (memcmp(NEEDLE, HAYSTACK2, NEEDLE_LEN) == 0) { + return HAYSTACK2; + } + HAYSTACK2--; + HAYSTACK++; + } + } +#ifdef DEBUG_MATCHING + HAYSTACK2++; + HAYSTACK--; + fprintf(stderr, "scompared %p-%p with %p-%p (%p)\n", + NEEDLE, NEEDLE + NEEDLE_LEN-1, + HAYSTACK2, HAYSTACK + NEEDLE_LEN-1, HAYSTACK); +#endif + return NULL; +} + +static const unsigned char * +my_memmem(const unsigned char *HAYSTACK, const size_t HAYSTACK_LEN, + const unsigned char * const NEEDLE, const size_t NEEDLE_LEN) +{ + const unsigned char * const UPPER_LIMIT = HAYSTACK + HAYSTACK_LEN - NEEDLE_LEN; + + while (HAYSTACK <= UPPER_LIMIT) { + if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) { + return HAYSTACK; + } else { + HAYSTACK++; + } + } +#ifdef DEBUG_MATCHING + HAYSTACK--; + fprintf(stderr, "fcompared %p-%p with %p-%p (%p)\n", + NEEDLE, NEEDLE + NEEDLE_LEN-1, + HAYSTACK - HAYSTACK_LEN + NEEDLE_LEN, HAYSTACK + NEEDLE_LEN-1, + HAYSTACK); +#endif + return NULL; +} + +static const unsigned char * +my_memrmem(const unsigned char *HAYSTACK, const size_t HAYSTACK_LEN, + const unsigned char * const NEEDLE, const size_t NEEDLE_LEN) +{ + const unsigned char * const LOWER_LIMIT = HAYSTACK - (HAYSTACK_LEN - 1); + + while (HAYSTACK >= LOWER_LIMIT) { + if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) { + return HAYSTACK; + } else { + HAYSTACK--; + } + } +#ifdef DEBUG_MATCHING + HAYSTACK++; + fprintf(stderr, "bcompared %p-%p with %p-%p (%p)\n", + NEEDLE, NEEDLE + NEEDLE_LEN-1, + HAYSTACK, HAYSTACK + (HAYSTACK_LEN - 1), + HAYSTACK + (HAYSTACK_LEN - 1) - NEEDLE_LEN - 1); +#endif + return NULL; +} + +/* find continuation in new buffer */ +static const unsigned char * +sync_buffers(const unsigned char * const newbuf) +{ + const unsigned char *retval = newbuf; + + if (global.overlap != 0) { + /* find position of SYNC_SIZE bytes + of the old buffer in the new buffer */ + size_t haystack_len; + const size_t needle_len = SYNC_SIZE; + const unsigned char * const oldbuf = (const unsigned char *) (get_previous_read_buffer()->data); + const unsigned char * haystack; + const unsigned char * needle; + + /* compare the previous buffer with the new one + * + * 1. symmetrical search: + * look for the last SYNC_SIZE bytes of the previous buffer + * in the new buffer (from the optimum to the outer positions). + * + * 2. if the first approach did not find anything do forward search + * look for the last SYNC_SIZE bytes of the previous buffer + * in the new buffer (from behind the overlap to the end). + * + */ + + haystack_len = min((global.nsectors - global.overlap)*CD_FRAMESIZE_RAW + +SYNC_SIZE+1, + global.overlap*CD_FRAMESIZE_RAW); + /* expected here */ + haystack = newbuf + CD_FRAMESIZE_RAW*global.overlap - SYNC_SIZE; + needle = oldbuf + CD_FRAMESIZE_RAW*global.nsectors - SYNC_SIZE; + +#ifdef DEBUG_MATCHING + fprintf(stderr, "oldbuf %p-%p new %p-%p %u %u %u\n", + oldbuf, oldbuf + CD_FRAMESIZE_RAW*global.nsectors - 1, + newbuf, newbuf + CD_FRAMESIZE_RAW*global.nsectors - 1, + CD_FRAMESIZE_RAW*global.nsectors, global.nsectors, global.overlap); +#endif + + retval = my_symmemmem(haystack, haystack_len, needle, needle_len); + if (retval != NULL) { + retval += SYNC_SIZE; + } else { + /* fallback to asymmetrical search */ + + /* if there is no asymmetrical part left, return with 'not found' */ + if (2*global.overlap == global.nsectors) { + retval = NULL; + } else if (2*global.overlap > global.nsectors) { + /* the asymmetrical part is in front, search backwards */ + haystack_len = (2*global.overlap-global.nsectors)*CD_FRAMESIZE_RAW; + haystack = newbuf + haystack_len - 1; + retval = my_memrmem(haystack, haystack_len, needle, needle_len); + } else { + /* the asymmetrical part is at the end, search forward */ + haystack = newbuf + 2*(global.overlap*CD_FRAMESIZE_RAW - SYNC_SIZE); + haystack_len = (global.nsectors-2*global.overlap)*CD_FRAMESIZE_RAW + 2*SYNC_SIZE; + retval = my_memmem(haystack, haystack_len, needle, needle_len); + } + if (retval != NULL) + retval += SYNC_SIZE; + } + +#ifdef SHOW_JITTER + if (retval) { + fprintf(stderr,"%d\n", + retval-(newbuf+global.overlap*CD_FRAMESIZE_RAW)); + } else { + fprintf(stderr,"no match\n"); + } +#endif + } + + return retval; +} + +/* quadratic interpolation + * p1, p3 span the interval 0 - 2. give interpolated value for 1/2 */ +static long int +interpolate(long int p1, long int p2, long int p3) +{ + return (3L*p1 + 6L*p2 - p3)/8L; +} + +static unsigned char *pStart; /* running ptr defining end of output buffer */ +static unsigned char *pDst; /* start of output buffer */ +/* + * Write the filtered sample into the output buffer. + */ +static void +emit_sample(long lsumval, long rsumval, long channels) +{ + if (global.findminmax) { + if (rsumval > global.maxamp[0]) global.maxamp[0] = rsumval; + if (rsumval < global.minamp[0]) global.minamp[0] = rsumval; + if (lsumval < global.minamp[1]) global.minamp[1] = lsumval; + if (lsumval > global.maxamp[1]) global.maxamp[1] = lsumval; + } + /* convert to output format */ + if ( channels == 1 ) { + Int16_t sum; /* mono section */ + sum = ( lsumval + rsumval ) >> (global.sh_bits + 1); + if ( global.sh_bits == 8 ) { + if ( waitforsignal == 1 ) { + if ( any_signal == 0 ) { + if ( ( (char) sum) != '\0' ) { + pStart = (unsigned char *) pDst; + any_signal = 1; + *pDst++ = ( unsigned char ) sum + ( 1 << 7 ); + } else global.SkippedSamples++; + } else *pDst++ = ( unsigned char ) sum + ( 1 << 7 ); + } else *pDst++ = ( unsigned char ) sum + ( 1 << 7 ); + } else { + Int16_t * myptr = (Int16_t *) pDst; + if ( waitforsignal == 1 ) { + if ( any_signal == 0 ) { + if ( sum != 0 ) { + pStart = (unsigned char *) pDst; + any_signal = 1; + *myptr = sum; pDst += sizeof( Int16_t ); + } else global.SkippedSamples++; + } else { *myptr = sum; pDst += sizeof( Int16_t ); } + } else { *myptr = sum; pDst += sizeof( Int16_t ); } + } + } else { + /* stereo section */ + lsumval >>= global.sh_bits; + rsumval >>= global.sh_bits; + if ( global.sh_bits == 8 ) { + if ( waitforsignal == 1 ) { + if ( any_signal == 0 ) { + if ( ((( char ) lsumval != '\0') || (( char ) rsumval != '\0'))) { + pStart = (unsigned char *) pDst; + any_signal = 1; + *pDst++ = ( unsigned char )( short ) lsumval + ( 1 << 7 ); + *pDst++ = ( unsigned char )( short ) rsumval + ( 1 << 7 ); + } else global.SkippedSamples++; + } else { + *pDst++ = ( unsigned char )( short ) lsumval + ( 1 << 7 ); + *pDst++ = ( unsigned char )( short ) rsumval + ( 1 << 7 ); + } + } else { + *pDst++ = ( unsigned char )( short ) lsumval + ( 1 << 7 ); + *pDst++ = ( unsigned char )( short ) rsumval + ( 1 << 7 ); + } + } else { + Int16_t * myptr = (Int16_t *) pDst; + if ( waitforsignal == 1 ) { + if ( any_signal == 0 ) { + if ( ((( Int16_t ) lsumval != 0) || (( Int16_t ) rsumval != 0))) { + pStart = (unsigned char *) pDst; + any_signal = 1; + *myptr++ = ( Int16_t ) lsumval; + *myptr = ( Int16_t ) rsumval; + pDst += 2*sizeof( Int16_t ); + } else global.SkippedSamples++; + } else { + *myptr++ = ( Int16_t ) lsumval; + *myptr = ( Int16_t ) rsumval; + pDst += 2*sizeof( Int16_t ); + } + } else { + *myptr++ = ( Int16_t ) lsumval; + *myptr = ( Int16_t ) rsumval; + pDst += 2*sizeof( Int16_t ); + } + } + } +} + +static void change_endianness(UINT4 *pSam, unsigned int Samples) +{ + UINT4 *pend = (pSam + Samples); + + /* type UINT4 may not be greater than the assumed biggest type */ +#if (SIZEOF_LONG_INT < 4) +error type unsigned long is too small +#endif + +#if (SIZEOF_LONG_INT == 4) + + unsigned long *plong = (unsigned long *)pSam; + + for (; plong < pend;) { + *plong = ((*plong >> 8L) & UINT_C(0x00ff00ff)) | + ((*plong << 8L) & UINT_C(0xff00ff00)); + plong++; + } +#else /* sizeof long unsigned > 4 bytes */ +#if (SIZEOF_LONG_INT == 8) +#define INTEGRAL_LONGS (SIZEOF_LONG_INT-1UL) + register unsigned long *plong; + unsigned long *pend0 = (unsigned long *) (((unsigned long) pend) & ~ INTEGRAL_LONGS); + + if (((unsigned long) pSam) & INTEGRAL_LONGS) { + *pSam = ((*pSam >> 8L) & UINT_C(0x00ff00ff)) | + ((*pSam << 8L) & UINT_C(0xff00ff00)); + pSam++; + } + + plong = (unsigned long *)pSam; + + for (; plong < pend0;) { + *plong = ((*plong >> 8L) & ULONG_C(0x00ff00ff00ff00ff)) | + ((*plong << 8L) & ULONG_C(0xff00ff00ff00ff00)); + plong++; + } + + if (((unsigned long *) pend) != pend0) { + UINT4 *pint = (UINT4 *) pend0; + + for (;pint < pend;) { + *pint = ((*pint >> 8) & UINT_C(0x00ff00ff)) | + ((*pint << 8) & UINT_C(0xff00ff00)); + pint++; + } + } +#else /* sizeof long unsigned > 4 bytes but not 8 */ + { + UINT4 *pint = pSam; + + for (;pint < pend;) { + *pint = ((*pint >> 8) & UINT_C(0x00ff00ff)) | + ((*pint << 8) & UINT_C(0xff00ff00)); + pint++; + } + } +#endif +#endif +} + +static void swap_channels(UINT4 *pSam, unsigned int Samples) +{ + UINT4 *pend = (pSam + Samples); + + /* type UINT4 may not be greater than the assumed biggest type */ +#if (SIZEOF_LONG_INT < 4) +error type unsigned long is too small +#endif + +#if (SIZEOF_LONG_INT == 4) + + unsigned long *plong = (unsigned long *)pSam; + + for (; plong < pend;) { + *plong = ((*plong >> 16L) & UINT_C(0x0000ffff)) | + ((*plong << 16L) & UINT_C(0xffff0000)); + plong++; + } +#else /* sizeof long unsigned > 4 bytes */ +#if (SIZEOF_LONG_INT == 8) +#define INTEGRAL_LONGS (SIZEOF_LONG_INT-1UL) + register unsigned long *plong; + unsigned long *pend0 = (unsigned long *) (((unsigned long) pend) & ~ INTEGRAL_LONGS); + + if (((unsigned long) pSam) & INTEGRAL_LONGS) { + *pSam = ((*pSam >> 16L) & UINT_C(0x0000ffff)) | + ((*pSam << 16L) & UINT_C(0xffff0000)); + pSam++; + } + + plong = (unsigned long *)pSam; + + for (; plong < pend0;) { + *plong = ((*plong >> 16L) & ULONG_C(0x0000ffff0000ffff)) | + ((*plong << 16L) & ULONG_C(0xffff0000ffff0000)); + plong++; + } + + if (((unsigned long *) pend) != pend0) { + UINT4 *pint = (UINT4 *) pend0; + + for (;pint < pend;) { + *pint = ((*pint >> 16L) & UINT_C(0x0000ffff)) | + ((*pint << 16L) & UINT_C(0xffff0000)); + pint++; + } + } +#else /* sizeof long unsigned > 4 bytes but not 8 */ + { + UINT4 *pint = pSam; + + for (;pint < pend;) { + *pint = ((*pint >> 16L) & UINT_C(0x0000ffff)) | + ((*pint << 16L) & UINT_C(0xffff0000)); + pint++; + } + } +#endif +#endif +} + +#ifdef ECHO_TO_SOUNDCARD +static long ReSampleBuffer(unsigned char *p, unsigned char *newp, + long samples, int samplesize); +static long ReSampleBuffer(unsigned char *p, unsigned char *newp, + long samples, int samplesize) +{ + double idx=0.0; + UINT4 di=0,si=0; + + if (global.playback_rate == 100.0) { + memcpy(newp, p, samplesize* samples); + di = samples; + } else while( si < (UINT4)samples ){ + memcpy( newp+(di*samplesize), p+(si*samplesize), samplesize ); + idx += (double)(global.playback_rate/100.0); + si = (UINT4)idx; + di++; + } + return di*samplesize; +} +#endif + +static int guess_endianess(UINT4 *p, Int16_t *p2, unsigned SamplesToDo) +{ + /* analyse samples */ + int vote_for_little = 0; + int vote_for_big = 0; + int total_votes; + + while (((UINT4 *)p2 - p) + (unsigned) 1 < SamplesToDo) { + unsigned char *p3 = (unsigned char *)p2; +#if MY_LITTLE_ENDIAN == 1 + int diff_lowl = *(p2+0) - *(p2+2); + int diff_lowr = *(p2+1) - *(p2+3); + int diff_bigl = ((*(p3 ) << 8) + *(p3+1)) - ((*(p3+4) << 8) + *(p3+5)); + int diff_bigr = ((*(p3+2) << 8) + *(p3+3)) - ((*(p3+6) << 8) + *(p3+7)); +#else + int diff_lowl = ((*(p3+1) << 8) + *(p3 )) - ((*(p3+5) << 8) + *(p3+4)); + int diff_lowr = ((*(p3+3) << 8) + *(p3+2)) - ((*(p3+7) << 8) + *(p3+6)); + int diff_bigl = *(p2+0) - *(p2+2); + int diff_bigr = *(p2+1) - *(p2+3); +#endif + + if ((abs(diff_lowl) + abs(diff_lowr)) < + (abs(diff_bigl) + abs(diff_bigr))) { + vote_for_little++; + } else { + if ((abs(diff_lowl) + abs(diff_lowr)) > + (abs(diff_bigl) + abs(diff_bigr))) { + vote_for_big++; + } + } + p2 += 2; + } +#ifdef DEBUG_VOTE_ENDIANESS + if (global.quiet != 1) + fprintf(stderr, "votes for little: %4d, votes for big: %4d\n", + vote_for_little, vote_for_big); +#endif + total_votes = vote_for_big + vote_for_little; + if (total_votes < 3 + || abs(vote_for_big - vote_for_little) < total_votes/3) { + return -1; + } else { + if (vote_for_big > vote_for_little) + return 1; + else + return 0; + } +} + +int jitterShift = 0; + +void handle_inputendianess(UINT4 *p, unsigned SamplesToDo) +{ + /* if endianess is unknown, guess endianess based on + differences between succesive samples. If endianess + is correct, the differences are smaller than with the + opposite byte order. + */ + if ((*in_lendian) < 0) { + Int16_t *p2 = (Int16_t *)p; + + /* skip constant samples */ + while ((((UINT4 *)p2 - p) + (unsigned) 1 < SamplesToDo) + && *p2 == *(p2+2)) p2++; + + if (((UINT4 *)p2 - p) + (unsigned) 1 < SamplesToDo) { + switch (guess_endianess(p, p2, SamplesToDo)) { + case -1: break; + case 1: (*in_lendian) = 0; +#if 0 + if (global.quiet != 1) + fprintf(stderr, "big endian detected\n"); +#endif + break; + case 0: (*in_lendian) = 1; +#if 0 + if (global.quiet != 1) + fprintf(stderr, "little endian detected\n"); +#endif + break; + } + } + } + + /* ENDIAN ISSUES: + * the individual endianess of cdrom/cd-writer, cpu, + * sound card and audio output format need a careful treatment. + * + * For possible sample processing (rate conversion) we need + * the samples in cpu byte order. This is the first conversion. + * + * After processing it depends on the endianness of the output + * format, whether a second conversion is needed. + * + */ + + if (global.need_hostorder && (*in_lendian) != MY_LITTLE_ENDIAN) { + /* change endianess of delivered samples to native cpu order */ + change_endianness(p, SamplesToDo); + } +} + +unsigned char * +synchronize(UINT4 *p, unsigned SamplesToDo, unsigned TotSamplesDone) +{ + static int jitter = 0; + char *pSrc; /* start of cdrom buffer */ + + /* synchronisation code */ + if (TotSamplesDone != 0 && global.overlap != 0 && SamplesToDo > CD_FRAMESAMPLES) { + + pSrc = (char *) sync_buffers((unsigned char *)p); + if (!pSrc ) { + return NULL; + } + if (pSrc) { + jitter = ((unsigned char *)pSrc - (((unsigned char *)p) + global.overlap*CD_FRAMESIZE_RAW))/4; + jitterShift += jitter; + SamplesToDo -= jitter + global.overlap*CD_FRAMESAMPLES; +#if 0 + fprintf(stderr, + "Length: pre %d, diff1 %ld, diff2 %ld, min %ld\n", SamplesToDo, + (TotSamplesWanted - TotSamplesDone), + SamplesNeeded((TotSamplesWanted - TotSamplesDone), undersampling), + min(SamplesToDo, SamplesNeeded((TotSamplesWanted - TotSamplesDone), undersampling))); +#endif + } + } else { + pSrc = ( char * ) p; + } + return (unsigned char *) pSrc; +} + +/* convert cdda data to required output format + * sync code for unreliable cdroms included + * + */ +long +SaveBuffer(UINT4 *p, unsigned long SamplesToDo, unsigned long *TotSamplesDone) +{ + UINT4 *pSrc; /* start of cdrom buffer */ + UINT4 *pSrcStop; /* end of cdrom buffer */ + + /* in case of different endianness between host and output format, + or channel swaps, or deemphasizing + copy in a seperate buffer and modify the local copy */ + if ( ((((!global.need_hostorder && global.need_big_endian == (*in_lendian)) || + (global.need_hostorder && global.need_big_endian != MY_BIG_ENDIAN) + ) || (global.deemphasize != 0) + ) && (global.OutSampleSize > 1) + ) || global.swapchannels != 0) { + static UINT4 *localoutputbuffer; + if (localoutputbuffer == NULL) { + localoutputbuffer = malloc(global.nsectors*CD_FRAMESIZE_RAW); + if (localoutputbuffer == NULL) { + perror("cannot allocate local buffer"); + return 1; + } + } + memcpy(localoutputbuffer, p, SamplesToDo*4); + p = localoutputbuffer; + } + + pSrc = p; + pDst = (unsigned char *) p; + pStart = ( unsigned char * ) pSrc; + pSrcStop = pSrc + SamplesToDo; + + /* code for subsampling and output stage */ + + if (global.ismono && global.findmono) { + Int16_t *pmm; + for (pmm = (Int16_t *)pStart; (UINT4 *) pmm < pSrcStop; pmm += 2) { + if (*pmm != *(pmm+1)) { + global.ismono = 0; + break; + } + } + } + /* optimize the case of no conversion */ + if (1 && undersampling == 1 && samples_to_do == 1 && + global.channels == 2 && global.OutSampleSize == 2 && Halved == 0) { + /* output format is the original cdda format -> + * just forward the buffer + */ + + if ( waitforsignal != 0 && any_signal == 0) { + UINT4 *myptr = (UINT4 *)pStart; + while (myptr < pSrcStop && *myptr == 0) myptr++; + pStart = (unsigned char *) myptr; + /* scan for first signal */ + if ( (UINT4 *)pStart != pSrcStop ) { + /* first non null amplitude is found in buffer */ + any_signal = 1; + global.SkippedSamples += ((UINT4 *)pStart - p); + } else { + global.SkippedSamples += (pSrcStop - p); + } + } + pDst = (unsigned char *) pSrcStop; /* set pDst to end */ + + if (global.deemphasize && (Get_Preemphasis(get_current_track())) ) { + /* this implements an attenuation treble shelving filter + to undo the effect of pre-emphasis. The filter is of + a recursive first order */ + static Int16_t lastin[2] = { 0, 0 }; + static double lastout[2] = { 0.0, 0.0 }; + Int16_t *pmm; + + /* Here is the gnuplot file for the frequency response + of the deemphasis. The error is below +-0.1dB + +# first define the ideal filter. We use the tenfold sampling frequency. +T=1./441000. +OmegaU=1./15E-6 +OmegaL=15./50.*OmegaU +V0=OmegaL/OmegaU +H0=V0-1. +B=V0*tan(OmegaU*T/2.) +# the coefficients follow +a1=(B - 1.)/(B + 1.) +b0=(1.0 + (1.0 - a1) * H0/2.) +b1=(a1 + (a1 - 1.0) * H0/2.) +# helper variables +D=b1/b0 +o=2*pi*T +H2(f)=b0*sqrt((1+2*cos(f*o)*D+D*D)/(1+2*cos(f*o)*a1+a1*a1)) +# now approximate the ideal curve with a fitted one for sampling frequency +# of 44100 Hz. +T2=1./44100. +V02=0.3365 +OmegaU2=1./19E-6 +B2=V02*tan(OmegaU2*T2/2.) +# the coefficients follow +a12=(B2 - 1.)/(B2 + 1.) +b02=(1.0 + (1.0 - a12) * (V02-1.)/2.) +b12=(a12 + (a12 - 1.0) * (V02-1.)/2.) +# helper variables +D2=b12/b02 +o2=2*pi*T2 +H(f)=b02*sqrt((1+2*cos(f*o2)*D2+D2*D2)/(1+2*cos(f*o2)*a12+a12*a12)) +# plot best, real, ideal, level with halved attenuation, +# level at full attentuation, 10fold magnified error +set logscale x +set grid xtics ytics mxtics mytics +plot [f=1000:20000] [-12:2] 20*log10(H(f)),20*log10(H2(f)), 20*log10(OmegaL/(2*pi*f)), 0.5*20*log10(V0), 20*log10(V0), 200*log10(H(f)/H2(f)) +pause -1 "Hit return to continue" + */ + +#ifdef TEST +#define V0 0.3365 +#define OMEGAG (1./19e-6) +#define T (1./44100.) +#define H0 (V0-1.) +#define B (V0*tan((OMEGAG * T)/2.0)) +#define a1 ((B - 1.)/(B + 1.)) +#define b0 (1.0 + (1.0 - a1) * H0/2.0) +#define b1 (a1 + (a1 - 1.0) * H0/2.0) +#undef V0 +#undef OMEGAG +#undef T +#undef H0 +#undef B +#else +#define a1 -0.62786881719628784282 +#define b0 0.45995451989513153057 +#define b1 -0.08782333709141937339 +#endif + + for (pmm = (Int16_t *)pStart; pmm < (Int16_t *)pDst;) { + lastout[0] = *pmm * b0 + lastin[0] * b1 - lastout[0] * a1; + lastin[0] = *pmm; + *pmm++ = lastout[0] > 0.0 ? lastout[0] + 0.5 : lastout[0] - 0.5; + lastout[1] = *pmm * b0 + lastin[1] * b1 - lastout[1] * a1; + lastin[1] = *pmm; + *pmm++ = lastout[1] > 0.0 ? lastout[1] + 0.5 : lastout[1] - 0.5; + } +#undef a1 +#undef b0 +#undef b1 + } + + if (global.swapchannels == 1) { + swap_channels((UINT4 *)pStart, SamplesToDo); + } + + if (global.findminmax) { + Int16_t *pmm; + for (pmm = (Int16_t *)pStart; pmm < (Int16_t *)pDst; pmm++) { + if (*pmm < global.minamp[1]) global.minamp[1] = *pmm; + if (*pmm > global.maxamp[1]) global.maxamp[1] = *pmm; + pmm++; + if (*pmm < global.minamp[0]) global.minamp[0] = *pmm; + if (*pmm > global.maxamp[0]) global.maxamp[0] = *pmm; + } + } + } else { + +#define none_missing 0 +#define one_missing 1 +#define two_missing 2 +#define collecting 3 + + static int sample_state = collecting; + static int Toggle_on = 0; + + if (global.channels == 2 && global.swapchannels == 1) { + swap_channels((UINT4 *)pStart, SamplesToDo); + } + + /* conversion required */ + while ( pSrc < pSrcStop ) { + + long l,r; + + long iSamples_left = (pSrcStop - pSrc) / sizeof(Int16_t) / 2; + Int16_t *myptr = (Int16_t *) pSrc; + + /* LSB l, MSB l */ + l = *myptr++; /* left channel */ + r = *myptr++; /* right channel */ + pSrc = (UINT4 *) myptr; + + switch (sample_state) { + case two_missing: +two__missing: + ls2 += l; rs2 += r; + if (undersampling > 1) { + ls3 += l; rs3 += r; + } + sample_state = one_missing; + break; + case one_missing: + auxl = l; auxr = r; + + ls3 += l; rs3 += r; + sample_state = none_missing; + + /* FALLTHROUGH */ +none__missing: + case none_missing: + /* Filtered samples are complete. Now interpolate and scale. */ + + if (Halved != 0 && Toggle_on == 0) { + lsum = interpolate(lsum, ls2, ls3)/(int) undersampling; + rsum = interpolate(rsum, rs2, rs3)/(int) undersampling; + } else { + lsum /= (int) undersampling; + rsum /= (int) undersampling; + } + emit_sample(lsum, rsum, global.channels); + /* reload counter */ + samples_to_do = undersampling - 1; + lsum = auxl; + rsum = auxr; + /* reset sample register */ + auxl = ls2 = ls3 = 0; + auxr = rs2 = rs3 = 0; + Toggle_on ^= 1; + sample_state = collecting; + break; + case collecting: + if ( samples_to_do > 0) { + samples_to_do--; + if (Halved != 0 && Toggle_on == 0) { + /* Divider x.5 : we need data for quadratic interpolation */ + iSamples_left--; + + lsum += l; rsum += r; + if ( samples_to_do < undersampling - 1) { + ls2 += l; rs2 += r; + } + if ( samples_to_do < undersampling - 2) { + ls3 += l; rs3 += r; + } + } else { + /* integral divider */ + lsum += l; + rsum += r; + iSamples_left--; + } + } else { + if (Halved != 0 && Toggle_on == 0) { + sample_state = two_missing; + goto two__missing; + } else { + auxl = l; + auxr = r; + sample_state = none_missing; + goto none__missing; + } + } + break; + } /* switch state */ + + } /* while */ + + /* flush_buffer */ + if ((samples_to_do == 0 && Halved == 0)) + { + if (Halved != 0 && Toggle_on == 0) { + lsum = interpolate(lsum, ls2, ls3)/(int) undersampling; + rsum = interpolate(rsum, rs2, rs3)/(int) undersampling; + } else { + lsum /= (int) undersampling; + rsum /= (int) undersampling; + } + emit_sample(lsum, rsum, global.channels); + + /* reload counter */ + samples_to_do = undersampling; + + /* reset sample register */ + lsum = auxl = ls2 = ls3 = 0; + rsum = auxr = rs2 = rs3 = 0; + Toggle_on ^= 1; + sample_state = collecting; + } + + } /* if optimize else */ + + if ( waitforsignal == 0 ) pStart = (unsigned char *)p; + + if ( waitforsignal == 0 || any_signal != 0) { + int retval = 0; + unsigned outlen; + unsigned todo; + + assert(pDst >= pStart); + outlen = (size_t) (pDst - pStart); + + if (outlen <= 0) return 0; + +#ifdef ECHO_TO_SOUNDCARD + + /* this assumes the soundcard needs samples in native cpu byte order */ + if (global.echo != 0) { + static unsigned char *newp; + unsigned newlen; + + newlen = (100*(outlen/4))/global.playback_rate; + newlen = (newlen*4); + if ( (newp != NULL) || (newp = malloc( 2*global.nsectors*CD_FRAMESIZE_RAW+32 )) ) { + newlen = ReSampleBuffer( pStart, newp, outlen/4, global.OutSampleSize*global.channels ); + write_snd_device((char *)newp, newlen); + } + } +#endif + + if ( global.no_file != 0 ) { + *TotSamplesDone += SamplesToDo; + return 0; + } + if ( (!global.need_hostorder && global.need_big_endian == (*in_lendian)) || + (global.need_hostorder && global.need_big_endian != MY_BIG_ENDIAN)) { + if ( global.OutSampleSize > 1) { + /* change endianness from input sample or native cpu order + to required output endianness */ + change_endianness((UINT4 *)pStart, outlen/4); + } + } + { + unsigned char * p2 = pStart; + + todo = outlen; + while (todo != 0) { + int retval_; + retval_ = global.audio_out->WriteSound ( global.audio, p2, todo ); + if (retval_ < 0) break; + + p2 += retval_; + todo -= retval_; + } + } + if (todo == 0) { + *TotSamplesDone += SamplesToDo; + return 0; + } else { + fprintf(stderr, "write(audio, 0x%p, %u) = %d\n",pStart,outlen,retval); + perror("Probably disk space exhausted"); + return 1; + } + } else { + *TotSamplesDone += SamplesToDo; + return 0; + } +} diff --git a/icedax/resample.h b/icedax/resample.h new file mode 100644 index 0000000..d25216c --- /dev/null +++ b/icedax/resample.h @@ -0,0 +1,26 @@ +/* + * 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. + * + */ + +/* @(#)resample.h 1.3 02/08/02 Copyright 1998,1999 Heiko Eissfeldt */ +#define SYNC_SIZE 600 /* has to be smaller than CD_FRAMESAMPLES */ + +extern int waitforsignal; /* flag: wait for any audio response */ +extern int any_signal; + +extern short undersampling; /* conversion factor */ +extern short samples_to_do; /* loop variable for conversion */ +extern int Halved; /* interpolate due to non integral divider */ +extern int jitterShift; /* track accumulated jitter */ +long SaveBuffer(UINT4 *p, unsigned long SecsToDo, unsigned long *BytesDone); +unsigned char *synchronize(UINT4 *p, unsigned SamplesToDo, + unsigned TotSamplesDone); +void handle_inputendianess(UINT4 *p, unsigned SamplesToDo); diff --git a/icedax/ringbuff.c b/icedax/ringbuff.c new file mode 100644 index 0000000..6678ffb --- /dev/null +++ b/icedax/ringbuff.c @@ -0,0 +1,231 @@ +/* + * 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. + * + */ + +/* @(#)ringbuff.c 1.8 02/11/21 Copyright 1998,1999,2000 Heiko Eissfeldt */ +#include "config.h" + +#include <stdxlib.h> +#include <stdio.h> +#include <standard.h> +#include <unixstd.h> + +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) +#include <sys/ipc.h> +#include <sys/sem.h> +#endif + +#include <usal/scsitransp.h> + +#include "mytype.h" +#include "global.h" +#include "interface.h" +#include "ringbuff.h" +#include "semshm.h" +#include "exitcodes.h" + +#undef WARN_INTERRUPT +#undef _DEBUG +#include <assert.h> + +static void occupy_buffer(void); + +myringbuff **he_fill_buffer; +myringbuff **last_buffer; +volatile unsigned long *total_segments_read; +volatile unsigned long *total_segments_written; +volatile int *child_waits; +volatile int *parent_waits; +volatile int *in_lendian; +volatile int *eorecording; + +static myringbuff *previous_read_buffer; +static unsigned int total_buffers; + +#define SEMS 2 + +#define defined_buffers() ((*total_segments_read) - (*total_segments_written)) +#define free_buffers() (total_buffers - defined_buffers()) +#define occupied_buffers() (defined_buffers()) + +/* ARGSUSED */ +void set_total_buffers(unsigned int num_buffers, int mysem_id) +{ +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) + union my_semun mysemun; + + mysemun.val = 0; + if (semctl(mysem_id,(int) DEF_SEM,SETVAL,mysemun) < 0) { + perror("semctl DEF_SEM"); + } + + mysemun.val = num_buffers; + if (semctl(mysem_id,(int) FREE_SEM,SETVAL,mysemun) < 0) { + perror("semctl FREE_SEM"); + } +#endif + + total_buffers = num_buffers; + + /* initialize pointers */ + *he_fill_buffer = *last_buffer = previous_read_buffer = NULL; +#ifdef DEBUG_SHM +fprintf(stderr, "init: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer); +#endif +} + +const myringbuff *get_previous_read_buffer() +{ + assert(previous_read_buffer != NULL); + assert(previous_read_buffer != *he_fill_buffer); + return previous_read_buffer; +} + +const myringbuff *get_he_fill_buffer() +{ + assert(*he_fill_buffer != NULL); + assert(previous_read_buffer != *he_fill_buffer); + return *he_fill_buffer; +} + +void define_buffer() +{ + assert(defined_buffers() < total_buffers); + +#ifdef _DEBUG +#if 0 + fprintf(stderr,"stop reading %p - %p\n", + *he_fill_buffer, (char *)(*he_fill_buffer) + ENTRY_SIZE -1); +#endif +#endif + + if (*last_buffer == NULL) + *last_buffer = *he_fill_buffer; +#ifdef DEBUG_SHM +fprintf(stderr, "define: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer); +#endif + + (*total_segments_read)++; + semrelease(sem_id,DEF_SEM,1); +} + +void drop_buffer() +{ + assert(free_buffers() < total_buffers); + assert(occupied_buffers() > 0); + +#ifdef _DEBUG +#if 0 + fprintf(stderr," stop writing %p - %p ", + *last_buffer, (char *)(*last_buffer) + ENTRY_SIZE -1); +#endif +#endif + + if (*last_buffer == NULL) + *last_buffer = *he_fill_buffer; + else + *last_buffer = INC(*last_buffer); +#ifdef DEBUG_SHM +fprintf(stderr, "drop: fill_b = %p, last_b = %p\n", *he_fill_buffer, *last_buffer); +#endif + (*total_segments_written)++; + semrelease(sem_id,FREE_SEM, 1); +} + +void drop_all_buffers() +{ + (*total_segments_written) = (*total_segments_read); + semrelease(sem_id,FREE_SEM, total_buffers); +} + +static void occupy_buffer() +{ + assert(occupied_buffers() <= total_buffers); + + previous_read_buffer = *he_fill_buffer; + + if (*he_fill_buffer == NULL) { + *he_fill_buffer = RB_BASE; + } else { + *he_fill_buffer = INC(*he_fill_buffer); + } +} + +#if defined HAVE_FORK_AND_SHAREDMEM +myringbuff * get_next_buffer() +{ +#ifdef WARN_INTERRUPT + if (free_buffers() <= 0) { + fprintf(stderr, "READER waits!! r=%lu, w=%lu\n", *total_segments_read, +*total_segments_written); + } +#endif + + /* wait for a new buffer to become available */ + if (semrequest(sem_id,FREE_SEM) != 0) { + /* semaphore operation failed. + try again... + */ + fprintf(stderr, "child reader sem request failed\n"); + exit(SEMAPHORE_ERROR); + } +#if 0 + fprintf(stderr,"start reading %p - %p\n", + *he_fill_buffer, (char *)(*fill_buffer) + ENTRY_SIZE -1); +#endif + + occupy_buffer(); + +#ifdef DEBUG_SHM +fprintf(stderr, "next: fill_b = %p, last_b = %p, @last = %p\n", *he_fill_buffer, *last_buffer, last_buffer); +#endif + return *he_fill_buffer; +} + +myringbuff *get_oldest_buffer() +{ + myringbuff *retval; + +#ifdef WARN_INTERRUPT + if (free_buffers() == total_buffers) { + fprintf(stderr, "WRITER waits!! r=%lu, w=%lu\n", *total_segments_read, + *total_segments_written); + } +#endif + /* wait for buffer to be defined */ + if (semrequest(sem_id,DEF_SEM) != 0) { + /* semaphore operation failed. */ + perror("request defined buff:"); + fprintf(stderr, "parent writer sem request failed\n"); + } + + retval = *last_buffer; + +#if 0 + fprintf(stderr," begin writing %p - %p\n", + retval, (char *)retval + ENTRY_SIZE -1); +#endif + + return retval; +} +#else /* HAVE_FORK_AND_SHAREDMEM */ +myringbuff * get_next_buffer() +{ + occupy_buffer(); + return *he_fill_buffer; +} + +myringbuff * get_oldest_buffer() +{ + return *he_fill_buffer; +} +#endif /* HAVE_FORK_AND_SHAREDMEM */ + diff --git a/icedax/ringbuff.h b/icedax/ringbuff.h new file mode 100644 index 0000000..6c85b3a --- /dev/null +++ b/icedax/ringbuff.h @@ -0,0 +1,97 @@ +/* + * 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. + * + */ + +/* @(#)ringbuff.h 1.5 01/10/20 Copyright 1998,1999,2000 Heiko Eissfeldt */ +/* This file contains data structures that reside in the shared memory + * segment. + */ + + +/* the linux semctl prototype is broken as is the definition + of union semun in sys/sem.h. */ + +#ifdef HAVE_UNION_SEMUN +# define my_semun semun +#else +union my_semun { + int val; + struct semid_ds *pid; + unsigned short *array; +}; +#endif + +/* Ringbuffer structures. + Space for the ringbuffer is allocated page aligned + and contains the following + + -------------------- start of page + header (once for the ring buffer) \\ + space for page alignment ||+- HEADER_SIZE +RB_BASE -+v || + myringbuffer.offset |/ + -------------------- start of page/-- pagesize + myringbuffer.data (SEGMENT_SIZE)\ + space for page alignment |+- ENTRY_SIZE_PAGE_AL + myringbuffer.offset / + -------------------- start of page + myringbuffer.data + space for page alignment + ... +*/ +typedef struct { + int offset; + UINT4 data[CD_FRAMESAMPLES]; +} myringbuff; + +struct ringbuffheader { + myringbuff *p1; + myringbuff *p2; + volatile unsigned long total_read; + volatile unsigned long total_written; + volatile int child_waitstate; + volatile int parent_waitstate; + volatile int input_littleendian; + volatile int end_is_reached; + volatile unsigned long nSamplesToDo; + int offset; + UINT4 data[CD_FRAMESAMPLES]; +}; + +extern myringbuff **he_fill_buffer; +extern myringbuff **last_buffer; +extern volatile unsigned long *total_segments_read; +extern volatile unsigned long *total_segments_written; +extern volatile int *child_waits; +extern volatile int *parent_waits; +extern volatile int *in_lendian; +extern volatile int *eorecording; + +#define palign(x, a) (((char *)(x)) + ((a) - 1 - (((unsigned)((x)-1))%(a)))) +#define multpage(x, a) ((((x) + (a) - 1) / (a)) * (a)) + +#define HEADER_SIZE multpage(offset_of(struct ringbuffheader, data), global.pagesize) +#define SEGMENT_SIZE (global.nsectors*CD_FRAMESIZE_RAW) +#define ENTRY_SIZE_PAGE_AL multpage(SEGMENT_SIZE + offset_of(myringbuff, data), global.pagesize) + +#define RB_BASE ((myringbuff *)(((unsigned char *)he_fill_buffer) + HEADER_SIZE - offset_of(myringbuff, data))) + +#define INC(a) (myringbuff *)(((char *)RB_BASE) + (((((char *) (a))-((char *)RB_BASE))/ENTRY_SIZE_PAGE_AL + 1) % total_buffers)*ENTRY_SIZE_PAGE_AL) + + +void set_total_buffers(unsigned int num_buffers, int mysem_id); +const myringbuff *get_previous_read_buffer(void); +const myringbuff *get_he_fill_buffer(void); +myringbuff *get_next_buffer(void); +myringbuff *get_oldest_buffer(void); +void define_buffer(void); +void drop_buffer(void); +void drop_all_buffers(void); diff --git a/icedax/scsi_cmds.c b/icedax/scsi_cmds.c new file mode 100644 index 0000000..e77b3af --- /dev/null +++ b/icedax/scsi_cmds.c @@ -0,0 +1,1720 @@ +/* + * 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. + * + */ + +/* @(#)scsi_cmds.c 1.29 03/03/31 Copyright 1998-2002 Heiko Eissfeldt */ +/* file for all SCSI commands + * FUA (Force Unit Access) bit handling copied from Monty's cdparanoia. + */ +#undef DEBUG_FULLTOC +#undef WARN_FULLTOC +#define TESTSUBQFALLBACK 0 + +#include "config.h" +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <schily.h> + +#include <btorder.h> + +#define g5x_cdblen(cdb, len) ((cdb)->count[0] = ((len) >> 16L)& 0xFF,\ + (cdb)->count[1] = ((len) >> 8L) & 0xFF,\ + (cdb)->count[2] = (len) & 0xFF) + + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> + +#include <usal/scsitransp.h> + +#include "mytype.h" +#include "icedax.h" +#include "interface.h" +#include "byteorder.h" +#include "global.h" +#include "wodim.h" +#include "toc.h" +#include "scsi_cmds.h" +#include "exitcodes.h" + +unsigned char *bufferTOC; +subq_chnl *SubQbuffer; +unsigned char *cmd; + +static unsigned ReadFullTOCSony(SCSI *usalp); +static unsigned ReadFullTOCMMC(SCSI *usalp); + + +int SCSI_emulated_ATAPI_on(SCSI *usalp) +{ +/* return is_atapi;*/ + if (usal_isatapi(usalp) > 0) + return (TRUE); + + (void) allow_atapi(usalp, TRUE); + return (allow_atapi(usalp, TRUE)); +} + +int heiko_mmc(SCSI *usalp) +{ + unsigned char mode[0x100]; + int was_atapi; + struct cd_mode_page_2A *mp; + int retval; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + + was_atapi = allow_atapi(usalp, 1); + usalp->silent++; + mp = mmc_cap(usalp, mode); + usalp->silent--; + allow_atapi(usalp, was_atapi); + if (mp == NULL) + return (0); + + /* have a look at the capabilities */ + if (mp->cd_da_supported == 0) { + retval = -1; + } else { + retval = 1 + mp->cd_da_accurate; + } + return retval; +} + + +int accepts_fua_bit; +unsigned char density = 0; +unsigned char orgmode4 = 0; +unsigned char orgmode10, orgmode11; + +/* get current sector size from SCSI cdrom drive */ +unsigned int +get_orig_sectorsize(SCSI *usalp, unsigned char *m4, unsigned char *m10, + unsigned char *m11) +{ + /* first get current values for density, etc. */ + + static unsigned char *modesense = NULL; + + if (modesense == NULL) { + modesense = malloc(12); + if (modesense == NULL) { + fprintf(stderr, "Cannot allocate memory for mode sense command in line %d\n", __LINE__); + return 0; + } + } + + /* do the scsi cmd */ + if (usalp->verbose) fprintf(stderr, "\nget density and sector size..."); + if (mode_sense(usalp, modesense, 12, 0x01, 0) < 0) + fprintf(stderr, "get_orig_sectorsize mode sense failed\n"); + + /* FIXME: some drives dont deliver block descriptors !!! */ + if (modesense[3] == 0) + return 0; + +#if 0 + modesense[4] = 0x81; + modesense[10] = 0x08; + modesense[11] = 0x00; +#endif + + if (m4 != NULL) /* density */ + *m4 = modesense[4]; + if (m10 != NULL) /* MSB sector size */ + *m10 = modesense[10]; + if (m11 != NULL) /* LSB sector size */ + *m11 = modesense[11]; + + return (modesense[10] << 8) + modesense[11]; +} + + + +/* switch CDROM scsi drives to given sector size */ +int set_sectorsize(SCSI *usalp, unsigned int secsize) +{ + static unsigned char mode [4 + 8]; + int retval; + + if (orgmode4 == 0xff) { + get_orig_sectorsize(usalp, &orgmode4, &orgmode10, &orgmode11); + } + if (orgmode4 == 0x82 && secsize == 2048) + orgmode4 = 0x81; + + /* prepare to read cds in the previous mode */ + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + mode[ 3] = 8; /* Block Descriptor Length */ + mode[ 4] = orgmode4; /* normal density */ + mode[10] = secsize >> 8; /* block length "msb" */ + mode[11] = secsize & 0xFF; /* block length lsb */ + + if (usalp->verbose) fprintf(stderr, "\nset density and sector size..."); + /* do the scsi cmd */ + if ((retval = mode_select(usalp, mode, 12, 0, usalp->inq->data_format >= 2)) < 0) + fprintf (stderr, "setting sector size failed\n"); + + return retval; +} + + +/* switch Toshiba/DEC and HP drives from/to cdda density */ +void EnableCddaModeSelect(SCSI *usalp, int fAudioMode, unsigned uSectorsize) +{ + /* reserved, Medium type=0, Dev spec Parm = 0, block descriptor len 0 oder 8, + Density (cd format) + (0=YellowBook, XA Mode 2=81h, XA Mode1=83h and raw audio via SCSI=82h), + # blks msb, #blks, #blks lsb, reserved, + blocksize, blocklen msb, blocklen lsb, + */ + + /* MODE_SELECT, page = SCSI-2 save page disabled, reserved, reserved, + parm list len, flags */ + static unsigned char mode [4 + 8] = { + /* mode section */ + 0, + 0, 0, + 8, /* Block Descriptor Length */ + /* block descriptor */ + 0, /* Density Code */ + 0, 0, 0, /* # of Blocks */ + 0, /* reserved */ + 0, 0, 0};/* Blocklen */ + + if (orgmode4 == 0 && fAudioMode) { + if (0 == get_orig_sectorsize(usalp, &orgmode4, &orgmode10, &orgmode11)) { + /* cannot retrieve density, sectorsize */ + orgmode10 = (CD_FRAMESIZE >> 8L); + orgmode11 = (CD_FRAMESIZE & 0xFF); + } + } + + if (fAudioMode) { + /* prepare to read audio cdda */ + mode [4] = density; /* cdda density */ + mode [10] = (uSectorsize >> 8L); /* block length "msb" */ + mode [11] = (uSectorsize & 0xFF); /* block length "lsb" */ + } else { + /* prepare to read cds in the previous mode */ + mode [4] = orgmode4; /* 0x00; \* normal density */ + mode [10] = orgmode10; /* (CD_FRAMESIZE >> 8L); \* block length "msb" */ + mode [11] = orgmode11; /* (CD_FRAMESIZE & 0xFF); \* block length lsb */ + } + + if (usalp->verbose) fprintf(stderr, "\nset density/sector size (EnableCddaModeSelect)...\n"); + /* do the scsi cmd */ + if (mode_select(usalp, mode, 12, 0, usalp->inq->data_format >= 2) < 0) + fprintf (stderr, "Audio mode switch failed\n"); +} + + +/* read CD Text information from the table of contents */ +void ReadTocTextSCSIMMC(SCSI *usalp) +{ + short datalength; + +#if 1 + /* READTOC, MSF, format, res, res, res, Start track/session, len msb, + len lsb, control */ + unsigned char *p = bufferTOC; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOC; + scmd->size = 4; + 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 = 0x43; /* Read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = 5; /* format field */ + scmd->cdb.g1_cdb.res6 = 0; /* track/session is reserved */ + g1_cdblen(&scmd->cdb.g1_cdb, 4); + + usalp->silent++; + if (usalp->verbose) fprintf(stderr, "\nRead TOC CD Text size ..."); + + usalp->cmdname = "read toc size (text)"; + + if (usal_cmd(usalp) < 0) { + usalp->silent--; + if (global.quiet != 1) + fprintf (stderr, "Read TOC CD Text failed (probably not supported).\n"); + p[0] = p[1] = '\0'; + return ; + } + usalp->silent--; + + datalength = (p[0] << 8) | (p[1]); + if (datalength <= 2) + return; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOC; + scmd->size = 2+datalength; + 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 = 0x43; /* Read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = 5; /* format field */ + scmd->cdb.g1_cdb.res6 = 0; /* track/session is reserved */ + g1_cdblen(&scmd->cdb.g1_cdb, 2+datalength); + + usalp->silent++; + if (usalp->verbose) fprintf(stderr, "\nRead TOC CD Text data (length %hd)...", 2+datalength); + + usalp->cmdname = "read toc data (text)"; + + if (usal_cmd(usalp) < 0) { + usalp->silent--; + if (global.quiet != 1) + fprintf (stderr, "Read TOC CD Text data failed (probably not supported).\n"); + p[0] = p[1] = '\0'; + return ; + } + usalp->silent--; +#else + { FILE *fp; + int read_; + /*fp = fopen("PearlJam.cdtext", "rb");*/ + /*fp = fopen("celine.cdtext", "rb");*/ + fp = fopen("japan.cdtext", "rb"); + if (fp == NULL) { perror(""); return; } + fillbytes(bufferTOC, CD_FRAMESIZE, '\0'); + read_ = fread(bufferTOC, 1, CD_FRAMESIZE, fp ); +fprintf(stderr, "read %d bytes. sizeof(bufferTOC)=%u\n", read_, CD_FRAMESIZE); + datalength = (bufferTOC[0] << 8) | (bufferTOC[1]); + fclose(fp); + } +#endif +} + +/* read the full TOC */ +static unsigned ReadFullTOCSony(SCSI *usalp) +{ + /* READTOC, MSF, format, res, res, res, Start track/session, len msb, + len lsb, control */ + register struct usal_cmd *scmd = usalp->scmd; + unsigned tracks = 99; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOC; + scmd->size = 4 + (3 + tracks + 6) * 11; + 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 = 0x43; /* Read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.res6 = 1; /* session */ + g1_cdblen(&scmd->cdb.g1_cdb, 4 + (3 + tracks + 6) * 11); + scmd->cdb.g1_cdb.vu_97 = 1; /* format */ + + usalp->silent++; + if (usalp->verbose) fprintf(stderr, "\nRead Full TOC Sony ..."); + + usalp->cmdname = "read full toc sony"; + + if (usal_cmd(usalp) < 0) { + usalp->silent--; + if (global.quiet != 1) + fprintf (stderr, "Read Full TOC Sony failed (probably not supported).\n"); + return 0; + } + usalp->silent--; + + return (unsigned)((bufferTOC[0] << 8) | bufferTOC[1]); +} + +struct msf_address { + unsigned char mins; + unsigned char secs; + unsigned char frame; +}; + +struct zmsf_address { + unsigned char zero; + unsigned char mins; + unsigned char secs; + unsigned char frame; +}; + +#ifdef WARN_FULLTOC +static unsigned lba(struct msf_address *ad); + +static unsigned lba(struct msf_address *ad) +{ + return ad->mins*60*75 + ad->secs*75 + ad->frame; +} +#endif + +static unsigned dvd_lba(struct zmsf_address *ad); + +static unsigned dvd_lba(struct zmsf_address *ad) +{ + return ad->zero*1053696 + ad->mins*60*75 + ad->secs*75 + ad->frame; +} + +struct tocdesc { + unsigned char session; + unsigned char adrctl; + unsigned char tno; + unsigned char point; + struct msf_address adr1; + struct zmsf_address padr2; +}; + +struct outer { + unsigned char len_msb; + unsigned char len_lsb; + unsigned char first_track; + unsigned char last_track; + struct tocdesc ent[1]; +}; + +static unsigned long first_session_leadout = 0; + +static unsigned collect_tracks(struct outer *po, unsigned entries, + BOOL bcd_flag); + +static unsigned collect_tracks(struct outer *po, unsigned entries, + BOOL bcd_flag) +{ + unsigned tracks = 0; + int i; + unsigned session; + unsigned last_start; + unsigned leadout_start_orig; + unsigned leadout_start; + unsigned max_leadout = 0; + +#ifdef DEBUG_FULLTOC + for (i = 0; i < entries; i++) { +fprintf(stderr, "%3d: %d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n" + ,i + ,bufferTOC[4+0 + (i * 11)] + ,bufferTOC[4+1 + (i * 11)] + ,bufferTOC[4+2 + (i * 11)] + ,bufferTOC[4+3 + (i * 11)] + ,bufferTOC[4+4 + (i * 11)] + ,bufferTOC[4+5 + (i * 11)] + ,bufferTOC[4+6 + (i * 11)] + ,bufferTOC[4+7 + (i * 11)] + ,bufferTOC[4+8 + (i * 11)] + ,bufferTOC[4+9 + (i * 11)] + ,bufferTOC[4+10 + (i * 11)] + ); + } +#endif + /* reformat to standard toc format */ + + bufferTOC[2] = 0; + bufferTOC[3] = 0; + session = 0; + last_start = 0; + leadout_start_orig = 0; + leadout_start = 0; + + for (i = 0; i < entries; i++) { +#ifdef WARN_FULLTOC + if (po->ent[i].tno != 0) { + fprintf(stderr, +"entry %d, tno is not 0: %d!\n", +i, po->ent[i].tno); + } +#endif + if (bcd_flag) { + po->ent[i].session = from_bcd(po->ent[i].session); + po->ent[i].adr1.mins = from_bcd(po->ent[i].adr1.mins); + po->ent[i].adr1.secs = from_bcd(po->ent[i].adr1.secs); + po->ent[i].adr1.frame = from_bcd(po->ent[i].adr1.frame); + po->ent[i].padr2.mins = from_bcd(po->ent[i].padr2.mins); + po->ent[i].padr2.secs = from_bcd(po->ent[i].padr2.secs); + po->ent[i].padr2.frame = from_bcd(po->ent[i].padr2.frame); + } + switch (po->ent[i].point) { + case 0xa0: + + /* check if session is monotonous increasing */ + + if (session+1 == po->ent[i].session) { + session = po->ent[i].session; + } +#ifdef WARN_FULLTOC + else fprintf(stderr, +"entry %d, session anomaly %d != %d!\n", +i, session+1, po->ent[i].session); + + /* check the adrctl field */ + if (0x10 != (po->ent[i].adrctl & 0x10)) { + fprintf(stderr, +"entry %d, incorrect adrctl field %x!\n", +i, po->ent[i].adrctl); + } +#endif + /* first track number */ + if (bufferTOC[2] < po->ent[i].padr2.mins + && bufferTOC[3] < po->ent[i].padr2.mins) { + bufferTOC[2] = po->ent[i].padr2.mins; + } +#ifdef WARN_FULLTOC + else + fprintf(stderr, +"entry %d, session %d: start tracknumber anomaly: %d <= %d,%d(last)!\n", +i, session, po->ent[i].padr2.mins, bufferTOC[2], bufferTOC[3]); +#endif + break; + + case 0xa1: +#ifdef WARN_FULLTOC + /* check if session is constant */ + if (session != po->ent[i].session) { + fprintf(stderr, +"entry %d, session anomaly %d != %d!\n", +i, session, po->ent[i].session); + } + + /* check the adrctl field */ + if (0x10 != (po->ent[i].adrctl & 0x10)) { + fprintf(stderr, +"entry %d, incorrect adrctl field %x!\n", +i, po->ent[i].adrctl); + } +#endif + /* last track number */ + if (bufferTOC[2] <= po->ent[i].padr2.mins + && bufferTOC[3] < po->ent[i].padr2.mins) { + bufferTOC[3] = po->ent[i].padr2.mins; + } +#ifdef WARN_FULLTOC + else + fprintf(stderr, +"entry %d, session %d: end tracknumber anomaly: %d <= %d,%d(last)!\n", +i, session, po->ent[i].padr2.mins, bufferTOC[2], bufferTOC[3]); +#endif + break; + + case 0xa2: +#ifdef WARN_FULLTOC + /* check if session is constant */ + if (session != po->ent[i].session) { + fprintf(stderr, +"entry %d, session anomaly %d != %d!\n", +i, session, po->ent[i].session); + } + + /* check the adrctl field */ + if (0x10 != (po->ent[i].adrctl & 0x10)) { + fprintf(stderr, +"entry %d, incorrect adrctl field %x!\n", +i, po->ent[i].adrctl); + } +#endif + /* register leadout position */ + { + unsigned leadout_start_tmp = + dvd_lba(&po->ent[i].padr2); + + if (first_session_leadout == 0) + first_session_leadout = leadout_start_tmp - 150; + + if (leadout_start_tmp > leadout_start) { + leadout_start_orig = leadout_start_tmp; + leadout_start = leadout_start_tmp; + } +#ifdef WARN_FULLTOC + else + fprintf(stderr, +"entry %d, leadout position anomaly %u!\n", +i, leadout_start_tmp); +#endif + } + break; + + case 0xb0: +#ifdef WARN_FULLTOC + /* check if session is constant */ + if (session != po->ent[i].session) { + fprintf(stderr, +"entry %d, session anomaly %d != %d!\n", +i, session, po->ent[i].session); + } + + /* check the adrctl field */ + if (0x50 != (po->ent[i].adrctl & 0x50)) { + fprintf(stderr, +"entry %d, incorrect adrctl field %x!\n", +i, po->ent[i].adrctl); + } + + /* check the next program area */ + if (lba(&po->ent[i].adr1) < 6750 + leadout_start) { + fprintf(stderr, +"entry %d, next program area %u < leadout_start + 6750 = %u!\n", +i, lba(&po->ent[i].adr1), 6750 + leadout_start); + } + + /* check the maximum leadout_start */ + if (max_leadout != 0 && dvd_lba(&po->ent[i].padr2) != max_leadout) { + fprintf(stderr, +"entry %d, max leadout_start %u != last max_leadout_start %u!\n", +i, dvd_lba(&po->ent[i].padr2), max_leadout); + } +#endif + if (max_leadout == 0) + max_leadout = dvd_lba(&po->ent[i].padr2); + + break; + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + break; + case 0xc0: + case 0xc1: + break; + default: + /* check if session is constant */ + if (session != po->ent[i].session) { +#ifdef WARN_FULLTOC + fprintf(stderr, +"entry %d, session anomaly %d != %d!\n", +i, session, po->ent[i].session); +#endif + continue; + } + + /* check tno */ + if (bcd_flag) + po->ent[i].point = from_bcd(po->ent[i].point); + + if (po->ent[i].point < bufferTOC[2] + || po->ent[i].point > bufferTOC[3]) { +#ifdef WARN_FULLTOC + fprintf(stderr, +"entry %d, track number anomaly %d - %d - %d!\n", +i, bufferTOC[2], po->ent[i].point, bufferTOC[3]); +#endif + } else { + /* check start position */ + unsigned trackstart = dvd_lba(&po->ent[i].padr2); + + /* correct illegal leadouts */ + if (leadout_start < trackstart) { + leadout_start = trackstart+1; + } + if (trackstart < last_start || trackstart >= leadout_start) { +#ifdef WARN_FULLTOC + fprintf(stderr, +"entry %d, track %d start position anomaly %d - %d - %d!\n", +i, po->ent[i].point, last_start, trackstart, leadout_start); +#endif + } else { + last_start = trackstart; + memcpy(&po->ent[tracks], &po->ent[i], sizeof(struct tocdesc)); + tracks++; + } + } + } /* switch */ + } /* for */ + + /* patch leadout track */ + po->ent[tracks].session = session; + po->ent[tracks].adrctl = 0x10; + po->ent[tracks].tno = 0; + po->ent[tracks].point = 0xAA; + po->ent[tracks].adr1.mins = 0; + po->ent[tracks].adr1.secs = 0; + po->ent[tracks].adr1.frame = 0; + po->ent[tracks].padr2.zero = leadout_start_orig / (1053696); + po->ent[tracks].padr2.mins = (leadout_start_orig / (60*75)) % 100; + po->ent[tracks].padr2.secs = (leadout_start_orig / 75) % 60; + po->ent[tracks].padr2.frame = leadout_start_orig % 75; + tracks++; + + /* length */ + bufferTOC[0] = ((tracks * 8) + 2) >> 8; + bufferTOC[1] = ((tracks * 8) + 2) & 0xff; + + + /* reformat 11 byte blocks to 8 byte entries */ + + /* 1: Session \ / reserved + 2: adr ctrl | | adr ctrl + 3: TNO | | track number + 4: Point | | reserved + 5: Min +-->----+ 0 + 6: Sec | | Min + 7: Frame | | Sec + 8: Zero | \ Frame + 9: PMin | + 10: PSec | + 11: PFrame / + */ + for (i = 0; i < tracks; i++) { + bufferTOC[4+0 + (i << 3)] = 0; + bufferTOC[4+1 + (i << 3)] = bufferTOC[4+1 + (i*11)]; + bufferTOC[4+1 + (i << 3)] = (bufferTOC[4+1 + (i << 3)] >> 4) | (bufferTOC[4+1 + (i << 3)] << 4); + bufferTOC[4+2 + (i << 3)] = bufferTOC[4+3 + (i*11)]; + bufferTOC[4+3 + (i << 3)] = 0; + bufferTOC[4+4 + (i << 3)] = bufferTOC[4+7 + (i*11)]; + bufferTOC[4+5 + (i << 3)] = bufferTOC[4+8 + (i*11)]; + bufferTOC[4+6 + (i << 3)] = bufferTOC[4+9 + (i*11)]; + bufferTOC[4+7 + (i << 3)] = bufferTOC[4+10 + (i*11)]; +#ifdef DEBUG_FULLTOC +fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n" + ,bufferTOC[4+ 1 + i*8] + ,bufferTOC[4+ 2 + i*8] + ,bufferTOC[4+ 4 + i*8] + ,bufferTOC[4+ 5 + i*8] + ,bufferTOC[4+ 6 + i*8] + ,bufferTOC[4+ 7 + i*8] +); +#endif + } + + TOC_entries(tracks, NULL, bufferTOC+4, 0); + return tracks; +} + +/* read the table of contents from the cd and fill the TOC array */ +unsigned ReadTocSony(SCSI *usalp) +{ + unsigned tracks = 0; + unsigned return_length; + + struct outer *po = (struct outer *)bufferTOC; + + return_length = ReadFullTOCSony(usalp); + + /* Check if the format was understood */ + if ((return_length & 7) == 2 && (bufferTOC[3] - bufferTOC[2]) == (return_length >> 3)) { + /* The extended format seems not be understood, fallback to + * the classical format. */ + return ReadTocSCSI( usalp ); + } + + tracks = collect_tracks(po, ((return_length - 2) / 11), TRUE); + + return --tracks; /* without lead-out */ +} + +/* read the start of the lead-out from the first session TOC */ +unsigned ReadFirstSessionTOCSony(SCSI *usalp) +{ + unsigned return_length; + + if (first_session_leadout != 0) + return first_session_leadout; + + return_length = ReadFullTOCSony(usalp); + if (return_length >= 4 + (3 * 11) -2) { + unsigned off; + + /* We want the entry with POINT = 0xA2, which has the start position + of the first session lead out */ + off = 4 + 2 * 11 + 3; + if (bufferTOC[off-3] == 1 && bufferTOC[off] == 0xA2) { + unsigned retval; + + off = 4 + 2 * 11 + 8; + retval = bufferTOC[off] >> 4; + retval *= 10; retval += bufferTOC[off] & 0xf; + retval *= 60; + off++; + retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf); + retval *= 75; + off++; + retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf); + retval -= 150; + + return retval; + } + } + return 0; +} + +/* read the full TOC */ +static unsigned ReadFullTOCMMC(SCSI *usalp) +{ + + /* READTOC, MSF, format, res, res, res, Start track/session, len msb, + len lsb, control */ + register struct usal_cmd *scmd = usalp->scmd; + unsigned tracks = 99; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOC; + scmd->size = 4 + (tracks + 8) * 11; + 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 = 0x43; /* Read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = 2; /* format */ + scmd->cdb.g1_cdb.res6 = 1; /* session */ + g1_cdblen(&scmd->cdb.g1_cdb, 4 + (tracks + 8) * 11); + + usalp->silent++; + if (usalp->verbose) fprintf(stderr, "\nRead Full TOC MMC..."); + + usalp->cmdname = "read full toc mmc"; + + if (usal_cmd(usalp) < 0) { + if (global.quiet != 1) + fprintf (stderr, "Read Full TOC MMC failed (probably not supported).\n"); +#ifdef B_BEOS_VERSION +#else + usalp->silent--; + return 0; +#endif + } + usalp->silent--; + + return (unsigned)((bufferTOC[0] << 8) | bufferTOC[1]); +} + +/* read the start of the lead-out from the first session TOC */ +unsigned ReadFirstSessionTOCMMC(SCSI *usalp) +{ + unsigned off; + unsigned return_length; + + if (first_session_leadout != 0) + return first_session_leadout; + + return_length = ReadFullTOCMMC(usalp); + + /* We want the entry with POINT = 0xA2, which has the start position + of the first session lead out */ + off = 4 + 3; + while (off < return_length && bufferTOC[off] != 0xA2) { + off += 11; + } + if (off < return_length) { + off += 5; + return (bufferTOC[off]*60 + bufferTOC[off+1])*75 + bufferTOC[off+2] - 150; + } + return 0; +} + +/* read the table of contents from the cd and fill the TOC array */ +unsigned ReadTocMMC(SCSI *usalp) +{ + unsigned tracks = 0; + unsigned return_length; + + struct outer *po = (struct outer *)bufferTOC; + + return_length = ReadFullTOCMMC(usalp); + if (return_length - 2 < 4*11 || ((return_length - 2) % 11) != 0) + return ReadTocSCSI(usalp); + + tracks = collect_tracks(po, ((return_length - 2) / 11), FALSE); + return --tracks; /* without lead-out */ +} + +/* read the table of contents from the cd and fill the TOC array */ +unsigned ReadTocSCSI(SCSI *usalp) +{ + unsigned tracks; + int result; + unsigned char bufferTOCMSF[CD_FRAMESIZE]; + + /* first read the first and last track number */ + /* READTOC, MSF format flag, res, res, res, res, Start track, len msb, + len lsb, flags */ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOC; + scmd->size = 4; + 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 = 0x43; /* read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.res6 = 1; /* start track */ + g1_cdblen(&scmd->cdb.g1_cdb, 4); + + if (usalp->verbose) fprintf(stderr, "\nRead TOC size (standard)..."); + /* do the scsi cmd (read table of contents) */ + + usalp->cmdname = "read toc size"; + if (usal_cmd(usalp) < 0) + FatalError ("Read TOC size failed.\n"); + + + tracks = ((bufferTOC [3] ) - bufferTOC [2] + 2) ; + if (tracks > MAXTRK) return 0; + if (tracks == 0) return 0; + + + memset(bufferTOCMSF, 0, sizeof(bufferTOCMSF)); + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOCMSF; + scmd->size = 4 + tracks * 8; + 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 = 0x43; /* read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.res = 1; /* MSF format */ + scmd->cdb.g1_cdb.res6 = 1; /* start track */ + g1_cdblen(&scmd->cdb.g1_cdb, 4 + tracks * 8); + + if (usalp->verbose) fprintf(stderr, "\nRead TOC tracks (standard MSF)..."); + /* do the scsi cmd (read table of contents) */ + + usalp->cmdname = "read toc tracks "; + result = usal_cmd(usalp); + + if (result < 0) { + /* MSF format did not succeeded */ + memset(bufferTOCMSF, 0, sizeof(bufferTOCMSF)); + } else { + int i; + for (i = 0; i < tracks; i++) { + bufferTOCMSF[4+1 + (i << 3)] = (bufferTOCMSF[4+1 + (i << 3)] >> 4) | (bufferTOCMSF[4+1 + (i << 3)] << 4); +#if 0 +fprintf(stderr, "MSF %d %02x %02x %02x %02x %02x %02x %02x %02x\n" + ,i + ,bufferTOCMSF[4+0 + (i * 8)] + ,bufferTOCMSF[4+1 + (i * 8)] + ,bufferTOCMSF[4+2 + (i * 8)] + ,bufferTOCMSF[4+3 + (i * 8)] + ,bufferTOCMSF[4+4 + (i * 8)] + ,bufferTOCMSF[4+5 + (i * 8)] + ,bufferTOCMSF[4+6 + (i * 8)] + ,bufferTOCMSF[4+7 + (i * 8)] + ); +#endif + } + } + + /* LBA format for cd burners like Philips CD-522 */ + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)bufferTOC; + scmd->size = 4 + tracks * 8; + 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 = 0x43; /* read TOC command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.res = 0; /* LBA format */ + scmd->cdb.g1_cdb.res6 = 1; /* start track */ + g1_cdblen(&scmd->cdb.g1_cdb, 4 + tracks * 8); + + if (usalp->verbose) fprintf(stderr, "\nRead TOC tracks (standard LBA)..."); + /* do the scsi cmd (read table of contents) */ + + usalp->cmdname = "read toc tracks "; + if (usal_cmd(usalp) < 0) { + FatalError ("Read TOC tracks (lba) failed.\n"); + } + { + int i; + for (i = 0; i < tracks; i++) { + bufferTOC[4+1 + (i << 3)] = (bufferTOC[4+1 + (i << 3)] >> 4) | (bufferTOC[4+1 + (i << 3)] << 4); +#if 0 +fprintf(stderr, "LBA %d %02x %02x %02x %02x %02x %02x %02x %02x\n" + ,i + ,bufferTOC[4+0 + (i * 8)] + ,bufferTOC[4+1 + (i * 8)] + ,bufferTOC[4+2 + (i * 8)] + ,bufferTOC[4+3 + (i * 8)] + ,bufferTOC[4+4 + (i * 8)] + ,bufferTOC[4+5 + (i * 8)] + ,bufferTOC[4+6 + (i * 8)] + ,bufferTOC[4+7 + (i * 8)] + ); +#endif + } + } + TOC_entries(tracks, bufferTOC+4, bufferTOCMSF+4, result); + return --tracks; /* without lead-out */ +} + +/* ---------------- Read methods ------------------------------ */ + +/* Read max. SectorBurst of cdda sectors to buffer + via standard SCSI-2 Read(10) command */ +static int ReadStandardLowlevel(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal, unsigned secsize); + +static int ReadStandardLowlevel(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal, unsigned secsize) +{ + /* READ10, flags, block1 msb, block2, block3, block4 lsb, reserved, + transfer len msb, transfer len lsb, block addressing mode */ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal * secsize; + 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; /* read 10 command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); + g1_cdbaddr(&scmd->cdb.g1_cdb, lSector); + g1_cdblen(&scmd->cdb.g1_cdb, SectorBurstVal); + if (usalp->verbose) fprintf(stderr, "\nReadStandard10 %s (%u)...", secsize > 2048 ? "CDDA" : "CD_DATA", secsize); + + usalp->cmdname = "ReadStandard10"; + + if (usal_cmd(usalp)) return 0; + + /* has all or something been read? */ + return SectorBurstVal - usal_getresid(usalp)/secsize; +} + + +int +ReadStandard(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal) +{ + return ReadStandardLowlevel(usalp, p, lSector, SectorBurstVal, CD_FRAMESIZE_RAW); +} + +int +ReadStandardData(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal) +{ + return ReadStandardLowlevel(usalp, p, lSector, SectorBurstVal, CD_FRAMESIZE); +} + +/* Read max. SectorBurst of cdda sectors to buffer + via vendor-specific ReadCdda(10) command */ +int ReadCdda10(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal) +{ + /* READ10, flags, block1 msb, block2, block3, block4 lsb, reserved, + transfer len msb, transfer len lsb, block addressing mode */ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; + 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 = 0xd4; /* Read audio command */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); + g1_cdbaddr(&scmd->cdb.g1_cdb, lSector); + g1_cdblen(&scmd->cdb.g1_cdb, SectorBurstVal); + if (usalp->verbose) fprintf(stderr, "\nReadNEC10 CDDA..."); + + usalp->cmdname = "Read10 NEC"; + + if (usal_cmd(usalp)) return 0; + + /* has all or something been read? */ + return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW; +} + + +/* Read max. SectorBurst of cdda sectors to buffer + via vendor-specific ReadCdda(12) command */ +int ReadCdda12(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; + 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; /* read audio command */ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); + g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); + g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); + + if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA..."); + + usalp->cmdname = "Read12"; + + if (usal_cmd(usalp)) return 0; + + /* has all or something been read? */ + return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW; +} + +/* Read max. SectorBurst of cdda sectors to buffer + via vendor-specific ReadCdda(12) command */ +/* +> It uses a 12 Byte CDB with 0xd4 as opcode, the start sector is coded as +> normal and the number of sectors is coded in Byte 8 and 9 (begining with 0). +*/ + +int ReadCdda12Matsushita(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; + 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 = 0xd4; /* read audio command */ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); + g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); + g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); + + if (usalp->verbose) fprintf(stderr, "\nReadMatsushita12 CDDA..."); + + usalp->cmdname = "Read12Matsushita"; + + if (usal_cmd(usalp)) return 0; + + /* has all or something been read? */ + return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW; +} + +/* Read max. SectorBurst of cdda sectors to buffer + via MMC standard READ CD command */ +int ReadCddaMMC12(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + register struct usal_cmd *scmd; + scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; + 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; /* read cd command */ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.res = 1 << 1; /* expected sector type field CDDA */ + g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); + g5x_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); + scmd->cdb.g5_cdb.count[3] = 1 << 4; /* User data */ + + if (usalp->verbose) fprintf(stderr, "\nReadMMC12 CDDA..."); + + usalp->cmdname = "ReadCD MMC 12"; + + if (usal_cmd(usalp)) return 0; + + /* has all or something been read? */ + return SectorBurstVal - usal_getresid(usalp)/CD_FRAMESIZE_RAW; +} + +int ReadCddaFallbackMMC(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + static int ReadCdda12_unknown = 0; + int retval = -999; + + usalp->silent++; + if (ReadCdda12_unknown + || ((retval = ReadCdda12(usalp, p, lSector, SectorBurstVal)) <= 0)) { + /* if the command is not available, use the regular + * MMC ReadCd + */ + if (retval <= 0 && usal_sense_key(usalp) == 0x05) { + ReadCdda12_unknown = 1; + } + usalp->silent--; + ReadCdRom = ReadCddaMMC12; + ReadCdRomSub = ReadCddaSubMMC12; + return ReadCddaMMC12(usalp, p, lSector, SectorBurstVal); + } + usalp->silent--; + return retval; +} + +/* Read the Sub-Q-Channel to SubQbuffer. This is the method for + * drives that do not support subchannel parameters. */ +#ifdef PROTOTYPES +static subq_chnl *ReadSubQFallback (SCSI *usalp, unsigned char sq_format, unsigned char track) +#else +static subq_chnl * +ReadSubQFallback(SCSI *usalp, unsigned char sq_format, unsigned char track) +#endif +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)SubQbuffer; + scmd->size = 24; + 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 = 0x42; /* Read SubQChannel */ + /* use LBA */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = 0x40; /* SubQ info */ + scmd->cdb.g1_cdb.addr[1] = 0; /* parameter list: all */ + scmd->cdb.g1_cdb.res6 = track; /* track number */ + g1_cdblen(&scmd->cdb.g1_cdb, 24); + + if (usalp->verbose) fprintf(stderr, "\nRead Subchannel_dumb..."); + + usalp->cmdname = "Read Subchannel_dumb"; + + if (usal_cmd(usalp) < 0) { + fprintf( stderr, "Read SubQ failed\n"); + } + + /* check, if the requested format is delivered */ + { unsigned char *p = (unsigned char *) SubQbuffer; + if ((((unsigned)p[2] << 8) | p[3]) /* LENGTH */ > ULONG_C(11) && + (p[5] >> 4) /* ADR */ == sq_format) { + if (sq_format == GET_POSITIONDATA) + p[5] = (p[5] << 4) | (p[5] >> 4); + return SubQbuffer; + } + } + + /* FIXME: we might actively search for the requested info ... */ + return NULL; +} + +/* Read the Sub-Q-Channel to SubQbuffer */ +#ifdef PROTOTYPES +subq_chnl *ReadSubQSCSI (SCSI *usalp, unsigned char sq_format, unsigned char track) +#else +subq_chnl * +ReadSubQSCSI(SCSI *usalp, unsigned char sq_format, unsigned char track) +#endif +{ + int resp_size; + register struct usal_cmd *scmd = usalp->scmd; + + switch (sq_format) { + case GET_POSITIONDATA: + resp_size = 16; + track = 0; + break; + case GET_CATALOGNUMBER: + resp_size = 24; + track = 0; + break; + case GET_TRACK_ISRC: + resp_size = 24; + break; + default: + fprintf(stderr, "ReadSubQSCSI: unknown format %d\n", sq_format); + return NULL; + } + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)SubQbuffer; + scmd->size = resp_size; + 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 = 0x42; + /* use LBA */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = 0x40; /* SubQ info */ + scmd->cdb.g1_cdb.addr[1] = sq_format; /* parameter list: all */ + scmd->cdb.g1_cdb.res6 = track; /* track number */ + g1_cdblen(&scmd->cdb.g1_cdb, resp_size); + + if (usalp->verbose) fprintf(stderr, "\nRead Subchannel..."); + + usalp->cmdname = "Read Subchannel"; + + if (usal_cmd(usalp) < 0) { + /* in case of error do a fallback for dumb firmwares */ + return ReadSubQFallback(usalp, sq_format, track); + } + + if (sq_format == GET_POSITIONDATA) + SubQbuffer->control_adr = (SubQbuffer->control_adr << 4) | (SubQbuffer->control_adr >> 4); + return SubQbuffer; +} + +static subq_chnl sc; + +static subq_chnl* fill_subchannel(unsigned char bufferwithQ[]); +static subq_chnl* fill_subchannel(unsigned char bufferwithQ[]) +{ + sc.subq_length = 0; + sc.control_adr = bufferwithQ[CD_FRAMESIZE_RAW + 0]; + sc.track = bufferwithQ[CD_FRAMESIZE_RAW + 1]; + sc.index = bufferwithQ[CD_FRAMESIZE_RAW + 2]; + return ≻ +} + +int +ReadCddaSubSony(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*(CD_FRAMESIZE_RAW + 16); + 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; /* read audio command */ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); + scmd->cdb.g5_cdb.res10 = 0x01; /* subcode 1 -> cdda + 16 * q sub */ + g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); + g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); + + if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA + SubChannels..."); + + usalp->cmdname = "Read12SubChannelsSony"; + + if (usal_cmd(usalp)) return -1; + + /* has all or something been read? */ + return usal_getresid(usalp) != 0; +} + +int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); + +int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*(CD_FRAMESIZE_RAW + 96); + 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; /* read audio command */ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); + scmd->cdb.g5_cdb.res10 = 0x02; /* subcode 2 -> cdda + 96 * q sub */ + g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); + g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); + + if (usalp->verbose) fprintf(stderr, "\nReadSony12 CDDA + 96 byte SubChannels..."); + + usalp->cmdname = "Read12SubChannelsSony"; + + if (usal_cmd(usalp)) return -1; + + /* has all or something been read? */ + return usal_getresid(usalp) != 0; +} + +subq_chnl *ReadSubChannelsSony(SCSI *usalp, unsigned lSector) +{ + /*int retval = ReadCddaSub96Sony(usalp, (UINT4 *)bufferTOC, lSector, 1);*/ + int retval = ReadCddaSubSony(usalp, (UINT4 *)bufferTOC, lSector, 1); + if (retval != 0) return NULL; + + return fill_subchannel(bufferTOC); +} + +/* Read max. SectorBurst of cdda sectors to buffer + via MMC standard READ CD command */ +int ReadCddaSubMMC12(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal) +{ + register struct usal_cmd *scmd; + scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)p; + scmd->size = SectorBurstVal*(CD_FRAMESIZE_RAW + 16); + 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; /* read cd command */ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.res = 1 << 1; /* expected sector type field CDDA */ + g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); + g5x_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); + scmd->cdb.g5_cdb.count[3] = 1 << 4; /* User data */ + scmd->cdb.g5_cdb.res10 = 0x02; /* subcode 2 -> cdda + 16 * q sub */ + + if (usalp->verbose) fprintf(stderr, "\nReadMMC12 CDDA + SUB..."); + + usalp->cmdname = "ReadCD Sub MMC 12"; + + if (usal_cmd(usalp)) return -1; + + /* has all or something been read? */ + return usal_getresid(usalp) != 0; +} + +static subq_chnl *ReadSubChannelsMMC(SCSI *usalp, unsigned lSector); +static subq_chnl *ReadSubChannelsMMC(SCSI *usalp, unsigned lSector) +{ + int retval = ReadCddaSubMMC12(usalp, (UINT4 *)bufferTOC, lSector, 1); + if (retval != 0) return NULL; + + return fill_subchannel(bufferTOC); +} + +subq_chnl *ReadSubChannelsFallbackMMC(SCSI *usalp, unsigned lSector) +{ + static int ReadSubSony_unknown = 0; + subq_chnl *retval = NULL; + + usalp->silent++; + if (ReadSubSony_unknown + || ((retval = ReadSubChannelsSony(usalp, lSector)) == NULL)) { + /* if the command is not available, use the regular + * MMC ReadCd + */ + if (retval == NULL && usal_sense_key(usalp) == 0x05) { + ReadSubSony_unknown = 1; + } + usalp->silent--; + return ReadSubChannelsMMC(usalp, lSector); + } + usalp->silent--; + return retval; +} + +subq_chnl *ReadStandardSub(usalp, lSector) + SCSI *usalp; + unsigned lSector; +{ + if (0 == ReadStandardLowlevel (usalp, (UINT4 *)bufferTOC, lSector, 1, CD_FRAMESIZE_RAW + 16 )) { + return NULL; + } +#if 0 +fprintf(stderr, "Subchannel Sec %x: %02x %02x %02x %02x\n" + ,lSector + ,bufferTOC[CD_FRAMESIZE_RAW + 0] + ,bufferTOC[CD_FRAMESIZE_RAW + 1] + ,bufferTOC[CD_FRAMESIZE_RAW + 2] + ,bufferTOC[CD_FRAMESIZE_RAW + 3] + ); +#endif + sc.control_adr = (bufferTOC[CD_FRAMESIZE_RAW + 0] << 4) + | bufferTOC[CD_FRAMESIZE_RAW + 1]; + sc.track = from_bcd(bufferTOC[CD_FRAMESIZE_RAW + 2]); + sc.index = from_bcd(bufferTOC[CD_FRAMESIZE_RAW + 3]); + return ≻ +} +/********* non standardized speed selects ***********************/ + +void SpeedSelectSCSIToshiba(SCSI *usalp, unsigned speed) +{ + static unsigned char mode [4 + 3]; + unsigned char *page = mode + 4; + int retval; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + /* the first 4 mode bytes are zero. */ + page[0] = 0x20; + page[1] = 1; + page[2] = speed; /* 0 for single speed, 1 for double speed (3401) */ + + if (usalp->verbose) fprintf(stderr, "\nspeed select Toshiba..."); + + usalp->silent++; + /* do the scsi cmd */ + if ((retval = mode_select(usalp, mode, 7, 0, usalp->inq->data_format >= 2)) < 0) + fprintf (stderr, "speed select Toshiba failed\n"); + usalp->silent--; +} + +void SpeedSelectSCSINEC(SCSI *usalp, unsigned speed) +{ + static unsigned char mode [4 + 8]; + unsigned char *page = mode + 4; + int retval; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + /* the first 4 mode bytes are zero. */ + page [0] = 0x0f; /* page code */ + page [1] = 6; /* parameter length */ + /* bit 5 == 1 for single speed, otherwise double speed */ + page [2] = speed == 1 ? 1 << 5 : 0; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)mode; + scmd->size = 12; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xC5; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = 0 ? 1 : 0 | 1 ? 0x10 : 0; + g1_cdblen(&scmd->cdb.g1_cdb, 12); + + if (usalp->verbose) fprintf(stderr, "\nspeed select NEC..."); + /* do the scsi cmd */ + + usalp->cmdname = "speed select NEC"; + + if ((retval = usal_cmd(usalp)) < 0) + fprintf(stderr ,"speed select NEC failed\n"); +} + +void SpeedSelectSCSIPhilipsCDD2600(SCSI *usalp, unsigned speed) +{ + /* MODE_SELECT, page = SCSI-2 save page disabled, reserved, reserved, + parm list len, flags */ + static unsigned char mode [4 + 8]; + unsigned char *page = mode + 4; + int retval; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + /* the first 4 mode bytes are zero. */ + page[0] = 0x23; + page[1] = 6; + page[2] = page [4] = speed; + page[3] = 1; + + if (usalp->verbose) fprintf(stderr, "\nspeed select Philips..."); + /* do the scsi cmd */ + if ((retval = mode_select(usalp, mode, 12, 0, usalp->inq->data_format >= 2)) < 0) + fprintf (stderr, "speed select PhilipsCDD2600 failed\n"); +} + +void SpeedSelectSCSISony(SCSI *usalp, unsigned speed) +{ + static unsigned char mode [4 + 4]; + unsigned char *page = mode + 4; + int retval; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + /* the first 4 mode bytes are zero. */ + page[0] = 0x31; + page[1] = 2; + page[2] = speed; + + if (usalp->verbose) fprintf(stderr, "\nspeed select Sony..."); + /* do the scsi cmd */ + usalp->silent++; + if ((retval = mode_select(usalp, mode, 8, 0, usalp->inq->data_format >= 2)) < 0) + fprintf (stderr, "speed select Sony failed\n"); + usalp->silent--; +} + +void SpeedSelectSCSIYamaha (usalp, speed) + SCSI *usalp; + unsigned speed; +{ + static unsigned char mode [4 + 4]; + unsigned char *page = mode + 4; + int retval; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + /* the first 4 mode bytes are zero. */ + page[0] = 0x31; + page[1] = 2; + page[2] = speed; + + if (usalp->verbose) fprintf(stderr, "\nspeed select Yamaha..."); + /* do the scsi cmd */ + if ((retval = mode_select(usalp, mode, 8, 0, usalp->inq->data_format >= 2)) < 0) + fprintf (stderr, "speed select Yamaha failed\n"); +} + +void SpeedSelectSCSIMMC(SCSI *usalp, unsigned speed) +{ + int spd; + register struct usal_cmd *scmd = usalp->scmd; + + if (speed == 0 || speed == 0xFFFF) { + spd = 0xFFFF; + } else { + spd = (1764 * speed) / 10; + } + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xBB; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], spd); + i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], 0xffff); + + if (usalp->verbose) fprintf(stderr, "\nspeed select MMC..."); + + usalp->cmdname = "set cd speed"; + + usalp->silent++; + if (usal_cmd(usalp) < 0) { + if (usal_sense_key(usalp) == 0x05 && + usal_sense_code(usalp) == 0x20 && + usal_sense_qual(usalp) == 0x00) { + /* this optional command is not implemented */ + } else { + usal_printerr(usalp); + fprintf (stderr, "speed select MMC failed\n"); + } + } + usalp->silent--; +} + +/* request vendor brand and model */ +unsigned char *Inquiry(SCSI *usalp) +{ + static unsigned char *Inqbuffer = NULL; + register struct usal_cmd *scmd = usalp->scmd; + + if (Inqbuffer == NULL) { + Inqbuffer = malloc(36); + if (Inqbuffer == NULL) { + fprintf(stderr, "Cannot allocate memory for inquiry command in line %d\n", __LINE__); + return NULL; + } + } + + fillbytes(Inqbuffer, 36, '\0'); + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)Inqbuffer; + scmd->size = 36; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_INQUIRY; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.count = 36; + + usalp->cmdname = "inquiry"; + + if (usal_cmd(usalp) < 0) + return (NULL); + + /* define structure with inquiry data */ + memcpy(usalp->inq, Inqbuffer, sizeof(*usalp->inq)); + + if (usalp->verbose) + usal_prbytes("Inquiry Data :", (Uchar *)Inqbuffer, 22 - scmd->resid); + + return (Inqbuffer); +} + +#define SC_CLASS_EXTENDED_SENSE 0x07 +#define TESTUNITREADY_CMD 0 +#define TESTUNITREADY_CMDLEN 6 + +#define ADD_SENSECODE 12 +#define ADD_SC_QUALIFIER 13 +#define NO_MEDIA_SC 0x3a +#define NO_MEDIA_SCQ 0x00 + +int TestForMedium(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (interface != GENERIC_SCSI) { + return 1; + } + + /* request READY status */ + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA | (1 ? SCG_SILENT:0); + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_TEST_UNIT_READY; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + + if (usalp->verbose) fprintf(stderr, "\ntest unit ready..."); + usalp->silent++; + + usalp->cmdname = "test unit ready"; + + if (usal_cmd(usalp) >= 0) { + usalp->silent--; + return 1; + } + usalp->silent--; + + if (scmd->sense.code >= SC_CLASS_EXTENDED_SENSE) { + return + scmd->u_sense.cmd_sense[ADD_SENSECODE] != NO_MEDIA_SC || + scmd->u_sense.cmd_sense[ADD_SC_QUALIFIER] != NO_MEDIA_SCQ; + } else { + /* analyse status. */ + /* 'check condition' is interpreted as not ready. */ + return (scmd->u_scb.cmd_scb[0] & 0x1e) != 0x02; + } +} + +int StopPlaySCSI(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = NULL; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = 0x1b; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + + if (usalp->verbose) fprintf(stderr, "\nstop audio play"); + /* do the scsi cmd */ + + usalp->cmdname = "stop audio play"; + + return usal_cmd(usalp) >= 0 ? 0 : -1; +} + +int Play_atSCSI(SCSI *usalp, unsigned int from_sector, unsigned int sectors) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = NULL; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x47; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[1] = (from_sector + 150) / (60*75); + scmd->cdb.g1_cdb.addr[2] = ((from_sector + 150) / 75) % 60; + scmd->cdb.g1_cdb.addr[3] = (from_sector + 150) % 75; + scmd->cdb.g1_cdb.res6 = (from_sector + 150 + sectors) / (60*75); + scmd->cdb.g1_cdb.count[0] = ((from_sector + 150 + sectors) / 75) % 60; + scmd->cdb.g1_cdb.count[1] = (from_sector + 150 + sectors) % 75; + + if (usalp->verbose) fprintf(stderr, "\nplay sectors..."); + /* do the scsi cmd */ + + usalp->cmdname = "play sectors"; + + return usal_cmd(usalp) >= 0 ? 0 : -1; +} + +static caddr_t scsibuffer; /* page aligned scsi transfer buffer */ + +void init_scsibuf(SCSI *scsp, unsigned amt); + +void init_scsibuf(SCSI *usalp, unsigned amt) +{ + if (scsibuffer != NULL) { + fprintf(stderr, "the SCSI transfer buffer has already been allocated!\n"); + exit(SETUPSCSI_ERROR); + } + scsibuffer = usal_getbuf(usalp, amt); + if (scsibuffer == NULL) { + fprintf(stderr, "could not get SCSI transfer buffer!\n"); + exit(SETUPSCSI_ERROR); + } +} diff --git a/icedax/scsi_cmds.h b/icedax/scsi_cmds.h new file mode 100644 index 0000000..d82d1c9 --- /dev/null +++ b/icedax/scsi_cmds.h @@ -0,0 +1,71 @@ +/* + * 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. + * + */ + +/* @(#)scsi_cmds.h 1.11 03/03/02 Copyright 1998,1999 Heiko Eissfeldt */ +/* header file for scsi_cmds.c */ + +extern unsigned char *cmd; +struct TOC; +int SCSI_emulated_ATAPI_on(SCSI *usalp); +unsigned char *Inquiry(SCSI *usalp); +int TestForMedium(SCSI *usalp); +void SpeedSelectSCSIMMC(SCSI *usalp, unsigned speed); +void SpeedSelectSCSIYamaha(SCSI *usalp, unsigned speed); +void SpeedSelectSCSISony(SCSI *usalp, unsigned speed); +void SpeedSelectSCSIPhilipsCDD2600(SCSI *usalp, unsigned speed); +void SpeedSelectSCSINEC(SCSI *usalp, unsigned speed); +void SpeedSelectSCSIToshiba(SCSI *usalp, unsigned speed); +subq_chnl *ReadSubQSCSI(SCSI *usalp, unsigned char sq_format, + unsigned char ltrack); +subq_chnl *ReadSubChannelsSony(SCSI *usalp, unsigned lSector); +subq_chnl *ReadSubChannelsFallbackMMC(SCSI *usalp, unsigned lSector); +subq_chnl *ReadStandardSub(SCSI *usalp, unsigned lSector); +int ReadCddaMMC12(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +int ReadCdda12Matsushita(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +int ReadCdda12(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SecorBurstVal); +int ReadCdda10(SCSI *usalp, UINT4 *p, unsigned lSector, unsigned SecorBurstVal); +int ReadStandard(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SctorBurstVal); +int ReadStandardData(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SctorBurstVal); +int ReadCddaFallbackMMC(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SctorBurstVal); +int ReadCddaSubSony(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +int ReadCddaSub96Sony(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +int ReadCddaSubMMC12(SCSI *usalp, UINT4 *p, unsigned lSector, + unsigned SectorBurstVal); +unsigned ReadTocSony(SCSI *usalp); +unsigned ReadTocMMC(SCSI *usalp); +unsigned ReadTocSCSI(SCSI *usalp); +unsigned ReadFirstSessionTOCSony(SCSI *usalp); +unsigned ReadFirstSessionTOCMMC(SCSI *usalp); +void ReadTocTextSCSIMMC(SCSI *usalp); +int Play_atSCSI(SCSI *usalp, unsigned int from_sector, unsigned int sectors); +int StopPlaySCSI(SCSI *usalp); +void EnableCddaModeSelect(SCSI *usalp, int fAudioMode, unsigned uSectorsize); +int set_sectorsize(SCSI *usalp, unsigned int secsize); +unsigned int +get_orig_sectorsize(SCSI *usalp, unsigned char *m4, unsigned char *m10, + unsigned char *m11); +int heiko_mmc(SCSI *usalp); +void init_scsibuf(SCSI *usalp, unsigned amt); +int myscsierr(SCSI *usalp); + +extern int accepts_fua_bit; +extern unsigned char density; +extern unsigned char orgmode4; +extern unsigned char orgmode10, orgmode11; + diff --git a/icedax/semshm.c b/icedax/semshm.c new file mode 100644 index 0000000..6c6edc7 --- /dev/null +++ b/icedax/semshm.c @@ -0,0 +1,473 @@ +/* + * 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. + * + */ + +/* + * Copyright 1998-2002 Heiko Eissfeldt + */ + +#define IPCTST +#undef IPCTST +/* -------------------------------------------------------------------- */ +/* semshm.c */ +/* -------------------------------------------------------------------- */ +/* int seminstall(key,amount) */ +/* int semrequest(semid,semnum) */ +/* int semrelease(semid,semnum) */ +/* -------------------------------------------------------------------- */ + +#include "config.h" + +#if !defined(HAVE_SMMAP) && !defined(HAVE_USGSHM) && !defined(HAVE_DOSALLOCSHAREDMEM) && !defined(HAVE_AREAS) +#undef FIFO /* We cannot have a FIFO on this platform */ +#endif + +#if !defined(USE_MMAP) && !defined(USE_USGSHM) +#define USE_MMAP +#endif + +#if !defined HAVE_SMMAP && defined FIFO +# undef USE_MMAP +# define USE_USGSHM /* SYSV shared memory is the default */ +#endif + +#ifdef USE_MMAP /* Only want to have one implementation */ +# undef USE_USGSHM /* mmap() is preferred */ +#endif + +#ifdef HAVE_DOSALLOCSHAREDMEM +# undef USE_MMAP +# undef USE_USGSHM +# define USE_OS2SHM +# undef USE_BEOS_AREAS +#endif + +#ifdef HAVE_AREAS +# undef USE_MMAP +# undef USE_USGSHM +# undef USE_OS2SHM +# define USE_BEOS_AREAS +#endif + +#include <stdio.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <standard.h> +#include <schily.h> + +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#endif + +#if defined(HAVE_SHMAT) && (HAVE_SHMAT == 1) +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#endif + +#ifdef USE_MMAP +#if defined(HAVE_SMMAP) && defined(USE_MMAP) +#include <mmapdefs.h> +#endif +#endif + +#include <usal/scsitransp.h> + +#ifdef USE_BEOS_AREAS +#include <be/kernel/OS.h> +#endif + +#include "mytype.h" +#include "interface.h" +#include "ringbuff.h" +#include "global.h" +#include "exitcodes.h" +#include "semshm.h" + +#ifdef DEBUG_SHM +char *start_of_shm; +char *end_of_shm; +#endif + +int flush_buffers(void); + + +/*------ Semaphore interfacing (for special cases only) ----------*/ +/*------ Synchronization with pipes is preferred ----------*/ + +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) + +int sem_id; +static int seminstall(key_t key, int amount); + +static int seminstall(key_t key, int amount) +{ + int ret_val; + int semflag; + + semflag = IPC_CREAT | 0600; +#ifdef IPCTST + fprintf(stderr,"seminstall: key: %d, #sems %d, flags %4x\n", + key,amount,semflag); +#endif + ret_val = semget(key,amount,semflag); + if ( ret_val == -1 ) + { + fprintf(stderr,"semget: (Key %lx, #%d) failed: ", + (long)key,amount); + perror(""); + } + return ret_val; +} + +/*-----------------------------------------------------------------*/ +int semrequest(int semid, int semnum) +{ + struct sembuf sops[1]; + int ret_val; + +#ifdef IPCTST + fprintf(stderr,"pid %d, ReQuest id:num %d:%d\n",getpid(),semid,semnum); +#endif + sops[0].sem_op = -1; + sops[0].sem_num = (short) semnum; + sops[0].sem_flg = 0; + + do { + errno = 0; + ret_val = semop(semid,sops,1); + if (ret_val == -1 && errno != EAGAIN && errno != EINTR) + { + fprintf(stderr,"Request Sema %d(%d) failed: ",semid,semnum); + perror(""); + } + } while (errno == EAGAIN || errno == EINTR); + return(ret_val); +} + +/*-----------------------------------------------------------------*/ +int semrelease(int semid, int semnum, int amount) +{ + struct sembuf sops[1]; + int ret_val; + +#ifdef IPCTST + fprintf(stderr,"%d RL %d:%d\n",getpid(),semid,semnum); +#endif + sops[0].sem_op = amount; + sops[0].sem_num = (short) semnum; + sops[0].sem_flg = 0; + ret_val = semop(semid,sops,1); + if ( ret_val == -1 && errno != EAGAIN) + { + fprintf(stderr,"Release Sema %d(%d) failed: ",semid,semnum); + perror(""); + } + return(ret_val); +} + +int flush_buffers() +{ + return 0; +} +#else +/*------ Synchronization with pipes ----------*/ +int pipefdp2c[2]; +int pipefdc2p[2]; + +void init_pipes() +{ + if (pipe(pipefdp2c) < 0) { + perror("cannot create pipe parent to child"); + exit(PIPE_ERROR); + } + if (pipe(pipefdc2p) < 0) { + perror("cannot create pipe child to parent"); + exit(PIPE_ERROR); + } +} + +void init_parent() +{ + close(pipefdp2c[0]); + close(pipefdc2p[1]); +} + +void init_child() +{ + close(pipefdp2c[1]); + close(pipefdc2p[0]); +} + +int semrequest(int dummy, int semnum) +{ + + if (semnum == FREE_SEM /* 0 */) { + int retval; + if ((*total_segments_read) - (*total_segments_written) >= global.buffers) { + /* parent/reader waits for freed buffers from the child/writer */ + *parent_waits = 1; + retval = read(pipefdp2c[0], &dummy, 1) != 1; + return retval; + } + } else { + int retval; + + if ((*total_segments_read) == (*total_segments_written)) { + /* child/writer waits for defined buffers from the parent/reader */ + *child_waits = 1; + retval = read(pipefdc2p[0], &dummy, 1) != 1; + return retval; + } + } + return 0; +} + +/* ARGSUSED */ +int semrelease(int dummy, int semnum, int amount) +{ + if (semnum == FREE_SEM /* 0 */) { + if (*parent_waits == 1) { + int retval; + /* child/writer signals freed buffer to the parent/reader */ + *parent_waits = 0; + retval = write(pipefdp2c[1], "12345678901234567890", amount) != amount; + return retval; + } + } else { + if (*child_waits == 1) { + int retval; + /* parent/reader signals defined buffers to the child/writer */ + *child_waits = 0; + retval = write(pipefdc2p[1], "12345678901234567890", amount) != amount; + return retval; + } + } + return 0; +} + +int flush_buffers() +{ + if ((*total_segments_read) > (*total_segments_written)) { + return write(pipefdc2p[1], "1", 1) != 1; + } + return 0; +} + +#endif + +/*------------------- Shared memory interfacing -----------------------*/ + + + +#if defined(HAVE_SHMAT) && (HAVE_SHMAT == 1) +static int shm_request_nommap(int size, unsigned char **memptr); + +/* request a shared memory block */ +static int shm_request_nommap(int size, unsigned char **memptr) +{ + int ret_val; + int shmflag; + int SHMEM_ID; + int cmd; + struct shmid_ds buf; + key_t key = IPC_PRIVATE; + + shmflag = IPC_CREAT | 0600; + ret_val = shmget(key,size,shmflag); + if ( ret_val == -1 ) + { + perror("shmget"); + return -1; + } + + SHMEM_ID = ret_val; + cmd = IPC_STAT; + ret_val = shmctl(SHMEM_ID,cmd,&buf); +#ifdef IPCTST + fprintf(stderr, "%d: shmctl STAT= %d, SHM_ID: %d, key %ld cuid %d cgid %d mode %3o size %d\n", + getpid(),ret_val,SHMEM_ID, + (long) buf.shm_perm.key,buf.shm_perm.cuid,buf.shm_perm.cgid, + buf.shm_perm.mode,buf.shm_segsz); +#endif + + *memptr = (unsigned char *) shmat(SHMEM_ID, NULL, 0); + if (*memptr == (unsigned char *) -1) { + *memptr = NULL; + fprintf( stderr, "shmat failed for %d bytes\n", size); + return -1; + } + + if (shmctl(SHMEM_ID, IPC_RMID, 0) < 0) { + fprintf( stderr, "shmctl failed to detach shared memory segment\n"); + return -1; + } + + +#ifdef DEBUG_SHM + start_of_shm = *memptr; + end_of_shm = (char *)(*memptr) + size; + + fprintf(stderr, "Shared memory from %p to %p (%d bytes)\n", start_of_shm, end_of_shm, size); +#endif + return 0; +} + + +#endif /* #if defined(HAVE_SHMAT) && (HAVE_SHMAT == 1) */ + + +static int shm_request(int size, unsigned char **memptr); + +#ifdef USE_USGSHM +/* request a shared memory block */ +static int shm_request(int size, unsigned char **memptr) +{ + return shm_request_nommap(size, memptr); +} +#endif + +/* release semaphores */ +void free_sem(void); +void free_sem() +{ +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) + int mycmd; + union my_semun unused_arg; + + mycmd = IPC_RMID; + + /* HP-UX warns here, but 'unused_arg' is not used for this operation */ + /* This warning is difficult to avoid, since the structure of the union + * generally is not known (os dependent). So we cannot initialize it + * properly. + */ + semctl(sem_id,0,mycmd,unused_arg); +#endif + +} + +#ifdef USE_MMAP +#if defined(HAVE_SMMAP) + +int shm_id; +/* request a shared memory block */ +static int shm_request(int size, unsigned char **memptr) +{ + int f; + char *addr; + +#ifdef MAP_ANONYMOUS /* HP/UX */ + f = -1; + addr = mmap(0, mmap_sizeparm(size), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, f, 0); +#else + if ((f = open("/dev/zero", O_RDWR)) < 0) + comerr("Cannot open '/dev/zero'.\n"); + addr = mmap(0, mmap_sizeparm(size), PROT_READ|PROT_WRITE, MAP_SHARED, f, 0); +#endif + + if (addr == (char *)-1) { +#if defined HAVE_SHMAT && (HAVE_SHMAT == 1) + unsigned char *address; + /* fallback to alternate method */ + if (0 != shm_request_nommap(size, &address) || (addr = (char *)address) == NULL) +#endif + comerr("Cannot get mmap for %d Bytes on /dev/zero.\n", size); + } + close(f); + + if (memptr != NULL) + *memptr = (unsigned char *)addr; + + return 0; +} +#endif /* HAVE_SMMAP */ +#endif /* USE_MMAP */ + +#ifdef USE_OS2SHM + +/* request a shared memory block */ +static int shm_request(int size, unsigned char **memptr) +{ + char *addr; + + /* + * The OS/2 implementation of shm (using shm.dll) limits the size of one + * memory segment to 0x3fa000 (aprox. 4MBytes). Using OS/2 native API we + * no such restriction so I decided to use it allowing fifos of arbitrary size + */ + if(DosAllocSharedMem(&addr,NULL,size,0X100L | 0x1L | 0x2L | 0x10L)) + comerr("DosAllocSharedMem() failed\n"); + + if (memptr != NULL) + *memptr = (unsigned char *)addr; + + return 0; +} +#endif + +#ifdef USE_BEOS_AREAS + +/* request a shared memory block */ +static int shm_request(int size, unsigned char **memptr) +{ + char *addr; + area_id aid; /* positive id of the mapping */ + + /* round up to a multiple of pagesize. */ + size = ((size - 1) | (B_PAGE_SIZE - 1)) + 1; + /* + * request a shared memory area in user space. + */ + aid = create_area(AREA_NAME, /* name of the mapping */ + (void *)&addr, /* address of shared memory */ + B_ANY_ADDRESS, /* type of address constraint */ + size, /* size in bytes (multiple of pagesize) */ + B_NO_LOCK, /* B_FULL_LOCK, */ /* memory locking */ + B_READ_AREA | B_WRITE_AREA); /* read and write permissions */ + + if (aid < B_OK) + comerrno(aid, "create_area() failed\n"); + + if (memptr != NULL) + *memptr = (unsigned char *)addr; + + return 0; +} +#endif + +void *request_shm_sem(unsigned amount_of_sh_mem, unsigned char **pointer) +{ +#if defined(HAVE_SEMGET) && defined(USE_SEMAPHORES) + /* install semaphores for double buffer usage */ + sem_id = seminstall(IPC_PRIVATE,2); + if ( sem_id == -1 ) { + perror("seminstall"); + exit(SEMAPHORE_ERROR); + } + +#endif + +#if defined(FIFO) + if (-1 == shm_request(amount_of_sh_mem, pointer)) { + perror("shm_request"); + exit(SHMMEM_ERROR); + } + + return *pointer; +#else + return NULL; +#endif +} diff --git a/icedax/semshm.h b/icedax/semshm.h new file mode 100644 index 0000000..2007f82 --- /dev/null +++ b/icedax/semshm.h @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +/* @(#)semshm.h 1.3 03/08/29 Copyright 1998,1999 Heiko Eissfeldt */ +#undef DEBUG_SHM +#ifdef DEBUG_SHM +extern char *start_of_shm; +extern char *end_of_shm; +#endif + +#define FREE_SEM 0 +#define DEF_SEM 1 + +#if defined (HAVE_SEMGET) && defined(USE_SEMAPHORES) +extern int sem_id; +#else +#define sem_id 42 /* nearly any other number would do it too */ +void init_pipes(void); +void init_parent(void); +void init_child(void); +#endif + + +#ifdef HAVE_AREAS +/* the name of the shared memory mapping for the FIFO under BeOS. */ +#define AREA_NAME "shmfifo" +#endif + +void free_sem(void); +int semrequest(int semid, int semnum); +int semrelease(int semid, int semnum, int amount); +int flush_buffers(void); +void * request_shm_sem(unsigned amount_of_sh_mem, unsigned char **pointer); + diff --git a/icedax/setuid.c b/icedax/setuid.c new file mode 100644 index 0000000..7f3e63c --- /dev/null +++ b/icedax/setuid.c @@ -0,0 +1,332 @@ +/* + * 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. + * + */ + +/* @(#)setuid.c 1.11 06/02/19 Copyright 1998,1999,2004 Heiko Eissfeldt, Copyright 2004-2006 J. Schilling */ +/* Security functions by zblaxell + + If these functions fail, it is because there was an installation error + or a programming error, and we can't be sure about what privileges + we do or do not have. This means we might not be able to recover + the privileges we need to fix anything that may be broken (e.g. the + CDDA state of some interface types), and we may in fact do something + quite dangerous (like write to the WAV file as root). + + In any case, it is unsafe to do anything but exit *now*. Ideally we'd + kill -9 our process group too, just to be sure. Root privileges are not + something you want floating around at random in user-level applications. + + If any signal handlers or child processes are introduced into this + program, it will be necessary to call dontneedroot() or neverneedroot() + on entry, respectively; otherwise, it will be possible to trick + the program into executing the signal handler or child process with + root privileges by sending signals at the right time. + */ + +#include "config.h" +#include <unixstd.h> +#include <stdio.h> +#include <stdxlib.h> + +#include "exitcodes.h" +#include "setuid.h" + +/*#undef DEBUG*/ +/*#define DEBUG*/ + +/* True at return from initsecurity */ +static uid_t real_uid = (uid_t) (-1); +static uid_t effective_uid = (uid_t) (-1); +static gid_t real_gid = (gid_t) (-1); +static gid_t effective_gid = (gid_t) (-1); + +/* Run this at the beginning of the program to initialize this code and + to drop privileges before someone uses them to shoot us in the foot. + Do not pass(go), do not dollars += 200. */ + +void initsecurity() +{ + int leffective_uid; + + alarm(0); /* can be inherited from parent process */ + real_uid = getuid(); + leffective_uid = geteuid(); + if ((int) real_uid != leffective_uid && leffective_uid != 0) { /* sanity check */ + fprintf(stderr, "Warning: setuid but not to root (uid=%ld, euid=%d)\n", (long) real_uid, leffective_uid); + fprintf(stderr, "Dropping setuid privileges now.\n"); + neverneedroot(); + } else { + effective_uid = leffective_uid; + } + real_gid = getgid(); + effective_gid = getegid(); + dontneedroot(); + dontneedgroup(); +} + +/* Temporarily gain root privileges. */ + +#if defined _POSIX_SAVED_IDS && defined (HAVE_SETEUID) && defined SCO +/* SCO seems to lack the prototypes... */ +int seteuid(uid_t euid); +int setegid(gid_t guid); +#endif + +void needroot(int necessary) +{ +#ifdef DEBUG + fprintf(stderr, "call to needroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif + if (effective_uid) { + if (necessary) { + fprintf(stderr, "Fatal error: require root privilege but not setuid root.\n"); + exit(PERM_ERROR); + } else + return; + } + if (real_uid == (uid_t) (-1)) { + fprintf(stderr, "Fatal error: initsecurity() not called.\n"); + exit(INTERNAL_ERROR); + } + + if (geteuid() == 0) return; /* nothing to do */ + +#if defined _POSIX_SAVED_IDS && defined (HAVE_SETEUID) + if (seteuid(effective_uid)) { + perror("seteuid in needroot()"); + exit(PERM_ERROR); + } +#else +#if defined (HAVE_SETREUID) + if (setreuid(real_uid, effective_uid)) { + perror("setreuid in needroot()"); + exit(PERM_ERROR); + } +#endif +#endif + if (geteuid() != 0 && necessary) { + fprintf(stderr, "Fatal error: did not get root privilege.\n"); + exit(PERM_ERROR); + } +#ifdef DEBUG + fprintf(stderr, "exit of needroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif +} + +/* Temporarily drop root privileges. */ + +void dontneedroot() +{ +#ifdef DEBUG + fprintf(stderr, "call to dontneedroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif + if (real_uid == (uid_t) (-1)) { + fprintf(stderr, "Fatal error: initsecurity() not called.\n"); + exit(INTERNAL_ERROR); + } + if (effective_uid) + return; + if (geteuid() != 0) return; /* nothing to do */ + +#if defined _POSIX_SAVED_IDS && defined (HAVE_SETEUID) + if (seteuid(real_uid)) { + perror("seteuid in dontneedroot()"); + exit(PERM_ERROR); + } +#else +#if defined (HAVE_SETREUID) + if (setreuid(effective_uid, real_uid)) { + perror("setreuid in dontneedroot()"); + exit(PERM_ERROR); + } +#endif +#endif + if (geteuid() != real_uid) { + fprintf(stderr, "Fatal error: did not drop root privilege.\n"); +#ifdef DEBUG + fprintf(stderr, "in to dontneedroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif + exit(PERM_ERROR); + } +} + +/* Permanently drop root privileges. */ + +void neverneedroot() +{ +#ifdef DEBUG + fprintf(stderr, "call to neverneedroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif + if (real_uid == (uid_t) (-1)) { + fprintf(stderr, "Fatal error: initsecurity() not called.\n"); + exit(INTERNAL_ERROR); + } + if (geteuid() == effective_uid) { +#if defined (HAVE_SETUID) + if (setuid(real_uid)) { + perror("setuid in neverneedroot()"); + exit(PERM_ERROR); + } +#endif + } +#if defined(__FreeBSD__) || defined(__DragonFly__) /* XXX this is a big hack and and not a permanent solution */ + else { +#if defined (HAVE_SETUID) + if (setuid(real_uid)) { + perror("setuid in neverneedroot()"); + exit(PERM_ERROR); + } +#endif + } +#endif + if (geteuid() != real_uid || getuid() != real_uid) { + fprintf(stderr, "Fatal error: did not drop root privilege.\n"); +#ifdef DEBUG + fprintf(stderr, "in to neverneedroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif + exit(PERM_ERROR); + } + effective_uid = real_uid; +#ifdef DEBUG + fprintf(stderr, "exit of neverneedroot (_euid_=%d, uid=%d), current=%d/%d, pid=%d\n", + effective_uid, real_uid, geteuid(), getuid(), getpid()); +#endif +} + +/* Temporarily gain group privileges. */ + +void needgroup(int necessary) +{ +#ifdef DEBUG + fprintf(stderr, "call to needgroup (egid=%d, gid=%d), current=%d/%d, pid=%d\n", + effective_gid, real_gid, getegid(), getgid(), getpid()); +#endif + if (real_gid == (gid_t) (-1)) { + fprintf(stderr, "Fatal error: initsecurity() not called.\n"); + exit(INTERNAL_ERROR); + } + + if (getegid() == effective_gid) return; /* nothing to do */ + +#if defined _POSIX_SAVED_IDS && defined (HAVE_SETEGID) + if (setegid(effective_gid)) { + perror("setegid in needgroup()"); + exit(PERM_ERROR); + } +#else +#if defined (HAVE_SETREGID) + if (setregid(real_gid, effective_gid)) { + perror("setregid in needgroup()"); + exit(PERM_ERROR); + } +#endif +#endif + if (necessary && getegid() != effective_gid) { + fprintf(stderr, "Fatal error: did not get group privilege.\n"); + exit(PERM_ERROR); + } +} + +/* Temporarily drop group privileges. */ + +void dontneedgroup() +{ +#ifdef DEBUG + fprintf(stderr, "call to dontneedgroup (egid=%d, gid=%d), current=%d/%d, pid=%d\n", + effective_gid, real_gid, getegid(), getgid(), getpid()); +#endif + if (real_gid == (gid_t) (-1)) { + fprintf(stderr, "Fatal error: initsecurity() not called.\n"); + exit(INTERNAL_ERROR); + } + if (getegid() != effective_gid) return; /* nothing to do */ +#if defined _POSIX_SAVED_IDS && defined (HAVE_SETEGID) + if (setegid(real_gid)) { + perror("setegid in dontneedgroup()"); + exit(PERM_ERROR); + } +#else +#if defined (HAVE_SETREGID) + if (setregid(effective_gid, real_gid)) { + perror("setregid in dontneedgroup()"); + exit(PERM_ERROR); + } +#endif +#endif + if (getegid() != real_gid) { + fprintf(stderr, "Fatal error: did not drop group privilege.\n"); + exit(PERM_ERROR); + } +#ifdef DEBUG + fprintf(stderr, "exit if dontneedgroup (egid=%d, gid=%d), current=%d/%d, pid=%d\n", + effective_gid, real_gid, getegid(), getgid(), getpid()); +#endif +} + +/* Permanently drop group privileges. */ + +void neverneedgroup() +{ +#ifdef DEBUG + fprintf(stderr, "call to neverneedgroup (egid=%d, gid=%d), current=%d/%d, pid=%d\n", + effective_gid, real_gid, getegid(), getgid(), getpid()); +#endif + if (real_gid == (gid_t) (-1)) { + fprintf(stderr, "Fatal error: initsecurity() not called.\n"); + exit(INTERNAL_ERROR); + } + if (getegid() == effective_gid) { +#if defined (HAVE_SETGID) + if (setgid(real_gid)) { + perror("setgid in neverneedgroup()"); + exit(PERM_ERROR); + } +#endif + } +#if defined(__FreeBSD__) || defined(__DragonFly__) /* XXX this is a big hack and and not a permanent solution */ + else { +#if defined (HAVE_SETGID) + if (setgid(real_gid)) { + perror("setgid in neverneedgroup()"); + exit(PERM_ERROR); + } +#endif + } +#endif + if (getegid() != real_gid || getgid() != real_gid) { + fprintf(stderr, "Fatal error: did not drop group privilege.\n"); + exit(PERM_ERROR); + } + effective_gid = real_gid; +} + +#if defined (HPUX) +int seteuid(uid_t uid) +{ + return setresuid(-1, uid, -1); +} + +int setreuid(uid_t uid1, uid_t uid2) +{ + return setresuid(uid2, uid2, uid1 == uid2 ? uid2 : 0); +} + +int setregid(gid_t gid1, gid_t gid2) +{ + return setresgid(gid2, gid2, gid1 == gid2 ? gid2 : 0); +} +#endif diff --git a/icedax/setuid.h b/icedax/setuid.h new file mode 100644 index 0000000..48a8ae0 --- /dev/null +++ b/icedax/setuid.h @@ -0,0 +1,31 @@ +/* + * 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. + * + */ + +/* @(#)setuid.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +/* Security functions */ +void initsecurity(void); + +void needroot(int necessary); +void dontneedroot(void); +void neverneedroot(void); + +void needgroup(int necessary); +void dontneedgroup(void); +void neverneedgroup(void); + +#if defined (HPUX) +#define HAVE_SETREUID +#define HAVE_SETREGID +int seteuid(uid_t uid); +int setreuid(uid_t uid1, uid_t uid2); +int setregid(gid_t gid1, gid_t gid2); +#endif diff --git a/icedax/sha.h b/icedax/sha.h new file mode 100644 index 0000000..ca5e4a0 --- /dev/null +++ b/icedax/sha.h @@ -0,0 +1,102 @@ +/* + * 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. + * + */ + +/* @(#)sha.h 1.4 03/06/28 Copyright 1998,1999 Heiko Eissfeldt */ +/*____________________________________________________________________________ +// +// CD Index - The Internet CD Index +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id: sha.h,v 1.1.1.2 1999/04/29 00:53:34 marc Exp $ +//____________________________________________________________________________ +*/ +#ifndef SHA_H +#define SHA_H + +/* NIST Secure Hash Algorithm */ +/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */ +/* from Peter C. Gutmann's implementation as found in */ +/* Applied Cryptography by Bruce Schneier */ + +/* This code is in the public domain */ + +/* Useful defines & typedefs */ + +typedef unsigned char BYTE; /* 8-bit quantity */ +typedef unsigned long ULONG; /* 32-or-more-bit quantity */ + +#define SHA_BLOCKSIZE 64 +#define SHA_DIGESTSIZE 20 + +typedef struct { + ULONG digest[5]; /* message digest */ + ULONG count_lo, count_hi; /* 64-bit bit count */ + BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ + int local; /* unprocessed amount in data */ +} SHA_INFO; + +void sha_init(SHA_INFO *); +void sha_update(SHA_INFO *, BYTE *, int); +void sha_final(unsigned char [20], SHA_INFO *); + +#ifdef SHA_FOR_C + +#include <mconfig.h> +#include <stdxlib.h> +#include <stdio.h> + +void sha_stream(unsigned char [20], SHA_INFO *, FILE *); +void sha_print(unsigned char [20]); +char *sha_version(void); +#endif /* SHA_FOR_C */ + +#define SHA_VERSION 1 + +#ifndef WIN32 +#ifdef WORDS_BIGENDIAN +# if SIZEOF_UNSIGNED_LONG_INT == 4 +# define SHA_BYTE_ORDER 4321 +# else +# if SIZEOF_UNSIGNED_LONG_INT == 8 +# define SHA_BYTE_ORDER 87654321 +# endif +# endif +#else +# if SIZEOF_UNSIGNED_LONG_INT == 4 +# define SHA_BYTE_ORDER 1234 +# else +# if SIZEOF_UNSIGNED_LONG_INT == 8 +# define SHA_BYTE_ORDER 12345678 +# endif +# endif +#endif + +#else + +#define SHA_BYTE_ORDER 1234 + +#endif + +#endif /* SHA_H */ diff --git a/icedax/sha_func.c b/icedax/sha_func.c new file mode 100644 index 0000000..06b55ac --- /dev/null +++ b/icedax/sha_func.c @@ -0,0 +1,376 @@ +/* + * 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. + * + */ + +/* @(#)sha_func.c 1.3 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */ +/*____________________________________________________________________________ +// +// CD Index - The Internet CD Index +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id: sha_func.c,v 1.2 1999/06/04 14:10:07 marc Exp $ +//____________________________________________________________________________ +*/ +/* NIST Secure Hash Algorithm */ + +/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */ +/* from Peter C. Gutmann's implementation as found in */ +/* Applied Cryptography by Bruce Schneier */ +/* Further modifications to include the "UNRAVEL" stuff, below */ +/* portability modifications Heiko Eissfeldt */ + +/* This code is in the public domain */ + +#include "config.h" +#include <strdefs.h> +#include "sha.h" + +/* UNRAVEL should be fastest & biggest */ +/* UNROLL_LOOPS should be just as big, but slightly slower */ +/* both undefined should be smallest and slowest */ + +#define UNRAVEL +/* #define UNROLL_LOOPS */ + +/* SHA f()-functions */ + +#define f1(x,y,z) ((x & y) | (~x & z)) +#define f2(x,y,z) (x ^ y ^ z) +#define f3(x,y,z) ((x & y) | (x & z) | (y & z)) +#define f4(x,y,z) (x ^ y ^ z) + +/* SHA constants */ + +#define CONST1 ULONG_C(0x5a827999) +#define CONST2 ULONG_C(0x6ed9eba1) +#define CONST3 ULONG_C(0x8f1bbcdc) +#define CONST4 ULONG_C(0xca62c1d6) + +/* truncate to 32 bits -- should be a null op on 32-bit machines */ + +#define T32(x) ((x) & ULONG_C(0xffffffff)) + +/* 32-bit rotate */ + +#define R32(x,n) T32(((x << n) | (x >> (32 - n)))) + +/* the generic case, for when the overall rotation is not unraveled */ + +#define FG(n) \ + T = T32(R32(A,5) + CONCAT(f,n(B,C,D)) + E + *WP++ + CONCAT(CONST,n)); \ + E = D; D = C; C = R32(B,30); B = A; A = T + +/* specific cases, for when the overall rotation is unraveled */ + +#define FA(n) \ + T = T32(R32(A,5) + CONCAT(f,n(B,C,D)) + E + *WP++ + CONCAT(CONST,n)); B = R32(B,30) + +#define FB(n) \ + E = T32(R32(T,5) + CONCAT(f,n(A,B,C)) + D + *WP++ + CONCAT(CONST,n)); A = R32(A,30) + +#define FC(n) \ + D = T32(R32(E,5) + CONCAT(f,n(T,A,B)) + C + *WP++ + CONCAT(CONST,n)); T = R32(T,30) + +#define FD(n) \ + C = T32(R32(D,5) + CONCAT(f,n(E,T,A)) + B + *WP++ + CONCAT(CONST,n)); E = R32(E,30) + +#define FE(n) \ + B = T32(R32(C,5) + CONCAT(f,n(D,E,T)) + A + *WP++ + CONCAT(CONST,n)); D = R32(D,30) + +#define FT(n) \ + A = T32(R32(B,5) + CONCAT(f,n(C,D,E)) + T + *WP++ + CONCAT(CONST,n)); C = R32(C,30) + +/* do SHA transformation */ + +static void sha_transform(SHA_INFO *sha_info); + +static void sha_transform(SHA_INFO *sha_info) +{ + int i; + BYTE *dp; + ULONG T, A, B, C, D, E, W[80], *WP; + + dp = sha_info->data; + +/* +the following makes sure that at least one code block below is +traversed or an error is reported, without the necessity for nested +preprocessor if/else/endif blocks, which are a great pain in the +nether regions of the anatomy... +*/ +#undef SWAP_DONE + +#if (SHA_BYTE_ORDER == 1234) +#define SWAP_DONE + for (i = 0; i < 16; ++i) { + T = *((ULONG *) dp); + dp += 4; + W[i] = ((T << 24) & ULONG_C(0xff000000)) | ((T << 8) & ULONG_C(0x00ff0000)) | + ((T >> 8) & ULONG_C(0x0000ff00)) | ((T >> 24) & ULONG_C(0x000000ff)); + } +#endif /* SHA_BYTE_ORDER == 1234 */ + +#if (SHA_BYTE_ORDER == 4321) +#define SWAP_DONE + for (i = 0; i < 16; ++i) { + T = *((ULONG *) dp); + dp += 4; + W[i] = T32(T); + } +#endif /* SHA_BYTE_ORDER == 4321 */ + +#if (SHA_BYTE_ORDER == 12345678) +#define SWAP_DONE + for (i = 0; i < 16; i += 2) { + T = *((ULONG *) dp); + dp += 8; + W[i] = ((T << 24) & ULONG_C(0xff000000)) | ((T << 8) & ULONG_C(0x00ff0000)) | + ((T >> 8) & ULONG_C(0x0000ff00)) | ((T >> 24) & ULONG_C(0x000000ff)); + T >>= 32; + W[i+1] = ((T << 24) & ULONG_C(0xff000000)) | ((T << 8) & ULONG_C(0x00ff0000)) | + ((T >> 8) & ULONG_C(0x0000ff00)) | ((T >> 24) & ULONG_C(0x000000ff)); + } +#endif /* SHA_BYTE_ORDER == 12345678 */ + +#if (SHA_BYTE_ORDER == 87654321) +#define SWAP_DONE + for (i = 0; i < 16; i += 2) { + T = *((ULONG *) dp); + dp += 8; + W[i] = T32(T >> 32); + W[i+1] = T32(T); + } +#endif /* SHA_BYTE_ORDER == 87654321 */ + +#ifndef SWAP_DONE +error Unknown byte order -- you need to add code here +#endif /* SWAP_DONE */ + + for (i = 16; i < 80; ++i) { + W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; +#if (SHA_VERSION == 1) + W[i] = R32(W[i], 1); +#endif /* SHA_VERSION */ + } + A = sha_info->digest[0]; + B = sha_info->digest[1]; + C = sha_info->digest[2]; + D = sha_info->digest[3]; + E = sha_info->digest[4]; + WP = W; +#ifdef UNRAVEL + FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); + FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); + FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); + FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); + FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); + FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); + FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); + FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); + sha_info->digest[0] = T32(sha_info->digest[0] + E); + sha_info->digest[1] = T32(sha_info->digest[1] + T); + sha_info->digest[2] = T32(sha_info->digest[2] + A); + sha_info->digest[3] = T32(sha_info->digest[3] + B); + sha_info->digest[4] = T32(sha_info->digest[4] + C); +#else /* !UNRAVEL */ +#ifdef UNROLL_LOOPS + FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); + FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); + FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); + FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); + FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); + FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); + FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); + FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); +#else /* !UNROLL_LOOPS */ + for (i = 0; i < 20; ++i) { FG(1); } + for (i = 20; i < 40; ++i) { FG(2); } + for (i = 40; i < 60; ++i) { FG(3); } + for (i = 60; i < 80; ++i) { FG(4); } +#endif /* !UNROLL_LOOPS */ + sha_info->digest[0] = T32(sha_info->digest[0] + A); + sha_info->digest[1] = T32(sha_info->digest[1] + B); + sha_info->digest[2] = T32(sha_info->digest[2] + C); + sha_info->digest[3] = T32(sha_info->digest[3] + D); + sha_info->digest[4] = T32(sha_info->digest[4] + E); +#endif /* !UNRAVEL */ +} + +/* initialize the SHA digest */ + +void sha_init(SHA_INFO *sha_info); + +void sha_init(SHA_INFO *sha_info) +{ + sha_info->digest[0] = ULONG_C(0x67452301); + sha_info->digest[1] = ULONG_C(0xefcdab89); + sha_info->digest[2] = ULONG_C(0x98badcfe); + sha_info->digest[3] = ULONG_C(0x10325476); + sha_info->digest[4] = ULONG_C(0xc3d2e1f0); + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; +} + +/* update the SHA digest */ + +void sha_update(SHA_INFO *sha_info, BYTE *buffer, int count); + +void sha_update(SHA_INFO *sha_info, BYTE *buffer, int count) +{ + int i; + ULONG clo; + + clo = T32(sha_info->count_lo + ((ULONG) count << 3)); + if (clo < sha_info->count_lo) { + ++sha_info->count_hi; + } + sha_info->count_lo = clo; + sha_info->count_hi += (ULONG) count >> 29; + if (sha_info->local) { + i = SHA_BLOCKSIZE - sha_info->local; + if (i > count) { + i = count; + } + memcpy(((BYTE *) sha_info->data) + sha_info->local, buffer, i); + count -= i; + buffer += i; + sha_info->local += i; + if (sha_info->local == SHA_BLOCKSIZE) { + sha_transform(sha_info); + } else { + return; + } + } + while (count >= SHA_BLOCKSIZE) { + memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); + buffer += SHA_BLOCKSIZE; + count -= SHA_BLOCKSIZE; + sha_transform(sha_info); + } + memcpy(sha_info->data, buffer, count); + sha_info->local = count; +} + +/* finish computing the SHA digest */ + +void sha_final(unsigned char digest[20], SHA_INFO *sha_info); + +void sha_final(unsigned char digest[20], SHA_INFO *sha_info) +{ + int count; + ULONG lo_bit_count, hi_bit_count; + + lo_bit_count = sha_info->count_lo; + hi_bit_count = sha_info->count_hi; + count = (int) ((lo_bit_count >> 3) & 0x3f); + ((BYTE *) sha_info->data)[count++] = 0x80; + if (count > SHA_BLOCKSIZE - 8) { + memset(((BYTE *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count); + sha_transform(sha_info); + memset((BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8); + } else { + memset(((BYTE *) sha_info->data) + count, 0, + SHA_BLOCKSIZE - 8 - count); + } + sha_info->data[56] = (unsigned char) ((hi_bit_count >> 24) & 0xff); + sha_info->data[57] = (unsigned char) ((hi_bit_count >> 16) & 0xff); + sha_info->data[58] = (unsigned char) ((hi_bit_count >> 8) & 0xff); + sha_info->data[59] = (unsigned char) ((hi_bit_count >> 0) & 0xff); + sha_info->data[60] = (unsigned char) ((lo_bit_count >> 24) & 0xff); + sha_info->data[61] = (unsigned char) ((lo_bit_count >> 16) & 0xff); + sha_info->data[62] = (unsigned char) ((lo_bit_count >> 8) & 0xff); + sha_info->data[63] = (unsigned char) ((lo_bit_count >> 0) & 0xff); + sha_transform(sha_info); + digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); + digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); + digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); + digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); + digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); + digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); + digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); + digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); + digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); + digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); + digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); + digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); + digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); + digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); + digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); + digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); + digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); + digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); + digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); + digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); +} + +#ifdef SHA_FOR_C + +/* compute the SHA digest of a FILE stream */ + +#define BLOCK_SIZE 8192 + +void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin); + +void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin) +{ + int i; + BYTE data[BLOCK_SIZE]; + + sha_init(sha_info); + while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) { + sha_update(sha_info, data, i); + } + sha_final(digest, sha_info); +} + +/* print a SHA digest */ + +void sha_print(unsigned char digest[20]); + +void sha_print(unsigned char digest[20]) +{ + int i, j; + + for (j = 0; j < 5; ++j) { + for (i = 0; i < 4; ++i) { + printf("%02x", *digest++); + } + printf("%c", (j < 4) ? ' ' : '\n'); + } +} + +char *sha_version(void); + +char *sha_version() +{ +#if (SHA_VERSION == 1) + static char *version = "SHA-1"; +#else + static char *version = "SHA"; +#endif + return(version); +} + +#endif /* SHA_FOR_C */ diff --git a/icedax/sndconfig.c b/icedax/sndconfig.c new file mode 100644 index 0000000..ac446fc --- /dev/null +++ b/icedax/sndconfig.c @@ -0,0 +1,607 @@ +/* + * 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. + * + */ + +/* @(#)sndconfig.c 1.17 04/08/03 Copyright 1998-2004 Heiko Eissfeldt */ +/* os dependent functions */ +#include "config.h" +#include <stdio.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <fctldefs.h> +#include <unixstd.h> +#include <sys/ioctl.h> + +#if !defined __CYGWIN32__ +# include <timedefs.h> +#endif +#include <schily.h> + + +/* soundcard setup */ +#if defined (HAVE_SOUNDCARD_H) || defined (HAVE_LINUX_SOUNDCARD_H) || defined (HAVE_SYS_SOUNDCARD_H) || defined (HAVE_MACHINE_SOUNDCARD_H) +# if defined (HAVE_SOUNDCARD_H) +# include <soundcard.h> +# else +# if defined (HAVE_MACHINE_SOUNDCARD_H) +# include <machine/soundcard.h> +# else +# if defined (HAVE_SYS_SOUNDCARD_H) +# include <sys/soundcard.h> +# else +# if defined (HAVE_LINUX_SOUNDCARD_H) +# include <linux/soundcard.h> +# endif +# endif +# endif +# endif +#endif + +#include "mytype.h" +#include "byteorder.h" +#include "lowlevel.h" +#include "global.h" +#include "sndconfig.h" + +#ifdef ECHO_TO_SOUNDCARD +# if defined(__CYGWIN32__) +# include <windows.h> +# include "mmsystem.h" +# endif + +# if defined(__EMX__) +# define INCL_DOS +# define INCL_OS2MM +# include <os2.h> +# define PPFN _PPFN +# include <os2me.h> +# undef PPFN +static unsigned long DeviceID; + +# define FRAGMENTS 2 +/* playlist-structure */ +typedef struct { + ULONG ulCommand; + ULONG ulOperand1, ulOperand2, ulOperand3; +} PLAYLISTSTRUCTURE; + +static PLAYLISTSTRUCTURE PlayList[FRAGMENTS + 1]; +static unsigned BufferInd; +# endif /* defined __EMX__ */ + +static char snd_device[200] = SOUND_DEV; + +int set_snd_device(const char *devicename) +{ + strncpy(snd_device, devicename, sizeof(snd_device)); + return 0; +} + +# if defined __CYGWIN32__ +static HWAVEOUT DeviceID; +# define WAVEHDRS 3 +static WAVEHDR wavehdr[WAVEHDRS]; +static unsigned lastwav = 0; + +static int check_winsound_caps(int bits, double rate, int channels); + +static int check_winsound_caps(int bits, double rate, int channels) +{ + int result = 0; + + WAVEOUTCAPS caps; + + /* get caps */ + if (waveOutGetDevCaps(0, &caps, sizeof(caps))) { + fprintf(stderr, "cannot get soundcard capabilities!\n"); + return 1; + } + + /* check caps */ + if ((bits == 8 && !(caps.dwFormats & 0x333)) || + (bits == 16 && !(caps.dwFormats & 0xccc))) { + fprintf(stderr, "%d bits sound are not supported\n", bits); + result = 2; + } + + if ((channels == 1 && !(caps.dwFormats & 0x555)) || + (channels == 2 && !(caps.dwFormats & 0xaaa))) { + fprintf(stderr, "%d sound channels are not supported\n", channels); + result = 3; + } + + if ((rate == 44100.0 && !(caps.dwFormats & 0xf00)) || + (rate == 22050.0 && !(caps.dwFormats & 0xf0)) || + (rate == 11025.0 && !(caps.dwFormats & 0xf))) { + fprintf(stderr, "%d sample rate is not supported\n", (int)rate); + result = 4; + } + + return result; +} +# endif /* defined CYGWIN */ +#endif /* defined ECHO_TO_SOUNDCARD */ + +#ifdef HAVE_SUN_AUDIOIO_H +# include <sun/audioio.h> +#endif +#ifdef HAVE_SYS_AUDIOIO_H +# include <sys/audioio.h> +#endif + +#ifdef HAVE_SYS_ASOUNDLIB_H +# include <sys/asoundlib.h> +snd_pcm_t *pcm_handle; +#endif + +#if defined HAVE_OSS && defined SNDCTL_DSP_GETOSPACE +audio_buf_info abinfo; +#endif + +int init_soundcard(double rate, int bits) +{ +#ifdef ECHO_TO_SOUNDCARD + if (global.echo) { +# if defined(HAVE_OSS) && HAVE_OSS == 1 + if (open_snd_device() != 0) { + errmsg("Cannot open sound device '%s'\n", snd_device); + global.echo = 0; + } else { + /* This the sound device initialisation for 4front Open sound drivers */ + + int dummy; + int garbled_rate = rate; + int stereo = (global.channels == 2); + int myformat = bits == 8 ? AFMT_U8 : + (MY_LITTLE_ENDIAN ? AFMT_S16_LE : AFMT_S16_BE); + int mask; + + if (ioctl(global.soundcard_fd, (int)SNDCTL_DSP_GETBLKSIZE, &dummy) == -1) { + fprintf(stderr, "Cannot get blocksize for %s\n", snd_device); + global.echo = 0; + } + if (ioctl(global.soundcard_fd, (int)SNDCTL_DSP_SYNC, NULL) == -1) { + fprintf(stderr, "Cannot sync for %s\n", snd_device); + global.echo = 0; + } + +#if defined SNDCTL_DSP_GETOSPACE + if (ioctl(global.soundcard_fd, SNDCTL_DSP_GETOSPACE, &abinfo) == -1) { + fprintf(stderr, "Cannot get input buffersize for %s\n", snd_device); + abinfo.fragments = 0; + } +#endif + + /* check, if the sound device can do the requested format */ + if (ioctl(global.soundcard_fd, (int)SNDCTL_DSP_GETFMTS, &mask) == -1) { + perror("fatal error:"); + return -1; + } + if ((mask & myformat) == 0) { + fprintf(stderr, "sound format (%d bits signed) is not available\n", bits); + if ((mask & AFMT_U8) != 0) { + bits = 8; + myformat = AFMT_U8; + } + } + if (ioctl(global.soundcard_fd, (int)SNDCTL_DSP_SETFMT, &myformat) == -1) { + fprintf(stderr, "Cannot set %d bits/sample for %s\n",bits, snd_device); + global.echo = 0; + } + + /* limited sound devices may not support stereo */ + if (stereo + && ioctl(global.soundcard_fd, (int)SNDCTL_DSP_STEREO, &stereo) == -1) { + fprintf(stderr, "Cannot set stereo mode for %s\n", snd_device); + stereo = 0; + } + if (!stereo + && ioctl(global.soundcard_fd, (int)SNDCTL_DSP_STEREO, &stereo) == -1) { + fprintf(stderr, "Cannot set mono mode for %s\n", snd_device); + global.echo = 0; + } + + /* set the sample rate */ + if (ioctl(global.soundcard_fd, (int)SNDCTL_DSP_SPEED, &garbled_rate) == -1) { + fprintf(stderr, "Cannot set rate %d.%2d Hz for %s\n", + (int)rate, (int)(rate*100)%100, snd_device); + global.echo = 0; + } + if ( abs((long)rate - garbled_rate) > rate / 20) { + fprintf(stderr, "sound device: next best sample rate is %d\n",garbled_rate); + } + } + +# else /* HAVE_OSS */ + +# if defined HAVE_SYS_AUDIOIO_H || defined HAVE_SUN_AUDIOIO_H + /* This is the SunOS / Solaris and compatibles sound initialisation */ + + if ((global.soundcard_fd = open(snd_device, O_WRONLY, 0)) == EOF) { + perror(""); + fprintf(stderr, "Cannot open %s\n",snd_device); + global.echo = 0; + } else { + + audio_info_t info; + +# if defined (AUDIO_INITINFO) && defined (AUDIO_ENCODING_LINEAR) + AUDIO_INITINFO(&info); + info.play.sample_rate = rate; + info.play.channels = global.channels; + info.play.precision = bits; + info.play.encoding = AUDIO_ENCODING_LINEAR; + info.play.pause = 0; + info.record.pause = 0; + info.monitor_gain = 0; + if (ioctl(global.soundcard_fd, AUDIO_SETINFO, &info) < 0) { + fprintf(stderr, "Cannot init %s (sun)\n", snd_device); + global.echo = 0; + } +# else + fprintf(stderr, "Cannot init sound device with 44.1 KHz sample rate on %s (sun compatible)\n", snd_device); + global.echo = 0; +# endif + } +# else /* SUN audio */ +# if defined(__CYGWIN32__) + /* Windows sound info */ + + MMRESULT mmres; + WAVEFORMATEX wavform; + + if (waveOutGetNumDevs() < 1) { + fprintf( stderr, "no sound devices available!\n"); + global.echo = 0; + return 1; + } + + /* check capabilities */ + if (check_winsound_caps(bits, rate, global.channels) != 0) { + fprintf( stderr, "soundcard capabilities are not sufficient!\n"); + global.echo = 0; + return 1; + } + + wavform.wFormatTag = WAVE_FORMAT_PCM; + wavform.nChannels = global.channels; + wavform.nSamplesPerSec = (int)rate; + wavform.wBitsPerSample = bits; + wavform.cbSize = sizeof(wavform); + wavform.nAvgBytesPerSec = (int)rate * global.channels * + (wavform.wBitsPerSample / 8); + wavform.nBlockAlign = global.channels * (wavform.wBitsPerSample / 8); + + DeviceID = 0; + mmres = waveOutOpen(&DeviceID, WAVE_MAPPER, &wavform, (unsigned long)WIN_CallBack, 0, CALLBACK_FUNCTION); + if (mmres) { + char erstr[329]; + + waveOutGetErrorText(mmres, erstr, sizeof(erstr)); + fprintf( stderr, "soundcard open error: %s!\n", erstr); + global.echo = 0; + return 1; + } + + global.soundcard_fd = 0; + + /* init all wavehdrs */ + { int i; + for (i=0; i < WAVEHDRS; i++) { + wavehdr[i].dwBufferLength = (global.channels*(bits/ 8)*(int)rate* + global.nsectors)/75; + wavehdr[i].lpData = malloc(wavehdr[i].dwBufferLength); + if (wavehdr[i].lpData == NULL) { + fprintf(stderr, "no memory for sound buffers available\n"); + waveOutReset(0); + waveOutClose(DeviceID); + return 1; + } + + mmres = waveOutPrepareHeader(DeviceID, &wavehdr[i], sizeof(WAVEHDR)); + if (mmres) { + char erstr[129]; + + waveOutGetErrorText(mmres, erstr, sizeof(erstr)); + fprintf( stderr, "soundcard prepare error: %s!\n", erstr); + return 1; + } + + wavehdr[i].dwLoops = 0; + wavehdr[i].dwFlags = WHDR_DONE; + wavehdr[i].dwBufferLength = 0; + } + } + +# else +# if defined(__EMX__) +# if defined (HAVE_MMPM) + /* OS/2 MMPM/2 MCI sound info */ + + MCI_OPEN_PARMS mciOpenParms; + int i; + + /* create playlist */ + for (i = 0; i < FRAGMENTS; i++) { + PlayList[i].ulCommand = DATA_OPERATION; /* play data */ + PlayList[i].ulOperand1 = 0; /* address */ + PlayList[i].ulOperand2 = 0; /* size */ + PlayList[i].ulOperand3 = 0; /* offset */ + } + PlayList[FRAGMENTS].ulCommand = BRANCH_OPERATION; /* jump */ + PlayList[FRAGMENTS].ulOperand1 = 0; + PlayList[FRAGMENTS].ulOperand2 = 0; /* destination */ + PlayList[FRAGMENTS].ulOperand3 = 0; + + memset(&mciOpenParms, 0, sizeof(mciOpenParms)); + mciOpenParms.pszDeviceType = (PSZ) (((unsigned long) MCI_DEVTYPE_WAVEFORM_AUDIO << 16) | (unsigned short) DeviceIndex); + mciOpenParms.pszElementName = (PSZ) & PlayList; + + /* try to open the sound device */ + if (mciSendCommand(0, MCI_OPEN, + MCI_WAIT | MCI_OPEN_SHAREABLE | MCIOPEN_Type_ID, &mciOpenParms, 0) + != MCIERR_SUCCESS) { + /* no sound */ + fprintf( stderr, "no sound devices available!\n"); + global.echo = 0; + return 1; + } + /* try to set the parameters */ + DeviceID = mciOpenParms.usDeviceID; + + { + MCI_WAVE_SET_PARMS mciWaveSetParms; + + memset(&mciWaveSetParms, 0, sizeof(mciWaveSetParms)); + mciWaveSetParms.ulSamplesPerSec = rate; + mciWaveSetParms.usBitsPerSample = bits; + mciWaveSetParms.usChannels = global.channels; + mciWaveSetParms.ulAudio = MCI_SET_AUDIO_ALL; + + /* set play-parameters */ + if (mciSendCommand(DeviceID, MCI_SET, + MCI_WAIT | MCI_WAVE_SET_SAMPLESPERSEC | + MCI_WAVE_SET_BITSPERSAMPLE | MCI_WAVE_SET_CHANNELS, + (PVOID) & mciWaveSetParms, 0)) { + MCI_GENERIC_PARMS mciGenericParms; + fprintf( stderr, "soundcard capabilities are not sufficient!\n"); + global.echo = 0; + /* close */ + mciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, &mciGenericParms, 0); + return 1; + } + } + +# endif /* EMX MMPM OS2 sound */ +# else +# if defined(__QNX__) + + int card = -1; + int dev = 0; + int rtn; + snd_pcm_channel_info_t pi; + snd_pcm_channel_params_t pp; + + if (card == -1) { + rtn = snd_pcm_open_preferred(&pcm_handle, + &card, &dev, SND_PCM_OPEN_PLAYBACK); + if (rtn < 0) { + perror("sound device open"); + return 1; + } + } else { + rtn = snd_pcm_open(&pcm_handle, + card, dev, SND_PCM_OPEN_PLAYBACK); + if (rtn < 0) { + perror("sound device open"); + return 1; + } + } + + memset(&pi, 0, sizeof(pi)); + pi.channel = SND_PCM_CHANNEL_PLAYBACK; + rtn = snd_pcm_plugin_info(pcm_handle, &pi); + if (rtn < 0) { + fprintf(stderr, "snd_pcm_plugin_info failed: %s\n", snd_strerror(rtn)); + return 1; + } + + memset(&pp, 0, sizeof(pp)); + pp.mode = SND_PCM_MODE_BLOCK; + pp.channel = SND_PCM_CHANNEL_PLAYBACK; + pp.start_mode = SND_PCM_START_FULL; + pp.stop_mode = SND_PCM_STOP_STOP; + + pp.buf.block.frag_size = pi.max_fragment_size; + pp.buf.block.frags_max = 1; + pp.buf.block.frags_min = 1; + + pp.format.interleave = 1; + pp.format.rate = rate; + pp.format.voices = global.channels; + if (bits == 8) { + pp.format.format = SND_PCM_SFMT_U8; + } else { + pp.format.format = SND_PCM_SFMT_S16_LE; + } + + rtn = snd_pcm_plugin_params(pcm_handle, &pp); + if (rtn < 0) { + fprintf(stderr, "snd_pcm_plugin_params failed: %s\n", snd_strerror(rtn)); + return 1; + } + + rtn = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); + if (rtn < 0) { + fprintf(stderr, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rtn)); + return 1; + } + + global.soundcard_fd = snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); + +# endif /* QNX sound */ +# endif /* EMX OS2 sound */ +# endif /* CYGWIN Windows sound */ +# endif /* else SUN audio */ +# endif /* else HAVE_OSS */ + } +#endif /* ifdef ECHO_TO_SOUNDCARD */ + return 0; +} + +int open_snd_device() +{ +#if defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK) + int fl; +#endif + +#if defined ECHO_TO_SOUNDCARD && !defined __CYGWIN32__ && !defined __EMX__ + global.soundcard_fd = open(snd_device, O_WRONLY +#ifdef linux + /* Linux BUG: the sound driver open() blocks, if the device is in use. */ + | O_NONBLOCK +#endif + , 0); + +#if defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK) + fl = fcntl(global.soundcard_fd, F_GETFL, 0); + fl &= ~O_NONBLOCK; + fcntl(global.soundcard_fd, F_SETFL, fl); +#endif + + return (global.soundcard_fd < 0); +#else + return 0; +#endif +} + +int close_snd_device () +{ +#if !defined ECHO_TO_SOUNDCARD + return 0; +#else + +# if defined __CYGWIN32__ + waveOutReset(0); + return waveOutClose(DeviceID); +# else /* !Cygwin32 */ + +# if defined __EMX__ +# if defined HAVE_MMPM + /* close the sound device */ + MCI_GENERIC_PARMS mciGenericParms; + mciSendCommand(DeviceID, MCI_CLOSE, MCI_WAIT, &mciGenericParms, 0); +# else /* HAVE_MMPM */ + return 0; +# endif /* HAVE_MMPM */ +# else /* !EMX */ +# if defined __QNX__ + snd_pcm_plugin_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); + return snd_pcm_close(pcm_handle); +# else /* !QNX */ + return close(global.soundcard_fd); +# endif /* !QNX */ +# endif /* !EMX */ +# endif /* !Cygwin32 */ +#endif /* ifdef ECHO_TO_SOUNDCARD */ +} + +int write_snd_device(char *buffer, unsigned todo) +{ + int result = 0; +#ifdef ECHO_TO_SOUNDCARD +#if defined __CYGWIN32__ + MMRESULT mmres; + + wavehdr[lastwav].dwBufferLength = todo; + memcpy(wavehdr[lastwav].lpData, buffer, todo); + + mmres = waveOutWrite(DeviceID, &wavehdr[lastwav], sizeof(WAVEHDR)); + if (mmres) { + char erstr[129]; + + waveOutGetErrorText(mmres, erstr, sizeof(erstr)); + fprintf( stderr, "soundcard write error: %s!\n", erstr); + return 1; + } + if (++lastwav >= WAVEHDRS) + lastwav -= WAVEHDRS; + result = mmres; +#else +#if defined __EMX__ + Playlist[BufferInd].ulOperand1 = buffer; + Playlist[BufferInd].ulOperand2 = todo; + Playlist[BufferInd].ulOperand3 = 0; + if (++BufferInd >= FRAGMENTS) + BufferInd -= FRAGMENTS; + + /* no MCI_WAIT here, because application program has to continue */ + memset(&mciPlayParms, 0, sizeof(mciPlayParms)); + if (mciSendCommand(DeviceID, MCI_PLAY, MCI_FROM, &mciPlayParms, 0)) { + fprintf( stderr, "soundcard write error: %s!\n", erstr); + return 1; + } + result = 0; +#else + int retval2; + int towrite; + +#if defined HAVE_OSS && defined SNDCTL_DSP_GETOSPACE + towrite = abinfo.fragments * abinfo.fragsize; + if (towrite == 0) +#endif + towrite = todo; + do { + fd_set writefds[1]; + struct timeval timeout2; + int wrote; + + timeout2.tv_sec = 0; + timeout2.tv_usec = 4*120000; + + FD_ZERO(writefds); + FD_SET(global.soundcard_fd, writefds); + retval2 = select(global.soundcard_fd + 1, + NULL, writefds, NULL, &timeout2); + switch (retval2) { + default: + case -1: perror ("select failed"); + /* fall through */ + case 0: /* timeout */ + result = 2; + goto outside_loop; + case 1: break; + } + if (towrite > todo) { + towrite = todo; + } +#if defined __QNX__ && defined HAVE_SYS_ASOUNDLIB_H + wrote = snd_pcm_plugin_write(pcm_handle, buffer, towrite); +#else + wrote = write(global.soundcard_fd, buffer, towrite); +#endif + if (wrote <= 0) { + perror( "cant write audio"); + result = 1; + goto outside_loop; + } else { + todo -= wrote; + buffer += wrote; + } + } while (todo > 0); +outside_loop: + ; +#endif /* !defined __EMX__ */ +#endif /* !defined __CYGWIN32__ */ +#endif /* ECHO_TO_SOUNDCARD */ + return result; +} + diff --git a/icedax/sndconfig.h b/icedax/sndconfig.h new file mode 100644 index 0000000..1a2e18d --- /dev/null +++ b/icedax/sndconfig.h @@ -0,0 +1,20 @@ +/* + * 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. + * + */ + +/* @(#)sndconfig.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +#define NONBLOCKING_AUDIO +int set_snd_device(const char *devicename); +int init_soundcard(double rate, int bits); + +int open_snd_device(void); +int close_snd_device(void); +int write_snd_device(char *buffer, unsigned length); diff --git a/icedax/sndfile.h b/icedax/sndfile.h new file mode 100644 index 0000000..73ef9ff --- /dev/null +++ b/icedax/sndfile.h @@ -0,0 +1,36 @@ +/* + * 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. + * + */ + +/* @(#)sndfile.h 1.4 06/02/19 Copyright 1998,1999 Heiko Eissfeldt, Copyright 2006 J. Schilling */ + +/* + * generic soundfile structure + */ + +#ifndef _SNDFILE_H +#define _SNDFILE_H + +#include <utypes.h> + +struct soundfile { + int (* InitSound)(int audio, long channels, Ulong rate, + long nBitsPerSample, + Ulong expected_bytes); + int (* ExitSound)(int audio, Ulong nBytesDone); + Ulong (* GetHdrSize)(void); + int (* WriteSound)(int audio, unsigned char *buf, Ulong BytesToDo); + Ulong (* InSizeToOutSize)(Ulong BytesToDo); + + int need_big_endian; +}; + +#endif /* _SNDFILE_H */ diff --git a/icedax/sun.c b/icedax/sun.c new file mode 100644 index 0000000..99ff443 --- /dev/null +++ b/icedax/sun.c @@ -0,0 +1,99 @@ +/* + * 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. + * + */ + +/* @(#)sun.c 1.4 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Heiko Eissfeldt + * + * + * --------------------------------------------------------------------- + * definitions for sun pcm output + * --------------------------------------------------------------------- + */ + +#include "config.h" +#include "mytype.h" +#include <stdio.h> +#include <unixstd.h> +#include "byteorder.h" +#include "sndfile.h" + +typedef struct SUNHDR { + unsigned int magic; /* dns. a la .snd */ + unsigned int data_location; /* offset to data */ + unsigned int size; /* # of data bytes */ + unsigned int format; /* format code */ + unsigned int sample_rate; /* in Hertz */ + unsigned int channelcount; /* 1 for mono, 2 for stereo */ + char info[8]; /* comments */ +} SUNHDR; + +static SUNHDR sunHdr; + +static int InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes); + +static int InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes) +{ + unsigned long format = nBitsPerSample > 8 ? 0x03 : 0x02; + + sunHdr.magic = cpu_to_le32(UINT4_C(0x646e732e)); + sunHdr.data_location = cpu_to_be32(0x20); + sunHdr.size = cpu_to_be32(expected_bytes); + sunHdr.format = cpu_to_be32(format); + sunHdr.sample_rate = cpu_to_be32(rate); + sunHdr.channelcount = cpu_to_be32(channels); + + return write (audio, &sunHdr, sizeof (sunHdr)); +} + +static int ExitSound(int audio, unsigned long nBytesDone); + +static int ExitSound(int audio, unsigned long nBytesDone) +{ + sunHdr.size = cpu_to_be32(nBytesDone); + + /* goto beginning */ + if (lseek(audio, 0L, SEEK_SET) == -1) { + return 0; + } + return write (audio, &sunHdr, sizeof (sunHdr)); +} + +static unsigned long GetHdrSize(void); + +static unsigned long GetHdrSize() +{ + return sizeof( sunHdr ); +} + +static unsigned long InSizeToOutSize(unsigned long BytesToDo); + +static unsigned long InSizeToOutSize(unsigned long BytesToDo) +{ + return BytesToDo; +} + +struct soundfile sunsound = +{ + InitSound, /* init header method */ + ExitSound, /* exit header method */ + GetHdrSize, /* report header size method */ + /* get sound samples out */ + (int (*)(int audio, unsigned char *buf, unsigned long BytesToDo)) write, + InSizeToOutSize, /* compressed? output file size */ + 1 /* needs big endian samples */ +}; + + diff --git a/icedax/sun.h b/icedax/sun.h new file mode 100644 index 0000000..400fc4a --- /dev/null +++ b/icedax/sun.h @@ -0,0 +1,14 @@ +/* + * 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. + * + */ + +/* @(#)sun.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +extern struct soundfile sunsound; diff --git a/icedax/toc.c b/icedax/toc.c new file mode 100644 index 0000000..e03c23d --- /dev/null +++ b/icedax/toc.c @@ -0,0 +1,3841 @@ +/* + * 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. + * + */ + +/* @(#)toc.c 1.57 06/02/19 Copyright 1998-2003 Heiko Eissfeldt */ +/* + * Copyright: GNU Public License 2 applies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * CDDA2WAV (C) Heiko Eissfeldt heiko@hexco.de + * CDDB routines (C) Ti Kan and Steve Scherf + */ +#include "config.h" +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <utypes.h> +#include <intcvt.h> +#include <unixstd.h> /* sleep */ +#include <ctype.h> +#include <errno.h> +#include <fctldefs.h> +#include <vadefs.h> +#include <schily.h> +#include <libport.h> +#include <sys/ioctl.h> + +#define CD_TEXT +#define CD_EXTRA +#undef DEBUG_XTRA +#undef DEBUG_CDTEXT +#undef DEBUG_CDDBP + + +#include <usal/scsitransp.h> + +#include "mytype.h" +#include "byteorder.h" +#include "interface.h" +#include "icedax.h" +#include "global.h" +#include "sha.h" +#include "base64.h" +#include "toc.h" +#include "exitcodes.h" +#include "ringbuff.h" + +int Get_Mins(unsigned long p_track); +int Get_Secs(unsigned long p_track); +int Get_Frames(unsigned long p_track); +int Get_Flags(unsigned long p_track); +int Get_SCMS(unsigned long p_track); + + +#if defined USE_REMOTE +/* tcp stuff */ +/* fix OS/2 compilation */ +#ifdef __EMX__ +#define gethostid nogethostid +#endif +#include <sys/socket.h> +#undef gethostid +#include <netinet/in.h> +#if defined(HAVE_NETDB_H) && !defined(HOST_NOT_FOUND) && \ + !defined(_INCL_NETDB_H) +#include <netdb.h> +#define _INCL_NETDB_H +#endif +#endif + +int have_CD_text; +int have_multisession; +int have_CD_extra; +int have_CDDB; + +struct iterator; + +static void UpdateTrackData(int p_num); +static void UpdateIndexData(int p_num); +static void UpdateTimeData(int p_min, int p_sec, int p_frm); +static unsigned int is_multisession(void); +static unsigned int get_end_of_last_audio_track(unsigned mult_off); +static int cddb_sum(int n); +static void dump_extra_info(unsigned from); +static int GetIndexOfSector(unsigned sec, unsigned track); +static int patch_cd_extra(unsigned track, unsigned long sector); +static void patch_to_audio(unsigned long p_track); +static int restrict_tracks_illleadout(void); +static void Set_MCN(unsigned char *MCN_arg); +static void Set_ISRC(int track, const unsigned char *ISRC_arg); +static void InitIterator(struct iterator *iter, unsigned long p_track); + +static unsigned char g_track=0xff, g_index=0xff; /* current track, index */ + +/* Conversion function: from logical block adresses to minute,second,frame + */ +int lba_2_msf(long lba, int *m, int *s, int *f) +{ +#ifdef __follow_redbook__ + if (lba >= -150 && lba < 405000) { /* lba <= 404849 */ +#else + if (lba >= -150) { +#endif + lba += 150; + } else if (lba >= -45150 && lba <= -151) { + lba += 450150; + } else + return 1; + + *m = lba / 60 / 75; + lba -= (*m)*60*75; + *s = lba / 75; + lba -= (*s)*75; + *f = lba; + + return 0; +} + +/* print the track currently read */ +static void UpdateTrackData(int p_num) +{ + if (global.quiet == 0) { + fprintf (stderr, "\ntrack: %.2d, ", p_num); fflush(stderr); + } + g_track = (unsigned char) p_num; +} + + +/* print the index currently read */ +static void UpdateIndexData(int p_num) +{ + if (global.quiet == 0) { + fprintf (stderr, "index: %.2d\n", p_num); fflush(stderr); + } + g_index = (unsigned char) p_num; +} + + +/* print the time of track currently read */ +static void UpdateTimeData(int p_min, int p_sec, int p_frm) +{ + if (global.quiet == 0) { + fprintf (stderr, "time: %.2d:%.2d.%.2d\r", p_min, p_sec, p_frm); + fflush(stderr); + } +} + +void AnalyzeQchannel(unsigned frame) +{ + subq_chnl *sub_ch; + + if (trackindex_disp != 0) { + sub_ch = ReadSubQ(get_scsi_p(), GET_POSITIONDATA,0); + /* analyze sub Q-channel data */ + if (sub_ch->track != g_track || + sub_ch->index != g_index) { + UpdateTrackData (sub_ch->track); + UpdateIndexData (sub_ch->index); + } + } + frame += 150; + UpdateTimeData ((unsigned char) (frame / (60*75)), + (unsigned char) ((frame % (60*75)) / 75), + (unsigned char) (frame % 75)); +} + +unsigned cdtracks = 0; + +int no_disguised_audiotracks(void) +{ + /* we can assume no audio tracks according to toc here. */ + /* read a data sector from the first data track */ + unsigned char p[3000]; + int retval; + get_scsi_p()->silent++; + retval = 1 == ReadCdRomData(get_scsi_p(), p, Get_StartSector(1), 1); + get_scsi_p()->silent--; + if (retval == 0) { + int i; +fprintf(stderr, "Warning: wrong track types found: patching to audio...\n"); + for (i = 0; i < cdtracks; i++) + patch_to_audio(i); + } + return retval; +} + + +#undef SIM_ILLLEADOUT +int ReadToc(void) +{ + int retval = (*doReadToc)( get_scsi_p() ); +#if defined SIM_ILLLEADOUT + g_toc[cdtracks+1] = 20*75; +#endif + return retval; +} + +static int can_read_illleadout(void); + +static int can_read_illleadout(void) +{ + SCSI *usalp = get_scsi_p(); + + UINT4 buffer [CD_FRAMESIZE_RAW/4]; + if (global.illleadout_cd == 0) return 0; + + usalp->silent++; + global.reads_illleadout = + ReadCdRom(usalp, buffer, Get_AudioStartSector(CDROM_LEADOUT), 1); + usalp->silent--; + return global.reads_illleadout; +} + + +unsigned find_an_off_sector(unsigned lSector, unsigned SectorBurstVal); + +unsigned find_an_off_sector(unsigned lSector, unsigned SectorBurstVal) +{ + long track_of_start = Get_Track(lSector); + long track_of_end = Get_Track(lSector + SectorBurstVal -1); + long start = Get_AudioStartSector(track_of_start); + long end = Get_EndSector(track_of_end); + + if (lSector - start > end - lSector + SectorBurstVal -1) + return start; + else + return end; +} + +#ifdef CD_TEXT +#include "scsi_cmds.h" +#endif + + +int handle_cdtext(void) +{ +#ifdef CD_TEXT + if (bufferTOC[0] == 0 && bufferTOC[1] == 0) { + have_CD_text = 0; + return have_CD_text; + } + + /* do a quick scan over all pack type indicators */ + { + int i; + int count_fails = 0; + int len = (bufferTOC[0] << 8) | bufferTOC[1]; + + len = min(len, 2048); + for (i = 0; i < len-4; i += 18) { + if (bufferTOC[4+i] < 0x80 || bufferTOC[4+i] > 0x8f) { + count_fails++; + } + } + have_CD_text = len > 4 && count_fails < 3; + } + +#else + have_CD_text = 0; +#endif + return have_CD_text; +} + + +#ifdef CD_TEXT +#include "cd_text.c" +#endif + + +#if defined CDROMMULTISESSION +static int tmp_fd; +#endif + +#ifdef CD_EXTRA +#include "cd_extra.c" +#endif + +static unsigned session_start; +/* + A Cd-Extra is detected, if it is a multisession CD with + only audio tracks in the first session and a data track + in the last session. + */ +static unsigned is_multisession(void) +{ + unsigned mult_off; +#if defined CDROMMULTISESSION + /* + * FIXME: we would have to do a ioctl (CDROMMULTISESSION) + * for the cdrom device associated with the generic device + * not just AUX_DEVICE + */ + struct cdrom_multisession ms_str; + + if (interface == GENERIC_SCSI) + tmp_fd = open (global.aux_name, O_RDONLY); + else + tmp_fd = global.cooked_fd; + + if (tmp_fd != -1) { + int result; + + ms_str.addr_format = CDROM_LBA; + result = ioctl(tmp_fd, CDROMMULTISESSION, &ms_str); + if (result == -1) { + if (global.verbose != 0) + perror("multi session ioctl not supported: "); + } else { +#ifdef DEBUG_XTRA + fprintf(stderr, "current ioctl multisession_offset = %u\n", ms_str.addr.lba); +#endif + if (interface == GENERIC_SCSI) + close (tmp_fd); + if (ms_str.addr.lba > 0) + return ms_str.addr.lba; + } + } +#endif + mult_off = 0; + if (LastAudioTrack() + 1 == FirstDataTrack()) { + mult_off = Get_StartSector(FirstDataTrack()); + } + +#ifdef DEBUG_XTRA + fprintf(stderr, "current guessed multisession_offset = %u\n", mult_off); +#endif + return mult_off; +} + +#define SESSIONSECTORS (152*75) +/* + The solution is to read the Table of Contents of the first + session only (if the drive permits that) and directly use + the start of the leadout. If this is not supported, we subtract + a constant of SESSIONSECTORS sectors (found heuristically). + */ +static unsigned get_end_of_last_audio_track(unsigned mult_off) +{ + unsigned retval; + + /* Try to read the first session table of contents. + This works for Sony and mmc type drives. */ + if (ReadLastAudio && (retval = ReadLastAudio(get_scsi_p())) != 0) { + return retval; + } else { + return mult_off - SESSIONSECTORS; + } +} + +static void dump_cdtext_info(void); + +#if defined CDDB_SUPPORT +static void emit_cddb_form(char *fname_baseval); +#endif + +#if defined CDINDEX_SUPPORT +static void emit_cdindex_form(char *fname_baseval); +#endif + + +typedef struct TOC { /* structure of table of contents (cdrom) */ + unsigned char reserved1; + unsigned char bFlags; + unsigned char bTrack; + unsigned char reserved2; + unsigned int dwStartSector; + int mins; + int secs; + int frms; + unsigned char ISRC[16]; + int SCMS; +} TOC; + + +/* Flags contains two fields: + bits 7-4 (ADR) + : 0 no sub-q-channel information + : 1 sub-q-channel contains current position + : 2 sub-q-channel contains media catalog number + : 3 sub-q-channel contains International Standard + Recording Code ISRC + : other values reserved + bits 3-0 (Control) : + bit 3 : when set indicates there are 4 audio channels else 2 channels + bit 2 : when set indicates this is a data track else an audio track + bit 1 : when set indicates digital copy is permitted else prohibited + bit 0 : when set indicates pre-emphasis is present else not present + */ + +#define GETFLAGS(x) ((x)->bFlags) +#define GETTRACK(x) ((x)->bTrack) +#define GETSTART(x) ((x)->dwStartSector) +#define GETMINS(x) ((x)->mins) +#define GETSECS(x) ((x)->secs) +#define GETFRAMES(x) ((x)->frms) +#define GETISRC(x) ((x)->ISRC) + +#define IS__PREEMPHASIZED(p) ( (GETFLAGS(p) & 0x10) != 0) +#define IS__INCREMENTAL(p) ( (GETFLAGS(p) & 0x10) != 0) +#define IS__COPYRESTRICTED(p) (!(GETFLAGS(p) & 0x20) != 0) +#define IS__COPYRIGHTED(p) (!(GETFLAGS(p) & 0x20) != 0) +#define IS__DATA(p) ( (GETFLAGS(p) & 0x40) != 0) +#define IS__AUDIO(p) (!(GETFLAGS(p) & 0x40) != 0) +#define IS__QUADRO(p) ( (GETFLAGS(p) & 0x80) != 0) + +/* + * Iterator interface inspired from Java + */ +struct iterator { + int index; + int startindex; + void (*reset)(struct iterator *this); + struct TOC *(*getNextTrack)(struct iterator *this); + int (*hasNextTrack)(struct iterator *this); +}; + + + + +/* The Table of Contents needs to be corrected if we + have a CD-Extra. In this case all audio tracks are + followed by a data track (in the second session). + Unlike for single session CDs the end of the last audio + track cannot be set to the start of the following + track, since the lead-out and lead-in would then + errenously be part of the audio track. This would + lead to read errors when trying to read into the + lead-out area. + So the length of the last track in case of Cd-Extra + has to be fixed. + */ +unsigned FixupTOC(unsigned no_tracks) +{ + unsigned mult_off; + unsigned offset = 0; + int j = -1; + unsigned real_end = 2000000; + + /* get the multisession offset in sectors */ + mult_off = is_multisession(); + + /* if the first track address had been the victim of an underflow, + * set it to zero. + */ + if (Get_StartSector(1) > Get_StartSector(LastTrack())) { + fprintf(stderr, "Warning: first track has negative start sector! Setting to zero.\n"); + toc_entry( 1, Get_Flags(1), Get_Tracknumber(1), Get_ISRC(1), 0, 0, 2, 0 ); + } + +#ifdef DEBUG_XTRA + fprintf(stderr, "current multisession_offset = %u\n", mult_off); +#endif + dump_cdtext_info(); + + if (mult_off > 100) { /* the offset has to have a minimum size */ + + /* believe the multisession offset :-) */ + /* adjust end of last audio track to be in the first session */ + real_end = get_end_of_last_audio_track(mult_off); +#ifdef DEBUG_XTRA + fprintf(stderr, "current end = %u\n", real_end); +#endif + + j = FirstDataTrack(); + if (LastAudioTrack() + 1 == j) { + long sj = Get_StartSector(j); + if (sj > (long)real_end) { + session_start = mult_off; + have_multisession = sj; + +#ifdef CD_EXTRA + offset = Read_CD_Extra_Info(sj); + + if (offset != 0) { + have_CD_extra = sj; + dump_extra_info(offset); + } +#endif + } + } + } + if (global.cddbp) { +#if defined USE_REMOTE + if (global.disctitle == NULL) { + have_CDDB = !request_titles(); + } +#else + fprintf(stderr, "Cannot lookup titles: no cddbp support included!\n"); +#endif + } +#if defined CDINDEX_SUPPORT || defined CDDB_SUPPORT + if (have_CD_text || have_CD_extra || have_CDDB) { + unsigned long count_audio_tracks = 0; + static struct iterator i; + if (i.reset == NULL) + InitIterator(&i, 1); + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + if (IS__AUDIO(p)) count_audio_tracks++; + } + + if (count_audio_tracks > 0 && global.no_cddbfile == 0) { +#if defined CDINDEX_SUPPORT + emit_cdindex_form(global.fname_base); +#endif +#if defined CDDB_SUPPORT + emit_cddb_form(global.fname_base); +#endif + } + } +#endif + if (have_multisession) { + /* set start of track to beginning of lead-out */ + patch_cd_extra(j, real_end); +#if defined CD_EXTRA && defined DEBUG_XTRA + fprintf(stderr, "setting end of session (track %d) to %u\n", j, real_end); +#endif + } + return offset; +} + +static int cddb_sum(int n) +{ + int ret; + + for (ret = 0; n > 0; n /= 10) { + ret += (n % 10); + } + + return ret; +} + +void calc_cddb_id(void) +{ + UINT4 i; + UINT4 t = 0; + UINT4 n = 0; + + for (i = 1; i <= cdtracks; i++) { + n += cddb_sum(Get_StartSector(i)/75 + 2); + } + + t = Get_StartSector(i)/75 - Get_StartSector(1)/75; + + global.cddb_id = (n % 0xff) << 24 | (t << 8) | cdtracks; +} + + +#undef TESTCDINDEX +#ifdef TESTCDINDEX +void TestGenerateId(void) +{ + SHA_INFO sha; + unsigned char digest[20], *base64; + unsigned long size; + + sha_init(&sha); + sha_update(&sha, (unsigned char *)"0123456789", 10); + sha_final(digest, &sha); + + base64 = rfc822_binary((char *)digest, 20, &size); + if (strncmp((char*) base64, "h6zsF82dzSCnFsws9nQXtxyKcBY-", size)) + { + free(base64); + + fprintf(stderr, "The SHA-1 hash function failed to properly generate the\n"); + fprintf(stderr, "test key.\n"); + exit(INTERNAL_ERROR); + } + free(base64); +} +#endif + +void calc_cdindex_id() +{ + SHA_INFO sha; + unsigned char digest[20], *base64; + unsigned long size; + unsigned i; + char temp[9]; + +#ifdef TESTCDINDEX + TestGenerateId(); + g_toc[1].bTrack = 1; + cdtracks = 15; + g_toc[cdtracks].bTrack = 15; + i = 1; + g_toc[i++].dwStartSector = 0U; + g_toc[i++].dwStartSector = 18641U; + g_toc[i++].dwStartSector = 34667U; + g_toc[i++].dwStartSector = 56350U; + g_toc[i++].dwStartSector = 77006U; + g_toc[i++].dwStartSector = 106094U; + g_toc[i++].dwStartSector = 125729U; + g_toc[i++].dwStartSector = 149785U; + g_toc[i++].dwStartSector = 168885U; + g_toc[i++].dwStartSector = 185910U; + g_toc[i++].dwStartSector = 205829U; + g_toc[i++].dwStartSector = 230142U; + g_toc[i++].dwStartSector = 246659U; + g_toc[i++].dwStartSector = 265614U; + g_toc[i++].dwStartSector = 289479U; + g_toc[i++].dwStartSector = 325732U; +#endif + sha_init(&sha); + sprintf(temp, "%02X", Get_Tracknumber(1)); + sha_update(&sha, (unsigned char *)temp, 2); + sprintf(temp, "%02X", Get_Tracknumber(cdtracks)); + sha_update(&sha, (unsigned char *)temp, 2); + + /* the position of the leadout comes first. */ + sprintf(temp, "%08lX", 150 + Get_StartSector(CDROM_LEADOUT)); + sha_update(&sha, (unsigned char *)temp, 8); + + /* now 99 tracks follow with their positions. */ + for (i = 1; i <= cdtracks; i++) { + sprintf(temp, "%08lX", 150+Get_StartSector(i)); + sha_update(&sha, (unsigned char *)temp, 8); + } + for (i++ ; i <= 100; i++) { + sha_update(&sha, (unsigned char *)"00000000", 8); + } + sha_final(digest, &sha); + + base64 = rfc822_binary((char *)digest, 20, &size); + global.cdindex_id = base64; +} + + +#if defined CDDB_SUPPORT + +#ifdef PROTOTYPES +static void escape_and_split(FILE *channel, const char *args, ...) +#else +/*VARARGS3*/ +static void escape_and_split(FILE *channel, const char *args, va_dcl va_alist) +#endif +{ + va_list marker; + + int prefixlen; + int len; + char *q; + +#ifdef PROTOTYPES + va_start(marker, args); +#else + va_start(marker); +#endif + + prefixlen = strlen(args); + len = prefixlen; + fputs(args, channel); + + q = va_arg(marker, char *); + while (*q != '\0') { + while (*q != '\0') { + len += 2; + if (*q == '\\') + fputs("\\\\", channel); + else if (*q == '\t') + fputs("\\t", channel); + else if (*q == '\n') + fputs("\\n", channel); + else { + fputc(*q, channel); + len--; + } + if (len > 78) { + fputc('\n', channel); + fputs(args, channel); + len = prefixlen; + } + q++; + } + q = va_arg(marker, char *); + } + fputc('\n', channel); + + va_end(marker); +} + +static void emit_cddb_form(char *fname_baseval) +{ + static struct iterator i; + unsigned first_audio; + FILE *cddb_form; + char fname[200]; + char *pp; + + if (fname_baseval == NULL || fname_baseval[0] == 0) + return; + + if (!strcmp(fname_baseval,"standard_output")) return; + InitIterator(&i, 1); + + strncpy(fname, fname_baseval, sizeof(fname) -1); + fname[sizeof(fname) -1] = 0; + pp = strrchr(fname, '.'); + if (pp == NULL) { + pp = fname + strlen(fname); + } + strncpy(pp, ".cddb", sizeof(fname) - 1 - (pp - fname)); + + cddb_form = fopen(fname, "w"); + if (cddb_form == NULL) return; + + first_audio = FirstAudioTrack(); + fprintf( cddb_form, "# xmcd\n#\n"); + fprintf( cddb_form, "# Track frame offsets:\n#\n"); + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + if (GETTRACK(p) == CDROM_LEADOUT) break; + fprintf( cddb_form, + "# %lu\n", 150 + Get_AudioStartSector(GETTRACK(p))); + } + + fprintf( cddb_form, "#\n# Disc length: %lu seconds\n#\n", + (150 + Get_StartSector(CDROM_LEADOUT)) / 75); + fprintf( cddb_form, "# Revision: %u\n", global.cddb_revision ); + fprintf( cddb_form, "# Submitted via: icedax " VERSION "\n" ); + + fprintf( cddb_form, "DISCID=%08lx\n", (unsigned long)global.cddb_id); + + if (global.disctitle == NULL && global.creator == NULL) { + fprintf( cddb_form, "DTITLE=\n"); + } else { + if (global.creator == NULL) { + escape_and_split( cddb_form, "DTITLE=", global.disctitle, ""); + } else if (global.disctitle == NULL) { + escape_and_split( cddb_form, "DTITLE=", global.creator, ""); + } else { + escape_and_split( cddb_form, "DTITLE=", global.creator, " / ", global.disctitle, ""); + } + } + if (global.cddb_year != 0) + fprintf( cddb_form, "DYEAR=%4u\n", global.cddb_year); + else + fprintf( cddb_form, "DYEAR=\n"); + fprintf( cddb_form, "DGENRE=%s\n", global.cddb_genre); + + i.reset(&i); + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + int ii; + + ii = GETTRACK(p); + if (ii == CDROM_LEADOUT) break; + + if (global.tracktitle[ii] != NULL) { + char prefix[10]; + sprintf(prefix, "TTITLE%d=", ii-1); + escape_and_split( cddb_form, prefix, global.tracktitle[ii], ""); + } else { + fprintf( cddb_form, "TTITLE%d=\n", ii-1); + } + } + + if (global.copyright_message == NULL) { + fprintf( cddb_form, "EXTD=\n"); + } else { + escape_and_split( cddb_form, "EXTD=", "Copyright ", global.copyright_message, ""); + } + + i.reset(&i); + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + int ii; + + ii = GETTRACK(p); + + if (ii == CDROM_LEADOUT) break; + + fprintf( cddb_form, "EXTT%d=\n", ii-1); + } + fprintf( cddb_form, "PLAYORDER=\n"); + fclose( cddb_form ); +} + +#if defined USE_REMOTE +#include <pwd.h> + +static int readn(register int fd, register char *ptr, register int nbytes) +{ + int nread; + + nread = read(fd, ptr, nbytes); +#ifdef DEBUG_CDDBP + if (nread > 0) { + fprintf(stderr, "READ :(%d)", nread); + write(2, ptr, nread); + } +#endif + if (nread < 0) { + perror("socket read error: "); + fprintf(stderr, "fd=%d, ptr=%p, nbytes=%d\n", fd, ptr, nbytes); + } + + return nread; +} + +static ssize_t writez(int fd, const char *ptr) +{ + size_t nleft, nbytes; + + nleft = nbytes = strlen(ptr); + + while (nleft > 0) { + ssize_t nwritten = write(fd, ptr, nleft); + if (nwritten <= 0) { + return nwritten; /* return error */ + } +#ifdef DEBUG_CDDBP + fprintf(stderr, "WRITE:%s\n", ptr); +#endif + + nleft -= nwritten; + ptr += nwritten; + } + + return nbytes - nleft; +} + +#define SOCKBUFF 2048 + +static void filter_nonprintable(char *c, size_t l) +{ + size_t i; + for(i = 0; i < l; ++i) { + if(!isprint(c[i]) && !isspace(c[i])) { + c[i] = '_'; + } + } +} + + +int process_cddb_titles(int sock_fd, char *inbuff, int readbytes); +int process_cddb_titles(int sock_fd, char *inbuff, int readbytes) +{ + int finished = 0; + char *p = inbuff; + int ind = 0; + unsigned char ** target = &global.creator; + + do { + while (readbytes > 0) { + /* do we have a complete line in the buffer? */ + p = (char *)memchr(inbuff+ind, '\n', readbytes); + if (p == NULL) break; + + /* look for the terminator first */ + if (!strncmp(".\r\n", inbuff+ind, 3)) { + finished = 1; + break; + } + /* kill carriage return */ + if (p > inbuff+ind && *(p-1) == '\r') { + *(p-1) = '\0'; + } + /* kill line feed */ + *p = '\0'; + + /* handle escaped characters */ + + { + char *q = inbuff+ind; + while (*q) { + if (*q++ == '\\' && *q != '\0') { + if (*q == '\\') { + readbytes--; + p--; + memmove(q, q+1, readbytes - (q-inbuff-ind)); + } else if (*q == 'n') { + *(q-1) = '\n'; + readbytes--; + p--; + memmove(q, q+1, readbytes - (q-inbuff-ind)); + } else if (*q == 't') { + *(q-1) = '\t'; + readbytes--; + p--; + memmove(q, q+1, readbytes - (q-inbuff-ind)); + } + } + } + + } + + /* handle multi line entries concatenate fields */ + +/* TODO if the delimiter is split into two lines, it is not recognized. */ + if (!strncmp(inbuff+ind, "DTITLE=", 7)) { + char *res = strstr(inbuff+ind+7, " / "); + int clen; + char *q; + + if (res == NULL) { + /* no limiter found yet */ + /* copy until the end */ + q = p; + } else { + /* limiter found */ + /* copy until the limiter */ + q = res; + *q = '\0'; + } + + clen = q - (inbuff+ind+7); + if (*target == NULL) { + *target = malloc(clen+1); + if (*target != NULL) + **target = '\0'; + } else { + *target = realloc(*target, strlen((char *)*target) + clen - 1); + } + if (*target != NULL) { + strcat((char *)*target, inbuff+ind+7); + } + + /* handle part after the delimiter, if present */ + if (res != NULL) { + target = (unsigned char **)&global.disctitle; + /* skip the delimiter */ + q += 3; + clen = p - q; + if (*target == NULL) { + *target = malloc(clen+1); + if (*target != NULL) + **target = '\0'; + } + if (*target != NULL) { + strcat((char *)*target, q); + } + } + } else if (!strncmp(inbuff+ind, "TTITLE", 6)) { + char *q = (char *)memchr(inbuff+ind, '=', readbytes); + unsigned tno; + + if (q != NULL) { + *q = '\0'; + tno = (unsigned)atoi(inbuff+ind+6); + tno++; + if (tno < 100) { + if (global.tracktitle[tno] == NULL) { + global.tracktitle[tno] = malloc( p - q + 1 ); + if (global.tracktitle[tno] != NULL) + *(global.tracktitle[tno]) = '\0'; + } else { + global.tracktitle[tno] = realloc(global.tracktitle[tno], strlen((char *)global.tracktitle[tno]) + p - q + 1 ); + } + if (global.tracktitle[tno] != NULL) { + strcat((char *)global.tracktitle[tno], q+1); + } + } + } + } else if (!strncmp(inbuff+ind, "DYEAR", 5)) { + char *q = (char *)memchr(inbuff+ind, '=', readbytes); + if (q++ != NULL) { + sscanf(q, "%d", &global.cddb_year); + } + } else if (!strncmp(inbuff+ind, "DGENRE", 6)) { + char *q = (char *)memchr(inbuff+ind, '=', readbytes); + if (q++ != NULL) { + /* patch from Joe Nuzman, thanks */ + /* might have significant whitespace */ + strncpy(global.cddb_genre, q, sizeof(global.cddb_genre)-1); + /* always have a terminator */ + global.cddb_genre[sizeof(global.cddb_genre)-1] = '\0'; + } + } else if (!strncmp(inbuff+ind, "# Revision: ", 12)) { + char *q = inbuff+ind+11; + sscanf(q, "%d", &global.cddb_revision); + global.cddb_revision++; + } + readbytes -= (p - inbuff -ind) + 1; + ind = (p - inbuff) + 1; + } + if (!finished) { + int newbytes; + memmove(inbuff, inbuff+ind, readbytes); + newbytes = readn(sock_fd, inbuff+readbytes, SOCKBUFF-readbytes); + if (newbytes < 0) { + fprintf(stderr, "Could not read from socket.\n"); + return 0; /* Caller checks for != 1 */ + } + filter_nonprintable(inbuff+readbytes, newbytes); + if (newbytes <= 0) + break; + readbytes += newbytes; + ind = 0; + } + } while (!(finished || readbytes == 0)); + return finished; +} + +static int handle_userchoice(char *p, unsigned size); + +static int handle_userchoice(char *p, unsigned size) +{ + unsigned nr = 0; + unsigned user_choice; + int i; + char *q; + char *o; + + /* count lines. */ + q = p; + while ((q = (char *)memchr(q, '\n', size - (q-p))) != NULL) { + nr++; + q++; + } + if (nr > 1) nr--; + + /* handle escaped characters */ + + { + char *r = p; + while (*r) { + if (*r++ == '\\' && *r != '\0') { + if (*r == '\\') { + size--; + memmove(r, r+1, size - (r-p)); + } else if (*r == 'n') { + *(r-1) = '\n'; + size--; + memmove(r, r+1, size - (r-p)); + } else if (*r == 't') { + *(r-1) = '\t'; + size--; + memmove(r, r+1, size - (r-p)); + } + } + } + } + + /* list entries. */ + q = p; + fprintf(stderr, "%u entries found:\n", nr); + for (q = (char *)memchr(q, '\n', size - (q-p)), o = p, i = 0; i < nr; i++) { + *q = '\0'; + fprintf(stderr, "%02u: %s\n", i, o); + o = q+1; + q = (char *)memchr(q, '\n', size - (q-p)); + } + fprintf(stderr, "%02u: ignore\n", i); + + /* get user response. */ + do { + fprintf(stderr, "please choose one (0-%u): ", nr); + scanf("%u", &user_choice); /* FIXME: check return value */ + } while (user_choice > nr); + + if (user_choice == nr) + return -1; + + /* skip to choice. */ + q = p; + for (i = 0; i <= (int)user_choice - 1; i++) { + q = (char *)memchr(q, '\0', size - (q-p)) + 1; + } + return q-p; +} + +/* request disc and track titles from a cddbp server. + * + * return values: + * 0 titles have been found exactly (success) + * -1 some communication error happened. + * 1 titles have not been found. + * 2 multiple fuzzy matches have been found. + */ +int +request_titles(void) +{ + int retval = 0; + int sock_fd; + struct sockaddr_in sa; + struct hostent *he; + struct servent *se; + struct passwd *pw = getpwuid(getuid()); + char hostname[HOST_NAME_MAX]; + char inbuff[SOCKBUFF]; + char outbuff[SOCKBUFF]; + int i; + char category[64]; + unsigned cat_offset; + unsigned disc_id; + ssize_t readbytes; + + sock_fd = socket(AF_INET, SOCK_STREAM, 0); + if (sock_fd < 0) { + perror("cddb socket failed: "); + retval = -1; + goto errout; + } + + /* TODO fallbacks + * freedb.freedb.org + * de.freedb.org + * at.freedb.org + */ + if (global.cddbp_server != NULL) + he = gethostbyname(global.cddbp_server); + else + he = gethostbyname(CDDBHOST /*"freedb.freedb.org"*/); + + if (he == NULL) { + perror("cddb cannot resolve freedb host: "); + he = malloc(sizeof(struct hostent)); + memset(he, 0 , sizeof(struct hostent)); + he->h_length = 4; + he->h_addrtype = AF_INET; + he->h_addr_list = malloc(4); + he->h_addr_list[0] = malloc(4); + ((struct in_addr *)(he->h_addr_list[0]))->s_addr = + /* kingfisher.berlios.de freedb.freedb.de */ + htonl(UINT_C(0xc3254d85)); /*0xc2610412*/ + he->h_name = "freedb.freedb.org"; +#if 0 + retval = -1; + goto errout; +#endif + } + + /* save result data IMMEDIATELY!! */ + memset(&sa, 0 , sizeof(struct sockaddr_in)); + sa.sin_family = he->h_addrtype; /* AF_INET; */ + sa.sin_addr.s_addr = ((struct in_addr *)((he->h_addr_list)[0]))->s_addr; + + se = NULL; + if (global.cddbp_port == NULL) + se = getservbyname("cddbp-alt", "tcp"); + + if (se == NULL) { + if (global.cddbp_port == NULL) { + se = getservbyname("cddbp", "tcp"); + } + if (se == NULL) { + se = malloc(sizeof(struct servent)); + memset(se, 0 , sizeof(struct servent)); + se->s_port = htons(CDDBPORT /*8880*/); +#if 0 + perror("cddb cannot resolve cddbp or cddbp-alt port:\n "); + retval = -1; + goto errout; +#endif + } + } + if (global.cddbp_port != NULL) { + se->s_port = htons(atoi(global.cddbp_port)); + } + + sa.sin_port = se->s_port; + +/* TODO timeout */ + if (0 > connect(sock_fd, (struct sockaddr *)&sa, + sizeof(struct sockaddr_in))) { + perror("cddb connect failed: "); + retval = -1; + goto errout; + } + + /* read banner */ + readbytes = readn(sock_fd, inbuff, sizeof(inbuff)); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + + if (strncmp(inbuff, "200 ", 4) && strncmp(inbuff, "201 ", 4)) { + if(readbytes == sizeof(inbuff)) + --readbytes; + inbuff[readbytes] = '\0'; + filter_nonprintable(inbuff, readbytes); + fprintf(stderr, "bad status from freedb server during sign-on banner: %s\n", inbuff); + retval = -1; + goto errout; + } + + /* say hello */ + hostname[0] = '\0'; + if (0 > gethostname(hostname, sizeof(hostname))) + strcpy(hostname, "unknown_host"); + hostname[sizeof(hostname)-1] = '\0'; + writez(sock_fd, "cddb hello "); + if (pw != NULL) { + BOOL space_err = FALSE; + BOOL ascii_err = FALSE; + /* change spaces to underscores */ + char *q = pw->pw_name; + while (*q != '\0') { + if (*q == ' ') { + if (!space_err) { + space_err = TRUE; + errmsgno(EX_BAD, + "Warning: Space in user name '%s'.\n", + pw->pw_name); + } + *q = '_'; + } + if (*q < ' ' || *q > '~') { + if (!ascii_err) { + ascii_err = TRUE; + errmsgno(EX_BAD, + "Warning: Nonascii character in user name '%s'.\n", + pw->pw_name); + } + *q = '_'; + } + q++; + } + writez(sock_fd, pw->pw_name); + writez(sock_fd, " "); + } else { + writez(sock_fd, "unknown "); + } + + /* change spaces to underscores */ + { + char *q = hostname; + BOOL space_err = FALSE; + BOOL ascii_err = FALSE; + + while (*q != '\0') { + if (*q == ' ') { + if (!space_err) { + space_err = TRUE; + errmsgno(EX_BAD, + "Warning: Space in hostname '%s'.\n", + hostname); + } + *q = '_'; + } + if (*q < ' ' || *q > '~') { + if (!ascii_err) { + ascii_err = TRUE; + errmsgno(EX_BAD, + "Warning: Nonascii character in hostname '%s'.\n", + hostname); + } + *q = '_'; + } + q++; + } + } + + writez(sock_fd, hostname); + writez(sock_fd, " icedax " VERSION "\n"); + + readbytes = readn(sock_fd, inbuff, sizeof(inbuff)); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + if (strncmp(inbuff, "200 ", 4)) { + if(readbytes == sizeof(inbuff)) + --readbytes; + inbuff[readbytes] = '\0'; + filter_nonprintable(inbuff, readbytes); + fprintf(stderr, "bad status from freedb server during hello: %s\n", inbuff); + retval = -1; + goto signoff; + } + + /* enable new protocol variant. Weird command here, no cddb prefix ?!?! */ + writez(sock_fd, "proto\n"); + readbytes = readn(sock_fd, inbuff, sizeof(inbuff)); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + /* check for errors and maximum supported protocol level */ + if (strncmp(inbuff, "201 ", 4) > 0) { + if(readbytes == sizeof(inbuff)) + --readbytes; + inbuff[readbytes] = '\0'; + filter_nonprintable(inbuff, readbytes); + fprintf(stderr, "bad status from freedb server during proto command: %s\n", inbuff); + retval = -1; + goto signoff; + } + + /* check the supported protocol level */ + if (!memcmp(inbuff, "200 CDDB protocol level: current 1, supported ", 46)) { + char *q = strstr(inbuff, " supported "); + unsigned pr_level; + + if (q != NULL) { + q += 11; + sscanf(q, "%u\n", &pr_level); + if (pr_level > 1) { + if (pr_level > 5) + pr_level = 5; + sprintf(inbuff, "proto %1u\n", pr_level); + writez(sock_fd, inbuff); + readbytes = readn(sock_fd, inbuff, sizeof(inbuff)); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + /* check for errors and maximum supported protocol level */ + if (strncmp(inbuff, "201 ", 4) > 0) { + if(readbytes == sizeof(inbuff)) + --readbytes; + inbuff[readbytes] = '\0'; + filter_nonprintable(inbuff, + readbytes); + fprintf(stderr, "bad status from freedb server during proto x: %s\n", inbuff); + retval = -1; + goto signoff; + } + } + } + } + + /* format query string */ + /* query */ +#define CDDPB_INCLUDING_DATATRACKS +#ifdef CDDPB_INCLUDING_DATATRACKS + sprintf(outbuff, "cddb query %08lx %ld ", (unsigned long)global.cddb_id, LastTrack() - FirstTrack() + 1); + /* first all leading datatracks */ + { + int j = FirstAudioTrack(); + if (j < 0) + j = LastTrack() +1; + for (i = FirstTrack(); i < j; i++) { + sprintf(outbuff + strlen(outbuff), "%ld ", 150 + Get_StartSector(i)); + } + } +#else + sprintf(outbuff, "cddb query %08lx %ld ", global.cddb_id, LastAudioTrack() - FirstAudioTrack() + 1); +#endif + /* all audio tracks */ + for (i = FirstAudioTrack(); i != -1 && i <= LastAudioTrack(); i++) { + sprintf(outbuff + strlen(outbuff), "%ld ", 150 + Get_AudioStartSector(i)); + } +#ifdef CDDPB_INCLUDING_DATATRACKS + /* now all trailing datatracks */ + for (; i != -1 && i <= LastTrack(); i++) { + sprintf(outbuff + strlen(outbuff), "%ld ", 150 + Get_StartSector(i)); + } + sprintf(outbuff + strlen(outbuff), "%lu\n", + (150 + Get_StartSector(CDROM_LEADOUT)) / 75); +#else + sprintf(outbuff + strlen(outbuff), "%lu\n", + (150 + Get_LastSectorOnCd(FirstAudioTrack())) / 75); +#endif +/* strcpy(outbuff, "cddb query 9709210c 12 150 12010 33557 50765 65380 81467 93235 109115 124135 137732 152575 166742 2339\n"); */ +/* strcpy(outbuff, "cddb query 03015501 1 296 344\n"); */ + writez(sock_fd, outbuff); + + readbytes = readn(sock_fd, inbuff, sizeof(inbuff) - 1); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + inbuff[readbytes] = '\0'; + filter_nonprintable(inbuff, readbytes); + cat_offset = 4; + if (!strncmp(inbuff, "210 ", 4) + || !strncmp(inbuff, "211 ", 4)) { + /* Check if there are really multiple entries. */ + char *p = (char *)memchr(inbuff, '\n', readbytes-1); + + if (p != NULL) cat_offset = p+1 - inbuff; + /* first entry */ + if (p) p = (char *)memchr(p+1, '\n', inbuff+readbytes - p); + /* second entry */ + if (p) p = (char *)memchr(p+1, '\n', inbuff+readbytes - p); + /* . */ + if (p) p = (char *)memchr(p+1, '\n', inbuff+readbytes - p); + if (p) { + /* multiple entries */ + switch (global.cddbp) { + case 2: /* take the first entry */ + break; + case 1: /* ask user */ + if (!global.gui) { + int userret = handle_userchoice(inbuff+cat_offset, readbytes - cat_offset); + if (userret == -1) { + /* ignore any selection */ + retval = -1; + goto signoff; + } + cat_offset += userret; + } + break; + default: + fprintf(stderr, "multiple entries found: %s\n", inbuff); + retval = 2; + goto signoff; + } + } + + } else if (strncmp(inbuff, "200 ", 4)) { + if (!strncmp(inbuff, "202 ", 4)) { + fprintf(stderr, "no cddb entry found: %s\n", inbuff); + retval = 1; + } else { + fprintf(stderr, "bad status from freedb server during query: %s\n%s", inbuff, outbuff); + retval = -1; + } + goto signoff; + } + sscanf(inbuff + cat_offset, "%s %x", category, &disc_id ); + + + /* read */ + sprintf(inbuff, "cddb read %s %08x\n", category, disc_id); + writez(sock_fd, inbuff); + + /* read status and first buffer size. */ + readbytes = readn(sock_fd, inbuff, sizeof(inbuff)); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + filter_nonprintable(inbuff, readbytes); + if (strncmp(inbuff, "210 ", 4)) { + if(readbytes == sizeof(inbuff)) + --readbytes; + inbuff[readbytes] = '\0'; + fprintf(stderr, "bad status from freedb server during read: %s\n", inbuff); + retval = -1; + goto signoff; + } + + if (1 != process_cddb_titles(sock_fd, inbuff, readbytes)) { + fprintf(stderr, "cddb read finished not correctly!\n"); + } + +signoff: + /* sign-off */ + writez(sock_fd, "quit\n"); + readbytes = readn(sock_fd, inbuff, sizeof(inbuff)); + if (readbytes < 0) { + fprintf(stderr, "Could not read from socket\n"); + retval = -1; + goto errout; + } + if (strncmp(inbuff, "230 ", 4)) { + if(readbytes == sizeof(inbuff)) + --readbytes; + inbuff[readbytes] = '\0'; + filter_nonprintable(inbuff, readbytes); + fprintf(stderr, "bad status from freedb server during quit: %s\n", inbuff); + goto errout; + } + +errout: + close(sock_fd); + return retval; +} +#endif +#endif + +#if defined CDINDEX_SUPPORT + +static int IsSingleArtist(void); + +/* check, if there are more than one track creators */ +static int IsSingleArtist(void) +{ + static struct iterator i; + InitIterator(&i, 1); + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + int ii; + + if (IS__DATA(p) || GETTRACK(p) == CDROM_LEADOUT) continue; + + ii = GETTRACK(p); + if (global.creator && global.trackcreator[ii] + && strcmp((char *) global.creator, + (char *) global.trackcreator[ii]) != 0) + return 0; + } + return 1; +} + +static const char *a2h[255-191] = { +"À", +"Á", +"Â", +"Ã", +"Ä", +"Å", +"Æ", +"Ç", +"È", +"É", +"Ê", +"Ë", +"Ì", +"Í", +"Î", +"Ï", +"Ð", +"Ñ", +"Ò", +"Ó", +"Ô", +"Õ", +"Ö", +"×", +"Ø", +"Ù", +"Ú", +"Û", +"Ü", +"Ý", +"Þ", +"ß", +"à", +"á", +"â", +"ã", +"ä", +"å", +"æ", +"ç", +"è", +"é", +"ê", +"ë", +"ì", +"í", +"î", +"ï", +"ð", +"ñ", +"ò", +"ó", +"ô", +"õ", +"ö", +"÷", +"ø", +"ù", +"ú", +"û", +"ü", +"ý", +"þ", +"ÿ", +}; + +static char *ascii2html(unsigned char *inp) +{ + static size_t buflen = 256; + static char *outline = 0; + size_t pos = 0; + size_t l=0; + + /* init */ + if(!outline) { + outline = malloc(buflen); + if(outline == 0) { + fprintf(stderr, "error: memory exhausted\n"); + _exit(EXIT_FAILURE); + } + } + + outline[pos] = '\0'; + + while (*inp != '\0') { + + /* Pick the sequence to insert */ + const char *insert; + char b[2]; + const int c = (unsigned char)*inp; + switch(c) { + case '"': insert = """; break; + case '&': insert = "&"; break; + case '<': insert = "<"; break; + case '>': insert = ">"; break; + case 160: insert = " "; break; + default: { + if(c < 192) { + b[0] = c; + b[1] = '\0'; + insert = b; + } else { + insert = a2h[c - 192]; + } + } + }; + + /* Resize buffer */ + l = strlen(insert); + while(pos + l + 1 >= buflen) { + outline = realloc(outline, buflen *= 2); + if(outline == 0) { + fprintf(stderr, "error: memory exhausted\n"); + _exit(EXIT_FAILURE); + } + } + + /* Copy in */ + strcpy(&outline[pos], insert); + pos += l; + + ++inp; + } + + return outline; +} + +static void emit_cdindex_form(char *fname_baseval) +{ + FILE *cdindex_form; + char fname[200]; + char *pp; + + if (fname_baseval == NULL || fname_baseval[0] == 0) + return; + + strncpy(fname, fname_baseval, sizeof(fname) -1); + fname[sizeof(fname) -1] = 0; + pp = strrchr(fname, '.'); + if (pp == NULL) { + pp = fname + strlen(fname); + } + strncpy(pp, ".cdindex", sizeof(fname) - 1 - (pp - fname)); + + cdindex_form = fopen(fname, "w"); + if (cdindex_form == NULL) return; + +#define CDINDEX_URL "http://www.musicbrainz.org/dtd/CDInfo.dtd" + + /* format XML page according to cdindex DTD (see www.musicbrainz.org) */ + fprintf( cdindex_form, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<!DOCTYPE CDInfo SYSTEM \"%s\">\n\n<CDInfo>\n", + CDINDEX_URL); + + fprintf( cdindex_form, " <Title>%s</Title>\n", + global.disctitle ? ascii2html(global.disctitle) : ""); + /* + * In case of mixed mode and Extra-CD, nonaudio tracks are included! + */ + fprintf( cdindex_form, " <NumTracks>%d</NumTracks>\n\n", cdtracks); + fprintf( cdindex_form, " <IdInfo>\n <DiskId>\n <Id>%s</Id>\n </DiskId>\n", global.cdindex_id); + + fprintf( cdindex_form, " </IdInfo>\n\n"); + + if (IsSingleArtist()) { + static struct iterator i; + InitIterator(&i, 1); + + fprintf( cdindex_form, " <SingleArtistCD>\n <Artist>%s</Artist>\n", + global.creator ? ascii2html(global.creator) : ""); + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + int ii = GETTRACK(p); + + if (ii == CDROM_LEADOUT) break; + if (IS__AUDIO(p)) { + fprintf( cdindex_form, + " <Track Num=\"%d\">\n <Name>%s</Name>\n </Track>\n", + ii, global.tracktitle[ii] ? ascii2html(global.tracktitle[ii]) : ""); + } else { + fprintf( cdindex_form, + " <Track Num=\"%d\">\n <Name>data track</Name>\n </Track>\n", + ii ); + } + } + fprintf( cdindex_form, " </SingleArtistCD>\n"); + } else { + static struct iterator i; + InitIterator(&i, 1); + + fprintf( cdindex_form, " <MultipleArtistCD>\n"); + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + int ii = GETTRACK(p); + + if (ii == CDROM_LEADOUT) break; + if (IS__AUDIO(p)) { + fprintf( cdindex_form, " <Artist>%s</Artist>\n", + global.trackcreator[ii] ? ascii2html(global.trackcreator[ii]) : ""); + fprintf( cdindex_form, " <Name>%s</Name>\n </Track>\n", + global.tracktitle[ii] ? ascii2html(global.tracktitle[ii]) : ""); + } else { + fprintf( cdindex_form, + " <Artist>data track</Artist>\n <Name>data track</Name>\n </Track>\n"); + } + } + fprintf( cdindex_form, " </MultipleArtistCD>\n"); + } + fprintf( cdindex_form, "</CDInfo>\n"); + + fclose( cdindex_form ); +} +#endif + +static void dump_cdtext_info(void) +{ +#ifdef CD_TEXT + /* interpret the contents of CD Text information based on an early draft + of SCSI-3 mmc version 2 from jan 2, 1998 + CD Text information consists of a text group containing up to + 8 language blocks containing up to + 255 Pack data chunks of + 18 bytes each. + So we have at most 36720 bytes to cope with. + */ + { + short int datalength; + unsigned char *p = bufferTOC; + unsigned char lastline[255*12]; + int lastitem = -1; + int itemcount = 0; + int inlinecount = 0; + int outlinecount = 0; + + lastline[0] = '\0'; + datalength = ((p[0] << 8) + p[1]) - 2; + datalength = min(datalength, 2048-4); + p += 4; + for (;datalength > 0; + datalength -= sizeof (cdtextpackdata), + p += sizeof (cdtextpackdata)) { + unsigned char *zeroposition; + + /* handle one packet of CD Text Information Descriptor Pack Data */ + /* this is raw R-W subchannel data converted to 8 bit values. */ + cdtextpackdata *c = (cdtextpackdata *)p; + int dbcc; + int crc_error; + unsigned tracknr; + +#ifdef DEBUG_CDTEXT + fprintf(stderr, "datalength =%d\n", datalength); +#endif + crc_error = !cdtext_crc_ok(c); + + if (lastitem != c->headerfield[0]) { + itemcount = 0; + lastitem = c->headerfield[0]; + } + + tracknr = c->headerfield[1] & 0x7f; + dbcc = ((unsigned)(c->headerfield[3] & 0x80)) >> 7; /* double byte character code */ + +#if defined DEBUG_CDTEXT + { + int extension_flag; + int sequence_number; + int block_number; + int character_position; + + extension_flag = ((unsigned)(c->headerfield[1] & 0x80)) >> 7; + sequence_number = c->headerfield[2]; + block_number = ((unsigned)(c->headerfield[3] & 0x30)) >> 4; /* language */ + character_position = c->headerfield[3] & 0x0f; + + fprintf(stderr, "CDText: ext_fl=%d, trnr=%u, seq_nr=%d, dbcc=%d, block_nr=%d, char_pos=%d\n", + extension_flag, tracknr, sequence_number, dbcc, block_number, character_position); + } +#endif + + /* print ASCII information */ + memcpy(lastline+inlinecount, c->textdatafield, 12); + inlinecount += 12; + zeroposition = (unsigned char *)memchr(lastline+outlinecount, '\0', inlinecount-outlinecount); + while (zeroposition != NULL) { + process_header(c, tracknr, dbcc, lastline+outlinecount); + outlinecount += zeroposition - (lastline+outlinecount) + 1; + +#if defined DEBUG_CDTEXT + fprintf(stderr, "\tin=%d, out=%d, items=%d, trcknum=%u\n", inlinecount, outlinecount, itemcount, tracknr); +{ int q; for (q= outlinecount; q < inlinecount; q++) fprintf (stderr, "%c", lastline[q] ? lastline[q] : 'ß'); fputs("\n", stderr); } +#else + if (DETAILED) { + if (crc_error) fputs(" ! uncorr. CRC-Error", stderr); + fputs("\n", stderr); + } +#endif + + itemcount++; + if (itemcount > (int)cdtracks + || (c->headerfield[0] == 0x8f + || (c->headerfield[0] <= 0x8d && c->headerfield[0] >= 0x86))) { + outlinecount = inlinecount; + break; + } + tracknr++; + zeroposition = (unsigned char *)memchr(lastline+outlinecount, '\0', inlinecount-outlinecount); + } + } + } +#endif +} + + + +static void dump_extra_info(unsigned int from) +{ +#ifdef CD_EXTRA + unsigned char *p; + unsigned pos, length; + + if (from == 0) return; + + p = Extra_buffer + 48; + while (*p != '\0') { + pos = GET_BE_UINT_FROM_CHARP(p+2); + length = GET_BE_UINT_FROM_CHARP(p+6); + if (pos == (unsigned)-1) { + pos = from+1; + } else { + pos += session_start; + } + +#ifdef DEBUG_XTRA + if (global.gui == 0 && global.verbose != 0) { + fprintf(stderr, "Language: %c%c (as defined by ISO 639)", *p, *(p+1)); + fprintf(stderr, " at sector %u, len=%u (sessionstart=%u)", pos, length, session_start); + fputs("\n", stderr); + } +#endif + /* dump this entry */ + Read_Subinfo(pos, length); + p += 10; + + if (p + 9 > (Extra_buffer + CD_FRAMESIZE)) + break; + } +#endif +} + +static char *quote(unsigned char *string); + +static char *quote(unsigned char *string) +{ + static char result[200]; + unsigned char *p = (unsigned char *)result; + + while (*string) { + if (*string == '\'' || *string == '\\') { + *p++ = '\\'; + } + *p++ = *string++; + } + *p = '\0'; + + return result; +} + + + +static void DisplayToc_with_gui(unsigned long dw); + +static void DisplayToc_with_gui(unsigned long dw) +{ + unsigned mins; + unsigned secnds; + unsigned frames; + int count_audio_trks; + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + mins = dw / ( 60*75 ); + secnds = ( dw % ( 60*75 ) ) / 75; + frames = ( dw % 75 ); + + /* summary */ + count_audio_trks = 0; + + if ((global.verbose & SHOW_STARTPOSITIONS) != 0) { + if (global.illleadout_cd != 0 && have_CD_extra == 0) { + fprintf( stderr, "Tracks:%u > %u:%02u.%02u\n", cdtracks, mins, secnds, frames ); + } else { + fprintf( stderr, "Tracks:%u %u:%02u.%02u\n", cdtracks, mins, secnds, frames ); + } + } + + if (global.quiet == 0) { + fprintf( stderr, "CDINDEX discid: %s\n", global.cdindex_id); + fprintf( stderr, "CDDB discid: 0x%08lx", (unsigned long) global.cddb_id); + + if (have_CDDB != 0) { + fprintf(stderr, " CDDBP titles: resolved\n"); + } else { + fprintf(stderr, "\n"); + } + if (have_CD_text != 0) { + fprintf(stderr, "CD-Text: detected\n"); + dump_cdtext_info(); + } else { + fprintf(stderr, "CD-Text: not detected\n"); + } + if (have_CD_extra != 0) { + fprintf(stderr, "CD-Extra: detected\n"); + dump_extra_info(have_CD_extra); + } else { + fprintf(stderr, "CD-Extra: not detected\n"); + } + + fprintf( stderr, + "Album title: '%s'", (void *)global.disctitle != NULL + ? quote(global.disctitle) : ""); + + fprintf( stderr, " from '%s'\n", (void *)global.creator != NULL + ? quote(global.creator) : ""); + } + count_audio_trks = 0; + + + if ((global.verbose & (SHOW_TOC | SHOW_STARTPOSITIONS | SHOW_SUMMARY | SHOW_TITLES)) != 0 + && i.hasNextTrack(&i)) { + TOC *o = i.getNextTrack(&i); + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + int from; + from = GETTRACK(o); + + fprintf(stderr, "T%02d:", from); + + if (IS__DATA(o)) { + /* + * Special case of cd extra + */ + unsigned int real_start = have_CD_extra + ? have_CD_extra : GETSTART(o); + + + dw = (unsigned long) (GETSTART(p) - real_start); + + mins = dw / ( 60*75 ); + secnds = ( dw % ( 60*75 )) / 75; + frames = ( dw % 75 ); + + if ( global.verbose & SHOW_STARTPOSITIONS ) + fprintf(stderr, + " %7u", + real_start + ); + + if ( global.verbose & SHOW_TOC ) + fprintf(stderr, + " %2u:%02u.%02u", + mins, secnds, frames + ); + + if ( global.verbose & SHOW_SUMMARY ) + fprintf(stderr, + " data %s %s N/A", + + /* how recorded */ + IS__INCREMENTAL(o) + ? "incremental" : "uninterrupted", + + /* copy-permission */ + IS__COPYRIGHTED(o) + ? "copydenied" : "copyallowed" + ); + fputs("\n", stderr); + } else { + dw = (unsigned long) (GETSTART(p) - GETSTART(o)); + mins = dw / ( 60*75 ); + secnds = ( dw % ( 60*75 )) / 75; + frames = ( dw % 75 ); + + if ( global.verbose & SHOW_STARTPOSITIONS ) + fprintf(stderr, + " %7u", + GETSTART(o) + ); + + if ( global.verbose & SHOW_TOC ) + fprintf(stderr, + " %2u:%02u.%02u", + mins, secnds, frames + ); + + if ( global.verbose & SHOW_SUMMARY ) + fprintf(stderr, + " audio %s %s %s", + + /* how recorded */ + IS__PREEMPHASIZED(o) + ? "pre-emphasized" : "linear", + + /* copy-permission */ + IS__COPYRIGHTED(o) + ? "copydenied" : "copyallowed", + + /* channels */ + IS__QUADRO(o) + ? "quadro" : "stereo"); + + /* Title */ + if ( global.verbose & SHOW_TITLES ) { + fprintf(stderr, + " title '%s' from ", + + (void *) global.tracktitle[GETTRACK(o)] != NULL + ? quote(global.tracktitle[GETTRACK(o)]) : "" + ); + + fprintf(stderr, + "'%s'", + + (void *) global.trackcreator[GETTRACK(o)] != NULL + ? quote(global.trackcreator[GETTRACK(o)]) : "" + ); + } + fputs("\n", stderr); + count_audio_trks++; + } + o = p; + } /* while */ + if ( global.verbose & SHOW_STARTPOSITIONS ) + if (GETTRACK(o) == CDROM_LEADOUT) { + fprintf(stderr, "Leadout: %7u\n", GETSTART(o)); + } + } /* if */ +} + +static void DisplayToc_no_gui(unsigned long dw); + +static void DisplayToc_no_gui(unsigned long dw) +{ + unsigned mins; + unsigned secnds; + unsigned frames; + int count_audio_trks; + unsigned ii = 0; + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + mins = dw / ( 60*75 ); + secnds = ( dw % ( 60*75 ) ) / 75; + frames = ( dw % 75 ); + + /* summary */ + count_audio_trks = 0; + + if (i.hasNextTrack(&i)) { + TOC *o = i.getNextTrack(&i); + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + int from; + from = GETTRACK(o); + + + while ( p != NULL && GETTRACK(p) != CDROM_LEADOUT + && GETFLAGS(o) == GETFLAGS(p) ) { + o = p; + p = i.getNextTrack(&i); + } + if ((global.verbose & SHOW_SUMMARY) == 0) continue; + + if (IS__DATA(o)) { + fputs( " DATAtrack recorded copy-permitted tracktype\n" , stderr); + fprintf(stderr, + " %2d-%2d %13.13s %14.14s data\n", + from, + GETTRACK(o), + /* how recorded */ + IS__INCREMENTAL(o) + ? "incremental" : "uninterrupted", + + /* copy-perm */ + IS__COPYRIGHTED(o) ? "no" : "yes" + ); + } else { + fputs( "AUDIOtrack pre-emphasis copy-permitted tracktype channels\n" , stderr); + fprintf(stderr, + " %2d-%2d %12.12s %14.14s audio %1c\n", + from, + GETTRACK(o), + IS__PREEMPHASIZED(o) + ? "yes" : "no", + IS__COPYRIGHTED(o) ? "no" : "yes", + IS__QUADRO(o) ? '4' : '2' + ); + count_audio_trks++; + } + o = p; + } + } + if ((global.verbose & SHOW_STARTPOSITIONS) != 0) { + if (global.illleadout_cd != 0 && have_multisession == 0) { + + fprintf ( stderr, + "Table of Contents: total tracks:%u, (total time more than %u:%02u.%02u)\n", + cdtracks, mins, secnds, frames ); + } else { + fprintf ( stderr, + "Table of Contents: total tracks:%u, (total time %u:%02u.%02u)\n", + cdtracks, mins, secnds, frames ); + } + } + + i.reset(&i); + if ((global.verbose & SHOW_TOC) != 0 && + i.hasNextTrack(&i)) { + TOC *o = i.getNextTrack(&i); + + for (; i.hasNextTrack(&i);) { + TOC *p = i.getNextTrack(&i); + + if ( GETTRACK(o) <= MAXTRK ) { + unsigned char brace1, brace2; + unsigned trackbeg; + trackbeg = have_multisession && IS__DATA(o) ? have_multisession : GETSTART(o); + + dw = (unsigned long) (GETSTART(p) - trackbeg); + mins = dw / ( 60*75 ); + secnds = ( dw % ( 60*75 )) / 75; + frames = ( dw % 75 ); + + if ( IS__DATA(o) ) { + /* data track display */ + brace1 = '['; + brace2 = ']'; + } else if (have_multisession + && GETTRACK(o) == LastAudioTrack()) { + /* corrected length of + * last audio track in cd extra + */ + brace1 = '|'; + brace2 = '|'; + } else { + /* audio track display */ + brace1 = '('; + brace2 = ')'; + } + fprintf ( stderr, + " %2u.%c%2u:%02u.%02u%c", + GETTRACK(o), + brace1, + mins, secnds, frames, + brace2 + ); + ii++; + + if ( ii % 5 == 0 ) + fputs( ",\n", stderr ); + else if (ii != cdtracks) + fputc ( ',', stderr ); + } + o = p; + } /* for */ + if ( (ii % 5) != 0 ) + fputs( "\n", stderr ); + + } /* if */ + + if ((global.verbose & SHOW_STARTPOSITIONS) != 0) { + fputs ("\nTable of Contents: starting sectors\n", stderr); + + ii = 0; + i.reset(&i); + if (i.hasNextTrack(&i)) { + TOC *o = i.getNextTrack(&i); + for ( ; i.hasNextTrack(&i);) { + TOC *p = i.getNextTrack(&i); + fprintf ( stderr, + " %2u.(%8u)", + GETTRACK(o), + have_multisession + && GETTRACK(o) == FirstDataTrack() + ? have_multisession + : GETSTART(o) +#ifdef DEBUG_CDDB + +150 +#endif + ); + + ii++; + if ( (ii) % 5 == 0 ) + fputs( ",\n", stderr ); + else + fputc ( ',', stderr ); + o = p; + } + fprintf ( stderr, " lead-out(%8u)", GETSTART(o)); + fputs ("\n", stderr); + } + } + if (global.quiet == 0) { + fprintf(stderr, "CDINDEX discid: %s\n", global.cdindex_id); + fprintf( stderr, "CDDB discid: 0x%08lx", (unsigned long) global.cddb_id); + + if (have_CDDB != 0) { + fprintf(stderr, " CDDBP titles: resolved\n"); + } else { + fprintf(stderr, "\n"); + } + if (have_CD_text != 0) { + fprintf(stderr, "CD-Text: detected\n"); + } else { + fprintf(stderr, "CD-Text: not detected\n"); + } + if (have_CD_extra != 0) { + fprintf(stderr, "CD-Extra: detected\n"); + } else { + fprintf(stderr, "CD-Extra: not detected\n"); + } + } + if ((global.verbose & SHOW_TITLES) != 0) { + int maxlen = 0; + + if ( global.disctitle != NULL ) { + fprintf( stderr, "Album title: '%s'", global.disctitle); + if ( global.creator != NULL ) { + fprintf( stderr, "\t[from %s]", global.creator); + } + fputs("\n", stderr); + } + + i.reset(&i); + for ( ; i.hasNextTrack(&i);) { + TOC *p = i.getNextTrack(&i); + int jj = GETTRACK(p); + + if ( global.tracktitle[jj] != NULL ) { + int len = strlen((char *)global.tracktitle[jj]); + maxlen = max(maxlen, len); + } + } + maxlen = (maxlen + 12 + 8 + 7)/8; + + i.reset(&i); + for ( ; i.hasNextTrack(&i); ) { + TOC *p = i.getNextTrack(&i); + int jj; + + if (IS__DATA(p)) + continue; + + jj = GETTRACK(p); + + if (jj == CDROM_LEADOUT) + break; + + if ( maxlen != 3 ) { + if ( global.tracktitle[jj] != NULL ) { + fprintf( stderr, "Track %2u: '%s'", jj, global.tracktitle[jj]); + } else { + fprintf( stderr, "Track %2u: '%s'", jj, ""); + } + if ( global.trackcreator[jj] != NULL + && global.trackcreator[jj][0] != '\0' +#if 1 + && (global.creator == NULL + || 0 != strcmp((char *)global.creator,(char *)global.trackcreator[jj])) +#endif + ) { + int j; + char *o = global.tracktitle[jj] != NULL + ? (char *)global.tracktitle[jj] + : ""; + for ( j = 0; + j < (maxlen - ((int)strlen(o) + 12)/8); + j++) + fprintf(stderr, "\t"); + fprintf( stderr, "[from %s]", global.trackcreator[jj]); + } + fputs("\n", stderr); + } + } + } +} + +void DisplayToc(void) +{ + unsigned long dw; + + /* special handling of pseudo-red-book-audio cds */ + if (cdtracks > 1 + && Get_StartSector(CDROM_LEADOUT) < Get_StartSector(cdtracks)) { + global.illleadout_cd = 1; + can_read_illleadout(); + } + + + /* get total time */ + if (global.illleadout_cd == 0) + dw = (unsigned long) Get_StartSector(CDROM_LEADOUT) - Get_StartSector(1); + else + dw = (unsigned long) Get_StartSector(cdtracks ) - Get_StartSector(1); + + if ( global.gui == 0 ) { + /* table formatting when in cmdline mode */ + DisplayToc_no_gui( dw ); + } else if (global.gui == 1) { + /* line formatting when in gui mode */ + DisplayToc_with_gui( dw ); + } + + if (global.illleadout_cd != 0) { + if (global.quiet == 0) { + fprintf(stderr, "CD with illegal leadout position detected!\n"); + } + + if (global.reads_illleadout == 0) { + /* limit accessible tracks + * to lowered leadout position + */ + restrict_tracks_illleadout(); + + if (global.quiet == 0) { + fprintf(stderr, + "The cdrom drive firmware does not permit access beyond the leadout position!\n"); + } + if (global.verbose & (SHOW_ISRC | SHOW_INDICES)) { + global.verbose &= ~(SHOW_ISRC | SHOW_INDICES); + fprintf(stderr, "Switching index scan and ISRC scan off!\n"); + } + + if (global.quiet == 0) { + fprintf(stderr, + "Audio extraction will be limited to track %ld with maximal %ld sectors...\n", + LastTrack(), + Get_EndSector(LastTrack())+1 + ); + } + } else { + /* The cdrom drive can read beyond the + * indicated leadout. We patch a new leadout + * position to the maximum: + * 99 minutes, 59 seconds, 74 frames + */ + patch_real_end(150 + (99*60+59)*75 + 74); + if (global.quiet == 0) { + fprintf(stderr, + "Restrictions apply, since the size of the last track is unknown!\n"); + } + } + } +} + +static void Read_MCN_toshiba(subq_chnl **sub_ch); + +static void Read_MCN_toshiba(subq_chnl **sub_ch) +{ + if (Toshiba3401() != 0 && global.quiet == 0 + && ((*sub_ch) != 0 + || (((subq_catalog *)(*sub_ch)->data)->mc_valid & 0x80))) { + /* no valid MCN yet. do more searching */ + long h = Get_AudioStartSector(1); + + while (h <= Get_AudioStartSector(1) + 100) { + if (Toshiba3401()) + ReadCdRom(get_scsi_p(), RB_BASE->data, h, global.nsectors); + (*sub_ch) = ReadSubQ(get_scsi_p(), GET_CATALOGNUMBER,0); + if ((*sub_ch) != NULL) { + subq_catalog *subq_cat; + + subq_cat = (subq_catalog *) (*sub_ch)->data; + if ((subq_cat->mc_valid & 0x80) != 0) { + break; + } + } + h += global.nsectors; + } + } +} + +static void Get_Set_MCN(void); + +static void Get_Set_MCN(void) +{ + subq_chnl *sub_ch; + subq_catalog *subq_cat = NULL; + fprintf(stderr, "scanning for MCN..."); + + sub_ch = ReadSubQ(get_scsi_p(), GET_CATALOGNUMBER,0); + +#define EXPLICIT_READ_MCN_ISRC 1 +#if EXPLICIT_READ_MCN_ISRC == 1 /* TOSHIBA HACK */ + Read_MCN_toshiba( &sub_ch ); +#endif + + if (sub_ch != NULL) + subq_cat = (subq_catalog *)sub_ch->data; + + if (sub_ch != NULL + && (subq_cat->mc_valid & 0x80) != 0 + && global.quiet == 0) { + + /* unified format guesser: + * format MCN all digits in bcd + * 1 13 + * A: ab cd ef gh ij kl m0 0 0 0 0 0 0 Plextor 6x Rel. 1.02 + * B: 0a 0b 0c 0d 0e 0f 0g 0h 0i 0j 0k 0l 0m Toshiba 3401 + * C: AS AS AS AS AS AS AS AS AS AS AS AS AS ASCII SCSI-2 Plextor 4.5x and 6x Rel. 1.06 + */ + unsigned char *cp = subq_cat->media_catalog_number; + if (!(cp[8] | cp[9] | cp[10] | cp[11] | cp[12]) + && ((cp[0] & 0xf0) | (cp[1] & 0xf0) + | (cp[2] & 0xf0) | (cp[3] & 0xf0) + | (cp[4] & 0xf0) | (cp[5] & 0xf0) + | (cp[6] & 0xf0))) { + /* reformat A: to B: */ + cp[12] = cp[6] >> 4; cp[11] = cp[5] & 0xf; + cp[10] = cp[5] >> 4; cp[ 9] = cp[4] & 0xf; + cp[ 8] = cp[4] >> 4; cp[ 7] = cp[3] & 0xf; + cp[ 6] = cp[3] >> 4; cp[ 5] = cp[2] & 0xf; + cp[ 4] = cp[2] >> 4; cp[ 3] = cp[1] & 0xf; + cp[ 2] = cp[1] >> 4; cp[ 1] = cp[0] & 0xf; + cp[ 0] = cp[0] >> 4; + } + + if (!isdigit(cp[0]) + && (memcmp(subq_cat->media_catalog_number, + "\0\0\0\0\0\0\0\0\0\0\0\0\0", 13) != 0)) { + sprintf((char *) + subq_cat->media_catalog_number, + "%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X%1.1X", + subq_cat->media_catalog_number [0], + subq_cat->media_catalog_number [1], + subq_cat->media_catalog_number [2], + subq_cat->media_catalog_number [3], + subq_cat->media_catalog_number [4], + subq_cat->media_catalog_number [5], + subq_cat->media_catalog_number [6], + subq_cat->media_catalog_number [7], + subq_cat->media_catalog_number [8], + subq_cat->media_catalog_number [9], + subq_cat->media_catalog_number [10], + subq_cat->media_catalog_number [11], + subq_cat->media_catalog_number [12] + ); + } + + if (memcmp(subq_cat->media_catalog_number,"0000000000000",13) + != 0) { + Set_MCN(subq_cat->media_catalog_number); + } + } +} + + +static void Read_ISRC_toshiba(subq_chnl **sub_ch, unsigned tr); + +static void Read_ISRC_toshiba(subq_chnl **sub_ch, unsigned tr) +{ + if (Toshiba3401() != 0) { + int j; + j = (Get_AudioStartSector(tr)/100 + 1) * 100; + do { + ReadCdRom(get_scsi_p(), RB_BASE->data, j, global.nsectors); + *sub_ch = ReadSubQ(get_scsi_p(), GET_TRACK_ISRC, Get_Tracknumber(tr)); + if (*sub_ch != NULL) { + subq_track_isrc * subq_tr; + + subq_tr = (subq_track_isrc *) (*sub_ch)->data; + if (subq_tr != NULL && (subq_tr->tc_valid & 0x80) != 0) + break; + } + j += global.nsectors; + } while (j < (Get_AudioStartSector(tr)/100 + 1) * 100 + 100); + } +} + + +static void Get_Set_ISRC(unsigned tr); + +static void Get_Set_ISRC(unsigned tr) +{ + subq_chnl *sub_ch; + subq_track_isrc * subq_tr; + + fprintf(stderr, "\rscanning for ISRCs: %d ...", tr); + + subq_tr = NULL; + sub_ch = ReadSubQ(get_scsi_p(), GET_TRACK_ISRC, tr); + +#if EXPLICIT_READ_MCN_ISRC == 1 /* TOSHIBA HACK */ + Read_ISRC_toshiba( &sub_ch, tr ); +#endif + + if (sub_ch != NULL) + subq_tr = (subq_track_isrc *)sub_ch->data; + + if (sub_ch != NULL && (subq_tr->tc_valid & 0x80) + && global.quiet == 0) { + unsigned char p_start[16]; + unsigned char *p = p_start; + unsigned char *cp = subq_tr->track_isrc; + + /* unified format guesser: + * there are 60 bits and 15 bytes available. + * 5 * 6bit-items + two zero fill bits + 7 * 4bit-items + * + * A: ab cd ef gh ij kl mn o0 0 0 0 0 0 0 0 Plextor 6x Rel. 1.02 + * B: 0a 0b 0c 0d 0e 0f 0g 0h 0i 0j 0k 0l 0m 0n 0o Toshiba 3401 + * C: AS AS AS AS AS AS AS AS AS AS AS AS AS AS AS ASCII SCSI-2 + * eg 'G''B''-''A''0''7''-''6''8''-''0''0''2''7''0' makes most sense + * D: 'G''B''A''0''7''6''8''0''0''2''7''0'0 0 0 Plextor 6x Rel. 1.06 and 4.5x R. 1.01 and 1.04 + */ + + /* Check for format A: */ + if (!(cp[8] | cp[9] | cp[10] | cp[11] | cp[12] | cp[13] | cp[14]) && + ((cp[0] & 0xf0) | (cp[1] & 0xf0) | (cp[2] & 0xf0) | + (cp[3] & 0xf0) | (cp[4] & 0xf0) | (cp[5] & 0xf0) | + (cp[6] & 0xf0) | (cp[7] & 0xf0))) { +#if DEBUG_ISRC + fprintf(stderr, "a!\t"); +#endif + /* reformat A: to B: */ + cp[14] = cp[7] >> 4; cp[13] = cp[6] & 0xf; + cp[12] = cp[6] >> 4; cp[11] = cp[5] & 0xf; + cp[10] = cp[5] >> 4; cp[ 9] = cp[4] & 0xf; + cp[ 8] = cp[4] >> 4; cp[ 7] = cp[3] & 0xf; + cp[ 6] = cp[3] >> 4; cp[ 5] = cp[2] & 0xf; + cp[ 4] = cp[2] >> 4; cp[ 3] = cp[1] & 0xf; + cp[ 2] = cp[1] >> 4; cp[ 1] = cp[0] & 0xf; + cp[ 0] = cp[0] >> 4; +#if DEBUG_ISRC + fprintf(stderr, "a->b: %15.15s\n", cp); +#endif + } + + /* Check for format B: + * If not yet in ASCII format, do the conversion + */ + if (cp[0] < '0' && cp[1] < '0') { + /* coding table for International Standard Recording Code */ + static char bin2ISRC[] = { + '0','1','2','3','4','5','6','7','8','9', /* 10 */ + ':',';','<','=','>','?','@', /* 17 */ + 'A','B','C','D','E','F','G','H','I','J','K', /* 28 */ + 'L','M','N','O','P','Q','R','S','T','U','V', /* 39 */ + 'W','X','Y','Z', /* 43 */ +#if 1 + '[','\\',']','^','_','`', /* 49 */ + 'a','b','c','d','e','f','g','h','i','j','k', /* 60 */ + 'l','m','n','o' /* 64 */ +#endif + }; + + /* build 6-bit vector of coded values */ + unsigned ind; + int bits; + +#if DEBUG_ISRC + fprintf(stderr, "b!\n"); +#endif + ind = (cp[0] << 26) + + (cp[1] << 22) + + (cp[2] << 18) + + (cp[3] << 14) + + (cp[4] << 10) + + (cp[5] << 6) + + (cp[6] << 2) + + (cp[7] >> 2); + + if ((cp[7] & 3) == 3) { + if (global.verbose) { + fprintf(stderr, + "Recorder-ID encountered: "); + for (bits = 0; bits < 30; bits +=6) { + unsigned binval = (ind & (ULONG_C(0x3f) << (24-bits))) + >> (24-bits); + if ((binval < sizeof(bin2ISRC)) && + (binval <= 9 || binval >= 16)) { + fprintf(stderr, "%X", bin2ISRC[binval]); + } + } + + fprintf(stderr, "%.1X%.1X%.1X%.1X%.1X%.1X%.1X", + subq_tr->track_isrc [8] & 0x0f, + subq_tr->track_isrc [9] & 0x0f, + subq_tr->track_isrc [10] & 0x0f, + subq_tr->track_isrc [11] & 0x0f, + subq_tr->track_isrc [12] & 0x0f, + subq_tr->track_isrc [13] & 0x0f, + subq_tr->track_isrc [14] & 0x0f + ); + fprintf(stderr, "\n"); + } + return; + } + if ((cp[7] & 3) != 0) { + fprintf(stderr, "unknown mode 3 entry C1=0x%02x, C2=0x%02x\n", + (cp[7] >> 1) & 1, cp[7] & 1); + return; + } + + /* decode ISRC due to IEC 908 */ + for (bits = 0; bits < 30; bits +=6) { + unsigned binval = (ind & ((unsigned long) 0x3fL << (24L-bits))) >> (24L-bits); + if ((binval >= sizeof(bin2ISRC)) || + (binval > 9 && binval < 16)) { + /* Illegal ISRC, dump and skip */ + int y; + + Get_ISRC(tr)[0] = '\0'; + fprintf(stderr, "\nIllegal ISRC for track %d, skipped: ", tr); + for (y = 0; y < 15; y++) { + fprintf(stderr, "%02x ", cp[y]); + } + fputs("\n", stderr); + return; + } + *p++ = bin2ISRC[binval]; + + /* insert a dash after two country characters for legibility */ + if (bits == 6) + *p++ = '-'; + } + + /* format year and serial number */ + sprintf ((char *)p, "-%.1X%.1X-%.1X%.1X%.1X%.1X%.1X", + subq_tr->track_isrc [8] & 0x0f, + subq_tr->track_isrc [9] & 0x0f, + subq_tr->track_isrc [10] & 0x0f, + subq_tr->track_isrc [11] & 0x0f, + subq_tr->track_isrc [12] & 0x0f, + subq_tr->track_isrc [13] & 0x0f, + subq_tr->track_isrc [14] & 0x0f + ); +#if DEBUG_ISRC + fprintf(stderr, "b: %15.15s!\n", p_start); +#endif + } else { + /* It might be in ASCII, surprise */ + int ii; + for (ii = 0; ii < 12; ii++) { + if (cp[ii] < '0' || cp[ii] > 'Z') { + break; + } + } + if (ii != 12) { + int y; + + Get_ISRC(ii)[0] = '\0'; + fprintf(stderr, "\nIllegal ISRC for track %d, skipped: ", ii+1); + for (y = 0; y < 15; y++) { + fprintf(stderr, "%02x ", cp[y]); + } + fputs("\n", stderr); + return; + } + +#if DEBUG_ISRC + fprintf(stderr, "ascii: %15.15s!\n", cp); +#endif + for (ii = 0; ii < 12; ii++) { +#if 1 + if ((ii == 2 || ii == 5 || ii == 7) && cp[ii] != ' ') + *p++ = '-'; +#endif + *p++ = cp[ii]; + } + if (p - p_start >= 16) + *(p_start + 15) = '\0'; + else + *p = '\0'; + } + + if (memcmp(p_start,"00-000-00-00000",15) != 0) { + Set_ISRC(tr, p_start); + } + } +} + +/* get and display Media Catalog Number ( one per disc ) + * and Track International Standard Recording Codes (for each track) + */ +void Read_MCN_ISRC(void) +{ + if ((global.verbose & SHOW_MCN) != 0) { + + if (Get_MCN()[0] == '\0') { + Get_Set_MCN(); + } + + if (Get_MCN()[0] != '\0') + fprintf(stderr, "\rMedia catalog number: %13.13s\n", Get_MCN()); + else + fprintf(stderr, "\rNo media catalog number present.\n"); + } + + + + if ((global.verbose & SHOW_ISRC) != 0) { + static struct iterator i; + + InitIterator(&i, 1); + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + unsigned ii = GETTRACK(p); + + if (ii == CDROM_LEADOUT) break; + + if (!IS__AUDIO(p)) + continue; + + if (GETISRC(p)[0] == '\0') { + Get_Set_ISRC(ii); + } + + if (GETISRC(p)[0] != '\0') { + fprintf (stderr, "\rT: %2d ISRC: %15.15s\n", ii, GETISRC(p)); + fflush(stderr); + } + } /* for all tracks */ + + fputs("\n", stderr); + } /* if SHOW_ISRC */ +} + +static int playing = 0; + +static subq_chnl *ReadSubChannel(unsigned sec); + +static subq_chnl *ReadSubChannel(unsigned sec) +{ + subq_chnl *sub_ch; + + /* + * For modern drives implement a direct method. If the drive supports + * reading of subchannel data, do direct reads. + */ + if (ReadSubChannels != NULL) { + get_scsi_p()->silent++; + sub_ch = ReadSubChannels(get_scsi_p(), sec); + get_scsi_p()->silent--; + if (sub_ch == NULL /*&& (usal_sense_key(get_scsi_p()) == 5)*/) { + /* command is not implemented */ + ReadSubChannels = NULL; +#if defined DEBUG_SUB +fprintf(stderr, "\nCommand not implemented: switching ReadSubChannels off !\n"); +#endif + goto fallback; + } + + /* check the adress mode field */ + if ((sub_ch->control_adr & 0x0f) == 0) { + /* no Q mode information present at all, weird */ + sub_ch->control_adr = 0xAA; + } + + if ((int)(sub_ch->control_adr & 0x0f) > 0x01) { + /* this sector just has no position information. + * we try the one before and then the one after. + */ + if (sec > 1) { + sec -= 1; + sub_ch = ReadSubChannels(get_scsi_p(), sec); + if (sub_ch == NULL) return NULL; + sec += 1; + } + if ((sub_ch->control_adr & 0x0f) != 0x01) { + sec += 2; + sub_ch = ReadSubChannels(get_scsi_p(), sec); + if (sub_ch == NULL) return NULL; + sec -= 2; + } + } + + /* check adress mode field for position information */ + if ((sub_ch->control_adr & 0x0f) == 0x01) { + return sub_ch; + } + ReadSubChannels = NULL; +fprintf(stderr, "\nCould not get position information (%02x) for sectors %d, %d, %d: switching ReadSubChannels off !\n", sub_ch->control_adr &0x0f, sec-1, sec, sec+2); + } + + /* + * We rely on audio sectors here!!! + * The only method that worked even with my antique Toshiba 3401, + * is playing the sector and then request the subchannel afterwards. + */ +fallback: + /* We need a conformed audio track here! */ + + /* Fallback to ancient method */ + if (-1 == Play_at(get_scsi_p(), sec, 1)) { + return NULL; + } + playing = 1; + sub_ch = ReadSubQ(get_scsi_p(), GET_POSITIONDATA,0); + return sub_ch; +} + +static int ReadSubControl(unsigned sec); +static int ReadSubControl(unsigned sec) +{ + subq_chnl *sub_ch = ReadSubChannel(sec); + if (sub_ch == NULL) return -1; + + return sub_ch->control_adr & 0xf0; +} + +static int HaveSCMS(unsigned StartSector); +static int HaveSCMS(unsigned StartSector) +{ + int i; + int cr; + int copy_bits_set = 0; + + for (i = 0; i < 8; i++) { + cr = ReadSubControl(StartSector + i); + if (cr == -1) continue; + (cr & 0x20) ? copy_bits_set++ : 0; + } + return (copy_bits_set >= 1 && copy_bits_set < 8); +} + +void Check_Toc(void) +{ + /* detect layout */ + + /* detect tracks */ +} + +static int GetIndexOfSector(unsigned sec, unsigned track) +{ + subq_chnl *sub_ch = ReadSubChannel(sec); + if (sub_ch == NULL) { + if ((long)sec == Get_EndSector(track)) { + fprintf(stderr, "Driver and/or firmware bug detected! Drive cannot play the very last sector (%u)!\n", sec); + } + return -1; + } + + /* can we trust that these values are hex and NOT bcd? */ + if ((sub_ch->track >= 0x10) && (sub_ch->track - track > 5)) { + /* change all values from bcd to hex */ + sub_ch->track = (sub_ch->track >> 4)*10 + (sub_ch->track & 0x0f); + sub_ch->index = (sub_ch->index >> 4)*10 + (sub_ch->index & 0x0f); + } + +#if 1 + /* compare tracks */ + if (sub_ch->index != 0 && track != sub_ch->track) { + if (global.verbose) fprintf(stderr, "\ntrack mismatch: %1d, in-track subchannel: %1d (index %1d, sector %1d)\n", + track, sub_ch->track, sub_ch->index, sec); + } +#endif + + /* compare control field with the one from the TOC */ + if ((Get_Flags(track) & 0xf0) != (sub_ch->control_adr & 0xf0)) { + int diffbits = (Get_Flags(track) & 0xf0) ^ (sub_ch->control_adr & 0xf0); + if ((diffbits & 0x80) == 0x80) { + /* broadcast difference */ + if (global.verbose) fprintf(stderr, "broadcast type conflict detected -> TOC:%s, subchannel:%s\n", + (sub_ch->control_adr & 0x80) == 0 ? "broadcast" : "nonbroadcast" + ,(sub_ch->control_adr & 0x80) != 0 ? "broadcast" : "nonbroadcast" + ); + } + if ((diffbits & 0x40) == 0x40) { + /* track type difference */ + if (global.verbose) fprintf(stderr, "track type conflict detected -> TOC:%s, subchannel:%s\n", + (sub_ch->control_adr & 0x40) == 0 ? "data" : "audio" + ,(sub_ch->control_adr & 0x40) != 0 ? "data" : "audio" + ); + } + if ((diffbits & 0x20) == 0x20 && !Get_SCMS(track)) { + /* copy permission difference is a sign for SCMS + * and is treated elsewhere. */ + if (global.verbose) fprintf(stderr, "difference: TOC:%s, subchannel:%s\ncorrecting TOC...\n", + (sub_ch->control_adr & 0x20) == 0 ? "unprotected" : "copyright protected", + (sub_ch->control_adr & 0x20) != 0 ? "unprotected" : "copyright protected" + ); + toc_entry(track, + (Get_Flags(track) & 0xDF) | (sub_ch->control_adr & 0x20), + Get_Tracknumber(track), + Get_ISRC(track), + Get_AudioStartSector(track), + Get_Mins(track), + Get_Secs(track), + Get_Frames(track) + ); + } + if ((diffbits & 0x10) == 0x10) { + /* preemphasis difference */ + if (global.verbose) fprintf(stderr, "difference: TOC:%s, subchannel:%s preemphasis\ncorrecting TOC...\n", + (sub_ch->control_adr & 0x10) == 0 ? "with" : "without", + (sub_ch->control_adr & 0x10) != 0 ? "with" : "without" + ); + toc_entry(track, + (Get_Flags(track) & 0xEF) | (sub_ch->control_adr & 0x10), + Get_Tracknumber(track), + Get_ISRC(track), + Get_AudioStartSector(track), + Get_Mins(track), + Get_Secs(track), + Get_Frames(track) + ); + } + + } + + return sub_ch ? sub_ch->index == 244 ? 1 : sub_ch->index : -1; +} + +static int ScanBackwardFrom(unsigned sec, unsigned limit, int *where, + unsigned track); + +static int ScanBackwardFrom(unsigned sec, unsigned limit, int *where, + unsigned track) +{ + unsigned lastindex = 0; + unsigned mysec = sec; + + /* try to find the transition of index n to index 0, + * if the track ends with an index 0. + */ + while ((lastindex = GetIndexOfSector(mysec, track)) == 0) { + if (mysec < limit+75) { + break; + } + mysec -= 75; + } + if (mysec == sec) { + /* there is no pre-gap in this track */ + if (where != NULL) *where = -1; + } else { + /* we have a pre-gap in this track */ + + if (lastindex == 0) { + /* we did not cross the transition yet -> search backward */ + do { + if (mysec < limit+1) { + break; + } + mysec --; + } while ((lastindex = GetIndexOfSector(mysec,track)) == 0); + if (lastindex != 0) { + /* successful */ + mysec ++; + /* register mysec as transition */ + if (where != NULL) *where = (int) mysec; + } else { + /* could not find transition */ + if (!global.quiet) + fprintf(stderr, + "Could not find index transition for pre-gap.\n"); + if (where != NULL) *where = -1; + } + } else { + int myindex = -1; + /* we have crossed the transition -> search forward */ + do { + if (mysec >= sec) { + break; + } + mysec ++; + } while ((myindex = GetIndexOfSector(mysec,track)) != 0); + if (myindex == 0) { + /* successful */ + /* register mysec as transition */ + if (where != NULL) *where = (int) mysec; + } else { + /* could not find transition */ + if (!global.quiet) + fprintf(stderr, + "Could not find index transition for pre-gap.\n"); + if (where != NULL) *where = -1; + } + } + } + return lastindex; +} + +#ifdef USE_LINEAR_SEARCH +static int linear_search(int searchInd, unsigned int Start, unsigned int End, + unsigned track); + +static int linear_search(int searchInd, unsigned int Start, unsigned int End, + unsigned track) +{ + int l = Start; + int r = End; + + for (; l <= r; l++ ) { + int ind; + + ind = GetIndexOfSector(l, track); + if ( searchInd == ind ) { + break; + } + } + if ( l <= r ) { + /* Index found. */ + return l; + } + + return -1; +} +#endif + +#ifndef USE_LINEAR_SEARCH +#undef DEBUG_BINSEARCH +static int binary_search(int searchInd, unsigned int Start, unsigned int End, + unsigned track); + +static int binary_search(int searchInd, unsigned Start, unsigned End, + unsigned track) +{ + int l = Start; + int r = End; + int x = 0; + int ind; + + while ( l <= r ) { + x = ( l + r ) / 2; + /* try to avoid seeking */ + ind = GetIndexOfSector(x, track); + if ( searchInd == ind ) { + break; + } else { + if ( searchInd < ind ) r = x - 1; + else l = x + 1; + } + } +#ifdef DEBUG_BINSEARCH +fprintf(stderr, "(%d,%d,%d > ",l,x,r); +#endif + if ( l <= r ) { + /* Index found. Now find the first position of this index */ + /* l=LastPos x=found r=NextPos */ + r = x; + while ( l < r-1 ) { + x = ( l + r ) / 2; + /* try to avoid seeking */ + ind = GetIndexOfSector(x, track); + if ( searchInd == ind ) { + r = x; + } else { + l = x; + } +#ifdef DEBUG_BINSEARCH +fprintf(stderr, "%d -> ",x); +#endif + } +#ifdef DEBUG_BINSEARCH +fprintf(stderr, "%d,%d)\n",l,r); +#endif + if (searchInd == GetIndexOfSector(l, track)) + return l; + else + return r; + } + + return -1; +} +#endif + + +static void register_index_position(int IndexOffset, + index_list **last_index_entry); + +static void register_index_position(int IndexOffset, + index_list **last_index_entry) +{ + index_list *indexentry; + + /* register higher index entries */ + if (*last_index_entry != NULL) { + indexentry = (index_list *) malloc( sizeof(index_list) ); + } else { + indexentry = NULL; + } + if (indexentry != NULL) { + indexentry->next = NULL; + (*last_index_entry)->next = indexentry; + *last_index_entry = indexentry; + indexentry->frameoffset = IndexOffset; +#if defined INFOFILES + } else { + fprintf( stderr, "No memory for index lists. Index positions\nwill not be written in info file!\n"); +#endif + } +} + +static void Set_SCMS(unsigned long p_track); + +#undef DEBUG_INDLIST +/* experimental code */ +/* search for indices (audio mode required) */ +unsigned ScanIndices(unsigned track, unsigned cd_index, int bulk) +{ + /* scan for indices. */ + /* look at last sector of track. */ + /* when the index is not equal 1 scan by bipartition + * for offsets of all indices */ + + unsigned starttrack, endtrack; + unsigned startindex, endindex; + + unsigned j; + int LastIndex=0; + int n_0_transition; + unsigned StartSector; + unsigned retval = 0; + + index_list *baseindex_pool; + index_list *last_index_entry; + + SCSI *usalp = get_scsi_p(); + + static struct iterator i; + InitIterator(&i, 1); + + EnableCdda(usalp, 0, 0); + EnableCdda(usalp, 1, CD_FRAMESIZE_RAW + 16); + + if (!global.quiet && !(global.verbose & SHOW_INDICES)) + fprintf(stderr, "seeking index start ..."); + + if (bulk != 1) { + starttrack = track; endtrack = track; + } else { + starttrack = 1; endtrack = cdtracks; + } + baseindex_pool = (index_list *) malloc( sizeof(index_list) * (endtrack - starttrack + 1)); +#ifdef DEBUG_INDLIST + fprintf(stderr, "index0-mem-pool %p\n", baseindex_pool); +#endif + + + while (i.hasNextTrack(&i)) { + struct TOC *p = i.getNextTrack(&i); + unsigned ii = GETTRACK(p); + + if ( ii < starttrack || IS__DATA(p) ) + continue; /* skip nonaudio tracks */ + + if ( ii > endtrack ) + break; + + if ( global.verbose & SHOW_INDICES ) { + if (global.illleadout_cd && global.reads_illleadout && ii == endtrack) { + fprintf(stderr, "Analysis of track %d skipped due to unknown length\n", ii); + } + } + if (global.illleadout_cd && global.reads_illleadout + && ii == endtrack) continue; + + StartSector = Get_AudioStartSector(ii); + if (HaveSCMS(StartSector)) { + Set_SCMS(ii); + } + if ( global.verbose & SHOW_INDICES ) { + fprintf( stderr, "\rindex scan: %d...", ii ); + fflush (stderr); + } + LastIndex = ScanBackwardFrom(Get_EndSector(ii), StartSector, &n_0_transition, ii); + if (LastIndex > 99) continue; + + if (baseindex_pool != NULL) { +#ifdef DEBUG_INDLIST +#endif + /* register first index entry for this track */ + baseindex_pool[ii - starttrack].next = NULL; + baseindex_pool[ii - starttrack].frameoffset = StartSector; + global.trackindexlist[ii] = &baseindex_pool[ii - starttrack]; +#ifdef DEBUG_INDLIST +#endif + } else { + global.trackindexlist[ii] = NULL; + } + last_index_entry = global.trackindexlist[ii]; + + if (LastIndex < 2) { + register_index_position(n_0_transition, &last_index_entry); + continue; + } + + if ((global.verbose & SHOW_INDICES) && LastIndex > 1) + fprintf(stderr, "\rtrack %2d has %d indices, index table (pairs of 'index: frame offset')\n", ii, LastIndex); + + startindex = 0; + endindex = LastIndex; + + for (j = startindex; j <= endindex; j++) { + int IndexOffset; + + /* this track has indices */ + +#ifdef USE_LINEAR_SEARCH + /* do a linear search */ + IndexOffset = linear_search(j, StartSector, Get_EndSector(ii), ii); +#else + /* do a binary search */ + IndexOffset = binary_search(j, StartSector, Get_EndSector(ii), ii); +#endif + + if (IndexOffset != -1) { + StartSector = IndexOffset; + } + + if (j == 1) + last_index_entry->frameoffset = IndexOffset; + else if (j > 1) + register_index_position(IndexOffset, &last_index_entry); + + if ( IndexOffset == -1 ) { + if (global.verbose & SHOW_INDICES) { + if (global.gui == 0) { + fprintf(stderr, "%2u: N/A ",j); + if (((j + 1) % 8) == 0) fputs("\n", stderr); + } else { + fprintf(stderr, "\rT%02d I%02u N/A\n",ii,j); + } + } + } else { + if (global.verbose & SHOW_INDICES) { + if (global.gui == 0) { + fprintf(stderr, + "%2u:%6lu ", + j, + IndexOffset-Get_AudioStartSector(ii) + ); + if (((j + 1) % 8) == 0) fputs("\n", stderr); + } else { + fprintf(stderr, + "\rT%02d I%02u %06lu\n", + ii, + j, + IndexOffset-Get_AudioStartSector(ii) + ); + } + } + + if (track == ii && cd_index == j) { + retval = IndexOffset-Get_AudioStartSector(ii); + } + } /* if IndexOffset */ + } /* for index */ + register_index_position(n_0_transition, &last_index_entry); + + /* sanity check. clear all consecutive nonindex entries (frameoffset -1) from the end. */ + { + index_list *ip = global.trackindexlist[ii]; + index_list *iq = NULL; + index_list *lastgood = iq; + + while (ip != NULL) + { + if (ip->frameoffset == -1) + { + /* no index available */ + if (lastgood == NULL) + { + /* if this is the first one in a sequence, store predecessor */ + lastgood = iq; + } + } else { + /* this is a valid index, reset marker */ + lastgood = NULL; + } + + iq = ip; + ip = ip->next; + } + /* terminate chain at the last well defined entry. */ + if (lastgood != NULL) + lastgood->next = NULL; + } + + if (global.gui == 0 && (global.verbose & SHOW_INDICES) + && ii != endtrack) + fputs("\n", stderr); + } /* for tracks */ + if (global.gui == 0 && (global.verbose & SHOW_INDICES)) + fputs("\n", stderr); + if (playing != 0) StopPlay(get_scsi_p()); + + EnableCdda(usalp, 0, 0); + EnableCdda(usalp, 1, CD_FRAMESIZE_RAW); + + return retval; +} + +static unsigned char MCN[14]; + +static void Set_MCN(unsigned char *MCN_arg) +{ + memcpy(MCN, MCN_arg, 14); + MCN[13] = '\0'; +} + +unsigned char *Get_MCN(void) +{ + return MCN; +} + + +static TOC g_toc [MAXTRK+1]; /* hidden track + 100 regular tracks */ + +/*#define IS_AUDIO(i) (!(g_toc[i].bFlags & 0x40))*/ + +int +TOC_entries(unsigned tracks, unsigned char *a, unsigned char *b, int binvalid) +{ + int i; + for (i = 1; i <= (int)tracks; i++) { + unsigned char *p; + unsigned long dwStartSector; + + if (binvalid) { + p = a + 8*(i-1); + + g_toc[i].bFlags = p[1]; + g_toc[i].bTrack = p[2]; + g_toc[i].ISRC[0] = 0; + dwStartSector = a_to_u_4_byte(p+4); + g_toc[i].dwStartSector = dwStartSector; + lba_2_msf((long)dwStartSector, + &g_toc[i].mins, + &g_toc[i].secs, + &g_toc[i].frms); + } else { + p = b + 8*(i-1); + g_toc[i].bFlags = p[1]; + g_toc[i].bTrack = p[2]; + g_toc[i].ISRC[0] = 0; + if ((int)((p[5]*60 + p[6])*75 + p[7]) >= 150) { + g_toc[i].dwStartSector = (p[5]*60 + p[6])*75 + p[7] -150; + } else { + g_toc[i].dwStartSector = 0; + } + g_toc[i].mins = p[5]; + g_toc[i].secs = p[6]; + g_toc[i].frms = p[7]; + } + } + return 0; +} + +void toc_entry(unsigned nr, unsigned flag, unsigned tr, unsigned char *ISRC, + unsigned long lba, int m, int s, int f) +{ + if (nr > MAXTRK) return; + + g_toc[nr].bFlags = flag; + g_toc[nr].bTrack = tr; + if (ISRC) { + strncpy((char *)g_toc[nr].ISRC, (char *)ISRC, + sizeof(g_toc[nr].ISRC) -1); + g_toc[nr].ISRC[sizeof(g_toc[nr].ISRC) -1] = '\0'; + } + g_toc[nr].dwStartSector = lba; + g_toc[nr].mins = m; + g_toc[nr].secs = s; + g_toc[nr].frms = f; +} + +int patch_real_end(unsigned long sector) +{ + g_toc[cdtracks+1].dwStartSector = sector; + return 0; +} + +static int patch_cd_extra(unsigned track, unsigned long sector) +{ + if (track <= cdtracks) + g_toc[track].dwStartSector = sector; + return 0; +} + +static int restrict_tracks_illleadout(void) +{ + struct TOC *o = &g_toc[cdtracks+1]; + int i; + for (i = cdtracks; i >= 0; i--) { + struct TOC *p = &g_toc[i]; + if (GETSTART(o) > GETSTART(p)) break; + } + patch_cd_extra(i+1, GETSTART(o)); + cdtracks = i; + + return 0; +} + +static void Set_ISRC(int track, const unsigned char *ISRC_arg) +{ + if (track <= (int)cdtracks) { + memcpy(Get_ISRC(track), ISRC_arg, 16); + } +} + + +unsigned char *Get_ISRC(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].ISRC; + return NULL; +} + +static void patch_to_audio(unsigned long p_track) +{ + if (p_track <= cdtracks) + g_toc[p_track].bFlags &= ~0x40; +} + +int Get_Flags(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].bFlags; + return -1; +} + +int Get_Mins(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].mins; + return -1; +} + +int Get_Secs(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].secs; + return -1; +} + +int Get_Frames(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].frms; + return -1; +} + +int Get_Preemphasis(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].bFlags & 0x10; + return -1; +} + +static void Set_SCMS(unsigned long p_track) +{ + g_toc[p_track].SCMS = 1; +} + +int Get_SCMS(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].SCMS; + return -1; +} + +int Get_Copyright(unsigned long p_track) +{ + if (p_track <= cdtracks) { + if (g_toc[p_track].SCMS) return 1; + return ((int)g_toc[p_track].bFlags & 0x20) >> 4; + } + return -1; +} + +int Get_Datatrack(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].bFlags & 0x40; + return -1; +} + +int Get_Channels(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].bFlags & 0x80; + return -1; +} + +int Get_Tracknumber(unsigned long p_track) +{ + if (p_track <= cdtracks) + return g_toc[p_track].bTrack; + return -1; +} + +static int useHiddenTrack(void) +{ + return 0; +} + + + +static void it_reset(struct iterator *this); + +static void it_reset(struct iterator *this) +{ + this->index = this->startindex; +} + + +static int it_hasNextTrack(struct iterator *this); +static struct TOC *it_getNextTrack(struct iterator *this); + +static int it_hasNextTrack(struct iterator *this) +{ + return this->index <= (int)cdtracks+1; +} + + + +static struct TOC *it_getNextTrack(struct iterator *this) +{ + /* if ( (*this->hasNextTrack)(this) == 0 ) return NULL; */ + if ( this->index > (int)cdtracks+1 ) return NULL; + + return &g_toc[ this->index++ ]; +} + + +static void InitIterator(struct iterator *iter, unsigned long p_track) +{ + if (iter == NULL) return; + + iter->index = iter->startindex = useHiddenTrack() ? 0 : p_track; + iter->reset = it_reset; + iter->getNextTrack = it_getNextTrack; + iter->hasNextTrack = it_hasNextTrack; +} + +#if 0 +static struct iterator *NewIterator(void); + +static struct iterator *NewIterator () +{ + struct iterator *retval; + + retval = malloc (sizeof(struct iterator)); + if (retval != NULL) { + InitIterator(retval, 1); + } + return retval; +} +#endif + +long Get_AudioStartSector(unsigned long p_track) +{ +#if 1 + if (p_track == CDROM_LEADOUT) + p_track = cdtracks + 1; + + if (p_track <= cdtracks +1 + && IS__AUDIO(&g_toc[p_track])) + return GETSTART(&g_toc[p_track]); +#else + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, p_track); + else i.reset(&i); + + if (p_track == cdtracks + 1) p_track = CDROM_LEADOUT; + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + + if (GETTRACK(p) == p_track) { + if (IS__DATA(p)) { + return -1; + } + return GETSTART(p); + } + } +#endif + return -1; +} + + +long Get_StartSector(unsigned long p_track) +{ +#if 1 + if (p_track == CDROM_LEADOUT) + p_track = cdtracks + 1; + + if (p_track <= cdtracks +1) + return GETSTART(&g_toc[p_track]); +#else + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, p_track); + else i.reset(&i); + + if (p_track == cdtracks + 1) p_track = CDROM_LEADOUT; + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + + if (GETTRACK(p) == p_track) { + return GETSTART(p); + } + } +#endif + return -1; +} + + +long Get_EndSector(unsigned long p_track) +{ +#if 1 + if (p_track <= cdtracks) + return GETSTART(&g_toc[p_track+1])-1; +#else + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, p_track); + else i.reset(&i); + + if (p_track == cdtracks + 1) p_track = CDROM_LEADOUT; + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + if (GETTRACK(p) == p_track) { + p = i.getNextTrack(&i); + if (p == NULL) { + return -1; + } + return GETSTART(p)-1; + } + } +#endif + return -1; +} + +long FirstTrack(void) +{ + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + if (i.hasNextTrack(&i)) { + return GETTRACK(i.getNextTrack(&i)); + } + return -1; +} + +long FirstAudioTrack(void) +{ + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + unsigned ii = GETTRACK(p); + + if (ii == CDROM_LEADOUT) break; + if (IS__AUDIO(p)) { + return ii; + } + } + return -1; +} + +long FirstDataTrack(void) +{ + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + if (IS__DATA(p)) { + return GETTRACK(p); + } + } + return -1; +} + +long LastTrack(void) +{ + return g_toc[cdtracks].bTrack; +} + +long LastAudioTrack(void) +{ + long j = -1; + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + if (IS__AUDIO(p) && (GETTRACK(p) != CDROM_LEADOUT)) { + j = GETTRACK(p); + } + } + return j; +} + +long Get_LastSectorOnCd(unsigned long p_track) +{ + long LastSec = 0; + static struct iterator i; + + if (global.illleadout_cd && global.reads_illleadout) + return 150+(99*60+59)*75+74; + + if (i.reset == NULL) InitIterator(&i, p_track); + else i.reset(&i); + + if (p_track == cdtracks + 1) p_track = CDROM_LEADOUT; + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + + if (GETTRACK(p) < p_track) + continue; + + LastSec = GETSTART(p); + + if (IS__DATA(p)) break; + } + return LastSec; +} + +int Get_Track(unsigned long sector) +{ + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, 1); + else i.reset(&i); + + if (i.hasNextTrack(&i)) { + TOC *o = i.getNextTrack(&i); + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + if ((GETSTART(o) <= sector) && (GETSTART(p) > sector)) { + if (IS__DATA(o)) { + return -1; + } else { + return GETTRACK(o); + } + } + o = p; + } + } + return -1; +} + +int CheckTrackrange(unsigned long from, unsigned long upto) +{ + static struct iterator i; + if (i.reset == NULL) InitIterator(&i, from); + else i.reset(&i); + + while (i.hasNextTrack(&i)) { + TOC *p = i.getNextTrack(&i); + + if (GETTRACK(p) < from) + continue; + + if (GETTRACK(p) == upto) + return 1; + + /* data tracks terminate the search */ + if (IS__DATA(p)) + return 0; + } + /* track not found */ + return 0; +} + +#ifdef USE_PARANOIA +long cdda_disc_firstsector(void *d); + +long cdda_disc_firstsector(void *d) +{ + return Get_StartSector(FirstAudioTrack()); +} + +int cdda_tracks(void *d); + +int cdda_tracks(void *d) +{ + return LastAudioTrack() - FirstAudioTrack() +1; +} + +int cdda_track_audiop(void *d, int track); + +int cdda_track_audiop(void *d, int track) +{ + return Get_Datatrack(track) == 0; +} + +long cdda_track_firstsector(void *d, int track); + +long cdda_track_firstsector(void *d, int track) +{ + return Get_AudioStartSector(track); +} + +long cdda_track_lastsector(void *d, int track); + +long cdda_track_lastsector(void *d, int track) +{ + return Get_EndSector(track); +} + +long cdda_disc_lastsector(void *d); + +long cdda_disc_lastsector(void *d) +{ + return Get_LastSectorOnCd(cdtracks) - 1; +} + +int cdda_sector_gettrack(void *d,long sector); + +int cdda_sector_gettrack(void *d, long sector) +{ + return Get_Track(sector); +} + +#endif diff --git a/icedax/toc.h b/icedax/toc.h new file mode 100644 index 0000000..84da13a --- /dev/null +++ b/icedax/toc.h @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +/* @(#)toc.h 1.9 06/02/19 Copyright 1998,1999 Heiko Eissfeldt, Copyright 2006 J. Schilling */ + +#define MAXTRK 100 /* maximum of audio tracks (without a hidden track) */ + +extern unsigned cdtracks; +extern int have_multisession; +extern int have_CD_extra; +extern int have_CD_text; +extern int have_CDDB; + +#if !defined(HAVE_NETDB_H) +#undef USE_REMOTE +#else +#define USE_REMOTE 1 +extern int request_titles(void); +#endif + +extern int ReadToc(void); +extern void Check_Toc(void); +extern int TOC_entries(unsigned tracks, + unsigned char *a, unsigned char *b, + int bvalid); +extern void toc_entry(unsigned nr, unsigned flag, unsigned tr, + unsigned char *ISRC, + unsigned long lba, int m, int s, int f); +extern int patch_real_end(unsigned long sector); +extern int no_disguised_audiotracks(void); + +extern int Get_Track(unsigned long sector); +extern long FirstTrack(void); +extern long LastTrack(void); +extern long FirstAudioTrack(void); +extern long FirstDataTrack(void); +extern long LastAudioTrack(void); +extern long Get_EndSector(unsigned long p_track); +extern long Get_StartSector(unsigned long p_track); +extern long Get_AudioStartSector(unsigned long p_track); +extern long Get_LastSectorOnCd(unsigned long p_track); +extern int CheckTrackrange(unsigned long from, unsigned long upto); + +extern int Get_Preemphasis(unsigned long p_track); +extern int Get_Channels(unsigned long p_track); +extern int Get_Copyright(unsigned long p_track); +extern int Get_Datatrack(unsigned long p_track); +extern int Get_Tracknumber(unsigned long p_track); +extern unsigned char *Get_MCN(void); +extern unsigned char *Get_ISRC(unsigned long p_track); + +extern unsigned find_an_off_sector(unsigned lSector, unsigned SectorBurstVal); +extern void DisplayToc(void); +extern unsigned FixupTOC(unsigned no_tracks); +extern void calc_cddb_id(void); +extern void calc_cdindex_id(void); +extern void Read_MCN_ISRC(void); +extern unsigned ScanIndices(unsigned trackval, unsigned indexval, int bulk); +extern int handle_cdtext(void); +extern int lba_2_msf(long lba, int *m, int *s, int *f); diff --git a/icedax/version.sed b/icedax/version.sed new file mode 100644 index 0000000..d0752df --- /dev/null +++ b/icedax/version.sed @@ -0,0 +1,4 @@ +/cdr_version\[\] = /{ + s/.*"\(.*\)";/\1/ + p +} diff --git a/icedax/wav.c b/icedax/wav.c new file mode 100644 index 0000000..b30ed9b --- /dev/null +++ b/icedax/wav.c @@ -0,0 +1,157 @@ +/* + * 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. + * + */ + +/* @(#)wav.c 1.4 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */ +/*** + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Heiko Eissfeldt + * + * + */ +#include "config.h" +#include <stdio.h> +#include <unixstd.h> +#include "byteorder.h" +#include "sndfile.h" + +/*** + * --------------------------------------------------------------------- + * definitions for RIFF-output (from windows MMSYSTEM) + * --------------------------------------------------------------------- + */ + +typedef unsigned int FOURCC; /* a four character code */ + +typedef struct CHUNKHDR { + FOURCC ckid; /* chunk ID */ + unsigned int dwSize; /* chunk size */ +} CHUNKHDR; + +/* flags for 'wFormatTag' field of WAVEFORMAT */ +#define WAVE_FORMAT_PCM 1 + +/* specific waveform format structure for PCM data */ +typedef struct pcmwaveformat_tag { + unsigned short wFormatTag; /* format type */ + unsigned short nChannels; /* number of channels (i.e. mono, stereo, etc.) */ + unsigned int nSamplesPerSec; /* sample rate */ + unsigned int nAvgBytesPerSec;/* for buffer size estimate */ + unsigned short nBlockAlign; /* block size of data */ + unsigned short wBitsPerSample; +} PCMWAVEFORMAT; +typedef PCMWAVEFORMAT *PPCMWAVEFORMAT; + + +/* MMIO macros */ +#define mmioFOURCC(ch0, ch1, ch2, ch3) \ + ((unsigned int)(unsigned char)(ch0) | ((unsigned int)(unsigned char)(ch1) << 8) | \ + ((unsigned int)(unsigned char)(ch2) << 16) | ((unsigned int)(unsigned char)(ch3) << 24)) + +#define FOURCC_RIFF mmioFOURCC ('R', 'I', 'F', 'F') +#define FOURCC_LIST mmioFOURCC ('L', 'I', 'S', 'T') +#define FOURCC_WAVE mmioFOURCC ('W', 'A', 'V', 'E') +#define FOURCC_FMT mmioFOURCC ('f', 'm', 't', ' ') +#define FOURCC_DATA mmioFOURCC ('d', 'a', 't', 'a') + + +/* simplified Header for standard WAV files */ +typedef struct WAVEHDR { + CHUNKHDR chkRiff; + FOURCC fccWave; + CHUNKHDR chkFmt; + unsigned short wFormatTag; /* format type */ + unsigned short nChannels; /* number of channels (i.e. mono, stereo, etc.) */ + unsigned int nSamplesPerSec; /* sample rate */ + unsigned int nAvgBytesPerSec;/* for buffer estimation */ + unsigned short nBlockAlign; /* block size of data */ + unsigned short wBitsPerSample; + CHUNKHDR chkData; +} WAVEHDR; + +#define IS_STD_WAV_HEADER(waveHdr) ( \ + waveHdr.chkRiff.ckid == FOURCC_RIFF && \ + waveHdr.fccWave == FOURCC_WAVE && \ + waveHdr.chkFmt.ckid == FOURCC_FMT && \ + waveHdr.chkData.ckid == FOURCC_DATA && \ + waveHdr.wFormatTag == WAVE_FORMAT_PCM) + +static WAVEHDR waveHdr; + +static int _InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes); + +static int _InitSound(int audio, long channels, unsigned long rate, + long nBitsPerSample, unsigned long expected_bytes) +{ + unsigned long nBlockAlign = channels * ((nBitsPerSample + 7) / 8); + unsigned long nAvgBytesPerSec = nBlockAlign * rate; + unsigned long temp = expected_bytes + sizeof(WAVEHDR) - sizeof(CHUNKHDR); + + waveHdr.chkRiff.ckid = cpu_to_le32(FOURCC_RIFF); + waveHdr.fccWave = cpu_to_le32(FOURCC_WAVE); + waveHdr.chkFmt.ckid = cpu_to_le32(FOURCC_FMT); + waveHdr.chkFmt.dwSize = cpu_to_le32(sizeof (PCMWAVEFORMAT)); + waveHdr.wFormatTag = cpu_to_le16(WAVE_FORMAT_PCM); + waveHdr.nChannels = cpu_to_le16(channels); + waveHdr.nSamplesPerSec = cpu_to_le32(rate); + waveHdr.nBlockAlign = cpu_to_le16(nBlockAlign); + waveHdr.nAvgBytesPerSec = cpu_to_le32(nAvgBytesPerSec); + waveHdr.wBitsPerSample = cpu_to_le16(nBitsPerSample); + waveHdr.chkData.ckid = cpu_to_le32(FOURCC_DATA); + waveHdr.chkRiff.dwSize = cpu_to_le32(temp); + waveHdr.chkData.dwSize = cpu_to_le32(expected_bytes); + + return write (audio, &waveHdr, sizeof (waveHdr)); +} + +static int _ExitSound(int audio, unsigned long nBytesDone); + +static int _ExitSound(int audio, unsigned long nBytesDone) +{ + unsigned long temp = nBytesDone + sizeof(WAVEHDR) - sizeof(CHUNKHDR); + + waveHdr.chkRiff.dwSize = cpu_to_le32(temp); + waveHdr.chkData.dwSize = cpu_to_le32(nBytesDone); + + /* goto beginning */ + if (lseek(audio, 0L, SEEK_SET) == -1) { + return 0; + } + return write (audio, &waveHdr, sizeof (waveHdr)); +} + +static unsigned long _GetHdrSize(void); + +static unsigned long _GetHdrSize(void) +{ + return sizeof( waveHdr ); +} + +static unsigned long InSizeToOutSize(unsigned long BytesToDo); + +static unsigned long InSizeToOutSize(unsigned long BytesToDo) +{ + return BytesToDo; +} + +struct soundfile wavsound = +{ + _InitSound, /* init header method */ + _ExitSound, /* exit header method */ + _GetHdrSize, /* report header size method */ + /* get sound samples out */ + (int (*)(int audio, unsigned char *buf, unsigned long BytesToDo)) write, + InSizeToOutSize, /* compressed? output file size */ + 0 /* needs big endian samples */ +}; + + diff --git a/icedax/wav.h b/icedax/wav.h new file mode 100644 index 0000000..e1a90d1 --- /dev/null +++ b/icedax/wav.h @@ -0,0 +1,14 @@ +/* + * 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. + * + */ + +/* @(#)wav.h 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */ +extern struct soundfile wavsound; diff --git a/include/AddNetworkBits.cmake b/include/AddNetworkBits.cmake new file mode 100644 index 0000000..56643b3 --- /dev/null +++ b/include/AddNetworkBits.cmake @@ -0,0 +1,60 @@ + +# various checks add additional of extra libs, most likely for SunOS +# using own checks and not CHECK_SYMBOLE because of spurios problems seen with +# it + +INCLUDE(CheckCSourceCompiles) + +SET(TESTSRC " +#include <sys/types.h> +#include <sys/socket.h> + +int main(int argc, char **argv) { +return socket(AF_INET, SOCK_STREAM, 0); +} +") + +SET(CMAKE_REQUIRED_LIBRARIES ) +CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBC_SOCKET) + +IF(NOT USE_LIBC_SOCKET) + + LIST(APPEND EXTRA_LIBS socket) + + SET(CMAKE_REQUIRED_LIBRARIES socket) + CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBSOCKET) + IF(NOT USE_LIBSOCKET) + MESSAGE(FATAL_ERROR "No working socket(...) found in libc or libsocket") + ENDIF(NOT USE_LIBSOCKET) + +ENDIF(NOT USE_LIBC_SOCKET) + +SET(TESTSRC " +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +int main(int argc, char **argv) { +struct hostent *h = gethostbyname(argv[0]); +return sizeof(h); +} +") + +CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBC_NLS) +IF(NOT USE_LIBC_NLS) + SET(CMAKE_REQUIRED_LIBRARIES nls) + CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBNLS) + IF(USE_LIBNLS) + LIST(APPEND EXTRA_LIBS nls) + ELSE(USE_LIBNLS) + SET(CMAKE_REQUIRED_LIBRARIES xnet) + CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBXNET) + IF(NOT USE_LIBXNET) + MESSAGE(FATAL_ERROR "Error: Could not find a system library providing gethostbyname.") + ELSE(NOT USE_LIBXNET) + LIST(APPEND EXTRA_LIBS xnet) + ENDIF(NOT USE_LIBXNET) + ENDIF(USE_LIBNLS) +ENDIF(NOT USE_LIBC_NLS) +SET(CMAKE_REQUIRED_LIBRARIES ) + diff --git a/include/AddScgBits.cmake b/include/AddScgBits.cmake new file mode 100644 index 0000000..6aaff73 --- /dev/null +++ b/include/AddScgBits.cmake @@ -0,0 +1,65 @@ + +IF(NOT GUARD_SCGCONFIG) + SET(GUARD_SCGCONFIG 1) + + +LIST(APPEND EXTRA_LIBS "usal") + +INCLUDE(CheckIncludeFiles) +CHECK_INCLUDE_FILES("stdio.h;camlib.h" HAVE_CAMLIB_H) + +IF(HAVE_CAMLIB_H) + + # quick an dirty, should better become a variable used by libusal only, + # analogous to SCG_SELF_LIBS + ADD_DEFINITIONS(-DHAVE_CAMLIB_H) + + LIST(APPEND EXTRA_LIBS "cam") + LIST(APPEND SCG_SELF_LIBS "cam") + +ENDIF(HAVE_CAMLIB_H) + +FIND_LIBRARY(HAVE_LIBVOLMGT "volmgt") +IF(HAVE_LIBVOLMGT) + LIST(APPEND EXTRA_LIBS "volmgt") + LIST(APPEND SCG_SELF_LIBS "volmgt") +ENDIF(HAVE_LIBVOLMGT) + + INCLUDE(CheckCSourceCompiles) + + SET(TESTSRC " +#include <sys/types.h> +#include <sys/socket.h> + +int main(int argc, char **argv) { + return socket(AF_INET, SOCK_STREAM, 0); +} +") + +SET(CMAKE_REQUIRED_LIBRARIES ) + CHECK_C_SOURCE_COMPILES("${TESTSRC}" LIBC_SOCKET) + +IF(NOT LIBC_SOCKET) + LIST(APPEND EXTRA_LIBS -lsocket) + #MESSAGE("Using libsocket for socket functions") +ENDIF(NOT LIBC_SOCKET) + + + SET(TESTSRC " +#include <sched.h> +struct sched_param scp; + int main(int argc, char **argv) { + return sched_setscheduler(0, SCHED_RR, &scp); + } +") + + +SET(CMAKE_REQUIRED_LIBRARIES ) + CHECK_C_SOURCE_COMPILES("${TESTSRC}" LIBC_SCHED) + +IF(NOT LIBC_SCHED) + LIST(APPEND EXTRA_LIBS -lrt) + #MESSAGE("Using librt for realtime functions") +ENDIF(NOT LIBC_SCHED) + +ENDIF(NOT GUARD_SCGCONFIG) diff --git a/include/AddSchilyBits.cmake b/include/AddSchilyBits.cmake new file mode 100644 index 0000000..475e5cd --- /dev/null +++ b/include/AddSchilyBits.cmake @@ -0,0 +1,13 @@ +IF(NOT CHECKED_rols) + SET(CHECKED_rols 1) + + LIST(APPEND EXTRA_LIBS "rols") + +# abuse this include file to make sure the target is set + + IF(NOT MANSUBDIR) + SET(MANSUBDIR "share/man") + ENDIF(NOT MANSUBDIR) + +ENDIF(NOT CHECKED_rols) + diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..99a69fd --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,170 @@ +PROJECT (INCLUDES C) + +FILE(READ "${CMAKE_SOURCE_DIR}/VERSION" CDRKIT_VERSION) +STRING(REPLACE "\n" "" CDRKIT_VERSION "${CDRKIT_VERSION}") +MESSAGE("Configuring Cdrkit, version ${CDRKIT_VERSION}") + +# auto-generated header with sizeof magic +INCLUDE(CheckTypeSize) +CHECK_TYPE_SIZE(short SIZE_SHORT) +MATH(EXPR SHORTLESS ${SIZE_SHORT}-1) +CHECK_TYPE_SIZE(int SIZE_INT) +MATH(EXPR INTLESS ${SIZE_INT}-1) +CHECK_TYPE_SIZE(long SIZE_LONG) +MATH(EXPR LONGLESS ${SIZE_LONG}-1) +CHECK_TYPE_SIZE("long long" SIZE_LLONG) +MATH(EXPR LLONGLESS ${SIZE_LLONG}-1) +CHECK_TYPE_SIZE(float SIZE_FLOAT) +MATH(EXPR FLOATLESS ${SIZE_FLOAT}-1) +CHECK_TYPE_SIZE(double SIZE_DOUBLE) +MATH(EXPR DOUBLELESS ${SIZE_DOUBLE}-1) +CHECK_TYPE_SIZE("char*" SIZE_PTR) +MATH(EXPR PTRLESS ${SIZE_PTR}-1) +CONFIGURE_FILE( align.h.in align.h) +#SET_SOURCE_FILES_PROPERTIES(align.h PROPERTIES GENERATED 1) + +TRY_COMPILE(VA_LIST_IS_ARRAY ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/test_VA_LIST_IS_ARRAY.c) +# invert the result, has the condition IFF compiler fails. There must be a simple way to say a=!b... but how? +IF(VA_LIST_IS_ARRAY) + SET(VA_LIST_IS_ARRAY FALSE) +else(VA_LIST_IS_ARRAY) + SET(VA_LIST_IS_ARRAY TRUE) +endif(VA_LIST_IS_ARRAY) + + +INCLUDE(TestBigEndian) +TEST_BIG_ENDIAN(WORDS_BIGENDIAN) + +TRY_RUN(BITFIELDS_HTOL TEST_DUMMY ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/test_BITFIELDS_HTOL.c) + +INCLUDE(CheckIncludeFiles) + +#SET(CMAKE_REQUIRED_INCLUDES "/usr/include;/usr/local/include") +CHECK_INCLUDE_FILES("stdarg.h" HAVE_STDARG_H) +CHECK_INCLUDE_FILES("stdlib.h" HAVE_STDLIB_H) +CHECK_INCLUDE_FILES("string.h" HAVE_STRING_H) +CHECK_INCLUDE_FILES("strings.h" HAVE_STRINGS_H) +CHECK_INCLUDE_FILES("unistd.h" HAVE_UNISTD_H) +CHECK_INCLUDE_FILES("getopt.h" HAVE_GETOPT_H) +CHECK_INCLUDE_FILES("limits.h" HAVE_LIMITS_H) +CHECK_INCLUDE_FILES("fcntl.h" HAVE_FCNTL_H) +CHECK_INCLUDE_FILES("sys/file.h" HAVE_SYS_FILE_H) +CHECK_INCLUDE_FILES("inttypes.h" HAVE_INTTYPES_H) +CHECK_INCLUDE_FILES("dirent.h" HAVE_DIRENT_H) +CHECK_INCLUDE_FILES("alloca.h" HAVE_ALLOCA_H) +CHECK_INCLUDE_FILES("termios.h" HAVE_TERMIOS_H) +CHECK_INCLUDE_FILES("termio.h" HAVE_TERMIO_H) +CHECK_INCLUDE_FILES("pwd.h" HAVE_PWD_H) +CHECK_INCLUDE_FILES("sys/time.h" HAVE_SYS_TIME_H) +CHECK_INCLUDE_FILES("utime.h" HAVE_UTIME_H) +CHECK_INCLUDE_FILES("sys/ioctl.h" HAVE_SYS_IOCTL_H) +CHECK_INCLUDE_FILES("sys/param.h" HAVE_SYS_PARAM_H) +CHECK_INCLUDE_FILES("wait.h" HAVE_WAIT_H) +CHECK_INCLUDE_FILES("sys/wait.h" HAVE_SYS_WAIT_H) +CHECK_INCLUDE_FILES("sys/resource.h" HAVE_SYS_RESOURCE_H) +CHECK_INCLUDE_FILES("sys/utsname.h" HAVE_SYS_UTSNAME_H) +CHECK_INCLUDE_FILES("poll.h" HAVE_POLL_H) +CHECK_INCLUDE_FILES("sys/poll.h" HAVE_SYS_POLL_H) +CHECK_INCLUDE_FILES("netdb.h" HAVE_NETDB_H) +CHECK_INCLUDE_FILES("sys/socket.h" HAVE_SYS_SOCKET_H) +CHECK_INCLUDE_FILES("linux/pg.h" HAVE_LINUX_PG_H) +CHECK_INCLUDE_FILES("arpa/inet.h" HAVE_ARPA_INET_H) +CHECK_INCLUDE_FILES("sys/ipc.h" HAVE_SYS_IPC_H) +CHECK_INCLUDE_FILES("sys/types.h;sys/mman.h" HAVE_SYS_MMAN_H) +CHECK_INCLUDE_FILES("sys/types.h;sys/dkio.h" HAVE_SYS_DKIO_H) +CHECK_INCLUDE_FILES("sys/types.h;sun/dkio.h" HAVE_SUN_DKIO_H) +CHECK_INCLUDE_FILES("iconv.h" HAVE_ICONV_H) + + +INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckFunctionExists) + +#SET(CMAKE_REQUIRED_LIBRARIES iconv) +SET(TESTSRC " +#include <iconv.h> +int main(int a, char **b) { iconv_t foo = iconv_open(b[0], b[0]); return(0); } +") + +CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBC_ICONV) +IF(NOT USE_LIBC_ICONV) +SET(CMAKE_REQUIRED_LIBRARIES iconv) +CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBICONV) +IF(NOT USE_LIBICONV) + message("ERROR: no library providing iconv found") +ENDIF(NOT USE_LIBICONV) +ENDIF(NOT USE_LIBC_ICONV) +SET(CMAKE_REQUIRED_INCLUDES ) + + + +#CHECK_C_SOURCE_COMPILES("${TESTSRC}" USE_LIBICONV) +#IF(NOT USE_LIBICONV) +# FIND_FILE(ICONV_H_LOCATION "iconv.h") +# IF(NOT "${ICONV_H_LOCATION}" EQUAL "/usr/include/iconv.h") +# MESSAGE("WARNING: iconv.h found in non-standard location (${ICONV_H_LOCATION}) but") +# MESSAGE("GNU libiconv is not available. See INSTALL for details. Sleeping 10 seconds.") +# EXECUTE_PROCESS(COMMAND "sleep" "10") +# ENDIF(NOT "${ICONV_H_LOCATION}" EQUAL "/usr/include/iconv.h") +#ENDIF(NOT USE_LIBICONV) + +SET(CMAKE_REQUIRED_LIBRARIES ) +SET(TESTSRC " +#include <stdlib.h> +int main() { return ( (int) drand48() ) ; } +") +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_DRAND48) +SET(TESTSRC " +#include <stdlib.h> +int main() { return ( (int) drand() ) ; } +") +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_DRAND) +SET(TESTSRC " +#include <sys/socket.h> +#include <netdb.h> +int main(int argc, char **argv) { +struct sockaddr sa; +return getnameinfo(&sa, 1, argv[0], 1, argv[1], 1, 0); +} +") +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_GETNAMEINFO) +SET(TESTSRC " +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +int main(int a, char **b) { +struct in_addr in; +inet_ntoa(in); +return 0; +} +") +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_INET_NTOA) + +SET(TESTSRC " +#include <sys/types.h> +#include <wait.h> +int main() { +union wait w; +return 0; +} +") +# FIXME: try the same with #include <sys/wait.h>... may work, if yes, integrate properly +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_UNION_WAIT) +SET(TESTSRC " +#include <sys/types.h> +#include <sys/mman.h> +int main() { +if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) + return(0); + } +") +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_MLOCKALL) +SET(TESTSRC " +int main(int argc, char **argv) { + int a[argc]; + return 0; +} +") +CHECK_C_SOURCE_COMPILES("${TESTSRC}" HAVE_DYN_ARRAYS) + +CONFIGURE_FILE( xconfig.h.in xconfig.h) + diff --git a/include/align.h.in b/include/align.h.in new file mode 100644 index 0000000..411fec1 --- /dev/null +++ b/include/align.h.in @@ -0,0 +1,84 @@ +/* + * This file has been generated automatically + * by CMake commands. Do not edit. + * + * Original contents from @(#)align_test.c 1.19 03/11/25 Copyright 1995 J. Schilling + * + */ + +#ifndef _UTYPES_H +#include <utypes.h> +#endif + +#define ALIGN_SHORT @SIZE_SHORT@ +#define ALIGN_INT @SIZE_INT@ +#define ALIGN_LONG @SIZE_LONG@ +#define ALIGN_LLONG @SIZE_LLONG@ +#define ALIGN_FLOAT @SIZE_FLOAT@ +#define ALIGN_DOUBLE @SIZE_DOUBLE@ +#define ALIGN_PTR @SIZE_PTR@ + +#define SIZE_SHORT @SIZE_SHORT@ +#define SIZE_INT @SIZE_INT@ +#define SIZE_LONG @SIZE_LONG@ +#define SIZE_LLONG @SIZE_LLONG@ +#define SIZE_FLOAT @SIZE_FLOAT@ +#define SIZE_DOUBLE @SIZE_DOUBLE@ +#define SIZE_PTR @SIZE_PTR@ + + +#define ALIGN_SMASK @SHORTLESS@ +#define ALIGN_IMASK @INTLESS@ +#define ALIGN_LMASK @LONGLESS@ +#define ALIGN_LLMASK @LLONGLESS@ +#define ALIGN_FMASK @FLOATLESS@ +#define ALIGN_DMASK @DOUBLELESS@ +#define ALIGN_PMASK @PTRLESS@ + + +/* + * There used to be a cast to an int but we get a warning from GCC. + * This warning message from GCC is wrong. + * Believe me that this macro would even be usable if I would cast to short. + * In order to avoid this warning, we are now using UIntptr_t + */ +#define xaligned(a, s) ((((UIntptr_t)(a)) & (s)) == 0 ) +#define x2aligned(a, b, s) (((((UIntptr_t)(a)) | ((UIntptr_t)(b))) & (s)) == 0 ) + +#define saligned(a) xaligned(a, ALIGN_SMASK) +#define s2aligned(a, b) x2aligned(a, b, ALIGN_SMASK) + +#define ialigned(a) xaligned(a, ALIGN_IMASK) +#define i2aligned(a, b) x2aligned(a, b, ALIGN_IMASK) + +#define laligned(a) xaligned(a, ALIGN_LMASK) +#define l2aligned(a, b) x2aligned(a, b, ALIGN_LMASK) + +#define llaligned(a) xaligned(a, ALIGN_LLMASK) +#define ll2aligned(a, b) x2aligned(a, b, ALIGN_LLMASK) + +#define faligned(a) xaligned(a, ALIGN_FMASK) +#define f2aligned(a, b) x2aligned(a, b, ALIGN_FMASK) + +#define daligned(a) xaligned(a, ALIGN_DMASK) +#define d2aligned(a, b) x2aligned(a, b, ALIGN_DMASK) + +#define paligned(a) xaligned(a, ALIGN_PMASK) +#define p2aligned(a, b) x2aligned(a, b, ALIGN_PMASK) + + +/* + * There used to be a cast to an int but we get a warning from GCC. + * This warning message from GCC is wrong. + * Believe me that this macro would even be usable if I would cast to short. + * In order to avoid this warning, we are now using UIntptr_t + */ +#define xalign(x, a, m) ( ((char *)(x)) + ( (a) - 1 - ((((UIntptr_t)(x))-1)&(m))) ) + +#define salign(x) xalign((x), ALIGN_SHORT, ALIGN_SMASK) +#define ialign(x) xalign((x), ALIGN_INT, ALIGN_IMASK) +#define lalign(x) xalign((x), ALIGN_LONG, ALIGN_LMASK) +#define llalign(x) xalign((x), ALIGN_LLONG, ALIGN_LLMASK) +#define falign(x) xalign((x), ALIGN_FLOAT, ALIGN_FMASK) +#define dalign(x) xalign((x), ALIGN_DOUBLE, ALIGN_DMASK) +#define palign(x) xalign((x), ALIGN_PTR, ALIGN_PMASK) diff --git a/include/allocax.h b/include/allocax.h new file mode 100644 index 0000000..11431de --- /dev/null +++ b/include/allocax.h @@ -0,0 +1,80 @@ +/* + * 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. + * + */ + +/* @(#)allocax.h 1.3 03/07/15 Copyright 2002 J. Schilling */ +/* + * Definitions for users of alloca() + * + * Important: #include this directly after <mconfig.h> + * and before any other include file. + * See comment in _AIX part below. + * + * Copyright (c) 2002 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. + */ + + +#ifndef _ALLOCAX_H +#define _ALLOCAX_H + +#ifdef __GNUC__ +# ifndef alloca +# define alloca(s) __builtin_alloca(s) +# endif +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + /* + * Indent so pre-ANSI compilers will ignore it + * + * Some versions of AIX may require this to be + * first in the file and only preceded by + * comments and preprocessor directives/ + */ + #pragma alloca +# else +# ifndef alloca + /* + * predefined by HP cc +Olibcalls + */ +# ifdef PROTOTYPES + extern void *alloca(); +# else + extern char *alloca(); +# endif +# endif +# endif +# endif +# endif +#endif + + +#endif /* _ALLOCAX_H */ diff --git a/include/avoffset.h b/include/avoffset.h new file mode 100644 index 0000000..aa0fdaa --- /dev/null +++ b/include/avoffset.h @@ -0,0 +1,13 @@ +/* + * 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. + * + */ + +/* Dummy */ diff --git a/include/btorder.h b/include/btorder.h new file mode 100644 index 0000000..a76a239 --- /dev/null +++ b/include/btorder.h @@ -0,0 +1,130 @@ +/* + * 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. + * + */ + +/* @(#)btorder.h 1.16 03/06/15 Copyright 1996 J. Schilling */ +/* + * Definitions for Bit and Byte ordering + * + * Copyright (c) 1996 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. + */ + + +#ifndef _BTORDER_H +#define _BTORDER_H + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> /* try to load isa_defs.h on Solaris */ +#define _INCL_SYS_TYPES_H +#endif + +#ifndef _MCONFIG_H +#include <mconfig.h> /* load bit/byte-oder from xmconfig.h*/ +#endif + +/* + * Convert bit-order definitions from xconfig.h into our values + * and verify them. + */ +#if defined(HAVE_C_BITFIELDS) && \ + defined(BITFIELDS_LTOH) +#define _BIT_FIELDS_LTOH +#endif + +#if defined(HAVE_C_BITFIELDS) && \ + defined(BITFIELDS_HTOL) +#define _BIT_FIELDS_HTOL +#endif + +#if defined(HAVE_C_BITFIELDS) && \ + !defined(BITFIELDS_HTOL) +#define BITFIELDS_LTOH +#define _BIT_FIELDS_LTOH +#endif + +#if defined(_BIT_FIELDS_LTOH) && defined(_BIT_FIELDS_HTOL) +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defines. And that's what we want. + */ +error Only one of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL may be defined +#endif + + +/* + * Convert byte-order definitions from xconfig.h into our values + * and verify them. + * Note that we cannot use the definitions _LITTLE_ENDIAN and _BIG_ENDIAN + * because they are used on IRIX-6.5 with different meaning. + */ +#if defined(HAVE_C_BIGENDIAN) && \ + !defined(WORDS_BIGENDIAN) +#define WORDS_LITTLEENDIAN +/*#define _LITTLE_ENDIAN*/ +#endif + +#if defined(HAVE_C_BIGENDIAN) && \ + defined(WORDS_BIGENDIAN) +#undef WORDS_LITTLEENDIAN +/*#define _BIG_ENDIAN*/ +#endif + +#if defined(_BIT_FIELDS_LTOH) || defined(_BIT_FIELDS_HTOL) +/* + * Bitorder is already known. + */ +#else +/* + * Bitorder not yet known. + */ +# if defined(sun3) || defined(mc68000) || \ + defined(sun4) || defined(__sparc) || defined(sparc) || \ + defined(__hppa) || defined(_ARCH_PPC) || defined(_IBMR2) +# define _BIT_FIELDS_HTOL +# endif + +# if defined(__sgi) && defined(__mips) +# define _BIT_FIELDS_HTOL +# endif + +# if defined(__i386__) || defined(__i386) || defined(i386) || \ + defined(__alpha__) || defined(__alpha) || defined(alpha) || \ + defined(__arm__) || defined(__arm) || defined(arm) +# define _BIT_FIELDS_LTOH +# endif + +# if defined(__ppc__) || defined(ppc) || defined(__ppc) || \ + defined(__PPC) || defined(powerpc) || defined(__powerpc__) + +# if defined(__BIG_ENDIAN__) +# define _BIT_FIELDS_HTOL +# else +# define _BIT_FIELDS_LTOH +# endif +# endif +#endif + +#endif /* _BTORDER_H */ diff --git a/include/ccomdefs.h b/include/ccomdefs.h new file mode 100644 index 0000000..6667501 --- /dev/null +++ b/include/ccomdefs.h @@ -0,0 +1,78 @@ +/* + * 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. + * + */ + +/* @(#)ccomdefs.h 1.3 03/06/15 Copyright 2000 J. Schilling */ +/* + * Various compiler dependant macros. + * + * Copyright (c) 2000 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. + */ + +#ifndef _CCOMDEFS_H +#define _CCOMDEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Compiler-dependent macros to declare that functions take printf-like + * or scanf-like arguments. They are defined to nothing for versions of gcc + * that are not known to support the features properly (old versions of gcc-2 + * didn't permit keeping the keywords out of the application namespace). + */ +#if __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 7 + +#define __printflike__(fmtarg, firstvararg) +#define __printf0like__(fmtarg, firstvararg) +#define __scanflike__(fmtarg, firstvararg) + +#else /* We found GCC that supports __attribute__ */ + +#define __printflike__(fmtarg, firstvararg) \ + __attribute__((__format__(__printf__, fmtarg, firstvararg))) +#define __printf0like__(fmtarg, firstvararg) \ + __attribute__((__format__(__printf0__, fmtarg, firstvararg))) + +/* + * FreeBSD GCC implements printf0 that allows the format string to + * be a NULL pointer. + */ +#if __FreeBSD_cc_version < 300001 +#undef __printf0like__ +#define __printf0like__ __printflike__ +#endif + +#define __scanflike__(fmtarg, firstvararg) \ + __attribute__((__format__(__scanf__, fmtarg, firstvararg))) + +#endif /* GNUC */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CCOMDEFS_H */ diff --git a/include/deflts.h b/include/deflts.h new file mode 100644 index 0000000..097047b --- /dev/null +++ b/include/deflts.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006 Eduard Bloch + * + * Config parsing code, with interface similar to basic libdeflt interface + * from J. Schilling but with different semantics + * + * get_value uses a static buffer (warning, non-reentrant) + * cfg_open and cfg_close maintain a static FILE pointer (warning, non-reentrant) + * + */ +/* + * 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. + */ + +#ifndef _DEFLTS_H +#define _DEFLTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* FIXME: use inline trough an INLINE macro wrapper */ +extern int cfg_open (const char *name); +extern int cfg_close (void); + +/* reset the position in FILE */ +extern void cfg_restart (void); +/* returns the next value found after the current position */ +extern char *cfg_get_next (const char *name); +/* equivalent to cfg_restart(); cfg_get_next(...) */ +extern char *cfg_get(const char *key); +/* function wrapped by those above */ +extern char *get_value(FILE *srcfile, const char *key, int dorewind); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/device.h b/include/device.h new file mode 100644 index 0000000..a3c8c92 --- /dev/null +++ b/include/device.h @@ -0,0 +1,162 @@ +/* + * 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. + * + */ + +/* @(#)device.h 1.13 05/01/24 Copyright 1995 J. Schilling */ +/* + * Generic header for users of major(), minor() and makedev() + * + * Copyright (c) 1995 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. + */ + +#ifndef _DEVICE_H +#define _DEVICE_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +/* + * On generic SVR4, major is a function (defined in sys/mkdev.h). + * On Solaris it is defined ... + * As we cannot just test if major is #define'd, we have to + * define _FOUND_MAJOR_ instead. + * + * WARNING: Do never include <sys/sysmacros.h> in SVR4, it contains + * an old definition for major()/minor() defining 8 minorbits. + * Use <sys/mkdev.h> instead. + */ +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif +/* + * Some systems define major in <sys/types.h>. + * We are ready... + */ +#ifdef major +# define _FOUND_MAJOR_ +#endif + +#ifdef MAJOR_IN_MKDEV +# ifndef _INCL_SYS_MKDEV_H +# include <sys/mkdev.h> +# define _INCL_SYS_MKDEV_H +# endif + /* + * Interix doesn't use makedev(); it uses mkdev() + */ +# if !defined(makedev) && defined(mkdev) +# define makedev(a,b) mkdev((a),(b)) +# endif +# define _FOUND_MAJOR_ +#endif + +#ifndef _FOUND_MAJOR_ +# ifdef MAJOR_IN_SYSMACROS +# ifndef _INCL_SYS_SYSMACROS_H +# include <sys/sysmacros.h> +# define _INCL_SYS_SYSMACROS_H +# endif +# define _FOUND_MAJOR_ +# endif +#endif + +/* + * If we are on HP/UX before HP/UX 8, + * major/minor are not in <sys/sysmacros.h>. + */ +#ifndef _FOUND_MAJOR_ +# if defined(hpux) || defined(__hpux__) || defined(__hpux) +# ifndef _INCL_SYS_MKOD_H +# include <sys/mknod.h> +# define _INCL_SYS_MKOD_H +# endif +# define _FOUND_MAJOR_ +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * For all other systems define major()/minor() here. + * XXX Check if this definition will be usefull for ms dos too. + */ +#ifndef _FOUND_MAJOR_ +# define major(dev) (((dev) >> 8) & 0xFF) +# define minor(dev) ((dev) & 0xFF) +# define makedev(majo, mino) (((majo) << 8) | (mino)) +#endif + +/* + * Don't pollute namespace... + */ +#undef _FOUND_MAJOR_ + +#ifdef __XDEV__ +/* + * The following defines are currently only needed for 'star'. + * We make it conditional code to avoid to pollute the namespace. + */ +#define XDEV_T unsigned long + +extern int minorbits; +extern XDEV_T minormask; +extern XDEV_T _dev_mask[]; + +#define dev_major(dev) (((XDEV_T)(dev)) >> minorbits) +#define _dev_major(mbits, dev) (((XDEV_T)(dev)) >> (mbits)) + +#define dev_minor(dev) (((XDEV_T)(dev)) & minormask) +#define _dev_minor(mbits, dev) (((XDEV_T)(dev)) & _dev_mask[(mbits)]) + + +#define dev_make(majo, mino) ((((XDEV_T)(majo)) << minorbits) | \ + ((XDEV_T)(mino))) +#define _dev_make(mbits, majo, mino) ((((XDEV_T)(majo)) << (mbits) | \ + ((XDEV_T)(mino))) + +extern void dev_init(BOOL debug); +#ifndef dev_major +extern XDEV_T dev_major(XDEV_T dev); +extern XDEV_T _dev_major(int mbits, XDEV_T dev); +extern XDEV_T dev_minor(XDEV_T dev); +extern XDEV_T _dev_minor(int mbits, XDEV_T dev); +extern XDEV_T dev_make(XDEV_T majo, XDEV_T mino); +extern XDEV_T _dev_make(int mbits, XDEV_T majo, XDEV_T mino); +#endif + +#endif /* __XDEV__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DEVICE_H */ diff --git a/include/dirdefs.h b/include/dirdefs.h new file mode 100644 index 0000000..fa966ab --- /dev/null +++ b/include/dirdefs.h @@ -0,0 +1,188 @@ +/* + * 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. + * + */ + +/* @(#)dirdefs.h 1.15 04/06/16 Copyright 1987, 1998 J. Schilling */ +/* + * Copyright (c) 1987, 1998 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. + */ + +#ifndef _DIRDEFS_H +#define _DIRDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef JOS +# ifndef _INCL_SYS_STYPES_H +# include <sys/stypes.h> +# define _INCL_SYS_STYPES_H +# endif +# ifndef _INCL_SYS_FILEDESC_H +# include <sys/filedesc.h> +# define _INCL_SYS_FILEDESC_H +# endif +# define NEED_READDIR +# define dirent _direct +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) +# define DIRSIZE 30 +# define FOUND_DIRSIZE + typedef struct _dirent { + char name[DIRSIZE]; + short ino; + } dirent; + +#else /* !JOS */ + +# ifndef _INCL_SYS_TYPES_H +# include <sys/types.h> +# define _INCL_SYS_TYPES_H +# endif +# ifndef _INCL_SYS_STAT_H +# include <sys/stat.h> +# define _INCL_SYS_STAT_H +# endif +# ifdef HAVE_LIMITS_H +# ifndef _INCL_LIMITS_H +# include <limits.h> +# define _INCL_LIMITS_H +# endif +# endif +# ifdef HAVE_SYS_PARAM_H +# ifndef _INCL_SYS_PARAM_H +# include <sys/param.h> +# define _INCL_SYS_PARAM_H +# endif +# endif + +# ifdef HAVE_DIRENT_H /* This a POSIX compliant system */ +# ifndef _INCL_DIRENT_H +# include <dirent.h> +# define _INCL_DIRENT_H +# endif +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) +# define _FOUND_DIR_ +# else /* This is a Pre POSIX system */ + +# define dirent direct +# define DIR_NAMELEN(dirent) (dirent)->d_namlen + +# if defined(HAVE_SYS_DIR_H) +# ifndef _INCL_SYS_DIR_H +# include <sys/dir.h> +# define _INCL_SYS_DIR_H +# endif +# define _FOUND_DIR_ +# endif + +# if defined(HAVE_NDIR_H) && !defined(_FOUND_DIR_) +# ifndef _INCL_NDIR_H +# include <ndir.h> +# define _INCL_NDIR_H +# endif +# define _FOUND_DIR_ +# endif + +# if defined(HAVE_SYS_NDIR_H) && !defined(_FOUND_DIR_) +# ifndef _INCL_SYS_NDIR_H +# include <sys/ndir.h> +# define _INCL_SYS_NDIR_H +# endif +# define _FOUND_DIR_ +# endif +# endif /* HAVE_DIRENT_H */ + +# if defined(_FOUND_DIR_) +/* + * Don't use defaults here to allow recognition of problems. + */ +# ifdef MAXNAMELEN +# define DIRSIZE MAXNAMELEN /* From sys/param.h */ +# define FOUND_DIRSIZE +# else +# ifdef MAXNAMLEN +# define DIRSIZE MAXNAMLEN /* From dirent.h */ +# define FOUND_DIRSIZE +# else +# ifdef DIRSIZ +# define DIRSIZE DIRSIZ /* From sys/dir.h */ +# define FOUND_DIRSIZE +# endif +# endif +# endif +# else /* !_FOUND_DIR_ */ + +# define NEED_DIRENT +# define NEED_READDIR +# define dirent _direct +# define DIR_NAMELEN(dirent) strlen((dirent)->d_name) + +# endif /* _FOUND_DIR_ */ + + +#ifdef NEED_DIRENT + +#ifndef FOUND_DIRSIZE +#define DIRSIZE 14 /* The old UNIX standard value */ +#define FOUND_DIRSIZE +#endif + +typedef struct _dirent { + short ino; + char name[DIRSIZE]; +} dirent; + +#endif /* NEED_DIRENT */ + +#endif /* !JOS */ + +#ifdef NEED_READDIR + typedef struct __dirdesc { + FILE *dd_fd; + } DIR; + + struct _direct { + unsigned long d_ino; + unsigned short d_reclen; + unsigned short d_namlen; + char d_name[DIRSIZE +1]; + }; + +extern DIR *opendir(); +extern closedir(); +extern struct dirent *readdir(); + +#endif /* NEED_READDIR */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DIRDEFS_H */ diff --git a/include/fctldefs.h b/include/fctldefs.h new file mode 100644 index 0000000..d382e68 --- /dev/null +++ b/include/fctldefs.h @@ -0,0 +1,93 @@ +/* + * 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. + * + */ + +/* @(#)fctldefs.h 1.13 03/02/23 Copyright 1996 J. Schilling */ +/* + * Generic header for users of open(), creat() and chmod() + * + * Copyright (c) 1996 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. + */ + +#ifndef _FCTLDEFS_H +#define _FCTLDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _STATDEFS_H +#include <statdefs.h> /* For 3rd arg of open() and chmod() */ +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> /* Needed for fcntl.h */ +#define _INCL_SYS_TYPES_H +#endif + +#ifdef HAVE_SYS_FILE_H +/* + * Historical systems with flock() only need sys/file.h + */ +# ifndef _INCL_SYS_FILE_H +# include <sys/file.h> +# define _INCL_SYS_FILE_H +# endif +#endif +#ifdef HAVE_FCNTL_H +# ifndef _INCL_FCNTL_H +# include <fcntl.h> +# define _INCL_FCNTL_H +#endif +#endif + +/* + * Do not define more than O_RDONLY / O_WRONLY / O_RDWR / O_BINARY + * The values may differ. + * + * O_BINARY is defined here to allow all applications to compile on a non DOS + * environment without repeating this definition. + */ +#ifndef O_RDONLY +# define O_RDONLY 0 +#endif +#ifndef O_WRONLY +# define O_WRONLY 1 +#endif +#ifndef O_RDWR +# define O_RDWR 2 +#endif +#ifndef O_BINARY /* Only present on DOS or similar */ +# define O_BINARY 0 +#endif +#ifndef O_NDELAY /* This is undefined on BeOS :-( */ +# define O_NDELAY 0 +#endif + +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + +#endif /* _FCTLDEFS_H */ diff --git a/include/getargs.h b/include/getargs.h new file mode 100644 index 0000000..6aa36b0 --- /dev/null +++ b/include/getargs.h @@ -0,0 +1,67 @@ +/* + * 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. + * + */ + +/* @(#)getargs.h 1.10 04/09/25 Copyright 1985 J. Schilling */ +/* + * Definitions for getargs()/getallargs()/getfiles() + * + * Copyright (c) 1985 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. + */ + +#ifndef _GETARGS_H +#define _GETARGS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define NOARGS 0 /* No more args */ +#define NOTAFLAG 1 /* Not a flag type argument */ +#define BADFLAG (-1) /* Not a valid flag argument */ +#define BADFMT (-2) /* Error in format string */ +#define NOTAFILE (-3) /* Seems to be a flag type */ + +typedef int (*getargfun)(const void *, void *); + +/* + * Keep in sync with schily.h + */ +extern int getallargs(int *, char * const**, const char *, ...); +extern int getargs(int *, char * const**, const char *, ...); +extern int getfiles(int *, char * const**, const char *); + +#ifdef __cplusplus +} +#endif + +#endif /* _GETARGS_H */ diff --git a/include/getcwd.h b/include/getcwd.h new file mode 100644 index 0000000..462a43c --- /dev/null +++ b/include/getcwd.h @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +/* @(#)getcwd.h 1.3 01/07/15 Copyright 1998 J. Schilling */ +/* + * Definitions for getcwd() + * + * Copyright (c) 1998 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. + */ + +#ifndef _GETCWD_H +#define _GETCWD_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef JOS +# ifndef _INCL_SYS_STYPES_H +# include <sys/stypes.h> +# define _INCL_SYS_STYPES_H +# endif + extern char *gwd(); +# define getcwd(b, len) gwd(b) +#else +# ifndef HAVE_GETCWD +# define getcwd(b, len) getwd(b) +# endif +#endif + +#endif /* _GETCWD_H */ diff --git a/include/glibc_elf.h b/include/glibc_elf.h new file mode 100644 index 0000000..ae640d5 --- /dev/null +++ b/include/glibc_elf.h @@ -0,0 +1,2558 @@ +/* + * This file has been modified for inclusion into the cdrkit package. + */ + +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _ELF_H +#define _ELF_H 1 + +/* Standard ELF types. */ + +#include <inttypes.h> +#include <sys/types.h> + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; + +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_LINUX 3 /* Linux. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_NUM 95 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_BEFORE 0xff00 /* Order section before all others + (Solaris). */ +#define SHN_AFTER 0xff01 /* Order section after all others + (Solaris). */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + + +/* How to extract and insert information held in the st_other field. */ + +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) + +/* For ELF64 the definitions are the same. */ +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) + +/* Symbol visibility specification encoded in the st_other field. */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct*/ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 10 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ + +/* Auxialiary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard <elf.h> file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + long int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ +#define AT_CLKTCK 17 /* Frequency of times() */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored. */ + +#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ + +/* Pointer to the global system page used for system calls and other + nice things. */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains + log2 of line size; mask those to get cache size. */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define ELF_NOTE_ABI 1 + +/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI + note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 +#define ELF_NOTE_OS_FREEBSD 3 + + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) + + +/* Motorola 68k specific definitions. */ + +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +/* Keep this the last entry. */ +#define R_68K_NUM 23 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* Keep this the last entry. */ +#define R_386_NUM 38 + +/* SUN SPARC specific definitions. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +/* Keep this the last entry. */ +#define R_SPARC_NUM 80 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* Bits present in AT_HWCAP, primarily for Sparc32. */ + +#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ +#define HWCAP_SPARC_ULTRA3 32 +#define HWCAP_SPARC_BLKINIT 64 /* Sun4v with block-init/load-twin. */ + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* The following are non-official names and should not be used. */ + +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +/* Keep this the last entry. */ +#define R_MIPS_NUM 38 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +#define DT_MIPS_NUM 0x32 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 +/* Keep this the last entry. */ +#define R_ALPHA_NUM 46 + +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + + +/* PowerPC specific declarations */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* PowerPC relocations defined for the TLS access ABI. */ +#define R_PPC_TLS 67 /* none (sym+add)@tls */ +#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ +#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ +#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ +#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ +#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ +#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ +#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ +#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ +#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ + +/* Keep this the last entry. */ +#define R_PPC_NUM 95 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ + +/* PowerPC64 relocations defined for the TLS access ABI. */ +#define R_PPC64_TLS 67 /* none (sym+add)@tls */ +#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ +#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ +#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ +#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ +#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ +#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ +#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ +#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ +#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ +#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ +#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ +#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ +#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ +#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ +#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ +#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ +#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ + +/* Keep this the last entry. */ +#define R_PPC64_NUM 107 + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_OPD (DT_LOPROC + 1) +#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +#define DT_PPC64_NUM 3 + + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 + +/* Additional symbol types for Thumb */ +#define STT_ARM_TFUNC 0xd + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ + +/* ARM relocs. */ +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +#define R_390_TLS_GDCALL 38 /* Tag for function call in general + dynamic TLS code. */ +#define R_390_TLS_LDCALL 39 /* Tag for function call in local + dynamic TLS code. */ +#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic + thread local data. */ +#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic + thread local data. */ +#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS + block. */ +#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS + block. */ +#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS + block. */ +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ +/* Keep this the last entry. */ +#define R_390_NUM 61 + + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 + + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ + +#define R_X86_64_NUM 24 + + +/* AM33 relocations. */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ + +#define R_MN10300_NUM 24 + + +/* M32R relocs. */ +#define R_M32R_NONE 0 /* No reloc. */ +#define R_M32R_16 1 /* Direct 16 bit. */ +#define R_M32R_32 2 /* Direct 32 bit. */ +#define R_M32R_24 3 /* Direct 24 bit. */ +#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +#define R_M32R_LO16 9 /* Low 16 bit. */ +#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +#define R_M32R_GNU_VTINHERIT 11 +#define R_M32R_GNU_VTENTRY 12 +/* M32R relocs use SHT_RELA. */ +#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +#define R_M32R_RELA_GNU_VTINHERIT 43 +#define R_M32R_RELA_GNU_VTENTRY 44 + +#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +#define R_M32R_COPY 50 /* Copy symbol at runtime */ +#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +#define R_M32R_RELATIVE 53 /* Adjust by program base */ +#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned + low */ +#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed + low */ +#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to + GOT with unsigned low */ +#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to + GOT with signed low */ +#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to + GOT */ +#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT + with unsigned low */ +#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT + with signed low */ +#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +#define R_M32R_NUM 256 /* Keep this the last entry. */ + + +#endif /* elf.h */ diff --git a/include/intcvt.h b/include/intcvt.h new file mode 100644 index 0000000..12ef59a --- /dev/null +++ b/include/intcvt.h @@ -0,0 +1,124 @@ +/* + * 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. + * + */ + +/* @(#)intcvt.h 1.4 03/12/29 Copyright 1986-2003 J. Schilling */ +/* + * Definitions for conversion to/from integer data types of various size. + * + * Copyright (c) 1986-2003 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. + */ + +#ifndef _INTCVT_H +#define _INTCVT_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#define i_to_2_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[1] = (i) & 0xFF) + +#define i_to_3_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[2] = (i) & 0xFF) + +#define i_to_4_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[3] = (i) & 0xFF) + + + +#define a_to_byte(a) (((Int8_t *) a)[0]) + +#define a_to_u_byte(a) ((UInt8_t) \ + (((Uchar *) a)[0] & 0xFF)) + +#define a_to_u_2_byte(a) ((UInt16_t) \ + ((((Uchar *) a)[1] & 0xFF) | \ + (((Uchar *) a)[0] << 8 & 0xFF00))) + +#define a_to_2_byte(a) (int)(Int16_t)a_to_u_2_byte(a) + +#define a_to_u_3_byte(a) ((Ulong) \ + ((((Uchar *) a)[2] & 0xFF) | \ + (((Uchar *) a)[1] << 8 & 0xFF00) | \ + (((Uchar *) a)[0] << 16 & 0xFF0000))) + +#define a_to_3_byte(a) a_to_u_3_byte(a) /* XXX Is there a signed version ? */ + +#ifdef __STDC__ +# define __TOP_4BYTE 0xFF000000UL +#else +# define __TOP_4BYTE 0xFF000000 +#endif + +#define a_to_u_4_byte(a) ((Ulong) \ + ((((Uchar*) a)[3] & 0xFF) | \ + (((Uchar*) a)[2] << 8 & 0xFF00) | \ + (((Uchar*) a)[1] << 16 & 0xFF0000) | \ + (((Uchar*) a)[0] << 24 & __TOP_4BYTE))) + +#define a_to_4_byte(a) (long)(Int32_t)a_to_u_4_byte(a) + +/* + * Little Endian versions of above macros + */ +#define li_to_2_byte(a, i) (((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[0] = (i) & 0xFF) + +#define li_to_3_byte(a, i) (((Uchar *)(a))[2] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[0] = (i) & 0xFF) + +#define li_to_4_byte(a, i) (((Uchar *)(a))[3] = ((i) >> 24)& 0xFF,\ + ((Uchar *)(a))[2] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[0] = (i) & 0xFF) + + +#define la_to_u_2_byte(a) ((UInt16_t) \ + ((((Uchar*) a)[0] & 0xFF) | \ + (((Uchar*) a)[1] << 8 & 0xFF00))) + +#define la_to_2_byte(a) (int)(Int16_t)la_to_u_2_byte(a) + +#define la_to_u_3_byte(a) ((Ulong) \ + ((((Uchar*) a)[0] & 0xFF) | \ + (((Uchar*) a)[1] << 8 & 0xFF00) | \ + (((Uchar*) a)[2] << 16 & 0xFF0000))) + +#define la_to_3_byte(a) la_to_u_3_byte(a) /* XXX Is there a signed version ? */ + +#define la_to_u_4_byte(a) ((Ulong) \ + ((((Uchar*) a)[0] & 0xFF) | \ + (((Uchar*) a)[1] << 8 & 0xFF00) | \ + (((Uchar*) a)[2] << 16 & 0xFF0000) | \ + (((Uchar*) a)[3] << 24 & __TOP_4BYTE))) + +#define la_to_4_byte(a) (long)(Int32_t)la_to_u_4_byte(a) + +#endif /* _INTCVT_H */ diff --git a/include/jmpdefs.h b/include/jmpdefs.h new file mode 100644 index 0000000..d9d2db0 --- /dev/null +++ b/include/jmpdefs.h @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +/* @(#)jmpdefs.h 1.2 00/11/08 Copyright 1999 J. Schilling */ +/* + * Definitions that help to handle a jmp_buf + * + * Copyright (c) 1998 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. + */ + +#ifndef _JMPDEFS_H +#define _JMPDEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + jmp_buf jb; +} jmps_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _JMPDEFS_H */ diff --git a/include/libport.h b/include/libport.h new file mode 100644 index 0000000..2d5930f --- /dev/null +++ b/include/libport.h @@ -0,0 +1,124 @@ +/* + * 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. + * + */ + +/* @(#)libport.h 1.9 03/06/15 Copyright 1995 J. Schilling */ +/* + * Copyright (c) 1995 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. + */ + + +#ifndef _LIBPORT_H +#define _LIBPORT_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif +#ifndef _STANDARD_H +#include <standard.h> +#endif + +/* + * Try to get HOST_NAME_MAX for gethostname() + */ +#ifndef _UNIXSTD_H +#include <unixstd.h> +#endif + +#ifndef HOST_NAME_MAX +#if defined(HAVE_NETDB_H) && !defined(HOST_NOT_FOUND) && \ + !defined(_INCL_NETDB_H) +#include <netdb.h> +#define _INCL_NETDB_H +#endif +#ifdef MAXHOSTNAMELEN +#define HOST_NAME_MAX MAXHOSTNAMELEN +#endif +#endif + +#ifndef HOST_NAME_MAX +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> /* Include various defs needed with some OS */ + /* Linux MAXHOSTNAMELEN */ +#endif +#ifdef MAXHOSTNAMELEN +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX MAXHOSTNAMELEN +#endif +#endif +#endif + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSERVER +/* + * Don't use the usleep() from libc on SCO's OPENSERVER. + * It will kill our processes with SIGALRM. + */ +/* + * Don't #undef HAVE_USLEEP in this file, SCO has a + * usleep() prototype in unistd.h + */ +/*#undef HAVE_USLEEP*/ +#endif + +#ifndef HAVE_GETHOSTID +extern long gethostid(void); +#endif +#ifndef HAVE_GETHOSTNAME +extern int gethostname(char *name, int namelen); +#endif +#ifndef HAVE_GETDOMAINNAME +extern int getdomainname(char *name, int namelen); +#endif +#ifndef HAVE_GETPAGESIZE +int getpagesize(void); +#endif +#ifndef HAVE_USLEEP +extern int usleep(int usec); +#endif + +#if !defined(HAVE_STRDUP) || defined(__SVR4) +extern char *strdup(const char *s); +#endif + +#ifndef HAVE_RENAME +extern int rename(const char *old, const char *new); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBPORT_H */ diff --git a/include/librmt.h b/include/librmt.h new file mode 100644 index 0000000..9264216 --- /dev/null +++ b/include/librmt.h @@ -0,0 +1,75 @@ +/* + * 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. + * + */ + +/* @(#)librmt.h 1.16 03/06/15 Copyright 1996 J. Schilling */ +/* + * Prototypes for rmt client subroutines + * + * Copyright (c) 1995,1996,2000-2002 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. + */ + +#ifndef _LIBRMT_H +#define _LIBRMT_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#include <rmtio.h> + +/* + * remote.c + */ +extern void rmtinit(int (*errmsgn)(int, const char *, ...), + void (*eexit)(int)); +extern int rmtdebug(int dlevel); +extern char *rmtfilename(char *name); +extern char *rmthostname(char *hostname, int hnsize, char *rmtspec); +extern int rmtgetconn(char *host, int trsize, int excode); +extern int rmtopen(int fd, char *fname, int fmode); +extern int rmtclose(int fd); +extern int rmtread(int fd, char *buf, int count); +extern int rmtwrite(int fd, char *buf, int count); +extern off_t rmtseek(int fd, off_t offset, int whence); +extern int rmtioctl(int fd, int cmd, int count); +#ifdef MTWEOF +extern int rmtstatus(int fd, struct mtget *mtp); +#endif +extern int rmtxstatus(int fd, struct rmtget *mtp); +#ifdef MTWEOF +extern void _rmtg2mtg(struct mtget *mtp, struct rmtget *rmtp); +extern int _mtg2rmtg(struct rmtget *rmtp, struct mtget *mtp); +#endif + +#endif /* _LIBRMT_H */ diff --git a/include/maxpath.h b/include/maxpath.h new file mode 100644 index 0000000..a26cfe4 --- /dev/null +++ b/include/maxpath.h @@ -0,0 +1,86 @@ +/* + * 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. + * + */ + +/* @(#)maxpath.h 1.6 03/08/23 Copyright 1985, 1995, 1998 J. Schilling */ +/* + * Definitions for dealing with statically limitations on pathnames + * + * Copyright (c) 1985, 1995, 1998 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. + */ + +#ifndef _MAXPATH_H +#define _MAXPATH_H + +#ifndef _DIRDEFS_H +#include <dirdefs.h> /* Includes mconfig.h if needed */ +#endif + +#ifdef JOS +#ifndef _JOS_MAXP_H +# include <jos_maxp.h> +#endif +# define FOUND_MAXPATHNAME +# define FOUND_MAXFILENAME +#else + +# ifdef MAXPATHLEN +# define MAXPATHNAME MAXPATHLEN /* From sys/param.h */ +# define FOUND_MAXPATHNAME +# else +# ifdef PATH_MAX +# define MAXPATHNAME PATH_MAX /* From limits.h */ +# define FOUND_MAXPATHNAME +# else +# define MAXPATHNAME 256 /* Is there a limit? */ +# endif +# endif + +/* + * Don't use defaults here to allow recognition of problems. + */ +# ifdef MAXNAMELEN +# define MAXFILENAME MAXNAMELEN /* From sys/param.h */ +# define FOUND_MAXFILENAME +# else +# ifdef MAXNAMLEN +# define MAXFILENAME MAXNAMLEN /* From dirent.h */ +# define FOUND_MAXFILENAME +# else +# ifdef DIRSIZ +# define MAXFILENAME DIRSIZ /* From sys/dir.h */ +# define FOUND_MAXFILENAME +# endif +# endif +# endif + +#if !defined(FOUND_MAXFILENAME) && defined(FOUND_DIRSIZE) +# define MAXFILENAME DIRSIZE /* From dirdefs.h */ +# define FOUND_MAXFILENAME +#endif + +#endif /* JOS */ + +#endif /* _MAXPATH_H */ diff --git a/include/mconfig.h b/include/mconfig.h new file mode 100644 index 0000000..ee356ec --- /dev/null +++ b/include/mconfig.h @@ -0,0 +1,487 @@ +/* + * 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. + * + */ + +/* @(#)mconfig.h 1.50 04/07/11 Copyright 1995 J. Schilling */ +/* + * definitions for machine configuration + * + * Copyright (c) 1995 J. Schilling + * + * This file must be included before any other file. + * If this file is not included before stdio.h you will not be + * able to get LARGEFILE support + * + * Use only cpp instructions. + * + * NOTE: SING: (Schily Is Not Gnu) + */ +/* + * 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. + */ + +#ifndef _MCONFIG_H +#define _MCONFIG_H + +/* whatever, just shut up */ +#define __sccsid "forked version from cdrkit" +#define _sccsid "forked version from cdrkit" + +/* + * This hack that is needed as long as VMS has no POSIX shell. + */ +#ifdef VMS +# define USE_STATIC_CONF +#endif + +#ifdef USE_STATIC_CONF +#include <xmconfig.h> /* This is the current static autoconf stuff */ +#else +#include <xconfig.h> /* This is the current dynamic autoconf stuff */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The NetBSD people want to bother us. + * They removed the definition for 'unix' and are bleating for every test + * for #if defined(unix). So we need to check for NetBSD early. + */ +#ifndef IS_UNIX +# if defined(__NetBSD__) +# define IS_UNIX +# endif +#endif + +#ifndef IS_UNIX +# if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__DJGPP__) +# define IS_UNIX +# endif +#endif + +#ifdef __MSDOS__ +# define IS_MSDOS +#endif + +#if defined(tos) || defined(__tos) +# define IS_TOS +#endif + +#ifdef THINK_C +# define IS_MAC +#endif + +#if defined(sun) || defined(__sun) || defined(__sun__) +# define IS_SUN +#endif + +#if defined(__CYGWIN32__) || defined(__CYGWIN__) +# define IS_GCC_WIN32 +# define IS_CYGWIN + +#if defined(unix) || defined(_X86) +# define IS_CYGWIN_1 +#endif +#endif + +/*--------------------------------------------------------------------------*/ +/* + * Some magic that cannot (yet) be figured out with autoconf. + */ + +#if defined(sun3) || defined(mc68000) || defined(mc68020) +# ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +# endif +#endif +#ifdef sparc +# ifndef HAVE_LDSTUB +# define HAVE_LDSTUB +# endif +# ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +# endif +#endif +#if defined(__i386_) || defined(i386) +# ifndef HAVE_XCHG +# define HAVE_XCHG +# endif +# ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +# endif +#endif + +/* + * Use of SCANSTACK is disabled by default + */ +#ifndef USE_SCANSTACK +# undef HAVE_SCANSTACK +#else +/* + * But .... + * The tests are much better now, so always give it a chance. + */ +#ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +#endif +#endif + +/* + * Allow to overwrite the defines in the makefiles by calling + * + * make COPTX=-DFORCE_SCANSTACK + */ +#ifdef FORCE_SCANSTACK +# undef NO_SCANSTACK +#ifndef HAVE_SCANSTACK +# define HAVE_SCANSTACK +#endif +#ifndef USE_SCANSTACK +# define USE_SCANSTACK +#endif +#endif + +/* + * This is the global switch to deactivate stack scanning + */ +#ifdef NO_SCANSTACK +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +#ifdef NO_FORK +# ifdef HAVE_FORK +# undef HAVE_FORK +# endif +# ifdef HAVE_VFORK +# undef HAVE_VFORK +# endif +#endif +#ifdef NO_VFORK +# ifdef HAVE_VFORK +# undef HAVE_VFORK +# endif +#endif + +#if defined(SOL2) || defined(SOL2) || \ + defined(S5R4) || defined(__S5R4) || defined(SVR4) +# ifndef __SVR4 +# define __SVR4 +# endif +#endif + +#ifdef __SVR4 +# ifndef SVR4 +# define SVR4 +# endif +#endif + +/* + * SunOS 4.x / SunOS 5.x + */ +#if defined(IS_SUN) +# define HAVE_GETAV0 +#endif + +/* + * AIX + */ +#if defined(_IBMR2) || defined(_AIX) +# ifndef IS_UNIX +# define IS_UNIX /* ??? really ??? */ +# endif +#endif + +/* + * QNX + */ +#if defined(__QNX__) +# ifndef IS_UNIX +# define IS_UNIX +# endif +#endif + +/* + * Silicon Graphics (must be before SVR4) + */ +#if defined(sgi) || defined(__sgi) +# define __NOT_SVR4__ /* Not a real SVR4 implementation */ +#endif + +/* + * Data General + */ +#if defined(__DGUX__) +#ifdef XXXXXXX +# undef HAVE_MTGET_DSREG +# undef HAVE_MTGET_RESID +# undef HAVE_MTGET_FILENO +# undef HAVE_MTGET_BLKNO +#endif +# define mt_type mt_model +# define mt_dsreg mt_status1 +# define mt_erreg mt_status2 + /* + * DGUX hides its flock as dg_flock. + */ +# define HAVE_FLOCK +# define flock dg_flock + /* + * Use the BSD style wait on DGUX to get the resource usages of child + * processes. + */ +# define _BSD_WAIT_FLAVOR +#endif + +/* + * Apple Rhapsody (This is the name for Mac OS X beta) + */ +#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody +# define HAVE_OSDEF /* prevent later definitions to overwrite current */ +# ifndef IS_UNIX +# define IS_UNIX +# endif +#endif + +/* + * NextStep + */ +#if defined(__NeXT__) && !defined(HAVE_OSDEF) +#define NO_PRINT_OVR +#undef HAVE_USG_STDIO /* + * NeXT Step 3.x uses __flsbuf(unsigned char, FILE *) + * instead of __flsbuf(int, FILE *) + */ +# ifndef IS_UNIX +# define IS_UNIX +# endif +#endif + +/* + * Mac OS X + */ +#if defined(__APPLE__) && defined(__MACH__) +# ifndef IS_UNIX +# define IS_UNIX +# endif +# define IS_MACOS_X +#endif + +/* + * NextStep 3.x has a broken linker that does not allow us to override + * these functions. + */ +#ifndef __OPRINTF__ + +#ifdef NO_PRINT_OVR +# define printf Xprintf +# define fprintf Xfprintf +# define sprintf Xsprintf +#endif + +#endif /* __OPRINTF__ */ + +/*--------------------------------------------------------------------------*/ +/* + * If there is no flock defined by the system, use emulation + * through fcntl record locking. + */ +#ifndef HAVE_FLOCK +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* don't block when locking */ +#define LOCK_UN 8 /* unlock */ +#endif + +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +/* + * gcc 2.x generally implements the long long type. + */ +#ifdef __GNUC__ +# if __GNUC__ > 1 +# ifndef HAVE_LONGLONG +# define HAVE_LONGLONG +# endif +# endif +#endif + +/* + * Convert to GNU name + */ +#ifdef HAVE_STDC_HEADERS +# ifndef STDC_HEADERS +# define STDC_HEADERS +# endif +#endif +/* + * Convert to SCHILY name + */ +#ifdef STDC_HEADERS +# ifndef HAVE_STDC_HEADERS +# define HAVE_STDC_HEADERS +# endif +#endif + +#ifdef IS_UNIX +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define far +# define near +#endif + +/* + * Win32 with Gygwin + */ +#ifdef IS_GCC_WIN32 +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define HAVE_DOS_DRIVELETTER +# define far +# define near +# define NEED_O_BINARY +#endif + +/* + * Win32 with Mingw32 + */ +#ifdef __MINGW32__ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER +# define far +# define near +# define NEED_O_BINARY +#endif + +/* + * OS/2 EMX + */ +#ifdef __EMX__ /* We don't want to call it UNIX */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER +# define far +# define near +# define NEED_O_BINARY +#endif + +#ifdef __BEOS__ /* We don't want to call it UNIX */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define far +# define near +#endif + +/* + * DOS with DJGPP + */ +#ifdef __DJGPP__ /* We don't want to call it UNIX */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER + +# define NEED_O_BINARY +#endif + +/* + * Vanilla DOS + */ +#if defined(IS_MSDOS) && !defined(__DJGPP__) +# define HAVE_PATH_DELIM +# define PATH_DELIM '\\' +# define PATH_DELIM_STR "\\" +# define PATH_ENV_DELIM ';' +# define PATH_ENV_DELIM_STR ";" +# define HAVE_DOS_DRIVELETTER + +# define NEED_O_BINARY +#endif + +/* + * ATARI TOS + */ +#ifdef IS_TOS +# define HAVE_PATH_DELIM +# define PATH_DELIM '\\' +# define PATH_DELIM_STR "\\" +# define PATH_ENV_DELIM ',' +# define PATH_ENV_DELIM_STR "," +# define HAVE_DOS_DRIVELETTER +# define far +# define near +#endif + +/* + * Mac OS 9 + */ +#ifdef IS_MAC +# define HAVE_PATH_DELIM +# define PATH_DELIM ':' +# define PATH_DELIM_STR ":" +# define PATH_ENV_DELIM ';' /* ??? */ +# define PATH_ENV_DELIM_STR ";" /* ??? */ +# define far +# define near +#endif + +/* + * I hope this will make compilation on unknown OS easier. + */ +#ifndef HAVE_PATH_DELIM /* Default to POSIX rules */ +# define HAVE_PATH_DELIM +# define PATH_DELIM '/' +# define PATH_DELIM_STR "/" +# define PATH_ENV_DELIM ':' +# define PATH_ENV_DELIM_STR ":" +# define far +# define near +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _MCONFIG_H */ diff --git a/include/mmapdefs.h b/include/mmapdefs.h new file mode 100644 index 0000000..82d5256 --- /dev/null +++ b/include/mmapdefs.h @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +/* @(#)mmapdefs.h 1.1 01/02/25 Copyright 2001 J. Schilling */ +/* + * Definitions to be used for mmap() + * + * Copyright (c) 2001 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. + */ + +#ifndef _MMAPDEFS_H +#define _MMAPDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#if defined(HAVE_SMMAP) + +#ifndef _INCL_SYS_MMAN_H +#include <sys/mman.h> +#define _INCL_SYS_MMAN_H +#endif + +#ifndef MAP_ANONYMOUS +# ifdef MAP_ANON +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif + +#ifndef MAP_FILE +# define MAP_FILE 0 /* Needed on Apollo Domain/OS */ +#endif + +/* + * Needed for Apollo Domain/OS and may be for others? + */ +#ifdef _MMAP_WITH_SIZEP +# define mmap_sizeparm(s) (&(s)) +#else +# define mmap_sizeparm(s) (s) +#endif + +#endif /* defined(HAVE_SMMAP) */ + +#endif /* _MMAPDEFS_H */ diff --git a/include/patmatch.h b/include/patmatch.h new file mode 100644 index 0000000..20ddc77 --- /dev/null +++ b/include/patmatch.h @@ -0,0 +1,116 @@ +/* + * 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. + * + */ + +/* @(#)patmatch.h 1.10 03/08/24 Copyright 1985 J. Schilling */ + +#ifndef _PATMATCH_H +#define _PATMATCH_H +/* + * Definitions for the pattern matching functions. + * + * Copyright (c) 1985,1995 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. + */ +/* + * The pattern matching functions are based on the algorithm + * presented by Martin Richards in: + * + * "A Compact Function for Regular Expression Pattern Matching", + * Software-Practice and Experience, Vol. 9, 527-534 (1979) + * + * Several changes have been made to the original source which has been + * written in BCPL: + * + * '/' is replaced by '!' (to allow UNIX filenames) + * '(',')' are replaced by '{', '}' + * '\'' is replaced by '\\' (UNIX compatible quote) + * + * Character classes have been added to allow "[<character list>]" + * to be used. + * Start of line '^' and end of line '$' have been added. + * + * Any number in the following comment is zero or more occurrencies + */ +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALT '!' /* Alternation in match i.e. this!that!the_other */ +#define REP '#' /* Any number of occurrences of the following expr */ +#define NIL '%' /* Empty string (exactly nothing) */ +#define STAR '*' /* Any number of any character (equivalent of #?) */ +#define ANY '?' /* Any one character */ +#define QUOTE '\\' /* Quotes the next character */ +#define LBRACK '{' /* Begin of precedence grouping */ +#define RBRACK '}' /* End of precedence grouping */ +#define LCLASS '[' /* Begin of character set */ +#define RCLASS ']' /* End of character set */ +#define NOT '^' /* If first in set: invert set content */ +#define RANGE '-' /* Range notation in sets */ +#define START '^' /* Begin of a line */ +#define END '$' /* End of a line */ + +/* + * A list of case statements that may be used for a issimple() or ispattern() + * funtion that checks whether a string conrtains characters that need the + * pattern matcher. + * + * Note that this list does not contain NOT or RANGE because you need + * LCLASS and RCLASS in addition. + */ +#define casePAT case ALT: case REP: case NIL: case STAR: case ANY: \ + case QUOTE: case LBRACK: case RBRACK: \ + case LCLASS: case RCLASS: case START: case END: + + +#define MAXPAT 128 /* Maximum length of pattern */ + +extern int patcompile(const unsigned char *__pat, int __patlen, int *__aux); + +extern unsigned char *opatmatch(const unsigned char *__pat, const int *__aux, + const unsigned char *__str, int __soff, + int __slen, int __alt); +extern unsigned char *opatlmatch(const unsigned char *__pat, const int *__aux, + const unsigned char *__str, int __soff, + int __slen, int __alt); +extern unsigned char *patmatch(const unsigned char *__pat, const int *__aux, + const unsigned char *__str, int __soff, + int __slen, int __alt, int __state[]); +extern unsigned char *patlmatch(const unsigned char *__pat, const int *__aux, + const unsigned char *__str, int __soff, + int __slen, int __alt, int __state[]); + +#ifdef __cplusplus +} +#endif + +#endif /* _PATMATCH_H */ diff --git a/include/prototyp.h b/include/prototyp.h new file mode 100644 index 0000000..70d06ca --- /dev/null +++ b/include/prototyp.h @@ -0,0 +1,106 @@ +/* + * 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. + * + */ + +/* @(#)prototyp.h 1.11 03/08/23 Copyright 1995 J. Schilling */ +/* + * Definitions for dealing with ANSI / KR C-Compilers + * + * Copyright (c) 1995 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. + */ + +/* + * mconfig.h includes prototype.h so we must do this include before we test + * for _PROTOTYP_H + */ +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _PROTOTYP_H +#define _PROTOTYP_H + +#ifndef PROTOTYPES + /* + * If this has already been defined, + * someone else knows better than us... + */ +# ifdef __STDC__ +# if __STDC__ /* ANSI C */ +# define PROTOTYPES +# endif +# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */ +# define PROTOTYPES +# endif +# endif +#endif /* PROTOTYPES */ + +#if !defined(PROTOTYPES) && (defined(__cplusplus) || defined(_MSC_VER)) + /* + * C++ always supports prototypes. + * Define PROTOTYPES so we are not forced to make + * a separtate autoconf run for C++ + * + * Microsoft C has prototypes but does not define __STDC__ + */ +# define PROTOTYPES +#endif + +/* + * If we have prototypes, we should have stdlib.h string.h stdarg.h + */ +#ifdef PROTOTYPES +#if !(defined(SABER) && defined(sun)) +# ifndef HAVE_STDARG_H +# define HAVE_STDARG_H +# endif +#endif +#ifndef JOS +# ifndef HAVE_STDLIB_H +# define HAVE_STDLIB_H +# endif +# ifndef HAVE_STRING_H +# define HAVE_STRING_H +# endif +# ifndef HAVE_STDC_HEADERS +# define HAVE_STDC_HEADERS +# endif +# ifndef STDC_HEADERS +# define STDC_HEADERS /* GNU name */ +# endif +#endif +#endif + +#ifdef NO_PROTOTYPES /* Force not to use prototypes */ +# undef PROTOTYPES +#endif + +#ifdef PROTOTYPES +# define __PR(a) a +#else +# define __PR(a) () +#endif + +#endif /* _PROTOTYP_H */ diff --git a/include/rmtio.h b/include/rmtio.h new file mode 100644 index 0000000..1bf46ec --- /dev/null +++ b/include/rmtio.h @@ -0,0 +1,167 @@ +/* + * 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. + * + */ + +/* @(#)rmtio.h 1.5 03/06/15 Copyright 1995,2000 J. Schilling */ +/* + * Definition for enhanced remote tape IO + * + * Copyright (c) 1995,2000-2002 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. + */ + +#ifndef _RMTIO_H +#define _RMTIO_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _UTYPES_H +#include <utypes.h> +#endif + +/* + * values for mt_op + */ +#define RMTWEOF 0 /* write an end-of-file record */ +#define RMTFSF 1 /* forward space over file mark */ +#define RMTBSF 2 /* backward space over file mark (1/2" only ) */ +#define RMTFSR 3 /* forward space to inter-record gap */ +#define RMTBSR 4 /* backward space to inter-record gap */ +#define RMTREW 5 /* rewind */ +#define RMTOFFL 6 /* rewind and put the drive offline */ +#define RMTNOP 7 /* no operation, sets status only */ + +#ifdef __needed__ +#define MTRETEN 8 /* retension the tape (cartridge tape only) */ +#define MTERASE 9 /* erase the entire tape */ +#define MTEOM 10 /* position to end of media */ +#define MTNBSF 11 /* backward space file to BOF */ + +#define MTSRSZ 12 /* set record size */ +#define MTGRSZ 13 /* get record size */ +#define MTLOAD 14 /* for loading a tape (use o_delay to open */ + /* the tape device) */ +#endif + +/* + * Definitions for the new RMT Protocol version 1 + * + * The new Protocol version tries to make the use + * of rmtioctl() more portable between different platforms. + */ +#define RMTIVERSION -1 /* Opcode to request version */ +#define RMT_NOVERSION -1 /* Old version code */ +#define RMT_VERSION 1 /* New (current) version code */ + +/* + * Support for commands bejond MTWEOF..MTNOP (0..7) + */ +#define RMTICACHE 0 /* enable controller cache */ +#define RMTINOCACHE 1 /* disable controller cache */ +#define RMTIRETEN 2 /* retension the tape (cartridge tape only) */ +#define RMTIERASE 3 /* erase the entire tape */ +#define RMTIEOM 4 /* position to end of media */ +#define RMTINBSF 5 /* backward space file to BOF */ + +/* + * Old MTIOCGET copies a binary version of struct mtget back + * over the wire. This is highly non portable. + * MTS_* retrieves ascii versions (%d format) of a single + * field in the struct mtget. + * NOTE: MTS_ERREG may only be valid on the first call and + * must be retrived first. + */ +#define MTS_TYPE 'T' /* mtget.mt_type */ +#define MTS_DSREG 'D' /* mtget.mt_dsreg */ +#define MTS_ERREG 'E' /* mtget.mt_erreg */ +#define MTS_RESID 'R' /* mtget.mt_resid */ +#define MTS_FILENO 'F' /* mtget.mt_fileno */ +#define MTS_BLKNO 'B' /* mtget.mt_blkno */ +#define MTS_FLAGS 'f' /* mtget.mt_flags */ +#define MTS_BF 'b' /* mtget.mt_bf */ + +/* + * structure for remote MTIOCGET - mag tape get status command + */ +struct rmtget { + Llong mt_type; /* type of magtape device */ + /* the following two registers are grossly device dependent */ + Llong mt_dsreg; /* ``drive status'' register */ + Int32_t mt_dsreg1; /* ``drive status'' register */ + Int32_t mt_dsreg2; /* ``drive status'' register */ + Llong mt_gstat; /* ``generic status'' register */ + Llong mt_erreg; /* ``error'' register */ + /* optional error info. */ + Llong mt_resid; /* residual count */ + Llong mt_fileno; /* file number of current position */ + Llong mt_blkno; /* block number of current position */ + Llong mt_flags; + Llong mt_gflags; /* generic flags */ + long mt_bf; /* optimum blocking factor */ + int mt_xflags; /* eXistence flags for struct members */ +}; + +/* + * Values for mt_xflags + */ +#define RMT_TYPE 0x0001 /* mt_type/mt_model present */ +#define RMT_DSREG 0x0002 /* mt_dsreg present */ +#define RMT_DSREG1 0x0004 /* mt_dsreg1 present */ +#define RMT_DSREG2 0x0008 /* mt_dsreg2 present */ +#define RMT_GSTAT 0x0010 /* mt_gstat present */ +#define RMT_ERREG 0x0020 /* mt_erreg present */ +#define RMT_RESID 0x0040 /* mt_resid present */ +#define RMT_FILENO 0x0080 /* mt_fileno present */ +#define RMT_BLKNO 0x0100 /* mt_blkno present */ +#define RMT_FLAGS 0x0200 /* mt_flags present */ +#define RMT_BF 0x0400 /* mt_bf present */ +#define RMT_COMPAT 0x0800 /* Created from old compat data */ + +/* + * values for mt_flags + */ +#define RMTF_SCSI 0x01 +#define RMTF_REEL 0x02 +#define RMTF_ASF 0x04 +#define RMTF_TAPE_HEAD_DIRTY 0x08 +#define RMTF_TAPE_CLN_SUPPORTED 0x10 + +/* + * these are recommended + */ +#ifdef __needed__ +#define MT_ISQIC 0x32 /* generic QIC tape drive */ +#define MT_ISREEL 0x33 /* generic reel tape drive */ +#define MT_ISDAT 0x34 /* generic DAT tape drive */ +#define MT_IS8MM 0x35 /* generic 8mm tape drive */ +#define MT_ISOTHER 0x36 /* generic other type of tape drive */ + +/* more Sun devices */ +#define MT_ISTAND25G 0x37 /* sun: SCSI Tandberg 2.5 Gig QIC */ +#define MT_ISDLT 0x38 /* sun: SCSI DLT tape drive */ +#define MT_ISSTK9840 0x39 /* sun: STK 9840 (Ironsides) */ +#endif + +#endif /* _RMTIO_H */ diff --git a/include/schily.h b/include/schily.h new file mode 100644 index 0000000..ec7cbb4 --- /dev/null +++ b/include/schily.h @@ -0,0 +1,288 @@ +/* + * 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. + * + */ + +/* @(#)schily.h 1.54 06/01/12 Copyright 1985-2006 J. Schilling */ +/* + * Definitions for libschily + * + * This file should be included past: + * + * mconfig.h / config.h + * standard.h + * stdio.h + * stdlib.h (better use stdxlib.h) + * unistd.h (better use unixstd.h) needed LARGEFILE support + * string.h + * sys/types.h + * + * If you need stdio.h, you must include it before schily.h + * + * NOTE: If you need ctype.h and did not include stdio.h you need to + * include ctype.h past schily.h as OpenBSD does not follow POSIX and + * defines EOF in ctype.h + * + * Copyright (c) 1985-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. + * + * 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. + */ + +#ifndef _SCHILY_H +#define _SCHILY_H + +#ifndef _STANDARD_H +#include <standard.h> +#endif +#ifndef _CCOMDEFS_H +#include <ccomdefs.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_INCL_SYS_TYPES_H) || defined(off_t) +# ifndef FOUND_OFF_T +# define FOUND_OFF_T +# endif +#endif +#if defined(_INCL_SYS_TYPES_H) || defined(size_t) +# ifndef FOUND_SIZE_T +# define FOUND_SIZE_T +# endif +#endif + +#ifdef __never_def__ +/* + * It turns out that we cannot use the folloginw definition because there are + * some platforms that do not behave application friendly. These are mainly + * BSD-4.4 based systems (which #undef a definition when size_t is available. + * We actually removed this code because of a problem with QNX Neutrino. + * For this reason, it is important not to include <sys/types.h> directly but + * via the Schily SING include files so we know whether it has been included + * before we come here. + */ +#if defined(_SIZE_T) || defined(_T_SIZE_) || defined(_T_SIZE) || \ + defined(__SIZE_T) || defined(_SIZE_T_) || \ + defined(_GCC_SIZE_T) || defined(_SIZET_) || \ + defined(__sys_stdtypes_h) || defined(___int_size_t_h) || defined(size_t) + +#ifndef FOUND_SIZE_T +# define FOUND_SIZE_T /* We already included a size_t definition */ +#endif +#endif +#endif /* __never_def__ */ + +#if defined(HAVE_LARGEFILES) +# define _fcons _fcons64 +# define fdup fdup64 +# define fileluopen fileluopen64 +# define fileopen fileopen64 +# define filemopen filemopen64 +# define filepos filepos64 +# define filereopen filereopen64 +# define fileseek fileseek64 +# define filesize filesize64 +# define filestat filestat64 +# define _openfd _openfd64 +#endif + +#ifdef EOF /* stdio.h has been included */ +extern int _cvmod(const char *, int *, int *); +extern FILE *_fcons(FILE *, int, int); +extern FILE *fdup(FILE *); +extern int fdown(FILE *); +extern int rols_fexecl(const char *, FILE *, FILE *, FILE *, const char *, ...); +extern int rols_fexecle(const char *, FILE *, FILE *, FILE *, const char *, ...); + /* 6th arg not const, fexecv forces av[ac] = NULL */ +extern int rols_fexecv(const char *, FILE *, FILE *, FILE *, int, char **); +extern int rols_fexecve(const char *, FILE *, FILE *, FILE *, char * const *, + char * const *); +extern int fspawnv(FILE *, FILE *, FILE *, int, char * const *); +extern int fspawnl(FILE *, FILE *, FILE *, const char *, const char *, ...); +extern int fspawnv_nowait(FILE *, FILE *, FILE *, const char *, int, + char *const*); +extern int rols_fgetline(FILE *, char *, int); +extern int fgetstr(FILE *, char *, int); +extern void file_raise(FILE *, int); +extern int fileclose(FILE *); +extern FILE *fileluopen(int, const char *); +extern FILE *fileopen(const char *, const char *); +#ifdef _INCL_SYS_TYPES_H +extern FILE *filemopen(const char *, const char *, mode_t); +#endif +#ifdef FOUND_OFF_T +extern off_t filepos(FILE *); +#endif +extern int fileread(FILE *, void *, int); +extern int ffileread(FILE *, void *, int); +extern FILE *filereopen(const char *, const char *, FILE *); +#ifdef FOUND_OFF_T +extern int fileseek(FILE *, off_t); +extern off_t filesize(FILE *); +#endif +#ifdef S_IFMT +extern int filestat(FILE *, struct stat *); +#endif +extern int filewrite(FILE *, void *, int); +extern int ffilewrite(FILE *, void *, int); +extern int flush(void); +extern int fpipe(FILE **); +extern int getbroken(FILE *, char *, char, char **, int); +extern int ofindline(FILE *, char, const char *, int, char **, int); +extern int peekc(FILE *); + +#ifdef __never_def__ +/* + * We cannot define this or we may get into problems with DOS based systems. + */ +extern int spawnv(FILE *, FILE *, FILE *, int, char * const *); +extern int spawnl(FILE *, FILE *, FILE *, const char *, const char *, ...); +extern int spawnv_nowait(FILE *, FILE *, FILE *, const char *, int, + char *const*); +#endif /* __never_def__m */ +#endif /* EOF */ + +extern int _niread(int, void *, int); +extern int _niwrite(int, void *, int); +extern int _nixread(int, void *, int); +extern int _nixwrite(int, void *, int); +extern int _openfd(const char *, int); +extern int on_comerr(void (*fun)(int, void *), void *arg); +/*PRINTFLIKE1*/ +extern void comerr(const char *, ...) __printflike__(1, 2); +/*PRINTFLIKE2*/ +extern void comerrno(int, const char *, ...) __printflike__(2, 3); +/*PRINTFLIKE1*/ +extern int errmsg(const char *, ...) __printflike__(1, 2); +/*PRINTFLIKE2*/ +extern int errmsgno(int, const char *, ...) __printflike__(2, 3); +#ifdef FOUND_SIZE_T +/*PRINTFLIKE3*/ +extern int serrmsg(char *, size_t, const char *, ...) __printflike__(3, 4); +/*PRINTFLIKE4*/ +extern int serrmsgno(int, char *, size_t, const char *, ...) __printflike__(4, 5); +#endif +extern void comexit(int); +extern char *errmsgstr(int); +/*PRINTFLIKE1*/ +extern int schily_error(const char *, ...) __printflike__(1, 2); +extern char *fillbytes(void *, int, char); +extern char *findbytes(const void *, int, char); +extern int findline(const char *, char, const char *, int, char **, int); +extern int rols_getline(char *, int); +extern int getstr(char *, int); +extern int breakline(char *, char, char **, int); +extern int getallargs(int *, char * const**, const char *, ...); +extern int getargs(int *, char * const**, const char *, ...); +extern int getfiles(int *, char * const**, const char *); +extern char *astoi(const char *, int *); +extern char *astol(const char *, long *); +extern char *astolb(const char *, long *, int base); +#ifdef _UTYPES_H +extern char *astoll(const char *, Llong *); +extern char *astollb(const char *, Llong *, int); +extern char *astoull(const char *, Ullong *); +extern char *astoullb(const char *, Ullong *, int); +#endif + +/*extern void handlecond __PR((const char *, SIGBLK *, int(*)(const char *, long, long), long));*/ +/*extern void unhandlecond __PR((SIGBLK *));*/ + +extern int patcompile(const unsigned char *, int, int *); +extern unsigned char *patmatch(const unsigned char *, const int *, + const unsigned char *, int, int, int, int[]); +extern unsigned char *patlmatch(const unsigned char *, const int *, + const unsigned char *, int, int, int, int[]); + +extern char *movebytes(const void *, void *, int); + +extern void save_args(int, char **); +extern int saved_ac(void); +extern char **saved_av(void); +extern char *saved_av0(void); +#ifndef seterrno +extern int seterrno(int); +#endif +extern void set_progname(const char *); +extern char *get_progname(void); + +extern void setfp(void * const *); +extern int wait_chld(int); /* for fspawnv_nowait() */ +extern int geterrno(void); +extern void raisecond(const char *, long); +extern char *strcatl(char *, ...); +extern int streql(const char *, const char *); +#ifdef va_arg +extern int format(void (*)(char, long), long, const char *, va_list); +#else +extern int format(void (*)(char, long), long, const char *, void *); +#endif + +extern int ftoes(char *, double, int, int); +extern int ftofs(char *, double, int, int); + +extern void swabbytes(void *, int); +extern char **getmainfp(void); +extern char **getavp(void); +extern char *getav0(void); +extern void **getfp(void); +extern int flush_reg_windows(int); +extern int cmpbytes(const void *, const void *, int); +extern int cmpnullbytes(const void *, int); + +#ifdef nonono +#if defined(HAVE_LARGEFILES) +/* + * To allow this, we need to figure out how to do autoconfiguration for off64_t + */ +extern FILE *_fcons64(FILE *, int, int); +extern FILE *fdup64(FILE *); +extern FILE *fileluopen64(int, const char *); +extern FILE *fileopen64(const char *, const char *); +#ifdef FOUND_OFF_T +extern off64_t filepos64(FILE *); +#endif +extern FILE *filereopen64(const char *, const char *, FILE *); +#ifdef FOUND_OFF_T +extern int fileseek64(FILE *, off64_t); +extern off64_t filesize64(FILE *); +#endif +#ifdef S_IFMT +extern int filestat64(FILE *, struct stat *); +#endif +extern int _openfd64(const char *, int); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#if defined(_JOS) || defined(JOS) +# ifndef _JOS_IO_H +# include <jos_io.h> +# endif +#endif + +#endif /* _SCHILY_H */ diff --git a/include/sigblk.h b/include/sigblk.h new file mode 100644 index 0000000..afb125a --- /dev/null +++ b/include/sigblk.h @@ -0,0 +1,80 @@ +/* + * 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. + * + */ + +/* @(#)sigblk.h 1.10 03/07/10 Copyright 1985, 1995-2003 J. Schilling */ +/* + * software signal block definition + * + * Copyright (c) 1985, 1995-2003 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. + */ + +#ifndef _SIGBLK_H +#define _SIGBLK_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _STANDARD_H +#include <standard.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sigblk { + long **sb_savfp; /* Real saved framepointer */ + struct sigblk *sb_signext; /* Next sw signal blk for this func */ + short sb_siglen; /* Strlen for sb_signame */ + const char *sb_signame; /* Name of software signal */ + + /* sb_sigfun: function to call */ + int (*sb_sigfun)(const char *, long, long); + + long sb_sigarg; /* Second arg for sb_sigfun */ +} SIGBLK; + +/* + * The handler function is called with three arguments: + * + * 1) The name of the software signal + * 2) The argument from the handlecond() call + * 3) The argument from the raisecond() call + */ +typedef int (*handlefunc_t)(const char *, long, long); + +extern void handlecond(const char *, SIGBLK *, + int(*)(const char *, long, long), + long); +extern void raisecond(const char *, long); +extern void starthandlecond(SIGBLK *); +extern void unhandlecond(SIGBLK *); + +#ifdef __cplusplus +} +#endif + +#endif /* _SIGBLK_H */ diff --git a/include/sigdefs.h b/include/sigdefs.h new file mode 100644 index 0000000..8e8ba7e --- /dev/null +++ b/include/sigdefs.h @@ -0,0 +1,81 @@ +/* + * 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. + * + */ + +/* @(#)sigdefs.h 1.5 02/01/19 Copyright 1997 J. Schilling */ +/* + * Signal abstraction for BSD/SVR4 signals + * + * Copyright (c) 1997 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. + */ + +#ifndef _SIGDEFS_H +#define _SIGDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef HAVE_SIGSET +/* + * Try to by default use the function that sets up signal handlers in a way + * that does not reset the handler after it has been called. + */ +#define signal sigset +#endif + +#ifdef HAVE_SIGPROCMASK +#define block_sigs(a) { \ + sigset_t __new; \ + \ + sigfillset(&__new); \ + sigprocmask(SIG_BLOCK, &__new, &a);\ + } +#define unblock_sig(s) { \ + sigset_t __new; \ + \ + sigemptyset(&__new); \ + sigaddset(&__new, (s)); \ + sigprocmask(SIG_UNBLOCK, &__new, NULL);\ + } +#define restore_sigs(a) sigprocmask(SIG_SETMASK, &a, 0); + +#else /* !HAVE_SIGPROCMASK */ + +#define sigset_t int +#define block_sigs(a) a = sigblock(0xFFFFFFFF) +#define restore_sigs(a) sigsetmask(a); +#define unblock_sig(s) { \ + int __old, __new; \ + \ + block_sigs(__old); \ + __new = sigmask(s); \ + __new = __old & ~__new; \ + sigsetmask(__new); \ + } + +#endif /* HAVE_SIGPROCMASK */ + +#endif /* _SIGDEFS_H */ diff --git a/include/standard.h b/include/standard.h new file mode 100644 index 0000000..d884973 --- /dev/null +++ b/include/standard.h @@ -0,0 +1,165 @@ +/* + * 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. + * + */ + +/* @(#)standard.h 1.31 03/08/23 Copyright 1985 J. Schilling */ +/* + * standard definitions + * + * This file should be included past: + * + * mconfig.h / config.h + * stdio.h + * stdlib.h (better use stdxlib.h) + * unistd.h (better use unixstd.h) needed LARGEFILE support + * + * If you need stdio.h, you must include it before standard.h + * + * Copyright (c) 1985 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. + */ + +#ifndef _STANDARD_H +#define _STANDARD_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifdef M68000 +# ifndef tos +# define JOS 1 +# endif +#endif + +/* + * fundamental constants + */ +#ifndef NULL +# define NULL 0 +#endif +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +/* + * Program exit codes + */ +#define EX_BAD (-1) + +/* + * standard storage class definitions + */ +#define GLOBAL extern +#define IMPORT extern +#define EXPORT +#define INTERN static +#define LOCAL static +#define FAST register + +#ifndef PROTOTYPES +# ifndef const +# define const +# endif +# ifndef signed +# define signed +# endif +# ifndef volatile +# define volatile +# endif +#endif /* PROTOTYPES */ + +/* + * standard type definitions + * + * The hidden Schily BOOL definition is used in case we need to deal + * with other BOOL defines on systems we like to port to. + */ +typedef int __SBOOL; +typedef int BOOL; +#ifdef JOS +# ifndef __GNUC__ +# define NO_VOID +# endif +#endif +#ifdef NO_VOID + typedef int VOID; +# ifndef lint + typedef int void; +# endif +#else + typedef void VOID; +#endif + +#if defined(_INCL_SYS_TYPES_H) || defined(off_t) +# ifndef FOUND_OFF_T +# define FOUND_OFF_T +# endif +#endif +#if defined(_INCL_SYS_TYPES_H) || defined(size_t) +# ifndef FOUND_SIZE_T +# define FOUND_SIZE_T +# endif +#endif + +#ifdef __never_def__ +/* + * It turns out that we cannot use the folloginw definition because there are + * some platforms that do not behave application friendly. These are mainly + * BSD-4.4 based systems (which #undef a definition when size_t is available. + * We actually removed this code because of a problem with QNX Neutrino. + * For this reason, it is important not to include <sys/types.h> directly but + * via the Schily SING include files so we know whether it has been included + * before we come here. + */ +#if defined(_SIZE_T) || defined(_T_SIZE_) || defined(_T_SIZE) || \ + defined(__SIZE_T) || defined(_SIZE_T_) || \ + defined(_GCC_SIZE_T) || defined(_SIZET_) || \ + defined(__sys_stdtypes_h) || defined(___int_size_t_h) || defined(size_t) + +#ifndef FOUND_SIZE_T +# define FOUND_SIZE_T /* We already included a size_t definition */ +#endif +#endif +#endif /* __never_def__ */ + +#if defined(_JOS) || defined(JOS) +# ifndef _SCHILY_H +# include <schily.h> +# endif + +# ifndef _JOS_DEFS_H +# include <jos_defs.h> +# endif + +# ifndef _JOS_IO_H +# include <jos_io.h> +# endif +#endif + +#endif /* _STANDARD_H */ diff --git a/include/statdefs.h b/include/statdefs.h new file mode 100644 index 0000000..cfaa96d --- /dev/null +++ b/include/statdefs.h @@ -0,0 +1,350 @@ +/* + * 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. + * + */ + +/* @(#)statdefs.h 1.9 03/06/15 Copyright 1998 J. Schilling */ +/* + * Definitions for stat() file mode + * + * Copyright (c) 1998 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. + */ + +#ifndef _STATDEFS_H +#define _STATDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> /* Needed for sys/stat.h */ +#define _INCL_SYS_TYPES_H +#endif +#ifndef _INCL_SYS_STAT_H +#include <sys/stat.h> /* For S_IS* and S_IF* */ +#define _INCL_SYS_STAT_H +#endif + +/* + * Apollo Domain/OS has a broken sys/stat.h that defines + * S_IFIFO == S_IFSOCK and creates trouble if the constants + * are used as case labels. + */ +#if S_IFIFO == S_IFSOCK +# undef S_IFSOCK +#endif + +#ifdef STAT_MACROS_BROKEN +#undef S_ISFIFO /* Named pipe */ +#undef S_ISCHR /* Character special */ +#undef S_ISMPC /* UNUSED multiplexed c */ +#undef S_ISDIR /* Directory */ +#undef S_ISNAM /* Named file (XENIX) */ +#undef S_ISBLK /* Block special */ +#undef S_ISMPB /* UNUSED multiplexed b */ +#undef S_ISREG /* Regular file */ +#undef S_ISCNT /* Contiguous file */ +#undef S_ISLNK /* Symbolic link */ +#undef S_ISSHAD /* Solaris shadow inode */ +#undef S_ISSOCK /* UNIX domain socket */ +#undef S_ISDOOR /* Solaris DOOR */ +#undef S_ISWHT /* BSD whiteout */ +#undef S_ISEVC /* UNOS eventcount */ +#endif + +#ifndef S_ISFIFO /* 1 Named pipe */ +# ifdef S_IFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# else +# define S_ISFIFO(m) (0) +# endif +#endif +#ifndef S_ISCHR /* 2 Character special */ +# ifdef S_IFCHR +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# else +# define S_ISCHR(m) (0) +# endif +#endif +#ifndef S_ISMPC /* 3 UNUSED multiplexed char */ +# ifdef S_IFMPC +# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) +# else +# define S_ISMPC(m) (0) +# endif +#endif +#ifndef S_ISDIR /* 4 Directory */ +# ifdef S_IFDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# else +# define S_ISDIR(m) (0) +# endif +#endif +#ifndef S_ISNAM /* 5 Named file (XENIX) */ +# ifdef S_IFNAM +# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) +# else +# define S_ISNAM(m) (0) +# endif +#endif +#ifndef S_ISBLK /* 6 Block special */ +# ifdef S_IFBLK +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# else +# define S_ISBLK(m) (0) +# endif +#endif +#ifndef S_ISMPB /* 7 UNUSED multiplexed block */ +# ifdef S_IFMPB +# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) +# else +# define S_ISMPB(m) (0) +# endif +#endif +#ifndef S_ISREG /* 8 Regular file */ +# ifdef S_IFREG +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +# else +# define S_ISREG(m) (0) +# endif +#endif +#ifndef S_ISCNT /* 9 Contiguous file */ +# ifdef S_IFCNT +# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT) +# else +# define S_ISCNT(m) (0) +# endif +#endif +#ifndef S_ISLNK /* 10 Symbolic link */ +# ifdef S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +# else +# define S_ISLNK(m) (0) +# endif +#endif +#ifndef S_ISSHAD /* 11 Solaris shadow inode */ +# ifdef S_IFSHAD +# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD) +# else +# define S_ISSHAD(m) (0) +# endif +#endif +#ifndef S_ISSOCK /* 12 UNIX domain socket */ +# ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +# else +# define S_ISSOCK(m) (0) +# endif +#endif +#ifndef S_ISDOOR /* 13 Solaris DOOR */ +# ifdef S_IFDOOR +# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) +# else +# define S_ISDOOR(m) (0) +# endif +#endif +#ifndef S_ISWHT /* 14 BSD whiteout */ +# ifdef S_IFWHT +# define S_ISWHT(m) (((m) & S_IFMT) == S_ISWHT) +# else +# define S_ISWHT(m) (0) +# endif +#endif +#ifndef S_IFEVC /* 15 UNOS eventcount */ +# ifdef S_IFEVC +# define S_ISEVC(m) (((m) & S_IFMT) == S_IFEVC) +# else +# define S_ISEVC(m) (0) +# endif +#endif + +#ifndef S_TYPEISMQ +/* + * XXX ??? where is a definition of a message queue ??? + */ +# define S_TYPEISMQ(_stbuf) (0) +#endif +#ifndef S_TYPEISSEM +# ifdef S_INSEM +# define S_TYPEISSEM(_stbuf) (S_ISNAM((_stbuf)->st_mode) && (_stbuf)->st_rdev == S_INSEM) +# else +# define S_TYPEISSEM(_stbuf) (0) +# endif +#endif +#ifndef S_TYPEISSHM +# ifdef S_INSHD +# define S_TYPEISSHM(_stbuf) (S_ISNAM((_stbuf)->st_mode) && (_stbuf)->st_rdev == S_INSHD) +# else +# define S_TYPEISSHM(_stbuf) (0) +# endif +#endif + +/* + * Mode permission bits. + * UNIX V.7 has only S_ISUID/S_ISGID/S_ISVTX and S_IREAD/S_IWRITE/S_IEXEC + */ +#ifndef S_ISUID /* Set-user-ID on execution */ +#define S_ISUID 0 /* If it is not defined, it is not supported */ +#endif +#ifndef S_ISGID /* Set-group-ID on execution */ +#define S_ISGID 0 /* If it is not defined, it is not supported */ +#endif +#ifndef S_ISVTX /* On directories, restricted deletion flag */ +#define S_ISVTX 0 /* If it is not defined, it is not supported */ +#endif + +#ifndef S_IRUSR /* Read permission, owner */ +#ifdef S_IREAD +#define S_IRUSR S_IREAD /* Needed on old UNIX systems */ +#else +#define S_IRUSR 0400 +#endif +#endif +#ifndef S_IWUSR /* Write permission, owner */ +#ifdef S_IWRITE +#define S_IWUSR S_IWRITE /* Needed on old UNIX systems */ +#else +#define S_IWUSR 0200 +#endif +#endif +#ifndef S_IXUSR /* Execute/search permission, owner */ +#ifdef S_IEXEC +#define S_IXUSR S_IEXEC /* Needed on old UNIX systems */ +#else +#define S_IXUSR 0100 +#endif +#endif +#ifndef S_IRGRP /* Read permission, group */ +#ifdef S_IREAD +#define S_IRGRP (S_IREAD >> 3) /* Needed on old UNIX systems */ +#else +#define S_IRGRP 040 +#endif +#endif +#ifndef S_IWGRP /* Write permission, group */ +#ifdef S_IWRITE +#define S_IWGRP (S_IWRITE >> 3) /* Needed on old UNIX systems */ +#else +#define S_IWGRP 020 +#endif +#endif +#ifndef S_IXGRP /* Execute/search permission, group */ +#ifdef S_IEXEC +#define S_IXGRP (S_IEXEC >> 3) /* Needed on old UNIX systems */ +#else +#define S_IXGRP 010 +#endif +#endif +#ifndef S_IROTH /* Read permission, others */ +#ifdef S_IREAD +#define S_IROTH (S_IREAD >> 6) /* Needed on old UNIX systems */ +#else +#define S_IROTH 004 +#endif +#endif +#ifndef S_IWOTH /* Write permission, others */ +#ifdef S_IWRITE +#define S_IWOTH (S_IWRITE >> 6) /* Needed on old UNIX systems */ +#else +#define S_IWOTH 002 +#endif +#endif +#ifndef S_IXOTH /* Execute/search permission, others */ +#ifdef S_IEXEC +#define S_IXOTH (S_IEXEC >> 6) /* Needed on old UNIX systems */ +#else +#define S_IXOTH 001 +#endif +#endif + +#ifndef S_IRWXU /* Read, write, execute/search by owner */ +#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR) +#endif +#ifndef S_IRWXG /* Read, write, execute/search by group */ +#define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP) +#endif +#ifndef S_IRWXO /* Read, write, execute/search by others */ +#define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH) +#endif + +/* + * SCO UnixWare has st_atim.st__tim.tv_nsec but the st_atim.tv_nsec tests also + * succeeds. If we use st_atim.tv_nsec on UnixWare, we get a warning about + * illegal structure usage. For this reason, our code needs to have + * #ifdef HAVE_ST__TIM before #ifdef HAVE_ST_NSEC. + */ +#if defined(HAVE_ST_ATIMENSEC) + +#define stat_ansecs(s) ((s)->st_atimensec) +#define stat_mnsecs(s) ((s)->st_mtimensec) +#define stat_cnsecs(s) ((s)->st_ctimensec) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST_SPARE1) && !defined(_FOUND_STAT_NSECS_) + +#define stat_ansecs(s) ((s)->st_spare1 * 1000) +#define stat_mnsecs(s) ((s)->st_spare2 * 1000) +#define stat_cnsecs(s) ((s)->st_spare3 * 1000) + +#define _FOUND_STAT_USECS_ +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST__TIM) && !defined(_FOUND_STAT_NSECS_) + +#define stat_ansecs(s) ((s)->st_atim.st__tim.tv_nsec) +#define stat_mnsecs(s) ((s)->st_mtim.st__tim.tv_nsec) +#define stat_cnsecs(s) ((s)->st_ctim.st__tim.tv_nsec) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST_NSEC) && !defined(_FOUND_STAT_NSECS_) + +#define stat_ansecs(s) ((s)->st_atim.tv_nsec) +#define stat_mnsecs(s) ((s)->st_mtim.tv_nsec) +#define stat_cnsecs(s) ((s)->st_ctim.tv_nsec) + +#define _FOUND_STAT_NSECS_ +#endif + +#if defined(HAVE_ST_ATIMESPEC) && !defined(_FOUND_STAT_NSECS_) + +#define stat_ansecs(s) ((s)->st_atimespec.tv_nsec) +#define stat_mnsecs(s) ((s)->st_mtimespec.tv_nsec) +#define stat_cnsecs(s) ((s)->st_ctimespec.tv_nsec) + +#define _FOUND_STAT_NSECS_ +#endif + +#if !defined(_FOUND_STAT_NSECS_) +#define stat_ansecs(s) (0) +#define stat_mnsecs(s) (0) +#define stat_cnsecs(s) (0) +#endif + +#endif /* _STATDEFS_H */ diff --git a/include/stdxlib.h b/include/stdxlib.h new file mode 100644 index 0000000..cf377af --- /dev/null +++ b/include/stdxlib.h @@ -0,0 +1,65 @@ +/* + * 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. + * + */ + +/* @(#)stdxlib.h 1.6 01/07/15 Copyright 1996 J. Schilling */ +/* + * Definitions for stdlib + * + * Copyright (c) 1996 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. + */ + +#ifndef _STDXLIB_H +#define _STDXLIB_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef HAVE_STDLIB_H +#ifndef _INCL_STDLIB_H +#include <stdlib.h> +#define _INCL_STDLIB_H +#endif +#else + +extern char *malloc(); +extern char *realloc(); + +extern double atof(); + +#endif /* HAVE_STDLIB_H */ + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef RAND_MAX +#define RAND_MAX 32767 +#endif + +#endif /* _STDXLIB_H */ diff --git a/include/stkframe.h b/include/stkframe.h new file mode 100644 index 0000000..fc1ae22 --- /dev/null +++ b/include/stkframe.h @@ -0,0 +1,101 @@ +/* + * 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. + * + */ + +/* @(#)stkframe.h 1.10 03/06/15 Copyright 1995 J. Schilling */ +/* + * Common definitions for routines that parse the stack frame. + * + * This file has to be fixed if you want to port routines which use getfp(). + * Have a look at struct frame below and use it as a sample, + * the new struct frame must at least contain a member 'fr_savfp'. + */ +/* + * 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. + */ + +#ifndef _STKFRAME_H +#define _STKFRAME_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#if defined(sun) && (defined(SVR4) || defined(__SVR4) || defined(__SVR4__)) + /* + * Solaris 2.x aka SunOS 5.x + */ +# ifdef i386 + /* + * On Solaris 2.1 x86 sys/frame.h is not useful at all + * On Solaris 2.4 x86 sys/frame.h is buggy (fr_savfp is int!!) + */ +# ifndef _INCL_SYS_REG_H +# include <sys/reg.h> +# define _INCL_SYS_REG_H +# endif +# endif +# ifndef _INCL_SYS_FRAME_H +# include <sys/frame.h> +# define _INCL_SYS_FRAME_H +# endif + +#else +# if defined(sun) + /* + * SunOS 4.x + */ +# ifndef _INCL_MACHINE_FRAME_H +# include <machine/frame.h> +# define _INCL_MACHINE_FRAME_H +# endif +# else + /* + * Anything that is not SunOS + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * XXX: I hope this will be useful on other machines (no guarantee) + * XXX: It is taken from a sun Motorola system, but should also be useful + * XXX: on a i386. + * XXX: In general you have to write a sample program, set a breakpoint + * XXX: on a small function and inspect the stackframe with adb. + */ + +struct frame { + struct frame *fr_savfp; /* saved frame pointer */ + int fr_savpc; /* saved program counter */ + int fr_arg[1]; /* array of arguments */ +}; + +#ifdef __cplusplus +} +#endif + +# endif /* ! defined (sun) */ +#endif /* ! defined (sun) && (defined(SVR4) || defined(__SVR4) || defined(__SVR4__)) */ + +#endif /* _STKFRAME_H */ diff --git a/include/strdefs.h b/include/strdefs.h new file mode 100644 index 0000000..36bdcaa --- /dev/null +++ b/include/strdefs.h @@ -0,0 +1,125 @@ +/* + * 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. + * + */ + +/* @(#)strdefs.h 1.8 03/03/09 Copyright 1996 J. Schilling */ +/* + * Definitions for strings + * + * Copyright (c) 1996 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. + */ + +#ifndef _STRDEFS_H +#define _STRDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +/* + * It may be that IBM's AIX has problems when doing + * #include <string.h> + * #include <strings.h> + * So I moved the #include <strings.h> to the top. As the file strings.h + * defines strcasecmp() we may need it... + * + * Note that the only real problem appears if we use rubbish FSF based code that + * #defines _NO_PROTO + */ +#ifdef HAVE_STRINGS_H +#ifndef _INCL_STRINGS_H +#include <strings.h> +#define _INCL_STRINGS_H +#endif +#endif /* HAVE_STRINGS_H */ + + +#ifdef HAVE_STRING_H +#ifndef _INCL_STRING_H +#include <string.h> +#define _INCL_STRING_H +#endif +#else /* HAVE_STRING_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#define NULL 0 +#endif + +extern void *memcpy(void *, const void *, int); +extern void *memmove(void *, const void *, int); +extern char *strcpy(char *, const char *); +extern char *strncpy(char *, const char *, int); + +extern char *strcat(char *, const char *); +extern char *strncat(char *, const char *, int); + +extern int memcmp(const void *, const void *, int); +extern int strcmp(const char *, const char *); +extern int strcoll(const char *, const char *); +extern int strncmp(const char *, const char *, int); +extern int strxfrm(char *, const char *, int); + +extern void *memchr(const void *, int, int); +extern char *strchr(const char *, int); + +extern int strcspn(const char *, const char *); +/*#pragma int_to_unsigned strcspn*/ + +extern char *strpbrk(const char *, const char *); +extern char *strrchr(const char *, int); + +extern int strspn(const char *, const char *); +/*#pragma int_to_unsigned strspn*/ + +extern char *strstr(const char *, const char *); +extern char *strtok(char *, const char *); +extern void *memset(void *, int, int); +extern char *strerror(int); + +extern int strlen(const char *); +/*#pragma int_to_unsigned strlen*/ + +extern void *memccpy(void *, const void *, int, int); + +extern int strcasecmp(const char *, const char *); +extern int strncasecmp(const char *, const char *, int); + +/*#define index strchr*/ +/*#define rindex strrchr*/ + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_STRING_H */ + +#endif /* _STRDEFS_H */ diff --git a/include/termcap.h b/include/termcap.h new file mode 100644 index 0000000..b220b2a --- /dev/null +++ b/include/termcap.h @@ -0,0 +1,73 @@ +/* + * 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. + * + */ + +/* @(#)termcap.h 1.6 03/06/15 Copyright 1995 J. Schilling */ +/* + * Copyright (c) 1995 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. + */ + +#ifndef _TERMCAP_H +#define _TERMCAP_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Flags for tcsetflags() + */ +#define TCF_NO_TC 0x0001 /* Don't follow tc= entries */ +#define TCF_NO_SIZE 0x0002 /* Don't get actual ttysize (li#/co#)*/ +#define TCF_NO_STRIP 0x0004 /* Don't strip down termcap buffer */ + +extern char PC; /* Pad character */ +extern char *BC; /* Backspace if not "\b" from "bc" capability*/ +extern char *UP; /* Cursor up string from "up" capability */ +extern short ospeed; /* output speed coded as in ioctl */ + +extern int tgetent(char *bp, char *name); +extern int tcsetflags(int flags); +extern char *tcgetbuf(void); +extern int tgetnum(char *ent); +extern BOOL tgetflag(char *ent); +extern char *tgetstr(char *ent, char **array); +extern char *tdecode(char *ep, char **array); + +extern int tputs(char *cp, int affcnt, int (*outc)(int c)); +extern char *tgoto(char *cm, int destcol, int destline); + +#ifdef __cplusplus +} +#endif + +#endif /* _TERMCAP_H */ diff --git a/include/test_BITFIELDS_HTOL.c b/include/test_BITFIELDS_HTOL.c new file mode 100644 index 0000000..674c457 --- /dev/null +++ b/include/test_BITFIELDS_HTOL.c @@ -0,0 +1,23 @@ +/* + * 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. + * + */ + +/* test_BITFIELD_HTOL.c derived from cdrtools aclocal.m4 by Joerg Schilling */ +/* Return 1 if bitfields are high-to-low, 0 if bitfields are low-to-high */ +int main() +{ + union { + unsigned char ch; + struct { unsigned char bf1:4, bf2:4; } bf; + } u; + u.ch = 0x12; + return (u.bf.bf1 == 1); +} diff --git a/include/test_VA_LIST_IS_ARRAY.c b/include/test_VA_LIST_IS_ARRAY.c new file mode 100644 index 0000000..2cd80c7 --- /dev/null +++ b/include/test_VA_LIST_IS_ARRAY.c @@ -0,0 +1,21 @@ +/* + * 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. + * + */ + +#include <stdarg.h> + +int main() { + +va_list a, b; + +a = b; +; return 0; } + diff --git a/include/timedefs.h b/include/timedefs.h new file mode 100644 index 0000000..08a9145 --- /dev/null +++ b/include/timedefs.h @@ -0,0 +1,143 @@ +/* + * 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. + * + */ + +/* @(#)timedefs.h 1.13 05/08/22 Copyright 1996 J. Schilling */ +/* + * Generic header for users of time(), gettimeofday() ... + * + * It includes definitions for time_t, struct timeval, ... + * + * Copyright (c) 1996 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. + */ + +#ifndef _TIMEDEFS_H +#define _TIMEDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> /* Needed for time_t */ +#define _INCL_SYS_TYPES_H +#endif + +#ifdef TIME_WITH_SYS_TIME +# ifndef _INCL_SYS_TIME_H +# include <sys/time.h> +# define _INCL_SYS_TIME_H +# endif +# ifndef _INCL_TIME_H +# include <time.h> +# define _INCL_TIME_H +# endif +#else +#ifdef HAVE_SYS_TIME_H +# ifndef _INCL_SYS_TIME_H +# include <sys/time.h> +# define _INCL_SYS_TIME_H +# endif +#else +# ifndef _INCL_TIME_H +# include <time.h> +# define _INCL_TIME_H +# endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__CYGWIN32__) || defined(__EMX__) || defined(__linux__) || defined(__DJGPP__) +/* + * Cygnus defines struct timeval in sys/time.h but not timerclear + * timerclear is defined in windows32/Sockets.h ??? + * + * EMX for OS/2 defines struct timeval in sys/time.h but not timerclear + * + * Linux defines struct timeval in sys/time.h but if __USE_BSD is not + * defined, timerclear is missing. + */ +#ifndef timerclear +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif +#endif + +#ifndef timerclear + +#ifndef VMS +struct timeval { + long tv_sec; + long tv_usec; +}; +#endif + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 + +#endif + +#undef timerfix +#define timerfix1(tvp) while ((tvp)->tv_usec < 0) { \ + (tvp)->tv_sec--; \ + (tvp)->tv_usec += 1000000; \ + } + +#define timerfix2(tvp) while ((tvp)->tv_usec > 1000000) { \ + (tvp)->tv_sec++; \ + (tvp)->tv_usec -= 1000000; \ + } + +#define timerfix(tvp) do { timerfix1(tvp); timerfix2(tvp); } while (0) + +/* + * timersub() and timeradd() are defined on FreeBSD with a different + * interface (3 parameters). + */ +#undef timersub +#define timersub(tvp1, tvp2) do { \ + (tvp1)->tv_sec -= (tvp2)->tv_sec; \ + (tvp1)->tv_usec -= (tvp2)->tv_usec; \ + timerfix1(tvp1); timerfix2(tvp1); \ + } while (0) + +#undef timeradd +#define timeradd(tvp1, tvp2) do { \ + (tvp1)->tv_sec += (tvp2)->tv_sec; \ + (tvp1)->tv_usec += (tvp2)->tv_usec; \ + timerfix1(tvp1); timerfix2(tvp1); \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* _TIMEDEFS_H */ diff --git a/include/ttydefs.h b/include/ttydefs.h new file mode 100644 index 0000000..8eed081 --- /dev/null +++ b/include/ttydefs.h @@ -0,0 +1,131 @@ +/* + * 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. + * + */ + +/* @(#)ttydefs.h 1.26 03/02/28 Copyright 1984-2003 J. Schilling */ +/* + * Terminal driver tty mode handling + * + * Copyright (c) 1984-2003 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. + */ + + +#ifndef _TTYDEFS_H +#define _TTYDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#ifdef JOS +# include <ttymodes.h> +# include <spfcode.h> +#else +#ifdef HAVE_TERMIOS_H +# include <termios.h> +# define _INCL_TERMIOS_H +# ifdef TIOCGETA /* FreeBSD */ +# define TCGETS TIOCGETA +# define TCSETSW TIOCSETAW +# endif +# ifdef TCGETATTR +# define TCGETS TCGETATTR +# define TCSETSW TCSETATTRD +# endif +#else +# ifdef HAVE_TERMIO_H +# include <termio.h> +# define _INCL_TERMIO_H +# ifndef TCGETS +# define termios termio +# define TCGETS TCGETA +# define TCSETSW TCSETAW +# endif +# else +# define USE_V7_TTY +# endif +#endif +#endif + +#if !defined(HAVE_TCGETATTR) || !defined(HAVE_TCSETATTR) +# undef TCSANOW +#endif + +#ifndef TCSANOW +# if !defined(TCGETS) || !defined(TCSETSW) +# define USE_V7_TTY +# endif +#endif + +#if !defined(_INCL_TERMIOS_H) && !defined(_INCL_TERMIO_H) +#ifdef HAVE_SYS_IOCTL_H +# ifndef _INCL_SYS_IOCTl_H +# include <sys/ioctl.h> +# define _INCL_SYS_IOCTL_H +# endif +#endif +#endif + +#ifdef HAVE_SYS_BSDTTY_H +#include <sys/bsdtty.h> +#endif + +#if !defined(TIOCGWINSZ) && ! defined(TIOCGSIZE) +# ifndef _INCL_SYS_IOCTl_H +# include <sys/ioctl.h> +# define _INCL_SYS_IOCTL_H +# endif +#endif + +#ifndef OXTABS /* OS/2 EMX */ +#define OXTABS 0 +#endif +#ifndef XTABS +# ifndef TAB3 /* FreeBSD */ +# define TABDLY OXTABS +# define XTABS OXTABS +# else +# define XTABS TAB3 +# endif +#endif +#ifndef ONLCR /* OS/2 EMX */ +#define ONLCR 0 +#endif +#ifndef OCRNL /* FreeBSD */ +# define OCRNL 0 +#endif +#ifndef ONLRET /* FreeBSD */ +# define ONLRET 0 +#endif +#ifndef _POSIX_VDISABLE +# define _POSIX_VDISABLE 0 +#endif + +#endif /* _TTYDEFS_H */ diff --git a/include/unixstd.h b/include/unixstd.h new file mode 100644 index 0000000..16c8816 --- /dev/null +++ b/include/unixstd.h @@ -0,0 +1,132 @@ +/* + * 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. + * + */ + +/* @(#)unixstd.h 1.12 04/06/17 Copyright 1996 J. Schilling */ +/* + * Definitions for unix system interface + * + * Copyright (c) 1996 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. + */ + +#ifndef _UNIXSTD_H +#define _UNIXSTD_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef HAVE_UNISTD_H + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif +#ifndef _INCL_UNISTD_H +#include <unistd.h> +#define _INCL_UNISTD_H +#endif + +#ifndef _SC_PAGESIZE +#ifdef _SC_PAGE_SIZE /* HP/UX & OSF */ +#define _SC_PAGESIZE _SC_PAGE_SIZE +#endif +#endif + +#else /* HAVE_UNISTD_H */ + +/* + * unistd.h grants things like off_t to be typedef'd. + */ +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#endif /* HAVE_UNISTD_H */ + +#ifndef STDIN_FILENO +# ifdef JOS +# ifndef _JOS_IO_H +# include <jos_io.h> +# endif +# else +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 +# endif +#endif + +#ifndef R_OK +/* Symbolic constants for the "access" routine: */ +#define R_OK 4 /* Test for Read permission */ +#define W_OK 2 /* Test for Write permission */ +#define X_OK 1 /* Test for eXecute permission */ +#define F_OK 0 /* Test for existence of File */ +#endif +#ifndef E_OK +#ifdef HAVE_ACCESS_E_OK +#ifdef EFF_ONLY_OK +#define E_OK EFF_ONLY_OK /* Irix */ +#else +#ifdef EUID_OK +#define E_OK EUID_OK /* UNICOS (0400) */ +#else +#define E_OK 010 /* Test effective uids */ +#endif /* EUID_OK */ +#endif /* EFF_ONLY_OK */ +#else +#define E_OK 0 +#endif /* HAVE_ACCESS_E_OK */ +#endif /* !E_OK */ + +/* Symbolic constants for the "lseek" routine: */ +#ifndef SEEK_SET +#define SEEK_SET 0 /* Set file pointer to "offset" */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* Set file pointer to current plus "offset" */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#if !defined(HAVE_UNISTD_H) || !defined(_POSIX_VERSION) +/* + * Maybe we need a lot more definitions here... + * It is not clear whether we should have prototyped definitions. + */ +extern int access(const char *, int); +extern int close(int); +extern int dup(int); +extern int dup2(int, int); +extern void _exit(int); +extern int link(const char *, const char *); +extern int read(int, void *, size_t); +extern int unlink(const char *); +extern int write(int, void *, size_t); +#endif + +#endif /* _UNIXSTD_H */ diff --git a/include/unls.h b/include/unls.h new file mode 100644 index 0000000..8a5c633 --- /dev/null +++ b/include/unls.h @@ -0,0 +1,85 @@ +/* + * 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. + * + */ + +/* @(#)unls.h 1.6 05/04/21 Copyright 2000-2005 J. Schilling */ +/* + * Definitions fur users of libunls + * + * Copyright (c) 2000-2005 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. + */ + +#ifndef _UNLS_H +#define _UNLS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _PROTOTYP_H +#include <prototyp.h> +#endif + +#ifdef USE_ICONV +#include <iconv.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct unls_unicode { + unsigned char unls_low; /* Low Byte */ + unsigned char unls_high; /* High Byte */ +}; + +struct unls_table { + char *unls_name; /* UNLS charset name */ + unsigned char **unls_uni2cs; /* Unicode -> Charset */ + struct unls_unicode *unls_cs2uni; /* Charset -> Unicode */ + struct unls_table *unls_next; /* Next table */ +#ifdef USE_ICONV + iconv_t iconv_d; +#endif +}; + +extern int init_unls(void); +extern int register_unls(struct unls_table *); +extern int unregister_unls(struct unls_table *); +extern struct unls_table *find_unls(char *); +extern void list_unls(void); +extern struct unls_table *load_unls(char *); +extern void unload_unls(struct unls_table *); +extern struct unls_table *load_unls_default(void); +extern int init_unls_file(char * name); + +#ifdef USE_ICONV +extern int init_nls_iconv(char * name); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _UNLS_H */ diff --git a/include/usal b/include/usal new file mode 120000 index 0000000..02d7e2f --- /dev/null +++ b/include/usal @@ -0,0 +1 @@ +../libusal/usal
\ No newline at end of file diff --git a/include/utimdefs.h b/include/utimdefs.h new file mode 100644 index 0000000..d54af42 --- /dev/null +++ b/include/utimdefs.h @@ -0,0 +1,87 @@ +/* + * 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. + * + */ + +/* @(#)utimdefs.h 1.5 03/06/15 Copyright 2001 J. Schilling */ +/* + * Defines for utimes() / utime() + * + * Copyright (c) 2001 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. + */ + +#ifndef _UTIMDEFS_H +#define _UTIMDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#ifdef HAVE_UTIMES +#ifndef _TIMEDEFS_H +#include <timedefs.h> +#endif +#endif + +#ifdef HAVE_UTIME_H +#ifndef _INCL_UTIME_H +#include <utime.h> +#define _INCL_UTIME_H +#endif +#else +#ifdef HAVE_SYS_UTIME_H +#ifndef _INCL_SYS_UTIME_H +#include <sys/utime.h> +#define _INCL_SYS_UTIME_H +#endif +#else +struct utimbuf { + time_t actime; + time_t modtime; +}; +#endif +#endif + +#ifdef __comment__ +/* + * file.c contains this + * I am not sure if it is really needed. + * It may be a good idea to add a test for HAVE_STRUCT_UTIMBUF + * as in gnutar. + */ +#if (__COHERENT__ >= 0x420) +# include <sys/utime.h> +#else +# include <utime.h> +#endif + +#endif /* __comment__ */ + + +#endif /* _UTIMDEFS_H */ diff --git a/include/utypes.h b/include/utypes.h new file mode 100644 index 0000000..9a4049f --- /dev/null +++ b/include/utypes.h @@ -0,0 +1,440 @@ +/* + * 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. + * + */ + +/* @(#)utypes.h 1.15 05/11/06 Copyright 1997 J. Schilling */ +/* + * Definitions for some user defined types + * + * Copyright (c) 1997 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. + */ + +#ifndef _UTYPES_H +#define _UTYPES_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +/* + * Include limits.h for CHAR_BIT + */ +#ifdef HAVE_LIMITS_H +#ifndef _INCL_LIMITS_H +#include <limits.h> +#define _INCL_LIMITS_H +#endif +#endif + +/* + * Include sys/param.h for NBBY + */ +#ifdef HAVE_SYS_PARAM_H +#ifndef _INCL_SYS_PARAM_H +#include <sys/param.h> +#define _INCL_SYS_PARAM_H +#endif +#endif + +#ifndef CHAR_BIT +#ifdef NBBY +#define CHAR_BIT NBBY +#endif +#endif + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* + * These macros may not work on all platforms but as we depend + * on two's complement in many places, they do not reduce portability. + * The macros below work with 2s complement and ones complement machines. + * Verify with this table... + * + * Bits 1's c. 2's complement. + * 100 -3 -4 + * 101 -2 -3 + * 110 -1 -2 + * 111 -0 -1 + * 000 +0 0 + * 001 +1 +1 + * 010 +2 +2 + * 011 +3 +3 + * + * Computing -TYPE_MINVAL(type) will not work on 2's complement machines + * if 'type' is int or more. Use -(UIntmax_t)TYPE_MINVAL(type), it works + * for both 1's complement and 2's complement machines. + */ +#define TYPE_ISSIGNED(t) (((t)-1) < ((t)0)) +#define TYPE_ISUNSIGNED(t) (!TYPE_ISSIGNED(t)) +#define TYPE_MSBVAL(t) ((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1))) +#define TYPE_MINVAL(t) (TYPE_ISSIGNED(t) \ + ? TYPE_MSBVAL(t) \ + : ((t)0)) +#define TYPE_MAXVAL(t) ((t)(~((t)0) - TYPE_MINVAL(t))) + +/* + * Let us include system defined types too. + */ +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +/* + * Several unsigned cardinal types + */ +typedef unsigned long Ulong; +typedef unsigned int Uint; +typedef unsigned short Ushort; +typedef unsigned char Uchar; + +/* + * This is a definition for a compiler dependant 64 bit type. + * It currently is silently a long if the compiler does not + * support it. Check if this is the right way. + */ +#ifndef NO_LONGLONG +# if defined(HAVE_LONGLONG) +# define USE_LONGLONG +# endif +#endif + +#ifdef USE_LONGLONG + +typedef long long Llong; +typedef unsigned long long Ullong; /* We should avoid this */ +typedef unsigned long long ULlong; + +#define SIZEOF_LLONG SIZEOF_LONG_LONG +#define SIZEOF_ULLONG SIZEOF_UNSIGNED_LONG_LONG + +#else + +typedef long Llong; +typedef unsigned long Ullong; /* We should avoid this */ +typedef unsigned long ULlong; + +#define SIZEOF_LLONG SIZEOF_LONG +#define SIZEOF_ULLONG SIZEOF_UNSIGNED_LONG + +#endif +#ifndef LLONG_MIN +#define LLONG_MIN TYPE_MINVAL(Llong) +#endif +#ifndef LLONG_MAX +#define LLONG_MAX TYPE_MAXVAL(Llong) +#endif +#ifndef ULLONG_MAX +#define ULLONG_MAX TYPE_MAXVAL(Ullong) +#endif + +/* + * The IBM AIX C-compiler seems to be the only compiler on the world + * which does not allow to use unsigned char bit fields as a hint + * for packed bit fields. Define a pesical type to avoid warnings. + * The packed attribute is honored wit unsigned int in this case too. + */ +#if defined(_AIX) && !defined(__GNUC__) + +typedef unsigned int Ucbit; + +#else + +typedef unsigned char Ucbit; + +#endif + +/* + * Start inttypes.h emulation. + * + * Thanks to Solaris 2.4 and even recent 1999 Linux versions, we + * cannot use the official UNIX-98 names here. Old Solaris versions + * define parts of the types in some exotic include files. + * Linux even defines incompatible types in <sys/types.h>. + */ + +#ifdef HAVE_INTTYPES_H +# ifndef _INCL_INTTYPES_H +# include <inttypes.h> +# define _INCL_INTTYPES_H +# endif +# define HAVE_INT64_T +# define HAVE_UINT64_T + +#define Int8_t int8_t +#define Int16_t int16_t +#define Int32_t int32_t +#define Int64_t int64_t +#define Intmax_t intmax_t +#define UInt8_t uint8_t +#define UInt16_t uint16_t +#define UInt32_t uint32_t +#define UInt64_t uint64_t +#define UIntmax_t uintmax_t + +#define Intptr_t intptr_t +#define UIntptr_t uintptr_t + +#else /* !HAVE_INTTYPES_H */ + +#if SIZEOF_CHAR != 1 || SIZEOF_UNSIGNED_CHAR != 1 +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if the above is true. And that's what we want. + */ +error Sizeof char is not equal 1 +#endif + +typedef signed char Int8_t; + +#if SIZEOF_SHORT_INT == 2 + typedef short Int16_t; +#else + error No int16_t found +#endif + +#if SIZEOF_INT == 4 + typedef int Int32_t; +#else + error No int32_t found +#endif + +#if SIZEOF_LONG_INT == 8 + typedef long Int64_t; +# define HAVE_INT64_T +#else +#if SIZEOF_LONG_LONG == 8 + typedef long long Int64_t; +# define HAVE_INT64_T +#else +/* error No int64_t found*/ +#endif +#endif + +#if SIZEOF_CHAR_P == SIZEOF_INT + typedef int Intptr_t; +#else +#if SIZEOF_CHAR_P == SIZEOF_LONG_INT + typedef long Intptr_t; +#else + error No intptr_t found +#endif +#endif + +typedef unsigned char UInt8_t; + +#if SIZEOF_UNSIGNED_SHORT_INT == 2 + typedef unsigned short UInt16_t; +#else + error No uint16_t found +#endif + +#if SIZEOF_UNSIGNED_INT == 4 + typedef unsigned int UInt32_t; +#else + error No int32_t found +#endif + +#if SIZEOF_UNSIGNED_LONG_INT == 8 + typedef unsigned long UInt64_t; +# define HAVE_UINT64_T +#else +#if SIZEOF_UNSIGNED_LONG_LONG == 8 + typedef unsigned long long UInt64_t; +# define HAVE_UINT64_T +#else +/* error No uint64_t found*/ +#endif +#endif + +#define Intmax_t Llong +#define UIntmax_t Ullong + +#if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_INT + typedef unsigned int UIntptr_t; +#else +#if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG_INT + typedef unsigned long UIntptr_t; +#else + error No uintptr_t found +#endif +#endif + +#endif /* HAVE_INTTYPES_H */ + +#ifndef CHAR_MIN +#define CHAR_MIN TYPE_MINVAL(char) +#endif +#ifndef CHAR_MAX +#define CHAR_MAX TYPE_MAXVAL(char) +#endif +#ifndef UCHAR_MAX +#define UCHAR_MAX TYPE_MAXVAL(unsigned char) +#endif + +#ifndef SHRT_MIN +#define SHRT_MIN TYPE_MINVAL(short) +#endif +#ifndef SHRT_MAX +#define SHRT_MAX TYPE_MAXVAL(short) +#endif +#ifndef USHRT_MAX +#define USHRT_MAX TYPE_MAXVAL(unsigned short) +#endif + +#ifndef INT_MIN +#define INT_MIN TYPE_MINVAL(int) +#endif +#ifndef INT_MAX +#define INT_MAX TYPE_MAXVAL(int) +#endif +#ifndef UINT_MAX +#define UINT_MAX TYPE_MAXVAL(unsigned int) +#endif + +#ifndef LONG_MIN +#define LONG_MIN TYPE_MINVAL(long) +#endif +#ifndef LONG_MAX +#define LONG_MAX TYPE_MAXVAL(long) +#endif +#ifndef ULONG_MAX +#define ULONG_MAX TYPE_MAXVAL(unsigned long) +#endif + +#ifndef INT8_MIN +#define INT8_MIN TYPE_MINVAL(Int8_t) +#endif +#ifndef INT8_MAX +#define INT8_MAX TYPE_MAXVAL(Int8_t) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX TYPE_MAXVAL(UInt8_t) +#endif + +#ifndef INT16_MIN +#define INT16_MIN TYPE_MINVAL(Int16_t) +#endif +#ifndef INT16_MAX +#define INT16_MAX TYPE_MAXVAL(Int16_t) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX TYPE_MAXVAL(UInt16_t) +#endif + +#ifndef INT32_MIN +#define INT32_MIN TYPE_MINVAL(Int32_t) +#endif +#ifndef INT32_MAX +#define INT32_MAX TYPE_MAXVAL(Int32_t) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX TYPE_MAXVAL(UInt32_t) +#endif + +#ifdef HAVE_INT64_T +#ifndef INT64_MIN +#define INT64_MIN TYPE_MINVAL(Int64_t) +#endif +#ifndef INT64_MAX +#define INT64_MAX TYPE_MAXVAL(Int64_t) +#endif +#endif +#ifdef HAVE_UINT64_T +#ifndef UINT64_MAX +#define UINT64_MAX TYPE_MAXVAL(UInt64_t) +#endif +#endif + +#ifndef INTMAX_MIN +#define INTMAX_MIN TYPE_MINVAL(Intmax_t) +#endif +#ifndef INTMAX_MAX +#define INTMAX_MAX TYPE_MAXVAL(Intmax_t) +#endif +#ifndef UINTMAX_MAX +#define UINTMAX_MAX TYPE_MAXVAL(UIntmax_t) +#endif + +#define SIZE_T_MIN TYPE_MINVAL(size_t) +#ifndef SIZE_T_MAX +#define SIZE_T_MAX TYPE_MAXVAL(size_t) +#endif + +#define SSIZE_T_MIN TYPE_MINVAL(ssize_t) +#define SSIZE_T_MAX TYPE_MAXVAL(ssize_t) + +#define OFF_T_MIN TYPE_MINVAL(off_t) +#define OFF_T_MAX TYPE_MAXVAL(off_t) + +#define UID_T_MIN TYPE_MINVAL(uid_t) +#define UID_T_MAX TYPE_MAXVAL(uid_t) + +#define GID_T_MIN TYPE_MINVAL(gid_t) +#define GID_T_MAX TYPE_MAXVAL(gid_t) + +#define PID_T_MIN TYPE_MINVAL(pid_t) +#define PID_T_MAX TYPE_MAXVAL(pid_t) + +#define MODE_T_MIN TYPE_MINVAL(mode_t) +#define MODE_T_MAX TYPE_MAXVAL(mode_t) + +#define TIME_T_MIN TYPE_MINVAL(time_t) +#define TIME_T_MAX TYPE_MAXVAL(time_t) + +#define CADDR_T_MIN TYPE_MINVAL(caddr_t) +#define CADDR_T_MAX TYPE_MAXVAL(caddr_t) + +#define DADDR_T_MIN TYPE_MINVAL(daddr_t) +#define DADDR_T_MAX TYPE_MAXVAL(daddr_t) + +#define DEV_T_MIN TYPE_MINVAL(dev_t) +#define DEV_T_MAX TYPE_MAXVAL(dev_t) + +#define MAJOR_T_MIN TYPE_MINVAL(major_t) +#define MAJOR_T_MAX TYPE_MAXVAL(major_t) + +#define MINOR_T_MIN TYPE_MINVAL(minor_t) +#define MINOR_T_MAX TYPE_MAXVAL(minor_t) + +#define INO_T_MIN TYPE_MINVAL(ino_t) +#define INO_T_MAX TYPE_MAXVAL(ino_t) + +#define NLINK_T_MIN TYPE_MINVAL(nlink_t) +#define NLINK_T_MAX TYPE_MAXVAL(nlink_t) + +#define BLKCNT_T_MIN TYPE_MINVAL(blkcnt_t) +#define BLKCNT_T_MAX TYPE_MAXVAL(blkcnt_t) + +#define CLOCK_T_MIN TYPE_MINVAL(clock_t) +#define CLOCK_T_MAX TYPE_MAXVAL(clock_t) + +#define SOCKLEN_T_MIN TYPE_MINVAL(socklen_t) +#define SOCKLEN_T_MAX TYPE_MAXVAL(socklen_t) + +#endif /* _UTYPES_H */ diff --git a/include/vadefs.h b/include/vadefs.h new file mode 100644 index 0000000..a686074 --- /dev/null +++ b/include/vadefs.h @@ -0,0 +1,131 @@ +/* + * 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. + * + */ + +/* @(#)vadefs.h 1.5 01/07/15 Copyright 1998 J. Schilling */ +/* + * Generic header for users of var args ... + * + * Includes a default definition for va_copy() + * and some magic know how about the SVr4 Power PC var args ABI + * to create a __va_arg_list() macro. + * + * Copyright (c) 1998 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. + */ + +#ifndef _VADEFS_H +#define _VADEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +#ifdef PROTOTYPES +/* + * For ANSI C-compilers prefer stdarg.h + */ +# ifdef HAVE_STDARG_H +# ifndef _INCL_STDARG_H +# include <stdarg.h> +# define _INCL_STDARG_H +# endif +# else +# ifndef _INCL_VARARGS_H +# include <varargs.h> +# define _INCL_VARARGS_H +# endif +# endif +#else +/* + * For K&R C-compilers prefer varargs.h + */ +# ifdef HAVE_VARARGS_H +# ifndef _INCL_VARARGS_H +# include <varargs.h> +# define _INCL_VARARGS_H +# endif +# else +# ifndef _INCL_STDARG_H +# include <stdarg.h> +# define _INCL_STDARG_H +# endif +# endif +#endif + +#if (defined(__linux__) || defined(__linux) || defined(sun)) && \ + (defined(__ppc) || defined(__PPC) || defined(powerpc) || defined(__powerpc__)) + +# ifndef VA_LIST_IS_ARRAY +# define VA_LIST_IS_ARRAY +# endif +#endif + + +/* + * __va_copy() is used by GCC 2.8 or newer until va_copy() becomes + * a final ISO standard. + */ +#if !defined(va_copy) && !defined(HAVE_VA_COPY) +# if defined(__va_copy) +# define va_copy(to, from) __va_copy(to, from) +# endif +#endif + +/* + * va_copy() is a Solaris extension to provide a portable way to perform a + * variable argument list "bookmarking" function. + * If it is not available via stdarg.h, use a simple assignement for backward + * compatibility. + */ +#if !defined(va_copy) && !defined(HAVE_VA_COPY) +#ifdef VA_LIST_IS_ARRAY +# define va_copy(to, from) ((to)[0] = (from)[0]) +#else +# define va_copy(to, from) ((to) = (from)) +#endif +#endif + +/* + * I don't know any portable way to get an arbitrary + * C object from a var arg list so I use a + * system-specific routine __va_arg_list() that knows + * if 'va_list' is an array. You will not be able to + * assign the value of __va_arg_list() but it works + * to be used as an argument of a function. + * It is a requirement for recursive printf to be able + * to use this function argument. If your system + * defines va_list to be an array you need to know this + * via autoconf or another mechanism. + * It would be nice to have something like + * __va_arg_list() in stdarg.h + */ + +#ifdef VA_LIST_IS_ARRAY +# define __va_arg_list(list) va_arg(list, void *) +#else +# define __va_arg_list(list) va_arg(list, va_list) +#endif + +#endif /* _VADEFS_H */ diff --git a/include/waitdefs.h b/include/waitdefs.h new file mode 100644 index 0000000..d363b4f --- /dev/null +++ b/include/waitdefs.h @@ -0,0 +1,152 @@ +/* + * 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. + * + */ + +/* @(#)waitdefs.h 1.10 03/02/25 Copyright 1995-2003 J. Schilling */ +/* + * Definitions to deal with various kinds of wait flavour + * + * Copyright (c) 1995-2003 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. + */ + +#ifndef _WAITDEFS_H +#define _WAITDEFS_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif + +/* + * Needed for SysVr4 + */ +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#if defined(HAVE_WAIT_H) +# ifndef _INCL_WAIT_H +# include <wait.h> +# define _INCL_WAIT_H +# endif +#else +/* + * K&R Compiler doesn't like #elif + */ +# if defined(HAVE_SYS_WAIT_H) /* POSIX.1 compl. sys/wait.h */ +# undef HAVE_UNION_WAIT /* POSIX.1 doesn't use U_W */ +# ifndef _INCL_SYS_WAIT_H +# include <sys/wait.h> +# define _INCL_SYS_WAIT_H +# endif +# else +# if defined(HAVE_UNION_WAIT) /* Pure BSD U_W / sys/wait.h */ +# ifndef _INCL_SYS_WAIT_H +# include <sys/wait.h> +# define _INCL_SYS_WAIT_H +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_UNION_WAIT +# define WAIT_T union wait +# ifndef WSTOPPED +# define WSTOPPED 0x7F +# endif +# ifndef WTERMSIG +# define WTERMSIG(status) ((status).w_termsig) +# endif +# ifndef WCOREDUMP +# define WCOREDUMP(status) ((status).w_coredump) +# endif +# ifndef WEXITSTATUS +# define WEXITSTATUS(status) ((status).w_retcode) +# endif +# ifndef WSTOPSIG +# define WSTOPSIG(status) ((status).w_stopsig) +# endif +# ifndef WIFSTOPPED +# define WIFSTOPPED(status) ((status).w_stopval == \ + WSTOPPED) +# endif +# ifndef WIFSIGNALED +# define WIFSIGNALED(status) ((status).w_stopval != \ + WSTOPPED && \ + (status).w_termsig != 0) +# endif +# ifndef WIFEXITED +# define WIFEXITED(status) ((status).w_stopval != \ + WSTOPPED && \ + (status).w_termsig == 0) +# endif +#else +# define WAIT_T int +# ifndef WTERMSIG +# define WTERMSIG(status) ((status) & 0x7F) +# endif +# ifndef WCOREDUMP +# define WCOREDUMP(status) ((status) & 0x80) +# endif +# ifndef WEXITSTATUS +# define WEXITSTATUS(status) (((status) >> 8) & 0xFF) +# endif +# ifndef WSTOPSIG +# define WSTOPSIG(status) (((status) >> 8) & 0xFF) +# endif +# ifndef WIFSTOPPED +# define WIFSTOPPED(status) (((status) & 0xFF) == 0x7F) +# endif +# ifndef WIFSIGNALED +# define WIFSIGNALED(status) (((status) & 0xFF) != 0x7F && \ + WTERMSIG(status) != 0) +# endif +# ifndef WIFEXITED +# define WIFEXITED(status) (((status) & 0xFF) == 0) +# endif +#endif + + +#ifndef WCOREFLG +#define WCOREFLG 0x80 +#endif + +#ifndef WSTOPFLG +#define WSTOPFLG 0x7F +#endif + +#ifndef WCONTFLG +#define WCONTFLG 0xFFFF +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _WAITDEFS_H */ diff --git a/include/xconfig.h.in b/include/xconfig.h.in new file mode 100644 index 0000000..c130600 --- /dev/null +++ b/include/xconfig.h.in @@ -0,0 +1,286 @@ +/* xconfig.h.in Prototype for xconfig.h, generated automatically by cmake in + * cdrkit's build system. + * + * Most features are expected to be available on every modern unixoide systems, + * others are probed. + * + * NOTE: Be carefull, there are some double checks for the 1 value hidden in + * the source, just defining it may be not enough. + * */ + +/* + * Copyright Eduard Bloch, 2006 + * + * Using constants names and comments from xconfig.h.in by J. Schilling, + * Copyright (c) 1998-2003 + * + */ + +/* + * Header Files + */ +#define PROTOTYPES 1 /* if Compiler supports ANSI C prototypes */ +#cmakedefine HAVE_STDARG_H + /* to use stdarg.h, else use varargs.h NOTE: SaberC on a Sun has prototypes but no stdarg.h */ + +#cmakedefine HAVE_STDLIB_H + /* to use general utility defines (malloc(), size_t ...) and general C library prototypes */ + +#cmakedefine HAVE_STRING_H + /* to get NULL and ANSI C string function prototypes */ +#cmakedefine HAVE_STRINGS_H + /* to get BSD string function prototypes */ +#define STDC_HEADERS 1 /* if ANSI compliant stdlib.h, stdarg.h, string.h, float.h are present */ +#cmakedefine HAVE_UNISTD_H + /* to get POSIX syscall prototypes XXX sys/file.h fcntl.h (unixstd/fctl)XXX*/ +#cmakedefine HAVE_GETOPT_H + /* to get getopt() prototype from getopt.h instead of unistd.h */ +#cmakedefine HAVE_LIMITS_H + /* to get POSIX numeric limits constants */ + +#cmakedefine HAVE_FCNTL_H + /* to access, O_XXX constants for open(), otherwise use sys/file.h */ +#cmakedefine HAVE_SYS_FILE_H + /* to use O_XXX constants for open() and flock() defs */ +#cmakedefine HAVE_INTTYPES_H + /* to use UNIX-98 inttypes.h */ +#cmakedefine HAVE_DIRENT_H + /* to use POSIX dirent.h */ + +#cmakedefine HAVE_ALLOCA_H + /* if alloca.h exists */ + +#cmakedefine HAVE_TERMIOS_H + /* to use POSIX termios.h */ +#cmakedefine HAVE_TERMIO_H + /* to use SVR4 termio.h */ +#cmakedefine HAVE_PWD_H + /* if pwd.h exists */ + +#cmakedefine HAVE_SYS_TIME_H + /* may include sys/time.h for struct timeval */ +#define TIME_WITH_SYS_TIME 1 /* may include both time.h and sys/time.h */ + +#define HAVE_UTIME 1 /* to use AT&T utime() and utimbuf */ +#define HAVE_UTIMES 1 /* to use BSD utimes() and sys/time.h */ + +#cmakedefine HAVE_UTIME_H + /* to use utime.h for the utimbuf structure declaration, else declare struct utimbuf yourself */ + +#cmakedefine HAVE_SYS_IOCTL_H + /* if sys/ioctl.h is present */ + +#cmakedefine HAVE_SYS_PARAM_H + /* if sys/param.h is present */ + +/* to use wait.h for prototypes and union wait */ +#cmakedefine HAVE_WAIT_H +/* else use sys/wait.h */ +#cmakedefine define HAVE_SYS_WAIT_H +#cmakedefine HAVE_SYS_RESOURCE_H + /* to use sys/resource.h for rlimit() and wait3() */ + +#cmakedefine HAVE_SYS_UTSNAME_H + /* to use uname() */ + +#cmakedefine HAVE_SYS_MTIO_H + /* to use mtio definitions from sys/mtio.h */ + +#cmakedefine HAVE_SYS_MMAN_H + /* to use definitions for mmap()/madvise()... from sys/mman.h */ +#define MAJOR_IN_SYSMACROS 1 /* if we should include sys/sysmacros.h to get major()/minor()/makedev() */ +#cmakedefine HAVE_SYS_DKIO_H +#cmakedefine HAVE_SUN_DKIO_H +#cmakedefine HAVE_POLL_H + /* if we may include poll.h to use poll() */ +#cmakedefine HAVE_SYS_POLL_H + /* if we may include sys/poll.h to use poll() */ + + +#cmakedefine HAVE_NETDB_H + /* if we have netdb.h for get*by*() and rcmd() */ +#cmakedefine HAVE_SYS_SOCKET_H + /* if we have sys/socket.h for socket() */ + +#cmakedefine HAVE_LINUX_PG_H + /* if we may include linux/pg.h for PP ATAPI sypport */ +#define HAVE_ERRNO_DEF 1 /* if we have errno definition in <errno.h> */ + +#cmakedefine HAVE_ARPA_INET_H + /* if we have arpa/inet.h (missing on BeOS) */ + /* BeOS has inet_ntoa() in <netdb.h> */ + +#cmakedefine HAVE_ICONV_H + +/* + * Convert to SCHILY name + */ +#ifdef STDC_HEADERS +# ifndef HAVE_STDC_HEADERS +# define HAVE_STDC_HEADERS +# endif +#endif + +/* + * Library Functions + */ +#define HAVE_ACCESS 1 /* access() is present in libc */ +#define HAVE_STRERROR 1 /* strerror() is present in libc */ +#define HAVE_MEMMOVE 1 /* memmove() is present in libc */ + +#define HAVE_MLOCK 1 /* mlock() is present in libc */ +#cmakedefine HAVE_MLOCKALL + /* working mlockall() is present in libc */ +#define HAVE_FLOCK 1 /* *BSD flock() is present in libc */ +#define HAVE_SETREUID 1 /* setreuid() is present in libc */ +#define HAVE_SETEUID 1 /* seteuid() is present in libc */ +#define HAVE_SETUID 1 /* setuid() is present in libc */ +#define HAVE_SETREGID 1 /* setregid() is present in libc */ +#define HAVE_SETEGID 1 /* setegid() is present in libc */ +#define HAVE_SETGID 1 /* setgid() is present in libc */ +#define HAVE_TCGETATTR 1 /* tcgetattr() is present in libc */ +#define HAVE_TCSETATTR 1 /* tcsetattr() is present in libc */ +#define HAVE_GETHOSTID 1 /* gethostid() is present in libc */ +#define HAVE_GETHOSTNAME 1 /* gethostname() is present in libc */ +#define HAVE_GETDOMAINNAME 1 /* getdomainname() is present in libc */ +#define HAVE_GETPAGESIZE 1 /* getpagesize() is present in libc */ +#define HAVE_POLL 1 /* poll() is present in libc */ +#define HAVE_SELECT 1 /* select() is present in libc */ +#define HAVE_LCHOWN 1 /* lchown() is present in libc */ +#define HAVE_SBRK 1 /* sbrk() is present in libc */ +#define HAVE_VA_COPY 1 /* va_copy() is present in varargs.h/stdarg.h */ +#define HAVE_DUP2 1 /* dup2() is present in libc */ +#define HAVE_GETCWD 1 /* POSIX getcwd() is present in libc */ +#define HAVE_SMMAP 1 /* may map anonymous memory to get shared mem */ +#define HAVE_SHMAT 1 /* shmat() is present in libc */ +#define HAVE_SEMGET 1 /* semget() is present in libc */ +#define HAVE_LSTAT 1 /* lstat() is present in libc */ +#define HAVE_READLINK 1 /* readlink() is present in libc */ +#define HAVE_RENAME 1 /* rename() is present in libc */ + +#cmakedefine HAVE_RAND + /* rand() is present in libc */ +#cmakedefine HAVE_DRAND48 + /* drand48() is present in libc */ +#define HAVE_SETPRIORITY 1 /* setpriority() is present in libc */ +#define HAVE_NICE 1 /* nice() is present in libc */ +#define HAVE_UNAME 1 /* uname() is present in libc */ +#define HAVE_SNPRINTF 1 /* snprintf() is present in libc */ +#define HAVE_STRCASECMP 1 /* strcasecmp() is present in libc */ +#define HAVE_STRDUP 1 /* strdup() is present in libc */ +#define HAVE_SIGPROCMASK 1 /* sigprocmask() is present in libc (POSIX) */ +#define HAVE_SIGSET 1 /* sigset() is present in libc (POSIX) */ +#define HAVE_NANOSLEEP 1 /* nanosleep() is present in libc */ +#define HAVE_USLEEP 1 /* usleep() is present in libc */ +#define HAVE_FORK 1 /* fork() is present in libc */ +#define HAVE_ALLOCA 1 /* alloca() is present (else use malloc())*/ +#define HAVE_VALLOC 1 /* valloc() is present in libc (else use malloc())*/ + +/* + * Important: This must be a result from a check _before_ the Large File test + * has been run. It then tells us whether these functions are + * available even when not in Large File mode. + * + * Do not run the AC_FUNC_FSEEKO test from the GNU tar Large File test + * siute. It will use the same cache names and interfere with our test. + * Instead use the tests AC_SMALL_FSEEKO/AC_SMALL/STELLO and make sure + * they are placed before the large file tests. + */ + +#define HAVE_RCMD 1 /* rcmd() is present in libc/libsocket */ +#define HAVE_SOCKET 1 /* socket() is present in libc/libsocket */ +#define HAVE_SOCKETPAIR 1 /* socketpair() is present in libc/libsocket */ +#define HAVE_GETSERVBYNAME 1 /* getservbyname() is present in libc/libsocket */ +/* inet_ntoa() is present in libc/libsocket */ +#cmakedefine HAVE_INET_NTOA + +/* getnameinfo() is present in libc/libsocket */ +#cmakedefine define HAVE_GETNAMEINFO + +/* + * We need to test for the include files too because Apollo Domain/OS has a + * libc that includes the functions but the includes files are not visible + * from the BSD compile environment. + */ +#if defined(HAVE_SHMAT) && defined(HAVE_SYS_SHM_H) && defined(HAVE_SYS_IPC_H) +# define HAVE_USGSHM /* USG shared memory is present */ +#endif +#if defined(HAVE_SEMGET) && defined(HAVE_SYS_SHM_H) && defined(HAVE_SYS_IPC_H) +# define HAVE_USGSEM /* USG semaphores are present */ +#endif + +#if defined(HAVE_GETPGRP) && !defined(HAVE_BSD_GETPGRP) +#define HAVE_POSIX_GETPGRP 1 /* getpgrp() in libc is POSIX compliant */ +#endif +#if defined(HAVE_SETPGRP) && !defined(HAVE_BSD_SETPGRP) +#define HAVE_POSIX_SETPGRP 1 /* setpgrp() in libc is POSIX compliant */ +#endif + +/* + * Structures + */ + +/* have union wait in wait.h */ +#cmakedefine HAVE_UNION_WAIT + +#define HAVE_ST_NSEC 1 /* if struct stat contains st_atim.tv_nsec (nanosecs) */ +#define HAVE_ST_RDEV 1 /* if struct stat contains st_rdev */ +#define HAVE_SOCKADDR_STORAGE 1 /* if socket.h defines struct sockaddr_storage */ + +/* + * Byteorder/Bitorder + */ +/* If using network byte order */ +#cmakedefine WORDS_BIGENDIAN +/* If high bits come first in structures */ +#cmakedefine BITFIELDS_HTOL +#define HAVE_C_BIGENDIAN /* Flag that WORDS_BIGENDIAN test was done */ +#define HAVE_C_BITFIELDS /* Flag that BITFIELDS_HTOL test was done */ + +/* + * Types/Keywords + */ +#define SIZEOF_CHAR 1 +#define SIZEOF_SHORT_INT @SIZE_SHORT@ +#define SIZEOF_INT @SIZE_INT@ +#define SIZEOF_LONG_INT @SIZE_LONG@ +#define SIZEOF_LONG_LONG @SIZE_LLONG@ +#define SIZEOF_CHAR_P @SIZE_PTR@ +#define SIZEOF_UNSIGNED_CHAR 1 +#define SIZEOF_UNSIGNED_SHORT_INT @SIZE_SHORT@ +#define SIZEOF_UNSIGNED_INT @SIZE_INT@ +#define SIZEOF_UNSIGNED_LONG_INT @SIZE_LONG@ +#define SIZEOF_UNSIGNED_LONG_LONG @SIZE_LLONG@ +#define SIZEOF_UNSIGNED_CHAR_P @SIZE_PTR@ + +#define HAVE_LONGLONG 1 /* Compiler defines long long type */ + + +/* + * Critical on some of Debian architectures (EB) */ +/* #define VA_LIST_IS_ARRAY 1 */ + +#cmakedefine VA_LIST_IS_ARRAY + +#define GETGROUPS_T gid_t +#define GID_T GETGROUPS_T + +/* + * Define as the return type of signal handlers (int or void). + */ +#define RETSIGTYPE void + +#define HAVE_LARGEFILES 1 +#define _FILE_OFFSET_BITS 64 /* glibc style */ +#define _LARGEFILE_SOURCE 1 /* To make ftello() visible (HP-UX 10.20). */ +#define _LARGE_FILES 1 /* Large file defined on AIX-style hosts. */ + +/* + * Misc CC / LD related stuff + */ +/* If the compiler allows dynamic sized arrays */ +#cmakedefine HAVE_DYN_ARRAYS + +#define HOST_SYSTEM "@CMAKE_SYSTEM_NAME@" +#cmakedefine CDRKIT_VERSION "@CDRKIT_VERSION@" +/*[$Rev: 467 $]" */ diff --git a/libedc/CMakeLists.txt b/libedc/CMakeLists.txt new file mode 100644 index 0000000..5ea1dd2 --- /dev/null +++ b/libedc/CMakeLists.txt @@ -0,0 +1,6 @@ +PROJECT (LIBEDC C) +INCLUDE_DIRECTORIES(../include . ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) + +AUX_SOURCE_DIRECTORY(. LIBEDC_SRCS) + +ADD_LIBRARY (edc STATIC ${LIBEDC_SRCS}) diff --git a/libedc/README b/libedc/README new file mode 100644 index 0000000..4788aed --- /dev/null +++ b/libedc/README @@ -0,0 +1,123 @@ +This describes the program as shipped with cdrkit, a spinoff from the +cdrtools project. However, the cdrtools developers are no longer +involved in the development of this spinoff and therefore shall not +be made responsible for any problem caused by it. Do not try to get +support for this program by contacting the original authors. + +This is a small description for the Reed-Solomon library intended for +CD sector formatting. + +Basics: +It is assumed that you have a basic knowledge of cd sector formats. + +The library can handle three types of sector data: + data sectors, + audio sectors, and + sub channel r-w sectors + +Currently only encoding is implemented. Decoding and optionally +error correction is planned for later. + +Stages: + +The process of sector formatting has several stages. Beginning with +a data sector (2048, 2324, or 2336 bytes) a sector of 2352 bytes is +built. This format can be read raw by SCSI MMC-2 and ATAPI drives and +is accepted by cd burners. The additions are an optionally 32 bit CRC +checksum and two layers of Reed-Solomon codes (called Reed-Solomon +Product Code RSPC). +This sector is then scrambled (exor'ed with a bitstream). +The result is called F1 frames. Afterwards even and odd bytes are +swapped, this is called F2 frames. The result is equivalent to an +audio sector and is treated as such by the cd burner. +So, if we wrote a series of sectors (F2 frames) into a CDR file and +later burned them as 'audio', they would turn up as perfect data sectors. + +So, now we are at the level of audio sectors. Audio sectors get their +own error correction data (called CIRC). Sector size goes up to +3136 bytes (that is 4/3 times 2352 bytes). Furthermore different +words get delayed differently and swap positions. The result is ready +to be fed into the so-called EightFourteenModulator (when subchannels +have been added). + +Now, only sub channels are missing. While the p and q sub +channels have to be generated elsewhere, any supplied r-w subchannel +user data is protected by two levels of error correction +codes. This format is read by cd burners when burning cd+graphics. +The cdimage is a sequence of sectors, each containing audio data and +after that subchannel data. +Similar to audio sectors delaying and permutation of words +takes place. After that the cd burner would mix sub channel data with +the formatted audio sectors to feed the EFModulator. + +NOTE: Most of the described stages need not to be done in order to +prepare sectors for burning, since all cd burners do at least CIRC, +delaying and swaps. For data sectors they also do scrambling and f2 +frame generation. + +Encoding routines: + +For data sectors + int do_encode_L2(unsigned char *inout, int sectortype, unsigned address); + + encodes data sectors. The returned data is __unscrambled__ and not in + F2-frame format. + +Parameters are: + inout pointer to an array of at least 2352 bytes. + sectortype One of the MODE_* constants from ecc.h. This defines + how to format the sector. + address The logical address to be used in the header + (150 = 0:2.0 MSF). + +NOTE: the data portion has be to aligned properly for performance +reasons (see ecc.h for details). So, no moves are necessary here. + +Generating f2 frames to be used like audio sectors + int scramble_L2(unsigned char *inout) + + generates f2 frames in place from sectors generated by do_encode_L2(). + +Parameters are: + inout pointer to an array of at least 2352 bytes. + + + +For sub channels + int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)* + PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute); + + repack user data and add error correction data. P and q subchannels +should be added later, since all bytes are in place then. + +Parameters are: + in pointer to an array of at least 72 bytes. It contains + the user data for one frame. + out pointer to an array of at least 96 bytes. Here is + output frame is placed. + delay1 do low level delaying, when set to 1. + permute do low level permutations, when set to 1. + +NOTE: Probably both options need either to be set on (1) or off (0) together. + +There is more, but that is seldomly used. + +Tests: +The library is accompanied by small verify programs, that compare real +raw sectors with the formatted results. They are also intended as demo +applications (how to use the library). In order to be able to feed +real raw sectors into them, the package read2448 is recommended/needed. +You can only verify sector streams of one sector type, currently no mix. + +For more information have a look into ecc.h + +recommended Documents: +Yellow Book or ISO 10149 +Appendix Red Book +Red Book or IEC 908 + +Source: libedc/README from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/libedc/crctable.out b/libedc/crctable.out new file mode 100644 index 0000000..3c99306 --- /dev/null +++ b/libedc/crctable.out @@ -0,0 +1,171 @@ +/* @(#)crctable.out 1.2 02/10/17 joerg */ + +/*****************************************************************/ +/* */ +/* CRC LOOKUP TABLE */ +/* ================ */ +/* The following CRC lookup table was generated automagically */ +/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ +/* Program V1.0 using the following model parameters: */ +/* */ +/* Width : 4 bytes. */ +/* Poly : 0x8001801BL */ +/* Reverse : TRUE. */ +/* */ +/* For more information on the Rocksoft^tm Model CRC Algorithm, */ +/* see the document titled "A Painless Guide to CRC Error */ +/* Detection Algorithms" by Ross Williams */ +/* (ross@guest.adelaide.edu.au.). This document is likely to be */ +/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/*****************************************************************/ + +#ifdef PROTOTYPES + +static unsigned int EDC_crctable[256] = +{ + 0x00000000U, 0x90910101U, 0x91210201U, 0x01B00300U, + 0x92410401U, 0x02D00500U, 0x03600600U, 0x93F10701U, + 0x94810801U, 0x04100900U, 0x05A00A00U, 0x95310B01U, + 0x06C00C00U, 0x96510D01U, 0x97E10E01U, 0x07700F00U, + 0x99011001U, 0x09901100U, 0x08201200U, 0x98B11301U, + 0x0B401400U, 0x9BD11501U, 0x9A611601U, 0x0AF01700U, + 0x0D801800U, 0x9D111901U, 0x9CA11A01U, 0x0C301B00U, + 0x9FC11C01U, 0x0F501D00U, 0x0EE01E00U, 0x9E711F01U, + 0x82012001U, 0x12902100U, 0x13202200U, 0x83B12301U, + 0x10402400U, 0x80D12501U, 0x81612601U, 0x11F02700U, + 0x16802800U, 0x86112901U, 0x87A12A01U, 0x17302B00U, + 0x84C12C01U, 0x14502D00U, 0x15E02E00U, 0x85712F01U, + 0x1B003000U, 0x8B913101U, 0x8A213201U, 0x1AB03300U, + 0x89413401U, 0x19D03500U, 0x18603600U, 0x88F13701U, + 0x8F813801U, 0x1F103900U, 0x1EA03A00U, 0x8E313B01U, + 0x1DC03C00U, 0x8D513D01U, 0x8CE13E01U, 0x1C703F00U, + 0xB4014001U, 0x24904100U, 0x25204200U, 0xB5B14301U, + 0x26404400U, 0xB6D14501U, 0xB7614601U, 0x27F04700U, + 0x20804800U, 0xB0114901U, 0xB1A14A01U, 0x21304B00U, + 0xB2C14C01U, 0x22504D00U, 0x23E04E00U, 0xB3714F01U, + 0x2D005000U, 0xBD915101U, 0xBC215201U, 0x2CB05300U, + 0xBF415401U, 0x2FD05500U, 0x2E605600U, 0xBEF15701U, + 0xB9815801U, 0x29105900U, 0x28A05A00U, 0xB8315B01U, + 0x2BC05C00U, 0xBB515D01U, 0xBAE15E01U, 0x2A705F00U, + 0x36006000U, 0xA6916101U, 0xA7216201U, 0x37B06300U, + 0xA4416401U, 0x34D06500U, 0x35606600U, 0xA5F16701U, + 0xA2816801U, 0x32106900U, 0x33A06A00U, 0xA3316B01U, + 0x30C06C00U, 0xA0516D01U, 0xA1E16E01U, 0x31706F00U, + 0xAF017001U, 0x3F907100U, 0x3E207200U, 0xAEB17301U, + 0x3D407400U, 0xADD17501U, 0xAC617601U, 0x3CF07700U, + 0x3B807800U, 0xAB117901U, 0xAAA17A01U, 0x3A307B00U, + 0xA9C17C01U, 0x39507D00U, 0x38E07E00U, 0xA8717F01U, + 0xD8018001U, 0x48908100U, 0x49208200U, 0xD9B18301U, + 0x4A408400U, 0xDAD18501U, 0xDB618601U, 0x4BF08700U, + 0x4C808800U, 0xDC118901U, 0xDDA18A01U, 0x4D308B00U, + 0xDEC18C01U, 0x4E508D00U, 0x4FE08E00U, 0xDF718F01U, + 0x41009000U, 0xD1919101U, 0xD0219201U, 0x40B09300U, + 0xD3419401U, 0x43D09500U, 0x42609600U, 0xD2F19701U, + 0xD5819801U, 0x45109900U, 0x44A09A00U, 0xD4319B01U, + 0x47C09C00U, 0xD7519D01U, 0xD6E19E01U, 0x46709F00U, + 0x5A00A000U, 0xCA91A101U, 0xCB21A201U, 0x5BB0A300U, + 0xC841A401U, 0x58D0A500U, 0x5960A600U, 0xC9F1A701U, + 0xCE81A801U, 0x5E10A900U, 0x5FA0AA00U, 0xCF31AB01U, + 0x5CC0AC00U, 0xCC51AD01U, 0xCDE1AE01U, 0x5D70AF00U, + 0xC301B001U, 0x5390B100U, 0x5220B200U, 0xC2B1B301U, + 0x5140B400U, 0xC1D1B501U, 0xC061B601U, 0x50F0B700U, + 0x5780B800U, 0xC711B901U, 0xC6A1BA01U, 0x5630BB00U, + 0xC5C1BC01U, 0x5550BD00U, 0x54E0BE00U, 0xC471BF01U, + 0x6C00C000U, 0xFC91C101U, 0xFD21C201U, 0x6DB0C300U, + 0xFE41C401U, 0x6ED0C500U, 0x6F60C600U, 0xFFF1C701U, + 0xF881C801U, 0x6810C900U, 0x69A0CA00U, 0xF931CB01U, + 0x6AC0CC00U, 0xFA51CD01U, 0xFBE1CE01U, 0x6B70CF00U, + 0xF501D001U, 0x6590D100U, 0x6420D200U, 0xF4B1D301U, + 0x6740D400U, 0xF7D1D501U, 0xF661D601U, 0x66F0D700U, + 0x6180D800U, 0xF111D901U, 0xF0A1DA01U, 0x6030DB00U, + 0xF3C1DC01U, 0x6350DD00U, 0x62E0DE00U, 0xF271DF01U, + 0xEE01E001U, 0x7E90E100U, 0x7F20E200U, 0xEFB1E301U, + 0x7C40E400U, 0xECD1E501U, 0xED61E601U, 0x7DF0E700U, + 0x7A80E800U, 0xEA11E901U, 0xEBA1EA01U, 0x7B30EB00U, + 0xE8C1EC01U, 0x7850ED00U, 0x79E0EE00U, 0xE971EF01U, + 0x7700F000U, 0xE791F101U, 0xE621F201U, 0x76B0F300U, + 0xE541F401U, 0x75D0F500U, 0x7460F600U, 0xE4F1F701U, + 0xE381F801U, 0x7310F900U, 0x72A0FA00U, 0xE231FB01U, + 0x71C0FC00U, 0xE151FD01U, 0xE0E1FE01U, 0x7070FF00U, +}; + +/*****************************************************************/ +/* End of CRC Lookup Table */ +/*****************************************************************/ + +#else /* PROTOTYPES */ + +static unsigned int EDC_crctable[256] = +{ + 0x00000000, 0x90910101, 0x91210201, 0x01B00300, + 0x92410401, 0x02D00500, 0x03600600, 0x93F10701, + 0x94810801, 0x04100900, 0x05A00A00, 0x95310B01, + 0x06C00C00, 0x96510D01, 0x97E10E01, 0x07700F00, + 0x99011001, 0x09901100, 0x08201200, 0x98B11301, + 0x0B401400, 0x9BD11501, 0x9A611601, 0x0AF01700, + 0x0D801800, 0x9D111901, 0x9CA11A01, 0x0C301B00, + 0x9FC11C01, 0x0F501D00, 0x0EE01E00, 0x9E711F01, + 0x82012001, 0x12902100, 0x13202200, 0x83B12301, + 0x10402400, 0x80D12501, 0x81612601, 0x11F02700, + 0x16802800, 0x86112901, 0x87A12A01, 0x17302B00, + 0x84C12C01, 0x14502D00, 0x15E02E00, 0x85712F01, + 0x1B003000, 0x8B913101, 0x8A213201, 0x1AB03300, + 0x89413401, 0x19D03500, 0x18603600, 0x88F13701, + 0x8F813801, 0x1F103900, 0x1EA03A00, 0x8E313B01, + 0x1DC03C00, 0x8D513D01, 0x8CE13E01, 0x1C703F00, + 0xB4014001, 0x24904100, 0x25204200, 0xB5B14301, + 0x26404400, 0xB6D14501, 0xB7614601, 0x27F04700, + 0x20804800, 0xB0114901, 0xB1A14A01, 0x21304B00, + 0xB2C14C01, 0x22504D00, 0x23E04E00, 0xB3714F01, + 0x2D005000, 0xBD915101, 0xBC215201, 0x2CB05300, + 0xBF415401, 0x2FD05500, 0x2E605600, 0xBEF15701, + 0xB9815801, 0x29105900, 0x28A05A00, 0xB8315B01, + 0x2BC05C00, 0xBB515D01, 0xBAE15E01, 0x2A705F00, + 0x36006000, 0xA6916101, 0xA7216201, 0x37B06300, + 0xA4416401, 0x34D06500, 0x35606600, 0xA5F16701, + 0xA2816801, 0x32106900, 0x33A06A00, 0xA3316B01, + 0x30C06C00, 0xA0516D01, 0xA1E16E01, 0x31706F00, + 0xAF017001, 0x3F907100, 0x3E207200, 0xAEB17301, + 0x3D407400, 0xADD17501, 0xAC617601, 0x3CF07700, + 0x3B807800, 0xAB117901, 0xAAA17A01, 0x3A307B00, + 0xA9C17C01, 0x39507D00, 0x38E07E00, 0xA8717F01, + 0xD8018001, 0x48908100, 0x49208200, 0xD9B18301, + 0x4A408400, 0xDAD18501, 0xDB618601, 0x4BF08700, + 0x4C808800, 0xDC118901, 0xDDA18A01, 0x4D308B00, + 0xDEC18C01, 0x4E508D00, 0x4FE08E00, 0xDF718F01, + 0x41009000, 0xD1919101, 0xD0219201, 0x40B09300, + 0xD3419401, 0x43D09500, 0x42609600, 0xD2F19701, + 0xD5819801, 0x45109900, 0x44A09A00, 0xD4319B01, + 0x47C09C00, 0xD7519D01, 0xD6E19E01, 0x46709F00, + 0x5A00A000, 0xCA91A101, 0xCB21A201, 0x5BB0A300, + 0xC841A401, 0x58D0A500, 0x5960A600, 0xC9F1A701, + 0xCE81A801, 0x5E10A900, 0x5FA0AA00, 0xCF31AB01, + 0x5CC0AC00, 0xCC51AD01, 0xCDE1AE01, 0x5D70AF00, + 0xC301B001, 0x5390B100, 0x5220B200, 0xC2B1B301, + 0x5140B400, 0xC1D1B501, 0xC061B601, 0x50F0B700, + 0x5780B800, 0xC711B901, 0xC6A1BA01, 0x5630BB00, + 0xC5C1BC01, 0x5550BD00, 0x54E0BE00, 0xC471BF01, + 0x6C00C000, 0xFC91C101, 0xFD21C201, 0x6DB0C300, + 0xFE41C401, 0x6ED0C500, 0x6F60C600, 0xFFF1C701, + 0xF881C801, 0x6810C900, 0x69A0CA00, 0xF931CB01, + 0x6AC0CC00, 0xFA51CD01, 0xFBE1CE01, 0x6B70CF00, + 0xF501D001, 0x6590D100, 0x6420D200, 0xF4B1D301, + 0x6740D400, 0xF7D1D501, 0xF661D601, 0x66F0D700, + 0x6180D800, 0xF111D901, 0xF0A1DA01, 0x6030DB00, + 0xF3C1DC01, 0x6350DD00, 0x62E0DE00, 0xF271DF01, + 0xEE01E001, 0x7E90E100, 0x7F20E200, 0xEFB1E301, + 0x7C40E400, 0xECD1E501, 0xED61E601, 0x7DF0E700, + 0x7A80E800, 0xEA11E901, 0xEBA1EA01, 0x7B30EB00, + 0xE8C1EC01, 0x7850ED00, 0x79E0EE00, 0xE971EF01, + 0x7700F000, 0xE791F101, 0xE621F201, 0x76B0F300, + 0xE541F401, 0x75D0F500, 0x7460F600, 0xE4F1F701, + 0xE381F801, 0x7310F900, 0x72A0FA00, 0xE231FB01, + 0x71C0FC00, 0xE151FD01, 0xE0E1FE01, 0x7070FF00, +}; + +#endif /* PROTOTYPES */ + +/*****************************************************************/ +/* End of CRC Lookup Table */ +/*****************************************************************/ diff --git a/libedc/ecc.h b/libedc/ecc.h new file mode 100644 index 0000000..76062b2 --- /dev/null +++ b/libedc/ecc.h @@ -0,0 +1,134 @@ +/* + * 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. + * + */ + +/* @(#)ecc.h 1.4 02/10/19 Copyright 1998-2002 Heiko Eissfeldt, Joerg Schilling */ + +/* + * compact disc reed-solomon routines + * + * (c) 1998-2002 by Heiko Eissfeldt, heiko@colossus.escape.de + * (c) 2002 by Joerg 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. + */ + +#define RS_L12_BITS 8 + +/* audio sector definitions for CIRC */ +#define FRAMES_PER_SECTOR 98 +/* user data bytes per frame */ +#define L1_RAW 24 +/* parity bytes with 8 bit */ +#define L1_Q 4 +#define L1_P 4 + +/* audio sector Cross Interleaved Reed-Solomon Code (CIRC) encoder (layer 1) */ +/* adds P- and Q- parity information to audio (f2) frames. Also + optionally handles the various delays and permutations. The output with all + stages enabled can be fed into the Eight-Fourteen-Modulator. + On input: 2352 bytes of audio data is given. + On output: 3136 bytes of CIRC enriched audio data are returned. + */ +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int scramble); + +/* data sector definitions for RSPC */ +/* user data bytes per frame */ +#define L2_RAW (1024*2) +/* parity bytes for 16 bit units */ +#define L2_Q (26*2*2) +#define L2_P (43*2*2) + +/* known sector types */ +#define MODE_0 0 +#define MODE_1 1 +#define MODE_2 2 +#define MODE_2_FORM_1 3 +#define MODE_2_FORM_2 4 + +/* set one of the MODE_* constants for subsequent data sector formatting */ +int set_sector_type(int st); +/* get the current sector type setting for data sector formatting */ +int get_sector_type(void); + +/* data sector layer 2 Reed-Solomon Product Code encoder */ +/* encode the given data portion depending on sector type (see + get/set_sector_type() functions). Use the given address for the header. + The returned data is __unscrambled__ and not in F2-frame format (for that + see function scramble_L2()). + Supported sector types: + MODE_0: a 12-byte sync field, a header and 2336 zeros are returned. + MODE_1: the user data portion (2048 bytes) has to be given + at offset 16 in the inout array. + Sync-, header-, edc-, spare-, p- and q- fields will be added. + MODE_2: the user data portion (2336 bytes) has to be given + at offset 16 in the inout array. + Sync- and header- fields will be added. + MODE_2_FORM_1: the user data portion (8 bytes subheader followed + by 2048 bytes data) has to be given at offset 16 + in the inout array. + Sync-, header-, edc-, p- and q- fields will be added. + MODE_2_FORM_2: the user data portion (8 bytes subheader followed + by 2324 bytes data) has to be given at offset 16 + in the inout array. + Sync-, header- and edc- fields will be added. +*/ +int do_encode_L2(unsigned char *inout, int sectortype, unsigned address); +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]); +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]); +unsigned int build_edc(unsigned char inout[], int from, int upto); + +/* generates f2 frames from otherwise fully formatted sectors (generated by + do_encode_L2()). */ +#define EDC_SCRAMBLE_NOSWAP 1 /* Do not swap bytes while scrambling */ +int scramble_L2(unsigned char *inout); + +/* r-w sub channel definitions */ +#define RS_SUB_RW_BITS 6 + +#define PACKETS_PER_SUBCHANNELFRAME 4 +#define LSUB_RAW 18 +#define LSUB_QRAW 2 +/* 6 bit */ +#define LSUB_Q 2 +#define LSUB_P 4 + +/* R-W subchannel encoder */ +/* On input: 72 bytes packed user data, four frames with each 18 bytes. + On output: per frame: 2 bytes user data, 2 bytes Q parity, + 16 bytes user data, 4 bytes P parity. + Options: + delay1: use low level delay line + scramble: perform low level permutations + */ +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int scramble); +int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int scramble); + +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]); +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); diff --git a/libedc/edc_ecc.c b/libedc/edc_ecc.c new file mode 100644 index 0000000..f98d4c5 --- /dev/null +++ b/libedc/edc_ecc.c @@ -0,0 +1,983 @@ +/* + * 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. + * + */ + +/* @(#)edc_ecc.c 1.21 03/04/04 Copyright 1998-2002 Heiko Eissfeldt, Joerg Schilling */ + +/* + * Copyright 1998-2002 by Heiko Eissfeldt + * Copyright 2002 by Joerg Schilling + * + * This file contains protected intellectual property. + * + * reed-solomon encoder / decoder for compact discs. + * + */ +/* + * 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 <align.h> +#include <utypes.h> +#include <stdxlib.h> +#include <strdefs.h> +#include "ecc.h" + +#ifndef HAVE_MEMMOVE +/*#define memmove(dst, src, size) movebytes((src), (dst), (size))*/ +#define memmove(d, s, n) bcopy ((s), (d), (n)) +#endif + +/* these prototypes will become public when the function are implemented */ +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], + unsigned char out[L2_RAW]); + +static int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + unsigned char out[L1_RAW*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int scramble); + + +/* ------------- tables generated by gen_encodes --------------*/ + +#include "scramble_table" + +#define DO4(a) a;a;a;a; +#define DO13(a) a;a;a;a;a;a;a;a;a;a;a;a;a; + +/* + * Scrambles 2352 - 12 = 2340 bytes + */ +int scramble_L2(unsigned char *inout); + +int scramble_L2(unsigned char *inout) +{ +#ifndef EDC_SCRAMBLE_NOSWAP + unsigned int *f = (unsigned int *)inout; +#endif + + if (!xaligned(inout + 12, sizeof(UInt32_t)-1)) { + + Uchar *r = inout + 12; + const Uchar *s = yellowbook_scrambler; + register int i; + + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char)/4; --i >= 0;) { + DO4(*r++ ^= *s++); + } + + } else { + UInt32_t *r = (UInt32_t *) (inout + 12); + const UInt32_t *s = yellowbook_scrambler_uint32; + register int i; + + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(UInt32_t)/13; --i >= 0;) { + DO13(*r++ ^= *s++); + } + } + +#ifndef EDC_SCRAMBLE_NOSWAP + + /* generate F1 frames */ + for (i = 2352/sizeof(unsigned int); i; i--) { + *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8); + } +#endif + + return (0); +} + +#include "l2sq_table" + +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]); + +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]) +{ + unsigned char *dps; + unsigned char *dp; + unsigned char *Q; + register int i; + int j; + + Q = inout + 4 + L2_RAW + 4 + 8 + L2_P; + + dps = inout; + for (j = 0; j < 26; j++) { + register unsigned short a; + register unsigned short b; + a = b = 0; + + dp = dps; + for (i = 0; i < 43; i++) { + + /* LSB */ + a ^= L2sq[i][*dp++]; + + /* MSB */ + b ^= L2sq[i][*dp]; + + dp += 2*44-1; + if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) { + dp -= (4 + L2_RAW + 4 + 8 + L2_P); + } + } + Q[0] = a >> 8; + Q[26*2] = a; + Q[1] = b >> 8; + Q[26*2+1] = b; + + Q += 2; + dps += 2*43; + } + return (0); +} + +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]); + +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]) +{ + unsigned char *dp; + unsigned char *P; + register int i; + int j; + + P = inout + 4 + L2_RAW + 4 + 8; + + for (j = 0; j < 43; j++) { + register unsigned short a; + register unsigned short b; + + a = b = 0; + dp = inout; + for (i = 19; i < 43; i++) { + + /* LSB */ + a ^= L2sq[i][*dp++]; + + /* MSB */ + b ^= L2sq[i][*dp]; + + dp += 2*43 -1; + } + P[0] = a >> 8; + P[43*2] = a; + P[1] = b >> 8; + P[43*2+1] = b; + + P += 2; + inout += 2; + } + return (0); +} + +static unsigned char bin2bcd(unsigned p); + +static unsigned char bin2bcd(unsigned p) +{ + return ((p/10)<<4)|(p%10); +} + +static int build_address(unsigned char inout[], int sectortype, unsigned address); + +static int +build_address(unsigned char inout[], int sectortype, unsigned address) +{ + inout[12] = bin2bcd(address / (60*75)); + inout[13] = bin2bcd((address / 75) % 60); + inout[14] = bin2bcd(address % 75); + if (sectortype == MODE_0) + inout[15] = 0; + else if (sectortype == MODE_1) + inout[15] = 1; + else if (sectortype == MODE_2) + inout[15] = 2; + else if (sectortype == MODE_2_FORM_1) + inout[15] = 2; + else if (sectortype == MODE_2_FORM_2) + inout[15] = 2; + else + return (-1); + return (0); +} + +#include "crctable.out" + +/* + * Called with 2064, 2056 or 2332 byte difference - all dividable by 4. + */ +unsigned int build_edc(unsigned char inout[], int from, int upto); + +unsigned int build_edc(unsigned char inout[], int from, int upto) +{ + unsigned char *p = inout+from; + unsigned int result = 0; + + upto -= from-1; + upto /= 4; + while (--upto >= 0) { + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); + } + return (result); +} + +/* Layer 2 Product code en/decoder */ +int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], + int sectortype, unsigned address); + +int +do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], + int sectortype, unsigned address) +{ + unsigned int result; + +/* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */ +#define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377" + + /* supply initial sync pattern */ + memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN)); + + if (sectortype == MODE_0) { + memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q); + build_address(inout, sectortype, address); + return (0); + } + + switch (sectortype) { + + case MODE_1: + build_address(inout, sectortype, address); + result = build_edc(inout, 0, 16+2048-1); + inout[2064+0] = result >> 0L; + inout[2064+1] = result >> 8L; + inout[2064+2] = result >> 16L; + inout[2064+3] = result >> 24L; + memset(inout+2064+4, 0, 8); + encode_L2_P(inout+12); + encode_L2_Q(inout+12); + break; + case MODE_2: + build_address(inout, sectortype, address); + break; + case MODE_2_FORM_1: + result = build_edc(inout, 16, 16+8+2048-1); + inout[2072+0] = result >> 0L; + inout[2072+1] = result >> 8L; + inout[2072+2] = result >> 16L; + inout[2072+3] = result >> 24L; + + /* clear header for P/Q parity calculation */ + inout[12] = 0; + inout[12+1] = 0; + inout[12+2] = 0; + inout[12+3] = 0; + encode_L2_P(inout+12); + encode_L2_Q(inout+12); + build_address(inout, sectortype, address); + break; + case MODE_2_FORM_2: + build_address(inout, sectortype, address); + result = build_edc(inout, 16, 16+8+2324-1); + inout[2348+0] = result >> 0L; + inout[2348+1] = result >> 8L; + inout[2348+2] = result >> 16L; + inout[2348+3] = result >> 24L; + break; + default: + return (-1); + } + + return (0); +} + + +/*--------------------------------------------------------------------------*/ +#include "encoder_tables" + +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]); + +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) +{ + unsigned char *Q; + int i; + + memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2); + Q = inout + L1_RAW/2; + + memset(Q, 0, L1_Q); + for (i = 0; i < L1_RAW + L1_Q; i++) { + unsigned char data; + + if (i == L1_RAW/2) i += L1_Q; + data = inout[i]; + if (data != 0) { + unsigned char base = rs_l12_log[data]; + + Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + } + } + return (0); +} + +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]); + +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]) +{ + unsigned char *P; + int i; + + P = inout + L1_RAW + L1_Q; + + memset(P, 0, L1_P); + for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) { + unsigned char data; + + data = inout[i]; + if (data != 0) { + unsigned char base = rs_l12_log[data]; + + P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)]; + } + } + return (0); +} + +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]); + +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]) +{ + return (0); +} + +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]); + +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]) +{ + return (0); +} + +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]); + +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]) +{ + return (0); +} + +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]); + +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]) +{ + return (0); +} + +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]); + +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]) +{ + unsigned char *Q; + int i; + + memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW); + Q = inout + LSUB_QRAW; + + memset(Q, 0, LSUB_Q); + + for (i = 0; i < LSUB_QRAW; i++) { + unsigned char data; + + data = inout[i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (0); +} + + +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); + +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) +{ + unsigned char *P; + int i; + + P = inout + LSUB_RAW + LSUB_Q; + + memset(P, 0, LSUB_P); + for (i = 0; i < LSUB_RAW + LSUB_Q; i++) { + unsigned char data; + + data = inout[i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (0); +} + +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]); + +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]) +{ + unsigned char Q[LSUB_Q]; + int i; + + memset(Q, 0, LSUB_Q); + for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) { + unsigned char data; + + data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (Q[0] != 0 || Q[1] != 0); +} + +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]); + +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]) +{ + unsigned char P[LSUB_P]; + int i; + + memset(P, 0, LSUB_P); + for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) { + unsigned char data; + + data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f; + if (data != 0) { + unsigned char base = rs_sub_rw_log[data]; + + P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)]; + } + } + return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0); +} + +/* Layer 1 CIRC en/decoder */ +#define MAX_L1_DEL1 2 +static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW]; +#define MAX_L1_DEL2 108 +static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q]; +#define MAX_L1_DEL3 1 +static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P]; +static unsigned l1_del_index; + +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute); + +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR], + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute) +{ + int i; + + for (i = 0; i < FRAMES_PER_SECTOR; i++) { + int j; + unsigned char t; + + if (in != out) + memcpy(out, in, L1_RAW); + + if (delay1) { + /* shift through delay line 1 */ + for (j = 0; j < L1_RAW; j++) { + if (((j/4) % MAX_L1_DEL1) == 0) { + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j]; + out[j] = t; + } + } + } + + if (permute) { + /* permute */ + t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18]; + out[18] = out[6]; out [6] = t; + t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19]; + out[19] = out[7]; out [7] = t; + t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14]; + out[14] = out[12]; out [12] = t; + t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15]; + out[15] = out[13]; out [13] = t; + } + + /* build Q parity */ + encode_L1_Q(out); + + if (delay2) { + /* shift through delay line 2 */ + for (j = 0; j < L1_RAW+L1_Q; j++) { + if (j != 0) { + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; + l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j]; + out[j] = t; + } + } + } + + /* build P parity */ + encode_L1_P(out); + + if (delay3) { + /* shift through delay line 3 */ + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { + if (((j) & MAX_L1_DEL3) == 0) { + t = l1_delay_line3[0][j]; + l1_delay_line3[0][j] = out[j]; + out[j] = t; + } + } + } + + /* invert Q and P parity */ + for (j = 0; j < L1_Q; j++) + out[j+12] = ~out[j+12]; + for (j = 0; j < L1_P; j++) + out[j+28] = ~out[j+28]; + + l1_del_index++; + out += L1_RAW+L1_Q+L1_P; + in += L1_RAW; + } + return (0); +} + +static +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + unsigned char out[L1_RAW*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute); + +static /* XXX should be non static XXX*/ + +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR], + unsigned char out[L1_RAW*FRAMES_PER_SECTOR], + int delay1, int delay2, int delay3, int permute) +{ + int i; + + for (i = 0; i < FRAMES_PER_SECTOR; i++) { + int j; + unsigned char t; + + if (delay3) { + /* shift through delay line 3 */ + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) { + if (((j) & MAX_L1_DEL3) != 0) { + t = l1_delay_line3[0][j]; + l1_delay_line3[0][j] = in[j]; + in[j] = t; + } + } + } + + /* invert Q and P parity */ + for (j = 0; j < L1_Q; j++) + in[j+12] = ~in[j+12]; + for (j = 0; j < L1_P; j++) + in[j+28] = ~in[j+28]; + + /* build P parity */ + decode_L1_P(in); + + if (delay2) { + /* shift through delay line 2 */ + for (j = 0; j < L1_RAW+L1_Q; j++) { + if (j != L1_RAW+L1_Q-1) { + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j]; + l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j]; + in[j] = t; + } + } + } + + /* build Q parity */ + decode_L1_Q(in); + + if (permute) { + /* permute */ + t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10]; + in[10] = in[8]; in [8] = t; + t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11]; + in[11] = in[9]; in [9] = t; + t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20]; + in[20] = in[16]; in [16] = t; + t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21]; + in[21] = in[17]; in [17] = t; + } + + if (delay1) { + /* shift through delay line 1 */ + for (j = 0; j < L1_RAW; j++) { + if (((j/4) % MAX_L1_DEL1) != 0) { + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j]; + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j]; + in[j] = t; + } + } + } + + if (in != out) + memcpy(out, in, (L1_RAW)); + + l1_del_index++; + in += L1_RAW+L1_Q+L1_P; + out += L1_RAW; + } + return (0); +} + +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], + unsigned char out[L2_RAW]); + +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], + unsigned char out[L2_RAW]) +{ + return (0); +} + + + +#define MAX_SUB_DEL 8 +static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P]; +static unsigned sub_del_index; + +/* R-W Subchannel en/decoder */ + +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute); + +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute) +{ + int i; + + if (in == out) return -1; + + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { + int j; + unsigned char t; + + memcpy(out, in, (LSUB_RAW)); + + /* build Q parity */ + encode_LSUB_Q(out); + + /* build P parity */ + encode_LSUB_P(out); + + if (permute) { + /* permute */ + t = out[1]; out[1] = out[18]; out[18] = t; + t = out[2]; out[2] = out[ 5]; out[ 5] = t; + t = out[3]; out[3] = out[23]; out[23] = t; + } + + if (delay1) { + /* shift through delay_line */ + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { + if ((j % MAX_SUB_DEL) != 0) { + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; + sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j]; + out[j] = t; + } + } + } + sub_del_index++; + out += LSUB_RAW+LSUB_Q+LSUB_P; + in += LSUB_RAW; + } + return (0); +} + +int +do_decode_sub( + unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute); + +int +do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], + int delay1, int permute) +{ + int i; + + if (in == out) return -1; + + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { + int j; + unsigned char t; + + if (delay1) { + /* shift through delay_line */ + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { + if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) { + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; + sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j]; + in[j] = t; + } + } + } + + if (permute) { + /* permute */ + t = in[1]; in[1] = in[18]; in[18] = t; + t = in[2]; in[2] = in[ 5]; in[ 5] = t; + t = in[3]; in[3] = in[23]; in[23] = t; + } + + /* build P parity */ + decode_LSUB_P(in); + + /* build Q parity */ + decode_LSUB_Q(in); + + memcpy(out, in, LSUB_QRAW); + memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW); + + sub_del_index++; + in += LSUB_RAW+LSUB_Q+LSUB_P; + out += LSUB_RAW; + } + return (0); +} + +static int sectortype = MODE_0; + +int get_sector_type(void); + +int get_sector_type() +{ + return (sectortype); +} + +int set_sector_type(int st); + +int set_sector_type(int st) +{ + switch(st) { + + case MODE_0: + case MODE_1: + case MODE_2: + case MODE_2_FORM_1: + case MODE_2_FORM_2: + sectortype = st; + return 0; + default: + return -1; + } +} + +/* ------------- --------------*/ +#ifdef MAIN + +#define DO_L1 1 +#define DO_L2 2 +#define DO_SUB 4 + +static const unsigned sect_size[8][2] = { +/* nothing */ +{0,0}, +/* Layer 1 decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR}, +/* Layer 2 decode/encode */ +{ 16+L2_RAW+12+L2_Q+L2_P, L2_RAW}, +/* Layer 1 and 2 decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR}, +/* Subchannel decode/encode */ +{ (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME}, +/* Layer 1 and subchannel decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR + + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + + L1_RAW*FRAMES_PER_SECTOR}, +/* Layer 2 and subchannel decode/encode */ +{ L2_RAW+L2_Q+L2_P+ + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + + L2_RAW}, +/* Layer 1, 2 and subchannel decode/encode */ +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR + + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + + L1_RAW*FRAMES_PER_SECTOR}, +}; + +int main(int argc, char *argv[]) +{ + int encode = 1; + int mask = DO_L2; + FILE *infp; + FILE *outfp; + unsigned address = 0; + unsigned char *l1_inbuf; + unsigned char *l1_outbuf; + unsigned char *l2_inbuf; + unsigned char *l2_outbuf; + unsigned char *sub_inbuf; + unsigned char *sub_outbuf; + unsigned char *last_outbuf; + unsigned char inbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME + + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR]; + unsigned char outbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME + + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR]; + unsigned load_offset; + + l1_inbuf = l2_inbuf = sub_inbuf = inbuf; + l1_outbuf = l2_outbuf = sub_outbuf = last_outbuf = outbuf; + + infp = fopen("sectors_in", "rb"); + outfp = fopen("sectors_out", "wb"); + + sectortype= MODE_1; + address = 0 + 75*2; + + switch (sectortype) { + + case MODE_1: + case MODE_2: + load_offset = 16; + break; + case MODE_2_FORM_1: + case MODE_2_FORM_2: + load_offset = 24; + break; + default: + load_offset = 0; + } + while(1) { + + if (1 != fread(inbuf+load_offset, + sect_size[mask][encode], 1, infp)) { + perror(""); + break; + } + if (encode == 1) { + if (mask & DO_L2) { + switch (sectortype) { + + case MODE_0: + break; + case MODE_1: + break; + case MODE_2: + if (1 != + fread(inbuf+load_offset+ + sect_size[mask][encode], + 2336 - sect_size[mask][encode], + 1, infp)) { perror(""); break; } + break; + case MODE_2_FORM_1: + break; + case MODE_2_FORM_2: + if (1 != + fread(inbuf+load_offset+ + sect_size[mask][encode], + 2324 - sect_size[mask][encode], + 1, infp)) { perror(""); break; } + break; + default: + if (1 != + fread(inbuf+load_offset+ + sect_size[mask][encode], + 2448 - sect_size[mask][encode], + 1, infp)) { perror(""); break; } + memset(inbuf,0,16); + /*memset(inbuf+16+2048,0,12+272);*/ + break; + } + do_encode_L2(l2_inbuf, MODE_1, address); + if (0) scramble_L2(l2_inbuf); + last_outbuf = l1_inbuf = l2_inbuf; + l1_outbuf = l2_inbuf; + sub_inbuf = l2_inbuf + L2_RAW; + sub_outbuf = l2_outbuf + 12 + 4+ L2_RAW+4+ 8+ L2_Q+L2_P; + } + if (mask & DO_L1) { + do_encode_L1(l1_inbuf, l1_outbuf,1,1,1,1); + last_outbuf = l1_outbuf; + sub_inbuf = l1_inbuf + L1_RAW*FRAMES_PER_SECTOR; + sub_outbuf = l1_outbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR; + } + if (mask & DO_SUB) { + do_encode_sub(sub_inbuf, sub_outbuf, 0, 0); + } + } else { + if (mask & DO_L1) { + do_decode_L1(l1_inbuf, l1_outbuf,1,1,1,1); + last_outbuf = l2_inbuf = l1_outbuf; + l2_outbuf = l1_inbuf; + sub_inbuf = l1_inbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR; + sub_outbuf = l1_outbuf + L1_RAW*FRAMES_PER_SECTOR; + } + if (mask & DO_L2) { + do_decode_L2(l2_inbuf, l2_outbuf); + last_outbuf = l2_outbuf; + sub_inbuf = l2_inbuf + L2_RAW+L2_Q+L2_P; + sub_outbuf = l2_outbuf + L2_RAW; + } + if (mask & DO_SUB) { + do_decode_sub(sub_inbuf, sub_outbuf, 1, 1); + } + } + if (1 != fwrite(last_outbuf, sect_size[mask][1 - encode], 1, outfp)) { + perror(""); + break; + } + address++; + } +#if 0 + /* flush the data from the delay lines with zeroed sectors, if necessary */ +#endif + return (0); +} +#endif diff --git a/libedc/edcspeed.c b/libedc/edcspeed.c new file mode 100644 index 0000000..d72ff6b --- /dev/null +++ b/libedc/edcspeed.c @@ -0,0 +1,75 @@ +/* + * 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. + * + */ + +#include <mconfig.h> +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <timedefs.h> +#include <strdefs.h> + +#define Uchar unsigned char + +static int encspeed(void); + +static int encspeed() +{ + register Uchar *sect; + register int i; + register int end; + register int secs; + struct timeval tv; + struct timeval tv2; + + sect = malloc(2352); + + secs = 10; + end = 75*1000000 * secs; + + memset(sect, 0, sizeof(sect)); + for (i=0; i < 2352; ) { + sect[i++] = 'J'; + sect[i++] = 'S'; + } + + gettimeofday(&tv, (struct timezone *)0); + for (i=0; i < end; i++) { +#ifdef OLD_LIBEDC + do_encode_L2(sect, 1, 1); + scramble_L2(sect); +#else + +/* lec_encode_mode1_sector(12345, sect);*/ +/* lec_scramble(sect);*/ +#endif +/* if ((i & 31) == 0) {*/ + if (1) { + gettimeofday(&tv2, (struct timezone *)0); + if (tv2.tv_sec >= (tv.tv_sec+secs) && + tv2.tv_usec >= tv.tv_usec) + break; + } + } + printf("%d sectors/%ds\n", i, secs); + printf("%d sectors/s\n", i/secs); + printf("speed: %5.2fx\n", (1.0*i)/750.0); + return ((i+74)/75) / secs ; +} + +int main(int argc, char *argv[]) +{ +/* lec_init();*/ + +/* printf("speed: %d\n", encspeed());*/ + encspeed(); + return (0); +} diff --git a/libedc/encoder_tables b/libedc/encoder_tables new file mode 100644 index 0000000..7b46485 --- /dev/null +++ b/libedc/encoder_tables @@ -0,0 +1,47 @@ +/* @(#)encoder_tables 1.4 02/10/19 */ + +/* + * 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. + */ + +static const unsigned char rs_l12_alog[255] = { + 1, 2, 4, 8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143, 3, 6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140, 5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141, 7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138, 9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,}; +static const unsigned char rs_l12_log[256] = { + 0, 0, 1,25, 2,50,26,198, 3,223,51,238,27,104,199,75, 4,100,224,14,52,141,239,129,28,193,105,248,200, 8,76,113, 5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154, 9,120,77,228,114,166, 6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87, 7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175,}; +static const unsigned char rs_sub_rw_alog[63] = { + 1, 2, 4, 8,16,32, 3, 6,12,24,48,35, 5,10,20,40,19,38,15,30,60,59,53,41,17,34, 7,14,28,56,51,37, 9,18,36,11,22,44,27,54,47,29,58,55,45,25,50,39,13,26,52,43,21,42,23,46,31,62,63,61,57,49,33,}; +static const unsigned char rs_sub_rw_log[63] = { + 0, 0, 1, 6, 2,12, 7,26, 3,32,13,35, 8,48,27,18, 4,24,33,16,14,52,36,54, 9,45,49,38,28,41,19,56, 5,62,25,11,34,31,17,47,15,23,53,51,37,44,55,40,10,61,46,30,50,22,39,43,29,60,42,21,20,59,57,}; +static const unsigned char SQ[2][2] = { +{26,6,}, +{7,1,}, +}; +static const unsigned char SP[4][20] = { +{57,38,44,29,17,57,53,58,60,39,12,38,18,41,6,25,39,37,5,18,}, +{38,62,42,13,30,11,46,5,54,26,12,49,48,46,8,50,28,9,12,39,}, +{32,18,41,49,52,62,38,36,39,58,37,24,34,51,51,27,28,36,22,21,}, +{44,50,35,23,0,59,1,3,45,18,44,24,47,12,31,45,43,11,24,6,}, +}; +static const unsigned char AQ[4][24] = { +{58,152,173,95,88,43,134,205,143,131,163,75,37,109,194,159,168,227,153,59,101,}, +{30,214,148,138,112,154,157,96,49,198,189,249,83,23,70,237,70,41,47,52,125,247,}, +{162,244,13,171,213,236,71,177,253,162,59,78,46,68,238,112,147,197,115,200,117,15,236,}, +{158,179,101,94,49,140,211,149,137,169,81,6,33,30,27,24,21,18,15,12,9,6,3,0,}, +}; +static const unsigned char AP[4][32] = { +{140,143,52,103,249,142,180,197,5,155,153,132,143,244,101,76,102,155,203,104,58,152,173,95,88,43,134,205,143,131,163,75,}, +{104,97,17,162,205,252,218,199,202,41,136,106,119,238,193,103,123,242,83,178,30,214,148,138,112,154,157,96,49,198,189,249,}, +{240,119,29,185,67,11,131,40,7,41,80,147,151,17,245,253,208,66,228,116,162,244,13,171,213,236,71,177,253,162,59,78,}, +{149,58,109,0,148,186,203,11,161,159,138,149,250,107,82,108,161,209,110,64,158,179,101,94,49,140,211,149,137,169,81,6,}, +}; diff --git a/libedc/l2sq_table b/libedc/l2sq_table new file mode 100644 index 0000000..29ab0cd --- /dev/null +++ b/libedc/l2sq_table @@ -0,0 +1,1180 @@ +/* @(#)l2sq_table 1.2 02/10/19 Copyright 2002 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. + */ + +static const unsigned short L2sq[43][256] = { +{0,44719,16707,61420,33414,11305,50117,28010,6417,47038, + 22610,63229,39831,13624,56020,29819,12834,40077,29537,56782, + 45220,7691,61927,24392,11059,34204,27248,50399,43445,1818, + 59638,18009,25668,51947,9479,35752,59074,18541,42881,2350, + 32085,54266,15382,37561,65491,20860,48784,4159,22118,63689, + 5925,47498,54496,31311,38307,15116,20343,57816,3636,41115, + 52721,25438,36018,8733,51336,26151,35275,10084,18958,58529, + 2893,42466,53657,32566,37082,15989,21279,64944,4700,48371, + 64170,21509,48105,5446,30764,54915,14703,38848,58299,19732, + 41720,3159,24893,53138,8318,36561,44236,611,60815,17184, + 11850,32997,28425,49574,46557,7026,62622,23089,14171,39412, + 30232,55479,40686,12353,57261,28930,7272,45767,23851,62340, + 34815,10576,50876,26643,1401,43990,17466,60053,36109,9122, + 52302,25313,3979,41252,20168,57447,37916,15027,54623,31728, + 5786,47157,22489,63862,48943,4480,65132,20675,15785,37638, + 31978,53829,42558,2193,59261,18898,9400,35351,26107,52052, + 59721,18406,43018,1701,27599,50528,10892,33827,61528,24311, + 45339,8116,29406,56433,13213,40242,56171,30148,39464,13447, + 23021,63298,6318,46593,49786,27861,33593,11670,16636,61011, + 447,44816,17797,60202,1222,43625,50947,27052,34368,10479, + 23700,62011,7639,45944,56850,28861,40785,12798,30631,55560, + 14052,38987,62753,23438,46178,6861,28342,49177,12277,33114, + 60464,17055,44403,988,8641,36718,24706,52781,41799,3560, + 57860,19627,14544,38527,31123,55100,47702,5369,64277,21946, + 5091,48460,21152,64527,37221,16330,53286,32393,2802,42077, + 19377,58654,34932,9947,51511,26520, +}, +{0,55768,44973,30325,17223,39583,60650,13618,34446,24406, + 10531,61691,50633,7185,27236,46012,4353,51417,48812,26484, + 21062,35742,65003,9267,38799,20055,14370,57850,54472,3344, + 31589,41661,8706,64474,36271,21623,24901,47261,52968,5936, + 42124,32084,2849,54009,59339,15891,18534,37310,13059,60123, + 40110,17782,28740,43420,57321,1585,46477,27733,6688,50168, + 63178,12050,22887,32959,17412,40412,60329,12913,1859,56987, + 43246,28982,49802,6994,27943,46335,33229,22549,11872,63416, + 21765,36061,64168,9072,5698,53146,47599,24631,54155,2643, + 31782,42494,37068,18708,16225,59065,26118,49118,51627,4211, + 9537,64665,35564,21300,57480,14672,20261,38653,41935,31255, + 3170,54714,30471,44767,55466,370,13376,60824,39917,16949, + 61833,10321,24100,34812,45774,27414,7523,50363,34824,20944, + 10149,65149,52047,4759,25826,48442,3718,55134,41259,30963, + 19905,37913,57964,15284,39177,16593,13988,61308,55886,918, + 30179,44091,8071,50783,45098,27122,23744,34072,62317,10933, + 43530,29650,1447,56447,59725,12437,18144,40760,11396,62812, + 33577,23281,28611,46619,49262,6582,47883,25299,5286,52606, + 63564,8596,22497,36409,15749,58461,37416,19440,32450,42778, + 53615,2231,52236,5588,25505,47737,36683,22163,8422,63806, + 19074,37722,58671,15607,2501,53277,42600,32688,56589,1237, + 29344,43896,40522,18322,12775,59455,23427,33371,62510,11766, + 6340,49436,46953,28337,60942,14294,16803,39035,44361,29841, + 740,56124,26752,45400,50989,7925,11207,61983,33898,23986, + 65295,9943,20642,35194,48200,26000,5093,51773,31105,41049, + 54828,4084,15046,58142,38251,19635, +}, +{0,27757,55514,46263,44457,49604,30067,6430,18255,11042, + 40853,62456,60134,34443,12860,24145,36510,58099,22084,14889, + 9015,20314,64493,38784,51665,42428,4363,32102,25720,2069, + 48290,53455,289,27980,55803,46486,44168,49381,29778,6207, + 18030,10755,40628,62169,60359,34730,13085,24432,36799,58322, + 22373,15112,8726,20091,64204,38561,51440,42141,4138,31815, + 25945,2356,48515,53742,578,28207,55960,46837,45035,50054, + 30513,7004,17677,10592,40407,61882,59556,33993,12414,23571, + 36060,57521,21510,14443,8565,19736,63919,38338,52115,43006, + 4937,32548,26170,2647,48864,53901,867,28430,56249,47060, + 44746,49831,30224,6781,17452,10305,40182,61595,59781,34280, + 12639,23858,36349,57744,21799,14666,8276,19513,63630,38115, + 51890,42719,4712,32261,26395,2934,49089,54188,1156,26857, + 56414,45107,43309,50496,29175,7578,17355,12198,39697,63356, + 61026,33295,14008,23253,35354,58999,21184,16045,10163,19422, + 65385,37636,52565,41272,5519,31202,24828,3217,47142,54347, + 1445,27080,56703,45330,43020,50273,28886,7355,17130,11911, + 39472,63069,61251,33582,14233,23540,35643,59222,21473,16268, + 9874,19199,65096,37413,52340,40985,5294,30915,25053,3504, + 47367,54634,1734,27307,56860,45681,43887,50946,29621,8152, + 16777,11748,39251,62782,60448,32845,13562,22679,34904,58421, + 20610,15599,9713,18844,64811,37190,53015,41850,6093,31648, + 25278,3795,47716,54793,2023,27530,57149,45904,43598,50723, + 29332,7929,16552,11461,39026,62495,60673,33132,13787,22966, + 35193,58644,20899,15822,9424,18621,64522,36967,52790,41563, + 5868,31361,25503,4082,47941,55080, +}, +{0,47289,28015,54742,56030,25191,47025,3848,43425,4376, + 50382,31863,29567,52166,7696,42665,20319,63462,8752,39561, + 38273,11576,63726,16471,59134,24135,35729,13096,15392,33945, + 20815,59894,40638,9735,62417,19304,17504,64729,10511,37302, + 14111,36774,23152,58057,60865,21880,32942,14359,53729,26968, + 48270,1079,2879,45958,26192,57065,30784,49401,5423,44438, + 41630,6695,53233,30536,8545,39384,19470,62647,64447,17158, + 38608,11881,35008,12409,58799,23830,21022,60071,16241,34760, + 28222,54919,849,48104,46304,3161,55695,24886,51103,32550, + 43760,4681,7489,42488,28718,51351,49119,1894,53936,27145, + 25857,56760,2158,45271,5758,44743,31505,50088,52384,29721, + 41423,6518,61568,18489,40431,9558,10846,37607,18225,65416, + 22817,57752,13390,36087,33791,15174,61072,22057,17090,64123, + 12205,38676,38940,8357,62835,19914,60259,21466,34316,16053, + 12733,35076,23762,58475,3485,46372,24818,55371,55107,28666, + 47660,661,42044,7301,51539,29162,32482,50779,5005,43828, + 56444,25797,45331,2474,1698,48667,27597,54132,30173,52580, + 6322,40971,44803,6074,49772,31445,37667,11162,65100,18165, + 18941,61764,9362,39979,14978,33339,22509,61268,57436,22757, + 36147,13706,25507,56090,3788,46709,47485,452,54290,27819, + 51714,29371,42861,8148,4316,43109,32179,50442,11516,37957, + 16787,63786,63010,20123,39757,9204,34141,15844,59442,20619, + 24451,59194,13036,35413,64797,17828,36978,10443,10179,40826, + 19116,61973,21692,60421,14803,33130,36450,14043,58125,23476, + 45634,2811,57133,26516,26780,53285,1523,48458,7139,41818, + 30348,52789,49469,31108,44114,5355, +}, +{0,53971,47547,27496,28523,48568,54992,1027,57046,3077, + 26477,46526,45501,25454,2054,56021,41393,29538,6154,51929, + 52954,7177,30561,42418,32615,44468,50908,5135,4108,49887, + 43447,31588,24447,36268,59076,13335,12308,58055,35247,23420, + 33193,21370,14354,60097,61122,15377,22393,34218,65230,11293, + 18293,38310,37285,17270,10270,64205,8216,62155,39331,19312, + 20339,40352,63176,9243,48894,27693,1861,54678,53653,838, + 26670,47869,24616,45819,55699,2880,3907,56720,46840,25643, + 8015,52636,42740,29735,28708,41719,51615,6988,49561,4938, + 30754,43761,44786,31777,5961,50586,57729,13138,22586,35561, + 36586,23609,14161,58754,16215,60804,34540,21567,20540,33519, + 59783,15188,16432,37603,63883,11096,12123,64904,38624,17459, + 40678,19509,10077,62862,61837,9054,18486,39653,25057,45874, + 55386,2697,3722,56409,46897,26082,48951,28132,1676,54367, + 53340,655,27111,47924,49232,4739,31211,43832,44859,32232, + 5760,50259,7814,52309,42813,30190,29165,41790,51286,6789, + 16030,60493,34597,22006,20981,33574,59470,15005,57416,12955, + 23027,35616,36643,24048,13976,58443,40751,19964,9876,62535, + 61508,8855,18943,39724,16889,37674,63554,10897,11922,64577, + 38697,17914,57119,3532,26276,46199,45172,25255,2511,56092, + 457,54042,47218,27297,28322,48241,55065,1482,32430,44157, + 50965,5574,4549,49942,43134,31405,41080,29355,6595,51984, + 53011,7616,30376,42107,32864,21171,14811,60168,61195,15832, + 22192,33891,24246,35941,59149,13790,12765,58126,34918,23221, + 8657,62210,39018,19129,20154,40041,63233,9682,65287,11732, + 18108,37999,36972,17087,10711,64260, +}, +{0,59366,54225,13367,48063,23641,26734,36744,27491,35973, + 47282,24404,53468,14138,781,58603,54982,12576,1303,58097, + 28025,35487,48808,22862,48549,23107,28276,35218,1562,57852, + 54731,12845,45457,22135,25152,34214,2606,60872,55807,15897, + 56050,15636,2339,61125,24909,34475,45724,21882,26455,32945, + 46214,21344,56552,15118,3897,59615,3124,60370,57317,14339, + 46987,20589,25690,33724,32575,39129,44270,19208,50304,9062, + 5969,61623,5212,62394,51085,8299,45027,18437,31794,39892, + 43513,19999,31272,40398,4678,62880,49559,9841,49818,9596, + 4427,63149,31013,40643,43764,19730,52910,10568,7551,64153, + 29969,37623,42688,16678,42445,16939,30236,37370,7794,63892, + 52643,10821,6248,65422,52153,11359,41943,17457,28678,38880, + 29451,38125,41178,18236,51380,12114,7013,64643,65150,6552, + 11695,51785,17857,41511,38416,29174,38173,29435,18124,41258, + 11938,51524,64883,6805,10424,53086,64361,7311,37639,29921, + 16598,42800,17371,42045,36874,30700,63588,8066,11189,52307, + 20463,43017,39998,31704,62544,5046,10113,49255,9356,50026, + 63325,4283,40755,30933,19682,43780,39209,32463,19192,44318, + 8854,50544,61767,5793,62026,5548,8603,50813,18933,44563, + 39460,32194,33089,26279,21136,46454,15102,56600,59695,3785, + 59938,3524,14835,56853,20893,46715,33356,26026,22407,45153, + 33878,25520,60472,3038,16361,55311,15588,56066,61237,2259, + 34651,24765,21642,45932,12496,55094,58113,1255,35695,27785, + 22718,48984,23475,48213,34914,28548,57356,2026,13277,54331, + 58902,496,13767,53793,23977,47695,36472,27038,36213,27283, + 24228,47426,14026,53548,58651,765, +}, +{0,29554,59108,38294,53717,41639,14129,17475,49079,52421, + 22867,10785,28258,7440,34950,64500,25459,4097,34199,63205, + 45734,49620,21570,10032,56516,44982,14880,18770,3345,32355, + 60405,39047,50918,46484,8194,21360,5939,25665,61911,33445, + 31057,2595,40885,60615,43140,56310,20064,15634,42389,55015, + 17265,12291,29760,1842,37540,57814,6690,26960,64710,36788, + 52215,47237,11539,24161,37329,58019,30517,1095,16388,13174, + 42720,54674,11878,23828,51330,48112,65459,36033,6487,27173, + 62114,33232,5190,26420,9079,20485,50579,46817,19733,15975, + 44017,55427,40128,61362,31268,2390,22327,9285,45523,49825, + 34530,62864,24582,4980,59520,39922,3684,32022,14677,18983, + 57265,44227,13380,18230,53920,41426,58769,38627,885,28679, + 35827,63617,27927,7781,23078,10580,48322,53168,16319,19661, + 55643,43561,61034,40216,2190,31740,32776,62330,26348,5534, + 20957,8879,46905,50251,23756,12222,47656,51546,36121,65131, + 27645,6287,58235,36873,1439,30445,12974,16860,54346,42808, + 63833,35371,8125,27855,10380,23550,52840,48410,18158,13724, + 40970,54136,38715,58441,29151,685,39466,59736,31950,4028, + 19455,14477,44315,56937,9629,22255,50041,45067,62536,34618, + 4780,25054,44654,56604,18570,15352,32699,3273,39263,59949, + 4569,25259,63293,33871,49164,45950,9960,21914,52509,48751, + 11257,22667,7368,28602,64044,35166,29354,472,37966,59196, + 41855,53261,17819,14057,26760,7162,36460,64798,47453,51759, + 24505,11467,55103,42061,12763,17065,1770,30104,57358,37756, + 3067,30857,60703,40557,55854,43356,15562,20408,46156,51006, + 21160,8666,26009,5867,33661,61455, +}, +{0,14648,29296,19272,58592,56792,38544,44968,54749,60645, + 42925,40597,12605,2053,17229,31349,47015,36511,50647,64751, + 21319,27263,8503,6159,25210,23362,4106,10546,34458,49058, + 62698,52690,29523,19051,291,14363,38835,44683,58819,56571, + 42638,40886,54526,60870,17006,31574,12318,2342,50420,64972, + 46724,36796,8212,6444,21092,27484,4393,10257,25433,23137, + 62921,52465,34745,48769,59046,57246,38102,44526,582,15230, + 28726,18702,13179,2627,16651,30771,55195,61091,42475,40147, + 20737,26681,9073,6729,46561,36057,51089,65193,34012,48612, + 63148,53140,24636,22788,4684,11124,38389,44237,59269,57021, + 28949,18477,869,14941,16424,30992,12888,2912,42184,40432, + 54968,61312,8786,7018,20514,26906,50866,65418,46274,36346, + 63375,52919,34303,48327,4975,10839,24863,22567,53585,59497, + 41761,39449,13745,3209,18369,32505,1164,15796,30460,20420, + 57452,55636,37404,43812,26358,24526,5254,11710,33302,47918, + 61542,51550,45867,35347,49499,63587,22475,28403,9659,7299, + 41474,39738,53362,59722,18146,32730,13458,3498,30687,20199, + 1455,15511,37695,43527,57679,55415,5541,11421,26581,24301, + 61765,51325,33589,47629,49272,63808,45576,35632,9368,7584, + 22248,28624,14327,3791,17799,31935,54039,59951,41319,39007, + 57898,56082,36954,43362,1738,16370,29882,19842,32848,47464, + 61984,51992,25776,23944,5824,12280,21901,27829,10237,7877, + 45421,34901,49949,64037,17572,32156,14036,4076,41028,39292, + 53812,60172,37241,43073,58121,55857,30105,19617,2025,16081, + 62211,51771,33139,47179,6115,11995,26003,23723,9950,8166, + 21678,28054,49726,64262,45134,35190, +}, +{0,7197,14394,9255,28788,27753,18510,21587,57576,64757, + 55506,50383,37020,35969,43174,46267,56781,49616,58871,63978, + 44473,45476,38275,35230,15653,8504,1311,6402,19793,20812, + 30059,26998,42887,48026,40893,33696,55283,52206,61385,62420, + 18287,23410,32597,25416,14107,11014,3873,4924,31306,26199, + 17008,24173,2622,5667,12804,11801,39586,34495,41624,48773, + 60118,63179,53996,52977,21267,20238,27433,30516,9063,16250, + 7005,1856,46075,45030,35777,38876,50063,57234,64437,59304, + 36574,37571,46820,43769,65194,58039,50832,55949,28214,29227, + 22028,18961,7746,607,9848,14949,62612,59529,52398,53427, + 34016,39165,48346,41159,5244,2145,11334,12379,25608,30741, + 23602,16431,10585,13636,4451,3454,22829,17712,24855,32010, + 51633,54700,61835,60822,47557,42456,33279,40418,42534,47675, + 40476,33281,54866,51791,61032,62069,18126,23251,32500,25321, + 14010,10919,3712,4765,31723,26614,17361,24524,2975,6018, + 13221,12216,39683,34590,41785,48932,60279,63338,54093,53072, + 417,7612,14747,9606,29141,28104,18927,22002,57673,64852, + 55667,50542,37181,36128,43271,46362,56428,49265,58454,63563, + 44056,45061,37922,34879,15492,8345,1214,6307,19696,20717, + 29898,26839,62773,59688,52495,53522,34113,39260,48507,41318, + 5597,2496,11751,12794,26025,31156,23955,16782,10488,13541, + 4290,3295,22668,17553,24758,31915,51216,54285,61482,60471, + 47204,42105,32862,40003,21170,20143,27272,30357,8902,16091, + 6908,1761,45658,44615,35424,38525,49710,56883,64020,58889, + 36735,37730,46917,43864,65291,58134,50993,56108,28567,29578, + 22445,19376,8163,1022,10201,15300, +}, +{0,32897,7455,40350,14910,47807,10017,42912,29820,62717, + 26979,59874,20034,52931,21341,54236,59640,26745,62951,30054, + 53958,21063,53209,20312,40068,7173,33179,282,42682,9787, + 48037,15140,52717,19820,53490,20595,63443,30546,60108,27213, + 47505,14608,42126,9231,33711,814,40624,7729,9493,42388, + 14346,47243,7979,40874,564,33461,20841,53736,19574,52471, + 27479,60374,30280,63177,34759,1862,39640,6745,48633,15736, + 41190,8295,62395,29498,61092,28197,51589,18692,54426,21531, + 28479,61374,29216,62113,21761,54656,18462,51359,6979,39874, + 1628,34525,8573,41468,15458,48355,18986,51883,22325,55220, + 28692,61589,27915,60810,15958,48855,9033,41928,1128,34025, + 6519,39414,41682,8787,49101,16204,39148,6253,34291,1394, + 54958,22063,52145,19248,60560,27665,61839,28942,5011,37650, + 3724,36365,10669,43308,13490,46131,26607,59246,31472,64113, + 24017,56656,16590,49231,64363,31722,58996,26357,49493,16852, + 56394,23755,36631,3990,37384,4745,46377,13736,43062,10423, + 56958,24319,50017,17376,58432,25793,63839,31198,43522,10883, + 46877,14236,36924,4285,36131,3490,13958,46599,11161,43800, + 3256,35897,4519,37158,17146,49787,24549,57188,30916,63557, + 26075,58714,37972,5333,35147,2506,44650,12011,45941,13300, + 57384,24745,64823,32182,55830,23191,50953,18312,31916,64557, + 25011,57650,18066,50707,23437,56076,2256,34897,5583,38222, + 13038,45679,12273,44912,22969,55608,17574,50215,25479,58118, + 32408,65049,11717,44356,12506,45147,6139,38778,2788,35429, + 45377,12736,44126,11487,35711,3070,38496,5857,50493,17852, + 55330,22691,65283,32642,57884,25245, +}, +{0,52943,33155,20300,7963,53716,40600,20567,15926,61689, + 49077,29050,8493,61410,41134,28257,31852,45731,65007,13088, + 25463,44472,58100,11323,16986,35989,50137,3350,23873,37774, + 56514,4621,63704,13847,31067,46996,59331,10508,26176,43151, + 50926,2081,18285,35234,55797,5946,22646,38585,33972,19067, + 1335,52216,39855,21856,6700,54499,47746,29773,15105,62926, + 42393,27478,9242,60117,60845,9058,27694,41697,62134,15481, + 29493,48634,54171,7508,21016,40151,52352,591,19715,33740, + 37313,24334,4162,56973,36570,16405,3929,49558,45047,24888, + 11892,57531,45292,32291,12655,65440,5493,56250,38134,23097, + 2670,50337,35821,17698,11075,58764,43712,25615,13400,64151, + 46555,31508,26905,42966,59546,9813,30210,47309,63361,14670, + 22319,39392,54956,6243,18484,34555,51639,1912,51015,2440, + 18116,34827,55388,5779,23007,38672,63857,14270,30962,46653, + 58986,10405,26601,43302,47915,30180,15016,62567,42032,27391, + 9651,60284,34077,19410,1182,51793,39430,21705,7045,54602, + 16287,61776,48668,28883,8324,61003,41223,28616,425,53094, + 32810,20197,7858,53373,40753,20990,17395,36156,49776,3263, + 23784,37415,56683,5028,32197,45834,64582,12937,25310,44049, + 58205,11666,10986,58405,43881,26022,13809,64318,46194,31421, + 5340,55827,38239,23440,3015,50440,35396,17547,22150,38985, + 55045,6602,18845,34642,51230,1745,26800,42623,59699,10236, + 30635,47460,63016,14567,53810,7421,21425,40318,52521,998, + 19626,33381,60420,8907,28039,41800,62239,15824,29340,48211, + 44638,24721,12253,57618,45381,32650,12486,65033,36968,24231, + 4587,57124,36723,16828,3824,49215, +}, +{0,59880,53197,9765,33671,27247,19530,42402,6931,62203, + 54494,15670,39060,29052,22361,48817,13862,57294,63979,4099, + 46497,23625,31340,37764,11573,50397,58104,2832,44722,18266, + 24959,34967,27724,34212,41857,19049,61387,1571,8198,51694, + 30559,40631,47250,20858,62680,7472,15125,54013,23146,45954, + 38311,31823,55789,12293,5664,65480,16761,43153,36532,26460, + 49918,11030,3379,58587,55448,12656,5973,65213,23327,45815, + 38098,32058,50059,10851,3142,58798,16396,43492,36801,26153, + 61118,1878,8563,51355,27961,34001,41716,19228,62893,7237, + 14944,54152,30250,40898,47591,20495,46292,23868,31513,37617, + 14163,57019,63646,4470,44999,17967,24586,35298,11328,50600, + 58253,2661,33522,27418,19775,42199,373,59549,52920,10064, + 39393,28681,22060,49092,6758,62350,54699,15427,44333,17605, + 25312,35592,11946,51010,57703,2191,46654,24534,31219,36891, + 13753,56401,64116,5020,39691,29411,21702,48430,6284,61796, + 55105,16041,32792,27120,20437,42557,927,60023,52306,9658, + 49505,10377,3756,59204,17126,43790,36139,25795,55922,13210, + 5567,64599,23029,45085,38456,32720,63303,7855,14474,53602, + 29888,40232,47885,21221,60500,1468,9113,51825,28627,34363, + 40990,18934,30133,40029,47736,21392,63026,8154,14847,53271, + 28326,34638,41323,18563,60705,1225,8940,51972,17299,43643, + 35934,26038,49172,10748,4057,58929,22656,45416,38733,32421, + 56071,13039,5322,64802,6649,61457,54836,16348,39550,29590, + 21939,48219,746,60162,52519,9423,33133,26757,20128,42824, + 12255,50743,57362,2554,44120,17840,25493,35453,13516,56612, + 64257,4841,46923,24227,30854,37230, +}, +{0,29813,59626,40095,52681,47548,9507,20822,34703,62458, + 28517,6928,19014,15923,41644,55001,4867,26486,64489,36764, + 57034,43711,13856,16981,38028,57593,31846,2067,22853,11568, + 45487,50650,9734,21107,52972,47769,60367,40890,805,30544, + 41353,54780,18787,15638,27712,6197,33962,61663,13573,16752, + 56815,43418,63692,36025,4134,25683,45706,50943,23136,11797, + 32579,2870,38825,58332,19468,14457,42214,53395,33221,62896, + 26927,7514,52099,49142,9065,22300,1610,29247,61088,39637, + 24335,11130,47077,50064,37574,59059,31276,3673,55424,44277, + 12394,17439,5449,24892,64931,35286,27146,7807,33504,63125, + 42947,54198,20265,15196,60805,39408,1391,28954,8268,21561, + 51366,48339,30985,3452,37347,58774,46272,49333,23594,10335, + 65158,35571,5740,25113,13135,18234,56229,45008,38936,60525, + 28914,1159,21969,8612,48443,51534,8087,27618,63357,33544, + 53854,42539,15028,20161,35611,65390,25585,6020,18130,12967, + 44600,55885,3220,30945,58494,36875,49501,46376,10679,24002, + 48670,51819,22260,8833,29655,1954,39741,61256,14737,19940, + 53627,42254,62552,32813,7346,26823,44317,55656,17911,12674, + 24788,5281,34878,64587,10898,24295,49784,46605,59227,37678, + 4017,31684,54292,41057,15614,18571,6621,28072,61751,34114, + 21403,10222,47985,52996,40530,59943,30392,717,50967,45922, + 12285,23432,2782,32427,57908,38465,16536,13549,43122,56327, + 36177,63780,26043,4558,61970,34407,6904,28301,16347,19374, + 55089,41796,30109,488,40311,59650,47188,52257,20670,9419, + 57617,38244,2555,32142,11480,22701,50226,45127,26270,4843, + 36468,64001,43863,57122,17341,14280, +}, +{0,46261,30071,49602,60142,24155,40857,11052,51649,32116, + 48310,2051,9007,38810,22104,58093,36767,15146,64232,20061, + 25969,53700,4102,42163,18014,62187,13097,34716,44208,6149, + 55751,28018,803,46998,30292,49889,59853,23928,40122,10255, + 51938,32343,49045,2848,8204,38073,21883,57806,36028,14345, + 63947,19838,26194,53991,4901,42896,17789,61896,12298,33983, + 44947,6950,56036,28241,1606,45811,29489,51076,60584,22557, + 39391,11626,53127,31538,47856,3653,9577,37340,20510,58539, + 35289,15724,64686,18459,25399,55170,5696,41717,16408,62637, + 13679,33242,43766,7747,57217,27444,1381,45520,28690,50343, + 61323,23358,39676,11849,52388,30737,47571,3430,9802,37631, + 21309,59272,35578,15951,65421,19256,24596,54433,5475,41430, + 17211,63374,13900,33529,43477,7520,56482,26647,3212,47161, + 31227,52558,58978,21207,37653,10144,50509,29176,45114,1167, + 12195,39702,23252,61025,33555,14246,63076,17105,27133,56648, + 7306,43071,19154,65127,16293,35600,41020,5257,54603,25086, + 4015,47898,31448,52845,58689,20980,36918,9347,50798,29403, + 45849,1964,11392,38965,23031,60738,32816,13445,62791,16882, + 27358,56939,8105,43804,18929,64836,15494,34867,41759,6058, + 54888,25309,2762,48767,32701,51976,57380,21649,38227,8678, + 49931,30654,46716,713,10725,40272,23698,59431,34133,12768, + 61474,17559,28603,56078,6860,44665,19604,63521,14819,36182, + 42618,4815,54029,26552,2537,48476,31902,51243,58119,22450, + 38512,8901,49192,29853,46431,490,10950,40563,24497,60164, + 34422,12995,62209,18356,27800,55341,6639,44378,20407,64258, + 15040,36469,42329,4588,53294,25755, +}, +{0,54485,46519,24930,30579,41894,49860,5649,61158,14899, + 23377,36740,39317,19776,11298,63735,49617,5380,29798,41139, + 46754,25207,789,55232,12087,64482,39552,20053,22596,35985, + 60915,14630,40895,19306,10760,65245,59596,15385,23931,35246, + 29017,42380,50414,4155,1578,54015,45981,26440,24174,35515, + 60377,16140,10525,64968,40106,18559,45192,25693,1343,53738, + 51195,4910,29260,42649,9059,63414,38612,16897,21520,32965, + 57767,13682,52613,6480,30770,44263,47862,28195,3905,56212, + 58034,13927,22277,33744,38337,16660,8310,62627,3156,55425, + 47587,27958,31527,45042,52880,6725,48348,26633,2411,56766, + 52143,8058,32280,43725,21050,34543,59277,13144,9545,61852, + 37118,17451,32013,43480,51386,7279,2686,57003,49097,27420, + 37867,18238,9820,62089,58520,12365,20783,34298,18118,37395, + 62321,10148,12725,58720,33794,20695,43040,31989,7575,51522, + 57171,2950,27364,48689,34583,21442,12960,58997,61540,9393, + 17875,37126,27121,48420,56390,2195,7810,51799,43829,32736, + 55673,3500,27854,47131,44554,31455,7101,53096,14239,58186, + 33320,22269,16620,37945,62811,8590,6312,52349,44319,31178, + 28635,47886,55916,3769,63054,8859,17401,38700,33085,21992, + 13450,57439,26021,45424,53266,1223,4822,50691,42849,29620, + 35651,24470,16116,59937,64560,10469,18823,40274,42100,28833, + 4547,50454,54023,2002,26288,45669,19090,40519,65317,11248, + 15841,59700,34902,23683,64026,11983,20397,39800,36201,22972, + 14558,60427,5372,49193,41291,30110,25487,46938,54840,749, + 15307,61214,36476,23209,19640,39021,63759,11738,54573,504, + 24730,46159,41566,30347,6121,49980, +}, +{0,58597,54743,12594,47027,21334,25188,34433,29563,38814, + 42668,16969,50376,8237,4383,62970,59126,531,13089,55236, + 20805,46496,33938,24695,38285,29032,16474,42175,8766,50907, + 63465,4876,53745,13588,1062,57539,26178,33447,45973,22384, + 41610,18031,30557,37816,5433,61916,49390,9227,14087,54242, + 58064,1589,32948,25681,21859,45446,17532,41113,37291,30030, + 62415,5930,9752,49917,49151,23322,27176,36557,2124,60585, + 56731,14718,52356,10337,6483,64950,31543,40914,44768,18949, + 22793,48620,36062,26683,61114,2655,15213,57224,10866,52887, + 65445,6976,40385,31012,18454,44275,28174,35563,48089,24380, + 55741,15704,3178,59535,7541,63888,51362,11335,43718,20003, + 32529,39924,35064,27677,23855,47562,16203,56238,60060,3705, + 64387,8038,11860,51889,19504,43221,39399,32002,25571,34566, + 46644,21201,54352,12469,391,58722,4248,62589,50511,8618, + 42795,17358,29436,38425,34069,25072,20674,46119,12966,54851, + 59249,916,63086,4747,9145,51036,16861,42296,37898,28911, + 45586,22263,26565,33568,1441,57668,53366,13459,49513,9612, + 5310,61531,30426,37439,41741,18408,21732,45057,33075,26070, + 58199,1970,13952,53861,10143,50042,62024,5805,36908,29897, + 17915,41246,56348,14585,2507,60718,27567,36682,48760,23197, + 44903,19330,31408,40533,6356,64561,52483,10726,15082,56847, + 61245,3032,36185,27068,22670,48235,18833,44404,40006,30883, + 65058,6855,11253,53008,3565,59656,55354,15583,47710,24251, + 28553,35692,32406,39539,43841,20388,51493,11712,7410,63511, + 60187,4094,16076,55849,23720,47181,35199,28058,39008,31877, + 19895,43346,12243,52022,64004,7905, +}, +{0,64765,58855,6426,55251,11054,12852,52937,46011,20294, + 22108,43681,25704,39061,33167,32114,31595,34710,40588,25201, + 44216,20549,18783,46498,51408,13357,11575,53706,7939,58366, + 64228,1561,63190,2603,4913,61388,8453,56824,50402,14367, + 17773,47504,41098,23671,37566,28227,30553,35748,36285,28992, + 26714,38055,23150,42643,49033,17268,15878,49915,56289,10012, + 59861,5416,3122,61647,61873,3404,5206,59563,9826,55967, + 50053,16248,16906,48887,42989,23312,38361,26916,28734,36035, + 35546,30247,28477,37824,23817,41460,47342,17427,14689,50588, + 56454,8315,61106,4687,2901,63400,1895,64410,57984,7805, + 53428,11337,13651,51630,46300,18465,20795,44486,25359,40946, + 34536,31253,31756,33009,39403,25878,43999,22306,20024,45765, + 53175,13130,10832,54957,6244,58521,64899,382,65407,898, + 6808,58981,10412,54353,52555,12726,19652,45113,43299,21982, + 39703,26602,32496,33293,33812,30953,25075,40206,21447,44858, + 46624,19165,14255,52050,53832,11957,57468,7297,1435,63846, + 2473,62804,60494,4275,56954,8839,15261,51040,47634,18159, + 24565,41736,28097,37180,34854,29915,29378,36415,38693,27608, + 42257,23020,16630,48139,49529,15748,9374,55395,5802,59991, + 62285,4016,3790,62003,60201,6100,55581,9696,15610,49159, + 48501,16776,22674,42095,27302,38491,36673,29628,30117,35160, + 36930,27839,41590,24203,18321,47980,50718,15075,9209,57092, + 4557,60720,62506,2263,63512,1253,7679,57602,12235,54070, + 51756,14033,19363,46942,44612,21177,40048,24717,31127,34154, + 33651,32654,26260,39529,21664,43101,45383,19898,12488,52277, + 54575,10706,59163,7142,764,65025, +}, +{0,61681,65023,3342,59363,5906,6684,60141,54235,9002, + 11812,57045,13368,50377,51655,14646,48043,19290,18004,46757, + 23624,44217,41399,20806,26736,39041,38287,25982,36755,32610, + 29292,33437,27467,39866,38580,26181,36008,31833,29015,33190, + 47248,18529,17775,46494,24435,44930,41612,21117,53472,8209, + 11551,56814,14083,51186,51964,14861,827,62410,65220,3637, + 58584,5161,6439,59862,54934,9831,11113,56216,12661,49540, + 52362,15483,1357,62908,63666,2115,58030,4703,8017,61344, + 27965,40396,37058,24627,35550,31279,30497,34768,48870,19991, + 17177,46056,22789,43508,42234,21515,48605,19756,16418,45267, + 23102,43727,42945,22320,28166,40695,37881,25352,35301,30996, + 29722,34027,1654,63111,64393,2936,57749,4452,7274,60571, + 54701,9564,10322,55459,12878,49855,53169,16192,45361,16832, + 19662,48191,22226,42531,43821,23516,25322,37403,40725,28644, + 34057,30200,30966,34823,2714,64107,63333,1940,60793,7560, + 4230,57463,55617,10672,9406,54351,16034,52819,50013,13228, + 55930,10891,10117,55156,15769,52584,49254,12439,2465,63824, + 62558,1199,60994,7859,5053,58188,25041,37152,39982,27871, + 34354,30403,31693,35644,45578,17147,20469,48900,21993,42264, + 43030,22759,26535,38742,39512,27305,32836,28853,32187,36170, + 46204,17549,18819,47474,21407,41838,44640,24209,56332,11517, + 8691,53506,15343,51998,50704,14049,4055,65318,61992,729, + 59444,6341,5579,58682,3308,64541,61715,482,60175,7166, + 5872,58881,57143,12230,8904,53817,14548,51237,50475,13786, + 46919,18358,19128,47689,20644,41045,44379,23978,25756,37997, + 39267,27026,33663,29582,32384,36465, +}, +{0,63223,61939,1796,65531,2316,3592,63743,58347,5404, + 4632,58607,7184,60135,60899,6932,56267,11580,10808,56527, + 9264,53959,54723,9012,14368,52951,51667,16164,51163,12588, + 13864,49375,43915,23932,23160,44175,21616,41607,42371,21364, + 18528,48791,47507,20324,47003,16748,18024,45215,28736,34487, + 33203,30532,36795,31052,32328,35007,37803,25948,25176,38063, + 27728,39591,40355,27476,19211,48636,47864,19471,46320,16903, + 17667,46068,43232,24087,22803,45028,22299,41452,42728,20511, + 37056,26167,24883,38852,28475,39372,40648,26687,29483,34268, + 33496,29743,36048,31271,32035,35796,57472,5751,4467,59268, + 8059,59788,61064,6271,875,62876,62104,1135,64656,2663, + 3427,64404,15179,52668,51896,15439,50352,12871,13635,50100, + 55456,11863,10579,57252,10075,53676,54952,8287,38422,24801, + 26597,37138,27117,40730,38942,28393,30205,33546,33806,29433, + 35334,31985,31733,36098,19933,47914,48174,19161,45606,17617, + 17365,46370,44598,22721,24517,43314,20941,42810,41022,22217, + 15773,52074,52334,15001,49766,13457,13205,50530,56950,10369, + 12165,55666,8589,55162,53374,9865,58966,4257,6053,57682, + 6573,61274,59486,7849,1469,62282,62542,697,64070,3249, + 2997,64834,56605,11242,11502,55833,8934,54289,54037,9698, + 16118,51201,52997,14834,49421,14330,12542,50697,1750,61473, + 63269,466,63789,4058,2270,65065,58685,5066,5326,57913, + 6854,60465,60213,7618,30358,32865,34661,29074,35181,32666, + 30878,36457,38269,25482,25742,37497,27270,40049,39797,28034, + 44381,23466,23726,43609,21158,42065,41813,21922,20150,47169, + 48965,18866,45389,18362,16574,46665, +}, +{0,62964,63477,513,62455,1539,1026,61942,64499,3591, + 3078,63986,2052,65008,65521,2565,60411,7695,7182,59898, + 6156,60920,61433,6669,4104,58876,59389,4617,58367,5643, + 5130,57854,52203,15903,15390,51690,14364,52712,53225,14877, + 12312,50668,51181,12825,50159,13851,13338,49646,8208,54756, + 55269,8721,54247,9747,9234,53734,56291,11799,11286,55778, + 10260,56800,57313,10773,35787,32319,31806,35274,30780,36296, + 36809,31293,28728,34252,34765,29241,33743,30267,29754,33230, + 24624,38340,38853,25137,37831,26163,25650,37318,39875,28215, + 27702,39362,26676,40384,40897,27189,16416,46548,47061,16929, + 46039,17955,17442,45526,48083,20007,19494,47570,18468,48592, + 49105,18981,43995,24111,23598,43482,22572,44504,45017,23085, + 20520,42460,42973,21033,41951,22059,21546,41438,2955,65151, + 64638,2442,63612,3464,3977,64125,61560,1420,1933,62073, + 911,63099,62586,398,57456,5508,6021,57969,4999,58995, + 58482,4486,7043,61047,60534,6530,59508,7552,8065,60021, + 49248,13716,14229,49761,13207,50787,50274,12694,15251,52839, + 52326,14738,51300,15760,16273,51813,11163,56943,56430,10650, + 55404,11672,12185,55917,53352,9628,10141,53865,9119,54891, + 54378,8606,32832,30132,30645,33345,29623,34371,33858,29110, + 31667,36423,35910,31154,34884,32176,32689,35397,27579,40527, + 40014,27066,38988,28088,28601,39501,36936,26044,26557,37449, + 25535,38475,37962,25022,19371,48735,48222,18858,47196,19880, + 20393,47709,45144,17836,18349,45657,17327,46683,46170,16814, + 41040,21924,22437,41553,21415,42579,42066,20902,23459,44631, + 44118,22946,43092,23968,24481,43605, +}, +{0,31355,62710,36493,62961,36746,263,31612,63487,36228, + 777,31090,526,30837,63224,35971,62435,35224,1813,32110, + 1554,31849,62180,34975,1052,32359,61674,35473,61933,35734, + 1307,32608,64475,33184,3885,30038,3626,29777,64220,32935, + 3108,30303,63698,33449,63957,33710,3363,30552,2104,29251, + 64718,34485,64969,34738,2367,29508,65479,34236,2865,29002, + 2614,28749,65216,33979,60331,37328,8029,25894,7770,25633, + 60076,37079,7252,26159,59554,37593,59813,37854,7507,26408, + 6216,25139,60606,38597,60857,38850,6479,25396,61367,38348, + 6977,24890,6726,24637,61104,38091,4208,27147,58502,40701, + 58753,40954,4471,27404,59279,40436,4985,26882,4734,26629, + 59016,40179,58259,39400,5989,27934,5730,27673,58004,39151, + 5228,28183,57498,39649,57757,39910,5483,28432,52043,45360, + 16317,17862,16058,17601,51788,45111,15540,18127,51266,45625, + 51525,45886,15795,18376,14504,17107,52318,46629,52569,46882, + 14767,17364,53079,46380,15265,16858,15014,16605,52816,46123, + 12432,19179,50278,48669,50529,48922,12695,19436,51055,48404, + 13209,18914,12958,18661,50792,48147,50035,47368,14213,19966, + 13954,19705,49780,47119,13452,20215,49274,47617,49533,47878, + 13707,20464,8416,23195,54294,44653,54545,44906,8679,23452, + 55071,44388,9193,22930,8942,22677,54808,44131,54019,43384, + 10229,23950,9970,23689,53764,43135,9468,24199,53258,43633, + 53517,43894,9723,24448,56123,41280,12237,21942,11978,21681, + 55868,41031,11460,22207,55346,41545,55605,41806,11715,22456, + 10456,21155,56366,42581,56617,42834,10719,21412,57127,42332, + 11217,20906,10966,20653,56864,42075, +}, +{0,46002,31609,51403,63218,17728,36235,15929,61945,16971, + 35456,14642,1803,46265,31858,53184,65519,19549,33942,14116, + 2333,47791,29284,49622,3606,48548,30063,50909,63716,19286, + 33693,12335,58307,20593,39098,11016,5425,42627,28232,56826, + 4666,41352,26947,56049,58568,22394,40881,11267,7212,44958, + 26453,54503,60126,22892,37287,8725,60885,24167,38572,9502, + 6951,43157,24670,54252,56219,26665,41186,4944,11625,40667, + 22032,58786,10850,39376,20763,58025,56464,28450,42985,5211, + 9332,38854,24333,60607,53894,24884,43519,6733,54669,26175, + 44788,7494,9087,37069,22534,60340,14424,35818,17185,61587, + 52906,32024,46547,1633,51617,31251,45784,362,16211,36065, + 17450,63384,51127,29701,48334,3964,12613,33527,19004,63886, + 13902,34300,19767,65157,49340,29454,48069,2167,43819,6297, + 53330,25568,24025,61035,9888,38162,23250,59744,8619,37401, + 44064,8082,55129,25835,21700,59254,12221,39951,41526,4484, + 55631,27389,42301,5775,56900,28150,21455,57469,10422,39684, + 18664,64346,13201,32803,48666,3496,50531,30417,47377,2723, + 49768,29146,20451,64593,13466,34600,46855,1205,52350,32716, + 16885,62023,14988,35134,18174,62796,15751,36405,45068,958, + 52085,30919,28848,49922,3017,47227,34370,13808,64827,20105, + 33097,13051,64048,18818,30651,50185,3266,49008,36703,15597, + 62502,18324,31149,51743,724,45414,32422,52500,1503,46701, + 34900,15334,62253,16543,37747,8385,59402,23480,25985,54835, + 7928,44362,25226,53560,6643,43585,38008,10186,61185,23731, + 27804,57134,6117,42071,39534,10716,57623,21157,40293,11991, + 58908,21934,27543,55333,4334,41820, +}, +{0,22872,45744,60392,31101,8229,52173,37525,62202,43938, + 16458,6418,35719,53983,14647,24687,63977,41137,19289,4609, + 32916,55756,12836,27516,2835,21067,47523,57595,29294,11062, + 49374,39302,61391,46743,23935,1063,38578,53226,9218,32090, + 7477,17517,44933,63197,25672,15632,55032,36768,5670,20350, + 42134,64974,28507,13827,56811,33971,58588,48516,22124,3892, + 40353,50425,12049,30281,50051,39643,28979,10347,47870,58278, + 2126,20758,12665,26657,33737,55953,18436,4444,64180,41964, + 14954,25394,35034,53634,17175,6735,61863,43263,51344,37320, + 31264,9080,45549,59573,861,23045,11340,29972,40700,51108, + 21809,3177,59265,48857,57014,34798,27654,13662,42955,65171, + 5499,19491,54693,36093,26389,15949,44248,62848,7784,18224, + 10079,32263,38383,52407,24098,1914,60562,46538,39707,49731, + 10667,28915,57958,47934,20694,2446,27105,12473,56145,33289, + 4252,18884,41516,64372,25330,15274,53314,35098,7055,17111, + 43327,61543,36872,51536,8888,31712,59765,45101,23493,669, + 29908,11660,50788,40764,3497,21745,48921,58945,34350,57206, + 13470,28102,65363,42507,19939,5307,36157,54373,16269,26325, + 62528,44312,18160,8104,32711,9887,52599,37935,1722,24546, + 46090,60754,22680,448,59944,45936,8677,30909,37717,51725, + 43618,62266,6354,16778,54047,35399,25007,14583,41329,63529, + 5057,19097,55308,33108,27324,13284,21387,2771,57659,47203, + 10998,29614,38982,49438,46935,60943,1511,23743,52778,38770, + 31898,9666,17837,7413,63261,44613,15568,25992,36448,55096, + 20158,6118,64526,42326,14275,28315,34163,56363,48196,58652, + 3828,22444,50489,40033,30601,11985, +}, +{0,11309,22618,29815,45236,40089,59630,50371,32117,20824, + 9519,2306,52673,57836,38299,47542,64234,54983,41648,36509, + 19038,26227,4612,15913,34719,43954,57285,62440,14123,6918, + 28529,17244,59849,50660,45459,40382,22909,30032,295,11530, + 38076,47249,52454,57547,9224,2085,31826,20607,4899,16142, + 19321,26452,41879,36794,64461,55264,28246,17019,13836,6689, + 57058,62159,34488,43669,53135,58274,38869,48120,32571,21270, + 10081,2892,45818,40663,60064,50829,590,11875,23060,30265, + 13669,6472,27967,16658,34257,43516,56715,61862,18448,25661, + 4170,15463,63652,54409,41214,36051,9798,2667,32284,21041, + 38642,47839,52904,57989,23347,30494,873,12100,60295,51114, + 46045,40944,56492,61569,34038,43227,27672,16437,13378,6255, + 41433,36340,63875,54702,4461,15680,18743,25882,33539,44846, + 56153,63348,13239,8090,27629,18368,65142,53851,42540,35329, + 20162,25327,5784,15029,31209,21956,8627,3486,51549,58736, + 37127,48426,1180,10417,23750,28907,46120,38917,60530,49247, + 27338,18151,12944,7869,55934,63059,33316,44553,6079,15250, + 20453,25544,42763,35622,65361,54140,36896,48141,51322,58455, + 8340,3257,30926,21731,60757,49528,46351,39202,24033,29132, + 1467,10646,19596,24737,5334,14587,64568,53269,42082,34895, + 12793,7636,27043,17806,33101,44384,55575,62778,46694,39499, + 60988,49681,1746,11007,24200,29349,51987,59198,37705,48996, + 31655,22410,9213,4048,42309,35176,64799,53554,5617,14812, + 19883,24966,55344,62493,32874,44103,26756,17577,12510,7411, + 24495,29570,2037,11224,61211,49974,46913,39788,8922,3831, + 31360,22189,37486,48707,51764,58905, +}, +{0,39065,11567,46518,23134,49863,30577,61416,46268,11301, + 39315,266,61154,30331,50125,23380,30053,60924,22602,49363, + 12091,47010,532,39565,49625,22848,60662,29807,39815,798, + 46760,11825,60106,29267,51173,24444,45204,10253,40379,1314, + 24182,50927,29529,60352,1064,40113,10503,45470,40879,1846, + 45696,10777,50673,23912,59614,28743,11027,45962,1596,40613, + 29005,59860,23650,50427,51593,20752,58534,31807,37847,2894, + 48888,9825,32053,58796,20506,51331,10091,49138,2628,37597, + 48364,9333,37315,2394,59058,32299,52125,21252,2128,37065, + 9599,48614,21006,51863,32545,59320,9027,48090,3692,38645, + 31005,57732,21554,52395,38911,3942,47824,8777,52641,21816, + 57486,30743,22054,52927,31497,58256,3192,38113,8535,47566, + 58010,31235,53173,22316,47300,8285,38379,3442,36623,6038, + 41504,15033,54609,19912,63614,24807,15283,41770,5788,36357, + 25069,63860,19650,54363,64106,25331,55109,20444,41012,14509, + 36123,5506,20182,54863,25593,64352,5256,35857,14759,41278, + 26053,64860,18666,53363,16283,42754,4788,35373,53625,18912, + 64598,25807,35623,5054,42504,16017,4256,34873,15759,42262, + 19198,53863,26577,65352,42012,15493,35123,4522,65090,26331, + 54125,19444,18054,56863,27561,62256,7384,33857,12791,43374, + 62010,27299,57109,18316,43108,12541,34123,7634,13283,43898, + 7884,34389,27069,61732,17554,56331,34655,8134,43632,13033, + 56577,17816,61486,26807,44108,13525,33123,6650,62994,28299, + 56125,17316,6384,32873,13791,44358,17070,55863,28545,63256, + 55593,16816,62470,27807,33655,7150,44632,14017,28053,62732, + 16570,55331,14283,44882,6884,33405, +}, +{0,49859,39323,23384,12075,60904,46768,29811,24150,40085, + 51149,1294,29053,46014,59622,10789,48300,32367,9527,59380, + 37767,20804,2588,51423,58106,8249,31585,47522,52689,3858, + 21578,38537,25925,42886,64734,15901,19054,34989,54261,4406, + 15123,63952,41608,24651,5176,55035,36259,20320,55785,6954, + 16498,33457,63170,13313,28505,44442,34751,17788,7716,56551, + 43156,27223,12559,62412,51850,2121,21265,37330,58785,10082, + 31802,48889,38108,22047,3399,53124,48119,31028,8812,57519, + 30246,46309,61373,11646,22797,39886,49302,597,10352,60083, + 45547,29480,1883,50584,40640,23555,45007,27916,13908,62615, + 32996,16935,6527,56252,61849,13146,26626,43713,57010,7281, + 18217,34282,4963,53664,35576,18491,15432,65163,42451,26384, + 19765,36854,54446,5741,25118,41181,64389,14662,35081,19402, + 4242,53841,42530,25825,16313,64890,55135,5532,20164,35847, + 63604,15031,25071,41772,13733,63334,44094,28413,6798,55373, + 33557,16854,27635,43312,62056,12459,17624,34331,56643,8064, + 60492,11919,30167,46868,50023,420,23292,38975,45594,28889, + 11137,59714,40241,24562,1194,50793,20704,37411,51579,3000, + 32715,48392,58960,9363,3766,52341,38701,21998,8605,58206, + 47110,31429,17283,33088,55832,6363,27816,44651,62771,14320, + 7637,57110,33870,18061,13054,61501,43877,27046,65327,15852, + 26292,42103,53252,4807,18847,35676,41337,25530,14562,64033, + 36434,19601,6089,54538,9926,58373,48989,32158,2541,52014, + 36982,21173,30864,47699,57611,9160,22459,38264,52768,3299, + 39530,22697,1009,49458,46401,30594,11482,60953,50236,1791, + 23975,40804,60183,10708,29324,45135, +}, +{0,61422,50113,11311,39839,29809,22622,47024,11043,50381, + 59618,1804,45244,24402,29565,40083,22086,47528,38279,31337, + 52697,8759,3608,57846,32101,37515,48804,20810,59130,2324, + 9531,51925,44172,17250,28493,32931,14099,55549,62674,6972, + 34735,26689,17518,43904,7216,62430,57329,12319,64202,5412, + 14603,55013,24917,36539,41620,19834,53737,15879,4648,64966, + 19062,42392,35255,26201,17669,43755,34500,26922,56986,12660, + 7515,62133,28198,33224,44519,16905,62905,6743,13944,55702, + 4931,64685,53378,16236,35036,26418,19229,42227,14432,55182, + 64417,5199,41983,19473,24638,36816,59785,1639,10824,50598, + 29206,40440,45527,24121,49834,11588,363,61061,22837,46811, + 39668,29978,49103,20513,31758,37856,9296,52158,59281,2175, + 38124,31490,22317,47299,3955,57501,52402,9052,35338,26084, + 18891,42533,4501,65147,53844,15802,41257,20167,25320,36102, + 15030,54616,63863,5785,56396,13218,8077,61539,18387,43069, + 33810,27644,63343,6273,13486,56128,27888,33566,44849,16607, + 9862,51560,58695,2729,48409,21239,32472,37174,3493,57931, + 52836,8586,38458,31188,22011,47637,28864,40750,45825,23791, + 60255,1201,10398,51056,23523,46093,38946,30668,49276,12178, + 957,60499,53007,8417,3278,58144,21648,47998,38737,30911, + 58412,3010,10221,51203,32691,36957,48242,21404,39241,30375, + 23176,46438,726,60728,49431,12025,45674,23940,29099,40517, + 10741,50715,59956,1498,25475,35949,41026,20396,63516,6130, + 15325,54323,18592,42830,35681,25743,54079,15569,4350,65296, + 13765,55851,62980,6634,44634,16820,28059,33397,7910,61704, + 56615,13001,34169,27287,18104,43350, +}, +{0,30582,61164,39322,49605,46771,12073,22623,40855,59617, + 29051,1549,24146,10532,45246,51144,9011,21573,52703,47785, + 58102,38272,3098,31596,48292,52178,21064,9534,32097,2583, + 37773,58619,18022,12560,43146,57340,34723,61653,26959,7737, + 55793,44679,14109,16491,6196,28482,63192,33198,25941,4643, + 35769,64719,42128,54246,19068,15626,64194,36276,5166,25432, + 15111,19569,54763,41629,36044,64442,25120,5462,19721,14975, + 41957,54419,4955,25645,64951,35521,53918,42472,15474,19204, + 45055,55433,16659,13925,28218,6476,32982,63392,12392,18206, + 56964,43506,61869,34523,8001,26679,51882,48604,9286,21296, + 2927,31769,58755,37621,21821,8779,48081,52391,38136,58254, + 31252,3426,59801,40687,1909,28675,10332,24362,50864,45510, + 30222,376,39138,61332,47051,49341,22823,11857,1413,29427, + 60265,39967,50240,45878,10924,24026,39442,60772,29950,904, + 23511,11425,46395,49741,9910,20928,51290,48940,59251,36869, + 2463,32489,47393,52823,22477,8379,30948,3986,38408,57726, + 17379,13461,44303,55929,33318,62800,27850,7100,56436,43778, + 12952,17902,7601,27335,62301,33835,24784,6054,36412,63818, + 41237,54883,20473,14479,65351,34865,4523,26333,16002,18932, + 53358,42776,35145,65087,26533,4307,18572,16378,42592,53526, + 5854,25000,63538,36676,55067,41069,14839,20097,43642,56588, + 17558,13280,27583,7369,34131,61989,13805,17051,56065,44151, + 62504,33630,6852,28082,53039,47193,8643,22197,3818,31132, + 57350,38768,20664,10190,48724,51490,37245,58891,32657,2279, + 60444,39786,752,30086,11737,23215,49973,46147,29579,1277, + 40295,59921,45646,50488,23714,11220, +}, +{0,15162,30324,19790,60648,55250,39580,41382,50637,65271, + 46009,34947,10533,4639,24401,25707,38791,44221,57843,56009, + 31599,16469,3355,13857,21066,26992,9278,7940,48802,34200, + 51414,62444,13075,2089,17767,32349,57339,58561,43407,37557, + 63198,52708,32938,48016,6710,8460,27714,22392,42132,40878, + 53984,59866,18556,29510,15880,1330,24921,23139,5933,11287, + 36273,46731,64453,49407,26150,23836,4178,11112,35534,45556, + 64698,51072,41963,39121,54687,61093,20227,29753,14711,589, + 61857,51867,34773,48367,7497,9843,27453,20487,13420,3926, + 16920,31010,55428,58302,44784,38346,21813,28175,9025,6267, + 47581,33511,53161,62611,37112,43970,59020,56758,31760,18218, + 2660,12638,49842,63880,46278,36860,11866,5472,22574,25364, + 1919,15429,28939,18993,60311,53421,40419,42713,52300,63350, + 47672,33026,8356,7070,22224,28138,2433,12987,32757,17615, + 58729,56915,37661,43047,23499,24817,11711,5765,46883,35865, + 49495,64109,40454,42300,59506,54088,29422,18900,1178,16288, + 65375,50277,35115,45585,5047,10381,26051,24313,14994,424, + 19686,30684,54906,60736,40974,39732,26840,21474,7852,9622, + 33840,48906,62020,51582,44309,38447,56161,57435,16893,31431, + 14217,3251,43626,37200,56350,59172,18050,32184,12534,3020, + 28583,21661,6611,8937,33615,47221,62779,52737,15853,1751, + 19353,28835,53509,59967,42865,40011,63520,49946,36436,46446, + 5320,12274,25276,22918,39289,41539,61197,54327,30097,20139, + 997,14559,23732,26510,10944,4602,45148,35686,50728,64786, + 3838,13764,30858,17328,57878,55596,37986,44888,52019,61449, + 48455,34429,10203,7393,20911,27285, +}, +{0,7452,14904,10020,29808,26988,20040,21332,59616,62972, + 53976,53188,40080,33164,42664,48052,52701,53441,63461,60153, + 47533,42161,33685,40585,9533,14369,7941,537,20813,19537, + 27509,30313,34727,39611,48543,41091,62423,61131,51695,54515, + 28487,29275,21887,18531,6967,1579,8463,15379,19066,22374, + 28738,27998,15882,8982,1074,6446,41626,49030,39074,34238, + 55018,52214,60626,61902,4947,3663,10603,13431,26403,31295, + 23835,16391,64435,59055,49547,56471,36803,37599,46587,43239, + 56974,50066,58550,63914,43774,47074,37062,36314,13934,11122, + 3158,4426,16926,24322,30758,25914,38132,35304,44748,46032, + 57476,64920,55996,51104,31764,24840,17964,23344,2148,5496, + 12892,12096,22825,17461,25361,32269,11609,12357,5985,2685, + 45513,44245,35825,38637,50617,55461,65409,58013,9894,15290, + 7326,386,21206,20426,26862,30194,52806,54106,62590,59746, + 47670,42794,32782,40210,60283,63079,53571,52319,40715,33303, + 42291,47151,923,7815,14755,9407,30699,27383,19923,20687, + 41217,48157,39737,34341,54641,51309,61257,62037,18913,21757, + 29657,28357,15761,8333,1961,6837,27868,29120,22244,19448, + 6316,1456,8852,16264,33852,39200,48644,41752,61516,60752, + 51828,55144,13813,10473,4045,4817,16773,23705,31677,26273, + 56597,49161,59181,64049,43365,46201,37725,36417,63528,58676, + 49680,57100,35928,37188,46688,43900,4296,3540,10992,14316, + 25784,31140,24192,17308,45650,44878,34922,38262,50722,56126, + 64538,57606,23218,18350,24714,32150,11970,13278,5370,2534, + 32655,25235,17847,22699,3071,5859,12743,11483,38767,35443, + 44375,45131,58143,65027,55591,50235, +}, +{0,3599,7198,4625,14396,13875,9250,10797,28792,32375, + 27750,25193,18500,17995,21594,23125,57584,61183,64750,62177, + 55500,54979,50386,51933,37000,40583,35990,33433,43188,42683, + 46250,47781,56829,54258,49635,53228,58817,60366,63967,63440, + 44421,41866,45467,49044,38329,39862,35239,34728,15629,13058, + 8467,12060,1329,2878,6447,5920,19829,17274,20843,24420, + 30025,31558,26967,26456,42983,43496,48121,46582,40923,37332, + 33733,36298,55199,55696,52097,50574,61347,57772,62397,64946, + 18199,18712,23305,21766,32555,28964,25397,27962,14191,14688, + 11121,9598,3923,348,4941,7490,31258,29717,26116,26635, + 16934,19497,24120,20535,2658,1133,5756,6259,12894,15441, + 11840,8271,39658,38117,34548,35067,41686,44249,48840,45255, + 60050,58525,63116,63619,53934,56481,52912,49343,21459,24028, + 20429,16834,27631,26080,30705,31230,9131,11684,16309,12730, + 7063,5528,1929,2438,45859,48428,44861,41266,35615,34064, + 38657,39182,50011,52564,57157,53578,64359,62824,59257,59766, + 36398,32801,37424,39999,46610,47133,43532,41987,65110,61529, + 57928,60487,50794,51301,55924,54395,28382,24785,29376,31951, + 22242,22765,19196,17651,7846,4265,696,3255,9882,10389, + 14980,13451,62516,64059,59434,58917,52232,49671,53270,56857, + 33868,35395,38994,38493,48240,45695,41070,44641,5316,6859, + 2266,1749,11512,8951,12518,16105,25788,27315,30882,30381, + 23680,21135,16542,20113,10697,10182,13783,15320,4597,8186, + 3563,996,22961,22462,17839,19360,24973,28546,32147,29596, + 51513,50998,54567,56104,61701,65290,60699,58132,47425,46926, + 42335,43856,33149,36722,40291,37740, +}, +{0,35208,3853,34437,7706,38802,4375,39071,15412,46524, + 13113,47793,8750,43942,11555,42155,30824,61920,30565,65261, + 26226,61434,27007,57591,17500,52692,19281,49881,23110,54222, + 21835,56515,61648,31064,65501,30293,61130,26434,57799,26703, + 52452,17772,50153,19041,54014,23414,56819,21627,35000,304, + 34741,3645,38562,7978,39343,4135,46220,15620,48001,12809, + 43670,8990,42395,11283,64957,29749,62128,31544,58279,27183, + 60586,25890,49545,18433,52868,18188,57235,22043,53406,22806, + 34261,3165,35544,848,39887,4679,38082,7498,47585,12393, + 46828,16228,43003,11891,43254,8574,3437,34021,608,35816, + 4983,39679,7290,38386,12633,47313,15956,47068,12099,42699, + 8270,43462,29957,64653,31240,62336,27423,58007,25618,60826, + 18737,49337,17980,53172,22315,56995,22566,53678,59239,28399, + 59498,25058,63869,28917,63088,32760,56147,21211,54366,24022, + 50505,19649,51780,17356,40719,5767,36866,6538,33045,2205, + 36376,1936,41787,10931,44086,9662,48417,13481,45612,15268, + 6071,40511,6330,37170,2477,32805,1696,36648,11139,41483, + 9358,44294,13721,48145,14996,45852,28639,58967,24786,59738, + 29125,63565,32456,63296,21483,55907,23782,54638,19953,50297, + 17148,52084,6874,37714,5591,40031,1216,36168,3021,33349, + 9966,44902,10723,41067,14580,45436,14329,48753,25266,60218, + 28095,58423,31912,62752,29605,64045,24198,55054,20875,55299, + 16540,51476,20369,50713,59914,25474,58631,27791,62480,32152, + 64285,29333,54846,24502,55603,20667,51236,16812,50985,20129, + 37474,7146,40303,5351,35960,1520,33653,2813,44630,10206, + 41307,10451,45132,14788,48961,14025, +}, +{0,17477,34954,52431,3337,18764,34179,49606,6674,24151, + 37528,55005,5915,21342,40849,56276,13348,28769,48302,63723, + 14637,32104,45479,62946,11830,27251,42684,58105,9023,26490, + 43957,61424,26696,11277,57538,42119,25921,8452,60875,43406, + 29274,13855,64208,48789,32595,15126,63449,45980,23660,6185, + 54502,37027,20837,5408,55791,40362,18046,571,52980,35505, + 19319,3890,50173,34744,53392,38101,22554,7263,56729,39388, + 21779,4438,51842,36551,16904,1613,51083,33742,20225,2884, + 58548,41201,27710,10363,59837,44536,24887,9586,65190,47843, + 30252,12905,62383,47082,31525,16224,47320,64669,12370,29719, + 46545,61844,15707,31006,41674,59023,10816,28165,44995,60294, + 10057,25356,36092,51385,1142,16435,33269,50608,2431,19770, + 38638,53931,7780,23073,39911,57250,4973,22312,48445,63864, + 13751,29170,45108,62577,14526,31995,42799,58218,12197,27616, + 43558,61027,8876,26345,35097,52572,403,17878,33808,49237, + 3226,18655,37643,55118,7041,24516,40450,55879,5768,21197, + 54645,37168,24063,6586,55420,39993,20726,5299,53095,35618, + 18413,936,49774,34347,19172,3745,57681,42260,27099,11678, + 60504,43037,25810,8343,64323,48902,29641,14220,63050,45583, + 32448,14981,28077,10728,58663,41314,24740,9441,59438,44139, + 30655,13306,65333,47984,31414,16115,62012,46713,22921,7628, + 53507,38214,21632,4293,56330,38991,17307,2014,51985,36692, + 20114,2775,50712,33373,1509,16800,36207,51498,2284,19625, + 32870,50211,8183,23474,38781,54072,4862,22203,39540,56881, + 12737,30084,47435,64782,15560,30861,46146,61447,11219,28566, + 41817,59164,9946,25247,44624,59925, +}, +{0,44205,17735,59882,35470,9763,53193,25444,2305,42412, + 19526,57579,33679,12066,50888,27237,4610,48815,22341,64488, + 39052,13345,56779,29030,6915,47022,24132,62185,37261,15648, + 54474,30823,9220,34985,24899,52718,44682,551,60365,18272, + 11525,33192,26690,50415,42891,2854,58060,20065,13830,39595, + 29505,57324,48264,4133,63951,21858,16135,37802,31296,55021, + 46473,6436,61646,23651,18440,58533,3407,41442,49798,28203, + 34753,11116,16649,60836,1102,43235,52103,26410,36544,8813, + 23050,63143,8013,46048,53380,31785,38339,14702,21259,65446, + 5708,47841,55685,29992,40130,12399,27660,49313,10571,34278, + 59010,18991,41925,3944,25869,51616,8266,36071,61315,17198, + 43716,1641,32270,53923,15177,38884,62592,22573,45511,7530, + 30479,56226,12872,40677,64897,20780,47302,5227,36880,15549, + 54615,31226,6814,46643,24537,62324,39185,13756,56406,28923, + 5023,48946,22232,64117,33298,11967,51029,27640,2204,42033, + 19931,57718,35603,10174,52820,25337,413,44336,17626,59511, + 46100,6329,61779,24062,16026,37431,31709,55152,48405,4536, + 63570,21759,14235,39734,29404,56945,42518,2747,58193,20476, + 11416,32821,27103,50546,44823,954,59984,18173,9625,35124, + 24798,52339,55320,29877,40287,12786,21142,65083,6097,47996, + 53529,32180,37982,14579,23447,63290,7888,45693,51738,26295, + 36701,9200,16532,60473,1491,43390,49947,28598,34396,10993, + 18837,58680,3282,41087,64540,20657,47451,5622,30354,55871, + 13269,40824,62749,22960,45146,7415,32659,54078,15060,38521, + 60958,17075,43865,2036,25744,51261,8663,36218,59167,19378, + 41560,3829,28049,49468,10454,33915, +}, +{0,55513,44463,30070,18243,40858,60140,12853,36486,22111, + 9001,64496,51653,4380,25706,48307,273,55752,44222,29799, + 18002,40587,60413,13092,36759,22350,8760,64225,51412,4109, + 25979,48546,546,56059,44941,30548,17761,40376,59598,12311, + 36004,21629,8459,63954,52199,4926,26184,48785,819,56298, + 44700,30277,17520,40105,59871,12550,36277,21868,8218,63683, + 51958,4655,26457,49024,1092,56477,43499,28978,17159,39902, + 61096,13937,35522,21019,10093,65460,52609,5464,24622,47351, + 1365,56716,43258,28707,16918,39631,61369,14176,35795,21258, + 9852,65189,52368,5193,24895,47590,1638,57023,43977,29456, + 16677,39420,60554,13395,35040,20537,9551,64918,53155,6010, + 25100,47829,1911,57262,43736,29185,16436,39149,60827,13634, + 35313,20776,9310,64647,52914,5739,25373,48068,2184,53329, + 42279,32254,20427,38674,57956,15037,34318,24279,11169,62328, + 49485,6548,27874,46139,2457,53568,42038,31983,20186,38403, + 58229,15276,34591,24518,10928,62057,49244,6277,28147,46378, + 2730,53875,42757,32732,19945,38192,57414,14495,33836,23797, + 10627,61786,50031,7094,28352,46617,3003,54114,42516,32461, + 19704,37921,57687,14734,34109,24036,10386,61515,49790,6823, + 28625,46856,3276,54293,41315,31162,19343,37718,58912,16121, + 33354,23187,12261,63292,50441,7632,26790,45183,3549,54532, + 41074,30891,19102,37447,59185,16360,33627,23426,12020,63021, + 50200,7361,27063,45422,3822,54839,41793,31640,18861,37236, + 58370,15579,32872,22705,11719,62750,50987,8178,27268,45661, + 4095,55078,41552,31369,18620,36965,58643,15818,33145,22944, + 11478,62479,50746,7907,27541,45900, +}, +{0,58083,55771,15160,44971,19784,30320,38035,17227,41384, + 39568,30835,60640,3587,13627,55256,34454,25717,24397,48558, + 10557,52190,61670,4613,50653,10046,7174,65253,27254,34965, + 45997,20814,4401,62418,51434,10761,48794,23673,26433,34210, + 21114,45209,35745,26946,64977,7986,9226,50921,38823,30020, + 20092,44191,14348,56047,57815,820,54508,13839,3383,61396, + 31559,39332,41628,16511,8802,49281,64441,6490,36297,28458, + 21522,46833,24873,33738,47346,23057,52866,11361,5977,62906, + 42228,17943,32047,40908,2911,59836,53892,12391,59327,1372, + 15972,56455,18452,43767,37327,29484,13139,53680,60040,2155, + 40184,32283,17699,42944,28696,37627,43459,19232,57267,15696, + 1640,58507,46533,22310,27678,36605,6766,63629,50101,8534, + 63118,5229,12117,52662,22821,48070,33022,25117,17604,42535, + 40223,32764,60271,2444,12980,53335,1935,58732,56916,15543, + 43044,19143,29183,37660,49746,8369,7049,63850,28153,36634, + 46114,22209,33049,25594,22722,47649,11954,52305,63337,5514, + 22005,46870,35886,28365,64094,6333,9093,49510,5822,62557, + 53093,11654,47381,23542,24782,33325,54115,12672,2744,59483, + 31944,40491,42259,18416,36904,29387,18931,43792,16259,56672, + 58968,1211,26278,33861,49021,23966,51469,11246,4310,62005, + 9709,50958,64566,7893,35398,26789,21405,45438,57392,723, + 14827,56072,20379,44408,38464,29859,41851,16792,31392,38979, + 3280,60979,54539,14312,30615,38260,44620,19631,55356,15071, + 487,58116,13532,54847,60679,4068,39799,31124,17068,41039, + 61697,5090,10458,51769,24234,48201,34673,26002,45642,20649, + 27537,35186,7649,65282,50234,9945, +}, +{0,65534,58337,7199,56287,9249,14398,51136,43939,21597, + 18498,47036,28796,36738,37789,27747,19291,46245,43194,22340, + 36996,28538,29541,35995,57592,7942,793,64743,15143,50393, + 55494,10040,38582,26952,30039,35497,19817,45719,44680,20854, + 15637,49899,57076,8458,59082,6452,1323,64213,56813,8723, + 15884,49650,1586,63948,58835,6701,30286,35248,38319,27217, + 44433,21103,20080,45454,12657,52879,53904,11630,60078,5456, + 2383,63153,39634,25900,31027,34509,16653,48883,41708,23826, + 31274,34260,39371,26165,41461,24075,16916,48618,53641,11895, + 12904,52630,2646,62888,59831,5705,42951,22585,17446,48088, + 31768,33766,40953,24583,3172,62362,61317,4219,55227,10309, + 13402,52132,60572,4962,3965,61571,14147,51389,54434,11100, + 18239,47297,42206,23328,40160,25374,32513,33023,25314,40220, + 33027,32509,47421,18115,23260,42274,51521,14015,10912,54622, + 4766,60768,61823,3713,10681,54855,51800,13734,62054,3480, + 4487,61049,33306,32228,25083,40453,22981,42555,47652,17882, + 62548,2986,6069,59467,12171,53365,52330,13204,24567,40969, + 48150,17384,33832,31702,26569,38967,48911,16625,23790,41744, + 25808,39726,34609,30927,5292,60242,63309,2227,53107,12429, + 11410,54124,21395,44141,45170,20364,34892,30642,27565,37971, + 63536,1998,7121,58415,9199,56337,49166,16368,6344,59190, + 64297,1239,49943,15593,8438,57096,45931,19605,20618,44916, + 26804,38730,35669,29867,50469,15067,9924,55610,7930,57604, + 64795,741,28294,37240,36199,29337,46425,19111,22200,43334, + 36478,29056,28063,37473,21921,43615,46656,18878,9693,55843, + 50748,14786,65026,508,7651,57885, +}, +{0,32638,65276,33154,57829,40603,7961,24679,57303,41129, + 8491,24149,15922,16716,49358,49072,41907,56525,23887,8753, + 16982,15656,48298,50132,31844,794,33432,64998,40321,58111, + 25469,7171,23419,9221,42375,56057,47774,50656,17506,15132, + 33964,64466,31312,1326,25929,6711,39861,58571,63688,34742, + 1588,31050,6445,26195,59345,39087,10015,22625,55779,42653, + 50938,47492,14342,18296,46838,51592,18442,14196,22291,10349, + 43503,54929,26913,5727,38877,59555,35012,63418,30264,2374, + 5445,27195,60345,38087,62624,35806,2652,29986,51858,46572, + 13422,19216,11127,21513,54667,43765,60813,37619,4977,27663, + 3176,29462,62100,36330,12890,19748,52390,46040,54207,44225, + 11587,21053,20030,12608,45250,53180,45019,53413,20775,11865, + 37353,61079,28437,4203,28684,3954,36592,61838,29169,3727, + 36621,61555,36884,61290,28392,4502,44582,53592,20698,12196, + 20419,12477,45375,52801,53826,44348,11454,21440,13223,19673, + 52571,45605,3477,29419,62313,35863,60528,37646,4748,28146, + 10890,22004,54390,43784,52079,46097,13715,19181,62813,35363, + 2977,29919,5304,27590,59972,38202,35129,63047,30661,2235, + 26844,6050,38432,59742,22254,10640,43026,55148,46859,51317, + 18935,13961,50951,47225,14843,18053,9954,22940,55326,42848, + 6352,26542,58924,39250,63797,34379,1993,30903,25780,7114, + 39496,58678,34129,64047,31661,1235,47971,50205,17823,15073, + 23174,9720,42106,56068,40060,58114,25216,7678,32153,743, + 33637,64539,17323,15573,48471,49705,41550,56624,23730,9164, + 16335,16561,49459,48717,56874,41300,8406,24488,57368,40806, + 7908,24986,509,32387,65281,32895, +}, +{0,16190,32380,16706,64760,50118,33412,48570,58861,56019, + 39825,42159,6421,9771,26473,22615,55239,59641,43451,38533, + 11071,5121,21827,27261,12842,3348,19542,29544,52946,61932, + 45230,36752,45971,36013,52719,62161,20331,28757,12567,3625, + 22142,26944,10242,5948,43654,38328,54522,60356,25684,23402, + 6696,9494,39084,42898,59088,55790,33209,48775,65477,49403, + 32065,17023,829,15363,31547,17413,1351,14969,34755,47357, + 63935,50817,40662,41448,57514,57236,25134,23824,7250,9068, + 44284,37826,53888,60862,20484,28474,11896,4422,18705,30255, + 14189,2131,46569,35543,52117,62635,51368,63382,46804,35306, + 13392,2926,18988,29970,11589,4731,21305,27655,53693,61059, + 44993,37119,8047,8273,24851,24109,58263,56489,40427,41685, + 64130,50620,34046,48064,1658,14660,30726,18232,63094,51528, + 34826,46900,2702,13744,29938,19404,5019,11429,28135,21209, + 61283,53341,37151,44577,8625,7823,24525,24819,56649,57975, + 41781,39947,50268,64354,47648,34078,14500,1946,18136,31206, + 17893,31451,15257,1191,47389,34339,51041,63583,40968,40758, + 56948,57674,23792,25550,8844,7602,37410,44316,60510,54112, + 28378,20964,4262,12184,30671,18673,2483,13965,35639,46089, + 62795,51829,36173,45683,62257,52239,29109,20107,4041,12535, + 26784,22430,5852,10722,37976,43878,59940,54554,23178,26036, + 9462,7112,42610,39244,55310,59184,48999,32857,49435,65061, + 17311,31905,15843,733,16094,480,16546,32668,49702,64792, + 48218,33636,56115,58381,42319,39537,10187,6389,22967,26249, + 59673,54823,38757,43099,5601,10975,27549,21667,3316,13258, + 29320,19894,61452,53042,36464,45390, +}, +{0,7966,15932,8482,31864,25446,16964,23898,63728,59374, + 50892,55762,33928,39830,47796,42410,60925,62179,54209,52447, + 37253,36507,44985,45223,5389,2579,11057,13359,26997,30315, + 22345,18519,51175,55545,63963,59077,48031,42113,34211,39613, + 16151,8201,299,7733,17263,23665,32083,25165,10778,13572, + 5158,2872,22114,18812,26718,30528,53994,52724,60630,62408, + 44690,45452,37038,36784,37843,36045,44527,45809,61355,61621, + 53655,52873,27427,29757,21791,18945,5979,2117,10599,13945, + 32302,24880,16402,24332,598,7496,15466,9076,34526,39360, + 47330,43004,64166,58808,50330,56196,21556,19242,27144,29974, + 10316,14162,5744,2414,44228,46042,37624,36326,53436,53154, + 61056,61854,47561,42711,34805,39147,50609,55983,64397,58515, + 16697,24103,32517,24603,15681,8799,893,7267,15291,9381, + 1415,6809,18371,22749,31231,26337,49995,56405,64887,57961, + 48947,41005,33039,40465,54854,51544,59514,63332,43582,46368, + 37890,35612,11958,12712,4234,3988,21198,19920,27890,29676, + 64604,58178,49760,56702,32804,40762,48664,41222,1196,7090, + 14992,9614,30932,26570,18152,23030,4513,3775,12189,12419, + 28121,29383,21477,19707,59729,63055,55149,51315,38185,35383, + 43797,46091,43112,46966,38484,35146,54288,51982,59948,62770, + 20632,20358,28324,29114,11488,13310,4828,3522,17813,23179, + 31657,25783,14829,9971,2001,6351,48485,41595,33625,40007, + 49437,56835,65313,57407,28559,28817,20915,20141,5111,3305, + 11723,13013,38783,34913,43331,46685,60167,62489,54587,51749, + 33394,40300,48206,41808,65034,57620,49206,57128,31362,26012, + 17598,23456,1786,6628,14534,10200, +}, +{0,3854,7708,4370,15416,13110,8740,11562,30832,30590, + 26220,26978,17480,19270,23124,21850,61664,65518,61180,57842, + 52440,50134,53956,56778,34960,34718,38540,39298,46248,48038, + 43700,42426,64989,62163,58305,60623,49637,52971,57337,53495, + 34221,35491,39857,38079,47509,46747,42889,43143,3389,563, + 4897,7215,12549,15883,12057,8215,30029,31299,27473,25695, + 18805,18043,22377,22631,59303,59561,63931,63157,56223,54417, + 50563,51853,40919,37081,33227,36549,41967,44257,48627,45821, + 5959,6217,2395,1621,11135,9329,13667,14957,28471,24633, + 28971,32293,21263,23553,19731,16925,6778,5492,1126,2920, + 9794,10572,14430,14160,25098,27908,31766,29464,24114,20796, + 16430,20256,60058,58772,62598,64392,54946,55724,51390,51120, + 37610,40420,36086,33784,44754,41436,45262,49088,54099,56413, + 52559,49729,61291,57445,61815,65145,43811,42029,46399,47665, + 38683,38933,35079,34313,9139,11453,15791,12961,8075,4229, + 407,3737,23491,21709,17887,19153,26619,26869,31207,30441, + 11918,8576,12434,16284,4790,7608,3242,932,22270,23024, + 18658,18412,27334,26056,29914,31700,56942,53600,49266,53116, + 57942,60760,64586,62276,42526,43280,47106,46860,39462,38184, + 33850,35636,13556,15354,10984,9702,2252,1986,5840,6622, + 19588,17290,21144,23958,28860,32690,28320,25006,50196,51994, + 55816,54534,63532,63266,58928,59710,48228,45930,41592,44406, + 32860,36690,40512,37198,51497,50727,55093,55355,62737,64031, + 60173,58371,45401,48727,44869,41035,36193,33391,37757,40051, + 14793,14023,10197,10459,1521,2815,7149,5347,16825,20151, + 24485,20651,32129,29327,25501,27795, +}, +{0,1798,3596,2314,7192,6942,4628,5394,14384,16182, + 13884,12602,9256,9006,10788,11554,28768,30566,32364,31082, + 27768,27518,25204,25970,18512,20310,18012,16730,21576,21326, + 23108,23874,57536,59334,61132,59850,64728,64478,62164,62930, + 55536,57334,55036,53754,50408,50158,51940,52706,37024,38822, + 40620,39338,36024,35774,33460,34226,43152,44950,42652,41370, + 46216,45966,47748,48514,56733,55963,54161,54423,49541,50819, + 53129,51343,58797,58027,60321,60583,63925,65203,63417,61631, + 44541,43771,41969,42231,45541,46819,49129,47343,38349,37579, + 39873,40135,35285,36563,34777,32991,15709,14939,13137,13399, + 8517,9795,12105,10319,1389,619,2913,3175,6517,7795, + 6009,4223,19773,19003,17201,17463,20773,22051,24361,22575, + 29965,29195,31489,31751,26901,28179,26393,24607,42791,40993, + 43307,44589,47935,48185,46387,45621,40727,38929,37147,38429, + 33551,33801,36099,35333,55111,53313,55627,56909,52063,52313, + 50515,49749,61303,59505,57723,59005,62319,62569,64867,64101, + 18407,16609,18923,20205,23551,23801,22003,21237,32727,30929, + 29147,30429,25551,25801,28099,27333,14215,12417,14731,16013, + 11167,11417,9619,8853,4023,2225,443,1725,5039,5289, + 7587,6821,31418,32188,29878,29616,26274,24996,26798,28584, + 17034,17804,19590,19328,24210,22932,20638,22424,2778,3548, + 1238,976,5826,4548,6350,8136,13034,13804,15590,15328, + 12018,10740,8446,10232,39546,40316,38006,37744,34402,33124, + 34926,36712,41546,42316,44102,43840,48722,47444,45150,46936, + 59930,60700,58390,58128,62978,61700,63502,65288,53802,54572, + 56358,56096,52786,51508,49214,51000, +}, +{0,770,1540,1286,3080,3850,2572,2318,6160,6930, + 7700,7446,5144,5914,4636,4382,12320,13090,13860,13606, + 15400,16170,14892,14638,10288,11058,11828,11574,9272,10042, + 8764,8510,24640,25410,26180,25926,27720,28490,27212,26958, + 30800,31570,32340,32086,29784,30554,29276,29022,20576,21346, + 22116,21862,23656,24426,23148,22894,18544,19314,20084,19830, + 17528,18298,17020,16766,49280,50050,50820,50566,52360,53130, + 51852,51598,55440,56210,56980,56726,54424,55194,53916,53662, + 61600,62370,63140,62886,64680,65450,64172,63918,59568,60338, + 61108,60854,58552,59322,58044,57790,41152,41922,42692,42438, + 44232,45002,43724,43470,47312,48082,48852,48598,46296,47066, + 45788,45534,37088,37858,38628,38374,40168,40938,39660,39406, + 35056,35826,36596,36342,34040,34810,33532,33278,40221,40479, + 39705,38939,37141,37399,38673,37907,34061,34319,33545,32779, + 35077,35335,36609,35843,44349,44607,43833,43067,41269,41527, + 42801,42035,46381,46639,45865,45099,47397,47655,48929,48163, + 64861,65119,64345,63579,61781,62039,63313,62547,58701,58959, + 58185,57419,59717,59975,61249,60483,52605,52863,52089,51323, + 49525,49783,51057,50291,54637,54895,54121,53355,55653,55911, + 57185,56419,23965,24223,23449,22683,20885,21143,22417,21651, + 17805,18063,17289,16523,18821,19079,20353,19587,28093,28351, + 27577,26811,25013,25271,26545,25779,30125,30383,29609,28843, + 31141,31399,32673,31907,15837,16095,15321,14555,12757,13015, + 14289,13523,9677,9935,9161,8395,10693,10951,12225,11459, + 3581,3839,3065,2299,501,759,2033,1267,5613,5871, + 5097,4331,6629,6887,8161,7395, +}, +}; diff --git a/libedc/scramble_table b/libedc/scramble_table new file mode 100644 index 0000000..41b8309 --- /dev/null +++ b/libedc/scramble_table @@ -0,0 +1,621 @@ +/* @(#)scramble_table 1.2 02/10/19 */ + +/* + * 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. + */ + +static const unsigned char yellowbook_scrambler[2340] = { + 1,128,0,96,0,40,0,30,128,8,96,6,168,2,254,129,128,96,96,40,40,30,158, + 136,104,102,174,170,252,127,1,224,0,72,0,54,128,22,224,14,200,4,86,131,126,225, + 224,72,72,54,182,150,246,238,198,204,82,213,253,159,1,168,0,126,128,32,96,24,40, + 10,158,135,40,98,158,169,168,126,254,160,64,120,48,34,148,25,175,74,252,55,1,214, + 128,94,224,56,72,18,182,141,182,229,182,203,54,215,86,222,190,216,112,90,164,59,59, + 83,83,125,253,225,129,136,96,102,168,42,254,159,0,104,0,46,128,28,96,9,232,6, + 206,130,212,97,159,104,104,46,174,156,124,105,225,238,200,76,86,181,254,247,0,70,128, + 50,224,21,136,15,38,132,26,227,75,9,247,70,198,178,210,245,157,135,41,162,158,249, + 168,66,254,177,128,116,96,39,104,26,174,139,60,103,81,234,188,79,49,244,20,71,79, + 114,180,37,183,91,54,187,86,243,126,197,224,83,8,61,198,145,146,236,109,141,237,165, + 141,187,37,179,91,53,251,87,3,126,129,224,96,72,40,54,158,150,232,110,206,172,84, + 125,255,97,128,40,96,30,168,8,126,134,160,98,248,41,130,158,225,168,72,126,182,160, + 118,248,38,194,154,209,171,28,127,73,224,54,200,22,214,142,222,228,88,75,122,183,99, + 54,169,214,254,222,192,88,80,58,188,19,49,205,212,85,159,127,40,32,30,152,8,106, + 134,175,34,252,25,129,202,224,87,8,62,134,144,98,236,41,141,222,229,152,75,42,183, + 95,54,184,22,242,142,197,164,83,59,125,211,97,157,232,105,142,174,228,124,75,97,247, + 104,70,174,178,252,117,129,231,32,74,152,55,42,150,159,46,232,28,78,137,244,102,199, + 106,210,175,29,188,9,177,198,244,82,199,125,146,161,173,184,125,178,161,181,184,119,50, + 166,149,186,239,51,12,21,197,207,19,20,13,207,69,148,51,47,85,220,63,25,208,10, + 220,7,25,194,138,209,167,28,122,137,227,38,201,218,214,219,30,219,72,91,118,187,102, + 243,106,197,239,19,12,13,197,197,147,19,45,205,221,149,153,175,42,252,31,1,200,0, + 86,128,62,224,16,72,12,54,133,214,227,30,201,200,86,214,190,222,240,88,68,58,179, + 83,53,253,215,1,158,128,104,96,46,168,28,126,137,224,102,200,42,214,159,30,232,8, + 78,134,180,98,247,105,134,174,226,252,73,129,246,224,70,200,50,214,149,158,239,40,76, + 30,181,200,119,22,166,142,250,228,67,11,113,199,100,82,171,125,191,97,176,40,116,30, + 167,72,122,182,163,54,249,214,194,222,209,152,92,106,185,239,50,204,21,149,207,47,20, + 28,15,73,196,54,211,86,221,254,217,128,90,224,59,8,19,70,141,242,229,133,139,35, + 39,89,218,186,219,51,27,85,203,127,23,96,14,168,4,126,131,96,97,232,40,78,158, + 180,104,119,110,166,172,122,253,227,1,137,192,102,208,42,220,31,25,200,10,214,135,30, + 226,136,73,166,182,250,246,195,6,209,194,220,81,153,252,106,193,239,16,76,12,53,197, + 215,19,30,141,200,101,150,171,46,255,92,64,57,240,18,196,13,147,69,173,243,61,133, + 209,163,28,121,201,226,214,201,158,214,232,94,206,184,84,114,191,101,176,43,52,31,87, + 72,62,182,144,118,236,38,205,218,213,155,31,43,72,31,118,136,38,230,154,202,235,23, + 15,78,132,52,99,87,105,254,174,192,124,80,33,252,24,65,202,176,87,52,62,151,80, + 110,188,44,113,221,228,89,139,122,231,99,10,169,199,62,210,144,93,172,57,189,210,241, + 157,132,105,163,110,249,236,66,205,241,149,132,111,35,108,25,237,202,205,151,21,174,143, + 60,100,17,235,76,79,117,244,39,7,90,130,187,33,179,88,117,250,167,3,58,129,211, + 32,93,216,57,154,146,235,45,143,93,164,57,187,82,243,125,133,225,163,8,121,198,162, + 210,249,157,130,233,161,142,248,100,66,171,113,191,100,112,43,100,31,107,72,47,118,156, + 38,233,218,206,219,20,91,79,123,116,35,103,89,234,186,207,51,20,21,207,79,20,52, + 15,87,68,62,179,80,117,252,39,1,218,128,91,32,59,88,19,122,141,227,37,137,219, + 38,219,90,219,123,27,99,75,105,247,110,198,172,82,253,253,129,129,160,96,120,40,34, + 158,153,168,106,254,175,0,124,0,33,192,24,80,10,188,7,49,194,148,81,175,124,124, + 33,225,216,72,90,182,187,54,243,86,197,254,211,0,93,192,57,144,18,236,13,141,197, + 165,147,59,45,211,93,157,249,169,130,254,225,128,72,96,54,168,22,254,142,192,100,80, + 43,124,31,97,200,40,86,158,190,232,112,78,164,52,123,87,99,126,169,224,126,200,32, + 86,152,62,234,144,79,44,52,29,215,73,158,182,232,118,206,166,212,122,223,99,24,41, + 202,158,215,40,94,158,184,104,114,174,165,188,123,49,227,84,73,255,118,192,38,208,26, + 220,11,25,199,74,210,183,29,182,137,182,230,246,202,198,215,18,222,141,152,101,170,171, + 63,63,80,16,60,12,17,197,204,83,21,253,207,1,148,0,111,64,44,48,29,212,9, + 159,70,232,50,206,149,148,111,47,108,28,45,201,221,150,217,174,218,252,91,1,251,64, + 67,112,49,228,20,75,79,119,116,38,167,90,250,187,3,51,65,213,240,95,4,56,3, + 82,129,253,160,65,184,48,114,148,37,175,91,60,59,81,211,124,93,225,249,136,66,230, + 177,138,244,103,7,106,130,175,33,188,24,113,202,164,87,59,126,147,96,109,232,45,142, + 157,164,105,187,110,243,108,69,237,243,13,133,197,163,19,57,205,210,213,157,159,41,168, + 30,254,136,64,102,176,42,244,31,7,72,2,182,129,182,224,118,200,38,214,154,222,235, + 24,79,74,180,55,55,86,150,190,238,240,76,68,53,243,87,5,254,131,0,97,192,40, + 80,30,188,8,113,198,164,82,251,125,131,97,161,232,120,78,162,180,121,183,98,246,169, + 134,254,226,192,73,144,54,236,22,205,206,213,148,95,47,120,28,34,137,217,166,218,250, + 219,3,27,65,203,112,87,100,62,171,80,127,124,32,33,216,24,90,138,187,39,51,90, + 149,251,47,3,92,1,249,192,66,208,49,156,20,105,207,110,212,44,95,93,248,57,130, + 146,225,173,136,125,166,161,186,248,115,2,165,193,187,16,115,76,37,245,219,7,27,66, + 139,113,167,100,122,171,99,63,105,208,46,220,28,89,201,250,214,195,30,209,200,92,86, + 185,254,242,192,69,144,51,44,21,221,207,25,148,10,239,71,12,50,133,213,163,31,57, + 200,18,214,141,158,229,168,75,62,183,80,118,188,38,241,218,196,91,19,123,77,227,117, + 137,231,38,202,154,215,43,30,159,72,104,54,174,150,252,110,193,236,80,77,252,53,129, + 215,32,94,152,56,106,146,175,45,188,29,177,201,180,86,247,126,198,160,82,248,61,130, + 145,161,172,120,125,226,161,137,184,102,242,170,197,191,19,48,13,212,5,159,67,40,49, + 222,148,88,111,122,172,35,61,217,209,154,220,107,25,239,74,204,55,21,214,143,30,228, + 8,75,70,183,114,246,165,134,251,34,195,89,145,250,236,67,13,241,197,132,83,35,125, + 217,225,154,200,107,22,175,78,252,52,65,215,112,94,164,56,123,82,163,125,185,225,178, + 200,117,150,167,46,250,156,67,41,241,222,196,88,83,122,189,227,49,137,212,102,223,106, + 216,47,26,156,11,41,199,94,210,184,93,178,185,181,178,247,53,134,151,34,238,153,140, + 106,229,239,11,12,7,69,194,179,17,181,204,119,21,230,143,10,228,7,11,66,135,113, + 162,164,121,187,98,243,105,133,238,227,12,73,197,246,211,6,221,194,217,145,154,236,107, + 13,239,69,140,51,37,213,219,31,27,72,11,118,135,102,226,170,201,191,22,240,14,196, + 4,83,67,125,241,225,132,72,99,118,169,230,254,202,192,87,16,62,140,16,101,204,43, + 21,223,79,24,52,10,151,71,46,178,156,117,169,231,62,202,144,87,44,62,157,208,105, + 156,46,233,220,78,217,244,90,199,123,18,163,77,185,245,178,199,53,146,151,45,174,157, + 188,105,177,238,244,76,71,117,242,167,5,186,131,51,33,213,216,95,26,184,11,50,135, + 85,162,191,57,176,18,244,13,135,69,162,179,57,181,210,247,29,134,137,162,230,249,138, + 194,231,17,138,140,103,37,234,155,15,43,68,31,115,72,37,246,155,6,235,66,207,113, + 148,36,111,91,108,59,109,211,109,157,237,169,141,190,229,176,75,52,55,87,86,190,190, + 240,112,68,36,51,91,85,251,127,3,96,1,232,0,78,128,52,96,23,104,14,174,132, + 124,99,97,233,232,78,206,180,84,119,127,102,160,42,248,31,2,136,1,166,128,122,224, + 35,8,25,198,138,210,231,29,138,137,167,38,250,154,195,43,17,223,76,88,53,250,151, + 3,46,129,220,96,89,232,58,206,147,20,109,207,109,148,45,175,93,188,57,177,210,244, + 93,135,121,162,162,249,185,130,242,225,133,136,99,38,169,218,254,219,0,91,64,59,112, + 19,100,13,235,69,143,115,36,37,219,91,27,123,75,99,119,105,230,174,202,252,87,1, + 254,128,64,96,48,40,20,30,143,72,100,54,171,86,255,126,192,32,80,24,60,10,145, + 199,44,82,157,253,169,129,190,224,112,72,36,54,155,86,235,126,207,96,84,40,63,94, + 144,56,108,18,173,205,189,149,177,175,52,124,23,97,206,168,84,126,191,96,112,40,36, + 30,155,72,107,118,175,102,252,42,193,223,16,88,12,58,133,211,35,29,217,201,154,214, + 235,30,207,72,84,54,191,86,240,62,196,16,83,76,61,245,209,135,28,98,137,233,166, + 206,250,212,67,31,113,200,36,86,155,126,235,96,79,104,52,46,151,92,110,185,236,114, + 205,229,149,139,47,39,92,26,185,203,50,215,85,158,191,40,112,30,164,8,123,70,163, + 114,249,229,130,203,33,151,88,110,186,172,115,61,229,209,139,28,103,73,234,182,207,54, + 212,22,223,78,216,52,90,151,123,46,163,92,121,249,226,194,201,145,150,236,110,205,236, + 85,141,255,37,128,27,32,11,88,7,122,130,163,33,185,216,114,218,165,155,59,43,83, + 95,125,248,33,130,152,97,170,168,127,62,160,16,120,12,34,133,217,163,26,249,203,2, + 215,65,158,176,104,116,46,167,92,122,185,227,50,201,213,150,223,46,216,28,90,137,251, + 38,195,90,209,251,28,67,73,241,246,196,70,211,114,221,229,153, +}; + +#ifdef PROTOTYPES + +# if !defined WORDS_BIGENDIAN +/* little endian */ +static const UInt32_t yellowbook_scrambler_uint32[2340/4] = { + 0x60008001UL,0x1E002800UL,0x06600880UL,0x81FE02A8UL,0x28606080UL, + 0x889E1E28UL,0xAAAE6668UL,0xE0017FFCUL,0x36004800UL,0x0EE01680UL, + 0x835604C8UL,0x48E0E17EUL,0x96B63648UL,0xCCC6EEF6UL,0x9FFDD552UL, + 0x7E00A801UL,0x18602080UL,0x879E0A28UL,0xA99E6228UL,0xA0FE7EA8UL, + 0x22307840UL,0x4AAF1994UL,0xD60137FCUL,0x38E05E80UL,0x8DB61248UL, + 0xCBB6E5B6UL,0xDE56D736UL,0x5A70D8BEUL,0x533B3BA4UL,0xE1FD7D53UL, + 0x66608881UL,0x9FFE2AA8UL,0x2E006800UL,0x09601C80UL,0x82CE06E8UL, + 0x689F61D4UL,0x9CAE2E68UL,0xEEE1697CUL,0xB5564CC8UL,0x4600F7FEUL, + 0x15E03280UL,0x84260F88UL,0x094BE31AUL,0xB2C646F7UL,0x879DF5D2UL, + 0xF99EA229UL,0xB1FE42A8UL,0x27607480UL,0x8BAE1A68UL,0xEA51673CUL, + 0xF4314FBCUL,0x724F4714UL,0x5BB725B4UL,0xF356BB36UL,0x53E0C57EUL, + 0x91C63D08UL,0x8D6DEC92UL,0xBB8DA5EDUL,0x355BB325UL,0x7E0357FBUL, + 0x4860E081UL,0x969E3628UL,0xACCE6EE8UL,0x61FF7D54UL,0x1E602880UL, + 0x867E08A8UL,0x29F862A0UL,0xA8E19E82UL,0xA0B67E48UL,0xC226F876UL, + 0x1CABD19AUL,0x36E0497FUL,0x8ED616C8UL,0x4B58E4DEUL,0x3663B77AUL, + 0xDEFED6A9UL,0x3A5058C0UL,0xCD3113BCUL,0x7F9F55D4UL,0x981E2028UL, + 0xAF866A08UL,0x8119FC22UL,0x0857E0CAUL,0x6290863EUL,0xDE8D29ECUL, + 0x2A4B98E5UL,0xB8365FB7UL,0xC58EF216UL,0x7D3B53A4UL,0xE89D61D3UL, + 0xE4AE8E69UL,0xF7614B7CUL,0xB2AE4668UL,0xE78175FCUL,0x37984A20UL, + 0x2E9F962AUL,0x894E1CE8UL,0x6AC766F4UL,0xBC1DAFD2UL,0xF4C6B109UL, + 0x927DC752UL,0x7DB8ADA1UL,0xB8B5A1B2UL,0x95A63277UL,0x0C33EFBAUL, + 0x13CFC515UL,0x45CF0D14UL,0x552F3394UL,0xD0193FDCUL,0x1907DC0AUL, + 0xA7D18AC2UL,0xE3897A1CUL,0xD6DAC926UL,0x48DB1EDBUL,0x66BB765BUL, + 0xEFC56AF3UL,0xC50D0C13UL,0x2D1393C5UL,0x9995DDCDUL,0x1FFC2AAFUL, + 0x5600C801UL,0x10E03E80UL,0x85360C48UL,0xC91EE3D6UL,0xBED656C8UL, + 0x4458F0DEUL,0x3553B33AUL,0x9E01D7FDUL,0x2E606880UL,0x897E1CA8UL, + 0x2AC866E0UL,0xE81E9FD6UL,0xB4864E08UL,0x8669F762UL,0x49FCE2AEUL, + 0x46E0F681UL,0x95D632C8UL,0x4C28EF9EUL,0x77C8B51EUL,0xFA8EA616UL, + 0x710B43E4UL,0xAB5264C7UL,0xB061BF7DUL,0xA71E7428UL,0xA3B67A48UL, + 0xC2D6F936UL,0x5C98D1DEUL,0x32EFB96AUL,0xCF9515CCUL,0x0F1C142FUL, + 0xD336C449UL,0xD9FEDD56UL,0x3BE05A80UL,0x8D461308UL,0x8B85E5F2UL, + 0xDA592723UL,0x1B33DBBAUL,0x177FCB55UL,0x04A80E60UL,0x6160837EUL, + 0x9E4E28E8UL,0x6E7768B4UL,0xFD7AACA6UL,0xC08901E3UL,0xDC2AD066UL, + 0x0AC8191FUL,0xE21E87D6UL,0xB6A64988UL,0x06C3F6FAUL,0x51DCC2D1UL, + 0xC16AFC99UL,0x0C4C10EFUL,0x13D7C535UL,0x65C88D1EUL,0xFF2EAB96UL, + 0xF039405CUL,0x930DC412UL,0x3DF3AD45UL,0x1CA3D185UL,0xD6E2C979UL, + 0xE8D69EC9UL,0x54B8CE5EUL,0xB065BF72UL,0x571F342BUL,0x90B63E48UL, + 0xCD26EC76UL,0x1F9BD5DAUL,0x761F482BUL,0x9AE62688UL,0x0F17EBCAUL, + 0x6334844EUL,0xAEFE6957UL,0x21507CC0UL,0xCA4118FCUL,0x3E3457B0UL, + 0xBC6E5097UL,0xE4DD712CUL,0xE77A8B59UL,0xC7A90A63UL,0x5D90D23EUL, + 0xD2BD39ACUL,0x69849DF1UL,0xECF96EA3UL,0x95F1CD42UL,0x6C236F84UL, + 0xCDCAED19UL,0x8FAE1597UL,0xEB11643CUL,0xF4754F4CUL,0x825A0727UL, + 0x58B321BBUL,0x03A7FA75UL,0x20D3813AUL,0x9A39D85DUL,0x8F2DEB92UL, + 0xBB39A45DUL,0x857DF352UL,0x7908A3E1UL,0xF9D2A2C6UL,0xA1E9829DUL, + 0x4264F88EUL,0x64BF71ABUL,0x1F642B70UL,0x762F486BUL,0xDAE9269CUL, + 0x5B14DBCEUL,0x23747B4FUL,0xBAEA5967UL,0x151433CFUL,0x34144FCFUL, + 0x3E44570FUL,0xFC7550B3UL,0x80DA0127UL,0x583B205BUL,0xE38D7A13UL, + 0x26DB8925UL,0x7BDB5ADBUL,0x694B631BUL,0xACC66EF7UL,0x81FDFD52UL, + 0x7860A081UL,0x999E2228UL,0xAFFE6AA8UL,0x21007C00UL,0x0A5018C0UL, + 0xC23107BCUL,0x7CAF5194UL,0xD8E1217CUL,0xBBB65A48UL,0xC556F336UL, + 0x5D00D3FEUL,0x129039C0UL,0xC58D0DECUL,0x2D3B93A5UL,0xF99D5DD3UL, + 0xE1FE82A9UL,0x36604880UL,0x8EFE16A8UL,0x2B5064C0UL,0xC8611F7CUL, + 0xBE9E5628UL,0xA44E70E8UL,0x63577B34UL,0x7EE0A97EUL,0x985620C8UL, + 0x4F90EA3EUL,0xD71D342CUL,0xE8B69E49UL,0xD4A6CE76UL,0x1863DF7AUL, + 0xD79ECA29UL,0xB89E5E28UL,0xA5AE7268UL,0xE3317BBCUL,0x76FF4954UL, + 0x1AD026C0UL,0xC7190BDCUL,0x1DB7D24AUL,0xE6B689B6UL,0xD7C6CAF6UL, + 0x988DDE12UL,0x3FABAA65UL,0x3C10503FUL,0xCCC5110CUL,0xCFFD1553UL, + 0x6F009401UL,0x1D302C40UL,0x469F09D4UL,0x95CE32E8UL,0x6C2F6F94UL, + 0xDDC92D1CUL,0xDAAED996UL,0xFB015BFCUL,0x31704340UL,0x4F4B14E4UL, + 0xA7267477UL,0x03BBFA5AUL,0xF0D54133UL,0x0338045FUL,0xA0FD8152UL, + 0x7230B841UL,0x5BAF2594UL,0xD3513B3CUL,0xF9E15D7CUL,0xB1E64288UL, + 0x0767F48AUL,0x21AF826AUL,0xCA7118BCUL,0x7E3B57A4UL,0xE86D6093UL, + 0xA49D8E2DUL,0xF36EBB69UL,0xF3ED456CUL,0xA3C5850DUL,0xD2CD3913UL, + 0x299F9DD5UL,0x88FE1EA8UL,0x2AB06640UL,0x48071FF4UL,0xB681B602UL, + 0x26C876E0UL,0xEBDE9AD6UL,0xB44A4F18UL,0x96563737UL,0x4CF0EEBEUL, + 0x57F33544UL,0x0083FE05UL,0x5028C061UL,0x7108BC1EUL,0xFB52A4C6UL, + 0xA161837DUL,0xA24E78E8UL,0x62B779B4UL,0xFE86A9F6UL,0x9049C0E2UL, + 0xCD16EC36UL,0x5F94D5CEUL,0x221C782FUL,0xDAA6D989UL,0x1B03DBFAUL, + 0x5770CB41UL,0x50AB3E64UL,0x21207C7FUL,0x8A5A18D8UL,0x5A3327BBUL, + 0x032FFB95UL,0xC0F9015CUL,0x9C31D042UL,0x6ECF6914UL,0x5D5F2CD4UL, + 0x928239F8UL,0x7D88ADE1UL,0xF8BAA1A6UL,0xC1A50273UL,0x4C7310BBUL, + 0x07DBF525UL,0x718B421BUL,0xAB7A64A7UL,0xD0693F63UL,0x591CDC2EUL, + 0xC3D6FAC9UL,0x5CC8D11EUL,0xF2FEB956UL,0x339045C0UL,0xCFDD152CUL, + 0xEF0A9419UL,0x85320C47UL,0x391FA3D5UL,0x8DD612C8UL,0x4BA8E59EUL, + 0x7650B73EUL,0xDAF126BCUL,0x7B135BC4UL,0x8975E34DUL,0x9ACA26E7UL, + 0x9F1E2BD7UL,0xAE366848UL,0xC16EFC96UL,0xFC4D50ECUL,0x20D78135UL, + 0x6A38985EUL,0xBC2DAF92UL,0xB4C9B11DUL,0xC67EF756UL,0x3DF852A0UL, + 0xACA19182UL,0xA1E27D78UL,0xF266B889UL,0x13BFC5AAUL,0x05D40D30UL, + 0x3128439FUL,0x6F5894DEUL,0x3D23AC7AUL,0xDC9AD1D9UL,0x4AEF196BUL, + 0xD61537CCUL,0x08E41E8FUL,0x72B7464BUL,0xFB86A5F6UL,0x9159C322UL, + 0x0D43ECFAUL,0x5384C5F1UL,0xE1D97D23UL,0x166BC89AUL,0x34FC4EAFUL, + 0x5E70D741UL,0x527B38A4UL,0xE1B97DA3UL,0x9675C8B2UL,0x9CFA2EA7UL, + 0xDEF12943UL,0x7A5358C4UL,0x8931E3BDUL,0x6ADF66D4UL,0x9C1A2FD8UL, + 0x5EC7290BUL,0xB25DB8D2UL,0xF7B2B5B9UL,0x22978635UL,0x6A8C99EEUL, + 0x0C0BEFE5UL,0xB3C24507UL,0x77CCB511UL,0x0A8FE615UL,0x420B07E4UL, + 0xA4A27187UL,0xF362BB79UL,0xE3EE8569UL,0xF6C5490CUL,0xC2DD06D3UL, + 0xEC9A91D9UL,0x45EF0D6BUL,0xD525338CUL,0x481B1FDBUL,0x6687760BUL, + 0xBFC9AAE2UL,0xC40EF016UL,0x7D435304UL,0x4884E1F1UL,0xE6A97663UL, + 0x57C0CAFEUL,0x108C3E10UL,0x152BCC65UL,0x34184FDFUL,0x2E47970AUL, + 0xA9759CB2UL,0x90CA3EE7UL,0x9D3E2C57UL,0x2E9C69D0UL,0xD94EDCE9UL, + 0x7BC75AF4UL,0xB94DA312UL,0x35C7B2F5UL,0xAE2D9792UL,0xB169BC9DUL, + 0x474CF4EEUL,0x05A7F275UL,0x213383BAUL,0x1A5FD8D5UL,0x87320BB8UL, + 0x39BFA255UL,0x0DF412B0UL,0xB3A24587UL,0xF7D2B539UL,0xA289861DUL, + 0xC28AF9E6UL,0x8C8A11E7UL,0x9BEA2567UL,0x1F442B0FUL,0xF6254873UL, + 0x42EB069BUL,0x249471CFUL,0x3B6C5B6FUL,0x9D6DD36DUL,0xBE8DA9EDUL, + 0x344BB0E5UL,0xBE565737UL,0x4470F0BEUL,0x555B3324UL,0x60037FFBUL, + 0x4E00E801UL,0x17603480UL,0x84AE0E68UL,0xE961637CUL,0xB4CE4EE8UL, + 0x667F7754UL,0x1FF82AA0UL,0xA6018802UL,0x23E07A80UL,0x8AC61908UL, + 0x8A1DE7D2UL,0xFA26A789UL,0x112BC39AUL,0x35584CDFUL,0x2E0397FAUL, + 0x5960DC81UL,0x93CE3AE8UL,0x6DCF6D14UL,0x5DAF2D94UL,0xD2B139BCUL, + 0x79875DF4UL,0xB9F9A2A2UL,0x85E1F282UL,0xA9266388UL,0x00DBFEDAUL, + 0x703B405BUL,0xEB0D6413UL,0x24738F45UL,0x1B5BDB25UL,0x77634B7BUL, + 0xCAAEE669UL,0xFE0157FCUL,0x30604080UL,0x8F1E1428UL,0xAB366448UL, + 0xC07EFF56UL,0x3C185020UL,0x2CC7910AUL,0xA9FD9D52UL,0x70E0BE81UL, + 0x9B362448UL,0xCF7EEB56UL,0x3F285460UL,0x6C38905EUL,0xBDCDAD12UL, + 0x34AFB195UL,0xCE61177CUL,0xBF7E54A8UL,0x24287060UL,0x6B489B1EUL, + 0xFC66AF76UL,0x10DFC12AUL,0x853A0C58UL,0xD91D23D3UL,0xEBD69AC9UL, + 0x5448CF1EUL,0xF056BF36UL,0x5310C43EUL,0xD1F53D4CUL,0x89621C87UL, + 0xFACEA6E9UL,0x711F43D4UL,0x9B5624C8UL,0x4F60EB7EUL,0x972E3468UL, + 0xECB96E5CUL,0x95E5CD72UL,0x5C272F8BUL,0x32CBB91AUL,0xBF9E55D7UL, + 0xA41E7028UL,0xA3467B08UL,0x82E5F972UL,0x589721CBUL,0x73ACBA6EUL, + 0x8BD1E53DUL,0xEA49671CUL,0xD436CFB6UL,0xD84EDF16UL,0x7B975A34UL, + 0x795CA32EUL,0xC9C2E2F9UL,0x6EEC9691UL,0x8D55ECCDUL,0x1B8025FFUL, + 0x07580B20UL,0x21A3827AUL,0xDA72D8B9UL,0x2B3B9BA5UL,0xF87D5F53UL, + 0x61988221UL,0x3E7FA8AAUL,0x0C7810A0UL,0xA3D98522UL,0x02CBF91AUL, + 0xB09E41D7UL,0xA72E7468UL,0xE3B97A5CUL,0x96D5C932UL,0x1CD82EDFUL, + 0x26FB895AUL,0xFBD15AC3UL,0xF149431CUL,0xD346C4F6UL,0x99E5DD72UL, + +}; +# endif +# if defined WORDS_BIGENDIAN +/* big endian */ +static const UInt32_t yellowbook_scrambler_uint32[2340/4] = { + 0x01800060UL,0x0028001EUL,0x80086006UL,0xA802FE81UL,0x80606028UL, + 0x281E9E88UL,0x6866AEAAUL,0xFC7F01E0UL,0x00480036UL,0x8016E00EUL, + 0xC8045683UL,0x7EE1E048UL,0x4836B696UL,0xF6EEC6CCUL,0x52D5FD9FUL, + 0x01A8007EUL,0x80206018UL,0x280A9E87UL,0x28629EA9UL,0xA87EFEA0UL, + 0x40783022UL,0x9419AF4AUL,0xFC3701D6UL,0x805EE038UL,0x4812B68DUL, + 0xB6E5B6CBUL,0x36D756DEUL,0xBED8705AUL,0xA43B3B53UL,0x537DFDE1UL, + 0x81886066UL,0xA82AFE9FUL,0x0068002EUL,0x801C6009UL,0xE806CE82UL, + 0xD4619F68UL,0x682EAE9CUL,0x7C69E1EEUL,0xC84C56B5UL,0xFEF70046UL, + 0x8032E015UL,0x880F2684UL,0x1AE34B09UL,0xF746C6B2UL,0xD2F59D87UL, + 0x29A29EF9UL,0xA842FEB1UL,0x80746027UL,0x681AAE8BUL,0x3C6751EAUL, + 0xBC4F31F4UL,0x14474F72UL,0xB425B75BUL,0x36BB56F3UL,0x7EC5E053UL, + 0x083DC691UL,0x92EC6D8DUL,0xEDA58DBBUL,0x25B35B35UL,0xFB57037EUL, + 0x81E06048UL,0x28369E96UL,0xE86ECEACUL,0x547DFF61UL,0x8028601EUL, + 0xA8087E86UL,0xA062F829UL,0x829EE1A8UL,0x487EB6A0UL,0x76F826C2UL, + 0x9AD1AB1CUL,0x7F49E036UL,0xC816D68EUL,0xDEE4584BUL,0x7AB76336UL, + 0xA9D6FEDEUL,0xC058503AUL,0xBC1331CDUL,0xD4559F7FUL,0x28201E98UL, + 0x086A86AFUL,0x22FC1981UL,0xCAE05708UL,0x3E869062UL,0xEC298DDEUL, + 0xE5984B2AUL,0xB75F36B8UL,0x16F28EC5UL,0xA4533B7DUL,0xD3619DE8UL, + 0x698EAEE4UL,0x7C4B61F7UL,0x6846AEB2UL,0xFC7581E7UL,0x204A9837UL, + 0x2A969F2EUL,0xE81C4E89UL,0xF466C76AUL,0xD2AF1DBCUL,0x09B1C6F4UL, + 0x52C77D92UL,0xA1ADB87DUL,0xB2A1B5B8UL,0x7732A695UL,0xBAEF330CUL, + 0x15C5CF13UL,0x140DCF45UL,0x94332F55UL,0xDC3F19D0UL,0x0ADC0719UL, + 0xC28AD1A7UL,0x1C7A89E3UL,0x26C9DAD6UL,0xDB1EDB48UL,0x5B76BB66UL, + 0xF36AC5EFUL,0x130C0DC5UL,0xC593132DUL,0xCDDD9599UL,0xAF2AFC1FUL, + 0x01C80056UL,0x803EE010UL,0x480C3685UL,0xD6E31EC9UL,0xC856D6BEUL, + 0xDEF05844UL,0x3AB35335UL,0xFDD7019EUL,0x8068602EUL,0xA81C7E89UL, + 0xE066C82AUL,0xD69F1EE8UL,0x084E86B4UL,0x62F76986UL,0xAEE2FC49UL, + 0x81F6E046UL,0xC832D695UL,0x9EEF284CUL,0x1EB5C877UL,0x16A68EFAUL, + 0xE4430B71UL,0xC76452ABUL,0x7DBF61B0UL,0x28741EA7UL,0x487AB6A3UL, + 0x36F9D6C2UL,0xDED1985CUL,0x6AB9EF32UL,0xCC1595CFUL,0x2F141C0FUL, + 0x49C436D3UL,0x56DDFED9UL,0x805AE03BUL,0x0813468DUL,0xF2E5858BUL, + 0x232759DAUL,0xBADB331BUL,0x55CB7F17UL,0x600EA804UL,0x7E836061UL, + 0xE8284E9EUL,0xB468776EUL,0xA6AC7AFDUL,0xE30189C0UL,0x66D02ADCUL, + 0x1F19C80AUL,0xD6871EE2UL,0x8849A6B6UL,0xFAF6C306UL,0xD1C2DC51UL, + 0x99FC6AC1UL,0xEF104C0CUL,0x35C5D713UL,0x1E8DC865UL,0x96AB2EFFUL, + 0x5C4039F0UL,0x12C40D93UL,0x45ADF33DUL,0x85D1A31CUL,0x79C9E2D6UL, + 0xC99ED6E8UL,0x5ECEB854UL,0x72BF65B0UL,0x2B341F57UL,0x483EB690UL, + 0x76EC26CDUL,0xDAD59B1FUL,0x2B481F76UL,0x8826E69AUL,0xCAEB170FUL, + 0x4E843463UL,0x5769FEAEUL,0xC07C5021UL,0xFC1841CAUL,0xB057343EUL, + 0x97506EBCUL,0x2C71DDE4UL,0x598B7AE7UL,0x630AA9C7UL,0x3ED2905DUL, + 0xAC39BDD2UL,0xF19D8469UL,0xA36EF9ECUL,0x42CDF195UL,0x846F236CUL, + 0x19EDCACDUL,0x9715AE8FUL,0x3C6411EBUL,0x4C4F75F4UL,0x27075A82UL, + 0xBB21B358UL,0x75FAA703UL,0x3A81D320UL,0x5DD8399AUL,0x92EB2D8FUL, + 0x5DA439BBUL,0x52F37D85UL,0xE1A30879UL,0xC6A2D2F9UL,0x9D82E9A1UL, + 0x8EF86442UL,0xAB71BF64UL,0x702B641FUL,0x6B482F76UL,0x9C26E9DAUL, + 0xCEDB145BUL,0x4F7B7423UL,0x6759EABAUL,0xCF331415UL,0xCF4F1434UL, + 0x0F57443EUL,0xB35075FCUL,0x2701DA80UL,0x5B203B58UL,0x137A8DE3UL, + 0x2589DB26UL,0xDB5ADB7BUL,0x1B634B69UL,0xF76EC6ACUL,0x52FDFD81UL, + 0x81A06078UL,0x28229E99UL,0xA86AFEAFUL,0x007C0021UL,0xC018500AUL, + 0xBC0731C2UL,0x9451AF7CUL,0x7C21E1D8UL,0x485AB6BBUL,0x36F356C5UL, + 0xFED3005DUL,0xC0399012UL,0xEC0D8DC5UL,0xA5933B2DUL,0xD35D9DF9UL, + 0xA982FEE1UL,0x80486036UL,0xA816FE8EUL,0xC064502BUL,0x7C1F61C8UL, + 0x28569EBEUL,0xE8704EA4UL,0x347B5763UL,0x7EA9E07EUL,0xC8205698UL, + 0x3EEA904FUL,0x2C341DD7UL,0x499EB6E8UL,0x76CEA6D4UL,0x7ADF6318UL, + 0x29CA9ED7UL,0x285E9EB8UL,0x6872AEA5UL,0xBC7B31E3UL,0x5449FF76UL, + 0xC026D01AUL,0xDC0B19C7UL,0x4AD2B71DUL,0xB689B6E6UL,0xF6CAC6D7UL, + 0x12DE8D98UL,0x65AAAB3FUL,0x3F50103CUL,0x0C11C5CCUL,0x5315FDCFUL, + 0x0194006FUL,0x402C301DUL,0xD4099F46UL,0xE832CE95UL,0x946F2F6CUL, + 0x1C2DC9DDUL,0x96D9AEDAUL,0xFC5B01FBUL,0x40437031UL,0xE4144B4FUL, + 0x777426A7UL,0x5AFABB03UL,0x3341D5F0UL,0x5F043803UL,0x5281FDA0UL, + 0x41B83072UL,0x9425AF5BUL,0x3C3B51D3UL,0x7C5DE1F9UL,0x8842E6B1UL, + 0x8AF46707UL,0x6A82AF21UL,0xBC1871CAUL,0xA4573B7EUL,0x93606DE8UL, + 0x2D8E9DA4UL,0x69BB6EF3UL,0x6C45EDF3UL,0x0D85C5A3UL,0x1339CDD2UL, + 0xD59D9F29UL,0xA81EFE88UL,0x4066B02AUL,0xF41F0748UL,0x02B681B6UL, + 0xE076C826UL,0xD69ADEEBUL,0x184F4AB4UL,0x37375696UL,0xBEEEF04CUL, + 0x4435F357UL,0x05FE8300UL,0x61C02850UL,0x1EBC0871UL,0xC6A452FBUL, + 0x7D8361A1UL,0xE8784EA2UL,0xB479B762UL,0xF6A986FEUL,0xE2C04990UL, + 0x36EC16CDUL,0xCED5945FUL,0x2F781C22UL,0x89D9A6DAUL,0xFADB031BUL, + 0x41CB7057UL,0x643EAB50UL,0x7F7C2021UL,0xD8185A8AUL,0xBB27335AUL, + 0x95FB2F03UL,0x5C01F9C0UL,0x42D0319CUL,0x1469CF6EUL,0xD42C5F5DUL, + 0xF8398292UL,0xE1AD887DUL,0xA6A1BAF8UL,0x7302A5C1UL,0xBB10734CUL, + 0x25F5DB07UL,0x1B428B71UL,0xA7647AABUL,0x633F69D0UL,0x2EDC1C59UL, + 0xC9FAD6C3UL,0x1ED1C85CUL,0x56B9FEF2UL,0xC0459033UL,0x2C15DDCFUL, + 0x19940AEFUL,0x470C3285UL,0xD5A31F39UL,0xC812D68DUL,0x9EE5A84BUL, + 0x3EB75076UL,0xBC26F1DAUL,0xC45B137BUL,0x4DE37589UL,0xE726CA9AUL, + 0xD72B1E9FUL,0x486836AEUL,0x96FC6EC1UL,0xEC504DFCUL,0x3581D720UL, + 0x5E98386AUL,0x92AF2DBCUL,0x1DB1C9B4UL,0x56F77EC6UL,0xA052F83DUL, + 0x8291A1ACUL,0x787DE2A1UL,0x89B866F2UL,0xAAC5BF13UL,0x300DD405UL, + 0x9F432831UL,0xDE94586FUL,0x7AAC233DUL,0xD9D19ADCUL,0x6B19EF4AUL, + 0xCC3715D6UL,0x8F1EE408UL,0x4B46B772UL,0xF6A586FBUL,0x22C35991UL, + 0xFAEC430DUL,0xF1C58453UL,0x237DD9E1UL,0x9AC86B16UL,0xAF4EFC34UL, + 0x41D7705EUL,0xA4387B52UL,0xA37DB9E1UL,0xB2C87596UL,0xA72EFA9CUL, + 0x4329F1DEUL,0xC458537AUL,0xBDE33189UL,0xD466DF6AUL,0xD82F1A9CUL, + 0x0B29C75EUL,0xD2B85DB2UL,0xB9B5B2F7UL,0x35869722UL,0xEE998C6AUL, + 0xE5EF0B0CUL,0x0745C2B3UL,0x11B5CC77UL,0x15E68F0AUL,0xE4070B42UL, + 0x8771A2A4UL,0x79BB62F3UL,0x6985EEE3UL,0x0C49C5F6UL,0xD306DDC2UL, + 0xD9919AECUL,0x6B0DEF45UL,0x8C3325D5UL,0xDB1F1B48UL,0x0B768766UL, + 0xE2AAC9BFUL,0x16F00EC4UL,0x0453437DUL,0xF1E18448UL,0x6376A9E6UL, + 0xFECAC057UL,0x103E8C10UL,0x65CC2B15UL,0xDF4F1834UL,0x0A97472EUL, + 0xB29C75A9UL,0xE73ECA90UL,0x572C3E9DUL,0xD0699C2EUL,0xE9DC4ED9UL, + 0xF45AC77BUL,0x12A34DB9UL,0xF5B2C735UL,0x92972DAEUL,0x9DBC69B1UL, + 0xEEF44C47UL,0x75F2A705UL,0xBA833321UL,0xD5D85F1AUL,0xB80B3287UL, + 0x55A2BF39UL,0xB012F40DUL,0x8745A2B3UL,0x39B5D2F7UL,0x1D8689A2UL, + 0xE6F98AC2UL,0xE7118A8CUL,0x6725EA9BUL,0x0F2B441FUL,0x734825F6UL, + 0x9B06EB42UL,0xCF719424UL,0x6F5B6C3BUL,0x6DD36D9DUL,0xEDA98DBEUL, + 0xE5B04B34UL,0x375756BEUL,0xBEF07044UL,0x24335B55UL,0xFB7F0360UL, + 0x01E8004EUL,0x80346017UL,0x680EAE84UL,0x7C6361E9UL,0xE84ECEB4UL, + 0x54777F66UL,0xA02AF81FUL,0x028801A6UL,0x807AE023UL,0x0819C68AUL, + 0xD2E71D8AUL,0x89A726FAUL,0x9AC32B11UL,0xDF4C5835UL,0xFA97032EUL, + 0x81DC6059UL,0xE83ACE93UL,0x146DCF6DUL,0x942DAF5DUL,0xBC39B1D2UL, + 0xF45D8779UL,0xA2A2F9B9UL,0x82F2E185UL,0x886326A9UL,0xDAFEDB00UL, + 0x5B403B70UL,0x13640DEBUL,0x458F7324UL,0x25DB5B1BUL,0x7B4B6377UL, + 0x69E6AECAUL,0xFC5701FEUL,0x80406030UL,0x28141E8FUL,0x486436ABUL, + 0x56FF7EC0UL,0x2050183CUL,0x0A91C72CUL,0x529DFDA9UL,0x81BEE070UL, + 0x4824369BUL,0x56EB7ECFUL,0x6054283FUL,0x5E90386CUL,0x12ADCDBDUL, + 0x95B1AF34UL,0x7C1761CEUL,0xA8547EBFUL,0x60702824UL,0x1E9B486BUL, + 0x76AF66FCUL,0x2AC1DF10UL,0x580C3A85UL,0xD3231DD9UL,0xC99AD6EBUL, + 0x1ECF4854UL,0x36BF56F0UL,0x3EC41053UL,0x4C3DF5D1UL,0x871C6289UL, + 0xE9A6CEFAUL,0xD4431F71UL,0xC824569BUL,0x7EEB604FUL,0x68342E97UL, + 0x5C6EB9ECUL,0x72CDE595UL,0x8B2F275CUL,0x1AB9CB32UL,0xD7559EBFUL, + 0x28701EA4UL,0x087B46A3UL,0x72F9E582UL,0xCB219758UL,0x6EBAAC73UL, + 0x3DE5D18BUL,0x1C6749EAUL,0xB6CF36D4UL,0x16DF4ED8UL,0x345A977BUL, + 0x2EA35C79UL,0xF9E2C2C9UL,0x9196EC6EUL,0xCDEC558DUL,0xFF25801BUL, + 0x200B5807UL,0x7A82A321UL,0xB9D872DAUL,0xA59B3B2BUL,0x535F7DF8UL, + 0x21829861UL,0xAAA87F3EUL,0xA010780CUL,0x2285D9A3UL,0x1AF9CB02UL, + 0xD7419EB0UL,0x68742EA7UL,0x5C7AB9E3UL,0x32C9D596UL,0xDF2ED81CUL, + 0x5A89FB26UL,0xC35AD1FBUL,0x1C4349F1UL,0xF6C446D3UL,0x72DDE599UL, + +}; +# endif + +#else /* PROTOTYPES */ + +# if !defined WORDS_BIGENDIAN +/* little endian */ +static const UInt32_t yellowbook_scrambler_uint32[2340/4] = { + 0x60008001,0x1E002800,0x06600880,0x81FE02A8,0x28606080, + 0x889E1E28,0xAAAE6668,0xE0017FFC,0x36004800,0x0EE01680, + 0x835604C8,0x48E0E17E,0x96B63648,0xCCC6EEF6,0x9FFDD552, + 0x7E00A801,0x18602080,0x879E0A28,0xA99E6228,0xA0FE7EA8, + 0x22307840,0x4AAF1994,0xD60137FC,0x38E05E80,0x8DB61248, + 0xCBB6E5B6,0xDE56D736,0x5A70D8BE,0x533B3BA4,0xE1FD7D53, + 0x66608881,0x9FFE2AA8,0x2E006800,0x09601C80,0x82CE06E8, + 0x689F61D4,0x9CAE2E68,0xEEE1697C,0xB5564CC8,0x4600F7FE, + 0x15E03280,0x84260F88,0x094BE31A,0xB2C646F7,0x879DF5D2, + 0xF99EA229,0xB1FE42A8,0x27607480,0x8BAE1A68,0xEA51673C, + 0xF4314FBC,0x724F4714,0x5BB725B4,0xF356BB36,0x53E0C57E, + 0x91C63D08,0x8D6DEC92,0xBB8DA5ED,0x355BB325,0x7E0357FB, + 0x4860E081,0x969E3628,0xACCE6EE8,0x61FF7D54,0x1E602880, + 0x867E08A8,0x29F862A0,0xA8E19E82,0xA0B67E48,0xC226F876, + 0x1CABD19A,0x36E0497F,0x8ED616C8,0x4B58E4DE,0x3663B77A, + 0xDEFED6A9,0x3A5058C0,0xCD3113BC,0x7F9F55D4,0x981E2028, + 0xAF866A08,0x8119FC22,0x0857E0CA,0x6290863E,0xDE8D29EC, + 0x2A4B98E5,0xB8365FB7,0xC58EF216,0x7D3B53A4,0xE89D61D3, + 0xE4AE8E69,0xF7614B7C,0xB2AE4668,0xE78175FC,0x37984A20, + 0x2E9F962A,0x894E1CE8,0x6AC766F4,0xBC1DAFD2,0xF4C6B109, + 0x927DC752,0x7DB8ADA1,0xB8B5A1B2,0x95A63277,0x0C33EFBA, + 0x13CFC515,0x45CF0D14,0x552F3394,0xD0193FDC,0x1907DC0A, + 0xA7D18AC2,0xE3897A1C,0xD6DAC926,0x48DB1EDB,0x66BB765B, + 0xEFC56AF3,0xC50D0C13,0x2D1393C5,0x9995DDCD,0x1FFC2AAF, + 0x5600C801,0x10E03E80,0x85360C48,0xC91EE3D6,0xBED656C8, + 0x4458F0DE,0x3553B33A,0x9E01D7FD,0x2E606880,0x897E1CA8, + 0x2AC866E0,0xE81E9FD6,0xB4864E08,0x8669F762,0x49FCE2AE, + 0x46E0F681,0x95D632C8,0x4C28EF9E,0x77C8B51E,0xFA8EA616, + 0x710B43E4,0xAB5264C7,0xB061BF7D,0xA71E7428,0xA3B67A48, + 0xC2D6F936,0x5C98D1DE,0x32EFB96A,0xCF9515CC,0x0F1C142F, + 0xD336C449,0xD9FEDD56,0x3BE05A80,0x8D461308,0x8B85E5F2, + 0xDA592723,0x1B33DBBA,0x177FCB55,0x04A80E60,0x6160837E, + 0x9E4E28E8,0x6E7768B4,0xFD7AACA6,0xC08901E3,0xDC2AD066, + 0x0AC8191F,0xE21E87D6,0xB6A64988,0x06C3F6FA,0x51DCC2D1, + 0xC16AFC99,0x0C4C10EF,0x13D7C535,0x65C88D1E,0xFF2EAB96, + 0xF039405C,0x930DC412,0x3DF3AD45,0x1CA3D185,0xD6E2C979, + 0xE8D69EC9,0x54B8CE5E,0xB065BF72,0x571F342B,0x90B63E48, + 0xCD26EC76,0x1F9BD5DA,0x761F482B,0x9AE62688,0x0F17EBCA, + 0x6334844E,0xAEFE6957,0x21507CC0,0xCA4118FC,0x3E3457B0, + 0xBC6E5097,0xE4DD712C,0xE77A8B59,0xC7A90A63,0x5D90D23E, + 0xD2BD39AC,0x69849DF1,0xECF96EA3,0x95F1CD42,0x6C236F84, + 0xCDCAED19,0x8FAE1597,0xEB11643C,0xF4754F4C,0x825A0727, + 0x58B321BB,0x03A7FA75,0x20D3813A,0x9A39D85D,0x8F2DEB92, + 0xBB39A45D,0x857DF352,0x7908A3E1,0xF9D2A2C6,0xA1E9829D, + 0x4264F88E,0x64BF71AB,0x1F642B70,0x762F486B,0xDAE9269C, + 0x5B14DBCE,0x23747B4F,0xBAEA5967,0x151433CF,0x34144FCF, + 0x3E44570F,0xFC7550B3,0x80DA0127,0x583B205B,0xE38D7A13, + 0x26DB8925,0x7BDB5ADB,0x694B631B,0xACC66EF7,0x81FDFD52, + 0x7860A081,0x999E2228,0xAFFE6AA8,0x21007C00,0x0A5018C0, + 0xC23107BC,0x7CAF5194,0xD8E1217C,0xBBB65A48,0xC556F336, + 0x5D00D3FE,0x129039C0,0xC58D0DEC,0x2D3B93A5,0xF99D5DD3, + 0xE1FE82A9,0x36604880,0x8EFE16A8,0x2B5064C0,0xC8611F7C, + 0xBE9E5628,0xA44E70E8,0x63577B34,0x7EE0A97E,0x985620C8, + 0x4F90EA3E,0xD71D342C,0xE8B69E49,0xD4A6CE76,0x1863DF7A, + 0xD79ECA29,0xB89E5E28,0xA5AE7268,0xE3317BBC,0x76FF4954, + 0x1AD026C0,0xC7190BDC,0x1DB7D24A,0xE6B689B6,0xD7C6CAF6, + 0x988DDE12,0x3FABAA65,0x3C10503F,0xCCC5110C,0xCFFD1553, + 0x6F009401,0x1D302C40,0x469F09D4,0x95CE32E8,0x6C2F6F94, + 0xDDC92D1C,0xDAAED996,0xFB015BFC,0x31704340,0x4F4B14E4, + 0xA7267477,0x03BBFA5A,0xF0D54133,0x0338045F,0xA0FD8152, + 0x7230B841,0x5BAF2594,0xD3513B3C,0xF9E15D7C,0xB1E64288, + 0x0767F48A,0x21AF826A,0xCA7118BC,0x7E3B57A4,0xE86D6093, + 0xA49D8E2D,0xF36EBB69,0xF3ED456C,0xA3C5850D,0xD2CD3913, + 0x299F9DD5,0x88FE1EA8,0x2AB06640,0x48071FF4,0xB681B602, + 0x26C876E0,0xEBDE9AD6,0xB44A4F18,0x96563737,0x4CF0EEBE, + 0x57F33544,0x0083FE05,0x5028C061,0x7108BC1E,0xFB52A4C6, + 0xA161837D,0xA24E78E8,0x62B779B4,0xFE86A9F6,0x9049C0E2, + 0xCD16EC36,0x5F94D5CE,0x221C782F,0xDAA6D989,0x1B03DBFA, + 0x5770CB41,0x50AB3E64,0x21207C7F,0x8A5A18D8,0x5A3327BB, + 0x032FFB95,0xC0F9015C,0x9C31D042,0x6ECF6914,0x5D5F2CD4, + 0x928239F8,0x7D88ADE1,0xF8BAA1A6,0xC1A50273,0x4C7310BB, + 0x07DBF525,0x718B421B,0xAB7A64A7,0xD0693F63,0x591CDC2E, + 0xC3D6FAC9,0x5CC8D11E,0xF2FEB956,0x339045C0,0xCFDD152C, + 0xEF0A9419,0x85320C47,0x391FA3D5,0x8DD612C8,0x4BA8E59E, + 0x7650B73E,0xDAF126BC,0x7B135BC4,0x8975E34D,0x9ACA26E7, + 0x9F1E2BD7,0xAE366848,0xC16EFC96,0xFC4D50EC,0x20D78135, + 0x6A38985E,0xBC2DAF92,0xB4C9B11D,0xC67EF756,0x3DF852A0, + 0xACA19182,0xA1E27D78,0xF266B889,0x13BFC5AA,0x05D40D30, + 0x3128439F,0x6F5894DE,0x3D23AC7A,0xDC9AD1D9,0x4AEF196B, + 0xD61537CC,0x08E41E8F,0x72B7464B,0xFB86A5F6,0x9159C322, + 0x0D43ECFA,0x5384C5F1,0xE1D97D23,0x166BC89A,0x34FC4EAF, + 0x5E70D741,0x527B38A4,0xE1B97DA3,0x9675C8B2,0x9CFA2EA7, + 0xDEF12943,0x7A5358C4,0x8931E3BD,0x6ADF66D4,0x9C1A2FD8, + 0x5EC7290B,0xB25DB8D2,0xF7B2B5B9,0x22978635,0x6A8C99EE, + 0x0C0BEFE5,0xB3C24507,0x77CCB511,0x0A8FE615,0x420B07E4, + 0xA4A27187,0xF362BB79,0xE3EE8569,0xF6C5490C,0xC2DD06D3, + 0xEC9A91D9,0x45EF0D6B,0xD525338C,0x481B1FDB,0x6687760B, + 0xBFC9AAE2,0xC40EF016,0x7D435304,0x4884E1F1,0xE6A97663, + 0x57C0CAFE,0x108C3E10,0x152BCC65,0x34184FDF,0x2E47970A, + 0xA9759CB2,0x90CA3EE7,0x9D3E2C57,0x2E9C69D0,0xD94EDCE9, + 0x7BC75AF4,0xB94DA312,0x35C7B2F5,0xAE2D9792,0xB169BC9D, + 0x474CF4EE,0x05A7F275,0x213383BA,0x1A5FD8D5,0x87320BB8, + 0x39BFA255,0x0DF412B0,0xB3A24587,0xF7D2B539,0xA289861D, + 0xC28AF9E6,0x8C8A11E7,0x9BEA2567,0x1F442B0F,0xF6254873, + 0x42EB069B,0x249471CF,0x3B6C5B6F,0x9D6DD36D,0xBE8DA9ED, + 0x344BB0E5,0xBE565737,0x4470F0BE,0x555B3324,0x60037FFB, + 0x4E00E801,0x17603480,0x84AE0E68,0xE961637C,0xB4CE4EE8, + 0x667F7754,0x1FF82AA0,0xA6018802,0x23E07A80,0x8AC61908, + 0x8A1DE7D2,0xFA26A789,0x112BC39A,0x35584CDF,0x2E0397FA, + 0x5960DC81,0x93CE3AE8,0x6DCF6D14,0x5DAF2D94,0xD2B139BC, + 0x79875DF4,0xB9F9A2A2,0x85E1F282,0xA9266388,0x00DBFEDA, + 0x703B405B,0xEB0D6413,0x24738F45,0x1B5BDB25,0x77634B7B, + 0xCAAEE669,0xFE0157FC,0x30604080,0x8F1E1428,0xAB366448, + 0xC07EFF56,0x3C185020,0x2CC7910A,0xA9FD9D52,0x70E0BE81, + 0x9B362448,0xCF7EEB56,0x3F285460,0x6C38905E,0xBDCDAD12, + 0x34AFB195,0xCE61177C,0xBF7E54A8,0x24287060,0x6B489B1E, + 0xFC66AF76,0x10DFC12A,0x853A0C58,0xD91D23D3,0xEBD69AC9, + 0x5448CF1E,0xF056BF36,0x5310C43E,0xD1F53D4C,0x89621C87, + 0xFACEA6E9,0x711F43D4,0x9B5624C8,0x4F60EB7E,0x972E3468, + 0xECB96E5C,0x95E5CD72,0x5C272F8B,0x32CBB91A,0xBF9E55D7, + 0xA41E7028,0xA3467B08,0x82E5F972,0x589721CB,0x73ACBA6E, + 0x8BD1E53D,0xEA49671C,0xD436CFB6,0xD84EDF16,0x7B975A34, + 0x795CA32E,0xC9C2E2F9,0x6EEC9691,0x8D55ECCD,0x1B8025FF, + 0x07580B20,0x21A3827A,0xDA72D8B9,0x2B3B9BA5,0xF87D5F53, + 0x61988221,0x3E7FA8AA,0x0C7810A0,0xA3D98522,0x02CBF91A, + 0xB09E41D7,0xA72E7468,0xE3B97A5C,0x96D5C932,0x1CD82EDF, + 0x26FB895A,0xFBD15AC3,0xF149431C,0xD346C4F6,0x99E5DD72, + +}; +# endif +# if defined WORDS_BIGENDIAN +/* big endian */ +static const UInt32_t yellowbook_scrambler_uint32[2340/4] = { + 0x01800060,0x0028001E,0x80086006,0xA802FE81,0x80606028, + 0x281E9E88,0x6866AEAA,0xFC7F01E0,0x00480036,0x8016E00E, + 0xC8045683,0x7EE1E048,0x4836B696,0xF6EEC6CC,0x52D5FD9F, + 0x01A8007E,0x80206018,0x280A9E87,0x28629EA9,0xA87EFEA0, + 0x40783022,0x9419AF4A,0xFC3701D6,0x805EE038,0x4812B68D, + 0xB6E5B6CB,0x36D756DE,0xBED8705A,0xA43B3B53,0x537DFDE1, + 0x81886066,0xA82AFE9F,0x0068002E,0x801C6009,0xE806CE82, + 0xD4619F68,0x682EAE9C,0x7C69E1EE,0xC84C56B5,0xFEF70046, + 0x8032E015,0x880F2684,0x1AE34B09,0xF746C6B2,0xD2F59D87, + 0x29A29EF9,0xA842FEB1,0x80746027,0x681AAE8B,0x3C6751EA, + 0xBC4F31F4,0x14474F72,0xB425B75B,0x36BB56F3,0x7EC5E053, + 0x083DC691,0x92EC6D8D,0xEDA58DBB,0x25B35B35,0xFB57037E, + 0x81E06048,0x28369E96,0xE86ECEAC,0x547DFF61,0x8028601E, + 0xA8087E86,0xA062F829,0x829EE1A8,0x487EB6A0,0x76F826C2, + 0x9AD1AB1C,0x7F49E036,0xC816D68E,0xDEE4584B,0x7AB76336, + 0xA9D6FEDE,0xC058503A,0xBC1331CD,0xD4559F7F,0x28201E98, + 0x086A86AF,0x22FC1981,0xCAE05708,0x3E869062,0xEC298DDE, + 0xE5984B2A,0xB75F36B8,0x16F28EC5,0xA4533B7D,0xD3619DE8, + 0x698EAEE4,0x7C4B61F7,0x6846AEB2,0xFC7581E7,0x204A9837, + 0x2A969F2E,0xE81C4E89,0xF466C76A,0xD2AF1DBC,0x09B1C6F4, + 0x52C77D92,0xA1ADB87D,0xB2A1B5B8,0x7732A695,0xBAEF330C, + 0x15C5CF13,0x140DCF45,0x94332F55,0xDC3F19D0,0x0ADC0719, + 0xC28AD1A7,0x1C7A89E3,0x26C9DAD6,0xDB1EDB48,0x5B76BB66, + 0xF36AC5EF,0x130C0DC5,0xC593132D,0xCDDD9599,0xAF2AFC1F, + 0x01C80056,0x803EE010,0x480C3685,0xD6E31EC9,0xC856D6BE, + 0xDEF05844,0x3AB35335,0xFDD7019E,0x8068602E,0xA81C7E89, + 0xE066C82A,0xD69F1EE8,0x084E86B4,0x62F76986,0xAEE2FC49, + 0x81F6E046,0xC832D695,0x9EEF284C,0x1EB5C877,0x16A68EFA, + 0xE4430B71,0xC76452AB,0x7DBF61B0,0x28741EA7,0x487AB6A3, + 0x36F9D6C2,0xDED1985C,0x6AB9EF32,0xCC1595CF,0x2F141C0F, + 0x49C436D3,0x56DDFED9,0x805AE03B,0x0813468D,0xF2E5858B, + 0x232759DA,0xBADB331B,0x55CB7F17,0x600EA804,0x7E836061, + 0xE8284E9E,0xB468776E,0xA6AC7AFD,0xE30189C0,0x66D02ADC, + 0x1F19C80A,0xD6871EE2,0x8849A6B6,0xFAF6C306,0xD1C2DC51, + 0x99FC6AC1,0xEF104C0C,0x35C5D713,0x1E8DC865,0x96AB2EFF, + 0x5C4039F0,0x12C40D93,0x45ADF33D,0x85D1A31C,0x79C9E2D6, + 0xC99ED6E8,0x5ECEB854,0x72BF65B0,0x2B341F57,0x483EB690, + 0x76EC26CD,0xDAD59B1F,0x2B481F76,0x8826E69A,0xCAEB170F, + 0x4E843463,0x5769FEAE,0xC07C5021,0xFC1841CA,0xB057343E, + 0x97506EBC,0x2C71DDE4,0x598B7AE7,0x630AA9C7,0x3ED2905D, + 0xAC39BDD2,0xF19D8469,0xA36EF9EC,0x42CDF195,0x846F236C, + 0x19EDCACD,0x9715AE8F,0x3C6411EB,0x4C4F75F4,0x27075A82, + 0xBB21B358,0x75FAA703,0x3A81D320,0x5DD8399A,0x92EB2D8F, + 0x5DA439BB,0x52F37D85,0xE1A30879,0xC6A2D2F9,0x9D82E9A1, + 0x8EF86442,0xAB71BF64,0x702B641F,0x6B482F76,0x9C26E9DA, + 0xCEDB145B,0x4F7B7423,0x6759EABA,0xCF331415,0xCF4F1434, + 0x0F57443E,0xB35075FC,0x2701DA80,0x5B203B58,0x137A8DE3, + 0x2589DB26,0xDB5ADB7B,0x1B634B69,0xF76EC6AC,0x52FDFD81, + 0x81A06078,0x28229E99,0xA86AFEAF,0x007C0021,0xC018500A, + 0xBC0731C2,0x9451AF7C,0x7C21E1D8,0x485AB6BB,0x36F356C5, + 0xFED3005D,0xC0399012,0xEC0D8DC5,0xA5933B2D,0xD35D9DF9, + 0xA982FEE1,0x80486036,0xA816FE8E,0xC064502B,0x7C1F61C8, + 0x28569EBE,0xE8704EA4,0x347B5763,0x7EA9E07E,0xC8205698, + 0x3EEA904F,0x2C341DD7,0x499EB6E8,0x76CEA6D4,0x7ADF6318, + 0x29CA9ED7,0x285E9EB8,0x6872AEA5,0xBC7B31E3,0x5449FF76, + 0xC026D01A,0xDC0B19C7,0x4AD2B71D,0xB689B6E6,0xF6CAC6D7, + 0x12DE8D98,0x65AAAB3F,0x3F50103C,0x0C11C5CC,0x5315FDCF, + 0x0194006F,0x402C301D,0xD4099F46,0xE832CE95,0x946F2F6C, + 0x1C2DC9DD,0x96D9AEDA,0xFC5B01FB,0x40437031,0xE4144B4F, + 0x777426A7,0x5AFABB03,0x3341D5F0,0x5F043803,0x5281FDA0, + 0x41B83072,0x9425AF5B,0x3C3B51D3,0x7C5DE1F9,0x8842E6B1, + 0x8AF46707,0x6A82AF21,0xBC1871CA,0xA4573B7E,0x93606DE8, + 0x2D8E9DA4,0x69BB6EF3,0x6C45EDF3,0x0D85C5A3,0x1339CDD2, + 0xD59D9F29,0xA81EFE88,0x4066B02A,0xF41F0748,0x02B681B6, + 0xE076C826,0xD69ADEEB,0x184F4AB4,0x37375696,0xBEEEF04C, + 0x4435F357,0x05FE8300,0x61C02850,0x1EBC0871,0xC6A452FB, + 0x7D8361A1,0xE8784EA2,0xB479B762,0xF6A986FE,0xE2C04990, + 0x36EC16CD,0xCED5945F,0x2F781C22,0x89D9A6DA,0xFADB031B, + 0x41CB7057,0x643EAB50,0x7F7C2021,0xD8185A8A,0xBB27335A, + 0x95FB2F03,0x5C01F9C0,0x42D0319C,0x1469CF6E,0xD42C5F5D, + 0xF8398292,0xE1AD887D,0xA6A1BAF8,0x7302A5C1,0xBB10734C, + 0x25F5DB07,0x1B428B71,0xA7647AAB,0x633F69D0,0x2EDC1C59, + 0xC9FAD6C3,0x1ED1C85C,0x56B9FEF2,0xC0459033,0x2C15DDCF, + 0x19940AEF,0x470C3285,0xD5A31F39,0xC812D68D,0x9EE5A84B, + 0x3EB75076,0xBC26F1DA,0xC45B137B,0x4DE37589,0xE726CA9A, + 0xD72B1E9F,0x486836AE,0x96FC6EC1,0xEC504DFC,0x3581D720, + 0x5E98386A,0x92AF2DBC,0x1DB1C9B4,0x56F77EC6,0xA052F83D, + 0x8291A1AC,0x787DE2A1,0x89B866F2,0xAAC5BF13,0x300DD405, + 0x9F432831,0xDE94586F,0x7AAC233D,0xD9D19ADC,0x6B19EF4A, + 0xCC3715D6,0x8F1EE408,0x4B46B772,0xF6A586FB,0x22C35991, + 0xFAEC430D,0xF1C58453,0x237DD9E1,0x9AC86B16,0xAF4EFC34, + 0x41D7705E,0xA4387B52,0xA37DB9E1,0xB2C87596,0xA72EFA9C, + 0x4329F1DE,0xC458537A,0xBDE33189,0xD466DF6A,0xD82F1A9C, + 0x0B29C75E,0xD2B85DB2,0xB9B5B2F7,0x35869722,0xEE998C6A, + 0xE5EF0B0C,0x0745C2B3,0x11B5CC77,0x15E68F0A,0xE4070B42, + 0x8771A2A4,0x79BB62F3,0x6985EEE3,0x0C49C5F6,0xD306DDC2, + 0xD9919AEC,0x6B0DEF45,0x8C3325D5,0xDB1F1B48,0x0B768766, + 0xE2AAC9BF,0x16F00EC4,0x0453437D,0xF1E18448,0x6376A9E6, + 0xFECAC057,0x103E8C10,0x65CC2B15,0xDF4F1834,0x0A97472E, + 0xB29C75A9,0xE73ECA90,0x572C3E9D,0xD0699C2E,0xE9DC4ED9, + 0xF45AC77B,0x12A34DB9,0xF5B2C735,0x92972DAE,0x9DBC69B1, + 0xEEF44C47,0x75F2A705,0xBA833321,0xD5D85F1A,0xB80B3287, + 0x55A2BF39,0xB012F40D,0x8745A2B3,0x39B5D2F7,0x1D8689A2, + 0xE6F98AC2,0xE7118A8C,0x6725EA9B,0x0F2B441F,0x734825F6, + 0x9B06EB42,0xCF719424,0x6F5B6C3B,0x6DD36D9D,0xEDA98DBE, + 0xE5B04B34,0x375756BE,0xBEF07044,0x24335B55,0xFB7F0360, + 0x01E8004E,0x80346017,0x680EAE84,0x7C6361E9,0xE84ECEB4, + 0x54777F66,0xA02AF81F,0x028801A6,0x807AE023,0x0819C68A, + 0xD2E71D8A,0x89A726FA,0x9AC32B11,0xDF4C5835,0xFA97032E, + 0x81DC6059,0xE83ACE93,0x146DCF6D,0x942DAF5D,0xBC39B1D2, + 0xF45D8779,0xA2A2F9B9,0x82F2E185,0x886326A9,0xDAFEDB00, + 0x5B403B70,0x13640DEB,0x458F7324,0x25DB5B1B,0x7B4B6377, + 0x69E6AECA,0xFC5701FE,0x80406030,0x28141E8F,0x486436AB, + 0x56FF7EC0,0x2050183C,0x0A91C72C,0x529DFDA9,0x81BEE070, + 0x4824369B,0x56EB7ECF,0x6054283F,0x5E90386C,0x12ADCDBD, + 0x95B1AF34,0x7C1761CE,0xA8547EBF,0x60702824,0x1E9B486B, + 0x76AF66FC,0x2AC1DF10,0x580C3A85,0xD3231DD9,0xC99AD6EB, + 0x1ECF4854,0x36BF56F0,0x3EC41053,0x4C3DF5D1,0x871C6289, + 0xE9A6CEFA,0xD4431F71,0xC824569B,0x7EEB604F,0x68342E97, + 0x5C6EB9EC,0x72CDE595,0x8B2F275C,0x1AB9CB32,0xD7559EBF, + 0x28701EA4,0x087B46A3,0x72F9E582,0xCB219758,0x6EBAAC73, + 0x3DE5D18B,0x1C6749EA,0xB6CF36D4,0x16DF4ED8,0x345A977B, + 0x2EA35C79,0xF9E2C2C9,0x9196EC6E,0xCDEC558D,0xFF25801B, + 0x200B5807,0x7A82A321,0xB9D872DA,0xA59B3B2B,0x535F7DF8, + 0x21829861,0xAAA87F3E,0xA010780C,0x2285D9A3,0x1AF9CB02, + 0xD7419EB0,0x68742EA7,0x5C7AB9E3,0x32C9D596,0xDF2ED81C, + 0x5A89FB26,0xC35AD1FB,0x1C4349F1,0xF6C446D3,0x72DDE599, + +}; +# endif + +#endif /* PROTOTYPES */ diff --git a/libhfs_iso/CMakeLists.txt b/libhfs_iso/CMakeLists.txt new file mode 100644 index 0000000..8558690 --- /dev/null +++ b/libhfs_iso/CMakeLists.txt @@ -0,0 +1,8 @@ +PROJECT (LIBhfs_iso C) +INCLUDE_DIRECTORIES(../include ../libhfs_iso ../wodim ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +ADD_DEFINITIONS(-DUSE_LARGEFILES -DABORT_DEEP_ISO_ONLY -DAPPLE_HYB -DUDF -DDVD_VIDEO -DSORTING -DHAVE_CONFIG_H -DUSE_LIBSCHILY -DUSE_SCG) + + +SET(LIBhfs_iso_SRCS block.c btree.c data.c file.c gdata.c hfs.c low.c node.c record.c volume.c) + +ADD_LIBRARY (hfs_iso STATIC ${LIBhfs_iso_SRCS}) diff --git a/libhfs_iso/README b/libhfs_iso/README new file mode 100644 index 0000000..5c6c00b --- /dev/null +++ b/libhfs_iso/README @@ -0,0 +1,41 @@ +# @(#)README 1.1 97/07/21 joerg + 06/09/11 christian + +Modified version of libhfs (v2.0) to work with mkhybrid. + +To complile for mkhybrid, use the #define -DAPPLE_HYB + +The libhfs.a created with this option must not be used with other +hfsutils routines. + +James Pearson 18/7/97 + +Copyright information from hfsutils: + + hfsutils - tools for reading and writing Macintosh HFS volumes + Copyright (C) 1996, 1997 Robert Leslie + + This describes the program as shipped with cdrkit, a spinoff from the + cdrtools project. However, the cdrtools developers are no longer + involved in the development of this spinoff and therefore shall not + be made responsible for any problem caused by it. Do not try to get + support for this program by contacting the original authors. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +Source: lihfs_iso/README from cdrtools package +Edited for cdrkit by Christian Fromme <kaner@strace.org> + diff --git a/libhfs_iso/block.c b/libhfs_iso/block.c new file mode 100644 index 0000000..bbca145 --- /dev/null +++ b/libhfs_iso/block.c @@ -0,0 +1,219 @@ +/* + * 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. + * + */ + +/* @(#)block.c 1.3 01/11/01 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <strdefs.h> +#include <unixstd.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "block.h" +#include "low.h" + +#ifdef DEBUG +#include <stdio.h> +#endif /* DEBUG */ + +/* + * NAME: block->readlb() + * DESCRIPTION: read a logical block from a volume + */ +int b_readlb(hfsvol *vol, unsigned long num, block *bp) +{ +#ifndef APPLE_HYB + int bytes; +#endif +#ifdef APPLE_HYB + block *b; + hce_mem *hce; + +#ifdef DEBUG + fprintf(stderr,"b_readlb: start block = %d\n", vol->vstart + num); +#endif /* DEBUG */ + + hce = vol->hce; + +/* Check to see if requested block is in the HFS header or catalog/exents + files. If it is, read info from memory copy. If not, then something + has gone horribly wrong ... */ + + if (num < hce->hfs_hdr_size) + b = (block *)hce->hfs_hdr + num; + else if (num < hce->hfs_hdr_size + hce->hfs_ce_size) + b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size; + else + { + ERROR(EIO, "should not happen!"); + return -1; + } + + memcpy(bp, b, HFS_BLOCKSZ); + +#else + + if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0) + { + ERROR(errno, "error seeking device"); + return -1; + } + + bytes = read(vol->fd, bp, HFS_BLOCKSZ); + if (bytes < 0) + { + ERROR(errno, "error reading from device"); + return -1; + } + else if (bytes == 0) + { + ERROR(EIO, "read EOF on volume"); + return -1; + } + else if (bytes != HFS_BLOCKSZ) + { + ERROR(EIO, "read incomplete block"); + return -1; + } +#endif /* APPLE_HYB */ + return 0; +} + +/* + * NAME: block->writelb() + * DESCRIPTION: write a logical block to a volume + */ +int b_writelb(hfsvol *vol, unsigned long num, block *bp) +{ +#ifndef APPLE_HYB + int bytes; +#endif +#ifdef APPLE_HYB + block *b; + hce_mem *hce; + +#ifdef DEBUG + fprintf(stderr,"b_writelb: start block = %d\n", vol->vstart + num); +#endif /* DEBUG */ + + hce = vol->hce; + +/* Check to see if requested block is in the HFS header or catalog/exents + files. If it is, write info to memory copy. If not, then it's a block + for an ordinary file - and as we are writing the files later, then just + ignore and return OK */ + if (num < hce->hfs_hdr_size) + b = (block *)hce->hfs_hdr + num; + else if (num < hce->hfs_hdr_size + hce->hfs_ce_size) + b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size; + else + { +#ifdef DEBUG + fprintf(stderr,"b_writelb: ignoring\n"); +#endif /* DEBUG */ + return 0; + } + + memcpy(b, bp, HFS_BLOCKSZ); + +#else + + if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0) + { + ERROR(errno, "error seeking device"); + return -1; + } + + bytes = write(vol->fd, bp, HFS_BLOCKSZ); + + if (bytes < 0) + { + ERROR(errno, "error writing to device"); + return -1; + } + else if (bytes != HFS_BLOCKSZ) + { + ERROR(EIO, "wrote incomplete block"); + return -1; + } +#endif /* APPLE_HYB */ + return 0; +} + +/* + * NAME: block->readab() + * DESCRIPTION: read a block from an allocation block from a volume + */ +int b_readab(hfsvol *vol, unsigned int anum, unsigned int idx, block *bp) +{ + /* verify the allocation block exists and is marked as in-use */ + + if (anum >= vol->mdb.drNmAlBlks) + { + ERROR(EIO, "read nonexistent block"); + return -1; + } + else if (vol->vbm && ! BMTST(vol->vbm, anum)) + { + ERROR(EIO, "read unallocated block"); + return -1; + } + + return b_readlb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp); +} + +/* + * NAME: b->writeab() + * DESCRIPTION: write a block to an allocation block to a volume + */ +int b_writeab(hfsvol *vol, unsigned int anum, unsigned int idx, block *bp) +{ + /* verify the allocation block exists and is marked as in-use */ + + if (anum >= vol->mdb.drNmAlBlks) + { + ERROR(EIO, "write nonexistent block"); + return -1; + } + else if (vol->vbm && ! BMTST(vol->vbm, anum)) + { + ERROR(EIO, "write unallocated block"); + return -1; + } + + vol->mdb.drAtrb &= ~HFS_ATRB_UMOUNTED; + vol->mdb.drLsMod = d_tomtime(time(0)); + ++vol->mdb.drWrCnt; + + vol->flags |= HFS_UPDATE_MDB; + + return b_writelb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp); +} diff --git a/libhfs_iso/block.h b/libhfs_iso/block.h new file mode 100644 index 0000000..ce3932d --- /dev/null +++ b/libhfs_iso/block.h @@ -0,0 +1,37 @@ +/* + * 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. + * + */ + +/* @(#)block.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +int b_readlb(hfsvol *, unsigned long, block *); +int b_writelb(hfsvol *, unsigned long, block *); + +int b_readab(hfsvol *, unsigned int, unsigned int, block *); +int b_writeab(hfsvol *, unsigned int, unsigned int, block *); diff --git a/libhfs_iso/btree.c b/libhfs_iso/btree.c new file mode 100644 index 0000000..9023428 --- /dev/null +++ b/libhfs_iso/btree.c @@ -0,0 +1,740 @@ +/* + * 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. + * + */ + +/* @(#)btree.c 1.3 04/06/17 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "block.h" +#include "file.h" +#include "btree.h" +#include "node.h" + +/* + * NAME: btree->getnode() + * DESCRIPTION: retrieve a numbered node from a B*-tree file + */ +int bt_getnode(node *np) +{ + btree *bt = np->bt; + block *bp = &np->data; + unsigned char *ptr; + int i; + + /* verify the node exists and is marked as in-use */ + + /* + * XXX This is the original code. As np->nnum is unsigned, the + * XXX comparison for < 0 makes no sense. + * XXX Thanks for a hint from Mike.Sullivan@Eng.Sun.COM + */ +/* if (np->nnum < 0 || (np->nnum > 0 && np->nnum >= bt->hdr.bthNNodes))*/ + + if (np->nnum > 0 && np->nnum >= bt->hdr.bthNNodes) + { + ERROR(EIO, "read nonexistent b*-tree node"); + return -1; + } + + if (bt->map && ! BMTST(bt->map, np->nnum)) + { + ERROR(EIO, "read unallocated b*-tree node"); + return -1; + } + + if (f_getblock(&bt->f, np->nnum, bp) < 0) + return -1; + + ptr = *bp; + + d_fetchl(&ptr, (long *) &np->nd.ndFLink); + d_fetchl(&ptr, (long *) &np->nd.ndBLink); + d_fetchb(&ptr, (char *) &np->nd.ndType); + d_fetchb(&ptr, (char *) &np->nd.ndNHeight); + d_fetchw(&ptr, (short *) &np->nd.ndNRecs); + d_fetchw(&ptr, &np->nd.ndResv2); + + if (np->nd.ndNRecs > HFS_MAXRECS) + { + ERROR(EIO, "too many b*-tree node records"); + return -1; + } + + i = np->nd.ndNRecs + 1; + + ptr = *bp + HFS_BLOCKSZ - (2 * i); + + while (i--) + d_fetchw(&ptr, (short *) &np->roff[i]); + + return 0; +} + +/* + * NAME: btree->putnode() + * DESCRIPTION: store a numbered node into a B*-tree file + */ +int bt_putnode(node *np) +{ + btree *bt = np->bt; + block *bp = &np->data; + unsigned char *ptr; + int i; + + /* verify the node exists and is marked as in-use */ + + if (np->nnum && np->nnum >= bt->hdr.bthNNodes) + { + ERROR(EIO, "write nonexistent b*-tree node"); + return -1; + } + else if (bt->map && ! BMTST(bt->map, np->nnum)) + { + ERROR(EIO, "write unallocated b*-tree node"); + return -1; + } + + ptr = *bp; + + d_storel(&ptr, np->nd.ndFLink); + d_storel(&ptr, np->nd.ndBLink); + d_storeb(&ptr, np->nd.ndType); + d_storeb(&ptr, np->nd.ndNHeight); + d_storew(&ptr, np->nd.ndNRecs); + d_storew(&ptr, np->nd.ndResv2); + + if (np->nd.ndNRecs > HFS_MAXRECS) + { + ERROR(EIO, "too many b*-tree node records"); + return -1; + } + + i = np->nd.ndNRecs + 1; + + ptr = *bp + HFS_BLOCKSZ - (2 * i); + + while (i--) + d_storew(&ptr, np->roff[i]); + + if (f_putblock(&bt->f, np->nnum, bp) < 0) + return -1; + + return 0; +} + +/* + * NAME: btree->readhdr() + * DESCRIPTION: read the header node of a B*-tree + */ +int bt_readhdr(btree *bt) +{ + unsigned char *ptr; + char *map; + int i; + unsigned long nnum; + + bt->hdrnd.bt = bt; + bt->hdrnd.nnum = 0; + + if (bt_getnode(&bt->hdrnd) < 0) + return -1; + + if (bt->hdrnd.nd.ndType != ndHdrNode || + bt->hdrnd.nd.ndNRecs != 3 || + bt->hdrnd.roff[0] != 0x00e || + bt->hdrnd.roff[1] != 0x078 || + bt->hdrnd.roff[2] != 0x0f8 || + bt->hdrnd.roff[3] != 0x1f8) + { + ERROR(EIO, "malformed b*-tree header node"); + return -1; + } + + /* read header record */ + + ptr = HFS_NODEREC(bt->hdrnd, 0); + + d_fetchw(&ptr, (short *) &bt->hdr.bthDepth); + d_fetchl(&ptr, (long *) &bt->hdr.bthRoot); + d_fetchl(&ptr, (long *) &bt->hdr.bthNRecs); + d_fetchl(&ptr, (long *) &bt->hdr.bthFNode); + d_fetchl(&ptr, (long *) &bt->hdr.bthLNode); + d_fetchw(&ptr, (short *) &bt->hdr.bthNodeSize); + d_fetchw(&ptr, (short *) &bt->hdr.bthKeyLen); + d_fetchl(&ptr, (long *) &bt->hdr.bthNNodes); + d_fetchl(&ptr, (long *) &bt->hdr.bthFree); + + for (i = 0; i < 76; ++i) + d_fetchb(&ptr, (char *) &bt->hdr.bthResv[i]); + + if (bt->hdr.bthNodeSize != HFS_BLOCKSZ) + { + ERROR(EINVAL, "unsupported b*-tree node size"); + return -1; + } + + /* read map record; construct btree bitmap */ + /* don't set bt->map until we're done, since getnode() checks it */ + + map = ALLOC(char, HFS_MAP1SZ); + if (map == 0) + { + ERROR(ENOMEM, 0); + return -1; + } + + memcpy(map, HFS_NODEREC(bt->hdrnd, 2), HFS_MAP1SZ); + bt->mapsz = HFS_MAP1SZ; + + /* read continuation map records, if any */ + + nnum = bt->hdrnd.nd.ndFLink; + + while (nnum) + { + node n; + char *newmap; + + n.bt = bt; + n.nnum = nnum; + + if (bt_getnode(&n) < 0) + { + FREE(map); + return -1; + } + + if (n.nd.ndType != ndMapNode || + n.nd.ndNRecs != 1 || + n.roff[0] != 0x00e || + n.roff[1] != 0x1fa) + { + FREE(map); + ERROR(EIO, "malformed b*-tree map node"); + return -1; + } + + newmap = REALLOC(map, char, bt->mapsz + HFS_MAPXSZ); + if (newmap == 0) + { + FREE(map); + ERROR(ENOMEM, 0); + return -1; + } + map = newmap; + + memcpy(map + bt->mapsz, HFS_NODEREC(n, 0), HFS_MAPXSZ); + bt->mapsz += HFS_MAPXSZ; + + nnum = n.nd.ndFLink; + } + + bt->map = map; + + return 0; +} + +/* + * NAME: btree->writehdr() + * DESCRIPTION: write the header node of a B*-tree + */ +int bt_writehdr(btree *bt) +{ + unsigned char *ptr; + char *map; + unsigned long mapsz, nnum; + int i; + + if (bt->hdrnd.bt != bt || + bt->hdrnd.nnum != 0 || + bt->hdrnd.nd.ndType != ndHdrNode || + bt->hdrnd.nd.ndNRecs != 3) + abort(); + + ptr = HFS_NODEREC(bt->hdrnd, 0); + + d_storew(&ptr, bt->hdr.bthDepth); + d_storel(&ptr, bt->hdr.bthRoot); + d_storel(&ptr, bt->hdr.bthNRecs); + d_storel(&ptr, bt->hdr.bthFNode); + d_storel(&ptr, bt->hdr.bthLNode); + d_storew(&ptr, bt->hdr.bthNodeSize); + d_storew(&ptr, bt->hdr.bthKeyLen); + d_storel(&ptr, bt->hdr.bthNNodes); + d_storel(&ptr, bt->hdr.bthFree); + + for (i = 0; i < 76; ++i) + d_storeb(&ptr, bt->hdr.bthResv[i]); + + memcpy(HFS_NODEREC(bt->hdrnd, 2), bt->map, HFS_MAP1SZ); + + if (bt_putnode(&bt->hdrnd) < 0) + return -1; + + map = bt->map + HFS_MAP1SZ; + mapsz = bt->mapsz - HFS_MAP1SZ; + + nnum = bt->hdrnd.nd.ndFLink; + + while (mapsz) + { + node n; + + if (nnum == 0) + { + ERROR(EIO, "truncated b*-tree map"); + return -1; + } + + n.bt = bt; + n.nnum = nnum; + + if (bt_getnode(&n) < 0) + return -1; + + if (n.nd.ndType != ndMapNode || + n.nd.ndNRecs != 1 || + n.roff[0] != 0x00e || + n.roff[1] != 0x1fa) + { + ERROR(EIO, "malformed b*-tree map node"); + return -1; + } + + memcpy(HFS_NODEREC(n, 0), map, HFS_MAPXSZ); + + if (bt_putnode(&n) < 0) + return -1; + + map += HFS_MAPXSZ; + mapsz -= HFS_MAPXSZ; + + nnum = n.nd.ndFLink; + } + + bt->flags &= ~HFS_UPDATE_BTHDR; + + return 0; +} + +/* High-Level B*-Tree Routines ============================================= */ + +/* + * NAME: btree->space() + * DESCRIPTION: assert space for new records, or extend the file + */ +int bt_space(btree *bt, unsigned int nrecs) +{ + unsigned int nnodes; + int space; + + nnodes = nrecs * (bt->hdr.bthDepth + 1); + + if (nnodes <= bt->hdr.bthFree) + return 0; + + /* make sure the extents tree has room too */ + + if (bt != &bt->f.vol->ext) + { + if (bt_space(&bt->f.vol->ext, 1) < 0) + return -1; + } + + space = f_alloc(&bt->f); + if (space < 0) + return -1; + + nnodes = space * (bt->f.vol->mdb.drAlBlkSiz / bt->hdr.bthNodeSize); + + bt->hdr.bthNNodes += nnodes; + bt->hdr.bthFree += nnodes; + + bt->flags |= HFS_UPDATE_BTHDR; + + bt->f.vol->flags |= HFS_UPDATE_ALTMDB; + + while (bt->hdr.bthNNodes > bt->mapsz * 8) + { + char *newmap; + node mapnd; + + /* extend tree map */ + + newmap = REALLOC(bt->map, char, bt->mapsz + HFS_MAPXSZ); + if (newmap == 0) + { + ERROR(ENOMEM, 0); + return -1; + } + + memset(newmap + bt->mapsz, 0, HFS_MAPXSZ); + + bt->map = newmap; + bt->mapsz += HFS_MAPXSZ; + + n_init(&mapnd, bt, ndMapNode, 0); + if (n_new(&mapnd) < 0) + return -1; + + /* link the new map node */ + + if (bt->hdrnd.nd.ndFLink == 0) + { + bt->hdrnd.nd.ndFLink = mapnd.nnum; + mapnd.nd.ndBLink = 0; + } + else + { + node n; + + n.bt = bt; + n.nnum = bt->hdrnd.nd.ndFLink; + + for (;;) + { + if (bt_getnode(&n) < 0) + return -1; + + if (n.nd.ndFLink == 0) + break; + + n.nnum = n.nd.ndFLink; + } + + n.nd.ndFLink = mapnd.nnum; + mapnd.nd.ndBLink = n.nnum; + + if (bt_putnode(&n) < 0) + return -1; + } + + mapnd.nd.ndNRecs = 1; + mapnd.roff[1] = 0x1fa; + + if (bt_putnode(&mapnd) < 0) + return -1; + } + + return 0; +} + +/* + * NAME: btree->insertx() + * DESCRIPTION: recursively locate a node and insert a record + */ +int bt_insertx(node *np, unsigned char *record, int *reclen) +{ + node child; + unsigned char *rec; + + if (n_search(np, record)) + { + ERROR(EIO, "b*-tree record already exists"); + return -1; + } + + switch ((unsigned char) np->nd.ndType) + { + case ndIndxNode: + if (np->rnum < 0) + rec = HFS_NODEREC(*np, 0); + else + rec = HFS_NODEREC(*np, np->rnum); + + child.bt = np->bt; + child.nnum = d_getl(HFS_RECDATA(rec)); + + if (bt_getnode(&child) < 0 || + bt_insertx(&child, record, reclen) < 0) + return -1; + + if (np->rnum < 0) + { + n_index(np->bt, HFS_NODEREC(child, 0), child.nnum, rec, 0); + if (*reclen == 0) + return bt_putnode(np); + } + + return *reclen ? n_insert(np, record, reclen) : 0; + + case ndLeafNode: + return n_insert(np, record, reclen); + + default: + ERROR(EIO, "unexpected b*-tree node"); + return -1; + } +} + +/* + * NAME: btree->insert() + * DESCRIPTION: insert a new node record into a tree + */ +int bt_insert(btree *bt, unsigned char *record, int reclen) +{ + node root; + + if (bt->hdr.bthRoot == 0) + { + /* create root node */ + + n_init(&root, bt, ndLeafNode, 1); + if (n_new(&root) < 0 || + bt_putnode(&root) < 0) + return -1; + + bt->hdr.bthDepth = 1; + bt->hdr.bthRoot = root.nnum; + bt->hdr.bthFNode = root.nnum; + bt->hdr.bthLNode = root.nnum; + + bt->flags |= HFS_UPDATE_BTHDR; + } + else + { + root.bt = bt; + root.nnum = bt->hdr.bthRoot; + + if (bt_getnode(&root) < 0) + return -1; + } + + if (bt_insertx(&root, record, &reclen) < 0) + return -1; + + if (reclen) + { + unsigned char oroot[HFS_MAXRECLEN]; + int orootlen; + + /* root node was split; create a new root */ + + n_index(bt, HFS_NODEREC(root, 0), root.nnum, oroot, &orootlen); + + n_init(&root, bt, ndIndxNode, root.nd.ndNHeight + 1); + if (n_new(&root) < 0) + return -1; + + ++bt->hdr.bthDepth; + bt->hdr.bthRoot = root.nnum; + + bt->flags |= HFS_UPDATE_BTHDR; + + /* insert index records for new root */ + + n_search(&root, oroot); + n_insertx(&root, oroot, orootlen); + + n_search(&root, record); + n_insertx(&root, record, reclen); + + if (bt_putnode(&root) < 0) + return -1; + } + + ++bt->hdr.bthNRecs; + bt->flags |= HFS_UPDATE_BTHDR; + + return 0; +} + +/* + * NAME: btree->deletex() + * DESCRIPTION: recursively locate a node and delete a record + */ +int bt_deletex(node *np, unsigned char *key, unsigned char *record, int *flag) +{ + node child; + unsigned char *rec; + int found; + + found = n_search(np, key); + + switch ((unsigned char) np->nd.ndType) + { + case ndIndxNode: + if (np->rnum < 0) + { + ERROR(EIO, "b*-tree record not found"); + return -1; + } + + rec = HFS_NODEREC(*np, np->rnum); + + child.bt = np->bt; + child.nnum = d_getl(HFS_RECDATA(rec)); + + if (bt_getnode(&child) < 0 || + bt_deletex(&child, key, rec, flag) < 0) + return -1; + + if (*flag) + { + *flag = 0; + + if (HFS_RECKEYLEN(rec) == 0) + return n_delete(np, record, flag); + + if (np->rnum == 0) + { + n_index(np->bt, HFS_NODEREC(*np, 0), np->nnum, record, 0); + *flag = 1; + } + + return bt_putnode(np); + } + + return 0; + + case ndLeafNode: + if (found == 0) + { + ERROR(EIO, "b*-tree record not found"); + return -1; + } + + return n_delete(np, record, flag); + + default: + ERROR(EIO, "unexpected b*-tree node"); + return -1; + } +} + +/* + * NAME: btree->delete() + * DESCRIPTION: remove a node record from a tree + */ +int bt_delete(btree *bt, unsigned char *key) +{ + node root; + unsigned char record[HFS_MAXRECLEN]; + int flag = 0; + + root.bt = bt; + root.nnum = bt->hdr.bthRoot; + + if (root.nnum == 0) + { + ERROR(EIO, "empty b*-tree"); + return -1; + } + + if (bt_getnode(&root) < 0 || + bt_deletex(&root, key, record, &flag) < 0) + return -1; + + if (bt->hdr.bthDepth > 1 && root.nd.ndNRecs == 1) + { + unsigned char *rec; + + /* chop the root */ + + rec = HFS_NODEREC(root, 0); + + --bt->hdr.bthDepth; + bt->hdr.bthRoot = d_getl(HFS_RECDATA(rec)); + + n_free(&root); + } + else if (bt->hdr.bthDepth == 1 && root.nd.ndNRecs == 0) + { + /* delete the root node */ + + bt->hdr.bthDepth = 0; + bt->hdr.bthRoot = 0; + bt->hdr.bthFNode = 0; + bt->hdr.bthLNode = 0; + + n_free(&root); + } + + --bt->hdr.bthNRecs; + bt->flags |= HFS_UPDATE_BTHDR; + + return 0; +} + +/* + * NAME: btree->search() + * DESCRIPTION: locate a data record given a search key + */ +int bt_search(btree *bt, unsigned char *key, node *np) +{ + np->bt = bt; + np->nnum = bt->hdr.bthRoot; + + if (np->nnum == 0) + { + ERROR(ENOENT, 0); + return 0; + } + + for (;;) + { + int found; + unsigned char *rec; + + if (bt_getnode(np) < 0) + return -1; + + found = n_search(np, key); + + switch ((unsigned char) np->nd.ndType) + { + case ndIndxNode: + if (np->rnum < 0) + { + ERROR(ENOENT, 0); + return 0; + } + + rec = HFS_NODEREC(*np, np->rnum); + np->nnum = d_getl(HFS_RECDATA(rec)); + break; + + case ndLeafNode: + if (! found) + ERROR(ENOENT, 0); + + return found; + + default: + ERROR(EIO, "unexpected b*-tree node"); + return -1; + } + } +} diff --git a/libhfs_iso/btree.h b/libhfs_iso/btree.h new file mode 100644 index 0000000..c4b7629 --- /dev/null +++ b/libhfs_iso/btree.h @@ -0,0 +1,47 @@ +/* + * 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. + * + */ + +/* @(#)btree.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +int bt_getnode(node *); +int bt_putnode(node *); + +int bt_readhdr(btree *); +int bt_writehdr(btree *); + +int bt_space(btree *, unsigned int); + +int bt_insertx(node *, unsigned char *, int *); +int bt_insert(btree *, unsigned char *, int); + +int bt_deletex(node *, unsigned char *, unsigned char *, int *); +int bt_delete(btree *, unsigned char *); + +int bt_search(btree *, unsigned char *, node *); diff --git a/libhfs_iso/data.c b/libhfs_iso/data.c new file mode 100644 index 0000000..3f503f4 --- /dev/null +++ b/libhfs_iso/data.c @@ -0,0 +1,379 @@ +/* + * 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. + * + */ + +/* @(#)data.c 1.5 02/02/10 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <strdefs.h> +#include <timedefs.h> + +#include "internal.h" +#include "data.h" +#include "btree.h" + +#ifdef APPLE_HYB +/* + * Depending on the version, AppleDouble/Single stores dates + * relative to 1st Jan 1904 (v1) or 1st Jan 2000 (v2) + * + * DUTDIFF is the difference between 1st Jan 2000 and + * 1st Jan 1970 (Unix epoch)). + */ + +#define DUTDIFF 946684800L +#endif /* APPLE_HYB */ +#define MUTDIFF 2082844800L +#define TZNONE 0x0FFFFFFFL /* A timezone diff that cannot occur */ + +static void calctzdiff(void); + +static +unsigned long tzdiff = TZNONE; + +static +unsigned char hfs_charorder[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + + 0x20, 0x22, 0x23, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + + 0x47, 0x48, 0x58, 0x5a, 0x5e, 0x60, 0x67, 0x69, + 0x6b, 0x6d, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7f, + 0x8d, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9f, 0xa1, + 0xa3, 0xa5, 0xa8, 0xaa, 0xab, 0xac, 0xad, 0xae, + + 0x54, 0x48, 0x58, 0x5a, 0x5e, 0x60, 0x67, 0x69, + 0x6b, 0x6d, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7f, + 0x8d, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9f, 0xa1, + 0xa3, 0xa5, 0xa8, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + + 0x4c, 0x50, 0x5c, 0x62, 0x7d, 0x81, 0x9a, 0x55, + 0x4a, 0x56, 0x4c, 0x4e, 0x50, 0x5c, 0x62, 0x64, + 0x65, 0x66, 0x6f, 0x70, 0x71, 0x72, 0x7d, 0x89, + 0x8a, 0x8b, 0x81, 0x83, 0x9c, 0x9d, 0x9e, 0x9a, + + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0x95, + 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0x52, 0x85, + 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xcb, 0x57, 0x8c, 0xcc, 0x52, 0x85, + + 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0x26, + 0x27, 0xd4, 0x20, 0x4a, 0x4e, 0x83, 0x87, 0x87, + 0xd5, 0xd6, 0x24, 0x25, 0x2d, 0x2e, 0xd7, 0xd8, + 0xa7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +/* + * NAME: data->getb() + * DESCRIPTION: marshal 1 byte into local host format + */ +char d_getb(unsigned char *ptr) +{ + return (char) ptr[0]; +} + +/* + * NAME: data->getw() + * DESCRIPTION: marshal 2 bytes into local host format + */ +short d_getw(unsigned char *ptr) +{ + return (short) + ((ptr[0] << 8) | + (ptr[1] << 0)); +} + +/* + * NAME: data->getl() + * DESCRIPTION: marshal 4 bytes into local host format + */ +long d_getl(unsigned char *ptr) +{ + return (long) + ((ptr[0] << 24) | + (ptr[1] << 16) | + (ptr[2] << 8) | + (ptr[3] << 0)); +} + +/* + * NAME: data->putb() + * DESCRIPTION: marshal 1 byte out to Macintosh (big-endian) format + */ +#ifdef PROTOTYPES +void d_putb(unsigned char *ptr, char data) +#else +void d_putb(unsigned char *ptr, char data) +#endif +{ + ptr[0] = (unsigned char) data; +} + +/* + * NAME: data->putw() + * DESCRIPTION: marshal 2 bytes out to Macintosh (big-endian) format + */ +#ifdef PROTOTYPES +void d_putw(unsigned char *ptr, short data) +#else +void d_putw(unsigned char *ptr, short data) +#endif +{ + ptr[0] = ((unsigned) data & 0xff00) >> 8; + ptr[1] = ((unsigned) data & 0x00ff) >> 0; +} + +/* + * NAME: data->putl() + * DESCRIPTION: marshal 4 bytes out to Macintosh (big-endian) format + */ +void d_putl(unsigned char *ptr, long data) +{ + ptr[0] = ((unsigned long) data & 0xff000000) >> 24; + ptr[1] = ((unsigned long) data & 0x00ff0000) >> 16; + ptr[2] = ((unsigned long) data & 0x0000ff00) >> 8; + ptr[3] = ((unsigned long) data & 0x000000ff) >> 0; +} + +/* + * NAME: data->fetchb() + * DESCRIPTION: incrementally retrieve a byte of data + */ +void d_fetchb(unsigned char **ptr, char *dest) +{ + *dest = d_getb(*ptr); + *ptr += 1; +} + +/* + * NAME: data->fetchw() + * DESCRIPTION: incrementally retrieve a word of data + */ +void d_fetchw(unsigned char **ptr, short *dest) +{ + *dest = d_getw(*ptr); + *ptr += 2; +} + +/* + * NAME: data->fetchl() + * DESCRIPTION: incrementally retrieve a long word of data + */ +void d_fetchl(unsigned char **ptr, long *dest) +{ + *dest = d_getl(*ptr); + *ptr += 4; +} + +/* + * NAME: data->fetchs() + * DESCRIPTION: incrementally retrieve a string + */ +void d_fetchs(unsigned char **ptr, char *dest, int size) +{ + int len; + char blen; + + d_fetchb(ptr, &blen); + len = blen; + + if (len > 0 && len < size) + memcpy(dest, *ptr, len); + else + len = 0; + + dest[len] = 0; + + *ptr += size - 1; +} + +/* + * NAME: data->storeb() + * DESCRIPTION: incrementally store a byte of data + */ +#ifdef PROTOTYPES +void d_storeb(unsigned char **ptr, char data) +#else +void d_storeb(unsigned char **ptr, char data) +#endif +{ + d_putb(*ptr, data); + *ptr += 1; +} + +/* + * NAME: data->storew() + * DESCRIPTION: incrementally store a word of data + */ +#ifdef PROTOTYPES +void d_storew(unsigned char **ptr, short data) +#else +void d_storew(unsigned char **ptr, short data) +#endif +{ + d_putw(*ptr, data); + *ptr += 2; +} + +/* + * NAME: data->storel() + * DESCRIPTION: incrementally store a long word of data + */ +void d_storel(unsigned char **ptr, long data) +{ + d_putl(*ptr, data); + *ptr += 4; +} + +/* + * NAME: data->stores() + * DESCRIPTION: incrementally store a string + */ +void d_stores(unsigned char **ptr, char *src, int size) +{ + int len; + + len = strlen(src); + if (len > --size) + len = 0; + + d_storeb(ptr, (unsigned char) len); + + memcpy(*ptr, src, len); + memset(*ptr + len, 0, size - len); + + *ptr += size; +} + +/* + * NAME: calctzdiff() + * DESCRIPTION: calculate the timezone difference between local time and UTC + */ +static void calctzdiff() +{ + time_t t; + int isdst; + struct tm tm, *tmp; + + time(&t); + isdst = localtime(&t)->tm_isdst; + + tmp = gmtime(&t); + if (tmp) + { + tm = *tmp; + tm.tm_isdst = isdst; + + tzdiff = t - mktime(&tm); + } + else + tzdiff = 0; +} + +/* + * NAME: data->tomtime() + * DESCRIPTION: convert UNIX time to Macintosh time + */ +unsigned long d_tomtime(unsigned long secs) +{ + time_t utime = secs; + + if (tzdiff == TZNONE) + calctzdiff(); + + return utime + tzdiff + MUTDIFF; +} + +/* + * NAME: data->toutime() + * DESCRIPTION: convert Macintosh time to UNIX time + */ +unsigned long d_toutime(unsigned long secs) +{ + time_t utime = secs; + + if (tzdiff == TZNONE) + calctzdiff(); + + return utime - MUTDIFF - tzdiff; +} + +#ifdef APPLE_HYB +/* + * NAME: data->dtoutime() + * DESCRIPTION: convert Apple Double v2 time to UNIX time + */ +unsigned long d_dtoutime(long secs) +{ + time_t utime = secs; + + if (tzdiff == TZNONE) + calctzdiff(); + + return utime + DUTDIFF - tzdiff; +} +#endif /* APPLE_HYB */ + +/* + * NAME: data->relstring() + * DESCRIPTION: compare two strings as per MacOS for HFS + */ +int d_relstring(char *str1, char *str2) +{ + int diff; + + while (*str1 && *str2) + { + diff = hfs_charorder[(unsigned char) *str1] - + hfs_charorder[(unsigned char) *str2]; + + if (diff) + return diff; + + ++str1, ++str2; + } + + if (! *str1 && *str2) + return -1; + else if (*str1 && ! *str2) + return 1; + + return 0; +} diff --git a/libhfs_iso/data.h b/libhfs_iso/data.h new file mode 100644 index 0000000..b3a68a5 --- /dev/null +++ b/libhfs_iso/data.h @@ -0,0 +1,57 @@ +/* + * 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. + * + */ + +/* @(#)data.h 1.2 01/11/11 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +char d_getb(unsigned char *); +short d_getw(unsigned char *); +long d_getl(unsigned char *); + +void d_putb(unsigned char *, char); +void d_putw(unsigned char *, short); +void d_putl(unsigned char *, long); + +void d_fetchb(unsigned char **, char *); +void d_fetchw(unsigned char **, short *); +void d_fetchl(unsigned char **, long *); +void d_fetchs(unsigned char **, char *, int); + +void d_storeb(unsigned char **, char); +void d_storew(unsigned char **, short); +void d_storel(unsigned char **, long); +void d_stores(unsigned char **, char *, int); + +unsigned long d_tomtime(unsigned long); +unsigned long d_toutime(unsigned long); +#ifdef APPLE_HYB +unsigned long d_dtoutime(long); +#endif /* APPLE_HYB */ + +int d_relstring(char *, char *); diff --git a/libhfs_iso/file.c b/libhfs_iso/file.c new file mode 100644 index 0000000..a0198c8 --- /dev/null +++ b/libhfs_iso/file.c @@ -0,0 +1,470 @@ +/* + * 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. + * + */ + +/* @(#)file.c 1.3 04/06/17 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <strdefs.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "block.h" +#include "file.h" +#include "btree.h" +#include "record.h" +#include "volume.h" + +/* #include <stdio.h> */ + + +/* + * NAME: file->selectfork() + * DESCRIPTION: choose a fork for file operations + */ +void f_selectfork(hfsfile *file, int ffork) +{ + if (ffork == 0) + { + file->fork = fkData; + memcpy(file->ext, file->cat.u.fil.filExtRec, sizeof(ExtDataRec)); + } + else + { + file->fork = fkRsrc; + memcpy(file->ext, file->cat.u.fil.filRExtRec, sizeof(ExtDataRec)); + } + + file->fabn = 0; + file->pos = 0; +} + +/* + * NAME: file->getptrs() + * DESCRIPTION: make pointers to the current fork's lengths and extents + */ +void f_getptrs(hfsfile *file, unsigned long **lglen, unsigned long **pylen, + ExtDataRec **extrec) +{ + if (file->fork == fkData) + { + if (lglen) + *lglen = &file->cat.u.fil.filLgLen; + if (pylen) + *pylen = &file->cat.u.fil.filPyLen; + if (extrec) + *extrec = &file->cat.u.fil.filExtRec; + } + else + { + if (lglen) + *lglen = &file->cat.u.fil.filRLgLen; + if (pylen) + *pylen = &file->cat.u.fil.filRPyLen; + if (extrec) + *extrec = &file->cat.u.fil.filRExtRec; + } +} + +/* + * NAME: file->doblock() + * DESCRIPTION: read or write a numbered block from a file + */ +int f_doblock(hfsfile *file, unsigned long number, block *bp, + int (*func)(hfsvol *, unsigned int, unsigned int, block *)) +{ + unsigned int abnum; + unsigned int blnum; + unsigned int fabn; + int i; + + abnum = number / file->vol->lpa; + blnum = number % file->vol->lpa; + + /* locate the appropriate extent record */ + + fabn = file->fabn; + + if (abnum < fabn) + { + ExtDataRec *extrec; + + f_getptrs(file, 0, 0, &extrec); + + fabn = file->fabn = 0; + memcpy(file->ext, extrec, sizeof(ExtDataRec)); + } + else + abnum -= fabn; + + for (;;) + { + unsigned int num; + + for (i = 0; i < 3; ++i) + { + num = file->ext[i].xdrNumABlks; + +#ifdef APPLE_HYB + if (i > 0) { +/* SHOULD NOT HAPPEN! - all the files should not be fragmented + if this happens, then a serious problem has occured, may be + a hard linked file? */ +#ifdef DEBUG + fprintf(stderr,"fragmented file: %s %d\n",file->name, i); */ +#endif /* DEBUG */ + ERROR(HCE_ERROR, "Possible Catalog file overflow - please report error"); + return -1; + } +#endif /* APPLE_HYB */ + if (abnum < num) + return func(file->vol, file->ext[i].xdrStABN + abnum, blnum, bp); + + fabn += num; + abnum -= num; + } + + if (v_extsearch(file, fabn, &file->ext, 0) <= 0) + return -1; + + file->fabn = fabn; + } +} + +/* + * NAME: file->alloc() + * DESCRIPTION: reserve disk blocks for a file + */ +int f_alloc(hfsfile *file) +{ + hfsvol *vol = file->vol; + ExtDescriptor blocks; + ExtDataRec *extrec; + unsigned long *pylen, clumpsz; + unsigned int start, end; + node n; + int i; + + clumpsz = file->clump; + if (clumpsz == 0) + clumpsz = vol->mdb.drClpSiz; + + blocks.xdrNumABlks = clumpsz / vol->mdb.drAlBlkSiz; + + if (v_allocblocks(vol, &blocks) < 0) + return -1; + + /* update the file's extents */ + + f_getptrs(file, 0, &pylen, &extrec); + + start = file->fabn; + end = *pylen / vol->mdb.drAlBlkSiz; + + n.nnum = 0; + i = -1; + + while (start < end) + { + for (i = 0; i < 3; ++i) + { + unsigned int num; + + num = file->ext[i].xdrNumABlks; + start += num; + + if (start == end) + break; + else if (start > end) + { + v_freeblocks(vol, &blocks); + ERROR(EIO, "file extents exceed file physical length"); + return -1; + } + else if (num == 0) + { + v_freeblocks(vol, &blocks); + ERROR(EIO, "empty file extent"); + return -1; + } + } + + if (start == end) + break; + + if (v_extsearch(file, start, &file->ext, &n) <= 0) + { + v_freeblocks(vol, &blocks); + return -1; + } + + file->fabn = start; + } + + if (i >= 0 && + file->ext[i].xdrStABN + file->ext[i].xdrNumABlks == blocks.xdrStABN) + file->ext[i].xdrNumABlks += blocks.xdrNumABlks; + else + { + /* create a new extent descriptor */ + + if (++i < 3) + file->ext[i] = blocks; + else + { + ExtKeyRec key; + unsigned char record[HFS_EXTRECMAXLEN]; + int reclen; + + /* record is full; create a new one */ + + file->ext[0] = blocks; + + for (i = 1; i < 3; ++i) + { + file->ext[i].xdrStABN = 0; + file->ext[i].xdrNumABlks = 0; + } + + file->fabn = start; + + r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, end); + r_packextkey(&key, record, &reclen); + r_packextdata(&file->ext, HFS_RECDATA(record), &reclen); + + if (bt_insert(&vol->ext, record, reclen) < 0) + { + v_freeblocks(vol, &blocks); + return -1; + } + + i = -1; + } + } + + if (i >= 0) + { + /* store the modified extent record */ + + if (file->fabn) + { + if ((n.nnum == 0 && + v_extsearch(file, file->fabn, 0, &n) <= 0) || + v_putextrec(&file->ext, &n) < 0) + { + v_freeblocks(vol, &blocks); + return -1; + } + } + else + memcpy(extrec, file->ext, sizeof(ExtDataRec)); + } + + *pylen += blocks.xdrNumABlks * vol->mdb.drAlBlkSiz; + + file->flags |= HFS_UPDATE_CATREC; + + return blocks.xdrNumABlks; +} + +/* + * NAME: file->trunc() + * DESCRIPTION: release disk blocks unneeded by a file + */ +int f_trunc(hfsfile *file) +{ + ExtDataRec *extrec; + unsigned long *lglen, *pylen, alblksz, newpylen; + unsigned int dlen, start, end; + node n; + int i; + + f_getptrs(file, &lglen, &pylen, &extrec); + + alblksz = file->vol->mdb.drAlBlkSiz; + newpylen = (*lglen / alblksz + (*lglen % alblksz != 0)) * alblksz; + + if (newpylen > *pylen) + { + ERROR(EIO, "file size exceeds physical length"); + return -1; + } + else if (newpylen == *pylen) + return 0; + + dlen = (*pylen - newpylen) / alblksz; + + start = file->fabn; + end = newpylen / alblksz; + + if (start >= end) + { + start = file->fabn = 0; + memcpy(file->ext, extrec, sizeof(ExtDataRec)); + } + + n.nnum = 0; + i = -1; + + while (start < end) + { + for (i = 0; i < 3; ++i) + { + unsigned int num; + + num = file->ext[i].xdrNumABlks; + start += num; + + if (start >= end) + break; + else if (num == 0) + { + ERROR(EIO, "empty file extent"); + return -1; + } + } + + if (start >= end) + break; + + if (v_extsearch(file, start, &file->ext, &n) <= 0) + return -1; + + file->fabn = start; + } + + if (start > end) + { + ExtDescriptor blocks; + + file->ext[i].xdrNumABlks -= start - end; + dlen -= start - end; + + blocks.xdrStABN = file->ext[i].xdrStABN + file->ext[i].xdrNumABlks; + blocks.xdrNumABlks = start - end; + + v_freeblocks(file->vol, &blocks); + } + + *pylen = newpylen; + + file->flags |= HFS_UPDATE_CATREC; + + do + { + while (dlen && ++i < 3) + { + unsigned int num; + + num = file->ext[i].xdrNumABlks; + start += num; + + if (num == 0) + { + ERROR(EIO, "empty file extent"); + return -1; + } + else if (num > dlen) + { + ERROR(EIO, "file extents exceed physical size"); + return -1; + } + + dlen -= num; + v_freeblocks(file->vol, &file->ext[i]); + + file->ext[i].xdrStABN = 0; + file->ext[i].xdrNumABlks = 0; + } + + if (file->fabn) + { + if (n.nnum == 0 && + v_extsearch(file, file->fabn, 0, &n) <= 0) + return -1; + + if (file->ext[0].xdrNumABlks) + { + if (v_putextrec(&file->ext, &n) < 0) + return -1; + } + else + { + if (bt_delete(&file->vol->ext, HFS_NODEREC(n, n.rnum)) < 0) + return -1; + + n.nnum = 0; + } + } + else + memcpy(extrec, file->ext, sizeof(ExtDataRec)); + + if (dlen) + { + if (v_extsearch(file, start, &file->ext, &n) <= 0) + return -1; + + file->fabn = start; + i = -1; + } + } + while (dlen); + + return 0; +} + +/* + * NAME: file->flush() + * DESCRIPTION: flush all pending changes to an open file + */ +int f_flush(hfsfile *file) +{ + hfsvol *vol = file->vol; + + if (! (vol->flags & HFS_READONLY)) + { + if (file->flags & HFS_UPDATE_CATREC) + { + node n; + + file->cat.u.fil.filStBlk = file->cat.u.fil.filExtRec[0].xdrStABN; + file->cat.u.fil.filRStBlk = file->cat.u.fil.filRExtRec[0].xdrStABN; + file->cat.u.fil.filClpSize = file->clump; + + if (v_catsearch(file->vol, file->parid, file->name, 0, 0, &n) <= 0 || + v_putcatrec(&file->cat, &n) < 0) + return -1; + + file->flags &= ~HFS_UPDATE_CATREC; + } + } + + return 0; +} diff --git a/libhfs_iso/file.h b/libhfs_iso/file.h new file mode 100644 index 0000000..9b95bd6 --- /dev/null +++ b/libhfs_iso/file.h @@ -0,0 +1,48 @@ +/* + * 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. + * + */ + +/* @(#)file.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +enum { + fkData = 0x00, + fkRsrc = 0xff +}; + +void f_selectfork(hfsfile *, int); +void f_getptrs(hfsfile *, unsigned long **, unsigned long **, ExtDataRec **); + +int f_doblock(hfsfile *, unsigned long, block *, + int (*)(hfsvol *, unsigned int, unsigned int, block *)); + +# define f_getblock(file, num, bp) f_doblock(file, num, bp, b_readab) +# define f_putblock(file, num, bp) f_doblock(file, num, bp, b_writeab) + +int f_alloc(hfsfile *); +int f_flush(hfsfile *); diff --git a/libhfs_iso/gdata.c b/libhfs_iso/gdata.c new file mode 100644 index 0000000..7642083 --- /dev/null +++ b/libhfs_iso/gdata.c @@ -0,0 +1,20 @@ +/* + * 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. + * + */ + +/* @(#)gdata.c 1.1 01/01/21 Copyright 2001 J. Schilling */ + +#include <mconfig.h> +#include "internal.h" + +char *hfs_error = "no error"; /* static error string */ +hfsvol *hfs_mounts; /* linked list of mounted volumes */ +hfsvol *hfs_curvol; /* current volume */ diff --git a/libhfs_iso/hfs.c b/libhfs_iso/hfs.c new file mode 100644 index 0000000..fb63ef4 --- /dev/null +++ b/libhfs_iso/hfs.c @@ -0,0 +1,2098 @@ +/* + * 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. + * + */ + +/* @(#)hfs.c 1.9 04/06/17 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* APPLE_HYB James Pearson j.pearson@ps.ucl.ac.uk 16/7/97 */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <ctype.h> +#include <statdefs.h> + +#include "internal.h" +#include "data.h" +#include "block.h" +#include "low.h" +#include "file.h" +#include "btree.h" +#include "node.h" +#include "record.h" +#include "volume.h" +#include "hfs.h" + +/* High-Level Volume Routines ============================================== */ + +/* + * NAME: hfs->mount() + * DESCRIPTION: open an HFS volume; return volume descriptor or 0 (error) + */ +#ifdef APPLE_HYB +hfsvol *hfs_mount(hce_mem *hce, int pnum, int flags) +#else +hfsvol *hfs_mount(char *path, int pnum, int flags) +#endif /* APPLE_HYB */ +{ +#ifndef APPLE_HYB + struct stat dev; +#endif + hfsvol *vol = 0; + +#ifndef APPLE_HYB + /* see if the volume is already mounted */ + + if (stat(path, &dev) >= 0) + { + struct stat mdev; + hfsvol *check; + + for (check = hfs_mounts; check; check = check->next) + { + if (fstat(check->fd, &mdev) >= 0 && + mdev.st_dev == dev.st_dev && + mdev.st_ino == dev.st_ino && + (check->pnum == 0 || check->pnum == pnum)) + { + /* verify compatible read/write mode */ + + if (((check->flags & HFS_READONLY) && + ! (flags & O_WRONLY)) || + (! (check->flags & HFS_READONLY) && + (flags & (O_WRONLY | O_RDWR)))) + { + vol = check; + break; + } + } + } + } +#endif /* APPLE_HYB */ + if (vol == 0) + { + vol = ALLOC(hfsvol, 1); + if (vol == 0) + { + ERROR(ENOMEM, 0); + return 0; + } + + vol->flags = 0; + vol->pnum = pnum; + vol->vstart = 0; + vol->vlen = 0; + vol->lpa = 0; + vol->vbm = 0; + vol->cwd = HFS_CNID_ROOTDIR; + + vol->refs = 0; + vol->files = 0; + vol->dirs = 0; + vol->prev = 0; + vol->next = 0; + + vol->ext.map = 0; + vol->ext.mapsz = 0; + vol->ext.flags = 0; + vol->ext.compare = r_compareextkeys; + + vol->cat.map = 0; + vol->cat.mapsz = 0; + vol->cat.flags = 0; + vol->cat.compare = r_comparecatkeys; + + /* open and lock the device */ + +#ifdef APPLE_HYB + vol->fd = 3; /* any +ve number will do? */ + vol->hce = hce; /* store the extra with the vol info */ +#else + if (flags & (O_WRONLY | O_RDWR)) + { + vol->fd = open(path, O_RDWR); + if (vol->fd >= 0 && l_lockvol(vol) < 0) + { + close(vol->fd); + vol->fd = -2; + } + } + + if (! (flags & (O_WRONLY | O_RDWR)) || + (vol->fd < 0 && + (errno == EROFS || errno == EACCES || errno == EAGAIN) && + (flags & O_RDWR))) + { + vol->flags |= HFS_READONLY; + vol->fd = open(path, O_RDONLY); + if (vol->fd >= 0 && l_lockvol(vol) < 0) + { + close(vol->fd); + vol->fd = -2; + } + } + + if (vol->fd < 0) + { + if (vol->fd != -2) + ERROR(errno, "error opening device"); + + v_destruct(vol); + + return 0; + } +#endif /* APPLE_HYB */ + + /* find out what kind of media this is and read the MDB */ + + if (l_readblock0(vol) < 0 || + l_readmdb(vol) < 0) + { +#ifndef APPLE_HYB + close(vol->fd); + v_destruct(vol); +#endif /* APPLE_HYB */ + return 0; + } + + /* verify this is an HFS volume */ + + if (vol->mdb.drSigWord != 0x4244) + { +#ifndef APPLE_HYB + close(vol->fd); +#endif /* APPLE_HYB */ + v_destruct(vol); + + ERROR(EINVAL, "not a Macintosh HFS volume"); + return 0; + } + + /* do minimal consistency checks */ + + if (vol->mdb.drAlBlkSiz % HFS_BLOCKSZ != 0) + { +#ifndef APPLE_HYB + close(vol->fd); +#endif /* APPLE_HYB */ + v_destruct(vol); + + ERROR(EINVAL, "bad volume allocation block size"); + return 0; + } + + if (vol->vlen == 0) + vol->vlen = vol->mdb.drAlBlSt + + vol->mdb.drNmAlBlks * (vol->mdb.drAlBlkSiz / HFS_BLOCKSZ) + 2; + + /* read the volume bitmap and extents/catalog B*-tree headers */ + + if (l_readvbm(vol) < 0 || + bt_readhdr(&vol->ext) < 0 || + bt_readhdr(&vol->cat) < 0) + { +#ifndef APPLE_HYB + close(vol->fd); +#endif /* APPLE_HYB */ + v_destruct(vol); + return 0; + } + + if (! (vol->mdb.drAtrb & HFS_ATRB_UMOUNTED)) + { + /* volume was not cleanly unmounted; scavenge free-space */ + + if (v_scavenge(vol) < 0) + { +#ifndef APPLE_HYB + close(vol->fd); +#endif /* APPLE_HYB */ + v_destruct(vol); + return 0; + } + } + + if (vol->flags & HFS_READONLY) + vol->mdb.drAtrb |= HFS_ATRB_HLOCKED; + else + vol->mdb.drAtrb &= ~HFS_ATRB_HLOCKED; + + vol->prev = 0; + vol->next = hfs_mounts; + + if (hfs_mounts) + hfs_mounts->prev = vol; + + hfs_mounts = vol; + } + + ++vol->refs; + + return hfs_curvol = vol; +} + +/* + * NAME: hfs->flush() + * DESCRIPTION: flush all pending changes to an HFS volume + */ +int hfs_flush(hfsvol *vol) +{ + hfsfile *file; + + if (v_getvol(&vol) < 0) + return -1; + + for (file = vol->files; file; file = file->next) + { + if (f_flush(file) < 0) + return -1; + } + + if (v_flush(vol, 0) < 0) + return -1; + + return 0; +} + +/* + * NAME: hfs->flushall() + * DESCRIPTION: flush all pending changes to all mounted HFS volumes + */ +void hfs_flushall() +{ + hfsvol *vol; + + for (vol = hfs_mounts; vol; vol = vol->next) + hfs_flush(vol); +} + +/* + * NAME: hfs->umount() + * DESCRIPTION: close an HFS volume + */ +#ifdef APPLE_HYB +/* extra argument used to alter the position of the extents/catalog files */ +int hfs_umount(hfsvol *vol, long end, long locked) +#else +int hfs_umount(hfsvol *vol) +#endif /* APPLE_HYB */ +{ + int result = 0; + + if (v_getvol(&vol) < 0) + return -1; + + if (--vol->refs) + return v_flush(vol, 0); + + /* close all open files and directories */ + + while (vol->files) +#ifdef APPLE_HYB + hfs_close(vol->files, 0, 0); +#else + hfs_close(vol->files); +#endif /* APPLE_HYB */ + + while (vol->dirs) + hfs_closedir(vol->dirs); + +#ifdef APPLE_HYB + if (end) + { + /* move extents and catalog to end of volume ... */ + long vbmsz = (vol->vlen / vol->lpa + 4095) / 4096; + + /* we are adding this "files" to the end of the ISO volume, + so calculate this address in HFS speak ... */ +/* end -= vol->mdb.drAlBlSt; */ + end -= (vol->mdb.drAlBlSt + vol->hce->hfs_map_size); + end /= vol->lpa; + + /* catalog file ... */ + vol->ext.f.cat.u.fil.filExtRec[0].xdrStABN = end; + vol->mdb.drXTExtRec[0].xdrStABN = end; + + /* move postition to start of extents file */ + end += vol->cat.f.cat.u.fil.filExtRec[0].xdrStABN; + + /* extents file ... */ + vol->cat.f.cat.u.fil.filExtRec[0].xdrStABN = end; + vol->mdb.drCTExtRec[0].xdrStABN = end; + + /* the volume bitmap is wrong as we have "moved" files + about - simple just set the whole lot (it's a readonly volume + anyway!) */ + memset(vol->vbm, 0xff, vbmsz*HFS_BLOCKSZ); + + /* set the free blocks to zero */ + vol->mdb.drFreeBks = 0; + + /* flag changes for flushing later */ + vol->flags |= HFS_UPDATE_VBM; + vol->flags |= HFS_UPDATE_MDB; + vol->mdb.drAtrb |= HFS_ATRB_HLOCKED; + if (locked) { + vol->mdb.drAtrb |= HFS_ATRB_SLOCKED; + } + vol->ext.flags |= HFS_UPDATE_BTHDR; + vol->cat.flags |= HFS_UPDATE_BTHDR; + } +#endif /* APPLE_HYB */ + + if (v_flush(vol, 1) < 0) + result = -1; + +#ifndef APPLE_HYB + if (close(vol->fd) < 0 && result == 0) + { + ERROR(errno, "error closing device"); + result = -1; + } +#endif /* APPLE_HYB */ + + if (vol->prev) + vol->prev->next = vol->next; + if (vol->next) + vol->next->prev = vol->prev; + + if (vol == hfs_mounts) + hfs_mounts = vol->next; + if (vol == hfs_curvol) + hfs_curvol = 0; + + v_destruct(vol); + + return result; +} + +/* + * NAME: hfs->umountall() + * DESCRIPTION: unmount all mounted volumes + */ +void hfs_umountall() +{ + while (hfs_mounts) +#ifdef APPLE_HYB + continue; +#else + hfs_umount(hfs_mounts); +#endif /* APPLE_HYB */ +} + +/* + * NAME: hfs->getvol() + * DESCRIPTION: return a pointer to a mounted volume + */ +hfsvol *hfs_getvol(char *name) +{ + hfsvol *vol; + + if (name == 0) + return hfs_curvol; + + for (vol = hfs_mounts; vol; vol = vol->next) + { + if (d_relstring(name, vol->mdb.drVN) == 0) + return vol; + } + + return 0; +} + +/* + * NAME: hfs->setvol() + * DESCRIPTION: change the current volume + */ +void hfs_setvol(hfsvol *vol) +{ + hfs_curvol = vol; +} + +/* + * NAME: hfs->vstat() + * DESCRIPTION: return volume statistics + */ +int hfs_vstat(hfsvol *vol, hfsvolent *ent) +{ + if (v_getvol(&vol) < 0) + return -1; + + strcpy(ent->name, vol->mdb.drVN); + + ent->flags = (vol->flags & HFS_READONLY) ? HFS_ISLOCKED : 0; + ent->totbytes = vol->mdb.drNmAlBlks * vol->mdb.drAlBlkSiz; + ent->freebytes = vol->mdb.drFreeBks * vol->mdb.drAlBlkSiz; + ent->crdate = d_toutime(vol->mdb.drCrDate); + ent->mddate = d_toutime(vol->mdb.drLsMod); + + return 0; +} + +/* + * NAME: hfs->format() + * DESCRIPTION: write a new filesystem + */ +#ifdef APPLE_HYB +int hfs_format(hce_mem *hce, int pnum, char *vname) +#else +int hfs_format(char *path, int pnum, char *vname) +#endif /* APPLE_HYB */ +{ + hfsvol vol; + btree *ext = &vol.ext; + btree *cat = &vol.cat; + unsigned int vbmsz; + int i, result = 0; + block vbm[16]; + char *map; + + if (strchr(vname, ':')) + { + ERROR(EINVAL, "volume name may not contain colons"); + return -1; + } + + i = strlen(vname); + if (i < 1 || i > HFS_MAX_VLEN) + { + ERROR(EINVAL, "volume name must be 1-27 chars"); + return -1; + } + + vol.flags = 0; + vol.pnum = pnum; + vol.vstart = 0; + vol.vlen = 0; + vol.lpa = 0; + vol.vbm = vbm; + vol.cwd = HFS_CNID_ROOTDIR; + + vol.refs = 0; + vol.files = 0; + vol.dirs = 0; + vol.prev = 0; + vol.next = 0; + +#ifndef APPLE_HYB + vol.fd = open(path, O_RDWR); + if (vol.fd < 0) + { + ERROR(errno, "error opening device for writing"); + return -1; + } + + if (l_lockvol(&vol) < 0) + { + close(vol.fd); + return -1; + } +#endif /* APPLE_HYB */ + if (pnum > 0) + { + if (l_readpm(&vol) < 0) + { + close(vol.fd); + return -1; + } + } + else /* determine size of entire device */ + { +#ifdef APPLE_HYB + vol.vlen = hce->hfs_vol_size; +#else + unsigned long low, high, mid; + block b; + + for (low = 0, high = 2879; b_readlb(&vol, high, &b) >= 0; high *= 2) + low = high; + + while (low < high - 1) + { + mid = (low + high) / 2; + + if (b_readlb(&vol, mid, &b) < 0) + high = mid; + else + low = mid; + } + + vol.vlen = low + 1; +#endif /* APPLE_HYB */ + } + + if (vol.vlen < 800 * 1024 / HFS_BLOCKSZ) + { +#ifndef APPLE_HYB + close(vol.fd); +#endif /* APPLE_HYB */ + + ERROR(EINVAL, "volume size must be >= 800K"); + return -1; + } + + /* initialize volume geometry */ + +#ifdef APPLE_HYB + /* force lpa to be a multiple of 4 (i.e. 2048/512) - as calculated + earlier */ + vol.lpa = hce->Csize/HFS_BLOCKSZ; +#else + vol.lpa = 1 + vol.vlen / 65536; +#endif /* APPLE_HYB */ + + vbmsz = (vol.vlen / vol.lpa + 4095) / 4096; + + vol.mdb.drSigWord = 0x4244; + vol.mdb.drCrDate = d_tomtime(time(0)); + vol.mdb.drLsMod = vol.mdb.drCrDate; + vol.mdb.drAtrb = 0; + vol.mdb.drNmFls = 0; + vol.mdb.drVBMSt = 3; + vol.mdb.drAllocPtr = 0; + vol.mdb.drNmAlBlks = (vol.vlen - 5 - vbmsz) / vol.lpa; + vol.mdb.drAlBlkSiz = vol.lpa * HFS_BLOCKSZ; + vol.mdb.drClpSiz = vol.mdb.drAlBlkSiz * 4; + vol.mdb.drAlBlSt = 3 + vbmsz; +#ifdef APPLE_HYB + /* round up start block to a muliple of lpa - important later */ +/*vol.mdb.drAlBlSt = ((vol.mdb.drAlBlSt + vol.lpa - 1) / vol.lpa) * vol.lpa; +*/ + /* take in accout alignment of files wrt HFS volume start i.e we want + drAlBlSt plus hfs_map_size to me a multiple of lpa */ + vol.mdb.drAlBlSt = ((vol.mdb.drAlBlSt + hce->hfs_map_size + vol.lpa - 1) / vol.lpa) * vol.lpa; + vol.mdb.drAlBlSt -= hce->hfs_map_size; +#endif /* APPLE_HYB */ + vol.mdb.drNxtCNID = HFS_CNID_ROOTDIR; /* modified later */ + vol.mdb.drFreeBks = vol.mdb.drNmAlBlks; + + strcpy(vol.mdb.drVN, vname); + + vol.mdb.drVolBkUp = 0; + vol.mdb.drVSeqNum = 0; + vol.mdb.drWrCnt = 0; + vol.mdb.drXTClpSiz = vol.mdb.drNmAlBlks / 128 * vol.mdb.drAlBlkSiz; +#ifdef APPLE_HYB + /* adjust size of extents/catalog upwards as we may have rounded up + allocation size */ + i = 1 + vol.vlen / 65536; + + vol.mdb.drXTClpSiz = (vol.mdb.drXTClpSiz * vol.lpa) / i; + + /* round up to lpa size */ + vol.mdb.drXTClpSiz = ((vol.mdb.drXTClpSiz + vol.mdb.drAlBlkSiz - 1) / + vol.mdb.drAlBlkSiz) * vol.mdb.drAlBlkSiz; + + /* ignore above, use what we have already calculated ... */ + vol.mdb.drXTClpSiz = hce->XTCsize; + + /* make Catalog file CTC (default twice) as big - prevents further allocation + later which we don't want - this seems to work OK ... */ +/*vol.mdb.drCTClpSiz = vol.mdb.drXTClpSiz * CTC; */ + vol.mdb.drCTClpSiz = vol.mdb.drXTClpSiz * hce->ctc_size; + + /* we want to put things at the end of the volume later, so we'll + cheat here ... shouldn't matter, as we only need the volume read + only anyway (we won't be adding files later!) - leave some extra + space for the alternative MDB (in the last allocation block) */ + + vol.mdb.drNmAlBlks = vol.mdb.drFreeBks = vol.vlen / vol.lpa - 1; +#else + vol.mdb.drCTClpSiz = vol.mdb.drXTClpSiz; +#endif /* APPLE_HYB */ + vol.mdb.drNmRtDirs = 0; + vol.mdb.drFilCnt = 0; + vol.mdb.drDirCnt = -1; /* incremented when root folder is created */ + + for (i = 0; i < 8; ++i) + vol.mdb.drFndrInfo[i] = 0; + + vol.mdb.drVCSize = 0; + vol.mdb.drVBMCSize = 0; + vol.mdb.drCtlCSize = 0; + + vol.mdb.drXTFlSize = 0; + vol.mdb.drCTFlSize = 0; + + for (i = 0; i < 3; ++i) + { + vol.mdb.drXTExtRec[i].xdrStABN = 0; + vol.mdb.drXTExtRec[i].xdrNumABlks = 0; + + vol.mdb.drCTExtRec[i].xdrStABN = 0; + vol.mdb.drCTExtRec[i].xdrNumABlks = 0; + } + + /* initialize volume bitmap */ + + memset(vol.vbm, 0, sizeof(vbm)); + +#ifdef APPLE_HYB + /* We don't want to write anything out at the moment, so we allocate + memory to hold the HFS "header" info and extents/catalog files. + Any reads/writes from/to these parts of the volume are trapped and + stored in memory. */ + + /* blocks up to the first unallocated block == HFS "header" info + This will be placed in the first 32kb of the ISO volume later */ + hce->hfs_hdr_size = vol.mdb.drAlBlSt; + + /* size of the extents and catalog files. This will be added + to the end of the ISO volume later */ + hce->hfs_ce_size = vol.mdb.drXTClpSiz + vol.mdb.drCTClpSiz; + + /* we also allocate space for the Desktop file and the alternative + MDB while we're here */ + FREE(hce->hfs_ce); + hce->hfs_ce = ALLOC(unsigned char, (hce->hfs_ce_size + vol.mdb.drClpSiz + + vol.mdb.drAlBlkSiz)); + + /* allocate memory for the map and hdr */ + FREE(hce->hfs_map); + hce->hfs_map = ALLOC(unsigned char, ((hce->hfs_hdr_size + hce->hfs_map_size) + *HFS_BLOCKSZ)); + + if (hce->hfs_ce == 0 || hce->hfs_map == 0) + { + ERROR(ENOMEM, 0); + result = -1; + } + + /* hfs_hdr is immediately after the hfs_map */ + hce->hfs_hdr = hce->hfs_map + hce->hfs_map_size*HFS_BLOCKSZ; + + /* size needed in HFS_BLOCKSZ blocks for later use */ + hce->hfs_ce_size /= HFS_BLOCKSZ; + + /* note size of Desktop file */ + hce->hfs_dt_size = vol.mdb.drClpSiz/HFS_BLOCKSZ; + + /* total size of catalog/extents and desktop */ + hce->hfs_tot_size = hce->hfs_ce_size + hce->hfs_dt_size; + + /* alternative MDB in the last alocation block */ + hce->hfs_alt_mdb = hce->hfs_ce + hce->hfs_tot_size*HFS_BLOCKSZ; + + /* add the MDB to the total size */ + hce->hfs_tot_size += vol.lpa; + + /* store this info in the volume info */ + vol.hce = hce; + +#endif /* APPLE_HYB */ + + /* create extents overflow file */ + + ext->f.vol = &vol; + ext->f.parid = 0; + strcpy(ext->f.name, "extents overflow"); + + ext->f.cat.cdrType = cdrFilRec; + /* ext->f.cat.cdrResrv2 */ + ext->f.cat.u.fil.filFlags = 0; + ext->f.cat.u.fil.filTyp = 0; + /* ext->f.cat.u.fil.filUsrWds */ + ext->f.cat.u.fil.filFlNum = HFS_CNID_EXT; + ext->f.cat.u.fil.filStBlk = 0; + ext->f.cat.u.fil.filLgLen = 0; + ext->f.cat.u.fil.filPyLen = 0; + ext->f.cat.u.fil.filRStBlk = 0; + ext->f.cat.u.fil.filRLgLen = 0; + ext->f.cat.u.fil.filRPyLen = 0; + ext->f.cat.u.fil.filCrDat = vol.mdb.drCrDate; + ext->f.cat.u.fil.filMdDat = vol.mdb.drLsMod; + ext->f.cat.u.fil.filBkDat = 0; + /* ext->f.cat.u.fil.filFndrInfo */ + ext->f.cat.u.fil.filClpSize = 0; + + for (i = 0; i < 3; ++i) + { + ext->f.cat.u.fil.filExtRec[i].xdrStABN = 0; + ext->f.cat.u.fil.filExtRec[i].xdrNumABlks = 0; + + ext->f.cat.u.fil.filRExtRec[i].xdrStABN = 0; + ext->f.cat.u.fil.filRExtRec[i].xdrNumABlks = 0; + } + /* ext->f.cat.u.fil.filResrv */ + f_selectfork(&ext->f, 0); + + ext->f.clump = vol.mdb.drXTClpSiz; + ext->f.flags = 0; + + ext->f.prev = ext->f.next = 0; + + n_init(&ext->hdrnd, ext, ndHdrNode, 0); + + ext->hdrnd.nnum = 0; + ext->hdrnd.nd.ndNRecs = 3; + ext->hdrnd.roff[1] = 0x078; + ext->hdrnd.roff[2] = 0x0f8; + ext->hdrnd.roff[3] = 0x1f8; + + memset(HFS_NODEREC(ext->hdrnd, 1), 0, 128); + + ext->hdr.bthDepth = 0; + ext->hdr.bthRoot = 0; + ext->hdr.bthNRecs = 0; + ext->hdr.bthFNode = 0; + ext->hdr.bthLNode = 0; + ext->hdr.bthNodeSize = HFS_BLOCKSZ; + ext->hdr.bthKeyLen = 0x07; + ext->hdr.bthNNodes = 0; + ext->hdr.bthFree = 0; + for (i = 0; i < 76; ++i) + ext->hdr.bthResv[i] = 0; + + map = ALLOC(char, HFS_MAP1SZ); + if (map == 0) + { + if (result == 0) + { + ERROR(ENOMEM, 0); + result = -1; + } + } + else + { + memset(map, 0, HFS_MAP1SZ); + BMSET(map, 0); + } + + ext->map = map; + ext->mapsz = HFS_MAP1SZ; + ext->flags = HFS_UPDATE_BTHDR; + ext->compare = r_compareextkeys; + + if (result == 0 && bt_space(ext, 1) < 0) + result = -1; + + --ext->hdr.bthFree; + + /* create catalog file */ + + cat->f.vol = &vol; + cat->f.parid = 0; + strcpy(cat->f.name, "catalog"); + + cat->f.cat.cdrType = cdrFilRec; + /* cat->f.cat.cdrResrv2 */ + cat->f.cat.u.fil.filFlags = 0; + cat->f.cat.u.fil.filTyp = 0; + /* cat->f.cat.u.fil.filUsrWds */ + cat->f.cat.u.fil.filFlNum = HFS_CNID_CAT; + cat->f.cat.u.fil.filStBlk = 0; + cat->f.cat.u.fil.filLgLen = 0; + cat->f.cat.u.fil.filPyLen = 0; + cat->f.cat.u.fil.filRStBlk = 0; + cat->f.cat.u.fil.filRLgLen = 0; + cat->f.cat.u.fil.filRPyLen = 0; + cat->f.cat.u.fil.filCrDat = vol.mdb.drCrDate; + cat->f.cat.u.fil.filMdDat = vol.mdb.drLsMod; + cat->f.cat.u.fil.filBkDat = 0; + /* cat->f.cat.u.fil.filFndrInfo */ + cat->f.cat.u.fil.filClpSize = 0; + + for (i = 0; i < 3; ++i) + { + cat->f.cat.u.fil.filExtRec[i].xdrStABN = 0; + cat->f.cat.u.fil.filExtRec[i].xdrNumABlks = 0; + + cat->f.cat.u.fil.filRExtRec[i].xdrStABN = 0; + cat->f.cat.u.fil.filRExtRec[i].xdrNumABlks = 0; + } + /* cat->f.cat.u.fil.filResrv */ + f_selectfork(&cat->f, 0); + + cat->f.clump = vol.mdb.drCTClpSiz; + cat->f.flags = 0; + + cat->f.prev = cat->f.next = 0; + + n_init(&cat->hdrnd, cat, ndHdrNode, 0); + + cat->hdrnd.nnum = 0; + cat->hdrnd.nd.ndNRecs = 3; + cat->hdrnd.roff[1] = 0x078; + cat->hdrnd.roff[2] = 0x0f8; + cat->hdrnd.roff[3] = 0x1f8; + + memset(HFS_NODEREC(cat->hdrnd, 1), 0, 128); + + cat->hdr.bthDepth = 0; + cat->hdr.bthRoot = 0; + cat->hdr.bthNRecs = 0; + cat->hdr.bthFNode = 0; + cat->hdr.bthLNode = 0; + cat->hdr.bthNodeSize = HFS_BLOCKSZ; + cat->hdr.bthKeyLen = 0x25; + cat->hdr.bthNNodes = 0; + cat->hdr.bthFree = 0; + for (i = 0; i < 76; ++i) + cat->hdr.bthResv[i] = 0; + + map = ALLOC(char, HFS_MAP1SZ); + if (map == 0) + { + if (result == 0) + { + ERROR(ENOMEM, 0); + result = -1; + } + } + else + { + memset(map, 0, HFS_MAP1SZ); + BMSET(map, 0); + } + + cat->map = map; + cat->mapsz = HFS_MAP1SZ; + cat->flags = HFS_UPDATE_BTHDR; + cat->compare = r_comparecatkeys; + + if (result == 0 && bt_space(cat, 1) < 0) + result = -1; + + --cat->hdr.bthFree; + + /* create root folder */ + + if (result == 0 && v_newfolder(&vol, HFS_CNID_ROOTPAR, vname) < 0) + result = -1; + + vol.mdb.drNxtCNID = 16; + + /* finish up */ + + if (result == 0) + { + block b; + + /* write boot blocks */ + + memset(&b, 0, sizeof(b)); + b_writelb(&vol, 0, &b); + b_writelb(&vol, 1, &b); + + /* flush other disk state */ + + vol.flags |= HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB | HFS_UPDATE_VBM; + + if (v_flush(&vol, 1) < 0) + result = -1; + } +#ifndef APPLE_HYB + if (close(vol.fd) < 0 && result == 0) + { + ERROR(errno, "error closing device"); + result = -1; + } +#endif /* APPLE_HYB */ + FREE(vol.ext.map); + FREE(vol.cat.map); + + return result; +} + +/* High-Level Directory Routines =========================================== */ + +/* + * NAME: hfs->chdir() + * DESCRIPTION: change current HFS directory + */ +int hfs_chdir(hfsvol *vol, char *path) +{ + CatDataRec data; + + if (v_getvol(&vol) < 0 || + v_resolve(&vol, path, &data, 0, 0, 0) <= 0) + return -1; + + if (data.cdrType != cdrDirRec) + { + ERROR(ENOTDIR, 0); + return -1; + } + + vol->cwd = data.u.dir.dirDirID; + + return 0; +} + +/* + * NAME: hfs->getcwd() + * DESCRIPTION: return the current working directory ID + */ +long hfs_getcwd(hfsvol *vol) +{ + if (v_getvol(&vol) < 0) + return 0; + + return vol->cwd; +} + +/* + * NAME: hfs->setcwd() + * DESCRIPTION: set the current working directory ID + */ +int hfs_setcwd(hfsvol *vol, long id) +{ + if (v_getvol(&vol) < 0) + return -1; + + if (id == vol->cwd) + return 0; + + /* make sure the directory exists */ + + if (v_getdthread(vol, id, 0, 0) <= 0) + return -1; + + vol->cwd = id; + + return 0; +} + +/* + * NAME: hfs->dirinfo() + * DESCRIPTION: given a directory ID, return its (name and) parent ID + */ +int hfs_dirinfo(hfsvol *vol, long *id, char *name) +{ + CatDataRec thread; + + if (v_getvol(&vol) < 0 || + v_getdthread(vol, *id, &thread, 0) <= 0) + return -1; + + *id = thread.u.dthd.thdParID; + + if (name) + strcpy(name, thread.u.dthd.thdCName); + + return 0; +} + +/* + * NAME: hfs->opendir() + * DESCRIPTION: prepare to read the contents of a directory + */ +hfsdir *hfs_opendir(hfsvol *vol, char *path) +{ + hfsdir *dir; + CatKeyRec key; + CatDataRec data; + unsigned char pkey[HFS_CATKEYLEN]; + + if (v_getvol(&vol) < 0) + return 0; + + dir = ALLOC(hfsdir, 1); + if (dir == 0) + { + ERROR(ENOMEM, 0); + return 0; + } + + dir->vol = vol; + + if (*path == 0) + { + /* meta-directory containing root dirs from all mounted volumes */ + + dir->dirid = 0; + dir->vptr = hfs_mounts; + } + else + { + if (v_resolve(&vol, path, &data, 0, 0, 0) <= 0) + { + FREE(dir); + return 0; + } + + if (data.cdrType != cdrDirRec) + { + FREE(dir); + ERROR(ENOTDIR, 0); + return 0; + } + + dir->dirid = data.u.dir.dirDirID; + dir->vptr = 0; + + r_makecatkey(&key, dir->dirid, ""); + r_packcatkey(&key, pkey, 0); + + if (bt_search(&vol->cat, pkey, &dir->n) <= 0) + { + FREE(dir); + return 0; + } + } + + dir->prev = 0; + dir->next = vol->dirs; + + if (vol->dirs) + vol->dirs->prev = dir; + + vol->dirs = dir; + + return dir; +} + +/* + * NAME: hfs->readdir() + * DESCRIPTION: return the next entry in the directory + */ +int hfs_readdir(hfsdir *dir, hfsdirent *ent) +{ + CatKeyRec key; + CatDataRec data; + unsigned char *ptr; + + if (dir->dirid == 0) + { + hfsvol *vol; + char cname[HFS_MAX_FLEN + 1]; + + for (vol = hfs_mounts; vol; vol = vol->next) + { + if (vol == dir->vptr) + break; + } + + if (vol == 0) + { + ERROR(ENOENT, "no more entries"); + return -1; + } + + if (v_getdthread(vol, HFS_CNID_ROOTDIR, &data, 0) <= 0 || + v_catsearch(vol, HFS_CNID_ROOTPAR, data.u.dthd.thdCName, + &data, cname, 0) < 0) + return -1; + + r_unpackdirent(HFS_CNID_ROOTPAR, cname, &data, ent); + + dir->vptr = vol->next; + + return 0; + } + + if (dir->n.rnum == -1) + { + ERROR(ENOENT, "no more entries"); + return -1; + } + + for (;;) + { + ++dir->n.rnum; + + while (dir->n.rnum >= (int)dir->n.nd.ndNRecs) + { + dir->n.nnum = dir->n.nd.ndFLink; + if (dir->n.nnum == 0) + { + dir->n.rnum = -1; + ERROR(ENOENT, "no more entries"); + return -1; + } + + if (bt_getnode(&dir->n) < 0) + { + dir->n.rnum = -1; + return -1; + } + + dir->n.rnum = 0; + } + + ptr = HFS_NODEREC(dir->n, dir->n.rnum); + + r_unpackcatkey(ptr, &key); + + if (key.ckrParID != dir->dirid) + { + dir->n.rnum = -1; + ERROR(ENOENT, "no more entries"); + return -1; + } + + r_unpackcatdata(HFS_RECDATA(ptr), &data); + + switch (data.cdrType) + { + case cdrDirRec: + case cdrFilRec: + r_unpackdirent(key.ckrParID, key.ckrCName, &data, ent); + return 0; + + case cdrThdRec: + case cdrFThdRec: + break; + + default: + dir->n.rnum = -1; + + ERROR(EIO, "unexpected directory entry found"); + return -1; + } + } +} + +/* + * NAME: hfs->closedir() + * DESCRIPTION: stop reading a directory + */ +int hfs_closedir(hfsdir *dir) +{ + hfsvol *vol = dir->vol; + + if (dir->prev) + dir->prev->next = dir->next; + if (dir->next) + dir->next->prev = dir->prev; + if (dir == vol->dirs) + vol->dirs = dir->next; + + FREE(dir); + + return 0; +} + +/* High-Level File Routines ================================================ */ + +/* + * NAME: hfs->open() + * DESCRIPTION: prepare a file for I/O + */ +hfsfile *hfs_open(hfsvol *vol, char *path) +{ + hfsfile *file; + + if (v_getvol(&vol) < 0) + return 0; + + file = ALLOC(hfsfile, 1); + if (file == 0) + { + ERROR(ENOMEM, 0); + return 0; + } + + if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, 0) <= 0) + { + FREE(file); + return 0; + } + + if (file->cat.cdrType != cdrFilRec) + { + FREE(file); + ERROR(EISDIR, 0); + return 0; + } + + file->vol = vol; + file->clump = file->cat.u.fil.filClpSize; + file->flags = 0; + + f_selectfork(file, 0); + + file->prev = 0; + file->next = vol->files; + + if (vol->files) + vol->files->prev = file; + + vol->files = file; + + return file; +} + +/* + * NAME: hfs->setfork() + * DESCRIPTION: select file fork for I/O operations + */ +int hfs_setfork(hfsfile *file, int ffork) +{ + int result = 0; + + if (! (file->vol->flags & HFS_READONLY) && + f_trunc(file) < 0) + result = -1; + + f_selectfork(file, ffork); + + return result; +} + +/* + * NAME: hfs->getfork() + * DESCRIPTION: return the current fork for I/O operations + */ +int hfs_getfork(hfsfile *file) +{ + return file->fork != fkData; +} + +/* + * NAME: hfs->read() + * DESCRIPTION: read from an open file + */ +long hfs_read(hfsfile *file, void *buf, unsigned long len) +{ + unsigned long *lglen, count; + unsigned char *ptr = buf; + + f_getptrs(file, &lglen, 0, 0); + + if (file->pos + len > *lglen) + len = *lglen - file->pos; + + count = len; + while (count) + { + block b; + unsigned long bnum, offs, chunk; + + bnum = file->pos / HFS_BLOCKSZ; + offs = file->pos % HFS_BLOCKSZ; + + chunk = HFS_BLOCKSZ - offs; + if (chunk > count) + chunk = count; + + if (f_getblock(file, bnum, &b) < 0) + return -1; + + memcpy(ptr, b + offs, chunk); + ptr += chunk; + + file->pos += chunk; + count -= chunk; + } + + return len; +} + +/* + * NAME: hfs->write() + * DESCRIPTION: write to an open file + */ +long hfs_write(hfsfile *file, void *buf, unsigned long len) +{ + unsigned long *lglen, *pylen, count; + unsigned char *ptr = buf; + + if (file->vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + f_getptrs(file, &lglen, &pylen, 0); + + count = len; + + /* set flag to update (at least) the modification time */ + + if (count) + { + file->cat.u.fil.filMdDat = d_tomtime(time(0)); + file->flags |= HFS_UPDATE_CATREC; + } + + while (count) + { + block b; + unsigned long bnum, offs, chunk; + + bnum = file->pos / HFS_BLOCKSZ; + offs = file->pos % HFS_BLOCKSZ; + + chunk = HFS_BLOCKSZ - offs; + if (chunk > count) + chunk = count; + + if (file->pos + chunk > *pylen) + { + if (bt_space(&file->vol->ext, 1) < 0 || + f_alloc(file) < 0) + return -1; + } +#ifndef APPLE_HYB + /* Ignore this part as we are always writing new files to an empty disk + i.e. offs will always be 0 */ + + if (offs > 0 || chunk < HFS_BLOCKSZ) + { + if (f_getblock(file, bnum, &b) < 0) + return -1; + } +#endif /* APPLE_HYB */ + memcpy(b + offs, ptr, chunk); + ptr += chunk; + + if (f_putblock(file, bnum, &b) < 0) + return -1; + + file->pos += chunk; + count -= chunk; + + if (file->pos > *lglen) + *lglen = file->pos; + } + + return len; +} + +/* + * NAME: hfs->truncate() + * DESCRIPTION: truncate an open file + */ +int hfs_truncate(hfsfile *file, unsigned long len) +{ + unsigned long *lglen; + + f_getptrs(file, &lglen, 0, 0); + + if (*lglen > len) + { + if (file->vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + *lglen = len; + + file->cat.u.fil.filMdDat = d_tomtime(time(0)); + file->flags |= HFS_UPDATE_CATREC; + + if (file->pos > len) + file->pos = len; + } + + return 0; +} + +/* + * NAME: hfs->lseek() + * DESCRIPTION: change file seek pointer + */ +long hfs_lseek(hfsfile *file, long offset, int from) +{ + unsigned long *lglen; + long newpos; + + f_getptrs(file, &lglen, 0, 0); + + switch (from) + { + case SEEK_SET: + newpos = offset; + break; + + case SEEK_CUR: + newpos = file->pos + offset; + break; + + case SEEK_END: + newpos = *lglen + offset; + break; + + default: + ERROR(EINVAL, 0); + return -1; + } + + if (newpos < 0) + newpos = 0; + else if (newpos > *lglen) + newpos = *lglen; + + file->pos = newpos; + + return newpos; +} + +/* + * NAME: hfs->close() + * DESCRIPTION: close a file + */ +#ifdef APPLE_HYB +/* extra args are used to set the start of the forks in the ISO volume */ +int hfs_close(hfsfile *file, long dext, long rext) +{ + int offset; +#else +int hfs_close(hfsfile *file) +{ +#endif /* APPLE_HYB */ + hfsvol *vol = file->vol; + int result = 0; + + if (f_trunc(file) < 0 || + f_flush(file) < 0) + result = -1; + +#ifdef APPLE_HYB + /* "start" of file is relative to the first available block */ + offset = vol->hce->hfs_hdr_size + vol->hce->hfs_map_size; + /* update the "real" starting extent and re-flush the file */ + if (dext) + file->cat.u.fil.filExtRec[0].xdrStABN = (dext - offset)/vol->lpa; + + if (rext) + file->cat.u.fil.filRExtRec[0].xdrStABN = (rext - offset)/vol->lpa; + + if (dext || rext) + file->flags |= HFS_UPDATE_CATREC; + + if (f_flush(file) < 0) + result = -1; +#endif /*APPLE_HYB */ + + if (file->prev) + file->prev->next = file->next; + if (file->next) + file->next->prev = file->prev; + if (file == vol->files) + vol->files = file->next; + + FREE(file); + + return result; +} + +/* High-Level Catalog Routines ============================================= */ + +/* + * NAME: hfs->stat() + * DESCRIPTION: return catalog information for an arbitrary path + */ +int hfs_stat(hfsvol *vol, char *path, hfsdirent *ent) +{ + CatDataRec data; + long parid; + char name[HFS_MAX_FLEN + 1]; + + if (v_getvol(&vol) < 0 || + v_resolve(&vol, path, &data, &parid, name, 0) <= 0) + return -1; + + r_unpackdirent(parid, name, &data, ent); + + return 0; +} + +/* + * NAME: hfs->fstat() + * DESCRIPTION: return catalog information for an open file + */ +int hfs_fstat(hfsfile *file, hfsdirent *ent) +{ + r_unpackdirent(file->parid, file->name, &file->cat, ent); + + return 0; +} + +/* + * NAME: hfs->setattr() + * DESCRIPTION: change a file's attributes + */ +int hfs_setattr(hfsvol *vol, char *path, hfsdirent *ent) +{ + CatDataRec data; + node n; + + if (v_getvol(&vol) < 0 || + v_resolve(&vol, path, &data, 0, 0, &n) <= 0) + return -1; + + if (vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + r_packdirent(&data, ent); + + if (v_putcatrec(&data, &n) < 0) + return -1; + + return 0; +} + +/* + * NAME: hfs->fsetattr() + * DESCRIPTION: change an open file's attributes + */ +int hfs_fsetattr(hfsfile *file, hfsdirent *ent) +{ + if (file->vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + r_packdirent(&file->cat, ent); + + file->flags |= HFS_UPDATE_CATREC; + + return 0; +} + +/* + * NAME: hfs->mkdir() + * DESCRIPTION: create a new directory + */ +int hfs_mkdir(hfsvol *vol, char *path) +{ + CatDataRec data; + long parid; + char name[HFS_MAX_FLEN + 1]; + int found; + + if (v_getvol(&vol) < 0) + return -1; + + found = v_resolve(&vol, path, &data, &parid, name, 0); + if (found < 0 || parid == 0) + return -1; + else if (found) + { + ERROR(EEXIST, 0); + return -1; + } + + if (parid == HFS_CNID_ROOTPAR) + { + ERROR(EINVAL, 0); + return -1; + } + + if (vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + if (v_newfolder(vol, parid, name) < 0) + return -1; + + return 0; +} + +/* + * NAME: hfs->rmdir() + * DESCRIPTION: delete an empty directory + */ +int hfs_rmdir(hfsvol *vol, char *path) +{ + CatKeyRec key; + CatDataRec data; + long parid; + char name[HFS_MAX_FLEN + 1]; + unsigned char pkey[HFS_CATKEYLEN]; + + if (v_getvol(&vol) < 0 || + v_resolve(&vol, path, &data, &parid, name, 0) <= 0) + return -1; + + if (data.cdrType != cdrDirRec) + { + ERROR(ENOTDIR, 0); + return -1; + } + + if (data.u.dir.dirVal != 0) + { + ERROR(ENOTEMPTY, 0); + return -1; + } + + if (parid == HFS_CNID_ROOTPAR) + { + ERROR(EINVAL, 0); + return -1; + } + + if (vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + /* delete directory record */ + + r_makecatkey(&key, parid, name); + r_packcatkey(&key, pkey, 0); + + if (bt_delete(&vol->cat, pkey) < 0) + return -1; + + /* delete thread record */ + + r_makecatkey(&key, data.u.dir.dirDirID, ""); + r_packcatkey(&key, pkey, 0); + + if (bt_delete(&vol->cat, pkey) < 0 || + v_adjvalence(vol, parid, 1, -1) < 0) + return -1; + + return 0; +} + +/* + * NAME: hfs->create() + * DESCRIPTION: create a new file + */ +int hfs_create(hfsvol *vol, char *path, char *type, char *creator) +{ + CatKeyRec key; + CatDataRec data; + long id, parid; + char name[HFS_MAX_FLEN + 1]; + unsigned char record[HFS_CATRECMAXLEN]; + int found, i, reclen; + + if (v_getvol(&vol) < 0) + return -1; + + found = v_resolve(&vol, path, &data, &parid, name, 0); + if (found < 0 || parid == 0) + return -1; + else if (found) + { + ERROR(EEXIST, 0); + return -1; + } + + if (parid == HFS_CNID_ROOTPAR) + { + ERROR(EINVAL, 0); + return -1; + } + + if (vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + /* create file `name' in parent `parid' */ + + if (bt_space(&vol->cat, 1) < 0) + return -1; + + id = vol->mdb.drNxtCNID++; + vol->flags |= HFS_UPDATE_MDB; + + /* create file record */ + + data.cdrType = cdrFilRec; + data.cdrResrv2 = 0; + + data.u.fil.filFlags = 0; + data.u.fil.filTyp = 0; + + memset(&data.u.fil.filUsrWds, 0, sizeof(data.u.fil.filUsrWds)); + + data.u.fil.filUsrWds.fdType = d_getl((unsigned char *) type); + data.u.fil.filUsrWds.fdCreator = d_getl((unsigned char *) creator); + + data.u.fil.filFlNum = id; + data.u.fil.filStBlk = 0; + data.u.fil.filLgLen = 0; + data.u.fil.filPyLen = 0; + data.u.fil.filRStBlk = 0; + data.u.fil.filRLgLen = 0; + data.u.fil.filRPyLen = 0; + data.u.fil.filCrDat = d_tomtime(time(0)); + data.u.fil.filMdDat = data.u.fil.filCrDat; + data.u.fil.filBkDat = 0; + + memset(&data.u.fil.filFndrInfo, 0, sizeof(data.u.fil.filFndrInfo)); + + data.u.fil.filClpSize = 0; + + for (i = 0; i < 3; ++i) + { + data.u.fil.filExtRec[i].xdrStABN = 0; + data.u.fil.filExtRec[i].xdrNumABlks = 0; + + data.u.fil.filRExtRec[i].xdrStABN = 0; + data.u.fil.filRExtRec[i].xdrNumABlks = 0; + } + + data.u.fil.filResrv = 0; + + r_makecatkey(&key, parid, name); + r_packcatkey(&key, record, &reclen); + r_packcatdata(&data, HFS_RECDATA(record), &reclen); + + if (bt_insert(&vol->cat, record, reclen) < 0 || + v_adjvalence(vol, parid, 0, 1) < 0) + return -1; + + return 0; +} + +/* + * NAME: hfs->delete() + * DESCRIPTION: remove both forks of a file + */ +int hfs_delete(hfsvol *vol, char *path) +{ + hfsfile file; + CatKeyRec key; + unsigned char pkey[HFS_CATKEYLEN]; + int found; + + if (v_getvol(&vol) < 0 || + v_resolve(&vol, path, &file.cat, &file.parid, file.name, 0) <= 0) + return -1; + + if (file.cat.cdrType != cdrFilRec) + { + ERROR(EISDIR, 0); + return -1; + } + + if (file.parid == HFS_CNID_ROOTPAR) + { + ERROR(EINVAL, 0); + return -1; + } + + if (vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + /* free disk blocks */ + + file.vol = vol; + file.flags = 0; + + file.cat.u.fil.filLgLen = 0; + file.cat.u.fil.filRLgLen = 0; + + f_selectfork(&file, 0); + if (f_trunc(&file) < 0) + return -1; + + f_selectfork(&file, 1); + if (f_trunc(&file) < 0) + return -1; + + /* delete file record */ + + r_makecatkey(&key, file.parid, file.name); + r_packcatkey(&key, pkey, 0); + + if (bt_delete(&vol->cat, pkey) < 0 || + v_adjvalence(vol, file.parid, 0, -1) < 0) + return -1; + + /* delete file thread, if any */ + + found = v_getfthread(vol, file.cat.u.fil.filFlNum, 0, 0); + if (found < 0) + return -1; + + if (found) + { + r_makecatkey(&key, file.cat.u.fil.filFlNum, ""); + r_packcatkey(&key, pkey, 0); + + if (bt_delete(&vol->cat, pkey) < 0) + return -1; + } + + return 0; +} + +/* + * NAME: hfs->rename() + * DESCRIPTION: change the name of and/or move a file or directory + */ +int hfs_rename(hfsvol *vol, char *srcpath, char *dstpath) +{ + hfsvol *srcvol; + CatDataRec src, dst; + long srcid, dstid; + CatKeyRec key; + char srcname[HFS_MAX_FLEN + 1], dstname[HFS_MAX_FLEN + 1]; + unsigned char record[HFS_CATRECMAXLEN]; + int found, isdir, moving, reclen; + node n; + + if (v_getvol(&vol) < 0 || + v_resolve(&vol, srcpath, &src, &srcid, srcname, 0) <= 0) + return -1; + + isdir = (src.cdrType == cdrDirRec); + srcvol = vol; + + found = v_resolve(&vol, dstpath, &dst, &dstid, dstname, 0); + if (found < 0) + return -1; + + if (vol != srcvol) + { + ERROR(EINVAL, "can't move across volumes"); + return -1; + } + + if (dstid == 0) + { + ERROR(ENOENT, "bad destination path"); + return -1; + } + + if (found && + dst.cdrType == cdrDirRec && + dst.u.dir.dirDirID != src.u.dir.dirDirID) + { + dstid = dst.u.dir.dirDirID; + strcpy(dstname, srcname); + + found = v_catsearch(vol, dstid, dstname, 0, 0, 0); + if (found < 0) + return -1; + } + + moving = (srcid != dstid); + + if (found) + { + char *ptr; + + ptr = strrchr(dstpath, ':'); + if (ptr == 0) + ptr = dstpath; + else + ++ptr; + + if (*ptr) + strcpy(dstname, ptr); + + if (! moving && strcmp(srcname, dstname) == 0) + return 0; /* source and destination are the same */ + + if (moving || d_relstring(srcname, dstname)) + { + ERROR(EEXIST, "can't use destination name"); + return -1; + } + } + + /* can't move anything into the root directory's parent */ + + if (moving && dstid == HFS_CNID_ROOTPAR) + { + ERROR(EINVAL, "can't move above root directory"); + return -1; + } + + if (moving && isdir) + { + long id; + + /* can't move root directory anywhere */ + + if (src.u.dir.dirDirID == HFS_CNID_ROOTDIR) + { + ERROR(EINVAL, "can't move root directory"); + return -1; + } + + /* make sure we aren't trying to move a directory inside itself */ + + for (id = dstid; id != HFS_CNID_ROOTDIR; id = dst.u.dthd.thdParID) + { + if (id == src.u.dir.dirDirID) + { + ERROR(EINVAL, "can't move directory inside itself"); + return -1; + } + + if (v_getdthread(vol, id, &dst, 0) <= 0) + return -1; + } + } + + if (vol->flags & HFS_READONLY) + { + ERROR(EROFS, 0); + return -1; + } + + /* change volume name */ + + if (dstid == HFS_CNID_ROOTPAR) + { + if (strlen(dstname) > HFS_MAX_VLEN) + { + ERROR(ENAMETOOLONG, 0); + return -1; + } + + strcpy(vol->mdb.drVN, dstname); + vol->flags |= HFS_UPDATE_MDB; + } + + /* remove source record */ + + r_makecatkey(&key, srcid, srcname); + r_packcatkey(&key, record, 0); + + if (bt_delete(&vol->cat, record) < 0) + return -1; + + /* insert destination record */ + + r_makecatkey(&key, dstid, dstname); + r_packcatkey(&key, record, &reclen); + r_packcatdata(&src, HFS_RECDATA(record), &reclen); + + if (bt_insert(&vol->cat, record, reclen) < 0) + return -1; + + /* update thread record */ + + if (isdir) + { + if (v_getdthread(vol, src.u.dir.dirDirID, &dst, &n) <= 0) + return -1; + + dst.u.dthd.thdParID = dstid; + strcpy(dst.u.dthd.thdCName, dstname); + + if (v_putcatrec(&dst, &n) < 0) + return -1; + } + else + { + found = v_getfthread(vol, src.u.fil.filFlNum, &dst, &n); + if (found < 0) + return -1; + + if (found) + { + dst.u.fthd.fthdParID = dstid; + strcpy(dst.u.fthd.fthdCName, dstname); + + if (v_putcatrec(&dst, &n) < 0) + return -1; + } + } + + /* update directory valences */ + + if (moving) + { + if (v_adjvalence(vol, srcid, isdir, -1) < 0 || + v_adjvalence(vol, dstid, isdir, 1) < 0) + return -1; + } + + return 0; +} +#ifdef APPLE_HYB +/* + * NAME: hfs->hfs_get_drAllocPtr() + * DESCRIPTION: get the current start of next allocation search + */ +unsigned short +hfs_get_drAllocPtr(hfsfile *file) +{ + return(file->vol->mdb.drAllocPtr); +} + +/* + * NAME: hfs->hfs_set_drAllocPtr() + * DESCRIPTION: set the current start of next allocation search + */ +#ifdef PROTOTYPES +int +hfs_set_drAllocPtr(hfsfile *file, unsigned short drAllocPtr, int size) +#else +int +hfs_set_drAllocPtr(hfsfile *file, unsigned short drAllocPtr, int size) +#endif +{ + hfsvol *vol = file->vol; + int result = 0; + + /* truncate the current fork */ + if (f_trunc(file) < 0 || + f_flush(file) < 0) + result = -1; + + /* convert the fork size into allocation blocks */ + size = (size + vol->mdb.drAlBlkSiz - 1)/vol->mdb.drAlBlkSiz; + + /* set the start of next allocation search to be after this fork */ + vol->mdb.drAllocPtr = drAllocPtr + size; + + vol->flags |= HFS_UPDATE_MDB; + + return result; +} + +/* + * NAME: hfs->vsetbless() + * DESCRIPTION: set blessed folder + * + * adapted from vsetattr() from v3.2.6 + */ +#ifdef PROTOTYPES +void +hfs_vsetbless(hfsvol *vol, unsigned long cnid) +#else +void +hfs_vsetbless(hfsvol *vol, unsigned long cnid) +#endif +{ + vol->mdb.drFndrInfo[0] = cnid; + + vol->flags |= HFS_UPDATE_MDB; +} +#endif /* APPLE_HYB */ diff --git a/libhfs_iso/hfs.h b/libhfs_iso/hfs.h new file mode 100644 index 0000000..f2c9d96 --- /dev/null +++ b/libhfs_iso/hfs.h @@ -0,0 +1,208 @@ +/* + * 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. + * + */ + +/* @(#)hfs.h 1.4 01/11/01 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef HFS_H +#define HFS_H + +#include <timedefs.h> +#include <standard.h> + +#ifdef APPLE_HYB +#include "hybrid.h" + +/* don't need device locking for mkhybrid */ +#ifndef NODEVLOCKS +#define NODEVLOCKS +#endif /* NODEVLOCKS */ + +#endif /* APPLE_HYB */ + +# define HFS_BLOCKSZ 512 +# define HFS_MAX_FLEN 31 +# define HFS_MAX_VLEN 27 + +typedef struct _hfsvol_ hfsvol; +typedef struct _hfsfile_ hfsfile; +typedef struct _hfsdir_ hfsdir; + +typedef struct { + char name[HFS_MAX_VLEN + 1]; /* name of volume */ + int flags; /* volume flags */ + unsigned long totbytes; /* total bytes on volume */ + unsigned long freebytes; /* free bytes on volume */ + time_t crdate; /* volume creation date */ + time_t mddate; /* last volume modification date */ +} hfsvolent; + +/* taken from v3.2.6 */ +typedef struct { + char name[HFS_MAX_FLEN + 1]; /* catalog name (MacOS Standard Roman) */ + int flags; /* bit flags */ + unsigned long cnid; /* catalog node id (CNID) */ + unsigned long parid; /* CNID of parent directory */ + + time_t crdate; /* date of creation */ + time_t mddate; /* date of last modification */ + time_t bkdate; /* date of last backup */ + + short fdflags; /* Macintosh Finder flags */ + + struct { + signed short v; /* Finder icon vertical coordinate */ + signed short h; /* horizontal coordinate */ + } fdlocation; + + union { + struct { + unsigned long dsize; /* size of data fork */ + unsigned long rsize; /* size of resource fork */ + + char type[5]; /* file type code (plus null) */ + char creator[5]; /* file creator code (plus null) */ + } file; + + struct { + unsigned short valence; /* number of items in directory */ + + struct { + signed short top; /* top edge of folder's rectangle */ + signed short left; /* left edge */ + signed short bottom; /* bottom edge */ + signed short right; /* right edge */ + } rect; + + /* mkhybrid extra */ + signed short view; /* Folder's view */ + + struct { + signed short v; /* Scoll vertical position */ + signed short h; /* Scoll horizontal position */ + } frscroll; + } dir; + } u; +} hfsdirent; + + +# define HFS_ISDIR 0x01 +# define HFS_ISLOCKED 0x02 + +# define HFS_CNID_ROOTPAR 1 +# define HFS_CNID_ROOTDIR 2 +# define HFS_CNID_EXT 3 +# define HFS_CNID_CAT 4 +# define HFS_CNID_BADALLOC 5 + +# define HFS_FNDR_ISONDESK (1 << 0) +# define HFS_FNDR_COLOR 0x0e +# define HFS_FNDR_COLORRESERVED (1 << 4) +# define HFS_FNDR_REQUIRESSWITCHLAUNCH (1 << 5) +# define HFS_FNDR_ISSHARED (1 << 6) +# define HFS_FNDR_HASNOINITS (1 << 7) +# define HFS_FNDR_HASBEENINITED (1 << 8) +# define HFS_FNDR_RESERVED (1 << 9) +# define HFS_FNDR_HASCUSTOMICON (1 << 10) +# define HFS_FNDR_ISSTATIONERY (1 << 11) +# define HFS_FNDR_NAMELOCKED (1 << 12) +# define HFS_FNDR_HASBUNDLE (1 << 13) +# define HFS_FNDR_ISINVISIBLE (1 << 14) +# define HFS_FNDR_ISALIAS (1 << 15) + +extern char *hfs_error; +/*extern unsigned char hfs_charorder[];*/ + +#ifdef APPLE_HYB +hfsvol *hfs_mount(hce_mem *, int, int); +#else +hfsvol *hfs_mount(char *, int, int); +#endif /* APPLE_HYB */ + +int hfs_flush(hfsvol *); +void hfs_flushall(void); +#ifdef APPLE_HYB +int hfs_umount(hfsvol *, long, long); +#else +int hfs_umount(hfsvol *); +#endif /* APPLE_HYB */ +void hfs_umountall(void); +hfsvol *hfs_getvol(char *); +void hfs_setvol(hfsvol *); + +int hfs_vstat(hfsvol *, hfsvolent *); +#ifdef APPLE_HYB +int hfs_format(hce_mem *, int, char *); +#else +int hfs_format(char *, int, char *); +#endif /* APPLE_HYB */ + +int hfs_chdir(hfsvol *, char *); +long hfs_getcwd(hfsvol *); +int hfs_setcwd(hfsvol *, long); +int hfs_dirinfo(hfsvol *, long *, char *); + +hfsdir *hfs_opendir(hfsvol *, char *); +int hfs_readdir(hfsdir *, hfsdirent *); +int hfs_closedir(hfsdir *); + +hfsfile *hfs_open(hfsvol *, char *); +int hfs_setfork(hfsfile *, int); +int hfs_getfork(hfsfile *); +long hfs_read(hfsfile *, void *, unsigned long); +long hfs_write(hfsfile *, void *, unsigned long); +int hfs_truncate(hfsfile *, unsigned long); +long hfs_lseek(hfsfile *, long, int); +#ifdef APPLE_HYB +int hfs_close(hfsfile *, long, long); +#else +int hfs_close(hfsfile *); +#endif /* APPLE_HYB */ + +int hfs_stat(hfsvol *, char *, hfsdirent *); +int hfs_fstat(hfsfile *, hfsdirent *); +int hfs_setattr(hfsvol *, char *, hfsdirent *); +int hfs_fsetattr(hfsfile *, hfsdirent *); + +int hfs_mkdir(hfsvol *, char *); +int hfs_rmdir(hfsvol *, char *); + +int hfs_create(hfsvol *, char *, char *, char *); +int hfs_delete(hfsvol *, char *); + +int hfs_rename(hfsvol *, char *, char *); + +int f_trunc(hfsfile *file); + +#ifdef APPLE_HYB +unsigned short hfs_get_drAllocPtr(hfsfile *); +int hfs_set_drAllocPtr(hfsfile *, unsigned short, int size); +void hfs_vsetbless(hfsvol *, unsigned long); +#endif /* APPLE_HYB */ + +#endif diff --git a/libhfs_iso/hybrid.h b/libhfs_iso/hybrid.h new file mode 100644 index 0000000..01b83a6 --- /dev/null +++ b/libhfs_iso/hybrid.h @@ -0,0 +1,67 @@ +/* + * 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. + * + */ + +/* @(#)hybrid.h 1.3 02/10/04 joerg */ +/* +** hybrid.h: extra info needed by libhfs and mkisofs +** +** James Pearson 15/9/97 +*/ + +#ifndef _HYBRID_H + +/* + * The following three variables can be overridden at run time + * by using the -hfs-parms option i.e. to use the following defaults + * you could use: -hfs-parms CTC=2,CTC_LOOP=4,MAX_XTCSIZE=4194304 + * i.e. to change just MAX_XTCSIZE to 2Mb use: + * -hfs-parms MAX_XTCSIZE=2097152 + */ + +#define CTC 2 /* factor to increase initial Catalog file + size to prevent the file growing */ +#define CTC_LOOP 4 /* number of attemps before we give up + trying to create the volume */ + +#define MAX_XTCSIZE 4*1024*1024 /* the maximum size of the Catalog file - + as the size of the Catalog file is linked + to the size of the volume, multi-gigabyte + volumes create very large Catalog and + Extent files - 4Mb is the size calculated + for a 1Gb volume - which is probably + overkill, but seems to be OK */ + +#define HCE_ERROR -9999 /* dummy errno value for Catalog file + size problems */ + +#define HFS_MAP_SIZE 16 /* size of HFS partition maps (8Kb) */ + +typedef struct { + int hfs_ce_size; /* extents/catalog size in HFS blks */ + int hfs_hdr_size; /* vol header size in HFS blks */ + int hfs_dt_size; /* Desktop file size in HFS blks */ + int hfs_tot_size; /* extents/catalog/dt size in HFS blks */ + int hfs_map_size; /* size of partition maps in HFS blks */ + unsigned long hfs_vol_size; /* size of volume in HFS blks */ + unsigned char *hfs_ce; /* mem copy of extents/catalog files */ + unsigned char *hfs_hdr; /* mem copy of vol header */ + unsigned char *hfs_alt_mdb; /* location of alternate MDB */ + unsigned char *hfs_map; /* location of partiton_maps */ + int Csize; /* size of allocation unit (bytes) */ + int XTCsize; /* def size of catalog/extents files (bytes) */ + int max_XTCsize; /* max size of catalog/extents files (bytes) */ + int ctc_size; /* factor to increase Catalog file size */ + char *error; /* HFS error message */ +} hce_mem; + +#define _HYBRID_H +#endif /* _HYBRID_H */ diff --git a/libhfs_iso/internal.h b/libhfs_iso/internal.h new file mode 100644 index 0000000..ee79b0c --- /dev/null +++ b/libhfs_iso/internal.h @@ -0,0 +1,369 @@ +/* + * 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. + * + */ + +/* @(#)internal.h 1.2 01/11/01 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <timedefs.h> +#include <standard.h> + +# include "hfs.h" + +# define ERROR(code, str) (hfs_error = (str), errno = (code)) + +# define SIZE(type, n) ((size_t) (sizeof(type) * (n))) +# define ALLOC(type, n) ((type *) malloc(SIZE(type, n))) +# define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0) +# define FREE(ptr) {if (ptr) free((void *) ptr) ;} + +# define REALLOC(ptr, type, n) \ + ((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n)))) +# define REALLOCX(ptr, type, n) \ + ((n) ? REALLOC(type, n) : (FREE(ptr), (type *) 0)) + +# define BMTST(bm, num) \ + (((char *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07))) +# define BMSET(bm, num) \ + (((char *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07))) +# define BMCLR(bm, num) \ + (((char *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07))) + +typedef unsigned char block[HFS_BLOCKSZ]; + +typedef signed char Char; +typedef unsigned char UChar; +typedef signed char SignedByte; +typedef signed short Integer; +typedef unsigned short UInteger; +typedef signed long LongInt; +typedef unsigned long ULongInt; +typedef char Str15[16]; +typedef char Str31[32]; +typedef long OSType; + +typedef struct { + UInteger xdrStABN; /* first allocation block */ + UInteger xdrNumABlks; /* number of allocation blocks */ +} ExtDescriptor; + +typedef ExtDescriptor ExtDataRec[3]; + +typedef struct { + SignedByte xkrKeyLen; /* key length */ + SignedByte xkrFkType; /* fork type (0x00/0xff == data/resource */ + ULongInt xkrFNum; /* file number */ + UInteger xkrFABN; /* starting file allocation block */ +} ExtKeyRec; + +typedef struct { + SignedByte ckrKeyLen; /* key length */ + SignedByte ckrResrv1; /* reserved */ + ULongInt ckrParID; /* parent directory ID */ + Str31 ckrCName; /* catalog node name */ +} CatKeyRec; + +# define HFS_MAP1SZ 256 +# define HFS_MAPXSZ 492 + +# define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum]) + +# define HFS_RECKEYLEN(ptr) (*(unsigned char *) (ptr)) +# define HFS_RECKEYSKIP(ptr) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1) +# define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr)) + +# define HFS_CATDATALEN sizeof(CatDataRec) +# define HFS_EXTDATALEN sizeof(ExtDataRec) + +# define HFS_CATKEYLEN sizeof(CatKeyRec) +# define HFS_EXTKEYLEN sizeof(ExtKeyRec) + +# define HFS_CATRECMAXLEN (HFS_CATKEYLEN + HFS_CATDATALEN) +# define HFS_EXTRECMAXLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN) + +# define HFS_MAXRECLEN HFS_CATRECMAXLEN + +typedef struct { + Integer v; /* vertical coordinate */ + Integer h; /* horizontal coordinate */ +} Point; + +typedef struct { + Integer top; /* top edge of rectangle */ + Integer left; /* left edge */ + Integer bottom; /* bottom edge */ + Integer right; /* rightmost edge */ +} Rect; + +typedef struct { + Rect frRect; /* folder's rectangle */ + Integer frFlags; /* flags */ + Point frLocation; /* folder's location */ + Integer frView; /* folder's view */ +} DInfo; + +typedef struct { + Point frScroll; /* scroll position */ + LongInt frOpenChain; /* directory ID chain of open folders */ + Integer frUnused; /* reserved */ + Integer frComment; /* comment ID */ + LongInt frPutAway; /* directory ID */ +} DXInfo; + +typedef struct { + OSType fdType; /* file type */ + OSType fdCreator; /* file's creator */ + Integer fdFlags; /* flags */ + Point fdLocation; /* file's location */ + Integer fdFldr; /* file's window */ +} FInfo; + +typedef struct { + Integer fdIconID; /* icon ID */ + Integer fdUnused[4]; /* reserved */ + Integer fdComment; /* comment ID */ + LongInt fdPutAway; /* home directory ID */ +} FXInfo; + +typedef struct { + Integer drSigWord; /* volume signature (0x4244 for HFS) */ + LongInt drCrDate; /* date and time of volume creation */ + LongInt drLsMod; /* date and time of last modification */ + Integer drAtrb; /* volume attributes */ + UInteger drNmFls; /* number of files in root directory */ + UInteger drVBMSt; /* first block of volume bit map (always 3) */ + UInteger drAllocPtr; /* start of next allocation search */ + UInteger drNmAlBlks; /* number of allocation blocks in volume */ + ULongInt drAlBlkSiz; /* size (in bytes) of allocation blocks */ + ULongInt drClpSiz; /* default clump size */ + UInteger drAlBlSt; /* first allocation block in volume */ + LongInt drNxtCNID; /* next unused catalog node ID (dir/file ID) */ + UInteger drFreeBks; /* number of unused allocation blocks */ + char drVN[28]; /* volume name (1-27 chars) */ + LongInt drVolBkUp; /* date and time of last backup */ + Integer drVSeqNum; /* volume backup sequence number */ + ULongInt drWrCnt; /* volume write count */ + ULongInt drXTClpSiz; /* clump size for extents overflow file */ + ULongInt drCTClpSiz; /* clump size for catalog file */ + UInteger drNmRtDirs; /* number of directories in root directory */ + ULongInt drFilCnt; /* number of files in volume */ + ULongInt drDirCnt; /* number of directories in volume */ + LongInt drFndrInfo[8]; /* information used by the Finder */ + UInteger drVCSize; /* size (in blocks) of volume cache */ + UInteger drVBMCSize; /* size (in blocks) of volume bitmap cache */ + UInteger drCtlCSize; /* size (in blocks) of common volume cache */ + ULongInt drXTFlSize; /* size (in bytes) of extents overflow file */ + ExtDataRec drXTExtRec; /* first extent record for extents file */ + ULongInt drCTFlSize; /* size (in bytes) of catalog file */ + ExtDataRec drCTExtRec; /* first extent record for catalog file */ +} MDB; + +# define HFS_ATRB_BUSY (1 << 6) +# define HFS_ATRB_HLOCKED (1 << 7) +# define HFS_ATRB_UMOUNTED (1 << 8) +# define HFS_ATRB_BBSPARED (1 << 9) +# define HFS_ATRB_COPYPROT (1 << 14) +# define HFS_ATRB_SLOCKED (1 << 15) + +typedef enum { + cdrDirRec = 1, + cdrFilRec = 2, + cdrThdRec = 3, + cdrFThdRec = 4 +} CatDataType; + +typedef struct { + SignedByte cdrType; /* record type */ + SignedByte cdrResrv2; /* reserved */ + union { + struct { /* cdrDirRec */ + Integer dirFlags; /* directory flags */ + UInteger dirVal; /* directory valence */ + ULongInt dirDirID; /* directory ID */ + LongInt dirCrDat; /* date and time of creation */ + LongInt dirMdDat; /* date and time of last modification */ + LongInt dirBkDat; /* date and time of last backup */ + DInfo dirUsrInfo; /* Finder information */ + DXInfo dirFndrInfo; /* additional Finder information */ + LongInt dirResrv[4]; /* reserved */ + } dir; + struct { /* cdrFilRec */ + SignedByte + filFlags; /* file flags */ + SignedByte + filTyp; /* file type */ + FInfo filUsrWds; /* Finder information */ + ULongInt filFlNum; /* file ID */ + UInteger filStBlk; /* first alloc block of data fork */ + ULongInt filLgLen; /* logical EOF of data fork */ + ULongInt filPyLen; /* physical EOF of data fork */ + UInteger filRStBlk; /* first alloc block of resource fork */ + ULongInt filRLgLen; /* logical EOF of resource fork */ + ULongInt filRPyLen; /* physical EOF of resource fork */ + LongInt filCrDat; /* date and time of creation */ + LongInt filMdDat; /* date and time of last modification */ + LongInt filBkDat; /* date and time of last backup */ + FXInfo filFndrInfo; /* additional Finder information */ + UInteger filClpSize; /* file clump size */ + ExtDataRec + filExtRec; /* first data fork extent record */ + ExtDataRec + filRExtRec; /* first resource fork extent record */ + LongInt filResrv; /* reserved */ + } fil; + struct { /* cdrThdRec */ + LongInt thdResrv[2]; /* reserved */ + ULongInt thdParID; /* parent ID for this directory */ + Str31 thdCName; /* name of this directory */ + } dthd; + struct { /* cdrFThdRec */ + LongInt fthdResrv[2]; /* reserved */ + ULongInt fthdParID; /* parent ID for this file */ + Str31 fthdCName; /* name of this file */ + } fthd; + } u; +} CatDataRec; + +struct _hfsfile_ { + struct _hfsvol_ *vol; /* pointer to volume descriptor */ + long parid; /* parent directory ID of this file */ + char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */ + CatDataRec cat; /* catalog information */ + ExtDataRec ext; /* current extent record */ + unsigned int fabn; /* starting file allocation block number */ + int fork; /* current selected fork for I/O */ + unsigned long pos; /* current file seek pointer */ + unsigned long clump; /* file's clump size, for allocation */ + int flags; /* bit flags */ + + struct _hfsfile_ *prev; + struct _hfsfile_ *next; +}; + +# define HFS_UPDATE_CATREC 0x01 + +typedef struct { + ULongInt ndFLink; /* forward link */ + ULongInt ndBLink; /* backward link */ + SignedByte ndType; /* node type */ + SignedByte ndNHeight; /* node level */ + UInteger ndNRecs; /* number of records in node */ + Integer ndResv2; /* reserved */ +} NodeDescriptor; + +# define HFS_MAXRECS 35 /* maximum based on minimum record size */ + +typedef struct _node_ { + struct _btree_ *bt; /* btree to which this node belongs */ + unsigned long nnum; /* node index */ + NodeDescriptor nd; /* node descriptor */ + int rnum; /* current record index */ + UInteger roff[HFS_MAXRECS + 1]; /* record offsets */ + block data; /* raw contents of node */ +} node; + +enum { + ndIndxNode = 0x00, + ndHdrNode = 0x01, + ndMapNode = 0x02, + ndLeafNode = 0xff +}; + +struct _hfsdir_ { + struct _hfsvol_ *vol; /* associated volume */ + long dirid; /* directory ID of interest (or 0) */ + + node n; /* current B*-tree node */ + struct _hfsvol_ *vptr; /* current volume pointer */ + + struct _hfsdir_ *prev; + struct _hfsdir_ *next; +}; + +typedef struct { + UInteger bthDepth; /* current depth of tree */ + ULongInt bthRoot; /* number of root node */ + ULongInt bthNRecs; /* number of leaf records in tree */ + ULongInt bthFNode; /* number of first leaf node */ + ULongInt bthLNode; /* number of last leaf node */ + UInteger bthNodeSize; /* size of a node */ + UInteger bthKeyLen; /* maximum length of a key */ + ULongInt bthNNodes; /* total number of nodes in tree */ + ULongInt bthFree; /* number of free nodes */ + SignedByte bthResv[76]; /* reserved */ +} BTHdrRec; + +typedef struct _btree_ { + hfsfile f; /* subset file information */ + node hdrnd; /* header node */ + BTHdrRec hdr; /* header record */ + char *map; /* usage bitmap */ + unsigned long mapsz; /* number of bytes in bitmap */ + int flags; /* bit flags */ + + int (*compare)(unsigned char *, unsigned char *); + /* key comparison function */ +} btree; + +# define HFS_UPDATE_BTHDR 0x01 + +struct _hfsvol_ { + int fd; /* volume's open file descriptor */ + int flags; /* bit flags */ + +#ifdef APPLE_HYB + hce_mem *hce; /* Extras needed by libhfs/mkisofs */ +#endif /* APPLE_HYB */ + + int pnum; /* ordinal HFS partition number */ + unsigned long vstart; /* logical block offset to start of volume */ + unsigned long vlen; /* number of logical blocks in volume */ + unsigned int lpa; /* number of logical blocks per allocation block */ + + MDB mdb; /* master directory block */ + block *vbm; /* volume bit map */ + btree ext; /* B*-tree control block for extents overflow file */ + btree cat; /* B*-tree control block for catalog file */ + long cwd; /* directory id of current working directory */ + + int refs; /* number of external references to this volume */ + hfsfile *files; /* list of open files */ + hfsdir *dirs; /* list of open directories */ + + struct _hfsvol_ *prev; + struct _hfsvol_ *next; +}; + +# define HFS_READONLY 0x01 + +# define HFS_UPDATE_MDB 0x10 +# define HFS_UPDATE_ALTMDB 0x20 +# define HFS_UPDATE_VBM 0x40 + +extern hfsvol *hfs_mounts; +extern hfsvol *hfs_curvol; diff --git a/libhfs_iso/low.c b/libhfs_iso/low.c new file mode 100644 index 0000000..94cba83 --- /dev/null +++ b/libhfs_iso/low.c @@ -0,0 +1,529 @@ +/* + * 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. + * + */ + +/* @(#)low.c 1.4 04/06/17 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <strdefs.h> +#include <stdxlib.h> +#include <errno.h> +#include <unixstd.h> +#include <fctldefs.h> + +#include "internal.h" +#include "data.h" +#include "block.h" +#include "low.h" +#include "file.h" + +/* + * NAME: low->lockvol() + * DESCRIPTION: prevent destructive simultaneous access + */ +int l_lockvol(hfsvol *vol) +{ +# ifndef NODEVLOCKS + + struct flock lock; + + lock.l_type = (vol->flags & HFS_READONLY) ? F_RDLCK : F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + + if (fcntl(vol->fd, F_SETLK, &lock) < 0) + { + ERROR(errno, "unable to obtain lock for device"); + return -1; + } + +# endif + + return 0; +} + +/* + * NAME: low->readblock0() + * DESCRIPTION: read the first sector and get bearings + */ +int l_readblock0(hfsvol *vol) +{ + block b; + unsigned char *ptr = b; + Block0 rec; + + if (b_readlb(vol, 0, &b) < 0) + return -1; + + d_fetchw(&ptr, &rec.sbSig); + d_fetchw(&ptr, &rec.sbBlkSize); + d_fetchl(&ptr, &rec.sbBlkCount); + d_fetchw(&ptr, &rec.sbDevType); + d_fetchw(&ptr, &rec.sbDevId); + d_fetchl(&ptr, &rec.sbData); + d_fetchw(&ptr, &rec.sbDrvrCount); + d_fetchl(&ptr, &rec.ddBlock); + d_fetchw(&ptr, &rec.ddSize); + d_fetchw(&ptr, &rec.ddType); + + switch (rec.sbSig) + { + case 0x4552: /* block device with a partition table */ + { + if (rec.sbBlkSize != HFS_BLOCKSZ) + { + ERROR(EINVAL, "unsupported block size"); + return -1; + } + + vol->vlen = rec.sbBlkCount; + + if (l_readpm(vol) < 0) + return -1; + } + break; + + case 0x4c4b: /* bootable floppy */ + vol->pnum = 0; + break; + + default: /* non-bootable floppy or something else */ + + /* some miscreant media may also be partitioned; + we attempt to read a partition map, but ignore any failure */ + + if (l_readpm(vol) < 0) + vol->pnum = 0; + } + + return 0; +} + +/* + * NAME: low->readpm() + * DESCRIPTION: read the partition map and locate an HFS volume + */ +int l_readpm(hfsvol *vol) +{ + block b; + unsigned char *ptr; + Partition map; + unsigned long bnum; + int pnum; + + bnum = 1; + pnum = vol->pnum; + + for (;;) + { + if (b_readlb(vol, bnum, &b) < 0) + return -1; + + ptr = b; + + d_fetchw(&ptr, &map.pmSig); + d_fetchw(&ptr, &map.pmSigPad); + d_fetchl(&ptr, &map.pmMapBlkCnt); + d_fetchl(&ptr, &map.pmPyPartStart); + d_fetchl(&ptr, &map.pmPartBlkCnt); + + memcpy(map.pmPartName, ptr, 32); + map.pmPartName[32] = 0; + ptr += 32; + + memcpy(map.pmParType, ptr, 32); + map.pmParType[32] = 0; + ptr += 32; + + d_fetchl(&ptr, &map.pmLgDataStart); + d_fetchl(&ptr, &map.pmDataCnt); + d_fetchl(&ptr, &map.pmPartStatus); + d_fetchl(&ptr, &map.pmLgBootStart); + d_fetchl(&ptr, &map.pmBootSize); + d_fetchl(&ptr, &map.pmBootAddr); + d_fetchl(&ptr, &map.pmBootAddr2); + d_fetchl(&ptr, &map.pmBootEntry); + d_fetchl(&ptr, &map.pmBootEntry2); + d_fetchl(&ptr, &map.pmBootCksum); + + memcpy(map.pmProcessor, ptr, 16); + map.pmProcessor[16] = 0; + ptr += 16; + + if (map.pmSig == 0x5453) + { + /* old partition map sig */ + + ERROR(EINVAL, "unsupported partition map signature"); + return -1; + } + + if (map.pmSig != 0x504d) + { + ERROR(EINVAL, "bad partition map"); + return -1; + } + + if (strcmp((char *) map.pmParType, "Apple_HFS") == 0 && --pnum == 0) + { + if (map.pmLgDataStart != 0) + { + ERROR(EINVAL, "unsupported start of partition logical data"); + return -1; + } + + vol->vstart = map.pmPyPartStart; + vol->vlen = map.pmPartBlkCnt; + + return 0; + } + + if (bnum >= map.pmMapBlkCnt) + { + ERROR(EINVAL, "can't find HFS partition"); + return -1; + } + + ++bnum; + } +} + +/* + * NAME: low->readmdb() + * DESCRIPTION: read the master directory block into memory + */ +int l_readmdb(hfsvol *vol) +{ + block b; + unsigned char *ptr = b; + MDB *mdb = &vol->mdb; + hfsfile *ext = &vol->ext.f; + hfsfile *cat = &vol->cat.f; + int i; + + if (b_readlb(vol, 2, &b) < 0) + return -1; + + d_fetchw(&ptr, &mdb->drSigWord); + d_fetchl(&ptr, &mdb->drCrDate); + d_fetchl(&ptr, &mdb->drLsMod); + d_fetchw(&ptr, &mdb->drAtrb); + d_fetchw(&ptr, (short *) &mdb->drNmFls); + d_fetchw(&ptr, (short *) &mdb->drVBMSt); + d_fetchw(&ptr, (short *) &mdb->drAllocPtr); + d_fetchw(&ptr, (short *) &mdb->drNmAlBlks); + d_fetchl(&ptr, (long *) &mdb->drAlBlkSiz); + d_fetchl(&ptr, (long *) &mdb->drClpSiz); + d_fetchw(&ptr, (short *) &mdb->drAlBlSt); + d_fetchl(&ptr, &mdb->drNxtCNID); + d_fetchw(&ptr, (short *) &mdb->drFreeBks); + + d_fetchs(&ptr, mdb->drVN, sizeof(mdb->drVN)); + + if (ptr - b != 64) + abort(); + + d_fetchl(&ptr, &mdb->drVolBkUp); + d_fetchw(&ptr, &mdb->drVSeqNum); + d_fetchl(&ptr, (long *) &mdb->drWrCnt); + d_fetchl(&ptr, (long *) &mdb->drXTClpSiz); + d_fetchl(&ptr, (long *) &mdb->drCTClpSiz); + d_fetchw(&ptr, (short *) &mdb->drNmRtDirs); + d_fetchl(&ptr, (long *) &mdb->drFilCnt); + d_fetchl(&ptr, (long *) &mdb->drDirCnt); + + for (i = 0; i < 8; ++i) + d_fetchl(&ptr, &mdb->drFndrInfo[i]); + + if (ptr - b != 124) + abort(); + + d_fetchw(&ptr, (short *) &mdb->drVCSize); + d_fetchw(&ptr, (short *) &mdb->drVBMCSize); + d_fetchw(&ptr, (short *) &mdb->drCtlCSize); + + d_fetchl(&ptr, (long *) &mdb->drXTFlSize); + + for (i = 0; i < 3; ++i) + { + d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrStABN); + d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrNumABlks); + } + + if (ptr - b != 146) + abort(); + + d_fetchl(&ptr, (long *) &mdb->drCTFlSize); + + for (i = 0; i < 3; ++i) + { + d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrStABN); + d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrNumABlks); + } + + if (ptr - b != 162) + abort(); + + vol->lpa = mdb->drAlBlkSiz / HFS_BLOCKSZ; + + /* extents pseudo-file structs */ + + ext->vol = vol; + ext->parid = 0; + strcpy(ext->name, "extents overflow"); + + ext->cat.cdrType = cdrFilRec; + /* ext->cat.cdrResrv2 */ + ext->cat.u.fil.filFlags = 0; + ext->cat.u.fil.filTyp = 0; + /* ext->cat.u.fil.filUsrWds */ + ext->cat.u.fil.filFlNum = HFS_CNID_EXT; + ext->cat.u.fil.filStBlk = mdb->drXTExtRec[0].xdrStABN; + ext->cat.u.fil.filLgLen = mdb->drXTFlSize; + ext->cat.u.fil.filPyLen = mdb->drXTFlSize; + ext->cat.u.fil.filRStBlk = 0; + ext->cat.u.fil.filRLgLen = 0; + ext->cat.u.fil.filRPyLen = 0; + ext->cat.u.fil.filCrDat = mdb->drCrDate; + ext->cat.u.fil.filMdDat = mdb->drLsMod; + ext->cat.u.fil.filBkDat = 0; + /* ext->cat.u.fil.filFndrInfo */ + ext->cat.u.fil.filClpSize = 0; + + memcpy(ext->cat.u.fil.filExtRec, mdb->drXTExtRec, sizeof(ExtDataRec)); + for (i = 0; i < 3; ++i) + { + ext->cat.u.fil.filRExtRec[i].xdrStABN = 0; + ext->cat.u.fil.filRExtRec[i].xdrNumABlks = 0; + } + f_selectfork(ext, 0); + + ext->clump = mdb->drXTClpSiz; + ext->flags = 0; + + ext->prev = ext->next = 0; + + /* catalog pseudo-file structs */ + + cat->vol = vol; + cat->parid = 0; + strcpy(cat->name, "catalog"); + + cat->cat.cdrType = cdrFilRec; + /* cat->cat.cdrResrv2 */ + cat->cat.u.fil.filFlags = 0; + cat->cat.u.fil.filTyp = 0; + /* cat->cat.u.fil.filUsrWds */ + cat->cat.u.fil.filFlNum = HFS_CNID_CAT; + cat->cat.u.fil.filStBlk = mdb->drCTExtRec[0].xdrStABN; + cat->cat.u.fil.filLgLen = mdb->drCTFlSize; + cat->cat.u.fil.filPyLen = mdb->drCTFlSize; + cat->cat.u.fil.filRStBlk = 0; + cat->cat.u.fil.filRLgLen = 0; + cat->cat.u.fil.filRPyLen = 0; + cat->cat.u.fil.filCrDat = mdb->drCrDate; + cat->cat.u.fil.filMdDat = mdb->drLsMod; + cat->cat.u.fil.filBkDat = 0; + /* cat->cat.u.fil.filFndrInfo */ + cat->cat.u.fil.filClpSize = 0; + + memcpy(cat->cat.u.fil.filExtRec, mdb->drCTExtRec, sizeof(ExtDataRec)); + for (i = 0; i < 3; ++i) + { + cat->cat.u.fil.filRExtRec[i].xdrStABN = 0; + cat->cat.u.fil.filRExtRec[i].xdrNumABlks = 0; + } + f_selectfork(cat, 0); + + cat->clump = mdb->drCTClpSiz; + cat->flags = 0; + + cat->prev = cat->next = 0; + + return 0; +} + +/* + * NAME: low->writemdb() + * DESCRIPTION: write the master directory block to disk + */ +int l_writemdb(hfsvol *vol) +{ + block b; + unsigned char *ptr = b; + MDB *mdb = &vol->mdb; + hfsfile *ext = &vol->ext.f; + hfsfile *cat = &vol->cat.f; + int i; + + memset(&b, 0, sizeof(b)); + + mdb->drXTFlSize = ext->cat.u.fil.filPyLen; + mdb->drXTClpSiz = ext->clump; + memcpy(mdb->drXTExtRec, ext->cat.u.fil.filExtRec, sizeof(ExtDataRec)); + + mdb->drCTFlSize = cat->cat.u.fil.filPyLen; + mdb->drCTClpSiz = cat->clump; + memcpy(mdb->drCTExtRec, cat->cat.u.fil.filExtRec, sizeof(ExtDataRec)); + + d_storew(&ptr, mdb->drSigWord); + d_storel(&ptr, mdb->drCrDate); + d_storel(&ptr, mdb->drLsMod); + d_storew(&ptr, mdb->drAtrb); + d_storew(&ptr, mdb->drNmFls); + d_storew(&ptr, mdb->drVBMSt); + d_storew(&ptr, mdb->drAllocPtr); + d_storew(&ptr, mdb->drNmAlBlks); + d_storel(&ptr, mdb->drAlBlkSiz); + d_storel(&ptr, mdb->drClpSiz); + d_storew(&ptr, mdb->drAlBlSt); + d_storel(&ptr, mdb->drNxtCNID); + d_storew(&ptr, mdb->drFreeBks); + d_stores(&ptr, mdb->drVN, sizeof(mdb->drVN)); + + if (ptr - b != 64) + abort(); + + d_storel(&ptr, mdb->drVolBkUp); + d_storew(&ptr, mdb->drVSeqNum); + d_storel(&ptr, mdb->drWrCnt); + d_storel(&ptr, mdb->drXTClpSiz); + d_storel(&ptr, mdb->drCTClpSiz); + d_storew(&ptr, mdb->drNmRtDirs); + d_storel(&ptr, mdb->drFilCnt); + d_storel(&ptr, mdb->drDirCnt); + + for (i = 0; i < 8; ++i) + d_storel(&ptr, mdb->drFndrInfo[i]); + + if (ptr - b != 124) + abort(); + + d_storew(&ptr, mdb->drVCSize); + d_storew(&ptr, mdb->drVBMCSize); + d_storew(&ptr, mdb->drCtlCSize); + d_storel(&ptr, mdb->drXTFlSize); + + for (i = 0; i < 3; ++i) + { + d_storew(&ptr, mdb->drXTExtRec[i].xdrStABN); + d_storew(&ptr, mdb->drXTExtRec[i].xdrNumABlks); + } + + if (ptr - b != 146) + abort(); + + d_storel(&ptr, mdb->drCTFlSize); + + for (i = 0; i < 3; ++i) + { + d_storew(&ptr, mdb->drCTExtRec[i].xdrStABN); + d_storew(&ptr, mdb->drCTExtRec[i].xdrNumABlks); + } + + if (ptr - b != 162) + abort(); + + if (b_writelb(vol, 2, &b) < 0) + return -1; + if (vol->flags & HFS_UPDATE_ALTMDB) + { +#ifdef APPLE_HYB + /* "write" alternative MDB to memory copy */ + memcpy(vol->hce->hfs_alt_mdb, &b, sizeof(b)); +#else + if (b_writelb(vol, vol->vlen - 2, &b) < 0) + return -1; +#endif /* APPLE_HYB */ + } + vol->flags &= ~(HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB); + + return 0; +} + +/* + * NAME: low->readvbm() + * DESCRIPTION: read the volume bit map into memory + */ +int l_readvbm(hfsvol *vol) +{ + int vbmst = vol->mdb.drVBMSt; + int vbmsz = (vol->mdb.drNmAlBlks + 4095) / (unsigned)4096; + block *bp; + + if ((int)(vol->mdb.drAlBlSt - vbmst) < vbmsz) + { + ERROR(EIO, "volume bitmap collides with volume data"); + return -1; + } + + bp = ALLOC(block, vbmsz); + if (bp == 0) + { + ERROR(ENOMEM, 0); + return -1; + } + + vol->vbm = bp; + + while (vbmsz--) + { + if (b_readlb(vol, vbmst++, bp++) < 0) + { + FREE(vol->vbm); + vol->vbm = 0; + + return -1; + } + } + + return 0; +} + +/* + * NAME: low->writevbm() + * DESCRIPTION: write the volume bit map to disk + */ +int l_writevbm(hfsvol *vol) +{ + int vbmst = vol->mdb.drVBMSt; + int vbmsz = (vol->mdb.drNmAlBlks + 4095) / (unsigned)4096; + block *bp = vol->vbm; + + while (vbmsz--) + { + if (b_writelb(vol, vbmst++, bp++) < 0) + return -1; + } + + vol->flags &= ~HFS_UPDATE_VBM; + + return 0; +} diff --git a/libhfs_iso/low.h b/libhfs_iso/low.h new file mode 100644 index 0000000..4434444 --- /dev/null +++ b/libhfs_iso/low.h @@ -0,0 +1,111 @@ +/* + * 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. + * + */ + +/* @(#)low.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +typedef struct { + Integer sbSig; /* device signature (should be 0x4552) */ + Integer sbBlkSize; /* block size of the device (in bytes) */ + LongInt sbBlkCount; /* number of blocks on the device */ + Integer sbDevType; /* reserved */ + Integer sbDevId; /* reserved */ + LongInt sbData; /* reserved */ + Integer sbDrvrCount; /* number of driver descriptor entries */ + LongInt ddBlock; /* first driver's starting block */ + Integer ddSize; /* size of the driver, in 512-byte blocks */ + Integer ddType; /* driver operating system type (MacOS = 1) */ + Integer ddPad[243]; /* additional drivers, if any */ +} Block0; + +typedef struct { + Integer bbID; /* boot blocks signature */ + LongInt bbEntry; /* entry point to boot code */ + Integer bbVersion; /* boot blocks version number */ + Integer bbPageFlags; /* used internally */ + Str15 bbSysName; /* System filename */ + Str15 bbShellName; /* Finder filename */ + Str15 bbDbg1Name; /* debugger filename */ + Str15 bbDbg2Name; /* debugger filename */ + Str15 bbScreenName; /* name of startup screen */ + Str15 bbHelloName; /* name of startup program */ + Str15 bbScrapName; /* name of system scrap file */ + Integer bbCntFCBs; /* number of FCBs to allocate */ + Integer bbCntEvts; /* number of event queue elements */ + LongInt bb128KSHeap; /* system heap size on 128K Mac */ + LongInt bb256KSHeap; /* used internally */ + LongInt bbSysHeapSize; /* system heap size on all machines */ + Integer filler; /* reserved */ + LongInt bbSysHeapExtra; /* additional system heap space */ + LongInt bbSysHeapFract; /* fraction of RAM for system heap */ +} BootBlkHdr; + +typedef struct { + Integer pmSig; /* partition signature (0x504d or 0x5453) */ + Integer pmSigPad; /* reserved */ + LongInt pmMapBlkCnt; /* number of blocks in partition map */ + LongInt pmPyPartStart; /* first physical block of partition */ + LongInt pmPartBlkCnt; /* number of blocks in partition */ + Char pmPartName[33]; /* partition name */ + Char pmParType[33]; /* partition type */ + /* + * Apple_partition_map partition map + * Apple_Driver device driver + * Apple_Driver43 SCSI Manager 4.3 device driver + * Apple_MFS Macintosh 64K ROM filesystem + * Apple_HFS Macintosh hierarchical filesystem + * Apple_Unix_SVR2 Unix filesystem + * Apple_PRODOS ProDOS filesystem + * Apple_Free unused + * Apple_Scratch empty + */ + LongInt pmLgDataStart; /* first logical block of data area */ + LongInt pmDataCnt; /* number of blocks in data area */ + LongInt pmPartStatus; /* partition status information */ + LongInt pmLgBootStart; /* first logical block of boot code */ + LongInt pmBootSize; /* size of boot code, in bytes */ + LongInt pmBootAddr; /* boot code load address */ + LongInt pmBootAddr2; /* reserved */ + LongInt pmBootEntry; /* boot code entry point */ + LongInt pmBootEntry2; /* reserved */ + LongInt pmBootCksum; /* boot code checksum */ + Char pmProcessor[17];/* processor type */ + Integer pmPad[188]; /* reserved */ +} Partition; + +int l_lockvol(hfsvol *); + +int l_readblock0(hfsvol *); +int l_readpm(hfsvol *); + +int l_readmdb(hfsvol *); +int l_writemdb(hfsvol *); + +int l_readvbm(hfsvol *); +int l_writevbm(hfsvol *); diff --git a/libhfs_iso/node.c b/libhfs_iso/node.c new file mode 100644 index 0000000..8fce735 --- /dev/null +++ b/libhfs_iso/node.c @@ -0,0 +1,473 @@ +/* + * 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. + * + */ + +/* @(#)node.c 1.2 02/02/10 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "btree.h" +#include "node.h" + +# define NODESPACE(n) \ + (HFS_BLOCKSZ - (n).roff[(n).nd.ndNRecs] - 2 * ((n).nd.ndNRecs + 1)) + +/* + * NAME: node->init() + * DESCRIPTION: construct an empty node + */ +void n_init(node *np, btree *bt, int type, int height) +{ + np->bt = bt; + np->nnum = -1; + + np->nd.ndFLink = 0; + np->nd.ndBLink = 0; + np->nd.ndType = type; + np->nd.ndNHeight = height; + np->nd.ndNRecs = 0; + np->nd.ndResv2 = 0; + + np->rnum = -1; + np->roff[0] = 0x00e; + + memset(np->data, 0, sizeof(np->data)); +} + +/* + * NAME: node->new() + * DESCRIPTION: allocate a new b*-tree node + */ +int n_new(node *np) +{ + btree *bt = np->bt; + unsigned long num; + + if (bt->hdr.bthFree == 0) + { + ERROR(EIO, "b*-tree full"); + return -1; + } + + num = 0; + while (num < bt->hdr.bthNNodes && BMTST(bt->map, num)) + ++num; + + if (num == bt->hdr.bthNNodes) + { + ERROR(EIO, "free b*-tree node not found"); + return -1; + } + + np->nnum = num; + + BMSET(bt->map, num); + --bt->hdr.bthFree; + + bt->flags |= HFS_UPDATE_BTHDR; + + return 0; +} + +/* + * NAME: node->free() + * DESCRIPTION: deallocate a b*-tree node + */ +void n_free(node *np) +{ + btree *bt = np->bt; + + BMCLR(bt->map, np->nnum); + ++bt->hdr.bthFree; + + bt->flags |= HFS_UPDATE_BTHDR; +} + +/* + * NAME: node->compact() + * DESCRIPTION: clean up a node, removing deleted records + */ +void n_compact(node *np) +{ + unsigned char *ptr; + int offset, nrecs, i; + + offset = 0x00e; + ptr = np->data + offset; + nrecs = 0; + + for (i = 0; i < (int)np->nd.ndNRecs; ++i) + { + unsigned char *rec; + int reclen; + + rec = HFS_NODEREC(*np, i); + reclen = np->roff[i + 1] - np->roff[i]; + + if (HFS_RECKEYLEN(rec) > 0) + { + np->roff[nrecs++] = offset; + offset += reclen; + + if (ptr == rec) + ptr += reclen; + else + { + while (reclen--) + *ptr++ = *rec++; + } + } + } + + np->roff[nrecs] = offset; + np->nd.ndNRecs = nrecs; +} + +/* + * NAME: node->search() + * DESCRIPTION: locate a record in a node, or the record it should follow + */ +int n_search(node *np, unsigned char *key) +{ + btree *bt = np->bt; + int i, comp = -1; + + for (i = np->nd.ndNRecs; i--; ) + { + unsigned char *rec; + + rec = HFS_NODEREC(*np, i); + + if (HFS_RECKEYLEN(rec) == 0) + continue; /* deleted record */ + + comp = bt->compare(rec, key); + + if (comp <= 0) + break; + } + + np->rnum = i; + + return comp == 0; +} + +/* + * NAME: node->index() + * DESCRIPTION: create an index record from a key and node pointer + */ +void n_index(btree *bt, unsigned char *key, unsigned long nnum, + unsigned char *record, int *reclen) +{ + if (bt == &bt->f.vol->cat) + { + /* force the key length to be 0x25 */ + + HFS_RECKEYLEN(record) = 0x25; + memset(record + 1, 0, 0x25); + memcpy(record + 1, key + 1, HFS_RECKEYLEN(key)); + } + else + memcpy(record, key, HFS_RECKEYSKIP(key)); + + d_putl(HFS_RECDATA(record), nnum); + + if (reclen) + *reclen = HFS_RECKEYSKIP(record) + 4; +} + +/* + * NAME: node->split() + * DESCRIPTION: divide a node into two and insert a record + */ +int n_split(node *left, unsigned char *record, int *reclen) +{ + node right; + int nrecs, i, mid; + unsigned char *rec; + + right = *left; + right.nd.ndBLink = left->nnum; + + if (n_new(&right) < 0) + return -1; + + left->nd.ndFLink = right.nnum; + nrecs = left->nd.ndNRecs; + + /* + * Ensure node split leaves enough room for new record. + * The size calculations used are based on the NODESPACE() macro, but + * I don't know what the extra 2's and 1's are needed for. + * John Witford <jwitford@hutch.com.au> + */ + n_search(&right, record); + mid = nrecs/2; + for(;;) + { + if (right.rnum < mid) + { + if ( mid > 0 + && (int)left->roff[mid] + *reclen + 2 > HFS_BLOCKSZ - 2 * (mid + 1)) + { + --mid; + if (mid > 0) + continue; + } + } + else + { + if ( mid < nrecs + && (int)right.roff[nrecs] - (int)right.roff[mid] + (int)left->roff[0] + *reclen + 2 > HFS_BLOCKSZ - 2 * (mid + 1)) + { + ++mid; + if (mid < nrecs) + continue; + } + } + break; + } + + for (i = 0; i < nrecs; ++i) + { + if (i < mid) + rec = HFS_NODEREC(right, i); + else + rec = HFS_NODEREC(*left, i); + + HFS_RECKEYLEN(rec) = 0; + } + +/* original code ... + for (i = 0; i < nrecs; ++i) + { + if (i < nrecs / 2) + rec = HFS_NODEREC(right, i); + else + rec = HFS_NODEREC(*left, i); + + HFS_RECKEYLEN(rec) = 0; + } +*/ + n_compact(left); + n_compact(&right); + + n_search(&right, record); + if (right.rnum >= 0) + n_insertx(&right, record, *reclen); + else + { + n_search(left, record); + n_insertx(left, record, *reclen); + } + + /* store the new/modified nodes */ + + if (bt_putnode(left) < 0 || + bt_putnode(&right) < 0) + return -1; + + /* create an index record for the new node in the parent */ + + n_index(right.bt, HFS_NODEREC(right, 0), right.nnum, record, reclen); + + /* update link pointers */ + + if (left->bt->hdr.bthLNode == left->nnum) + { + left->bt->hdr.bthLNode = right.nnum; + left->bt->flags |= HFS_UPDATE_BTHDR; + } + + if (right.nd.ndFLink) + { + node n; + + n.bt = right.bt; + n.nnum = right.nd.ndFLink; + + if (bt_getnode(&n) < 0) + return -1; + + n.nd.ndBLink = right.nnum; + + if (bt_putnode(&n) < 0) + return -1; + } + + return 0; +} + +/* + * NAME: node->insertx() + * DESCRIPTION: insert a record into a node (which must already have room) + */ +void n_insertx(node *np, unsigned char *record, int reclen) +{ + int rnum, i; + unsigned char *ptr; + + rnum = np->rnum + 1; + + /* push other records down to make room */ + + for (ptr = HFS_NODEREC(*np, np->nd.ndNRecs) + reclen; + ptr > HFS_NODEREC(*np, rnum) + reclen; --ptr) + *(ptr - 1) = *(ptr - 1 - reclen); + + ++np->nd.ndNRecs; + + for (i = np->nd.ndNRecs; i > rnum; --i) + np->roff[i] = np->roff[i - 1] + reclen; + + /* write the new record */ + + memcpy(HFS_NODEREC(*np, rnum), record, reclen); +} + +/* + * NAME: node->insert() + * DESCRIPTION: insert a new record into a node; return a record for parent + */ +int n_insert(node *np, unsigned char *record, int *reclen) +{ + n_compact(np); + + /* check for free space */ + + if (np->nd.ndNRecs >= HFS_MAXRECS || + *reclen + 2 > (int)NODESPACE(*np)) + return n_split(np, record, reclen); + + n_insertx(np, record, *reclen); + *reclen = 0; + + return bt_putnode(np); +} + +/* + * NAME: node->merge() + * DESCRIPTION: combine two nodes into a single node + */ +int n_merge(node *right, node *left, unsigned char *record, int *flag) +{ + int i, offset; + + /* copy records and offsets */ + + memcpy(HFS_NODEREC(*left, left->nd.ndNRecs), HFS_NODEREC(*right, 0), + right->roff[right->nd.ndNRecs] - right->roff[0]); + + offset = left->roff[left->nd.ndNRecs] - right->roff[0]; + + for (i = 1; i <= (int)right->nd.ndNRecs; ++i) + left->roff[++left->nd.ndNRecs] = offset + right->roff[i]; + + /* update link pointers */ + + left->nd.ndFLink = right->nd.ndFLink; + + if (bt_putnode(left) < 0) + return -1; + + if (right->bt->hdr.bthLNode == right->nnum) + { + right->bt->hdr.bthLNode = left->nnum; + right->bt->flags |= HFS_UPDATE_BTHDR; + } + + if (right->nd.ndFLink) + { + node n; + + n.bt = right->bt; + n.nnum = right->nd.ndFLink; + + if (bt_getnode(&n) < 0) + return -1; + + n.nd.ndBLink = left->nnum; + + if (bt_putnode(&n) < 0) + return -1; + } + + n_free(right); + + HFS_RECKEYLEN(record) = 0; + *flag = 1; + + return 0; +} + +/* + * NAME: node->delete() + * DESCRIPTION: remove a record from a node + */ +int n_delete(node *np, unsigned char *record, int *flag) +{ + node left; + unsigned char *rec; + + rec = HFS_NODEREC(*np, np->rnum); + + HFS_RECKEYLEN(rec) = 0; + n_compact(np); + + /* see if we can merge with our left sibling */ + + left.bt = np->bt; + left.nnum = np->nd.ndBLink; + + if (left.nnum > 0) + { + if (bt_getnode(&left) < 0) + return -1; + + if ((int)(np->nd.ndNRecs + left.nd.ndNRecs) <= HFS_MAXRECS && + (int)(np->roff[np->nd.ndNRecs] - np->roff[0] + + 2 * np->nd.ndNRecs) <= (int)NODESPACE(left)) + return n_merge(np, &left, record, flag); + } + + if (np->rnum == 0) + { + /* special case: first record changed; update parent record key */ + + n_index(np->bt, HFS_NODEREC(*np, 0), np->nnum, record, 0); + *flag = 1; + } + + return bt_putnode(np); +} diff --git a/libhfs_iso/node.h b/libhfs_iso/node.h new file mode 100644 index 0000000..39d3227 --- /dev/null +++ b/libhfs_iso/node.h @@ -0,0 +1,48 @@ +/* + * 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. + * + */ + +/* @(#)node.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +void n_init(node *, btree *, int, int); + +int n_new(node *); +void n_free(node *); + +void n_compact(node *); +int n_search(node *, unsigned char *); + +void n_index(btree *, unsigned char *, unsigned long, unsigned char *, int *); +int n_split(node *, unsigned char *, int *); + +void n_insertx(node *, unsigned char *, int); +int n_insert(node *, unsigned char *, int *); + +int n_merge(node *, node *, unsigned char *, int *); +int n_delete(node *, unsigned char *, int *); diff --git a/libhfs_iso/record.c b/libhfs_iso/record.c new file mode 100644 index 0000000..e202158 --- /dev/null +++ b/libhfs_iso/record.c @@ -0,0 +1,551 @@ +/* + * 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. + * + */ + +/* @(#)record.c 1.1 00/04/26 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "record.h" + +/* + * NAME: record->packcatkey() + * DESCRIPTION: pack a catalog record key + */ +void r_packcatkey(CatKeyRec *key, unsigned char *pkey, int *len) +{ + unsigned char *start = pkey; + + d_storeb(&pkey, key->ckrKeyLen); + d_storeb(&pkey, key->ckrResrv1); + d_storel(&pkey, key->ckrParID); + d_stores(&pkey, key->ckrCName, sizeof(key->ckrCName)); + + if (len) + *len = HFS_RECKEYSKIP(start); +} + +/* + * NAME: record->unpackcatkey() + * DESCRIPTION: unpack a catalog record key + */ +void r_unpackcatkey(unsigned char *pkey, CatKeyRec *key) +{ + d_fetchb(&pkey, (char *) &key->ckrKeyLen); + d_fetchb(&pkey, (char *) &key->ckrResrv1); + d_fetchl(&pkey, (long *) &key->ckrParID); + d_fetchs(&pkey, key->ckrCName, sizeof(key->ckrCName)); +} + +/* + * NAME: record->packextkey() + * DESCRIPTION: pack an extents record key + */ +void r_packextkey(ExtKeyRec *key, unsigned char *pkey, int *len) +{ + unsigned char *start = pkey; + + d_storeb(&pkey, key->xkrKeyLen); + d_storeb(&pkey, key->xkrFkType); + d_storel(&pkey, key->xkrFNum); + d_storew(&pkey, key->xkrFABN); + + if (len) + *len = HFS_RECKEYSKIP(start); +} + +/* + * NAME: record->unpackextkey() + * DESCRIPTION: unpack an extents record key + */ +void r_unpackextkey(unsigned char *pkey, ExtKeyRec *key) +{ + d_fetchb(&pkey, (char *) &key->xkrKeyLen); + d_fetchb(&pkey, (char *) &key->xkrFkType); + d_fetchl(&pkey, (long *) &key->xkrFNum); + d_fetchw(&pkey, (short *) &key->xkrFABN); +} + +/* + * NAME: record->comparecatkeys() + * DESCRIPTION: compare two (packed) catalog record keys + */ +int r_comparecatkeys(unsigned char *pkey1, unsigned char *pkey2) +{ + CatKeyRec key1; + CatKeyRec key2; + int diff; + + r_unpackcatkey(pkey1, &key1); + r_unpackcatkey(pkey2, &key2); + + diff = key1.ckrParID - key2.ckrParID; + if (diff) + return diff; + + return d_relstring(key1.ckrCName, key2.ckrCName); +} + +/* + * NAME: record->compareextkeys() + * DESCRIPTION: compare two (packed) extents record keys + */ +int r_compareextkeys(unsigned char *pkey1, unsigned char *pkey2) +{ + ExtKeyRec key1; + ExtKeyRec key2; + int diff; + + r_unpackextkey(pkey1, &key1); + r_unpackextkey(pkey2, &key2); + + diff = key1.xkrFNum - key2.xkrFNum; + if (diff) + return diff; + + diff = (unsigned char) key1.xkrFkType - + (unsigned char) key2.xkrFkType; + if (diff) + return diff; + + return key1.xkrFABN - key2.xkrFABN; +} + +/* + * NAME: record->packcatdata() + * DESCRIPTION: pack catalog record data + */ +void r_packcatdata(CatDataRec *data, unsigned char *pdata, int *len) +{ + unsigned char *start = pdata; + int i; + + d_storeb(&pdata, data->cdrType); + d_storeb(&pdata, data->cdrResrv2); + + switch (data->cdrType) + { + case cdrDirRec: + d_storew(&pdata, data->u.dir.dirFlags); + d_storew(&pdata, data->u.dir.dirVal); + d_storel(&pdata, data->u.dir.dirDirID); + d_storel(&pdata, data->u.dir.dirCrDat); + d_storel(&pdata, data->u.dir.dirMdDat); + d_storel(&pdata, data->u.dir.dirBkDat); + + d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.top); + d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.left); + d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.bottom); + d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.right); + d_storew(&pdata, data->u.dir.dirUsrInfo.frFlags); + d_storew(&pdata, data->u.dir.dirUsrInfo.frLocation.v); + d_storew(&pdata, data->u.dir.dirUsrInfo.frLocation.h); + d_storew(&pdata, data->u.dir.dirUsrInfo.frView); + + d_storew(&pdata, data->u.dir.dirFndrInfo.frScroll.v); + d_storew(&pdata, data->u.dir.dirFndrInfo.frScroll.h); + d_storel(&pdata, data->u.dir.dirFndrInfo.frOpenChain); + d_storew(&pdata, data->u.dir.dirFndrInfo.frUnused); + d_storew(&pdata, data->u.dir.dirFndrInfo.frComment); + d_storel(&pdata, data->u.dir.dirFndrInfo.frPutAway); + + for (i = 0; i < 4; ++i) + d_storel(&pdata, data->u.dir.dirResrv[i]); + + break; + + case cdrFilRec: + d_storeb(&pdata, data->u.fil.filFlags); + d_storeb(&pdata, data->u.fil.filTyp); + + d_storel(&pdata, data->u.fil.filUsrWds.fdType); + d_storel(&pdata, data->u.fil.filUsrWds.fdCreator); + d_storew(&pdata, data->u.fil.filUsrWds.fdFlags); + d_storew(&pdata, data->u.fil.filUsrWds.fdLocation.v); + d_storew(&pdata, data->u.fil.filUsrWds.fdLocation.h); + d_storew(&pdata, data->u.fil.filUsrWds.fdFldr); + + d_storel(&pdata, data->u.fil.filFlNum); + + d_storew(&pdata, data->u.fil.filStBlk); + d_storel(&pdata, data->u.fil.filLgLen); + d_storel(&pdata, data->u.fil.filPyLen); + + d_storew(&pdata, data->u.fil.filRStBlk); + d_storel(&pdata, data->u.fil.filRLgLen); + d_storel(&pdata, data->u.fil.filRPyLen); + + d_storel(&pdata, data->u.fil.filCrDat); + d_storel(&pdata, data->u.fil.filMdDat); + d_storel(&pdata, data->u.fil.filBkDat); + + d_storew(&pdata, data->u.fil.filFndrInfo.fdIconID); + for (i = 0; i < 4; ++i) + d_storew(&pdata, data->u.fil.filFndrInfo.fdUnused[i]); + d_storew(&pdata, data->u.fil.filFndrInfo.fdComment); + d_storel(&pdata, data->u.fil.filFndrInfo.fdPutAway); + + d_storew(&pdata, data->u.fil.filClpSize); + + for (i = 0; i < 3; ++i) + { + d_storew(&pdata, data->u.fil.filExtRec[i].xdrStABN); + d_storew(&pdata, data->u.fil.filExtRec[i].xdrNumABlks); + } + + for (i = 0; i < 3; ++i) + { + d_storew(&pdata, data->u.fil.filRExtRec[i].xdrStABN); + d_storew(&pdata, data->u.fil.filRExtRec[i].xdrNumABlks); + } + + d_storel(&pdata, data->u.fil.filResrv); + break; + + case cdrThdRec: + for (i = 0; i < 2; ++i) + d_storel(&pdata, data->u.dthd.thdResrv[i]); + + d_storel(&pdata, data->u.dthd.thdParID); + d_stores(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName)); + break; + + case cdrFThdRec: + for (i = 0; i < 2; ++i) + d_storel(&pdata, data->u.fthd.fthdResrv[i]); + + d_storel(&pdata, data->u.fthd.fthdParID); + d_stores(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName)); + break; + + default: + abort(); + } + + if (len) + *len += pdata - start; +} + +/* + * NAME: record->unpackcatdata() + * DESCRIPTION: unpack catalog record data + */ +void r_unpackcatdata(unsigned char *pdata, CatDataRec *data) +{ + int i; + + d_fetchb(&pdata, (char *) &data->cdrType); + d_fetchb(&pdata, (char *) &data->cdrResrv2); + + switch (data->cdrType) + { + case cdrDirRec: + d_fetchw(&pdata, &data->u.dir.dirFlags); + d_fetchw(&pdata, (short *) &data->u.dir.dirVal); + d_fetchl(&pdata, (long *) &data->u.dir.dirDirID); + d_fetchl(&pdata, &data->u.dir.dirCrDat); + d_fetchl(&pdata, &data->u.dir.dirMdDat); + d_fetchl(&pdata, &data->u.dir.dirBkDat); + + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.top); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.left); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.bottom); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.right); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frFlags); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frLocation.v); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frLocation.h); + d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frView); + + d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frScroll.v); + d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frScroll.h); + d_fetchl(&pdata, &data->u.dir.dirFndrInfo.frOpenChain); + d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frUnused); + d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frComment); + d_fetchl(&pdata, &data->u.dir.dirFndrInfo.frPutAway); + + for (i = 0; i < 4; ++i) + d_fetchl(&pdata, &data->u.dir.dirResrv[i]); + + break; + + case cdrFilRec: + d_fetchb(&pdata, (char *) &data->u.fil.filFlags); + d_fetchb(&pdata, (char *) &data->u.fil.filTyp); + + d_fetchl(&pdata, &data->u.fil.filUsrWds.fdType); + d_fetchl(&pdata, &data->u.fil.filUsrWds.fdCreator); + d_fetchw(&pdata, &data->u.fil.filUsrWds.fdFlags); + d_fetchw(&pdata, &data->u.fil.filUsrWds.fdLocation.v); + d_fetchw(&pdata, &data->u.fil.filUsrWds.fdLocation.h); + d_fetchw(&pdata, &data->u.fil.filUsrWds.fdFldr); + + d_fetchl(&pdata, (long *) &data->u.fil.filFlNum); + + d_fetchw(&pdata, (short *) &data->u.fil.filStBlk); + d_fetchl(&pdata, (long *) &data->u.fil.filLgLen); + d_fetchl(&pdata, (long *) &data->u.fil.filPyLen); + + d_fetchw(&pdata, (short *) &data->u.fil.filRStBlk); + d_fetchl(&pdata, (long *) &data->u.fil.filRLgLen); + d_fetchl(&pdata, (long *) &data->u.fil.filRPyLen); + + d_fetchl(&pdata, &data->u.fil.filCrDat); + d_fetchl(&pdata, &data->u.fil.filMdDat); + d_fetchl(&pdata, &data->u.fil.filBkDat); + + d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdIconID); + for (i = 0; i < 4; ++i) + d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdUnused[i]); + d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdComment); + d_fetchl(&pdata, &data->u.fil.filFndrInfo.fdPutAway); + + d_fetchw(&pdata, (short *) &data->u.fil.filClpSize); + + for (i = 0; i < 3; ++i) + { + d_fetchw(&pdata, (short *) &data->u.fil.filExtRec[i].xdrStABN); + d_fetchw(&pdata, (short *) &data->u.fil.filExtRec[i].xdrNumABlks); + } + + for (i = 0; i < 3; ++i) + { + d_fetchw(&pdata, (short *) &data->u.fil.filRExtRec[i].xdrStABN); + d_fetchw(&pdata, (short *) &data->u.fil.filRExtRec[i].xdrNumABlks); + } + + d_fetchl(&pdata, &data->u.fil.filResrv); + break; + + case cdrThdRec: + for (i = 0; i < 2; ++i) + d_fetchl(&pdata, &data->u.dthd.thdResrv[i]); + + d_fetchl(&pdata, (long *) &data->u.dthd.thdParID); + d_fetchs(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName)); + break; + + case cdrFThdRec: + for (i = 0; i < 2; ++i) + d_fetchl(&pdata, &data->u.fthd.fthdResrv[i]); + + d_fetchl(&pdata, (long *) &data->u.fthd.fthdParID); + d_fetchs(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName)); + break; + + default: + abort(); + } +} + +/* + * NAME: record->packextdata() + * DESCRIPTION: pack extent record data + */ +void r_packextdata(ExtDataRec *data, unsigned char *pdata, int *len) +{ + unsigned char *start = pdata; + int i; + + for (i = 0; i < 3; ++i) + { + d_storew(&pdata, (*data)[i].xdrStABN); + d_storew(&pdata, (*data)[i].xdrNumABlks); + } + + if (len) + *len += pdata - start; +} + +/* + * NAME: record->unpackextdata() + * DESCRIPTION: unpack extent record data + */ +void r_unpackextdata(unsigned char *pdata, ExtDataRec *data) +{ + int i; + + for (i = 0; i < 3; ++i) + { + d_fetchw(&pdata, (short *) &(*data)[i].xdrStABN); + d_fetchw(&pdata, (short *) &(*data)[i].xdrNumABlks); + } +} + +/* + * NAME: record->makecatkey() + * DESCRIPTION: construct a catalog record key + */ +void r_makecatkey(CatKeyRec *key, long parid, char *name) +{ + int len; + + len = strlen(name) + 1; + + key->ckrKeyLen = 0x05 + len + (len & 1); + key->ckrResrv1 = 0; + key->ckrParID = parid; + + strcpy(key->ckrCName, name); +} + +/* + * NAME: record->makeextkey() + * DESCRIPTION: construct an extents record key + */ +void r_makeextkey(ExtKeyRec *key, int ffork, long fnum, unsigned int fabn) +{ + key->xkrKeyLen = 0x07; + key->xkrFkType = ffork; + key->xkrFNum = fnum; + key->xkrFABN = fabn; +} + +/* + * NAME: record->unpackdirent() + * DESCRIPTION: unpack catalog information into hfsdirent structure + * + * Taken fron v3.2.6 + */ +void r_unpackdirent(long parid, char *name, CatDataRec *data, hfsdirent *ent) +{ + strcpy(ent->name, name); + ent->parid = parid; + + switch (data->cdrType) + { + case cdrDirRec: + ent->flags = HFS_ISDIR; + ent->cnid = data->u.dir.dirDirID; + + ent->crdate = d_toutime(data->u.dir.dirCrDat); + ent->mddate = d_toutime(data->u.dir.dirMdDat); + ent->bkdate = d_toutime(data->u.dir.dirBkDat); + + ent->fdflags = data->u.dir.dirUsrInfo.frFlags; + ent->fdlocation.v = data->u.dir.dirUsrInfo.frLocation.v; + ent->fdlocation.h = data->u.dir.dirUsrInfo.frLocation.h; + + ent->u.dir.valence = data->u.dir.dirVal; + + ent->u.dir.rect.top = data->u.dir.dirUsrInfo.frRect.top; + ent->u.dir.rect.left = data->u.dir.dirUsrInfo.frRect.left; + ent->u.dir.rect.bottom = data->u.dir.dirUsrInfo.frRect.bottom; + ent->u.dir.rect.right = data->u.dir.dirUsrInfo.frRect.right; + + /* mkhybrid extra */ + ent->u.dir.frscroll.v = data->u.dir.dirFndrInfo.frScroll.v; + ent->u.dir.frscroll.h = data->u.dir.dirFndrInfo.frScroll.h; + ent->u.dir.view = data->u.dir.dirUsrInfo.frView; + + break; + + case cdrFilRec: + ent->flags = (data->u.fil.filFlags & (1 << 0)) ? HFS_ISLOCKED : 0; + ent->cnid = data->u.fil.filFlNum; + + ent->crdate = d_toutime(data->u.fil.filCrDat); + ent->mddate = d_toutime(data->u.fil.filMdDat); + ent->bkdate = d_toutime(data->u.fil.filBkDat); + + ent->fdflags = data->u.fil.filUsrWds.fdFlags; + ent->fdlocation.v = data->u.fil.filUsrWds.fdLocation.v; + ent->fdlocation.h = data->u.fil.filUsrWds.fdLocation.h; + + ent->u.file.dsize = data->u.fil.filLgLen; + ent->u.file.rsize = data->u.fil.filRLgLen; + + d_putl((unsigned char *) ent->u.file.type, + data->u.fil.filUsrWds.fdType); + d_putl((unsigned char *) ent->u.file.creator, + data->u.fil.filUsrWds.fdCreator); + + ent->u.file.type[4] = ent->u.file.creator[4] = 0; + + break; + } +} + +/* + * NAME: record->packdirent() + * DESCRIPTION: make changes to a catalog record + * + * Taken fron v3.2.6 + */ +void r_packdirent(CatDataRec *data, hfsdirent *ent) +{ + switch (data->cdrType) + { + case cdrDirRec: + data->u.dir.dirCrDat = d_tomtime(ent->crdate); + data->u.dir.dirMdDat = d_tomtime(ent->mddate); + data->u.dir.dirBkDat = d_tomtime(ent->bkdate); + + data->u.dir.dirUsrInfo.frFlags = ent->fdflags; + data->u.dir.dirUsrInfo.frLocation.v = ent->fdlocation.v; + data->u.dir.dirUsrInfo.frLocation.h = ent->fdlocation.h; + + data->u.dir.dirUsrInfo.frRect.top = ent->u.dir.rect.top; + data->u.dir.dirUsrInfo.frRect.left = ent->u.dir.rect.left; + data->u.dir.dirUsrInfo.frRect.bottom = ent->u.dir.rect.bottom; + data->u.dir.dirUsrInfo.frRect.right = ent->u.dir.rect.right; + + /* mkhybrid extra */ + data->u.dir.dirFndrInfo.frScroll.v = ent->u.dir.frscroll.v; + data->u.dir.dirFndrInfo.frScroll.h = ent->u.dir.frscroll.h; + data->u.dir.dirUsrInfo.frView = ent->u.dir.view; + + break; + + case cdrFilRec: + if (ent->flags & HFS_ISLOCKED) + data->u.fil.filFlags |= (1 << 0); + else + data->u.fil.filFlags &= ~(1 << 0); + + data->u.fil.filCrDat = d_tomtime(ent->crdate); + data->u.fil.filMdDat = d_tomtime(ent->mddate); + data->u.fil.filBkDat = d_tomtime(ent->bkdate); + + data->u.fil.filUsrWds.fdFlags = ent->fdflags; + data->u.fil.filUsrWds.fdLocation.v = ent->fdlocation.v; + data->u.fil.filUsrWds.fdLocation.h = ent->fdlocation.h; + + data->u.fil.filUsrWds.fdType = + d_getl((unsigned char *) ent->u.file.type); + data->u.fil.filUsrWds.fdCreator = + d_getl((unsigned char *) ent->u.file.creator); + + break; + } +} diff --git a/libhfs_iso/record.h b/libhfs_iso/record.h new file mode 100644 index 0000000..90934eb --- /dev/null +++ b/libhfs_iso/record.h @@ -0,0 +1,52 @@ +/* + * 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. + * + */ + +/* @(#)record.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +void r_packcatkey(CatKeyRec *, unsigned char *, int *); +void r_unpackcatkey(unsigned char *, CatKeyRec *); + +void r_packextkey(ExtKeyRec *, unsigned char *, int *); +void r_unpackextkey(unsigned char *, ExtKeyRec *); + +int r_comparecatkeys(unsigned char *, unsigned char *); +int r_compareextkeys(unsigned char *, unsigned char *); + +void r_packcatdata(CatDataRec *, unsigned char *, int *); +void r_unpackcatdata(unsigned char *, CatDataRec *); + +void r_packextdata(ExtDataRec *, unsigned char *, int *); +void r_unpackextdata(unsigned char *, ExtDataRec *); + +void r_makecatkey(CatKeyRec *, long, char *); +void r_makeextkey(ExtKeyRec *, int, long, unsigned int); + +void r_unpackdirent(long, char *, CatDataRec *, hfsdirent *); +void r_packdirent(CatDataRec *, hfsdirent *); diff --git a/libhfs_iso/volume.c b/libhfs_iso/volume.c new file mode 100644 index 0000000..b352735 --- /dev/null +++ b/libhfs_iso/volume.c @@ -0,0 +1,741 @@ +/* + * 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. + * + */ + +/* @(#)volume.c 1.4 04/06/17 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "low.h" +#include "btree.h" +#include "record.h" +#include "volume.h" + +static void markexts(block *vbm, ExtDataRec *exts); + + +/* + * NAME: vol->catsearch() + * DESCRIPTION: search catalog tree + */ +int v_catsearch(hfsvol *vol, long parid, char *name, CatDataRec *data, + char *cname, node *np) +{ + CatKeyRec key; + unsigned char pkey[HFS_CATKEYLEN]; + node n; + unsigned char *ptr; + int found; + + if (np == 0) + np = &n; + + r_makecatkey(&key, parid, name); + r_packcatkey(&key, pkey, 0); + + found = bt_search(&vol->cat, pkey, np); + if (found <= 0) + return found; + + ptr = HFS_NODEREC(*np, np->rnum); + + if (cname) + { + r_unpackcatkey(ptr, &key); + strcpy(cname, key.ckrCName); + } + + if (data) + r_unpackcatdata(HFS_RECDATA(ptr), data); + + return 1; +} + +/* + * NAME: vol->extsearch() + * DESCRIPTION: search extents tree + */ +int v_extsearch(hfsfile *file, unsigned int fabn, ExtDataRec *data, node *np) +{ + ExtKeyRec key; + ExtDataRec extsave; + unsigned int fabnsave; + unsigned char pkey[HFS_EXTKEYLEN]; + node n; + unsigned char *ptr; + int found; + + if (np == 0) + np = &n; + + r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, fabn); + r_packextkey(&key, pkey, 0); + + /* in case bt_search() clobbers these */ + + memcpy(&extsave, &file->ext, sizeof(ExtDataRec)); + fabnsave = file->fabn; + + found = bt_search(&file->vol->ext, pkey, np); + + memcpy(&file->ext, &extsave, sizeof(ExtDataRec)); + file->fabn = fabnsave; + + if (found <= 0) + return found; + + if (data) + { + ptr = HFS_NODEREC(*np, np->rnum); + r_unpackextdata(HFS_RECDATA(ptr), data); + } + + return 1; +} + +/* + * NAME: vol->getthread() + * DESCRIPTION: retrieve catalog thread information for a file or directory + */ +int v_getthread(hfsvol *vol, long id, CatDataRec *thread, node *np, int type) +{ + CatDataRec rec; + int found; + + if (thread == 0) + thread = &rec; + + found = v_catsearch(vol, id, "", thread, 0, np); + if (found <= 0) + return found; + + if (thread->cdrType != type) + { + ERROR(EIO, "bad thread record"); + return -1; + } + + return 1; +} + +/* + * NAME: vol->putcatrec() + * DESCRIPTION: store catalog information + */ +int v_putcatrec(CatDataRec *data, node *np) +{ + unsigned char pdata[HFS_CATDATALEN], *ptr; + int len = 0; + + r_packcatdata(data, pdata, &len); + + ptr = HFS_NODEREC(*np, np->rnum); + memcpy(HFS_RECDATA(ptr), pdata, len); + + return bt_putnode(np); +} + +/* + * NAME: vol->putextrec() + * DESCRIPTION: store extent information + */ +int v_putextrec(ExtDataRec *data, node *np) +{ + unsigned char pdata[HFS_EXTDATALEN], *ptr; + int len = 0; + + r_packextdata(data, pdata, &len); + + ptr = HFS_NODEREC(*np, np->rnum); + memcpy(HFS_RECDATA(ptr), pdata, len); + + return bt_putnode(np); +} + +/* + * NAME: vol->allocblocks() + * DESCRIPTION: allocate a contiguous range of blocks + */ +int v_allocblocks(hfsvol *vol, ExtDescriptor *blocks) +{ + unsigned int request, found, foundat, start, end, pt; + block *vbm; + int wrap = 0; + + if (vol->mdb.drFreeBks == 0) + { + ERROR(ENOSPC, "volume full"); + return -1; + } + + request = blocks->xdrNumABlks; + found = 0; + foundat = 0; + start = vol->mdb.drAllocPtr; + end = vol->mdb.drNmAlBlks; + pt = start; + vbm = vol->vbm; + + if (request == 0) + abort(); + + for (;;) + { + unsigned int mark; + + /* skip blocks in use */ + + while (pt < end && BMTST(vbm, pt)) + ++pt; + + if (wrap && pt >= start) + break; + + /* count blocks not in use */ + + mark = pt; + while (pt < end && pt - mark < request && ! BMTST(vbm, pt)) + ++pt; + + if (pt - mark > found) + { + found = pt - mark; + foundat = mark; + } + + if (pt == end) + pt = 0, wrap = 1; + + if (found == request) + break; + } + + if (found == 0 || found > vol->mdb.drFreeBks) + { + ERROR(EIO, "bad volume bitmap or free block count"); + return -1; + } + + blocks->xdrStABN = foundat; + blocks->xdrNumABlks = found; + + vol->mdb.drAllocPtr = pt; + vol->mdb.drFreeBks -= found; + + for (pt = foundat; pt < foundat + found; ++pt) + BMSET(vbm, pt); + + vol->flags |= HFS_UPDATE_MDB | HFS_UPDATE_VBM; + + return 0; +} + +/* + * NAME: vol->freeblocks() + * DESCRIPTION: deallocate a contiguous range of blocks + */ +void v_freeblocks(hfsvol *vol, ExtDescriptor *blocks) +{ + unsigned int start, len, pt; + block *vbm; + + start = blocks->xdrStABN; + len = blocks->xdrNumABlks; + vbm = vol->vbm; + + vol->mdb.drFreeBks += len; + + for (pt = start; pt < start + len; ++pt) + BMCLR(vbm, pt); + + vol->flags |= HFS_UPDATE_MDB | HFS_UPDATE_VBM; +} + +/* + * NAME: vol->resolve() + * DESCRIPTION: translate a pathname; return catalog information + */ +int v_resolve(hfsvol **vol, char *path, CatDataRec *data, long *parid, + char *fname, node *np) +{ + long dirid; + char name[HFS_MAX_FLEN + 1], *nptr; + int found; + + if (*path == 0) + { + ERROR(ENOENT, "empty path"); + return -1; + } + + if (parid) + *parid = 0; + + nptr = strchr(path, ':'); + + if (*path == ':' || nptr == 0) + { + dirid = (*vol)->cwd; /* relative path */ + + if (*path == ':') + ++path; + + if (*path == 0) + { + found = v_getdthread(*vol, dirid, data, 0); + if (found <= 0) + return found; + + if (parid) + *parid = data->u.dthd.thdParID; + + return v_catsearch(*vol, data->u.dthd.thdParID, + data->u.dthd.thdCName, data, fname, np); + } + } + else + { + hfsvol *check; + + dirid = HFS_CNID_ROOTPAR; /* absolute path */ + + if (nptr - path > HFS_MAX_VLEN) + { + ERROR(ENAMETOOLONG, 0); + return -1; + } + + strncpy(name, path, nptr - path); + name[nptr - path] = 0; + + for (check = hfs_mounts; check; check = check->next) + { + if (d_relstring(check->mdb.drVN, name) == 0) + { + *vol = check; + break; + } + } + } + + for (;;) + { + while (*path == ':') + { + ++path; + + found = v_getdthread(*vol, dirid, data, 0); + if (found <= 0) + return found; + + dirid = data->u.dthd.thdParID; + } + + if (*path == 0) + { + found = v_getdthread(*vol, dirid, data, 0); + if (found <= 0) + return found; + + if (parid) + *parid = data->u.dthd.thdParID; + + return v_catsearch(*vol, data->u.dthd.thdParID, + data->u.dthd.thdCName, data, fname, np); + } + + nptr = name; + while (nptr < name + sizeof(name) - 1 && *path && *path != ':') + *nptr++ = *path++; + + if (*path && *path != ':') + { + ERROR(ENAMETOOLONG, 0); + return -1; + } + + *nptr = 0; + if (*path == ':') + ++path; + + if (parid) + *parid = dirid; + + found = v_catsearch(*vol, dirid, name, data, fname, np); + if (found < 0) + return -1; + + if (found == 0) + { + if (*path && parid) + *parid = 0; + + if (*path == 0 && fname) + strcpy(fname, name); + + return 0; + } + + switch (data->cdrType) + { + case cdrDirRec: + if (*path == 0) + return 1; + + dirid = data->u.dir.dirDirID; + break; + + case cdrFilRec: + if (*path == 0) + return 1; + + ERROR(ENOTDIR, "invalid pathname"); + return -1; + + default: + ERROR(EIO, "unexpected catalog record"); + return -1; + } + } +} + +/* + * NAME: vol->destruct() + * DESCRIPTION: free memory consumed by a volume descriptor + */ +void v_destruct(hfsvol *vol) +{ + FREE(vol->vbm); + + FREE(vol->ext.map); + FREE(vol->cat.map); + + FREE(vol); +} + +/* + * NAME: vol->getvol() + * DESCRIPTION: validate a volume reference + */ +int v_getvol(hfsvol **vol) +{ + if (*vol == 0) + { + if (hfs_curvol == 0) + { + ERROR(EINVAL, "no volume is current"); + return -1; + } + + *vol = hfs_curvol; + } + + return 0; +} + +/* + * NAME: vol->flush() + * DESCRIPTION: flush all pending changes (B*-tree, MDB, VBM) to disk + */ +int v_flush(hfsvol *vol, int umounting) +{ + if (! (vol->flags & HFS_READONLY)) + { + if ((vol->ext.flags & HFS_UPDATE_BTHDR) && + bt_writehdr(&vol->ext) < 0) + return -1; + + if ((vol->cat.flags & HFS_UPDATE_BTHDR) && + bt_writehdr(&vol->cat) < 0) + return -1; + + if ((vol->flags & HFS_UPDATE_VBM) && + l_writevbm(vol) < 0) + return -1; + + if (umounting && + ! (vol->mdb.drAtrb & HFS_ATRB_UMOUNTED)) + { + vol->mdb.drAtrb |= HFS_ATRB_UMOUNTED; + vol->flags |= HFS_UPDATE_MDB; + } + + if ((vol->flags & (HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB)) && + l_writemdb(vol) < 0) + return -1; + } + + return 0; +} + +/* + * NAME: vol->adjvalence() + * DESCRIPTION: update a volume's valence counts + */ +int v_adjvalence(hfsvol *vol, long parid, int isdir, int adj) +{ + node n; + CatDataRec data; + + if (isdir) + vol->mdb.drDirCnt += adj; + else + vol->mdb.drFilCnt += adj; + + vol->flags |= HFS_UPDATE_MDB; + + if (parid == HFS_CNID_ROOTDIR) + { + if (isdir) + vol->mdb.drNmRtDirs += adj; + else + vol->mdb.drNmFls += adj; + } + else if (parid == HFS_CNID_ROOTPAR) + return 0; + + if (v_getdthread(vol, parid, &data, 0) <= 0 || + v_catsearch(vol, data.u.dthd.thdParID, data.u.dthd.thdCName, + &data, 0, &n) <= 0 || + data.cdrType != cdrDirRec) + { + ERROR(EIO, "can't find parent directory"); + return -1; + } + + data.u.dir.dirVal += adj; + data.u.dir.dirMdDat = d_tomtime(time(0)); + + return v_putcatrec(&data, &n); +} + +/* + * NAME: vol->newfolder() + * DESCRIPTION: create a new HFS folder + */ +int v_newfolder(hfsvol *vol, long parid, char *name) +{ + CatKeyRec key; + CatDataRec data; + long id; + unsigned char record[HFS_CATRECMAXLEN]; + int i, reclen; + + if (bt_space(&vol->cat, 2) < 0) + return -1; + + id = vol->mdb.drNxtCNID++; + vol->flags |= HFS_UPDATE_MDB; + + /* create directory record */ + + data.cdrType = cdrDirRec; + data.cdrResrv2 = 0; + + data.u.dir.dirFlags = 0; + data.u.dir.dirVal = 0; + data.u.dir.dirDirID = id; + data.u.dir.dirCrDat = d_tomtime(time(0)); + data.u.dir.dirMdDat = data.u.dir.dirCrDat; + data.u.dir.dirBkDat = 0; + + memset(&data.u.dir.dirUsrInfo, 0, sizeof(data.u.dir.dirUsrInfo)); + memset(&data.u.dir.dirFndrInfo, 0, sizeof(data.u.dir.dirFndrInfo)); + for (i = 0; i < 4; ++i) + data.u.dir.dirResrv[i] = 0; + + r_makecatkey(&key, parid, name); + r_packcatkey(&key, record, &reclen); + r_packcatdata(&data, HFS_RECDATA(record), &reclen); + + if (bt_insert(&vol->cat, record, reclen) < 0) + return -1; + + /* create thread record */ + + data.cdrType = cdrThdRec; + data.cdrResrv2 = 0; + + data.u.dthd.thdResrv[0] = 0; + data.u.dthd.thdResrv[1] = 0; + data.u.dthd.thdParID = parid; + strcpy(data.u.dthd.thdCName, name); + + r_makecatkey(&key, id, ""); + r_packcatkey(&key, record, &reclen); + r_packcatdata(&data, HFS_RECDATA(record), &reclen); + + if (bt_insert(&vol->cat, record, reclen) < 0 || + v_adjvalence(vol, parid, 1, 1) < 0) + return -1; + + return 0; +} + +/* + * NAME: markexts() + * DESCRIPTION: set bits from an extent record in the volume bitmap + */ +static +void markexts(block *vbm, ExtDataRec *exts) +{ + int i; + unsigned int start, len; + + for (i = 0; i < 3; ++i) + { + for (start = (*exts)[i].xdrStABN, + len = (*exts)[i].xdrNumABlks; len--; ++start) + BMSET(vbm, start); + } +} + +/* + * NAME: vol->scavenge() + * DESCRIPTION: safeguard blocks in the volume bitmap + */ +int v_scavenge(hfsvol *vol) +{ + block *vbm = vol->vbm; + node n; + unsigned int pt, blks; + + if (vbm == 0) + return 0; + + markexts(vbm, &vol->mdb.drXTExtRec); + markexts(vbm, &vol->mdb.drCTExtRec); + + vol->flags |= HFS_UPDATE_VBM; + + /* scavenge the extents overflow file */ + + n.bt = &vol->ext; + n.nnum = vol->ext.hdr.bthFNode; + + if (n.nnum > 0) + { + if (bt_getnode(&n) < 0) + return -1; + + n.rnum = 0; + + for (;;) + { + ExtDataRec data; + unsigned char *ptr; + + while (n.rnum >= (int)n.nd.ndNRecs) + { + n.nnum = n.nd.ndFLink; + if (n.nnum == 0) + break; + + if (bt_getnode(&n) < 0) + return -1; + + n.rnum = 0; + } + + if (n.nnum == 0) + break; + + ptr = HFS_NODEREC(n, n.rnum); + r_unpackextdata(HFS_RECDATA(ptr), &data); + + markexts(vbm, &data); + + ++n.rnum; + } + } + + /* scavenge the catalog file */ + + n.bt = &vol->cat; + n.nnum = vol->cat.hdr.bthFNode; + + if (n.nnum > 0) + { + if (bt_getnode(&n) < 0) + return -1; + + n.rnum = 0; + + for (;;) + { + CatDataRec data; + unsigned char *ptr; + + while (n.rnum >= (int)n.nd.ndNRecs) + { + n.nnum = n.nd.ndFLink; + if (n.nnum == 0) + break; + + if (bt_getnode(&n) < 0) + return -1; + + n.rnum = 0; + } + + if (n.nnum == 0) + break; + + ptr = HFS_NODEREC(n, n.rnum); + r_unpackcatdata(HFS_RECDATA(ptr), &data); + + if (data.cdrType == cdrFilRec) + { + markexts(vbm, &data.u.fil.filExtRec); + markexts(vbm, &data.u.fil.filRExtRec); + } + + ++n.rnum; + } + } + + for (blks = 0, pt = vol->mdb.drNmAlBlks; pt--; ) + { + if (! BMTST(vbm, pt)) + ++blks; + } + + if (vol->mdb.drFreeBks != blks) + { + vol->mdb.drFreeBks = blks; + vol->flags |= HFS_UPDATE_MDB; + } + + return 0; +} diff --git a/libhfs_iso/volume.h b/libhfs_iso/volume.h new file mode 100644 index 0000000..2cc6005 --- /dev/null +++ b/libhfs_iso/volume.h @@ -0,0 +1,58 @@ +/* + * 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. + * + */ + +/* @(#)volume.h 1.1 00/03/05 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +int v_catsearch(hfsvol *, long, char *, CatDataRec *, char *, node *); +int v_extsearch(hfsfile *, unsigned int, ExtDataRec *, node *); + +int v_getthread(hfsvol *, long, CatDataRec *, node *, int); + +# define v_getdthread(vol, id, thread, np) \ + v_getthread(vol, id, thread, np, cdrThdRec) +# define v_getfthread(vol, id, thread, np) \ + v_getthread(vol, id, thread, np, cdrFThdRec) + +int v_putcatrec(CatDataRec *, node *); +int v_putextrec(ExtDataRec *, node *); + +int v_allocblocks(hfsvol *, ExtDescriptor *); +void v_freeblocks(hfsvol *, ExtDescriptor *); + +int v_resolve(hfsvol **, char *, CatDataRec *, long *, char *, node *); + +void v_destruct(hfsvol *); +int v_getvol(hfsvol **); +int v_flush(hfsvol *, int); + +int v_adjvalence(hfsvol *, long, int, int); +int v_newfolder(hfsvol *, long, char *); + +int v_scavenge(hfsvol *); diff --git a/libparanoia/CMakeLists.txt b/libparanoia/CMakeLists.txt new file mode 100644 index 0000000..4319496 --- /dev/null +++ b/libparanoia/CMakeLists.txt @@ -0,0 +1,6 @@ +PROJECT (LIBparanoia C) +INCLUDE_DIRECTORIES(../include ${CMAKE_BINARY_DIR} ../wodim ${CMAKE_BINARY_DIR}/include) +ADD_DEFINITIONS(-DHAVE_CONFIG_H) +SET(LIBparanoia_SRCS gap.c isort.c overlap.c p_block.c paranoia.c pmalloc.c) + +ADD_LIBRARY (paranoia STATIC ${LIBparanoia_SRCS}) diff --git a/libparanoia/README.interface b/libparanoia/README.interface new file mode 100644 index 0000000..a7a44b4 --- /dev/null +++ b/libparanoia/README.interface @@ -0,0 +1,75 @@ +/* + * Exports (libparanoia) cdda_paranoia.h + */ +cdrom_paranoia *paranoia_init __PR((void * d, int nsectors)); +void paranoia_modeset __PR((cdrom_paranoia * p, int mode)); +long paranoia_seek __PR((cdrom_paranoia * p, long seek, int mode)); +Int16_t *paranoia_read __PR((cdrom_paranoia * p, void (*callback) (long, int))); +Int16_t *paranoia_read_limited __PR((cdrom_paranoia * p, void (*callback) (long, int), int maxretries)); +void paranoia_free __PR((cdrom_paranoia * p)); +void paranoia_overlapset __PR((cdrom_paranoia * p, long overlap)); + +/* + * Exports ?? (libparanoia) overlap.h + */ +extern void paranoia_resetall __PR((cdrom_paranoia * p)); +extern void paranoia_resetcache __PR((cdrom_paranoia * p)); + +Supported: + +PARANOIA_MODE_VERIFY +PARANOIA_MODE_OVERLAP +PARANOIA_MODE_NEVERSKIP + +Unsupported: + +PARANOIA_MODE_FRAGMENT +PARANOIA_MODE_SCRATCH +PARANOIA_MODE_REPAIR + + + +/* + * Imports (global Code) + */ +cdda_disc_firstsector (cdrom_drive *d) -> long sector +cdda_disc_lastsector (cdrom_drive *d) -> long sector +cdda_read (cdrom_drive *d, void *buffer, long beginsector, long sectors) -> long sectors +cdda_sector_gettrack (cdrom_drive *d,long sector) -> int trackno +cdda_track_audiop (cdrom_drive *d,int track) -> int ??? /* Is audiotrack */ +cdda_track_firstsector (cdrom_drive *d,int track) -> long sector +cdda_track_lastsector (cdrom_drive *d,int track) -> long sector +cdda_tracks (cdrom_drive *d) -> int tracks + +callback (long inpos, int function) + +/* + * Imports (libc) + */ +calloc +free +malloc +realloc + +memcmp +memcpy +memmove +memset + +qsort + +/*--------------------------------------------------------------------------*/ +usalp = usal_open(); +bufsize = usal_bufsize(usalp, CDR_BUF_SIZE); +nsecs = bufsize / SEC_SIZE; + +cdp = paranoia_init(usalp, nsecs); +# paranoia_modeset(cdp, mode); +# paranoia_overlapset(cdp, overlap); + +while (not ready) { + bp = paranoia_read(cdp, NULL); + write(f, bp, SEC_SISE); +} + +paranoia_free(cdp); diff --git a/libparanoia/README.paranoia b/libparanoia/README.paranoia new file mode 100644 index 0000000..4864c32 --- /dev/null +++ b/libparanoia/README.paranoia @@ -0,0 +1,83 @@ +# @(#)README.paranoia 1.1 97/04/04 J. Schilling from Monty (xiphmont@mit.edu) +README.paranoia + +Paranoia II: +(c) Monty +xiphmont@mit.edu + +Hi there. + +All CDROM drives are not created equal. You're probably using this +patch because yours is a little less equal than others-- or maybe you +just keep your CD collection in a box of full of gravel. Jewel cases +are for wimps; you know what I'm talking about. + +This patch adds extra-robust interframe syncronization, code to detect +scratches (and hold sync across the scratch) and finally routines to +filter out scratches as best possible. These are all handled +automatically by fairly modular code. + +1) extra interframe syncronization ------------------------------------- + +Some CD drives can read audio data from an exact starting point to an +exact ending point flawlessly; these are rare. A larger number of +drives read from only an approximately correct starting point, but do +manage to get all the data in-tact from wherever they manage to begin +the read. Stock cdda2wav is coded with this in mind. + +More drives, especially IDE-like and recent ATAPI drives, suffer from +framing misalignments within atomic multi-sector read operations. +Cdda2wav is also set, by default, to read 75 sectors at a time from +ATAPI drives, which Linux's IDE driver breaks into multiple 8 sector +reads to conserve kernel memory. Both of these things will break +cdda2wav; the symptoms include cracks or pops within the read sample. + +The "Paranoia" patch will verify the alignment of *every* byte read by +cdda2wav. The goal is data integrity, not performance: a minimum 50% +speed hit will result from the patch, likely more if your CDROM +suffers from the framing bugs the patch corrects. + +2) scratch detection and tolerance ------------------------------------ + +Because overlap syncronization requires matching exact, perfect sample +sections, scratched CDs typically cause normal cdda2wav to bail when +overlap syncronization is turned on. The second part of the +"Paranoia" patch ignores scratches in the read bitstream and +syncronizes using the data that can still be "trusted". This step +also collects first-pass scratch detection information used by the +third section of the patch. + +Expect performance to drop through the floor on a badly scratched CD; +the code can no longer use a simple case of exact matching for speedy +correlation. Maintaining solid sync across a scratch is processor +bound; later I'll add speedier algorithms for correlation than the +brute force method currently used. Scratch detection imposes little +additional overhead on a non-scratched CD. + +3) scratch repair ----------------------------------------------------- + +Scratches are an irrevocable loss of data. Still, it's usually +possible to reconstruct a sample closer to the original data than the +raw hissing, fluttering and crackling that severe scratches in the CD +surface produce. + +Scratch filtering is the 'hard part' of this patch. It needs to do +two things; first, find the 'pops' that escaped detection in section 2 +of the patch and secondly fill in the gaps. Both are acheived using +delta (slew) averaging and forward and backward linear predictive +interpolation (with IIR filters) to fill in known gaps as well as look +for 'problem values' in stretches of sample known to be scratched. + +THE SCRATCH DETECTION IS NOT PERFECT. Nor is the repair perfect, +although it is easier than detecting scratches reliably. Both are +cases of coming arbitrarily close to perfection; Paranoia is designed +with light to moderate damage in mind, but will still recover a +listenable sample from heavy damage. + +Paranoia still has quite a bit of room for improvement in the scratch +repair code... If cdda2wav + Paranoia is not doing an acceptable job +on CDs that you just gotta have, drop me a line; I didn't want to sink +months into a project I wasn't certain anyone would ever use :-) + +Monty + diff --git a/libparanoia/cdda_paranoia.h b/libparanoia/cdda_paranoia.h new file mode 100644 index 0000000..24a2411 --- /dev/null +++ b/libparanoia/cdda_paranoia.h @@ -0,0 +1,108 @@ +/* + * 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. + * + */ + +/* @(#)cdda_paranoia.h 1.20 04/02/20 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + * + */ + +#ifndef _CDROM_PARANOIA_H +#define _CDROM_PARANOIA_H + +#ifndef _MCONFIG_H +#include <mconfig.h> +#endif +#ifndef _UTYPES_H +#include <utypes.h> +#endif + +#ifndef __GNUC__ +#define inline +#endif + +#define CD_FRAMESIZE_RAW 2352 +#define CD_FRAMEWORDS (CD_FRAMESIZE_RAW/2) + +/* + * Second parameter of the callback function + */ +#define PARANOIA_CB_READ 0 /* Read off adjust ??? */ +#define PARANOIA_CB_VERIFY 1 /* Verifying jitter */ +#define PARANOIA_CB_FIXUP_EDGE 2 /* Fixed edge jitter */ +#define PARANOIA_CB_FIXUP_ATOM 3 /* Fixed atom jitter */ +#define PARANOIA_CB_SCRATCH 4 /* Unsupported */ +#define PARANOIA_CB_REPAIR 5 /* Unsupported */ +#define PARANOIA_CB_SKIP 6 /* Skip exhausted retry */ +#define PARANOIA_CB_DRIFT 7 /* Drift detected */ +#define PARANOIA_CB_BACKOFF 8 /* Unsupported */ +#define PARANOIA_CB_OVERLAP 9 /* Dyn Overlap adjust */ +#define PARANOIA_CB_FIXUP_DROPPED 10 /* Fixed dropped bytes */ +#define PARANOIA_CB_FIXUP_DUPED 11 /* Fixed duplicate bytes */ +#define PARANOIA_CB_READERR 12 /* Hard read error */ + +/* + * Cdparanoia modes to be set with paranoia_modeset() + */ +#define PARANOIA_MODE_FULL 0xFF +#define PARANOIA_MODE_DISABLE 0 + +#define PARANOIA_MODE_VERIFY 1 /* Verify data integrity in overlap area */ +#define PARANOIA_MODE_FRAGMENT 2 /* unsupported */ +#define PARANOIA_MODE_OVERLAP 4 /* Perform overlapped reads */ +#define PARANOIA_MODE_SCRATCH 8 /* unsupported */ +#define PARANOIA_MODE_REPAIR 16 /* unsupported */ +#define PARANOIA_MODE_NEVERSKIP 32 /* Do not skip failed reads (retry maxretries) */ + + +#ifndef CDP_COMPILE +typedef void cdrom_paranoia; +#endif + +/* + * The interface from libcdparanoia to the high level caller + */ +extern cdrom_paranoia *paranoia_init(void * d, int nsectors); +extern void paranoia_dynoverlapset(cdrom_paranoia * p, int minoverlap, + int maxoverlap); +extern void paranoia_modeset(cdrom_paranoia * p, int mode); +extern long paranoia_seek(cdrom_paranoia * p, long seek, int mode); +extern Int16_t *paranoia_read(cdrom_paranoia * p, void (*callback) (long, int)); +extern Int16_t *paranoia_read_limited(cdrom_paranoia * p, + void (*callback) (long, int), + int maxretries); +extern void paranoia_free(cdrom_paranoia * p); +extern void paranoia_overlapset(cdrom_paranoia * p, long overlap); + +#ifndef HAVE_MEMMOVE +#define memmove(dst, src, size) movebytes((src), (dst), (size)) +#endif + + +/* + * The callback interface from libparanoia to the CD-ROM interface + */ +extern long cdda_disc_firstsector(void *d); /* -> long sector */ +extern long cdda_disc_lastsector(void *d); /* -> long sector */ +/* -> long sectors */ +extern long cdda_read(void *d, void *buffer, long beginsector, long sectors); +extern int cdda_sector_gettrack(void *d, long sector); /* -> int trackno */ +extern int cdda_track_audiop(void *d, int track); /* -> int Is audiotrack */ +extern long cdda_track_firstsector(void *d, int track); /* -> long sector */ +extern long cdda_track_lastsector(void *d, int track); /* -> long sector */ +extern int cdda_tracks(void *d); /* -> int tracks */ + +#endif /* _CDROM_PARANOIA_H */ diff --git a/libparanoia/gap.c b/libparanoia/gap.c new file mode 100644 index 0000000..6bb1b92 --- /dev/null +++ b/libparanoia/gap.c @@ -0,0 +1,244 @@ +/* + * 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. + * + */ + +/* @(#)gap.c 1.12 04/02/18 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + * + * Gapa analysis support code for paranoia + * + */ + +#include <mconfig.h> +#include <standard.h> +#include <utypes.h> +#include <strdefs.h> +#include "p_block.h" +#include "cdda_paranoia.h" +#include "gap.h" + +long i_paranoia_overlap_r(Int16_t * buffA, Int16_t * buffB, long offsetA, + long offsetB); +long i_paranoia_overlap_f(Int16_t * buffA, Int16_t * buffB, long offsetA, + long offsetB, long sizeA, long sizeB); +int i_stutter_or_gap(Int16_t * A, Int16_t * B, long offA, long offB, long gap); +void i_analyze_rift_f(Int16_t * A, Int16_t * B, + long sizeA, long sizeB, + long aoffset, long boffset, + long *matchA, long *matchB, long *matchC); +void i_analyze_rift_r(Int16_t * A, Int16_t * B, + long sizeA, long sizeB, + long aoffset, long boffset, + long *matchA, long *matchB, long *matchC); +void analyze_rift_silence_f(Int16_t * A, Int16_t * B, + long sizeA, long sizeB, + long aoffset, long boffset, + long *matchA, long *matchB); + +/* + * Gap analysis code + */ +long i_paranoia_overlap_r(Int16_t *buffA, Int16_t *buffB, long offsetA, + long offsetB) +{ + long beginA = offsetA; + long beginB = offsetB; + + for (; beginA >= 0 && beginB >= 0; beginA--, beginB--) + if (buffA[beginA] != buffB[beginB]) + break; + beginA++; + beginB++; + + return (offsetA - beginA); +} + +long i_paranoia_overlap_f(Int16_t *buffA, Int16_t *buffB, long offsetA, + long offsetB, long sizeA, long sizeB) +{ + long endA = offsetA; + long endB = offsetB; + + for (; endA < sizeA && endB < sizeB; endA++, endB++) + if (buffA[endA] != buffB[endB]) + break; + + return (endA - offsetA); +} + +int i_stutter_or_gap(Int16_t *A, Int16_t *B, long offA, long offB, long gap) +{ + long a1 = offA; + long b1 = offB; + + if (a1 < 0) { + b1 -= a1; + gap += a1; + a1 = 0; + } + return (memcmp(A + a1, B + b1, gap * 2)); +} + +/* + * riftv is the first value into the rift -> or <- + */ +void i_analyze_rift_f(Int16_t *A, Int16_t *B, long sizeA, long sizeB, + long aoffset, long boffset, long *matchA, long *matchB, + long *matchC) +{ + + long apast = sizeA - aoffset; + long bpast = sizeB - boffset; + long i; + + *matchA = 0, *matchB = 0, *matchC = 0; + + /* + * Look for three possible matches... (A) Ariftv->B, + * (B) Briftv->A and (c) AB->AB. + */ + for (i = 0; ; i++) { + if (i < bpast) /* A */ + if (i_paranoia_overlap_f(A, B, aoffset, boffset + i, sizeA, sizeB) >= MIN_WORDS_RIFT) { + *matchA = i; + break; + } + if (i < apast) { /* B */ + if (i_paranoia_overlap_f(A, B, aoffset + i, boffset, sizeA, sizeB) >= MIN_WORDS_RIFT) { + *matchB = i; + break; + } + if (i < bpast) /* C */ + if (i_paranoia_overlap_f(A, B, aoffset + i, boffset + i, sizeA, sizeB) >= MIN_WORDS_RIFT) { + *matchC = i; + break; + } + } else if (i >= bpast) + break; + + } + + if (*matchA == 0 && *matchB == 0 && *matchC == 0) + return; + + if (*matchC) + return; + if (*matchA) { + if (i_stutter_or_gap(A, B, aoffset - *matchA, boffset, *matchA)) + return; + *matchB = -*matchA; /* signify we need to remove n bytes */ + /* from B */ + *matchA = 0; + return; + } else { + if (i_stutter_or_gap(B, A, boffset - *matchB, aoffset, *matchB)) + return; + *matchA = -*matchB; + *matchB = 0; + return; + } +} + +/* + * riftv must be first even val of rift moving back + */ +void i_analyze_rift_r(Int16_t *A, Int16_t *B, long sizeA, long sizeB, + long aoffset, long boffset, long *matchA, long *matchB, + long *matchC) +{ + + long apast = aoffset + 1; + long bpast = boffset + 1; + long i; + + *matchA = 0, *matchB = 0, *matchC = 0; + + /* + * Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and + * (c) AB->AB. + */ + for (i = 0; ; i++) { + if (i < bpast) /* A */ + if (i_paranoia_overlap_r(A, B, aoffset, boffset - i) >= MIN_WORDS_RIFT) { + *matchA = i; + break; + } + if (i < apast) { /* B */ + if (i_paranoia_overlap_r(A, B, aoffset - i, boffset) >= MIN_WORDS_RIFT) { + *matchB = i; + break; + } + if (i < bpast) /* C */ + if (i_paranoia_overlap_r(A, B, aoffset - i, boffset - i) >= MIN_WORDS_RIFT) { + *matchC = i; + break; + } + } else if (i >= bpast) + break; + + } + + if (*matchA == 0 && *matchB == 0 && *matchC == 0) + return; + + if (*matchC) + return; + + if (*matchA) { + if (i_stutter_or_gap(A, B, aoffset + 1, boffset - *matchA + 1, *matchA)) + return; + *matchB = -*matchA; /* signify we need to remove n bytes */ + /* from B */ + *matchA = 0; + return; + } else { + if (i_stutter_or_gap(B, A, boffset + 1, aoffset - *matchB + 1, *matchB)) + return; + *matchA = -*matchB; + *matchB = 0; + return; + } +} + +void analyze_rift_silence_f(Int16_t *A, Int16_t *B, long sizeA, long sizeB, + long aoffset, long boffset, long *matchA, + long *matchB) +{ + *matchA = -1; + *matchB = -1; + + sizeA = min(sizeA, aoffset + MIN_WORDS_RIFT); + sizeB = min(sizeB, boffset + MIN_WORDS_RIFT); + + aoffset++; + boffset++; + + while (aoffset < sizeA) { + if (A[aoffset] != A[aoffset - 1]) { + *matchA = 0; + break; + } + aoffset++; + } + + while (boffset < sizeB) { + if (B[boffset] != B[boffset - 1]) { + *matchB = 0; + break; + } + boffset++; + } +} diff --git a/libparanoia/gap.h b/libparanoia/gap.h new file mode 100644 index 0000000..f772ae3 --- /dev/null +++ b/libparanoia/gap.h @@ -0,0 +1,46 @@ +/* + * 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. + * + */ + +/* @(#)gap.h 1.10 04/02/18 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + */ + +#ifndef _GAP_H_ +#define _GAP_H_ + +extern long i_paranoia_overlap_r(Int16_t * buffA, Int16_t * buffB, + long offsetA, long offsetB); +extern long i_paranoia_overlap_f(Int16_t * buffA, Int16_t * buffB, + long offsetA, long offsetB, + long sizeA, long sizeB); +extern int i_stutter_or_gap(Int16_t * A, Int16_t * B, + long offA, long offB, + long gap); +extern void i_analyze_rift_f(Int16_t * A, Int16_t * B, + long sizeA, long sizeB, + long aoffset, long boffset, + long *matchA, long *matchB, long *matchC); +extern void i_analyze_rift_r(Int16_t * A, Int16_t * B, + long sizeA, long sizeB, + long aoffset, long boffset, + long *matchA, long *matchB, long *matchC); +extern void analyze_rift_silence_f(Int16_t * A, Int16_t * B, + long sizeA, long sizeB, + long aoffset, long boffset, + long *matchA, long *matchB); + +#endif diff --git a/libparanoia/isort.c b/libparanoia/isort.c new file mode 100644 index 0000000..a3d38ad --- /dev/null +++ b/libparanoia/isort.c @@ -0,0 +1,159 @@ +/* + * 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. + * + */ + +/* @(#)isort.c 1.14 04/02/20 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + * + * sorted vector abstraction for paranoia + * + */ + +/* + * Old isort got a bit complex. This re-constrains complexity to + * give a go at speed through a more alpha-6-like mechanism. + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <standard.h> +#include <utypes.h> +#include <strdefs.h> +#include "p_block.h" +#include "isort.h" +#include "pmalloc.h" + +sort_info *sort_alloc(long size); +void sort_unsortall(sort_info * i); +void sort_free(sort_info * i); +void sort_sort(sort_info * i, long sortlo, long sorthi); +void sort_setup(sort_info * i, Int16_t * vector, long *abspos, long size, + long sortlo, long sorthi); +sort_link *sort_getmatch(sort_info * i, long post, long overlap, int value); +sort_link *sort_nextmatch(sort_info * i, sort_link * prev); + + +sort_info *sort_alloc(long size) +{ + sort_info *ret = _pcalloc(1, sizeof (sort_info)); + + ret->vector = NULL; + ret->sortbegin = -1; + ret->size = -1; + ret->maxsize = size; + + ret->head = _pcalloc(65536, sizeof (sort_link *)); + ret->bucketusage = _pmalloc(65536 * sizeof (long)); + ret->revindex = _pcalloc(size, sizeof (sort_link)); + ret->lastbucket = 0; + + return (ret); +} + +void sort_unsortall(sort_info *i) +{ + if (i->lastbucket > 2000) { /* a guess */ + memset(i->head, 0, 65536 * sizeof (sort_link *)); + } else { + long b; + + for (b = 0; b < i->lastbucket; b++) + i->head[i->bucketusage[b]] = NULL; + } + + i->lastbucket = 0; + i->sortbegin = -1; +} + +void sort_free(sort_info *i) +{ + _pfree(i->revindex); + _pfree(i->head); + _pfree(i->bucketusage); + _pfree(i); +} + +void sort_sort(sort_info *i, long sortlo, long sorthi) +{ + long j; + + for (j = sorthi - 1; j >= sortlo; j--) { + sort_link **hv = i->head + i->vector[j] + 32768; + sort_link *l = i->revindex + j; + + if (*hv == NULL) { + i->bucketusage[i->lastbucket] = i->vector[j] + 32768; + i->lastbucket++; + } + l->next = *hv; + *hv = l; + } + i->sortbegin = 0; +} + +/* + * size *must* be less than i->maxsize + */ +void sort_setup(sort_info *i, Int16_t *vector, long *abspos, long size, + long sortlo, long sorthi) +{ + if (i->sortbegin != -1) + sort_unsortall(i); + + i->vector = vector; + i->size = size; + i->abspos = abspos; + + i->lo = min(size, max(sortlo - *abspos, 0)); + i->hi = max(0, min(sorthi - *abspos, size)); +} + +sort_link *sort_getmatch(sort_info *i, long post, long overlap, int value) +{ + sort_link *ret; + + if (i->sortbegin == -1) + sort_sort(i, i->lo, i->hi); + /* + * Now we reuse lo and hi + */ + post = max(0, min(i->size, post)); + i->val = value + 32768; + i->lo = max(0, post - overlap); /* absolute position */ + i->hi = min(i->size, post + overlap); /* absolute position */ + + ret = i->head[i->val]; + while (ret) { + if (ipos(i, ret) < i->lo) { + ret = ret->next; + } else { + if (ipos(i, ret) >= i->hi) + ret = NULL; + break; + } + } +/* i->head[i->val]=ret; */ + return (ret); +} + +sort_link *sort_nextmatch(sort_info *i, sort_link *prev) +{ + sort_link *ret = prev->next; + + if (!ret || ipos(i, ret) >= i->hi) + return (NULL); + return (ret); +} diff --git a/libparanoia/isort.h b/libparanoia/isort.h new file mode 100644 index 0000000..1b6661c --- /dev/null +++ b/libparanoia/isort.h @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +/* @(#)isort.h 1.10 04/02/18 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + */ + +#ifndef _ISORT_H_ +#define _ISORT_H_ + +typedef struct sort_link { + struct sort_link *next; +} sort_link; + +typedef struct sort_info { + Int16_t *vector; /* vector */ + /* vec storage doesn't belong to us */ + + long *abspos; /* pointer for side effects */ + long size; /* vector size */ + + long maxsize; /* maximum vector size */ + + long sortbegin; /* range of contiguous sorted area */ + long lo; + long hi; /* current post, overlap range */ + int val; /* ...and val */ + + /* + * sort structs + */ + sort_link **head; /* sort buckets (65536) */ + + long *bucketusage; /* of used buckets (65536) */ + long lastbucket; + sort_link *revindex; + +} sort_info; + +extern sort_info *sort_alloc(long size); +extern void sort_unsortall(sort_info * i); +extern void sort_setup(sort_info * i, Int16_t * vector, long *abspos, + long size, long sortlo, long sorthi); +extern void sort_free(sort_info * i); +extern sort_link *sort_getmatch(sort_info * i, long post, long overlap, + int value); +extern sort_link *sort_nextmatch(sort_info * i, sort_link * prev); + +#define is(i) ((i)->size) +#define ib(i) (*(i)->abspos) +#define ie(i) ((i)->size + *(i)->abspos) +#define iv(i) ((i)->vector) +#define ipos(i, l) ((l) - (i)->revindex) + +#endif diff --git a/libparanoia/overlap.c b/libparanoia/overlap.c new file mode 100644 index 0000000..6f15baf --- /dev/null +++ b/libparanoia/overlap.c @@ -0,0 +1,228 @@ +/* + * 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. + * + */ + +/* @(#)overlap.c 1.11 04/02/20 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + * + * Statistic code and cache management for overlap settings + * + */ + +#include <mconfig.h> +#include <stdxlib.h> +#include <standard.h> +#include <utypes.h> +#include "p_block.h" +#include "cdda_paranoia.h" +#include "overlap.h" +#include "isort.h" + +void paranoia_resetcache(cdrom_paranoia *p); +void paranoia_resetall(cdrom_paranoia *p); +void i_paranoia_trim(cdrom_paranoia *p, long beginword, long endword); +void offset_adjust_settings(cdrom_paranoia *p, void (*callback)(long, int)); +void offset_add_value(cdrom_paranoia *p, offsets *o, long value, + void (*callback)(long, int)); + +/* + * Internal cache management + */ +void paranoia_resetcache(cdrom_paranoia *p) +{ + c_block *c = c_first(p); + v_fragment *v; + + while (c) { + free_c_block(c); + c = c_first(p); + } + + v = v_first(p); + while (v) { + free_v_fragment(v); + v = v_first(p); + } +} + +void paranoia_resetall(cdrom_paranoia *p) +{ + p->root.returnedlimit = 0; + p->dyndrift = 0; + p->root.lastsector = 0; + + if (p->root.vector) { + i_cblock_destructor(p->root.vector); + p->root.vector = NULL; + } + paranoia_resetcache(p); +} + +void i_paranoia_trim(cdrom_paranoia *p, long beginword, long endword) +{ + root_block *root = &(p->root); + + if (root->vector != NULL) { + long target = beginword - p->maxdynoverlap; + long rbegin = cb(root->vector); + long rend = ce(root->vector); + + if (rbegin > beginword) + goto rootfree; + + if (rbegin + p->maxdynoverlap < beginword) { + if (target + MIN_WORDS_OVERLAP > rend) + goto rootfree; + + { + long offset = target - rbegin; + + c_removef(root->vector, offset); + } + } { + c_block *c = c_first(p); + + while (c) { + c_block *next = c_next(c); + + if (ce(c) < beginword - p->maxdynoverlap) + free_c_block(c); + c = next; + } + } + + } + return; + +rootfree: + + i_cblock_destructor(root->vector); + root->vector = NULL; + root->returnedlimit = -1; + root->lastsector = 0; + +} + +/* + * Statistical and heuristic[al? :-] management + */ +void offset_adjust_settings(cdrom_paranoia *p, void (*callback)(long, int)) +{ + if (p->stage2.offpoints >= 10) { + /* + * drift: look at the average offset value. If it's over one + * sector, frob it. We just want a little hysteresis [sp?] + */ + long av = (p->stage2.offpoints ? p->stage2.offaccum / p->stage2.offpoints : 0); + + if (abs(av) > p->dynoverlap / 4) { + av = (av / MIN_SECTOR_EPSILON) * MIN_SECTOR_EPSILON; + + if (callback) + (*callback) (ce(p->root.vector), PARANOIA_CB_DRIFT); + p->dyndrift += av; + + /* + * Adjust all the values in the cache otherwise we get + * a (potentially unstable) feedback loop + */ + { + c_block *c = c_first(p); + v_fragment *v = v_first(p); + + while (v && v->one) { + /* + * safeguard beginning bounds case with + * a hammer + */ + if (fb(v) < av || cb(v->one) < av) { + v->one = NULL; + } else { + fb(v) -= av; + } + v = v_next(v); + } + while (c) { + long adj = min(av, cb(c)); + + c_set(c, cb(c) - adj); + c = c_next(c); + } + } + + p->stage2.offaccum = 0; + p->stage2.offmin = 0; + p->stage2.offmax = 0; + p->stage2.offpoints = 0; + p->stage2.newpoints = 0; + p->stage2.offdiff = 0; + } + } + if (p->stage1.offpoints >= 10) { + /* + * dynoverlap: we arbitrarily set it to 4x the running + * difference value, unless min/max are more + */ + p->dynoverlap = (p->stage1.offpoints ? p->stage1.offdiff / + p->stage1.offpoints * 3 : CD_FRAMEWORDS); + + if (p->dynoverlap < -p->stage1.offmin * 1.5) + p->dynoverlap = -p->stage1.offmin * 1.5; + + if (p->dynoverlap < p->stage1.offmax * 1.5) + p->dynoverlap = p->stage1.offmax * 1.5; + + if (p->dynoverlap < p->mindynoverlap) + p->dynoverlap = p->mindynoverlap; + if (p->dynoverlap > p->maxdynoverlap) + p->dynoverlap = p->maxdynoverlap; + + if (callback) + (*callback) (p->dynoverlap, PARANOIA_CB_OVERLAP); + + if (p->stage1.offpoints > 600) { + /* + * bit of a bug; this routine is called too often + * due to the overlap mesh alg we use in stage 1 + */ + p->stage1.offpoints /= 1.2; + p->stage1.offaccum /= 1.2; + p->stage1.offdiff /= 1.2; + } + p->stage1.offmin = 0; + p->stage1.offmax = 0; + p->stage1.newpoints = 0; + } +} + +void offset_add_value(cdrom_paranoia *p, offsets *o, long value, + void (*callback)(long, int)) +{ + if (o->offpoints != -1) { + + o->offdiff += abs(value); + o->offpoints++; + o->newpoints++; + o->offaccum += value; + if (value < o->offmin) + o->offmin = value; + if (value > o->offmax) + o->offmax = value; + + if (o->newpoints >= 10) + offset_adjust_settings(p, callback); + } +} diff --git a/libparanoia/overlap.h b/libparanoia/overlap.h new file mode 100644 index 0000000..44db6e2 --- /dev/null +++ b/libparanoia/overlap.h @@ -0,0 +1,33 @@ +/* + * 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. + * + */ + +/* @(#)overlap.h 1.7 04/02/18 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + */ + +#ifndef _OVERLAP_H_ +#define _OVERLAP_H_ + +extern void paranoia_resetcache(cdrom_paranoia *p); +extern void paranoia_resetall(cdrom_paranoia *p); +extern void i_paranoia_trim(cdrom_paranoia *p, long beginword, long endword); +extern void offset_adjust_settings(cdrom_paranoia *p, + void (*callback) (long, int)); +extern void offset_add_value(cdrom_paranoia *p, offsets *o, long value, + void (*callback) (long, int)); + +#endif diff --git a/libparanoia/overlapdef.txt b/libparanoia/overlapdef.txt new file mode 100644 index 0000000..3aff6cf --- /dev/null +++ b/libparanoia/overlapdef.txt @@ -0,0 +1,20 @@ +# @(#)overlapdef.txt 1.1 98/08/19 J. Schilling from Monty (xiphmont@mit.edu) + + 0 70 100 +A |----------|-----| +B |-----|---------| + 0 40 100 + +offset=-30 +begin=30 +end=100 + + 0 70 100 +A |----------|-----| +B |-----|---------| + 50 90 150 + +offset=20 +begin=30 +end=100 + diff --git a/libparanoia/p_block.c b/libparanoia/p_block.c new file mode 100644 index 0000000..e37334b --- /dev/null +++ b/libparanoia/p_block.c @@ -0,0 +1,474 @@ +/* + * 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. + * + */ + +/* @(#)p_block.c 1.19 04/02/23 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +#include <mconfig.h> +#include <stdxlib.h> +#include <standard.h> +#include <utypes.h> +#include <strdefs.h> +#include "p_block.h" +#include "cdda_paranoia.h" +#include "pmalloc.h" + +linked_list *new_list(void *(*newp) (void), void (*freep) (void *)); +linked_element *add_elem(linked_list *l, void *elem); +linked_element *new_elem(linked_list *list); +void free_elem(linked_element *e, int free_ptr); +void free_list(linked_list *list, int free_ptr); +void *get_elem(linked_element *e); +linked_list *copy_list(linked_list *list); +static c_block *i_cblock_constructor(void); +void i_cblock_destructor(c_block *c); +c_block *new_c_block(cdrom_paranoia *p); +void free_c_block(c_block *c); +static v_fragment *i_vfragment_constructor(void); +static void i_v_fragment_destructor(v_fragment *v); +v_fragment *new_v_fragment(cdrom_paranoia *p, c_block *one, long begin, + long end, int last); +void free_v_fragment(v_fragment *v); +c_block *c_first(cdrom_paranoia *p); +c_block *c_last(cdrom_paranoia *p); +c_block *c_next(c_block *c); +c_block *c_prev(c_block *c); +v_fragment *v_first(cdrom_paranoia *p); +v_fragment *v_last(cdrom_paranoia *p); +v_fragment *v_next(v_fragment *v); +v_fragment *v_prev(v_fragment *v); +void recover_cache(cdrom_paranoia *p); +Int16_t *v_buffer(v_fragment *v); +c_block *c_alloc(Int16_t *vector, long begin, long size); +void c_set(c_block *v, long begin); +void c_remove(c_block *v, long cutpos, long cutsize); +void c_overwrite(c_block *v, long pos, Int16_t *b, long size); +void c_append(c_block *v, Int16_t *vector, long size); +void c_removef(c_block *v, long cut); +void i_paranoia_firstlast(cdrom_paranoia *p); +cdrom_paranoia *paranoia_init(void *d, int nsectors); + + +linked_list *new_list(void *(*newp)(void), void (*freep)(void *)) +{ + linked_list *ret = _pcalloc(1, sizeof (linked_list)); + + ret->new_poly = newp; + ret->free_poly = freep; + return (ret); +} + +linked_element *add_elem(linked_list *l, void *elem) +{ + + linked_element *ret = _pcalloc(1, sizeof (linked_element)); + + ret->stamp = l->current++; + ret->ptr = elem; + ret->list = l; + + if (l->head) + l->head->prev = ret; + else + l->tail = ret; + ret->next = l->head; + ret->prev = NULL; + l->head = ret; + l->active++; + + return (ret); +} + +linked_element *new_elem(linked_list *list) +{ + void *new = list->new_poly(); + + return (add_elem(list, new)); +} + +void free_elem(linked_element *e, int free_ptr) +{ + linked_list *l = e->list; + + if (free_ptr) + l->free_poly(e->ptr); + + if (e == l->head) + l->head = e->next; + if (e == l->tail) + l->tail = e->prev; + + if (e->prev) + e->prev->next = e->next; + if (e->next) + e->next->prev = e->prev; + + l->active--; + _pfree(e); +} + +void free_list(linked_list *list, int free_ptr) +{ + while (list->head) + free_elem(list->head, free_ptr); + _pfree(list); +} + +void *get_elem(linked_element *e) +{ + return (e->ptr); +} + +linked_list *copy_list(linked_list *list) +{ + linked_list *new = new_list(list->new_poly, list->free_poly); + linked_element *i = list->tail; + + while (i) { + add_elem(new, i->ptr); + i = i->prev; + } + return (new); +} + +/**** C_block stuff ******************************************************/ + +#define vp_cblock_constructor_func ((void*(*)(void))i_cblock_constructor) +static c_block *i_cblock_constructor() +{ + c_block *ret = _pcalloc(1, sizeof (c_block)); + + return (ret); +} + +#define vp_cblock_destructor_func ((void(*)(void*))i_cblock_destructor) +void i_cblock_destructor(c_block *c) +{ + if (c) { + if (c->vector) + _pfree(c->vector); + if (c->flags) + _pfree(c->flags); + c->e = NULL; + _pfree(c); + } +} + +c_block *new_c_block(cdrom_paranoia *p) +{ + linked_element *e = new_elem(p->cache); + c_block *c = e->ptr; + + c->e = e; + c->p = p; + return (c); +} + +void free_c_block(c_block *c) +{ + /* + * also rid ourselves of v_fragments that reference this block + */ + v_fragment *v = v_first(c->p); + + while (v) { + v_fragment *next = v_next(v); + + if (v->one == c) + free_v_fragment(v); + v = next; + } + + free_elem(c->e, 1); +} + +#define vp_vfragment_constructor_func ((void*(*)(void))i_vfragment_constructor) +static v_fragment *i_vfragment_constructor() +{ + v_fragment *ret = _pcalloc(1, sizeof (v_fragment)); + + return (ret); +} + +#define vp_v_fragment_destructor_func ((void(*)(void*))i_v_fragment_destructor) +static void i_v_fragment_destructor(v_fragment *v) +{ + _pfree(v); +} + +v_fragment *new_v_fragment(cdrom_paranoia *p, c_block *one, long begin, + long end, int last) +{ + linked_element *e = new_elem(p->fragments); + v_fragment *b = e->ptr; + + b->e = e; + b->p = p; + + b->one = one; + b->begin = begin; + b->vector = one->vector + begin - one->begin; + b->size = end - begin; + b->lastsector = last; + + return (b); +} + +void free_v_fragment(v_fragment *v) +{ + free_elem(v->e, 1); +} + +c_block *c_first(cdrom_paranoia *p) +{ + if (p->cache->head) + return (p->cache->head->ptr); + return (NULL); +} + +c_block* c_last(cdrom_paranoia *p) +{ + if (p->cache->tail) + return (p->cache->tail->ptr); + return (NULL); +} + +c_block *c_next(c_block *c) +{ + if (c->e->next) + return (c->e->next->ptr); + return (NULL); +} + +c_block *c_prev(c_block *c) +{ + if (c->e->prev) + return (c->e->prev->ptr); + return (NULL); +} + +v_fragment *v_first(cdrom_paranoia *p) +{ + if (p->fragments->head) { + return (p->fragments->head->ptr); + } + return (NULL); +} + +v_fragment *v_last(cdrom_paranoia *p) +{ + if (p->fragments->tail) + return (p->fragments->tail->ptr); + return (NULL); +} + +v_fragment *v_next(v_fragment *v) +{ + if (v->e->next) + return (v->e->next->ptr); + return (NULL); +} + +v_fragment *v_prev(v_fragment *v) +{ + if (v->e->prev) + return (v->e->prev->ptr); + return (NULL); +} + +void recover_cache(cdrom_paranoia *p) +{ + linked_list *l = p->cache; + + /* + * Are we at/over our allowed cache size? + */ + while (l->active > p->cache_limit) { + /* + * cull from the tail of the list + */ + free_c_block(c_last(p)); + } + +} + +Int16_t *v_buffer(v_fragment *v) +{ + if (!v->one) + return (NULL); + if (!cv(v->one)) + return (NULL); + return (v->vector); +} + +/* + * alloc a c_block not on a cache list + */ +c_block *c_alloc(Int16_t *vector, long begin, long size) +{ + c_block *c = _pcalloc(1, sizeof (c_block)); + + c->vector = vector; + c->begin = begin; + c->size = size; + return (c); +} + +void c_set(c_block *v, long begin) +{ + v->begin = begin; +} + +/* + * pos here is vector position from zero + */ +void c_insert(c_block *v, long pos, Int16_t *b, long size) +{ + int vs = cs(v); + + if (pos < 0 || pos > vs) + return; + + if (v->vector) + v->vector = _prealloc(v->vector, sizeof (Int16_t) * (size + vs)); + else + v->vector = _pmalloc(sizeof (Int16_t) * size); + + if (pos < vs) + memmove(v->vector + pos + size, v->vector + pos, + (vs - pos) * sizeof (Int16_t)); + memcpy(v->vector + pos, b, size * sizeof (Int16_t)); + + v->size += size; +} + +void c_remove(c_block *v, long cutpos, long cutsize) +{ + int vs = cs(v); + + if (cutpos < 0 || cutpos > vs) + return; + if (cutpos + cutsize > vs) + cutsize = vs - cutpos; + if (cutsize < 0) + cutsize = vs - cutpos; + if (cutsize < 1) + return; + + memmove(v->vector + cutpos, v->vector + cutpos + cutsize, + (vs - cutpos - cutsize) * sizeof (Int16_t)); + + v->size -= cutsize; +} + +void c_overwrite(c_block *v, long pos, Int16_t *b, long size) +{ + int vs = cs(v); + + if (pos < 0) + return; + if (pos + size > vs) + size = vs - pos; + + memcpy(v->vector + pos, b, size * sizeof (Int16_t)); +} + +void c_append(c_block *v, Int16_t *vector, long size) +{ + int vs = cs(v); + + /* + * update the vector + */ + if (v->vector) + v->vector = _prealloc(v->vector, sizeof (Int16_t) * (size + vs)); + else + v->vector = _pmalloc(sizeof (Int16_t) * size); + memcpy(v->vector + vs, vector, sizeof (Int16_t) * size); + + v->size += size; +} + +void c_removef(c_block *v, long cut) +{ + c_remove(v, 0, cut); + v->begin += cut; +} + + + +/* + * Initialization + */ +void i_paranoia_firstlast(cdrom_paranoia *p) +{ + int i; + void *d = p->d; + + p->current_lastsector = -1; + for (i = cdda_sector_gettrack(d, p->cursor); i < cdda_tracks(d); i++) + if (!cdda_track_audiop(d, i)) + p->current_lastsector = cdda_track_lastsector(d, i - 1); + if (p->current_lastsector == -1) + p->current_lastsector = cdda_disc_lastsector(d); + + p->current_firstsector = -1; + for (i = cdda_sector_gettrack(d, p->cursor); i > 0; i--) + if (!cdda_track_audiop(d, i)) + p->current_firstsector = cdda_track_firstsector(d, i + 1); + if (p->current_firstsector == -1) + p->current_firstsector = cdda_disc_firstsector(d); + +} + +cdrom_paranoia *paranoia_init(void *d, int nsectors) +{ + cdrom_paranoia *p = _pcalloc(1, sizeof (cdrom_paranoia)); + + p->cache = new_list(vp_cblock_constructor_func, + vp_cblock_destructor_func); + + p->fragments = new_list(vp_vfragment_constructor_func, + vp_v_fragment_destructor_func); + + p->nsectors = nsectors; + p->readahead = 150; + p->sortcache = sort_alloc(p->readahead * CD_FRAMEWORDS); + p->d = d; + p->mindynoverlap = MIN_SECTOR_EPSILON; + p->maxdynoverlap = MAX_SECTOR_OVERLAP * CD_FRAMEWORDS; + p->maxdynoverlap = (nsectors - 1) * CD_FRAMEWORDS; + p->dynoverlap = MAX_SECTOR_OVERLAP * CD_FRAMEWORDS; + p->cache_limit = JIGGLE_MODULO; + p->enable = PARANOIA_MODE_FULL; + p->cursor = cdda_disc_firstsector(d); + p->lastread = -1000000; + + /* + * One last one... in case data and audio tracks are mixed... + */ + i_paranoia_firstlast(p); + + return (p); +} + +void paranoia_dynoverlapset(cdrom_paranoia *p, int minoverlap, int maxoverlap) +{ + if (minoverlap >= 0) + p->mindynoverlap = minoverlap; + if (maxoverlap > minoverlap) + p->maxdynoverlap = maxoverlap; + + if (p->maxdynoverlap < p->mindynoverlap) + p->maxdynoverlap = p->mindynoverlap; +} diff --git a/libparanoia/p_block.h b/libparanoia/p_block.h new file mode 100644 index 0000000..418c193 --- /dev/null +++ b/libparanoia/p_block.h @@ -0,0 +1,210 @@ +/* + * 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. + * + */ + +/* @(#)p_block.h 1.16 04/02/20 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + */ + +#ifndef _p_block_h_ +#define _p_block_h_ + +#define MIN_WORDS_OVERLAP 64 /* 16 bit words */ +#define MIN_WORDS_SEARCH 64 /* 16 bit words */ +#define MIN_WORDS_RIFT 16 /* 16 bit words */ +#define MAX_SECTOR_OVERLAP 32 /* sectors */ +#define MIN_SECTOR_EPSILON 128 /* words */ +#define MIN_SECTOR_BACKUP 16 /* sectors */ +#define JIGGLE_MODULO 15 /* sectors */ +#define MIN_SILENCE_BOUNDARY 1024 /* 16 bit words */ + +#define min(x, y) ((x) > (y)?(y):(x)) +#define max(x, y) ((x) < (y)?(y):(x)) + +#include "isort.h" + +typedef struct linked_list { + /* linked list */ + struct linked_element *head; + struct linked_element *tail; + + void *(*new_poly)(void); + void (*free_poly)(void *poly); + long current; + long active; + +} linked_list; + +typedef struct linked_element { + void *ptr; + struct linked_element *prev; + struct linked_element *next; + + struct linked_list *list; + int stamp; +} linked_element; + +extern linked_list *new_list(void *(*newp) (void), + void (*freep) (void *)); +extern linked_element *new_elem(linked_list *list); +extern linked_element *add_elem(linked_list *list, void *elem); +extern void free_list(linked_list *list, int free_ptr); /* unlink or free */ +extern void free_elem(linked_element *e, int free_ptr); /* unlink or free */ +extern void *get_elem(linked_element *e); +extern linked_list *copy_list(linked_list *list); /* shallow; doesn't copy */ + /* contained structures */ + +typedef struct c_block { + /* The buffer */ + Int16_t *vector; + long begin; + long size; + + /* auxiliary support structures */ + unsigned char *flags; + /* + * 1 known boundaries in read data + * 2 known blanked data + * 4 matched sample + * 8 reserved + * 16 reserved + * 32 reserved + * 64 reserved + * 128 reserved + */ + + /* end of session cases */ + long lastsector; + struct cdrom_paranoia *p; + struct linked_element *e; +} c_block; + +extern void free_c_block(c_block *c); +extern void i_cblock_destructor(c_block *c); +extern c_block *new_c_block(struct cdrom_paranoia *p); + +typedef struct v_fragment { + c_block *one; + + long begin; + long size; + Int16_t *vector; + + /* end of session cases */ + long lastsector; + + /* linked list */ + struct cdrom_paranoia *p; + struct linked_element *e; + +} v_fragment; + +extern void free_v_fragment(v_fragment *c); +extern v_fragment *new_v_fragment(struct cdrom_paranoia *p, c_block *one, + long begin, long end, + int lastsector); +extern Int16_t *v_buffer(v_fragment *v); + +extern c_block *c_first(struct cdrom_paranoia *p); +extern c_block *c_last(struct cdrom_paranoia *p); +extern c_block *c_next(c_block *c); +extern c_block *c_prev(c_block *c); + +extern v_fragment *v_first(struct cdrom_paranoia *p); +extern v_fragment *v_last(struct cdrom_paranoia *p); +extern v_fragment *v_next(v_fragment *v); +extern v_fragment *v_prev(v_fragment *v); + +typedef struct root_block { + long returnedlimit; + long lastsector; + struct cdrom_paranoia *p; + + c_block *vector; /* doesn't use any sorting */ + int silenceflag; + long silencebegin; +} root_block; + +typedef struct offsets { + long offpoints; + long newpoints; + long offaccum; + long offdiff; + long offmin; + long offmax; + +} offsets; + +typedef struct cdrom_paranoia { + void *d; /* A pointer to the driver interface */ + int nsectors; /* # of sectors that fit into DMA buf */ + + root_block root; /* verified/reconstructed cached data */ + linked_list *cache; /* our data as read from the cdrom */ + long cache_limit; + linked_list *fragments; /* fragments of blocks that have been */ + /* 'verified' */ + sort_info *sortcache; + + int readahead; /* sectors of readahead in each readop */ + int jitter; + long lastread; + + int enable; + long cursor; + long current_lastsector; + long current_firstsector; + + /* statistics for drift/overlap */ + struct offsets stage1; + struct offsets stage2; + + long mindynoverlap; + long maxdynoverlap; + long dynoverlap; + long dyndrift; + + /* statistics for verification */ + +} cdrom_paranoia; + +extern c_block *c_alloc(Int16_t *vector, long begin, long size); +extern void c_set(c_block *v, long begin); +extern void c_insert(c_block *v, long pos, Int16_t *b, long size); +extern void c_remove(c_block *v, long cutpos, long cutsize); +extern void c_overwrite(c_block *v, long pos, Int16_t *b, long size); +extern void c_append(c_block *v, Int16_t *vector, long size); +extern void c_removef(c_block *v, long cut); + +#define ce(v) ((v)->begin + (v)->size) +#define cb(v) ((v)->begin) +#define cs(v) ((v)->size) + +/* + * pos here is vector position from zero + */ +extern void recover_cache(cdrom_paranoia *p); +extern void i_paranoia_firstlast(cdrom_paranoia *p); + +#define cv(c) ((c)->vector) + +#define fe(f) ((f)->begin + (f)->size) +#define fb(f) ((f)->begin) +#define fs(f) ((f)->size) +#define fv(f) (v_buffer(f)) + +#define CDP_COMPILE +#endif diff --git a/libparanoia/paranoia.c b/libparanoia/paranoia.c new file mode 100644 index 0000000..56a7be4 --- /dev/null +++ b/libparanoia/paranoia.c @@ -0,0 +1,1741 @@ +/* + * 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. + * + */ + +/* @(#)paranoia.c 1.33 04/08/17 J. Schilling from cdparanoia-III-alpha9.8 */ +/* + * Modifications to make the code portable Copyright (c) 2002 J. Schilling + */ +/* + * CopyPolicy: GNU Public License 2 applies + * Copyright (C) by Monty (xiphmont@mit.edu) + * + * Toplevel file for the paranoia abstraction over the cdda lib + * + */ + +/* immediate todo:: */ +/* Allow disabling of root fixups? */ + +/* + * Dupe bytes are creeping into cases that require greater overlap + * than a single fragment can provide. We need to check against a + * larger area* (+/-32 sectors of root?) to better eliminate + * dupes. Of course this leads to other problems... Is it actually a + * practically solvable problem? + */ +/* Bimodal overlap distributions break us. */ +/* scratch detection/tolerance not implemented yet */ + +/* + * Da new shtick: verification now a two-step assymetric process. + * + * A single 'verified/reconstructed' data segment cache, and then the + * multiple fragment cache + * + * verify a newly read block against previous blocks; do it only this + * once. We maintain a list of 'verified sections' from these matches. + * + * We then glom these verified areas into a new data buffer. + * Defragmentation fixups are allowed here alone. + * + * We also now track where read boundaries actually happened; do not + * verify across matching boundaries. + */ + +/* + * Silence. "It's BAAAAAAaaack." + * + * audio is now treated as great continents of values floating on a + * mantle of molten silence. Silence is not handled by basic + * verification at all; we simply anchor sections of nonzero audio to a + * position and fill in everything else as silence. We also note the + * audio that interfaces with silence; an edge must be 'wet'. + */ + +#include <mconfig.h> +#include <allocax.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <standard.h> +#include <utypes.h> +#include <stdio.h> +#include <strdefs.h> +#include "p_block.h" +#include "cdda_paranoia.h" +#include "overlap.h" +#include "gap.h" +#include "isort.h" +#include "pmalloc.h" + +/* + * used by: i_iterate_stage2() / i_stage2_each() + */ +typedef struct sync_result { + long offset; + long begin; + long end; +} sync_result; + +static inline long re(root_block *root); +static inline long rb(root_block *root); +static inline long rs(root_block *root); +static inline Int16_t *rv(root_block *root); +static inline long i_paranoia_overlap(Int16_t *buffA, Int16_t *buffB, + long offsetA, long offsetB, + long sizeA, long sizeB, + long *ret_begin, long *ret_end); +static inline long i_paranoia_overlap2(Int16_t *buffA, Int16_t *buffB, + Uchar *flagsA, Uchar *flagsB, + long offsetA, long offsetB, + long sizeA, long sizeB, + long *ret_begin, long *ret_end); +static inline long do_const_sync(c_block *A, + sort_info *B, Uchar *flagB, + long posA, long posB, + long *begin, long *end, long *offset); +static inline long try_sort_sync(cdrom_paranoia *p, + sort_info *A, Uchar *Aflags, + c_block *B, + long post, long *begin, long *end, + long *offset, void (*callback) (long, int)); +static inline void stage1_matched(c_block *old, c_block *new, + long matchbegin, long matchend, + long matchoffset, + void (*callback) (long, int)); +static long i_iterate_stage1(cdrom_paranoia *p, c_block *old, c_block *new, + void (*callback) (long, int)); +static long i_stage1(cdrom_paranoia *p, c_block *new, + void (*callback) (long, int)); +static long i_iterate_stage2(cdrom_paranoia *p, v_fragment *v, sync_result *r, + void (*callback)(long, int)); +static void i_silence_test(root_block *root); +static long i_silence_match(root_block *root, v_fragment *v, + void (*callback) (long, int)); +static long i_stage2_each(root_block *root, v_fragment *v, + void (*callback) (long, int)); +static int i_init_root(root_block *root, v_fragment *v, + long begin, void (*callback)(long, int)); +static int vsort(const void *a, const void *b); +static int i_stage2(cdrom_paranoia *p, long beginword, long endword, + void (*callback)(long, int)); +static void i_end_case(cdrom_paranoia *p, long endword, + void (*callback)(long, int)); +static void verify_skip_case(cdrom_paranoia *p, + void (*callback)(long, int)); +void paranoia_free(cdrom_paranoia *p); +void paranoia_modeset(cdrom_paranoia *p, int enable); +long paranoia_seek(cdrom_paranoia *p, long seek, int mode); +c_block *i_read_c_block(cdrom_paranoia *p, long beginword, long endword, + void (*callback)(long,int)); +Int16_t *paranoia_read(cdrom_paranoia *p, void (*callback)(long, int)); +Int16_t *paranoia_read_limited(cdrom_paranoia *p, void (*callback)(long, int), + int max_retries); +void paranoia_overlapset(cdrom_paranoia *p, long overlap); + + +static inline long re(root_block *root) +{ + if (!root) + return (-1); + if (!root->vector) + return (-1); + return (ce(root->vector)); +} + +static inline long rb(root_block *root) +{ + if (!root) + return (-1); + if (!root->vector) + return (-1); + return (cb(root->vector)); +} + +static inline long rs(root_block *root) +{ + if (!root) + return (-1); + if (!root->vector) + return (-1); + return (cs(root->vector)); +} + +static inline Int16_t *rv(root_block *root) +{ + if (!root) + return (NULL); + if (!root->vector) + return (NULL); + return (cv(root->vector)); +} + +#define rc(r) ((r)->vector) + +/* + * matching and analysis code + */ +static inline long +i_paranoia_overlap(Int16_t *buffA, Int16_t *buffB, long offsetA, long offsetB, + long sizeA, long sizeB, long *ret_begin, long *ret_end) +{ + long beginA = offsetA; + long endA = offsetA; + long beginB = offsetB; + long endB = offsetB; + + for (; beginA >= 0 && beginB >= 0; beginA--, beginB--) + if (buffA[beginA] != buffB[beginB]) + break; + beginA++; + beginB++; + + for (; endA < sizeA && endB < sizeB; endA++, endB++) + if (buffA[endA] != buffB[endB]) + break; + + if (ret_begin) + *ret_begin = beginA; + if (ret_end) + *ret_end = endA; + return (endA - beginA); +} + +static inline long +i_paranoia_overlap2(Int16_t *buffA, Int16_t *buffB, Uchar *flagsA, + Uchar *flagsB, long offsetA, long offsetB, long sizeA, + long sizeB, long *ret_begin, long *ret_end) +{ + long beginA = offsetA; + long endA = offsetA; + long beginB = offsetB; + long endB = offsetB; + + for (; beginA >= 0 && beginB >= 0; beginA--, beginB--) { + if (buffA[beginA] != buffB[beginB]) + break; + /* + * don't allow matching across matching sector boundaries + */ + if ((flagsA[beginA] & flagsB[beginB] & 1)) { + beginA--; + beginB--; + break; + } + /* + * don't allow matching through known missing data + */ + if ((flagsA[beginA] & 2) || (flagsB[beginB] & 2)) + break; + } + beginA++; + beginB++; + + for (; endA < sizeA && endB < sizeB; endA++, endB++) { + if (buffA[endA] != buffB[endB]) + break; + /* + * don't allow matching across matching sector boundaries + */ + if ((flagsA[endA] & flagsB[endB] & 1) && endA != beginA) { + break; + } + /* + * don't allow matching through known missing data + */ + if ((flagsA[endA] & 2) || (flagsB[endB] & 2)) + break; + } + + if (ret_begin) + *ret_begin = beginA; + if (ret_end) + *ret_end = endA; + return (endA - beginA); +} + +/* Top level of the first stage matcher */ + +/* + * We match each analysis point of new to the preexisting blocks + * recursively. We can also optionally maintain a list of fragments of + * the preexisting block that didn't match anything, and match them back + * afterward. + */ +#define OVERLAP_ADJ (MIN_WORDS_OVERLAP/2-1) + +static inline long +do_const_sync(c_block *A, sort_info *B, Uchar *flagB, long posA, long posB, + long *begin, long *end, long *offset) +{ + Uchar *flagA = A->flags; + long ret = 0; + + if (flagB == NULL) + ret = i_paranoia_overlap(cv(A), iv(B), posA, posB, + cs(A), is(B), begin, end); + else if ((flagB[posB] & 2) == 0) + ret = i_paranoia_overlap2(cv(A), iv(B), flagA, flagB, posA, posB, cs(A), + is(B), begin, end); + + if (ret > MIN_WORDS_SEARCH) { + *offset = (posA + cb(A)) - (posB + ib(B)); + *begin += cb(A); + *end += cb(A); + return (ret); + } + return (0); +} + +/* + * post is w.r.t. B. in stage one, we post from old. In stage 2 we + * post from root. Begin, end, offset count from B's frame of + * reference + */ +static inline long +try_sort_sync(cdrom_paranoia *p, sort_info *A, Uchar *Aflags, c_block *B, + long post, long *begin, long *end, long *offset, + void (*callback)(long, int)) +{ + + long dynoverlap = p->dynoverlap; + sort_link *ptr = NULL; + Uchar *Bflags = B->flags; + + /* + * block flag matches 0x02 (unmatchable) + */ + if (Bflags == NULL || (Bflags[post - cb(B)] & 2) == 0) { + /* + * always try absolute offset zero first! + */ + { + long zeropos = post - ib(A); + + if (zeropos >= 0 && zeropos < is(A)) { + if (cv(B)[post - cb(B)] == iv(A)[zeropos]) { + if (do_const_sync(B, A, Aflags, + post - cb(B), zeropos, + begin, end, offset)) { + + offset_add_value(p, &(p->stage1), *offset, callback); + + return (1); + } + } + } + } + } else + return (0); + + ptr = sort_getmatch(A, post - ib(A), dynoverlap, cv(B)[post - cb(B)]); + + while (ptr) { + + if (do_const_sync(B, A, Aflags, + post - cb(B), ipos(A, ptr), + begin, end, offset)) { + offset_add_value(p, &(p->stage1), *offset, callback); + return (1); + } + ptr = sort_nextmatch(A, ptr); + } + + *begin = -1; + *end = -1; + *offset = -1; + return (0); +} + +static inline void +stage1_matched(c_block *old, c_block *new, long matchbegin, long matchend, + long matchoffset, void (*callback)(long, int)) +{ + long i; + long oldadjbegin = matchbegin - cb(old); + long oldadjend = matchend - cb(old); + long newadjbegin = matchbegin - matchoffset - cb(new); + long newadjend = matchend - matchoffset - cb(new); + + if (matchbegin - matchoffset <= cb(new) || + matchbegin <= cb(old) || + (new->flags[newadjbegin] & 1) || + (old->flags[oldadjbegin] & 1)) { + if (matchoffset) + if (callback) + (*callback) (matchbegin, PARANOIA_CB_FIXUP_EDGE); + } else if (callback) + (*callback) (matchbegin, PARANOIA_CB_FIXUP_ATOM); + + if (matchend - matchoffset >= ce(new) || + (new->flags[newadjend] & 1) || + matchend >= ce(old) || + (old->flags[oldadjend] & 1)) { + if (matchoffset) + if (callback) + (*callback) (matchend, PARANOIA_CB_FIXUP_EDGE); + } else if (callback) + (*callback) (matchend, PARANOIA_CB_FIXUP_ATOM); + + /* + * Mark the verification flags. Don't mark the first or last OVERLAP/2 + * elements so that overlapping fragments have to overlap by OVERLAP to + * actually merge. We also remove elements from the sort such that + * later sorts do not have to sift through already matched data + */ + newadjbegin += OVERLAP_ADJ; + newadjend -= OVERLAP_ADJ; + for (i = newadjbegin; i < newadjend; i++) + new->flags[i] |= 4; /* mark verified */ + + oldadjbegin += OVERLAP_ADJ; + oldadjend -= OVERLAP_ADJ; + for (i = oldadjbegin; i < oldadjend; i++) + old->flags[i] |= 4; /* mark verified */ + +} + +#define CB_NULL (void (*)(long, int))0 + +static long +i_iterate_stage1(cdrom_paranoia *p, c_block *old, c_block *new, + void (*callback)(long, int)) +{ + + long matchbegin = -1; + long matchend = -1; + long matchoffset; + + /* + * we no longer try to spread the stage one search area by dynoverlap + */ + long searchend = min(ce(old), ce(new)); + long searchbegin = max(cb(old), cb(new)); + long searchsize = searchend - searchbegin; + sort_info *i = p->sortcache; + long ret = 0; + long j; + + long tried = 0; + long matched = 0; + + if (searchsize <= 0) + return (0); + + /* + * match return values are in terms of the new vector, not old + */ + for (j = searchbegin; j < searchend; j += 23) { + if ((new->flags[j - cb(new)] & 6) == 0) { + tried++; + if (try_sort_sync(p, i, new->flags, old, j, &matchbegin, &matchend, &matchoffset, + callback) == 1) { + + matched += matchend - matchbegin; + + /* + * purely cosmetic: if we're matching zeros, + * don't use the callback because they will + * appear to be all skewed + */ + { + long jj = matchbegin - cb(old); + long end = matchend - cb(old); + + for (; jj < end; jj++) + if (cv(old)[jj] != 0) + break; + if (jj < end) { + stage1_matched(old, new, matchbegin, matchend, matchoffset, callback); + } else { + stage1_matched(old, new, matchbegin, matchend, matchoffset, CB_NULL); + } + } + ret++; + if (matchend - 1 > j) + j = matchend - 1; + } + } + } +#ifdef NOISY + fprintf(stderr, "iterate_stage1: search area=%ld[%ld-%ld] tried=%ld matched=%ld spans=%ld\n", + searchsize, searchbegin, searchend, tried, matched, ret); +#endif + + return (ret); +} + +static long +i_stage1(cdrom_paranoia *p, c_block *new, void (*callback)(long, int)) +{ + + long size = cs(new); + c_block *ptr = c_last(p); + int ret = 0; + long begin = 0; + long end; + + if (ptr) + sort_setup(p->sortcache, cv(new), &cb(new), cs(new), + cb(new), ce(new)); + + while (ptr && ptr != new) { + + if (callback) + (*callback) (cb(new), PARANOIA_CB_VERIFY); + i_iterate_stage1(p, ptr, new, callback); + + ptr = c_prev(ptr); + } + + /* + * parse the verified areas of new into v_fragments + */ + begin = 0; + while (begin < size) { + for (; begin < size; begin++) + if (new->flags[begin] & 4) + break; + for (end = begin; end < size; end++) + if ((new->flags[end] & 4) == 0) + break; + if (begin >= size) + break; + + ret++; + + new_v_fragment(p, new, cb(new) + max(0, begin - OVERLAP_ADJ), + cb(new) + min(size, end + OVERLAP_ADJ), + (end + OVERLAP_ADJ >= size && new->lastsector)); + + begin = end; + } + + return (ret); +} + +/* + * reconcile v_fragments to root buffer. Free if matched, fragment/fixup root + * if necessary + * + * do *not* match using zero posts + */ +static long +i_iterate_stage2(cdrom_paranoia *p, v_fragment *v, sync_result *r, + void (*callback)(long, int)) +{ + root_block *root = &(p->root); + long matchbegin = -1; + long matchend = -1; + long offset; + long fbv; + long fev; + +#ifdef NOISY + fprintf(stderr, "Stage 2 search: fbv=%ld fev=%ld\n", fb(v), fe(v)); +#endif + + if (min(fe(v) + p->dynoverlap, re(root)) - + max(fb(v) - p->dynoverlap, rb(root)) <= 0) + return (0); + + if (callback) + (*callback) (fb(v), PARANOIA_CB_VERIFY); + + /* + * just a bit of v; determine the correct area + */ + fbv = max(fb(v), rb(root) - p->dynoverlap); + + /* + * we want to avoid zeroes + */ + while (fbv < fe(v) && fv(v)[fbv - fb(v)] == 0) + fbv++; + if (fbv == fe(v)) + return (0); + fev = min(min(fbv + 256, re(root) + p->dynoverlap), fe(v)); + + { + /* + * spread the search area a bit. We post from root, so + * containment must strictly adhere to root + */ + long searchend = min(fev + p->dynoverlap, re(root)); + long searchbegin = max(fbv - p->dynoverlap, rb(root)); + sort_info *i = p->sortcache; + long j; + + sort_setup(i, fv(v), &fb(v), fs(v), fbv, fev); + for (j = searchbegin; j < searchend; j += 23) { + while (j < searchend && rv(root)[j - rb(root)] == 0) + j++; + if (j == searchend) + break; + + if (try_sort_sync(p, i, (Uchar *)0, rc(root), j, + &matchbegin, &matchend, &offset, callback)) { + + r->begin = matchbegin; + r->end = matchend; + r->offset = -offset; + if (offset) + if (callback) + (*callback) (r->begin, PARANOIA_CB_FIXUP_EDGE); + return (1); + } + } + } + return (0); +} + +/* + * simple test for a root vector that ends in silence + */ +static void i_silence_test(root_block *root) +{ + Int16_t *vec = rv(root); + long end = re(root) - rb(root) - 1; + long j; + + for (j = end - 1; j >= 0; j--) + if (vec[j] != 0) + break; + if (j < 0 || end - j > MIN_SILENCE_BOUNDARY) { + if (j < 0) + j = 0; + root->silenceflag = 1; + root->silencebegin = rb(root) + j; + if (root->silencebegin < root->returnedlimit) + root->silencebegin = root->returnedlimit; + } +} + +/* + * match into silence vectors at offset zero if at all possible. This + * also must be called with vectors in ascending begin order in case + * there are nonzero islands + */ +static long +i_silence_match(root_block *root, v_fragment *v, void (*callback)(long, int)) +{ + + cdrom_paranoia *p = v->p; + Int16_t *vec = fv(v); + long end = fs(v); + long begin; + long j; + + /* + * does this vector begin wet? + */ + if (end < MIN_SILENCE_BOUNDARY) + return (0); + for (j = 0; j < end; j++) + if (vec[j] != 0) + break; + if (j < MIN_SILENCE_BOUNDARY) + return (0); + j += fb(v); + + /* + * is the new silent section ahead of the end of the old + * by < p->dynoverlap? + */ + if (fb(v) >= re(root) && fb(v) - p->dynoverlap < re(root)) { + /* + * extend the zeroed area of root + * XXX dynarrays are not needed here. + */ + long addto = fb(v) + MIN_SILENCE_BOUNDARY - re(root); +/* Int16_t avec[addto];*/ +#ifdef HAVE_ALLOCA + Int16_t *avec = alloca(addto * sizeof (Int16_t)); +#else + Int16_t *avec = _pmalloc(addto * sizeof (Int16_t)); +#endif + + memset(avec, 0, sizeof (avec)); + c_append(rc(root), avec, addto); +#ifndef HAVE_ALLOCA + _pfree(avec); +#endif + } + /* + * do we have an 'effortless' overlap? + */ + begin = max(fb(v), root->silencebegin); + end = min(j, re(root)); + + if (begin < end) { + /* + * don't use it unless it will extend... + */ + if (fe(v) > re(root)) { + long voff = begin - fb(v); + + c_remove(rc(root), begin - rb(root), -1); + c_append(rc(root), vec + voff, fs(v) - voff); + } + offset_add_value(p, &p->stage2, 0, callback); + + } else { + if (j < begin) { + /* + * OK, we'll have to force it a bit as the root is + * jittered forward + */ + long voff = j - fb(v); + + /* + * don't use it unless it will extend... + */ + if (begin + fs(v) - voff > re(root)) { + c_remove(rc(root), root->silencebegin - rb(root), -1); + c_append(rc(root), vec + voff, fs(v) - voff); + } + offset_add_value(p, &p->stage2, end - begin, callback); + } else + return (0); + } + + /* + * test the new root vector for ending in silence + */ + root->silenceflag = 0; + i_silence_test(root); + + if (v->lastsector) + root->lastsector = 1; + free_v_fragment(v); + return (1); +} + +static long +i_stage2_each(root_block *root, v_fragment *v, void (*callback)(long, int)) +{ + + cdrom_paranoia *p = v->p; + long dynoverlap = p->dynoverlap / 2 * 2; + + if (!v || !v->one) + return (0); + + if (!rv(root)) { + return (0); + } else { + sync_result r; + + if (i_iterate_stage2(p, v, &r, callback)) { + + long begin = r.begin - rb(root); + long end = r.end - rb(root); + long offset = r.begin + r.offset - fb(v) - begin; + long temp; + c_block *l = NULL; + + /* + * we have a match! We don't rematch off rift, we chase + * the match all the way to both extremes doing rift + * analysis. + */ +#ifdef NOISY + fprintf(stderr, "Stage 2 match\n"); +#endif + + /* + * chase backward + * note that we don't extend back right now, only + * forward. + */ + while ((begin + offset > 0 && begin > 0)) { + long matchA = 0, + matchB = 0, + matchC = 0; + long beginL = begin + offset; + + if (l == NULL) { + Int16_t *buff = _pmalloc(fs(v) * sizeof (Int16_t)); + + l = c_alloc(buff, fb(v), fs(v)); + memcpy(buff, fv(v), fs(v) * sizeof (Int16_t)); + } + i_analyze_rift_r(rv(root), cv(l), + rs(root), cs(l), + begin - 1, beginL - 1, + &matchA, &matchB, &matchC); + +#ifdef NOISY + fprintf(stderr, "matching rootR: matchA:%ld matchB:%ld matchC:%ld\n", + matchA, matchB, matchC); +#endif + + if (matchA) { + /* + * a problem with root + */ + if (matchA > 0) { + /* + * dropped bytes; add back from v + */ + if (callback) + (*callback) (begin + rb(root) - 1, PARANOIA_CB_FIXUP_DROPPED); + if (rb(root) + begin < p->root.returnedlimit) + break; + else { + c_insert(rc(root), begin, cv(l) + beginL - matchA, + matchA); + offset -= matchA; + begin += matchA; + end += matchA; + } + } else { + /* + * duplicate bytes; drop from root + */ + if (callback) + (*callback) (begin + rb(root) - 1, PARANOIA_CB_FIXUP_DUPED); + if (rb(root) + begin + matchA < p->root.returnedlimit) + break; + else { + c_remove(rc(root), begin + matchA, -matchA); + offset -= matchA; + begin += matchA; + end += matchA; + } + } + } else if (matchB) { + /* + * a problem with the fragment + */ + if (matchB > 0) { + /* + * dropped bytes + */ + if (callback) + (*callback) (begin + rb(root) - 1, PARANOIA_CB_FIXUP_DROPPED); + c_insert(l, beginL, rv(root) + begin - matchB, + matchB); + offset += matchB; + } else { + /* + * duplicate bytes + */ + if (callback) + (*callback) (begin + rb(root) - 1, PARANOIA_CB_FIXUP_DUPED); + c_remove(l, beginL + matchB, -matchB); + offset += matchB; + } + } else if (matchC) { + /* + * Uhh... problem with both + * Set 'disagree' flags in root + */ + if (rb(root) + begin - matchC < p->root.returnedlimit) + break; + c_overwrite(rc(root), begin - matchC, + cv(l) + beginL - matchC, matchC); + + } else { + /* + * do we have a mismatch due to silence + * beginning/end case? + * in the 'chase back' case, we don't + * do anything. + * Did not determine nature of + * difficulty... report and bail + */ + /* RRR(*callback)(post,PARANOIA_CB_XXX); */ + break; + } + /* + * not the most efficient way, but it will do + * for now + */ + beginL = begin + offset; + i_paranoia_overlap(rv(root), cv(l), + begin, beginL, + rs(root), cs(l), + &begin, &end); + } + + /* + * chase forward + */ + temp = l ? cs(l) : fs(v); + while (end + offset < temp && end < rs(root)) { + long matchA = 0, + matchB = 0, + matchC = 0; + long beginL = begin + offset; + long endL = end + offset; + + if (l == NULL) { + Int16_t *buff = _pmalloc(fs(v) * sizeof (Int16_t)); + + l = c_alloc(buff, fb(v), fs(v)); + memcpy(buff, fv(v), fs(v) * sizeof (Int16_t)); + } + i_analyze_rift_f(rv(root), cv(l), + rs(root), cs(l), + end, endL, + &matchA, &matchB, &matchC); + +#ifdef NOISY + fprintf(stderr, "matching rootF: matchA:%ld matchB:%ld matchC:%ld\n", + matchA, matchB, matchC); +#endif + + if (matchA) { + /* + * a problem with root + */ + if (matchA > 0) { + /* + * dropped bytes; add back from v + */ + if (callback) + (*callback) (end + rb(root), PARANOIA_CB_FIXUP_DROPPED); + if (end + rb(root) < p->root.returnedlimit) + break; + c_insert(rc(root), end, cv(l) + endL, matchA); + } else { + /* + * duplicate bytes; drop from root + */ + if (callback) + (*callback) (end + rb(root), PARANOIA_CB_FIXUP_DUPED); + if (end + rb(root) < p->root.returnedlimit) + break; + c_remove(rc(root), end, -matchA); + } + } else if (matchB) { + /* + * a problem with the fragment + */ + if (matchB > 0) { + /* + * dropped bytes + */ + if (callback) + (*callback) (end + rb(root), PARANOIA_CB_FIXUP_DROPPED); + c_insert(l, endL, rv(root) + end, matchB); + } else { + /* + * duplicate bytes + */ + if (callback) + (*callback) (end + rb(root), PARANOIA_CB_FIXUP_DUPED); + c_remove(l, endL, -matchB); + } + } else if (matchC) { + /* + * Uhh... problem with both + * Set 'disagree' flags in root + */ + if (end + rb(root) < p->root.returnedlimit) + break; + c_overwrite(rc(root), end, cv(l) + endL, matchC); + } else { + analyze_rift_silence_f(rv(root), cv(l), + rs(root), cs(l), + end, endL, + &matchA, &matchB); + if (matchA) { + /* + * silence in root + * Can only do this if we haven't + * already returned data + */ + if (end + rb(root) >= p->root.returnedlimit) { + c_remove(rc(root), end, -1); + } + } else if (matchB) { + /* + * silence in fragment; lose it + */ + if (l) + i_cblock_destructor(l); + free_v_fragment(v); + return (1); + + } else { + /* + * Could not determine nature of + * difficulty... report and bail + */ + /* RRR(*callback)(post,PARANOIA_CB_XXX); */ + } + break; + } + /* + * not the most efficient way, but it will do for now + */ + i_paranoia_overlap(rv(root), cv(l), + begin, beginL, + rs(root), cs(l), + (long *)0, &end); + } + + /* + * if this extends our range, let's glom + */ + { + long sizeA = rs(root); + long sizeB; + long vecbegin; + Int16_t *vector; + + if (l) { + sizeB = cs(l); + vector = cv(l); + vecbegin = cb(l); + } else { + sizeB = fs(v); + vector = fv(v); + vecbegin = fb(v); + } + + if (sizeB - offset > sizeA || v->lastsector) { + if (v->lastsector) { + root->lastsector = 1; + } + if (end < sizeA) + c_remove(rc(root), end, -1); + + if (sizeB - offset - end) + c_append(rc(root), vector + end + offset, + sizeB - offset - end); + + i_silence_test(root); + + /* + * add offset into dynoverlap stats + */ + offset_add_value(p, &p->stage2, offset + vecbegin - rb(root), callback); + } + } + if (l) + i_cblock_destructor(l); + free_v_fragment(v); + return (1); + + } else { + /* + * D'oh. No match. What to do with the fragment? + */ + if (fe(v) + dynoverlap < re(root) && !root->silenceflag) { + /* + * It *should* have matched. No good; free it. + */ + free_v_fragment(v); + } + /* + * otherwise, we likely want this for an upcoming match + * we don't free the sort info (if it was collected) + */ + return (0); + + } + } +} + +static int +i_init_root(root_block *root, v_fragment *v, long begin, + void (*callback)(long, int)) +{ + if (fb(v) <= begin && fe(v) > begin) { + + root->lastsector = v->lastsector; + root->returnedlimit = begin; + + if (rv(root)) { + i_cblock_destructor(rc(root)); + rc(root) = NULL; + } + { + Int16_t *buff = _pmalloc(fs(v) * sizeof (Int16_t)); + + memcpy(buff, fv(v), fs(v) * sizeof (Int16_t)); + root->vector = c_alloc(buff, fb(v), fs(v)); + } + i_silence_test(root); + + return (1); + } else + return (0); +} + +static int vsort(const void *a, const void *b) +{ + return ((*(v_fragment **) a)->begin - (*(v_fragment **) b)->begin); +} + +static int +i_stage2(cdrom_paranoia *p, long beginword, long endword, + void (*callback)(long, int)) +{ + + int flag = 1; + int ret = 0; + root_block *root = &(p->root); + +#ifdef NOISY + fprintf(stderr, "Fragments:%ld\n", p->fragments->active); + fflush(stderr); +#endif + + /* + * even when the 'silence flag' is lit, we try to do non-silence + * matching in the event that there are still audio vectors with + * content to be sunk before the silence + */ + while (flag) { + /* + * loop through all the current fragments + */ + v_fragment *first = v_first(p); + long active = p->fragments->active, + count = 0; +#ifdef HAVE_DYN_ARRAYS + v_fragment *list[active]; +#else + v_fragment **list = _pmalloc(active * sizeof (v_fragment *)); +#endif + + while (first) { + v_fragment *next = v_next(first); + + list[count++] = first; + first = next; + } + + flag = 0; + if (count) { + /* + * sorted in ascending order of beginning + */ + qsort(list, active, sizeof (v_fragment *), vsort); + + /* + * we try a nonzero based match even if in silent mode + * in the case that there are still cached vectors to + * sink behind continent->ocean boundary + */ + for (count = 0; count < active; count++) { + first = list[count]; + if (first->one) { + if (rv(root) == NULL) { + if (i_init_root(&(p->root), first, beginword, callback)) { + free_v_fragment(first); + flag = 1; + ret++; + } + } else { + if (i_stage2_each(root, first, callback)) { + ret++; + flag = 1; + } + } + } + } + + /* + * silence handling + */ + if (!flag && p->root.silenceflag) { + for (count = 0; count < active; count++) { + first = list[count]; + if (first->one) { + if (rv(root) != NULL) { + if (i_silence_match(root, first, callback)) { + ret++; + flag = 1; + } + } + } + } + } + } +#ifndef HAVE_DYN_ARRAYS + _pfree(list); +#endif + } + return (ret); +} + +static void +i_end_case(cdrom_paranoia *p, long endword, void (*callback)(long, int)) +{ + + root_block *root = &p->root; + + /* + * have an 'end' flag; if we've just read in the last sector in a + * session, set the flag. If we verify to the end of a fragment + * which has the end flag set, we're done (set a done flag). + * Pad zeroes to the end of the read + */ + if (root->lastsector == 0) + return; + if (endword < re(root)) + return; + + { + long addto = endword - re(root); + char *temp = _pcalloc(addto, sizeof (char) * 2); + + c_append(rc(root), (void *) temp, addto); + _pfree(temp); + + /* + * trash da cache + */ + paranoia_resetcache(p); + + } +} + +/* + * We want to add a sector. Look through the caches for something that + * spans. Also look at the flags on the c_block... if this is an + * obliterated sector, get a bit of a chunk past the obliteration. + * + * Not terribly smart right now, actually. We can probably find + * *some* match with a cache block somewhere. Take it and continue it + * through the skip + */ +static void +verify_skip_case(cdrom_paranoia *p, void (*callback)(long, int)) +{ + + root_block *root = &(p->root); + c_block *graft = NULL; + int vflag = 0; + int gend = 0; + long post; + +#ifdef NOISY + fprintf(stderr, "\nskipping\n"); +#endif + + if (rv(root) == NULL) { + post = 0; + } else { + post = re(root); + } + if (post == -1) + post = 0; + + if (callback) + (*callback) (post, PARANOIA_CB_SKIP); + + if (p->enable & PARANOIA_MODE_NEVERSKIP) + return; + + /* + * We want to add a sector. Look for a c_block that spans, + * preferrably a verified area + */ + { + c_block *c = c_first(p); + + while (c) { + long cbegin = cb(c); + long cend = ce(c); + + if (cbegin <= post && cend > post) { + long vend = post; + + if (c->flags[post - cbegin] & 4) { + /* + * verified area! + */ + while (vend < cend && (c->flags[vend - cbegin] & 4)) + vend++; + if (!vflag || vend > vflag) { + graft = c; + gend = vend; + } + vflag = 1; + } else { + /* + * not a verified area + */ + if (!vflag) { + while (vend < cend && (c->flags[vend - cbegin] & 4) == 0) + vend++; + if (graft == NULL || gend > vend) { + /* + * smallest unverified area + */ + graft = c; + gend = vend; + } + } + } + } + c = c_next(c); + } + + if (graft) { + long cbegin = cb(graft); + long cend = ce(graft); + + while (gend < cend && (graft->flags[gend - cbegin] & 4)) + gend++; + gend = min(gend + OVERLAP_ADJ, cend); + + if (rv(root) == NULL) { + Int16_t *buff = _pmalloc(cs(graft)); + + memcpy(buff, cv(graft), cs(graft)); + rc(root) = c_alloc(buff, cb(graft), cs(graft)); + } else { + c_append(rc(root), cv(graft) + post - cbegin, + gend - post); + } + + root->returnedlimit = re(root); + return; + } + } + + /* + * No? Fine. Great. Write in some zeroes :-P + */ + { + void *temp = _pcalloc(CD_FRAMESIZE_RAW, sizeof (Int16_t)); + + if (rv(root) == NULL) { + rc(root) = c_alloc(temp, post, CD_FRAMESIZE_RAW); + } else { + c_append(rc(root), temp, CD_FRAMESIZE_RAW); + _pfree(temp); + } + root->returnedlimit = re(root); + } +} + +/* + * toplevel + */ +void paranoia_free(cdrom_paranoia *p) +{ + paranoia_resetall(p); + sort_free(p->sortcache); + _pfree(p); +} + +void paranoia_modeset(cdrom_paranoia *p, int enable) +{ + p->enable = enable; +} + +long paranoia_seek(cdrom_paranoia *p, long seek, int mode) +{ + long sector; + long ret; + + switch (mode) { + case SEEK_SET: + sector = seek; + break; + case SEEK_END: + sector = cdda_disc_lastsector(p->d) + seek; + break; + default: + sector = p->cursor + seek; + break; + } + + if (cdda_sector_gettrack(p->d, sector) == -1) + return (-1); + + i_cblock_destructor(p->root.vector); + p->root.vector = NULL; + p->root.lastsector = 0; + p->root.returnedlimit = 0; + + ret = p->cursor; + p->cursor = sector; + + i_paranoia_firstlast(p); + + /* + * Evil hack to fix pregap patch for NEC drives! To be rooted out in a10 + */ + p->current_firstsector = sector; + + return (ret); +} + +/* + * returns last block read, -1 on error + */ +c_block *i_read_c_block(cdrom_paranoia *p, long beginword, long endword, + void (*callback)(long, int)) +{ + /* + * why do it this way? We need to read lots of sectors to kludge + * around stupid read ahead buffers on cheap drives, as well as avoid + * expensive back-seeking. We also want to 'jiggle' the start address + * to try to break borderline drives more noticeably (and make broken + * drives with unaddressable sectors behave more often). + */ + long readat; + long firstread; + long totaltoread = p->readahead; + long sectatonce = p->nsectors; + long driftcomp = (float) p->dyndrift / CD_FRAMEWORDS + .5; + c_block *new = NULL; + root_block *root = &p->root; + Int16_t *buffer = NULL; + void *bufbase = NULL; + Uchar *flags = NULL; + long sofar; + long dynoverlap = (p->dynoverlap + CD_FRAMEWORDS - 1) / CD_FRAMEWORDS; + long anyflag = 0; + int reduce = 0; +static int pagesize = -1; +#define valign(x, a) (((char *)(x)) + ((a) - 1 - ((((UIntptr_t)(x))-1)%(a)))) + + /* + * What is the first sector to read? want some pre-buffer if we're not + * at the extreme beginning of the disc + */ + if (p->enable & (PARANOIA_MODE_VERIFY | PARANOIA_MODE_OVERLAP)) { + + /* + * we want to jitter the read alignment boundary + */ + long target; + + if (rv(root) == NULL || rb(root) > beginword) + target = p->cursor - dynoverlap; + else + target = re(root) / (CD_FRAMEWORDS) - dynoverlap; + + if (target + MIN_SECTOR_BACKUP > p->lastread && target <= p->lastread) + target = p->lastread - MIN_SECTOR_BACKUP; + + /* + * we want to jitter the read alignment boundary, as some + * drives, beginning from a specific point, will tend to + * lose bytes between sectors in the same place. Also, as + * our vectors are being made up of multiple reads, we want + * the overlap boundaries to move.... + */ + readat = (target & (~((long) JIGGLE_MODULO - 1))) + p->jitter; + if (readat > target) + readat -= JIGGLE_MODULO; + p->jitter++; + if (p->jitter >= JIGGLE_MODULO) + p->jitter = 0; + + } else { + readat = p->cursor; + } + + readat += driftcomp; + + if (p->enable & (PARANOIA_MODE_OVERLAP | PARANOIA_MODE_VERIFY)) { + flags = _pcalloc(totaltoread * CD_FRAMEWORDS, 1); + new = new_c_block(p); + recover_cache(p); + } else { + /* + * in the case of root it's just the buffer + */ + paranoia_resetall(p); + new = new_c_block(p); + } + + /* + * Do not use valloc() as valloc() in glibc is buggy and returns memory + * that cannot be passed to free(). + */ + if (pagesize < 0) { + pagesize = getpagesize(); + if (pagesize < 0) + pagesize = 4096; /* Just a guess */ + } + reduce = pagesize / CD_FRAMESIZE_RAW; + bufbase = _pmalloc(totaltoread * CD_FRAMESIZE_RAW + pagesize); + buffer = (Int16_t *)valign(bufbase, pagesize); + sofar = 0; + firstread = -1; + + /* + * actual read loop + */ + while (sofar < totaltoread) { + long secread = sectatonce; + long adjread = readat; + long thisread; + + /* + * don't under/overflow the audio session + */ + if (adjread < p->current_firstsector) { + secread -= p->current_firstsector - adjread; + adjread = p->current_firstsector; + } + if (adjread + secread - 1 > p->current_lastsector) + secread = p->current_lastsector - adjread + 1; + + if (sofar + secread > totaltoread) + secread = totaltoread - sofar; + + /* + * If we are inside the buffer, the transfers are no longer + * page aligned. Reduce the transfer size to avoid problems. + * Such problems are definitely known to appear on FreeBSD. + */ + if ((sofar > 0) && (secread > (sectatonce - reduce))) + secread = sectatonce - reduce; + + if (secread > 0) { + + if (firstread < 0) + firstread = adjread; + if ((thisread = cdda_read(p->d, buffer + sofar * CD_FRAMEWORDS, adjread, + secread)) < secread) { + + if (thisread < 0) + thisread = 0; + + /* + * Uhhh... right. Make something up. But + * don't make us seek backward! + */ + if (callback) + (*callback) ((adjread + thisread) * CD_FRAMEWORDS, PARANOIA_CB_READERR); + memset(buffer + (sofar + thisread) * CD_FRAMEWORDS, 0, + CD_FRAMESIZE_RAW * (secread - thisread)); + if (flags) + memset(flags + (sofar + thisread) * CD_FRAMEWORDS, 2, + CD_FRAMEWORDS * (secread - thisread)); + } + if (thisread != 0) + anyflag = 1; + + if (flags && sofar != 0) { + /* + * Don't verify across overlaps that are too + * close to one another + */ + int i = 0; + + for (i = -MIN_WORDS_OVERLAP / 2; i < MIN_WORDS_OVERLAP / 2; i++) + flags[sofar * CD_FRAMEWORDS + i] |= 1; + } + p->lastread = adjread + secread; + + if (adjread + secread - 1 == p->current_lastsector) + new->lastsector = -1; + + if (callback) + (*callback) ((adjread + secread - 1) * CD_FRAMEWORDS, PARANOIA_CB_READ); + + sofar += secread; + readat = adjread + secread; + } else if (readat < p->current_firstsector) { + readat += sectatonce; + /* + * due to being before the + * readable area + */ + } else { + break; /* due to being past the readable area */ + } + } + + if (anyflag) { + new->vector = _pmalloc(totaltoread * CD_FRAMESIZE_RAW); + memcpy(new->vector, buffer, totaltoread * CD_FRAMESIZE_RAW); + _pfree(bufbase); + + new->begin = firstread * CD_FRAMEWORDS - p->dyndrift; + new->size = sofar * CD_FRAMEWORDS; + new->flags = flags; + } else { + if (new) + free_c_block(new); + if (bufbase) + _pfree(bufbase); + if (flags) + _pfree(flags); + new = NULL; + bufbase = NULL; + flags = NULL; + } + return (new); +} + +/* + * The returned buffer is *not* to be freed by the caller. It will + * persist only until the next call to paranoia_read() for this p + */ +Int16_t *paranoia_read(cdrom_paranoia *p, void (*callback)(long, int)) +{ + return (paranoia_read_limited(p, callback, 20)); +} + +/* + * I added max_retry functionality this way in order to avoid breaking any + * old apps using the nerw libs. cdparanoia 9.8 will need the updated libs, + * but nothing else will require it. + */ +Int16_t *paranoia_read_limited(cdrom_paranoia *p, void (*callback)(long, int), + int max_retries) +{ + long beginword = p->cursor * (CD_FRAMEWORDS); + long endword = beginword + CD_FRAMEWORDS; + long retry_count = 0; + long lastend = -2; + root_block *root = &p->root; + + if (beginword > p->root.returnedlimit) + p->root.returnedlimit = beginword; + lastend = re(root); + + /* + * First, is the sector we want already in the root? + */ + while (rv(root) == NULL || + rb(root) > beginword || + (re(root) < endword + p->maxdynoverlap && + p->enable & (PARANOIA_MODE_VERIFY | PARANOIA_MODE_OVERLAP)) || + re(root) < endword) { + + /* + * Nope; we need to build or extend the root verified range + */ + if (p->enable & (PARANOIA_MODE_VERIFY | PARANOIA_MODE_OVERLAP)) { + i_paranoia_trim(p, beginword, endword); + recover_cache(p); + if (rb(root) != -1 && p->root.lastsector) + i_end_case(p, endword + p->maxdynoverlap, + callback); + else + i_stage2(p, beginword, + endword + p->maxdynoverlap, + callback); + } else + i_end_case(p, endword + p->maxdynoverlap, + callback); /* only trips if we're already */ + /* done */ + + if (!(rb(root) == -1 || rb(root) > beginword || + re(root) < endword + p->maxdynoverlap)) + break; + + /* + * Hmm, need more. Read another block + */ + { + c_block *new = i_read_c_block(p, beginword, endword, callback); + + if (new) { + if (p->enable & (PARANOIA_MODE_OVERLAP | PARANOIA_MODE_VERIFY)) { + + if (p->enable & PARANOIA_MODE_VERIFY) + i_stage1(p, new, callback); + else { + /* + * just make v_fragments from the + * boundary information. + */ + long begin = 0, + end = 0; + + while (begin < cs(new)) { + while (end < cs(new) && (new->flags[begin] & 1)) + begin++; + end = begin + 1; + while (end < cs(new) && (new->flags[end] & 1) == 0) + end++; + { + new_v_fragment(p, new, begin + cb(new), + end + cb(new), + (new->lastsector && cb(new) + end == ce(new))); + } + begin = end; + } + } + + } else { + + if (p->root.vector) + i_cblock_destructor(p->root.vector); + free_elem(new->e, 0); + p->root.vector = new; + + i_end_case(p, endword + p->maxdynoverlap, + callback); + + } + } + } + + /* + * Are we doing lots of retries? ********************** + * + * Check unaddressable sectors first. There's no backoff + * here; jiggle and minimum backseek handle that for us + */ + if (rb(root) != -1 && lastend + 588 < re(root)) { + /* + * If we've not grown half a sector + */ + lastend = re(root); + retry_count = 0; + } else { + /* + * increase overlap or bail + */ + retry_count++; + + /* + * The better way to do this is to look at how many + * actual matches we're getting and what kind of gap + */ + if (retry_count % 5 == 0) { + if (p->dynoverlap == p->maxdynoverlap || + retry_count == max_retries) { + verify_skip_case(p, callback); + retry_count = 0; + } else { + if (p->stage1.offpoints != -1) { /* hack */ + p->dynoverlap *= 1.5; + if (p->dynoverlap > p->maxdynoverlap) + p->dynoverlap = p->maxdynoverlap; + if (callback) + (*callback) (p->dynoverlap, PARANOIA_CB_OVERLAP); + } + } + } + } + } + p->cursor++; + + return (rv(root) + (beginword - rb(root))); +} + +/* + * a temporary hack + */ +void paranoia_overlapset(cdrom_paranoia *p, long overlap) +{ + p->dynoverlap = overlap * CD_FRAMEWORDS; + p->stage1.offpoints = -1; +} diff --git a/libparanoia/pmalloc.c b/libparanoia/pmalloc.c new file mode 100644 index 0000000..65dee97 --- /dev/null +++ b/libparanoia/pmalloc.c @@ -0,0 +1,89 @@ +/* + * 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. + * + */ + +/* @(#)pmalloc.c 1.3 04/05/15 Copyright 2004 J. Schilling */ +/* + * Paranoia malloc() functions + * + * Copyright (c) 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 <stdxlib.h> +#include <standard.h> +#include <schily.h> +#include "pmalloc.h" + +#ifdef PM_ADD_DEBUG +static int madd = 8192; +static int cadd = 8192; +static int radd = 8192; +#else +static int madd = 0; +/*static int cadd = 0;*/ +static int radd = 0; +#endif + +void _pfree(void *ptr) +{ + free(ptr); +} + +void *_pmalloc(size_t size) +{ + void *p; + + p = malloc(size + madd); + if (p == NULL) + raisecond("NO MEM", 0L); + return (p); +} + +void *_pcalloc(size_t nelem, size_t elsize) +{ + void *p; +#ifdef PM_ADD_DEBUG + size_t n = nelem * elsize; + + n += cadd; + p = calloc(1, n); +#else + p = calloc(nelem, elsize); +#endif + if (p == NULL) + raisecond("NO MEM", 0L); + return (p); +} + +void *_prealloc(void *ptr, size_t size) +{ + void *p; + + p = realloc(ptr, size + radd); + if (p == NULL) + raisecond("NO MEM", 0L); + return (p); +} diff --git a/libparanoia/pmalloc.h b/libparanoia/pmalloc.h new file mode 100644 index 0000000..f64ad2f --- /dev/null +++ b/libparanoia/pmalloc.h @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +/* @(#)pmalloc.h 1.1 04/02/20 Copyright 2004 J. Schilling */ +/* + * Paranoia malloc() functions + * + * Copyright (c) 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. + */ + +#ifndef _PMALLOC_H +#define _PMALLOC_H + +extern void _pfree(void *ptr); +extern void *_pmalloc(size_t size); +extern void *_pcalloc(size_t nelem, size_t elsize); +extern void *_prealloc(void *ptr, size_t size); + +#endif /* _PMALLOC_H */ diff --git a/librols/CMakeLists.txt b/librols/CMakeLists.txt new file mode 100644 index 0000000..9aabc7c --- /dev/null +++ b/librols/CMakeLists.txt @@ -0,0 +1,7 @@ +PROJECT (LIBROLS C) +INCLUDE_DIRECTORIES(../include ../libhfs_iso ${CMAKE_BINARY_DIR} ../wodim ${CMAKE_BINARY_DIR}/include) + +SET(LIBROLS_SRCS astoi.c astoll.c astoull.c breakline.c cmpbytes.c comerr.c error.c fexec.c fillbytes.c getargs.c getav0.c getdomainname.c geterrno.c gethostid.c gethostname.c getpagesize.c handlecond.c movebytes.c raisecond.c rename.c saveargs.c seterrno.c spawn.c strcatl.c strdup.c streql.c swabbytes.c usleep.c stdio/cvmod.c stdio/dat.c stdio/fcons.c stdio/fdown.c stdio/fdup.c stdio/ffileread.c stdio/ffilewrite.c stdio/fgetline.c stdio/file_raise.c stdio/fileclose.c stdio/fileluopen.c stdio/filemopen.c stdio/fileopen.c stdio/filepos.c stdio/fileread.c stdio/filereopen.c stdio/fileseek.c stdio/filesize.c stdio/filestat.c stdio/filewrite.c stdio/flag.c stdio/flush.c stdio/fpipe.c stdio/niread.c stdio/niwrite.c stdio/nixread.c stdio/nixwrite.c stdio/openfd.c stdio/peekc.c default.c) + +ADD_LIBRARY (rols STATIC ${CMAKE_CURRENT_SOURCE_DIR}/../include/xconfig.h ${CMAKE_CURRENT_SOURCE_DIR}/../include/align.h ${LIBROLS_SRCS}) + diff --git a/librols/astoi.c b/librols/astoi.c new file mode 100644 index 0000000..94c14a3 --- /dev/null +++ b/librols/astoi.c @@ -0,0 +1,151 @@ +/* + * 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. + * + */ + +/* @(#)astoi.c 1.8 03/06/15 Copyright 1985, 1995-2003 J. Schilling */ +/* + * astoi() converts a string to int + * astol() converts a string to long + * + * Leading tabs and spaces are ignored. + * Both return pointer to the first char that has not been used. + * Caller must check if this means a bad conversion. + * + * leading "+" is ignored + * leading "0" makes conversion octal (base 8) + * leading "0x" makes conversion hex (base 16) + * + * Copyright (c) 1985, 1995-2003 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 <standard.h> +#include <schily.h> + +#define is_space(c) ((c) == ' ' || (c) == '\t') +#define is_digit(c) ((c) >= '0' && (c) <= '9') +#define is_hex(c) (\ + ((c) >= 'a' && (c) <= 'f') || \ + ((c) >= 'A' && (c) <= 'F')) + +#define to_lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c)) + +#ifdef notdef +EXPORT int +atoi(s) + char *s; +{ + long l; + + (void) astol(s, &l); + return ((int) l); +} + +EXPORT long +atol(s) + char *s; +{ + long l; + + (void) astol(s, &l); + return (l); +} +#endif + +EXPORT char * +astoi(s, i) + const char *s; + int *i; +{ + long l; + char *ret; + + ret = astol(s, &l); + *i = l; + return (ret); +} + +EXPORT char * +astol(s, l) + register const char *s; + long *l; +{ + return (astolb(s, l, 0)); +} + +EXPORT char * +astolb(s, l, base) + register const char *s; + long *l; + register int base; +{ + int neg = 0; + register long ret = 0L; + register int digit; + register char c; + + while (is_space(*s)) + s++; + + if (*s == '+') { + s++; + } else if (*s == '-') { + s++; + neg++; + } + + if (base == 0) { + if (*s == '0') { + base = 8; + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } + } else { + base = 10; + } + } + for (; (c = *s) != 0; s++) { + + if (is_digit(c)) { + digit = c - '0'; + } else if (is_hex(c)) { + digit = to_lower(c) - 'a' + 10; + } else { + break; + } + + if (digit < base) { + ret *= base; + ret += digit; + } else { + break; + } + } + if (neg) + ret = -ret; + *l = ret; + return ((char *)s); +} diff --git a/librols/astoll.c b/librols/astoll.c new file mode 100644 index 0000000..1e35808 --- /dev/null +++ b/librols/astoll.c @@ -0,0 +1,120 @@ +/* + * 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. + * + */ + +/* @(#)astoll.c 1.3 03/06/15 Copyright 1985, 2000-2003 J. Schilling */ +/* + * astoll() converts a string to long long + * + * Leading tabs and spaces are ignored. + * Both return pointer to the first char that has not been used. + * Caller must check if this means a bad conversion. + * + * leading "+" is ignored + * leading "0" makes conversion octal (base 8) + * leading "0x" makes conversion hex (base 16) + * + * Llong is silently reverted to long if the compiler does not + * support long long. + * + * Copyright (c) 1985, 2000-2003 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 <standard.h> +#include <utypes.h> +#include <schily.h> + +#define is_space(c) ((c) == ' ' || (c) == '\t') +#define is_digit(c) ((c) >= '0' && (c) <= '9') +#define is_hex(c) (\ + ((c) >= 'a' && (c) <= 'f') || \ + ((c) >= 'A' && (c) <= 'F')) + +#define to_lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c)) + +char * +astoll(s, l) + register const char *s; + Llong *l; +{ + return (astollb(s, l, 0)); +} + +char * +astollb(s, l, base) + register const char *s; + Llong *l; + register int base; +{ + int neg = 0; + register Llong ret = (Llong)0; + register int digit; + register char c; + + while (is_space(*s)) + s++; + + if (*s == '+') { + s++; + } else if (*s == '-') { + s++; + neg++; + } + + if (base == 0) { + if (*s == '0') { + base = 8; + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } + } else { + base = 10; + } + } + for (; (c = *s) != 0; s++) { + + if (is_digit(c)) { + digit = c - '0'; + } else if (is_hex(c)) { + digit = to_lower(c) - 'a' + 10; + } else { + break; + } + + if (digit < base) { + ret *= base; + ret += digit; + } else { + break; + } + } + if (neg) + ret = -ret; + *l = ret; + return ((char *)s); +} diff --git a/librols/astoull.c b/librols/astoull.c new file mode 100644 index 0000000..6ab6920 --- /dev/null +++ b/librols/astoull.c @@ -0,0 +1,182 @@ +/* + * 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. + * + */ + +/* @(#)astoll.c 1.3 03/06/15 Copyright 1985, 2000-2005 J. Schilling */ +/* + * astoll() converts a string to long long + * + * Leading tabs and spaces are ignored. + * Both return pointer to the first char that has not been used. + * Caller must check if this means a bad conversion. + * + * leading "+" is ignored + * leading "0" makes conversion octal (base 8) + * leading "0x" makes conversion hex (base 16) + * + * Llong is silently reverted to long if the compiler does not + * support long long. + * + * Copyright (c) 1985, 2000-2005 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 <standard.h> +#include <utypes.h> +#include <schily.h> +#include <errno.h> +#ifndef HAVE_ERRNO_DEF +extern int errno; +#endif + +#define is_space(c) ((c) == ' ' || (c) == '\t') +#define is_digit(c) ((c) >= '0' && (c) <= '9') +#define is_hex(c) (\ + ((c) >= 'a' && (c) <= 'f') || \ + ((c) >= 'A' && (c) <= 'F')) + +#define is_lower(c) ((c) >= 'a' && (c) <= 'z') +#define is_upper(c) ((c) >= 'A' && (c) <= 'Z') +#define to_lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c)) + +#if ('i' + 1) < 'j' +#define BASE_MAX ('i' - 'a' + 10 + 1) /* This is EBCDIC */ +#else +#define BASE_MAX ('z' - 'a' + 10 + 1) /* This is ASCII */ +#endif + + + +EXPORT char *astoull __PR((const char *s, Ullong *l)); +EXPORT char *astoullb __PR((const char *s, Ullong *l, int base)); + +EXPORT char * +astoull(s, l) + register const char *s; + Ullong *l; +{ + return (astoullb(s, l, 0)); +} + +EXPORT char * +astoullb(s, l, base) + register const char *s; + Ullong *l; + register int base; +{ +#ifdef DO_SIGNED + int neg = 0; +#endif + register Ullong ret = (Ullong)0; + Ullong maxmult; + register int digit; + register char c; + + if (base > BASE_MAX || base == 1 || base < 0) { + errno = EINVAL; + return ((char *)s); + } + + while (is_space(*s)) + s++; + + if (*s == '+') { + s++; + } else if (*s == '-') { +#ifndef DO_SIGNED + errno = EINVAL; + return ((char *)s); +#else + s++; + neg++; +#endif + } + + if (base == 0) { + if (*s == '0') { + base = 8; + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } + } else { + base = 10; + } + } + maxmult = TYPE_MAXVAL(Ullong) / base; + for (; (c = *s) != 0; s++) { + + if (is_digit(c)) { + digit = c - '0'; +#ifdef OLD + } else if (is_hex(c)) { + digit = to_lower(c) - 'a' + 10; +#else + } else if (is_lower(c)) { + digit = c - 'a' + 10; + } else if (is_upper(c)) { + digit = c - 'A' + 10; +#endif + } else { + break; + } + + if (digit < base) { + if (ret > maxmult) + goto overflow; + ret *= base; + if (TYPE_MAXVAL(Ullong) - ret < digit) + goto overflow; + ret += digit; + } else { + break; + } + } +#ifdef DO_SIGNED + if (neg) + ret = -ret; +#endif + *l = ret; + return ((char *)s); +overflow: + for (; (c = *s) != 0; s++) { + + if (is_digit(c)) { + digit = c - '0'; + } else if (is_lower(c)) { + digit = c - 'a' + 10; + } else if (is_upper(c)) { + digit = c - 'A' + 10; + } else { + break; + } + if (digit >= base) + break; + } + *l = TYPE_MAXVAL(Ullong); + errno = ERANGE; + return ((char *)s); +} diff --git a/librols/breakline.c b/librols/breakline.c new file mode 100644 index 0000000..fe0ab9a --- /dev/null +++ b/librols/breakline.c @@ -0,0 +1,77 @@ +/* + * 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. + * + */ + +/* @(#)breakline.c 1.10 04/09/25 Copyright 1985, 1995-2003 J. Schilling */ +/* + * break a line pointed to by *buf into fields + * returns the number of tokens, the line was broken into (>= 1) + * + * delim is the delimiter to break at + * array[0 .. found-1] point to strings from broken line + * array[found ... len] point to '\0' + * len is the size of the array + * + * Copyright (c) 1985, 1995-2003 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 <standard.h> +#include <schily.h> + +#ifdef PROTOTYPES +EXPORT int +breakline(char *buf, + register char delim, + register char *array[], + register int len) +#else +EXPORT int +breakline(buf, delim, array, len) + char *buf; + register char delim; + register char *array[]; + register int len; +#endif +{ + register char *bp = buf; + register char *dp; + register int i; + register int found; + + for (i = 0, found = 1; i < len; i++) { + for (dp = bp; *dp != '\0' && *dp != delim; dp++) + /* LINTED */ + ; + + array[i] = bp; + if (*dp == delim) { + *dp++ = '\0'; + found++; + } + bp = dp; + } + return (found); +} diff --git a/librols/cmpbytes.c b/librols/cmpbytes.c new file mode 100644 index 0000000..360635f --- /dev/null +++ b/librols/cmpbytes.c @@ -0,0 +1,122 @@ +/* + * 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. + * + */ + +/* @(#)cmpbytes.c 1.15 03/06/15 Copyright 1988, 1995-2003 J. Schilling */ +/* + * compare data + * + * Copyright (c) 1988, 1995-2003 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 <standard.h> +#include <align.h> +#include <schily.h> + +#define DO8(a) a; a; a; a; a; a; a; a; + +EXPORT int +cmpbytes(fromp, top, cnt) + const void *fromp; + const void *top; + int cnt; +{ + register const char *from = (char *)fromp; + register const char *to = (char *)top; + register int n; + register int i; + + /* + * If we change cnt to be unsigned, check for == instead of <= + */ + if ((n = cnt) <= 0) + return (cnt); + + /* + * Compare byte-wise until properly aligned for a long pointer. + */ + i = sizeof (long) - 1; + while (--n >= 0 && --i >= 0 && !l2aligned(from, to)) { + if (*to++ != *from++) + goto cdiff; + } + n++; + + if (n >= (int)(8 * sizeof (long))) { + if (l2aligned(from, to)) { + register const long *froml = (const long *)from; + register const long *tol = (const long *)to; + register int rem = n % (8 * sizeof (long)); + + n /= (8 * sizeof (long)); + do { + DO8( + if (*tol++ != *froml++) + break; + ); + } while (--n > 0); + + if (n > 0) { + --froml; + --tol; + to = (const char *)tol; + from = (const char *)froml; + goto ldiff; + } + to = (const char *)tol; + from = (const char *)froml; + n = rem; + } + + if (n >= 8) { + n -= 8; + do { + DO8( + if (*to++ != *from++) + goto cdiff; + ); + } while ((n -= 8) >= 0); + n += 8; + } + if (n > 0) do { + if (*to++ != *from++) + goto cdiff; + } while (--n > 0); + return (cnt); + } + if (n > 0) do { + if (*to++ != *from++) + goto cdiff; + } while (--n > 0); + return (cnt); +ldiff: + n = sizeof (long); + do { + if (*to++ != *from++) + goto cdiff; + } while (--n > 0); +cdiff: + return (--from - (char *)fromp); +} diff --git a/librols/comerr.c b/librols/comerr.c new file mode 100644 index 0000000..7100fef --- /dev/null +++ b/librols/comerr.c @@ -0,0 +1,268 @@ +/* + * 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. + * + */ + +/* @(#)comerr.c 1.29 03/06/15 Copyright 1985-1989, 1995-2003 J. Schilling */ +/* + * Routines for printing command errors + * + * Copyright (c) 1985-1989, 1995-2003 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 <unixstd.h> /* include <sys/types.h> try to get size_t */ +#include <stdio.h> /* Try again for size_t */ +#include <stdxlib.h> /* Try again for size_t */ +#include <standard.h> +#include <vadefs.h> +#include <strdefs.h> +#include <schily.h> +#include <errno.h> +#ifndef HAVE_STRERROR +extern char *sys_errlist[]; +extern int sys_nerr; +#endif + +EXPORT int on_comerr __PR((void (*fun)(int, void *), void *arg)); +EXPORT void comerr __PR((const char *, ...)); +EXPORT void comerrno __PR((int, const char *, ...)); +EXPORT int errmsg __PR((const char *, ...)); +EXPORT int errmsgno __PR((int, const char *, ...)); +LOCAL int _comerr __PR((int, int, const char *, va_list)); +EXPORT void comexit __PR((int)); +EXPORT char *errmsgstr __PR((int)); + +typedef struct ex { + struct ex *next; + void (*func) __PR((int, void *)); + void *arg; +} ex_t; + +LOCAL ex_t *exfuncs; + +EXPORT int +on_comerr(func, arg) + void (*func) __PR((int, void *)); + void *arg; +{ + ex_t *fp; + + fp = malloc(sizeof (*fp)); + if (fp == NULL) + return (-1); + + fp->func = func; + fp->arg = arg; + fp->next = exfuncs; + exfuncs = fp; + return (0); +} + +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT void +comerr(const char *msg, ...) +#else +EXPORT void +comerr(msg, va_alist) + char *msg; + va_dcl +#endif +{ + va_list args; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + (void) _comerr(TRUE, geterrno(), msg, args); + /* NOTREACHED */ + va_end(args); +} + +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT void +comerrno(int err, const char *msg, ...) +#else +EXPORT void +comerrno(err, msg, va_alist) + int err; + char *msg; + va_dcl +#endif +{ + va_list args; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + (void) _comerr(TRUE, err, msg, args); + /* NOTREACHED */ + va_end(args); +} + +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +errmsg(const char *msg, ...) +#else +EXPORT int +errmsg(msg, va_alist) + char *msg; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + ret = _comerr(FALSE, geterrno(), msg, args); + va_end(args); + return (ret); +} + +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT int +errmsgno(int err, const char *msg, ...) +#else +EXPORT int +errmsgno(err, msg, va_alist) + int err; + char *msg; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, msg); +#else + va_start(args); +#endif + ret = _comerr(FALSE, err, msg, args); + va_end(args); + return (ret); +} + +#ifdef __BEOS__ + /* + * On BeOS errno is a big negative number (0x80000000 + small number). + * We assume that small negative numbers are safe to be used as special + * values that prevent printing the errno text. + * + * We tried to use #if EIO < 0 but this does not work because EIO is + * defined to a enum. ENODEV may work as ENODEV is defined to a number + * directly. + */ +#define silent_schily_error(e) ((e) < 0 && (e) >= -1024) +#else + /* + * On UNIX errno is a small non-negative number, so we assume that + * negative values cannot be a valid errno and don't print the error + * string in this case. However the value may still be used as exit() + * code if 'exflg' is set. + */ +#define silent_schily_error(e) ((e) < 0) +#endif +LOCAL int +_comerr(exflg, err, msg, args) + int exflg; + int err; + const char *msg; + va_list args; +{ + char errbuf[20]; + char *errnam; + char *prognam = get_progname(); + + if (silent_schily_error(err)) { + fprintf(stderr, "%s: ", prognam); + vfprintf(stderr, msg, args); + } else { + errnam = errmsgstr(err); + if (errnam == NULL) { + (void) snprintf(errbuf, sizeof (errbuf), + "Error %d", err); + errnam = errbuf; + } + fprintf(stderr, "%s: %s. ", prognam, errnam); + vfprintf(stderr, msg, args); + } + if (exflg) { + comexit(err); + /* NOTREACHED */ + } + return (err); +} + +EXPORT void +comexit(err) + int err; +{ + while (exfuncs) { + (*exfuncs->func)(err, exfuncs->arg); + exfuncs = exfuncs->next; + } + exit(err); + /* NOTREACHED */ +} + +EXPORT char * +errmsgstr(err) + int err; +{ +#ifdef HAVE_STRERROR + /* + * POSIX compliance may look strange... + */ + int errsav = geterrno(); + char *ret; + + seterrno(0); + ret = strerror(err); + err = geterrno(); + seterrno(errsav); + + if (ret == NULL || err) + return (NULL); + return (ret); +#else + if (err < 0 || err >= sys_nerr) { + return (NULL); + } else { + return (sys_errlist[err]); + } +#endif +} diff --git a/librols/default.c b/librols/default.c new file mode 100644 index 0000000..10878c3 --- /dev/null +++ b/librols/default.c @@ -0,0 +1,179 @@ +/* + * Copyright 2006 Eduard Bloch + * + * Uses my config parser code and small wrappers to provide the old interface. + * + */ +/* + * 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 <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +enum parstate { + KEYBEGINSEARCH, + KEYCOMPARE, + EQSIGNSEARCH, + VALBEGINSEARCH, + LASTCHARSEARCH +}; + +#define GETVAL_BUF_LEN 512 +#define isUspace(x) isspace( (int) (unsigned char) x) + +static FILE *glob_cfg_ptr = NULL; + +/* + * Warning, uses static line buffer, not reentrant. NULL returned if the key isn't found. + */ +static char *get_value(FILE *srcfile, const char *key, int dorewind) { + static char linebuf[GETVAL_BUF_LEN]; + + if(!srcfile) + return ((char *) NULL); + + if(dorewind) + rewind(srcfile); + + if(!key) + return NULL; + +next_line: + while(fgets(linebuf, sizeof(linebuf)-1, srcfile)) { + int i; + int keybeg=0; + int s=KEYBEGINSEARCH; + char *ret=NULL; + int lastchar=0; + + /* simple state machine, char position moved by the states (or not), + * state change is done by the state (or not) */ + for( i=0 ; i<sizeof(linebuf) ; ) { + /* printf("key: %s, %s, s: %d\n", key, linebuf, s); */ + switch(s) { + case(KEYBEGINSEARCH): + { + if(isUspace(linebuf[i])) + i++; + else if(linebuf[i] == '#' || linebuf[i]=='\0') + goto next_line; + else { + s=KEYCOMPARE; + keybeg=i; + } + } + break; + case(KEYCOMPARE): /* compare the key */ + { + if(key[i-keybeg]=='\0') + /* end of key, next state decides what to do on this position */ + s=EQSIGNSEARCH; + else { + if(linebuf[i-keybeg]!=key[i-keybeg]) + goto next_line; + else + i++; + } + } + break; + case(EQSIGNSEARCH): /* skip whitespace, stop on =, break on anything else */ + { + if(isUspace(linebuf[i])) + i++; + else if(linebuf[i]=='=') { + s=VALBEGINSEARCH; + i++; + } + else + goto next_line; + } + break; + case(VALBEGINSEARCH): + { + if(isUspace(linebuf[i])) + i++; + else { + /* possible at EOF */ + if(linebuf[i] == '\0') + return NULL; + + lastchar=i-1; /* lastchar can be a space, see below */ + ret= & linebuf[i]; + s=LASTCHARSEARCH; + } + } + break; + case(LASTCHARSEARCH): + { + if(linebuf[i]) { + if(!isUspace(linebuf[i])) + lastchar=i; + } + else { /* got string end, terminate after the last seen char */ + if(linebuf+lastchar < ret) /* no non-space found */ + return NULL; + linebuf[lastchar+1]='\0'; + return ret; + } + i++; + } + break; + } + } + } + return NULL; +} + +int cfg_open(const char *name) +{ + if(glob_cfg_ptr) { + fclose(glob_cfg_ptr); + glob_cfg_ptr=NULL; + } + if(!name) { + glob_cfg_ptr=NULL; + return 0; + } + glob_cfg_ptr = fopen(name, "r"); + return (glob_cfg_ptr ? 0 : -1); +} + +int cfg_close() +{ + int r; + if(!glob_cfg_ptr) + return 0; + r=fclose(glob_cfg_ptr); + glob_cfg_ptr=NULL; + return r; +} + +void cfg_restart() +{ + get_value(glob_cfg_ptr, NULL, 1); +} + +char *cfg_get(const char *key) +{ + return get_value(glob_cfg_ptr, key, 1); +} + +char *cfg_get_next(const char *key) +{ + return get_value(glob_cfg_ptr, key, 0); +} diff --git a/librols/error.c b/librols/error.c new file mode 100644 index 0000000..d0f1e12 --- /dev/null +++ b/librols/error.c @@ -0,0 +1,62 @@ +/* + * 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. + * + */ + +/* @(#)error.c 1.13 03/06/15 Copyright 1985, 1989, 1995-2003 J. Schilling */ +/* + * fprintf() on standard error stdio stream + * + * Copyright (c) 1985, 1989, 1995-2003 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 <vadefs.h> +#include <schily.h> + +/* VARARGS1 */ +#ifdef PROTOTYPES +EXPORT int +schily_error(const char *fmt, ...) +#else +EXPORT int +schily_error(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + ret = vfprintf(stderr, fmt, args); + va_end(args); + return (ret); +} diff --git a/librols/fexec.c b/librols/fexec.c new file mode 100644 index 0000000..9136402 --- /dev/null +++ b/librols/fexec.c @@ -0,0 +1,421 @@ +/* + * 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. + * + */ + +/* @(#)fexec.c 1.24 04/06/06 Copyright 1985, 1995-2004 J. Schilling */ +/* + * Execute a program with stdio redirection + * + * Copyright (c) 1985, 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> +#define rols_fexecl __nothing_1_ /* prototype in schily.h is wrong */ +#define rols_fexecle __nothing_2_ /* prototype in schily.h is wrong */ +#include <schily.h> +#undef rols_fexecl +#undef rols_fexecle + int rols_fexecl __PR((const char *, FILE *, FILE *, FILE *, ...)); + int rols_fexecle __PR((const char *, FILE *, FILE *, FILE *, ...)); +#include <unixstd.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <vadefs.h> + +#ifdef JOS +# include <error.h> +#else +# include <errno.h> +#endif +#include <fctldefs.h> +#include <dirdefs.h> +#include <maxpath.h> + +#define MAX_F_ARGS 16 + +extern char **environ; + +LOCAL void fdcopy __PR((int, int)); +LOCAL void fdmove __PR((int, int)); +LOCAL const char *chkname __PR((const char *, const char *)); +LOCAL const char *getpath __PR((char * const *)); + +#ifdef PROTOTYPES +EXPORT int +rols_fexecl(const char *name, FILE *in, FILE *out, FILE *err, ...) +#else +EXPORT int +rols_fexecl(name, in, out, err, va_alist) + char *name; + FILE *in; + FILE *out; + FILE *err; + va_dcl +#endif +{ + va_list args; + int ac = 0; + char *xav[MAX_F_ARGS]; + char **av; + char **pav; + char *p; + int ret; + +#ifdef PROTOTYPES + va_start(args, err); +#else + va_start(args); +#endif + while (va_arg(args, char *) != NULL) + ac++; + va_end(args); + + if (ac < MAX_F_ARGS) { + pav = av = xav; + } else { + pav = av = (char **)malloc((ac+1)*sizeof (char *)); + if (av == 0) + return (-1); + } + +#ifdef PROTOTYPES + va_start(args, err); +#else + va_start(args); +#endif + do { + p = va_arg(args, char *); + *pav++ = p; + } while (p != NULL); + va_end(args); + + ret = rols_fexecv(name, in, out, err, ac, av); + if (av != xav) + free(av); + return (ret); +} + +#ifdef PROTOTYPES +EXPORT int +rols_fexecle(const char *name, FILE *in, FILE *out, FILE *err, ...) +#else +EXPORT int +rols_fexecle(name, in, out, err, va_alist) + char *name; + FILE *in; + FILE *out; + FILE *err; + va_dcl +#endif +{ + va_list args; + int ac = 0; + char *xav[MAX_F_ARGS]; + char **av; + char **pav; + char *p; + char **env; + int ret; + +#ifdef PROTOTYPES + va_start(args, err); +#else + va_start(args); +#endif + while (va_arg(args, char *) != NULL) + ac++; + env = va_arg(args, char **); + va_end(args); + + if (ac < MAX_F_ARGS) { + pav = av = xav; + } else { + pav = av = (char **)malloc((ac+1)*sizeof (char *)); + if (av == 0) + return (-1); + } + +#ifdef PROTOTYPES + va_start(args, err); +#else + va_start(args); +#endif + do { + p = va_arg(args, char *); + *pav++ = p; + } while (p != NULL); + va_end(args); + + ret = rols_fexecve(name, in, out, err, av, env); + if (av != xav) + free(av); + return (ret); +} + +EXPORT int +rols_fexecv(name, in, out, err, ac, av) + const char *name; + FILE *in, *out, *err; + int ac; + char *av[]; +{ + av[ac] = NULL; /* force list to be null terminated */ + return (rols_fexecve(name, in, out, err, av, environ)); +} + +EXPORT int +rols_fexecve(name, in, out, err, av, env) + const char *name; + FILE *in, *out, *err; + char * const av[], * const env[]; +{ + char nbuf[MAXPATHNAME+1]; + char *np; + const char *path; + int ret; + int fin; + int fout; + int ferr; +#ifndef JOS + int o[3]; + int f[3]; + int errsav; + + o[0] = o[1] = o[2] = f[0] = f[1] = f[2] = 0; +#endif + + fflush(out); + fflush(err); + fin = fdown(in); + fout = fdown(out); + ferr = fdown(err); +#ifdef JOS + + /* + * If name contains a pathdelimiter ('/' on unix) + * or name is too long ... + * try exec without path search. + */ + if (find('/', name) || strlen(name) > MAXFILENAME) { + ret = exec_env(name, fin, fout, ferr, av, env); + + } else if ((path = getpath(env)) == NULL) { + ret = exec_env(name, fin, fout, ferr, av, env); + if ((ret == ENOFILE) && strlen(name) <= (sizeof (nbuf) - 6)) { + strcatl(nbuf, "/bin/", name, (char *)NULL); + ret = exec_env(nbuf, fin, fout, ferr, av, env); + if (ret == EMISSDIR) + ret = ENOFILE; + } + } else { + int nlen = strlen(name); + + for (;;) { + np = nbuf; + /* + * JOS always uses ':' as PATH Environ separator + */ + while (*path != ':' && *path != '\0' && + np < &nbuf[MAXPATHNAME-nlen-2]) { + + *np++ = *path++; + } + *np = '\0'; + if (*nbuf == '\0') + strcatl(nbuf, name, (char *)NULL); + else + strcatl(nbuf, nbuf, "/", name, (char *)NULL); + ret = exec_env(nbuf, fin, fout, ferr, av, env); + if (ret == EMISSDIR) + ret = ENOFILE; + if (ret != ENOFILE || *path == '\0') + break; + path++; + } + } + return (ret); + +#else /* JOS */ + + if (fin != 0) { + f[0] = fcntl(0, F_GETFD, 0); + o[0] = dup(0); + fcntl(o[0], F_SETFD, 1); + fdcopy(fin, 0); + } + if (fout != 1) { + f[1] = fcntl(1, F_GETFD, 0); + o[1] = dup(1); + fcntl(o[1], F_SETFD, 1); + fdcopy(fout, 1); + } + if (ferr != 2) { + f[2] = fcntl(2, F_GETFD, 0); + o[2] = dup(2); + fcntl(o[2], F_SETFD, 1); + fdcopy(ferr, 2); + } + if (fin != 0) + close(fin); + if (fout != 1) + close(fout); + if (ferr != 2) + close(ferr); + + /* + * If name contains a pathdelimiter ('/' on unix) + * or name is too long ... + * try exec without path search. + */ +#ifdef FOUND_MAXFILENAME + if (strchr(name, '/') || strlen(name) > (unsigned)MAXFILENAME) { +#else + if (strchr(name, '/')) { +#endif + ret = execve(name, av, env); + + } else if ((path = getpath(env)) == NULL) { + ret = execve(name, av, env); + if ((geterrno() == ENOENT) && strlen(name) <= (sizeof (nbuf) - 6)) { + strcatl(nbuf, "/bin/", name, (char *)NULL); + ret = execve(nbuf, av, env); + } + } else { + int nlen = strlen(name); + + for (;;) { + np = nbuf; + while (*path != PATH_ENV_DELIM && *path != '\0' && + np < &nbuf[MAXPATHNAME-nlen-2]) { + + *np++ = *path++; + } + *np = '\0'; + if (*nbuf == '\0') + strcatl(nbuf, name, (char *)NULL); + else + strcatl(nbuf, nbuf, "/", name, (char *)NULL); + ret = execve(nbuf, av, env); + if (geterrno() != ENOENT || *path == '\0') + break; + path++; + } + } + errsav = geterrno(); + /* reestablish old files */ + if (ferr != 2) { + fdmove(2, ferr); + fdmove(o[2], 2); + if (f[2] == 0) + fcntl(2, F_SETFD, 0); + } + if (fout != 1) { + fdmove(1, fout); + fdmove(o[1], 1); + if (f[1] == 0) + fcntl(1, F_SETFD, 0); + } + if (fin != 0) { + fdmove(0, fin); + fdmove(o[0], 0); + if (f[0] == 0) + fcntl(0, F_SETFD, 0); + } + seterrno(errsav); + return (ret); + +#endif /* JOS */ +} + +#ifndef JOS + +LOCAL void +fdcopy(fd1, fd2) + int fd1; + int fd2; +{ + close(fd2); + fcntl(fd1, F_DUPFD, fd2); +} + +LOCAL void +fdmove(fd1, fd2) + int fd1; + int fd2; +{ + fdcopy(fd1, fd2); + close(fd1); +} + +#endif + +/*---------------------------------------------------------------------------- +| +| get PATH from env +| ++----------------------------------------------------------------------------*/ + +LOCAL const char * +getpath(env) + char * const *env; +{ + char * const *p = env; + const char *p2; + + if (p != NULL) { + while (*p != NULL) { + if ((p2 = chkname("PATH", *p)) != NULL) + return (p2); + p++; + } + } + return (NULL); +} + + +/*---------------------------------------------------------------------------- +| +| Check if name is in environment. +| Return pointer to value name is found. +| ++----------------------------------------------------------------------------*/ + +LOCAL const char * +chkname(name, ev) + const char *name; + const char *ev; +{ + for (;;) { + if (*name != *ev) { + if (*ev == '=' && *name == '\0') + return (++ev); + return (NULL); + } + name++; + ev++; + } +} diff --git a/librols/fillbytes.c b/librols/fillbytes.c new file mode 100644 index 0000000..8d500e9 --- /dev/null +++ b/librols/fillbytes.c @@ -0,0 +1,110 @@ +/* + * 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. + * + */ + +/* @(#)fillbytes.c 1.13 03/06/15 Copyright 1987, 1995-2003 J. Schilling */ +/* + * fill memory with data + * + * Copyright (c) 1987, 1995-2003 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 <standard.h> +#include <align.h> +#include <schily.h> + +#define DO8(a) a; a; a; a; a; a; a; a; + +#define cval ((char) lval) + +#ifdef PROTOTYPES +EXPORT char * +fillbytes(void *tov, int cnt, char val) +#else +EXPORT char * +fillbytes(tov, cnt, val) + void *tov; + int cnt; + char val; +#endif +{ + register char *to = (char *)tov; + register int n; + register long lval; + + /* + * If we change cnt to be unsigned, check for == instead of <= + */ + if ((n = cnt) <= 0) + return (to); + + lval = val & 0xFF; + + /* + * Assign byte-wise until properly aligned for a long pointer. + */ + while (--n >= 0 && !laligned(to)) { + *to++ = cval; + } + n++; + + if (n >= (int)(8 * sizeof (long))) { + register int rem = n % (8 * sizeof (long)); + + lval |= (lval<<8); + lval |= (lval<<16); +#if SIZE_LONG > SIZE_INT + lval |= (lval<<32); +#endif + + n /= (8 * sizeof (long)); + { + register long *tol = (long *)to; + + do { + DO8 (*tol++ = lval); + } while (--n > 0); + + to = (char *)tol; + } + n = rem; + + if (n >= 8) { + n -= 8; + do { + DO8 (*to++ = cval); + } while ((n -= 8) >= 0); + n += 8; + } + if (n > 0) do { + *to++ = cval; + } while (--n > 0); + return (to); + } + if (n > 0) do { + *to++ = cval; + } while (--n > 0); + return (to); +} diff --git a/librols/findbytes.c b/librols/findbytes.c new file mode 100644 index 0000000..0b56597 --- /dev/null +++ b/librols/findbytes.c @@ -0,0 +1,164 @@ +/* + * 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. + * + */ + +/* @(#)findbytes.c 1.2 03/06/15 Copyright 2000-2003 J. Schilling */ +/* + * Find a byte with specific value in memory. + * + * Copyright (c) 2000-2003 J. Schilling + * + * Based on a strlen() idea from Torbjorn Granlund (tege@sics.se) and + * Dan Sahlin (dan@sics.se) and the memchr() suggestion + * from Dick Karpinski (dick@cca.ucsf.edu). + */ +/* + * 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 <stdxlib.h> +#include <utypes.h> +#include <align.h> +#include <standard.h> +#include <strdefs.h> +#include <schily.h> + +#ifdef PROTOTYPES +EXPORT char * +findbytes(const void *vp, int cnt, char val) +#else +EXPORT char * +findbytes(vp, cnt, val) + const void *vp; + register int cnt; + char val; +#endif +{ + register Uchar uval = (Uchar)val; + register const Uchar *cp = (Uchar *)vp; + register const Ulong *lp; + register Ulong lval; + register Ulong lmask; + register Ulong magic_mask; + + /* + * Test byte-wise until cp is properly aligned for a long pointer. + */ + while (--cnt >= 0 && !laligned(cp)) { + if (*cp++ == uval) + return ((char *)--cp); + } + cnt++; + + /* + * The magic mask is a long word where all carry bits a clear. + * This are bits 8, 16, 24 ... + * In addition, the top bit is not set (e.g bit 31 or 63). The magic + * mask will look this way: + * + * bits: 01111110 11111110 ... 11111110 11111111 + * bytes: AAAAAAAA BBBBBBBB ... CCCCCCCC DDDDDDDD + * + * If we add anything to this magic number, no carry bit will change if + * it is the first carry bit left to a 0 byte. Adding anything != 0 + * to the magic number will just turn the carry bit left to the byte + * but does not propagate any further. + */ +#if SIZE_LONG == 4 + magic_mask = 0x7EFEFEFFL; +#else +#if SIZE_LONG == 8 + magic_mask = 0x7EFEFEFEFEFEFEFFL; +#else + /* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defines. And that's what we want. + */ + error SIZE_LONG has unknown value +#endif +#endif + + lmask = val & 0xFF; + lmask |= lmask << 8; + lmask |= lmask << 16; +#if SIZE_LONG > 4 + lmask |= lmask << 32; +#endif +#if SIZE_LONG > 8 + error SIZE_LONG has unknown value +#endif + for (lp = (const Ulong *)cp; cnt >= sizeof (long); cnt -= sizeof (long)) { + /* + * We are not looking for 0 bytes so we need to xor with the + * long mask of repeated bytes. If any of the bytes matches our + * wanted char, we will create a 0 byte in the current long. + * But how will we find if at least one byte in a long is zero? + * + * If we add 'magic_mask' and any of the holes in the magic + * mask do not change, we most likely found a 0 byte in the + * long word. It is only a most likely match because if bits + * 24..30 (ot bits 56..62) are 0 but bit 31 (or bit 63) is set + * we will believe that we found a match but there is none. + * This will happen if there is 0x80nnnnnn / 0x80nnnnnnnnnnnnnn + */ + lval = (*lp++ ^ lmask); /* create 0 byte on match */ + lval = (lval + magic_mask) ^ ~lval; /* set bits unchanged by +*/ + if ((lval & ~magic_mask) != 0) { /* a magic hole was set */ + /* + * If any of the hole bits did not change by addition, + * we most likely had a match. + * If this was a correct match, find the matching byte. + */ + cp = (const Uchar *)(lp - 1); + + if (cp[0] == uval) + return ((char *)cp); + if (cp[1] == uval) + return ((char *)&cp[1]); + if (cp[2] == uval) + return ((char *)&cp[2]); + if (cp[3] == uval) + return ((char *)&cp[3]); +#if SIZE_LONG > 4 + if (cp[4] == uval) + return ((char *)&cp[4]); + if (cp[5] == uval) + return ((char *)&cp[5]); + if (cp[6] == uval) + return ((char *)&cp[6]); + if (cp[7] == uval) + return ((char *)&cp[7]); +#endif +#if SIZE_LONG > 8 + error SIZE_LONG has unknown value +#endif + } + } + + for (cp = (const Uchar *)lp; --cnt >= 0; ) { + if (*cp++ == uval) + return ((char *)--cp); + } + return ((char *)NULL); +} diff --git a/librols/getargs.c b/librols/getargs.c new file mode 100644 index 0000000..76f1a88 --- /dev/null +++ b/librols/getargs.c @@ -0,0 +1,838 @@ +/* + * 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. + * + */ + +/* @(#)getargs.c 2.37 04/09/25 Copyright 1985, 1988, 1994-2003 J. Schilling */ +#define NEW +/* + * Copyright (c) 1985, 1988, 1994-2003 J. Schilling + * + * 1.3.88 Start implementation of release 2 + */ +/* + * Parse arguments on a command line. + * Format string type specifier (appearing directly after flag name): + * '' BOOL + * '!' BOOL with size modifier +++ NEU +++ (XXX nicht fertig) + * '*' string + * '?' char + * '#' number + * '&' call function + * '+' inctype +++ NEU +++ + * + * The '#' and '+' types may have size modifiers added: + * 'c'/'C' char + * 's'/'S' short + * 'i'/'I' int (default) + * 'l'/'L' long + * 'll'/'LL' long long + * + * The format string 'f* ' may be used to disallow -ffoo for f* + * + * XXX This is currently only implemented for the '*' format + */ +/* + * 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. + */ +/* LINTLIBRARY */ +#include <mconfig.h> +#include <standard.h> +#include <utypes.h> +#include <getargs.h> +#include <vadefs.h> +#include <strdefs.h> +#include <schily.h> +#include <ctype.h> + +#define NOARGS 0 /* No more args */ +#define NOTAFLAG 1 /* Not a flag type argument */ +#define BADFLAG (-1) /* Not a valid flag argument */ +#define BADFMT (-2) /* Error in format string */ +#define NOTAFILE (-3) /* Seems to be a flag type arg */ + + + int _getargs __PR((int *, char *const **, const char *, + BOOL, va_list)); +LOCAL int dofile __PR((int *, char *const **, const char **)); +LOCAL int doflag __PR((int *, char *const **, const char *, + const char *, BOOL, va_list)); +LOCAL int dosflags __PR((const char *, const char *, BOOL, va_list)); +LOCAL int checkfmt __PR((const char *)); +LOCAL int checkeql __PR((const char *)); + +LOCAL va_list va_dummy; + +LOCAL char fmtspecs[] = "#?*&+"; +/*LOCAL char fmtspecs[] = "#?*&+!";*/ + +#define isfmtspec(c) (strchr(fmtspecs, c) != NULL) + +/*--------------------------------------------------------------------------- +| +| get flags until a non flag type argument is reached +| ++---------------------------------------------------------------------------*/ +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT int +getargs(int *pac, char *const **pav, const char *fmt, ...) +#else +EXPORT int +getargs(pac, pav, fmt, va_alist) + int *pac; + char **pav[]; + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + ret = _getargs(pac, pav, fmt, TRUE, args); + va_end(args); + return (ret); +} + + +/*--------------------------------------------------------------------------- +| +| get all flags on the command line, do not stop on files +| ++---------------------------------------------------------------------------*/ +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT int +getallargs(int *pac, char *const **pav, const char *fmt, ...) +#else +EXPORT int +getallargs(pac, pav, fmt, va_alist) + int *pac; + char **pav[]; + char *fmt; + va_dcl +#endif +{ + va_list args; + int ret; + +#ifdef PROTOTYPES + va_start(args, fmt); +#else + va_start(args); +#endif + for (; ; (*pac)--, (*pav)++) { + if ((ret = _getargs(pac, pav, fmt, TRUE, args)) != NOTAFLAG) + break; + } + va_end(args); + return (ret); +} + + +/*--------------------------------------------------------------------------- +| +| get next non flag type argument (i.e. a file) +| ++---------------------------------------------------------------------------*/ +EXPORT int +getfiles(pac, pav, fmt) + int *pac; + char *const *pav[]; + const char *fmt; +{ + return (_getargs(pac, pav, fmt, FALSE, va_dummy)); +} + + +/*--------------------------------------------------------------------------- +| +| check args until the next non flag type argmument is reached +| *pac is decremented, *pav is incremented so that the +| non flag type argument is at *pav[0] +| +| return code: +| NOARGS no more args +| NOTAFLAG not a flag type argument +| BADFLAG a non-matching flag type argument +| BADFMT bad syntax in format string +| +| ++---------------------------------------------------------------------------*/ +/*LOCAL*/ int +_getargs(pac, pav, fmt, setargs, args) + register int *pac; + register char *const **pav; + const char *fmt; + BOOL setargs; + va_list args; +{ + const char *argp; + int ret; + + + for (; *pac > 0; (*pac)--, (*pav)++) { + argp = **pav; + + ret = dofile(pac, pav, &argp); + + if (ret != NOTAFILE) + return (ret); + + ret = doflag(pac, pav, argp, fmt, setargs, args); + + if (ret != NOTAFLAG) + return (ret); + } + return (NOARGS); +} + + +/*--------------------------------------------------------------------------- +| +| check if *pargp is a file type argument +| ++---------------------------------------------------------------------------*/ +LOCAL int +dofile(pac, pav, pargp) + register int *pac; + register char *const **pav; + const char **pargp; +{ + register const char *argp = *pargp; + + + if (argp[0] == '-') { + /* + * "-" is a special non flag type argument + * that usually means take stdin instead of a named file + */ + if (argp[1] == '\0') + return (NOTAFLAG); + /* + * "--" is a prefix to take the next argument + * as non flag type argument + * NOTE: Posix requires "--" to indicate the end of the + * flags on the command line. But we are currently not + * Posix. + */ + if (argp[1] == '-' && argp[2] == '\0') { + if (--(*pac) > 0) { + (*pav)++; + return (NOTAFLAG); + } else { + return (NOARGS); + } + } + } + + /* + * now check if it may be flag type argument + * flag type arguments begin with a '-', a '+' or contain a '=' + * i.e. -flag +flag or flag= + */ + if (argp[0] != '-' && argp[0] != '+' && (!checkeql(argp))) + return (NOTAFLAG); + + return (NOTAFILE); +} + + +/*--------------------------------------------------------------------------- +| +| compare argp with the format string +| if a match is found store the result a la scanf in one of the +| arguments pointed to in the va_list +| +| If setargs is FALSE, only check arguments for getfiles() +| in this case, va_list may be a dummy arg. +| ++---------------------------------------------------------------------------*/ +LOCAL int +doflag(pac, pav, argp, fmt, setargs, oargs) + int *pac; + char *const **pav; + register const char *argp; + register const char *fmt; + BOOL setargs; + va_list oargs; +{ + char argstr[2]; + long val; + Llong llval; + int singlecharflag = 0; + BOOL isspec; + BOOL hasdash = FALSE; + BOOL doubledash = FALSE; + BOOL haseql = checkeql(argp); + const char *sargp; + const char *sfmt = fmt; + va_list args; + char *const *spav = *pav; + int spac = *pac; + void *curarg = (void *)0; + + /* + * flags beginning with '-' don't have to include the '-' in + * the format string. + * flags beginning with '+' have to include it in the format string. + */ + if (argp[0] == '-') { + argp++; + hasdash = TRUE; + /* + * Implement legacy support for --longopt + * If we find a double dash, we do not look for combinations + * of boolean single char flags. + */ + if (argp[0] == '-') { + argp++; + doubledash = TRUE; + /* + * Allow -- only for long options. + */ + if (argp[1] == '\0') { + return (BADFLAG); + } + } + } + sargp = argp; + + /* + * Initialize 'args' to the start of the argument list. + * I don't know any portable way to copy an arbitrary + * C object so I use a system-specific routine + * (probably a macro) from stdarg.h. (Remember that + * if va_list is an array, 'args' will be a pointer + * and '&args' won't be what I would need for memcpy.) + * It is a system requirement for SVr4 compatibility + * to be able to do this assgignement. If your system + * defines va_list to be an array but does not define + * va_copy() you are lost. + * This is needed to make sure, that 'oargs' will not + * be clobbered. + */ + va_copy(args, oargs); + + if (setargs) + curarg = va_arg(args, void *); + + /* + * check if the first flag in format string is a singlechar flag + */ + if (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0') + singlecharflag++; + /* + * check the whole format string for a match + */ + for (;;) { + for (; *fmt; fmt++, argp++) { + if (*fmt == '\\') { + /* + * Allow "#?*&+" to appear inside a flag. + * NOTE: they must be escaped by '\\' only + * inside the the format string. + */ + fmt++; + isspec = FALSE; + } else { + isspec = isfmtspec(*fmt); + } + /* + * If isspec is TRUE, the arg beeing checked starts + * like a valid flag. Argp now points to the rest. + */ + if (isspec) { + /* + * If *argp is '+' and we are on the + * beginning of the arg that is currently + * checked, this cannot be an inc type flag. + */ + if (*argp == '+' && argp == sargp) + continue; + /* + * skip over to arg of flag + */ + if (*argp == '=') { + argp++; + } else if (*argp != '\0' && haseql) { + /* + * Flag and arg are not separated by a + * space. + * Check here for: + * xxxxx=yyyyy match on '&' + * Checked before: + * abc=yyyyy match on 'abc&' + * or 'abc*' + * or 'abc#' + * We come here if 'argp' starts with + * the same sequence as a valid flag + * and contains an equal sign. + * We have tested before if the text + * before 'argp' matches exactly. + * At this point we have no exact match + * and we only allow to match + * the special pattern '&'. + * We need this e.g. for 'make'. + * We allow any flag type argument to + * match the format string "&" to set + * up a function that handles all odd + * stuff that getargs will not grok. + * In addition, to allow getargs to be + * used for CPP type flags we allow to + * match -Dabc=xyz on 'D&'. Note that + * Dabc=xyz will not match 'D&'. + */ + if ((!hasdash && argp != sargp) || *fmt != '&') + goto nextarg; + } + + /* + * The format string 'f* ' may be used + * to disallow -ffoo for f* + * + * XXX This is currently only implemented for + * XXX the '*' format + */ + if (!haseql && *argp != '\0' && fmt[0] == '*' && fmt[1] == ' ') + goto nextarg; + /* + * *arpp == '\0' || !haseql + * We come here if 'argp' starts with + * the same sequence as a valid flag. + * This will match on the following args: + * -farg match on 'f*' + * -f12 match on 'f#' + * +12 match on '+#' + * -12 match on '#' + * and all args that are separated from + * their flags. + * In the switch statement below, we check + * if the text after 'argp' (if *argp != 0) or + * the next arg is a valid arg for this flag. + */ + break; + } else if (*fmt == *argp) { + if (argp[1] == '\0' && + (fmt[1] == '\0' || fmt[1] == ',')) { + + if (setargs) + *((int *)curarg) = TRUE; + + + return (checkfmt(fmt)); /* XXX */ + } + } else { + /* + * skip over to next format identifier + * & reset arg pointer + */ + nextarg: + while (*fmt != ',' && *fmt != '\0') { + /* function has extra arg on stack */ + if (*fmt == '&' && setargs) + curarg = va_arg(args, void *); + fmt++; + } + argp = sargp; + break; + } + } + switch (*fmt) { + + case '\0': + /* + * Boolean type has been tested before. + */ + if (singlecharflag && !doubledash && + (val = dosflags(sargp, sfmt, setargs, oargs)) != + BADFLAG) + return (val); + + + return (BADFLAG); + + case ',': + fmt++; + if (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0') + singlecharflag++; + if (setargs) + curarg = va_arg(args, void *); + continue; + + case '*': + if (*argp == '\0') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + if (fmt[1] == ' ') /* To disallow -ffoo for f* */ + fmt++; + if (setargs) + *((const char **)curarg) = argp; + + + return (checkfmt(fmt)); + + case '?': + /* + * If more than one char arg, it + * cannot be a character argument. + */ + if (argp[1] != '\0') + goto nextchance; + if (setargs) + *((char *)curarg) = *argp; + + + return (checkfmt(fmt)); + + case '+': + /* + * inc type is similar to boolean, + * there is no arg in argp to convert. + */ + if (*argp != '\0') + goto nextchance; + /* + * If *fmt is '+' and we are on the beginning + * of the format desciptor that is currently + * checked, this cannot be an inc type flag. + */ + if (fmt == sfmt || fmt[-1] == ',') + goto nextchance; + + if (fmt[1] == 'l' || fmt[1] == 'L') { + if (fmt[2] == 'l' || fmt[2] == 'L') { + if (setargs) + *((Llong *)curarg) += 1; + fmt += 2; + } else { + if (setargs) + *((long *)curarg) += 1; + fmt++; + } + } else if (fmt[1] == 's' || fmt[1] == 'S') { + if (setargs) + *((short *)curarg) += 1; + fmt++; + } else if (fmt[1] == 'c' || fmt[1] == 'C') { + if (setargs) + *((char *)curarg) += 1; + fmt++; + } else { + if (fmt[1] == 'i' || fmt[1] == 'I') + fmt++; + if (setargs) + *((int *)curarg) += 1; + } + + argstr[0] = *fmt; + argstr[1] = '\0'; + + return (checkfmt(fmt)); + + case '#': + if (*argp == '\0') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + if (*astoll(argp, &llval) != '\0') { + /* + * arg is not a valid number! + * go to next format in the format string + * and check if arg matches any other type + * in the format specs. + */ + nextchance: + while (*fmt != ',' && *fmt != '\0') { + if (*fmt == '&' && setargs) + curarg = va_arg(args, void *); + fmt++; + } + argp = sargp; + *pac = spac; + *pav = spav; + continue; + } + val = (long)llval; + if (fmt[1] == 'l' || fmt[1] == 'L') { + if (fmt[2] == 'l' || fmt[2] == 'L') { + if (setargs) + *((Llong *)curarg) = llval; + fmt += 2; + } else { + if (setargs) + *((long *)curarg) = val; + fmt++; + } + } else if (fmt[1] == 's' || fmt[1] == 'S') { + if (setargs) + *((short *)curarg) = (short)val; + fmt++; + } else if (fmt[1] == 'c' || fmt[1] == 'C') { + if (setargs) + *((char *)curarg) = (char)val; + fmt++; + } else { + if (fmt[1] == 'i' || fmt[1] == 'I') + fmt++; + if (setargs) + *((int *)curarg) = (int)val; + } + argstr[0] = *fmt; + argstr[1] = '\0'; + + return (checkfmt(fmt)); + + case '&': + if (*argp == '\0') { + if (*pac > 1) { + (*pac)--; + (*pav)++; + argp = **pav; + } else { + return (BADFLAG); + } + } + + if ((val = checkfmt(fmt)) != NOTAFLAG) + return (val); + + if (setargs) { + int ret; + void *funarg = va_arg(args, void *); + + ret = ((*(getargfun)curarg) (argp, funarg)); + if (ret != NOTAFILE) + return (ret); + fmt++; + } else { + return (val); + } + /* + * Called function returns NOTAFILE: try next format. + */ + } + } +} + + +/*--------------------------------------------------------------------------- +| +| parse args for combined single char flags +| ++---------------------------------------------------------------------------*/ +typedef struct { + void *curarg; /* The pointer to the arg to modify */ + short count; /* The number of times a sc flag appears */ + char c; /* The single char flag character */ + char type; /* The type of the single char flag */ +} sflags; + +LOCAL int +dosflags(argp, fmt, setargs, oargs) + register const char *argp; + register const char *fmt; + BOOL setargs; + va_list oargs; +{ +#define MAXSF 32 + sflags sf[MAXSF]; + va_list args; + register sflags *rsf = sf; + register int nsf = 0; + register const char *p = argp; + register int i; + register void *curarg = (void *)0; + char type; + + /* + * Initialize 'args' to the start of the argument list. + * I don't know any portable way to copy an arbitrary + * C object so I use a system-specific routine + * (probably a macro) from stdarg.h. (Remember that + * if va_list is an array, 'args' will be a pointer + * and '&args' won't be what I would need for memcpy.) + * It is a system requirement for SVr4 compatibility + * to be able to do this assgignement. If your system + * defines va_list to be an array but does not define + * va_copy() you are lost. + * This is needed to make sure, that 'oargs' will not + * be clobbered. + */ + va_copy(args, oargs); + + if (setargs) + curarg = va_arg(args, void *); + + while (*p) { + for (i = 0; i < nsf; i++) { + if (rsf[i].c == *p) + break; + } + if (i >= MAXSF) + return (BADFLAG); + if (i == nsf) { + rsf[i].curarg = (void *)0; + rsf[i].count = 0; + rsf[i].c = *p; + rsf[i].type = (char)-1; + nsf++; + } + rsf[i].count++; + p++; + } + + while (*fmt) { + if (!isfmtspec(*fmt) && + (fmt[1] == ',' || fmt[1] == '+' || fmt[1] == '\0') && + strchr(argp, *fmt)) { + for (i = 0; i < nsf; i++) { + if (rsf[i].c == *fmt) { + if (fmt[1] == '+') { + fmt++; + if (fmt[1] == ',' || + fmt[1] == '\0') { + rsf[i].type = 'i'; + } else if ((fmt[1] == 'l' || + fmt[1] == 'L') && + (fmt[2] == 'l' || + fmt[2] == 'L')) { + /* + * Type 'Q'uad (ll) + */ + rsf[i].type = 'Q'; + fmt++; + } else { + /* + * Type 'l','i','s','c' + */ + rsf[i].type = fmt[1]; + } + } else { + /* + * ',' or '\0' for BOOL + */ + rsf[i].type = fmt[1]; + } + rsf[i].curarg = curarg; + break; + } + } + } + while (*fmt != ',' && *fmt != '\0') { + /* function has extra arg on stack */ + if (*fmt == '&' && setargs) + curarg = va_arg(args, void *); + fmt++; + } + if (*fmt != '\0') + fmt++; + + if (setargs) + curarg = va_arg(args, void *); + } + for (i = 0; i < nsf; i++) { + type = rsf[i].type; + if (type == (char)-1) { + return (BADFLAG); + } + if (rsf[i].curarg) { + if (type == ',' || type == '\0') { + *((int *)rsf[i].curarg) = TRUE; + } else if (type == 'i' || type == 'I') { + *((int *)rsf[i].curarg) += rsf[i].count; + } else if (type == 'l' || type == 'L') { + *((long *)rsf[i].curarg) += rsf[i].count; + } else if (type == 'Q') { + *((Llong *)rsf[i].curarg) += rsf[i].count; + } else if (type == 's' || type == 'S') { + *((short *)rsf[i].curarg) += rsf[i].count; + } else if (type == 'c' || type == 'C') { + *((char *)rsf[i].curarg) += rsf[i].count; + } else { + return (BADFLAG); + } + } + } + return (NOTAFLAG); +} + +/*--------------------------------------------------------------------------- +| +| If the next format character is a comma or the string delimiter, +| there are no invalid format specifiers. Return success. +| Otherwise raise the getarg_bad_format condition. +| ++---------------------------------------------------------------------------*/ +LOCAL int +checkfmt(fmt) + const char *fmt; +{ + char c; + + c = *(++fmt); /* non constant expression */ + + + if (c == ',' || c == '\0') { + return (NOTAFLAG); + } else { + raisecond("getarg_bad_format", (long)fmt); + return (BADFMT); + } +} + +/*--------------------------------------------------------------------------- +| +| Parse the string as long as valid characters can be found. +| Valid flag identifiers are chosen from the set of +| alphanumeric characters, '-' and '_'. +| If the next character is an equal sign the string +| contains a valid flag identifier. +| ++---------------------------------------------------------------------------*/ +LOCAL int +checkeql(str) + register const char *str; +{ + register unsigned char c; + + for (c = (unsigned char)*str; + isalnum(c) || c == '_' || c == '-'; c = *str++) + /* LINTED */ + ; + return (c == '='); +} diff --git a/librols/getav0.c b/librols/getav0.c new file mode 100644 index 0000000..3b7e2f4 --- /dev/null +++ b/librols/getav0.c @@ -0,0 +1,155 @@ +/* + * 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. + * + */ + +/* @(#)getav0.c 1.16 04/05/09 Copyright 1985, 1995-2004 J. Schilling */ +/* + * Get arg vector by scanning the stack + * + * Copyright (c) 1985, 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 <sigblk.h> +#include <avoffset.h> +#include <standard.h> +#include <schily.h> + +#if !defined(AV_OFFSET) || !defined(FP_INDIR) +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +#ifdef HAVE_SCANSTACK + +#include <stkframe.h> + +#define is_even(p) ((((long)(p)) & 1) == 0) +#define even(p) (((long)(p)) & ~1L) +#ifdef __future__ +#define even(p) (((long)(p)) - 1) /* will this work with 64 bit ?? */ +#endif + +EXPORT char **getmainfp __PR((void)); +EXPORT char **getavp __PR((void)); +EXPORT char *getav0 __PR((void)); + + +EXPORT char ** +getmainfp() +{ + register struct frame *fp; + char **av; +#if FP_INDIR > 0 + register int i = 0; +#endif + + /* + * As the SCO OpenServer C-Compiler has a bug that may cause + * the first function call to getfp() been done before the + * new stack frame is created, we call getfp() twice. + */ + (void) getfp(); + fp = (struct frame *)getfp(); + if (fp == NULL) + return (NULL); + + while (fp->fr_savfp) { + if (fp->fr_savpc == NULL) + break; + + if (!is_even(fp->fr_savfp)) { + fp = (struct frame *)even(fp->fr_savfp); + if (fp == NULL) + break; + fp = (struct frame *)((SIGBLK *)fp)->sb_savfp; + continue; + } + fp = (struct frame *)fp->fr_savfp; + +#if FP_INDIR > 0 + i++; +#endif + } + +#if FP_INDIR > 0 + i -= FP_INDIR; + fp = (struct frame *)getfp(); + if (fp == NULL) + return (NULL); + + while (fp->fr_savfp) { + if (fp->fr_savpc == NULL) + break; + + if (!is_even(fp->fr_savfp)) { + fp = (struct frame *)even(fp->fr_savfp); + if (fp == NULL) + break; + fp = (struct frame *)((SIGBLK *)fp)->sb_savfp; + continue; + } + fp = (struct frame *)fp->fr_savfp; + + if (--i <= 0) + break; + } +#endif + + av = (char **)fp; + return (av); +} + +EXPORT char ** +getavp() +{ + register struct frame *fp; + char **av; + + fp = (struct frame *)getmainfp(); + if (fp == NULL) + return (NULL); + + av = (char **)(((char *)fp) + AV_OFFSET); /* aus avoffset.h */ + /* -> avoffset.c */ + return (av); +} + +EXPORT char * +getav0() +{ + return (getavp()[0]); +} + +#else + +EXPORT char * +getav0() +{ + return ("???"); +} + +#endif /* HAVE_SCANSTACK */ diff --git a/librols/getdomainname.c b/librols/getdomainname.c new file mode 100644 index 0000000..8338770 --- /dev/null +++ b/librols/getdomainname.c @@ -0,0 +1,115 @@ +/* + * 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. + * + */ + +/* @(#)getdomainname.c 1.16 03/06/15 Copyright 1995-2003 J. Schilling */ +/* + * Copyright (c) 1995-2003 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 <standard.h> +#include <stdxlib.h> +#ifdef HAVE_SYS_SYSTEMINFO_H +#include <sys/systeminfo.h> +#endif +#include <libport.h> + +#ifndef HAVE_GETDOMAINNAME +EXPORT int getdomainname __PR((char *name, int namelen)); +#endif + + +/*#undef HAVE_GETDOMAINNAME*/ +/*#undef SI_SRPC_DOMAIN*/ + +#if !defined(HAVE_GETDOMAINNAME) && defined(SI_SRPC_DOMAIN) +#define FUNC_GETDOMAINNAME + +EXPORT int +getdomainname(name, namelen) + char *name; + int namelen; +{ + if (sysinfo(SI_SRPC_DOMAIN, name, namelen) < 0) + return (-1); + return (0); +} +#endif + +#if !defined(HAVE_GETDOMAINNAME) && !defined(FUNC_GETDOMAINNAME) +#define FUNC_GETDOMAINNAME + +#include <stdio.h> +#include <strdefs.h> +#include <schily.h> + +EXPORT int +getdomainname(name, namelen) + char *name; + int namelen; +{ + FILE *f; + char name1[1024]; + char *p; + char *p2; + + name[0] = '\0'; + + f = fileopen("/etc/resolv.conf", "r"); + + if (f == NULL) + return (-1); + + while (rols_fgetline(f, name1, sizeof (name1)) >= 0) { + if ((p = strchr(name1, '#')) != NULL) + *p = '\0'; + + /* + * Skip leading whitespace. + */ + p = name1; + while (*p != '\0' && (*p == ' ' || *p == '\t')) + p++; + + if (strncmp(p, "domain", 6) == 0) { + p += 6; + while (*p != '\0' && (*p == ' ' || *p == '\t')) + p++; + if ((p2 = strchr(p, ' ')) != NULL) + *p2 = '\0'; + if ((p2 = strchr(p, '\t')) != NULL) + *p2 = '\0'; + + strncpy(name, p, namelen); + + fclose(f); + return (0); + } + } + fclose(f); + return (0); +} +#endif diff --git a/librols/geterrno.c b/librols/geterrno.c new file mode 100644 index 0000000..8e60e78 --- /dev/null +++ b/librols/geterrno.c @@ -0,0 +1,51 @@ +/* + * 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. + * + */ + +/* @(#)geterrno.c 1.9 03/06/15 Copyright 1985, 1995-2003 J. Schilling */ +/* + * Get error number + * + * Copyright (c) 1985, 1995-2003 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 <errno.h> +#include <standard.h> +#include <schily.h> + +#ifndef HAVE_ERRNO_DEF +extern int errno; +#endif + +#ifdef geterrno +#undef geterrno +#endif + +EXPORT int +geterrno() + +{ + return (errno); +} diff --git a/librols/gethostid.c b/librols/gethostid.c new file mode 100644 index 0000000..1b4fe02 --- /dev/null +++ b/librols/gethostid.c @@ -0,0 +1,77 @@ +/* + * 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. + * + */ + +/* @(#)gethostid.c 1.15 03/06/15 Copyright 1995-2003 J. Schilling */ +/* + * Copyright (c) 1995-2003 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 <standard.h> +#include <stdxlib.h> +#include <utypes.h> +#ifdef HAVE_SYS_SYSTEMINFO_H +#include <sys/systeminfo.h> +#endif +#include <libport.h> + +#ifndef HAVE_GETHOSTID +EXPORT long gethostid __PR((void)); +#endif + + +#if !defined(HAVE_GETHOSTID) + +#if defined(SI_HW_SERIAL) + +EXPORT long +gethostid() +{ + long id; + + char hbuf[257]; + sysinfo(SI_HW_SERIAL, hbuf, sizeof (hbuf)); + id = atoi(hbuf); + return (id); +} +#else + +#include <errno.h> +EXPORT long +gethostid() +{ + long id = -1L; + +#ifdef ENOSYS + seterrno(ENOSYS); +#else + seterrno(EINVAL); +#endif + return (id); +} +#endif + +#endif diff --git a/librols/gethostname.c b/librols/gethostname.c new file mode 100644 index 0000000..483ee7f --- /dev/null +++ b/librols/gethostname.c @@ -0,0 +1,78 @@ +/* + * 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. + * + */ + +/* @(#)gethostname.c 1.15 03/10/04 Copyright 1995 J. Schilling */ +/* + * Copyright (c) 1995 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 <standard.h> +#include <stdxlib.h> +#ifdef HAVE_SYS_SYSTEMINFO_H +#include <sys/systeminfo.h> +#endif +#include <libport.h> + +#ifndef HAVE_GETHOSTNAME +EXPORT int gethostname __PR((char *name, int namelen)); + + +#ifdef SI_HOSTNAME + +EXPORT int +gethostname(name, namelen) + char *name; + int namelen; +{ + if (sysinfo(SI_HOSTNAME, name, namelen) < 0) + return (-1); + return (0); +} +#else + +#if defined(HAVE_UNAME) && defined(HAVE_SYS_UTSNAME_H) +#include <sys/utsname.h> +#include <strdefs.h> + +EXPORT int +gethostname(name, namelen) + char *name; + int namelen; +{ + struct utsname uts; + + if (uname(&uts) < 0) + return (-1); + + strncpy(name, uts.nodename, namelen); + return (0); +} +#endif + +#endif + +#endif /* HAVE_GETHOSTNAME */ diff --git a/librols/getpagesize.c b/librols/getpagesize.c new file mode 100644 index 0000000..8a98edd --- /dev/null +++ b/librols/getpagesize.c @@ -0,0 +1,65 @@ +/* + * 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. + * + */ + +/* @(#)getpagesize.c 1.1 01/11/28 Copyright 2001 J. Schilling */ +/* + * Copyright (c) 2001 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> + +#ifndef HAVE_GETPAGESIZE + +#include <unixstd.h> +#include <standard.h> +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#include <libport.h> + +#ifdef HAVE_OS_H +#include <OS.h> /* BeOS for B_PAGE_SIZE */ +#endif + +int getpagesize(void) +{ +#ifdef _SC_PAGESIZE + return sysconf(_SC_PAGESIZE); +#else +# ifdef PAGESIZE /* Traditional UNIX page size from param.h */ + return PAGESIZE; +# else + +# ifdef B_PAGE_SIZE /* BeOS page size from OS.h */ + return B_PAGE_SIZE; +# else + return 512; +# endif +# endif +#endif +} + +#endif /* HAVE_GETPAGESIZE */ diff --git a/librols/handlecond.c b/librols/handlecond.c new file mode 100644 index 0000000..06668b8 --- /dev/null +++ b/librols/handlecond.c @@ -0,0 +1,287 @@ +/* + * 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. + * + */ + +/* @(#)handlecond.c 1.22 04/05/09 Copyright 1985-2004 J. Schilling */ +/* + * setup/clear a condition handler for a software signal + */ +/* + * 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. + */ +/* + * A procedure frame is marked to have handlers if the + * previous freme pointer for this procedure is odd. + * The even base value, in this case actually points to a SIGBLK which + * holds the saved "real" frame pointer. + * The SIGBLK mentioned above may me the start of a chain of SIGBLK's, + * containing different handlers. + * + * This will work on processors which support a frame pointer chain + * on the stack. + * On a processor which doesn't support this I think of a method + * where handlecond() has an own chain of frames, holding chains of + * SIGBLK's. + * In this case, a parameter has to be added to handlecond() and + * unhandlecond(). This parameter will be an opaque cookie which is zero + * on the first call to handlecond() in a procedure. + * A new cookie will be returned by handlecond() which must be used on + * each subsequent call to handlecond() and unhandlecond() in the same + * procedure. + * + * Copyright (c) 1985-2004 J. Schilling + */ +#include <mconfig.h> +#include <sigblk.h> +#include <standard.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <avoffset.h> +#include <utypes.h> +#include <schily.h> + +#if !defined(AV_OFFSET) || !defined(FP_INDIR) +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +#ifdef HAVE_SCANSTACK +#include <stkframe.h> +#else +extern SIGBLK *__roothandle; +#endif /* HAVE_SCANSTACK */ + +#define is_even(p) ((((long)(p)) & 1) == 0) +#define even(p) (((long)(p)) & ~1L) +#if defined(__sun) && defined(__i386) +/* + * Solaris x86 has a broken frame.h which defines the frame ptr to int. + */ +#define odd(p) (((Intptr_t)(p)) | 1) +#else +#define odd(p) (void *)(((Intptr_t)(p)) | 1) +#endif + +#ifdef __future__ +#define even(p) (((long)(p)) - 1) /* will this work with 64 bit ?? */ +#endif + +EXPORT void starthandlecond __PR((SIGBLK *sp)); + +#ifdef PROTOTYPES +EXPORT void +handlecond(const char *signame, + register SIGBLK *sp, + int (*func)(const char *, long, long), + long arg1) +#else +EXPORT void +handlecond(signame, sp, func, arg1) + char *signame; + register SIGBLK *sp; + BOOL (*func)(); + long arg1; +#endif +{ + register SIGBLK *this; + register SIGBLK *last = (SIGBLK *)NULL; +#ifdef HAVE_SCANSTACK + struct frame *fp = (struct frame *)NULL; +#endif + int slen; + + if (signame == NULL || (slen = strlen(signame)) == 0) { + raisecond("handle_bad_name", (long)signame); + abort(); + } + +#ifdef HAVE_SCANSTACK + fp = (struct frame *)getfp(); + fp = (struct frame *)fp->fr_savfp; /* point to frame of caller */ + if (is_even(fp->fr_savfp)) { + /* + * Easy case: no handlers yet + * save real framepointer in sp->sb_savfp + */ + sp->sb_savfp = (long **)fp->fr_savfp; + this = (SIGBLK *)NULL; + } else { + this = (SIGBLK *)even(fp->fr_savfp); + } +#else + this = __roothandle; +#endif + + for (; this; this = this->sb_signext) { + if (this == sp) { + /* + * If a SIGBLK is reused, the name must not change. + */ + if (this->sb_signame != NULL && + !streql(this->sb_signame, signame)) { + raisecond("handle_reused_block", (long)signame); + abort(); + } + sp->sb_sigfun = func; + sp->sb_sigarg = arg1; + return; + } + if (this->sb_signame != NULL && + streql(this->sb_signame, signame)) { + if (last == (SIGBLK *)NULL) { + /* + * 'this' is the first entry in chain + */ + if (this->sb_signext == (SIGBLK *)NULL) { + /* + * only 'this' entry is in chain, copy + * saved real frame pointer into new sp + */ + sp->sb_savfp = this->sb_savfp; + } else { +#ifdef HAVE_SCANSTACK + /* + * make second entry first link in chain + */ + this->sb_signext->sb_savfp = + this->sb_savfp; + fp->fr_savfp = odd(this->sb_signext); +#else + /* + * Cannot happen if scanning the stack + * is not possible... + */ + raisecond("handle_is_empty", (long)0); + abort(); +#endif + } + continue; /* don't trash 'last' ptr */ + } else { + last->sb_signext = this->sb_signext; + } + } + last = this; + } + sp->sb_signext = (SIGBLK *)NULL; + sp->sb_signame = signame; + sp->sb_siglen = slen; + sp->sb_sigfun = func; + sp->sb_sigarg = arg1; + /* + * If there is a chain append to end of the chain, else make it first + */ + if (last) + last->sb_signext = sp; +#ifdef HAVE_SCANSTACK + else + fp->fr_savfp = odd(sp); +#else + /* + * Cannot happen if scanning the stack is not possible... + */ + else { + raisecond("handle_is_empty", (long)0); + abort(); + } +#endif +} + +EXPORT void +starthandlecond(sp) + register SIGBLK *sp; +{ +#ifdef HAVE_SCANSTACK + struct frame *fp = NULL; + + /* + * As the SCO OpenServer C-Compiler has a bug that may cause + * the first function call to getfp() been done before the + * new stack frame is created, we call getfp() twice. + */ + (void) getfp(); +#endif + + sp->sb_signext = (SIGBLK *)NULL; + sp->sb_signame = NULL; + sp->sb_siglen = 0; + sp->sb_sigfun = (handlefunc_t)NULL; + sp->sb_sigarg = 0; + +#ifdef HAVE_SCANSTACK + fp = (struct frame *)getfp(); + fp = (struct frame *)fp->fr_savfp; /* point to frame of caller */ + + if (is_even(fp->fr_savfp)) { + /* + * Easy case: no handlers yet + * save real framepointer in sp + */ + sp->sb_savfp = (long **)fp->fr_savfp; + fp->fr_savfp = odd(sp); + } else { + raisecond("handle_not_empty", (long)0); + abort(); + } +#else + sp->sb_savfp = (long **)__roothandle; + __roothandle = sp; +#endif +} + +EXPORT void +unhandlecond(sp) + register SIGBLK *sp; +{ +#ifdef HAVE_SCANSTACK + register struct frame *fp; + register SIGBLK *sps; + + /* + * As the SCO OpenServer C-Compiler has a bug that may cause + * the first function call to getfp() been done before the + * new stack frame is created, we call getfp() twice. + */ + (void) getfp(); + fp = (struct frame *)getfp(); + fp = (struct frame *)fp->fr_savfp; /* point to frame of caller */ + + if (!is_even(fp->fr_savfp)) { /* if handlers */ + sps = (SIGBLK *)even(fp->fr_savfp); /* point to SIGBLK */ + /* real framepointer */ +#if defined(__sun) && defined(__i386) + fp->fr_savfp = (intptr_t)sps->sb_savfp; +#else + fp->fr_savfp = (struct frame *)sps->sb_savfp; +#endif + } +#else + if (__roothandle == NULL) { + raisecond("handle_is_empty", (long)0); + abort(); + } + /* + * Pop top level handler chain. + */ + __roothandle = (SIGBLK *)__roothandle->sb_savfp; +#endif +} diff --git a/librols/movebytes.c b/librols/movebytes.c new file mode 100644 index 0000000..3724c99 --- /dev/null +++ b/librols/movebytes.c @@ -0,0 +1,136 @@ +/* + * 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. + * + */ + +/* @(#)movebytes.c 1.13 03/06/15 Copyright 1985, 1989, 1995-2003 J. Schilling */ +/* + * move data + * + * Copyright (c) 1985, 1989, 1995-2003 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 <standard.h> +#include <align.h> +#include <schily.h> + +#define DO8(a) a; a; a; a; a; a; a; a; + +EXPORT char * +movebytes(fromv, tov, cnt) + const void *fromv; + void *tov; + int cnt; +{ + register const char *from = fromv; + register char *to = tov; + register int n; + + /* + * If we change cnt to be unsigned, check for == instead of <= + */ + if ((n = cnt) <= 0) + return (to); + + if (from >= to) { + /* + * source is on higher adresses than destination: + * move bytes forwards + */ + if (n >= (int)(8 * sizeof (long))) { + if (l2aligned(from, to)) { + register const long *froml = (const long *)from; + register long *tol = (long *)to; + register int rem = n % (8 * sizeof (long)); + + n /= (8 * sizeof (long)); + do { + DO8 (*tol++ = *froml++); + } while (--n > 0); + + from = (const char *)froml; + to = (char *)tol; + n = rem; + } + + if (n >= 8) { + n -= 8; + do { + DO8 (*to++ = *from++); + } while ((n -= 8) >= 0); + n += 8; + } + + if (n > 0) do { + *to++ = *from++; + } while (--n > 0); + return (to); + } + if (n > 0) do { + *to++ = *from++; + } while (--n > 0); + return (to); + } else { + char *ep; + + /* + * source is on lower adresses than destination: + * move bytes backwards + */ + to += n; + from += n; + ep = to; + if (n >= (int)(8 * sizeof (long))) { + if (l2aligned(from, to)) { + register const long *froml = (const long *)from; + register long *tol = (long *)to; + register int rem = n % (8 * sizeof (long)); + + n /= (8 * sizeof (long)); + do { + DO8 (*--tol = *--froml); + } while (--n > 0); + + from = (const char *)froml; + to = (char *)tol; + n = rem; + } + if (n >= 8) { + n -= 8; + do { + DO8 (*--to = *--from); + } while ((n -= 8) >= 0); + n += 8; + } + if (n > 0) do { + *--to = *--from; + } while (--n > 0); + return (ep); + } + if (n > 0) do { + *--to = *--from; + } while (--n > 0); + return (ep); + } +} diff --git a/librols/raisecond.c b/librols/raisecond.c new file mode 100644 index 0000000..01cef9c --- /dev/null +++ b/librols/raisecond.c @@ -0,0 +1,179 @@ +/* + * 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. + * + */ + +/* @(#)raisecond.c 1.18 04/05/09 Copyright 1985, 1989, 1995-2004 J. Schilling */ +/* + * raise a condition (software signal) + */ +/* + * 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. + */ +/* + * Check for installed condition handlers. + * If a handler is found, the function is called with the appropriate args. + * If no handler is found or no handler signals success, + * the program will be aborted. + * + * Copyright (c) 1985, 1989, 1995-2004 J. Schilling + */ +#include <mconfig.h> +#include <stdio.h> +#include <standard.h> +#include <sigblk.h> +#include <unixstd.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <avoffset.h> +#include <schily.h> + +#if !defined(AV_OFFSET) || !defined(FP_INDIR) +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +/* + * Macros to print to stderr without stdio, to avoid screwing up. + */ +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif +#define eprints(a) do { int ret; ret = write(STDERR_FILENO, (a), sizeof (a)-1); } while (0) +#define eprintl(a) do { int ret; ret = write(STDERR_FILENO, (a), strlen(a)); } while (0) + +#define is_even(p) ((((long)(p)) & 1) == 0) +#define even(p) (((long)(p)) & ~1L) +#ifdef __future__ +#define even(p) (((long)(p)) - 1) /* will this work with 64 bit ?? */ +#endif + + +LOCAL void raiseabort __PR((const char *)); + +#ifdef HAVE_SCANSTACK +#include <stkframe.h> +#define next_frame(vp) do { \ + if (((struct frame *)(vp))->fr_savfp == 0) { \ + vp = (void *)0; \ + break; \ + } \ + if (((struct frame *)(vp))->fr_savpc == 0) { \ + vp = (void *)0; \ + break; \ + } \ + vp = \ + (void *)((struct frame *)(vp))->fr_savfp; \ + } while (vp != NULL && is_even(vp)); \ + vp = (struct frame *)even(vp); +#else +EXPORT SIGBLK *__roothandle; + +#define next_frame(vp) vp = (((SIGBLK *)(vp))->sb_savfp); +#endif + +LOCAL BOOL framehandle __PR((SIGBLK *, const char *, const char *, long)); + +/* + * Loop through the chain of procedure frames on the stack. + * + * Frame pointers normally have even values. + * Frame pointers of procedures with an installed handler are marked odd. + * The even base value, in this case actually points to a SIGBLK which + * holds the saved "real" frame pointer. + * The SIGBLK mentioned above may me the start of a chain of SIGBLK's, + * containing different handlers. + */ +EXPORT void +raisecond(signame, arg2) + const char *signame; + long arg2; +{ + register void *vp = NULL; + +#ifdef HAVE_SCANSTACK + /* + * As the SCO OpenServer C-Compiler has a bug that may cause + * the first function call to getfp() been done before the + * new stack frame is created, we call getfp() twice. + */ + (void) getfp(); + vp = getfp(); + next_frame(vp); +#else + vp = __roothandle; +#endif + + while (vp) { + if (framehandle((SIGBLK *)vp, signame, signame, arg2)) + return; + else if (framehandle((SIGBLK *)vp, "any_other", signame, arg2)) + return; +#ifdef HAVE_SCANSTACK + vp = (struct frame *)((SIGBLK *)vp)->sb_savfp; +#endif + next_frame(vp); + } + /* + * No matching handler that signals success found. + * Print error message and abort. + */ + raiseabort(signame); + /* NOTREACHED */ +} + +/* + * Loop through the handler chain for a procedure frame. + * + * If no handler with matching name is found, return FALSE, + * otherwise the first handler with matching name is called. + * The return value in the latter case depends on the called function. + */ +LOCAL BOOL +framehandle(sp, handlename, signame, arg2) + register SIGBLK *sp; + const char *handlename; + const char *signame; + long arg2; +{ + for (; sp; sp = sp->sb_signext) { + if (sp->sb_signame != NULL && + streql(sp->sb_signame, handlename)) { + if (sp->sb_sigfun == NULL) { /* deactivated */ + return (FALSE); + } else { + return (*sp->sb_sigfun)(signame, + sp->sb_sigarg, arg2); + } + } + } + return (FALSE); +} + +LOCAL void +raiseabort(signame) + const char *signame; +{ + eprints("Condition not caught: "); eprintl(signame); eprints(".\n"); + abort(); + /* NOTREACHED */ +} diff --git a/librols/rename.c b/librols/rename.c new file mode 100644 index 0000000..dca60ea --- /dev/null +++ b/librols/rename.c @@ -0,0 +1,144 @@ +/* + * 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. + * + */ + +/* @(#)rename.c 1.6 04/09/04 Copyright 1998-2003 J. Schilling */ +/* + * rename() for old systems that don't have it. + * + * Copyright (c) 1998-2003 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. + */ + +#define rename __nothing__ +#include <mconfig.h> + +#ifndef HAVE_RENAME + +#include <stdio.h> /* XXX not OK but needed for js_xx() in schily.h */ +#include <unixstd.h> +#include <strdefs.h> +#include <statdefs.h> +#include <maxpath.h> +#include <standard.h> +#include <utypes.h> +#include <schily.h> +#include <errno.h> +#undef rename +#include <libport.h> + +#ifndef MAXPATHNAME +#define MAXPATHNAME 1024 +#endif + +#if MAXPATHNAME < 1024 +#undef MAXPATHNAME +#define MAXPATHNAME 1024 +#endif + +#define MAXNAME MAXPATHNAME + +#define FILEDESC struct stat + +#ifndef HAVE_LSTAT +#define lstat stat +#endif + +EXPORT int +rename(old, new) + const char *old; + const char *new; +{ + char nname[MAXNAME]; + char bakname[MAXNAME]; + char strpid[32]; + int strplen; + BOOL savpresent = FALSE; + BOOL newpresent = FALSE; + int serrno; + FILEDESC ostat; + FILEDESC xstat; + + serrno = geterrno(); + + if (lstat(old, &ostat) < 0) + return (-1); + + if (lstat(new, &xstat) >= 0) { + newpresent = TRUE; + if (ostat.st_dev == xstat.st_dev && + ostat.st_ino == xstat.st_ino) + return (0); /* old == new we are done */ + } + + strplen = snprintf(strpid, sizeof (strpid), ".%lld", + (Llong)getpid()); + + if (strlen(new) <= (MAXNAME-strplen) || + strchr(&new[MAXNAME-strplen], '/') == NULL) { + /* + * Save old version of file 'new'. + */ + strncpy(nname, new, MAXNAME-strplen); + nname[MAXNAME-strplen] = '\0'; + snprintf(bakname, sizeof (bakname), "%s%s", nname, strpid); + unlink(bakname); + if (link(new, bakname) >= 0) + savpresent = TRUE; + } + + if (newpresent) { + if (rmdir(new) < 0) { + if (geterrno() == ENOTDIR) { + if (unlink(new) < 0) + return (-1); + } else { + return (-1); + } + } + } + + /* + * Now add 'new' name to 'old'. + */ + if (link(old, new) < 0) { + serrno = geterrno(); + /* + * Make sure not to loose old version of 'new'. + */ + if (savpresent) { + unlink(new); + link(bakname, new); + unlink(bakname); + } + seterrno(serrno); + return (-1); + } + if (unlink(old) < 0) + return (-1); + unlink(bakname); /* Fails in most cases... */ + seterrno(serrno); /* ...so restore errno */ + return (0); +} +#endif /* HAVE_RENAME */ diff --git a/librols/saveargs.c b/librols/saveargs.c new file mode 100644 index 0000000..c3a0b3c --- /dev/null +++ b/librols/saveargs.c @@ -0,0 +1,135 @@ +/* + * 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. + * + */ + +/* @(#)saveargs.c 1.11 03/07/13 Copyright 1995-2003 J. Schilling */ +/* + * save argc, argv for command error printing routines + * + * Copyright (c) 1995-2003 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 <standard.h> +#include <strdefs.h> +#include <stdxlib.h> +#include <avoffset.h> +#include <schily.h> + +#if !defined(AV_OFFSET) || !defined(FP_INDIR) +# ifdef HAVE_SCANSTACK +# undef HAVE_SCANSTACK +# endif +#endif + +static int ac_saved; +static char **av_saved; +static char *av0_saved; +static char *progname_saved; + +static char av0_sp[32]; /* av0 space, avoid malloc() in most cases */ +static char prn_sp[32]; /* name space, avoid malloc() in most cases */ +static char dfl_str[] = "?"; + +EXPORT void +save_args(ac, av) + int ac; + char *av[]; +{ + int slen; + + ac_saved = ac; + av_saved = av; + + if (av0_saved && av0_saved != av0_sp) + free(av0_saved); + + slen = strlen(av[0]) + 1; + + if (slen <= (int)sizeof (av0_sp)) + av0_saved = av0_sp; + else + av0_saved = malloc(slen); + + if (av0_saved) + strcpy(av0_saved, av[0]); +} + +EXPORT int +saved_ac() +{ + return (ac_saved); +} + +EXPORT char ** +saved_av() +{ + return (av_saved); +} + +EXPORT char * +saved_av0() +{ + return (av0_saved); +} + +EXPORT void +set_progname(name) + const char *name; +{ + int slen; + + if (progname_saved && progname_saved != prn_sp) + free(progname_saved); + + slen = strlen(name) + 1; + + if (slen <= sizeof (prn_sp)) + progname_saved = prn_sp; + else + progname_saved = malloc(slen); + + if (progname_saved) + strcpy(progname_saved, name); +} + +EXPORT char * +get_progname() +{ +#ifdef HAVE_SCANSTACK + char *progname; +#endif + + if (progname_saved) + return (progname_saved); + if (av0_saved) + return (av0_saved); +#ifdef HAVE_SCANSTACK + progname = getav0(); /* scan stack to get argv[0] */ + if (progname) + return (progname); +#endif + return (dfl_str); +} diff --git a/librols/seterrno.c b/librols/seterrno.c new file mode 100644 index 0000000..39c2c81 --- /dev/null +++ b/librols/seterrno.c @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +/* @(#)seterrno.c 1.8 03/06/15 Copyright 1985, 1995-2003 J. Schilling */ +/* + * Set error number + * + * Copyright (c) 1985, 1995-2003 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 <standard.h> +#include <errno.h> +#include <schily.h> + +#ifndef HAVE_ERRNO_DEF +extern int errno; +#endif + +#ifdef seterrno +#undef seterrno +#endif + +EXPORT int +seterrno(err) + int err; +{ + int old = errno; + + errno = err; + return (old); +} diff --git a/librols/snprintf.c b/librols/snprintf.c new file mode 100644 index 0000000..87b7364 --- /dev/null +++ b/librols/snprintf.c @@ -0,0 +1,102 @@ +/* + * 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. + * + */ + +/* @(#)snprintf.c 1.9 04/05/09 Copyright 1985, 1996-2004 J. Schilling */ +/* + * Copyright (c) 1985, 1996-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. + */ + +#define snprintf __nothing__ /* prototype may be wrong (e.g. IRIX) */ +#include <mconfig.h> +#include <unixstd.h> /* include <sys/types.h> try to get size_t */ +#include <stdio.h> /* Try again for size_t */ +#include <stdxlib.h> /* Try again for size_t */ +#include <vadefs.h> +#include <standard.h> +#include <schily.h> +#undef snprintf + +EXPORT int snprintf __PR((char *, size_t maxcnt, const char *, ...)); + +typedef struct { + char *ptr; + int count; +} *BUF, _BUF; + +#ifdef PROTOTYPES +static void _cput(char c, long l) +#else +static void _cput(c, l) + char c; + long l; +#endif +{ + register BUF bp = (BUF)l; + + if (--bp->count > 0) { + *bp->ptr++ = c; + } else { + /* + * Make sure that there will never be a negative overflow. + */ + bp->count++; + } +} + +/* VARARGS2 */ +#ifdef PROTOTYPES +EXPORT int +snprintf(char *buf, size_t maxcnt, const char *form, ...) +#else +EXPORT int +snprintf(buf, maxcnt, form, va_alist) + char *buf; + unsigned maxcnt; + char *form; + va_dcl +#endif +{ + va_list args; + int cnt; + _BUF bb; + + bb.ptr = buf; + bb.count = maxcnt; + +#ifdef PROTOTYPES + va_start(args, form); +#else + va_start(args); +#endif + cnt = format(_cput, (long)&bb, form, args); + va_end(args); + if (maxcnt > 0) + *(bb.ptr) = '\0'; + if (bb.count < 0) + return (-1); + + return (cnt); +} diff --git a/librols/spawn.c b/librols/spawn.c new file mode 100644 index 0000000..011e92f --- /dev/null +++ b/librols/spawn.c @@ -0,0 +1,170 @@ +/* + * 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. + * + */ + +/* @(#)spawn.c 1.17 04/09/25 Copyright 1985, 1989, 1995-2003 J. Schilling */ +/* + * Spawn another process/ wait for child process + * + * Copyright (c) 1985, 1989, 1995-2003 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> +#define fspawnl __nothing__ /* prototype in schily.h is wrong */ +#define spawnl __nothing__ /* prototype in schily.h is wrong */ +#include <schily.h> +#undef fspawnl +#undef spawnl +#include <unixstd.h> +#include <stdxlib.h> +#include <vadefs.h> +#include <waitdefs.h> +#include <errno.h> + +#define MAX_F_ARGS 16 + +EXPORT int fspawnl __PR((FILE *, FILE *, FILE *, ...)); + +EXPORT int +fspawnv(in, out, err, argc, argv) + FILE *in; + FILE *out; + FILE *err; + int argc; + char * const argv[]; +{ + int pid; + + if ((pid = fspawnv_nowait(in, out, err, argv[0], argc, argv)) < 0) + return (pid); + + return (wait_chld(pid)); +} + +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT int +fspawnl(FILE *in, FILE *out, FILE *err, ...) +#else +EXPORT int +fspawnl(in, out, err, va_alist) + FILE *in; + FILE *out; + FILE *err; + va_dcl +#endif +{ + va_list args; + int ac = 0; + char *xav[MAX_F_ARGS]; + char **av; + char **pav; + char *p; + int ret; + +#ifdef PROTOTYPES + va_start(args, err); +#else + va_start(args); +#endif + while (va_arg(args, char *) != NULL) + ac++; + va_end(args); + + if (ac < MAX_F_ARGS) { + pav = av = xav; + } else { + pav = av = (char **)malloc((ac+1)*sizeof (char *)); + if (av == 0) + return (-1); + } + +#ifdef PROTOTYPES + va_start(args, err); +#else + va_start(args); +#endif + do { + p = va_arg(args, char *); + *pav++ = p; + } while (p != NULL); + va_end(args); + + ret = fspawnv(in, out, err, ac, av); + if (av != xav) + free(av); + return (ret); +} + +EXPORT int +fspawnv_nowait(in, out, err, name, argc, argv) + FILE *in; + FILE *out; + FILE *err; + const char *name; + int argc; + char * const argv[]; +{ + int pid = -1; /* Initialization needed to make GCC happy */ + int i; + + for (i = 1; i < 64; i *= 2) { + if ((pid = fork()) >= 0) + break; + sleep(i); + } + if (pid != 0) + return (pid); + /* + * silly: fexecv must set av[ac] = NULL + * so we have to cast argv tp (char **) + */ + rols_fexecv(name, in, out, err, argc, (char **)argv); + exit(geterrno()); + /* NOTREACHED */ +} + +EXPORT int +wait_chld(pid) + int pid; +{ + int died; + WAIT_T status; + + do { + do { + died = wait(&status); + } while (died < 0 && geterrno() == EINTR); + if (died < 0) + return (died); + } while (died != pid); + + if (WCOREDUMP(status)) + unlink("core"); + + return (WEXITSTATUS(status)); +} diff --git a/librols/stdio/cvmod.c b/librols/stdio/cvmod.c new file mode 100644 index 0000000..a825c42 --- /dev/null +++ b/librols/stdio/cvmod.c @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +/* @(#)cvmod.c 2.9 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +EXPORT int +_cvmod(mode, omode, flag) + const char *mode; + int *omode; + int *flag; +{ + while (*mode) { + switch (*mode) { + + case 'r': *omode |= O_RDONLY; *flag |= FI_READ; break; + case 'w': *omode |= O_WRONLY; *flag |= FI_WRITE; break; + case 'e': *omode |= O_EXCL; break; + case 'c': *omode |= O_CREAT; *flag |= FI_CREATE; break; + case 't': *omode |= O_TRUNC; *flag |= FI_TRUNC; break; + case 'a': *omode |= O_APPEND; *flag |= FI_APPEND; break; + case 'u': *flag |= FI_UNBUF; break; + /* dummy on UNIX */ + case 'b': *omode |= O_BINARY; *flag |= FI_BINARY; break; + /* + * XXX do we need this ? + * XXX May this be a problem? + */ + case 'l': *omode |= O_LARGEFILE; break; + default: raisecond(_badmode, 0L); + return (0); + } + mode++; + } + if (*flag & FI_READ && *flag & FI_WRITE) { + *omode &= ~(O_RDONLY|O_WRONLY); + *omode |= O_RDWR; + } + return (1); +} diff --git a/librols/stdio/dat.c b/librols/stdio/dat.c new file mode 100644 index 0000000..cda63cf --- /dev/null +++ b/librols/stdio/dat.c @@ -0,0 +1,34 @@ +/* + * 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. + * + */ + +/* @(#)dat.c 1.3 03/06/15 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 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. + */ + +char _badfile[] = "bad_file"; +char _badmode[] = "bad_file_mode"; +char _badop[] = "bad_file_op"; diff --git a/librols/stdio/fcons.c b/librols/stdio/fcons.c new file mode 100644 index 0000000..1630248 --- /dev/null +++ b/librols/stdio/fcons.c @@ -0,0 +1,94 @@ +/* + * 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. + * + */ + +/* @(#)fcons.c 2.17 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using fseeko()/ftello() + * instead of fseek()/ftell() if available. + */ + +LOCAL char *fmtab[] = { + "", /* 0 FI_NONE */ + "r", /* 1 FI_READ */ + "w", /* 2 FI_WRITE **1) */ + "r+", /* 3 FI_READ | FI_WRITE */ + "b", /* 4 FI_NONE | FI_BINARY */ + "rb", /* 5 FI_READ | FI_BINARY */ + "wb", /* 6 FI_WRITE | FI_BINARY **1) */ + "r+b", /* 7 FI_READ | FI_WRITE | FI_BINARY */ + +/* + FI_APPEND */ "", /* 0 FI_NONE */ +/* ... */ "r", /* 1 FI_READ */ + "a", /* 2 FI_WRITE **1) */ + "a+", /* 3 FI_READ | FI_WRITE */ + "b", /* 4 FI_NONE | FI_BINARY */ + "rb", /* 5 FI_READ | FI_BINARY */ + "ab", /* 6 FI_WRITE | FI_BINARY **1) */ + "a+b", /* 7 FI_READ | FI_WRITE | FI_BINARY */ + }; +/* + * NOTES: + * 1) fdopen() guarantees not to create/trunc files in this case + * + * "w" will create/trunc files with fopen() + * "a" will create files with fopen() + */ + + +EXPORT FILE * +_fcons(fd, f, flag) + register FILE *fd; + int f; + int flag; +{ + int my_gflag = _io_glflag; + + if (fd == (FILE *)NULL) + fd = fdopen(f, + fmtab[flag&(FI_READ|FI_WRITE|FI_BINARY | FI_APPEND)]); + + if (fd != (FILE *)NULL) { + if (flag & FI_APPEND) { + (void) fseek(fd, (off_t)0, SEEK_END); + } + if (flag & FI_UNBUF) { + setbuf(fd, NULL); + my_gflag |= _IOUNBUF; + } + set_my_flag(fd, my_gflag); /* must clear it if fd is reused */ + return (fd); + } + if (flag & FI_CLOSE) + close(f); + + return ((FILE *) NULL); +} diff --git a/librols/stdio/fdown.c b/librols/stdio/fdown.c new file mode 100644 index 0000000..375530f --- /dev/null +++ b/librols/stdio/fdown.c @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +/* @(#)fdown.c 1.10 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +EXPORT int +fdown(f) + register FILE *f; +{ + down(f); + return (fileno(f)); +} diff --git a/librols/stdio/fdup.c b/librols/stdio/fdup.c new file mode 100644 index 0000000..cdb180d --- /dev/null +++ b/librols/stdio/fdup.c @@ -0,0 +1,51 @@ +/* + * 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. + * + */ + +/* @(#)fdup.c 1.14 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using fseeko()/ftello() + * instead of fseek()/ftell() if available. + */ + +EXPORT FILE * +fdup(f) + register FILE *f; +{ + int newfd; + + down(f); + if ((newfd = dup(fileno(f))) < 0) + return ((FILE *) NULL); + + lseek(newfd, ftell(f), SEEK_SET); + return (_fcons((FILE *)0, newfd, (FI_READ | FI_WRITE | FI_CLOSE))); +} diff --git a/librols/stdio/ffileread.c b/librols/stdio/ffileread.c new file mode 100644 index 0000000..cbf8276 --- /dev/null +++ b/librols/stdio/ffileread.c @@ -0,0 +1,51 @@ +/* + * 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. + * + */ + +/* @(#)ffileread.c 1.10 04/09/25 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" +#include <errno.h> + +EXPORT int +ffileread(f, buf, len) + register FILE *f; + void *buf; + int len; +{ + register int fd; + register int ret; + + down2(f, _IOREAD, _IORW); + fd = fileno(f); + + while ((ret = read(fd, buf, len)) < 0 && geterrno() == EINTR) + /* LINTED */ + ; + return (ret); +} diff --git a/librols/stdio/ffilewrite.c b/librols/stdio/ffilewrite.c new file mode 100644 index 0000000..61f6635 --- /dev/null +++ b/librols/stdio/ffilewrite.c @@ -0,0 +1,43 @@ +/* + * 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. + * + */ + +/* @(#)ffilewrite.c 1.6 04/08/08 Copyright 1986 J. Schilling */ +/* + * Copyright (c) 1986 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 "schilyio.h" + +EXPORT int +ffilewrite(f, buf, len) + register FILE *f; + void *buf; + int len; +{ + down2(f, _IORWT, _IORW); + + return (write(fileno(f), (char *)buf, len)); +} diff --git a/librols/stdio/fgetline.c b/librols/stdio/fgetline.c new file mode 100644 index 0000000..910e0e6 --- /dev/null +++ b/librols/stdio/fgetline.c @@ -0,0 +1,84 @@ +/* + * 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. + * + */ + +/* @(#)fgetline.c 1.8 04/09/25 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" + +/* + * XXX should we check if HAVE_USG_STDIO is defined and + * XXX use something line memccpy to speed things up ??? + */ + +EXPORT int +rols_fgetline(f, buf, len) + register FILE *f; + char *buf; + register int len; +{ + register int c = '\0'; + register char *bp = buf; + register int nl = '\n'; + + down2(f, _IOREAD, _IORW); + + for (;;) { + if ((c = getc(f)) < 0) + break; + if (c == nl) + break; + if (--len > 0) { + *bp++ = (char)c; + } else { + /* + * Read up to end of line + */ + while ((c = getc(f)) >= 0 && c != nl) + /* LINTED */ + ; + break; + } + } + *bp = '\0'; + /* + * If buffer is empty and we hit EOF, return EOF + */ + if (c < 0 && bp == buf) + return (c); + + return (bp - buf); +} + +EXPORT int +rols_getline(buf, len) + char *buf; + int len; +{ + return (rols_fgetline(stdin, buf, len)); +} diff --git a/librols/stdio/file_raise.c b/librols/stdio/file_raise.c new file mode 100644 index 0000000..5605c8e --- /dev/null +++ b/librols/stdio/file_raise.c @@ -0,0 +1,59 @@ +/* + * 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. + * + */ + +/* @(#)file_raise.c 1.8 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +EXPORT void +file_raise(f, flg) + register FILE *f; + int flg; +{ + int oflag; +extern int _io_glflag; + + if (f == (FILE *)NULL) { + if (flg) + _io_glflag &= ~_IONORAISE; + else + _io_glflag |= _IONORAISE; + return; + } + down(f); + + oflag = my_flag(f); + + if (flg) + oflag &= ~_IONORAISE; + else + oflag |= _IONORAISE; + + set_my_flag(f, oflag); +} diff --git a/librols/stdio/fileclose.c b/librols/stdio/fileclose.c new file mode 100644 index 0000000..ce78958 --- /dev/null +++ b/librols/stdio/fileclose.c @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +/* @(#)fileclose.c 1.7 04/08/08 Copyright 1986 J. Schilling */ +/* + * Copyright (c) 1988 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 "schilyio.h" + +EXPORT int +fileclose(f) + FILE *f; +{ + down(f); + return (fclose(f)); +} diff --git a/librols/stdio/fileluopen.c b/librols/stdio/fileluopen.c new file mode 100644 index 0000000..f178d8a --- /dev/null +++ b/librols/stdio/fileluopen.c @@ -0,0 +1,84 @@ +/* + * 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. + * + */ + +/* @(#)fileluopen.c 1.17 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using fseeko()/ftello() + * instead of fseek()/ftell() if available. + */ + +#ifndef O_NDELAY /* This is undefined on BeOS :-( */ +#define O_NDELAY 0 +#endif +#ifndef O_CREAT +#define O_CREAT 0 +#endif +#ifndef O_TRUNC +#define O_TRUNC 0 +#endif +#ifndef O_EXCL +#define O_EXCL 0 +#endif + +/* + * fileluopen - open a stream for lun + */ +EXPORT FILE * +fileluopen(f, mode) + int f; + const char *mode; +{ + int omode = 0; + int flag = 0; + + if (!_cvmod(mode, &omode, &flag)) + return ((FILE *) NULL); + + if (omode & (O_NDELAY|O_CREAT|O_TRUNC|O_EXCL)) { + raisecond(_badmode, 0L); + return ((FILE *) NULL); + } + +#ifdef F_GETFD + if (fcntl(f, F_GETFD, 0) < 0) { + raisecond(_badfile, 0L); + return ((FILE *) NULL); + } +#endif + +#ifdef O_APPEND + if (omode & O_APPEND) + lseek(f, (off_t)0, SEEK_END); +#endif + + return (_fcons((FILE *)0, f, flag)); +} diff --git a/librols/stdio/filemopen.c b/librols/stdio/filemopen.c new file mode 100644 index 0000000..b8b7482 --- /dev/null +++ b/librols/stdio/filemopen.c @@ -0,0 +1,55 @@ +/* + * 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. + * + */ + +/* @(#)filemopen.c 1.4 05/08/18 Copyright 1986, 1995-2005 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2005 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 "schilyio.h" + +EXPORT FILE * +#ifdef PROTOTYPES +filemopen(const char *name, const char *mode, mode_t cmode) +#else +filemopen(name, mode, cmode) + const char *name; + const char *mode; + mode_t cmode; +#endif +{ + int ret; + int omode = 0; + int flag = 0; + + if (!_cvmod(mode, &omode, &flag)) + return ((FILE *) NULL); + + if ((ret = open(name, omode, cmode)) < 0) + return ((FILE *) NULL); + + return (_fcons((FILE *)0, ret, flag | FI_CLOSE)); +} diff --git a/librols/stdio/fileopen.c b/librols/stdio/fileopen.c new file mode 100644 index 0000000..4b5e9a8 --- /dev/null +++ b/librols/stdio/fileopen.c @@ -0,0 +1,50 @@ +/* + * 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. + * + */ + +/* @(#)fileopen.c 1.11 05/08/18 Copyright 1986, 1995-2005 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2005 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 "schilyio.h" + +EXPORT FILE * +fileopen(name, mode) + const char *name; + const char *mode; +{ + int ret; + int omode = 0; + int flag = 0; + + if (!_cvmod(mode, &omode, &flag)) + return ((FILE *) NULL); + + if ((ret = _openfd(name, omode)) < 0) + return ((FILE *) NULL); + + return (_fcons((FILE *)0, ret, flag | FI_CLOSE)); +} diff --git a/librols/stdio/filepos.c b/librols/stdio/filepos.c new file mode 100644 index 0000000..37f9166 --- /dev/null +++ b/librols/stdio/filepos.c @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +/* @(#)filepos.c 1.10 04/08/08 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using fseeko()/ftello() + * instead of fseek()/ftell() if available. + */ + +EXPORT off_t +filepos(f) + register FILE *f; +{ + down(f); + return (ftell(f)); +} diff --git a/librols/stdio/fileread.c b/librols/stdio/fileread.c new file mode 100644 index 0000000..2550f31 --- /dev/null +++ b/librols/stdio/fileread.c @@ -0,0 +1,105 @@ +/* + * 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. + * + */ + +/* @(#)fileread.c 1.14 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +static char _readerr[] = "file_read_err"; + +#ifdef HAVE_USG_STDIO + +EXPORT int +fileread(f, buf, len) + register FILE *f; + void *buf; + int len; +{ + int cnt; + register int n; + + down2(f, _IOREAD, _IORW); + + if (f->_flag & _IONBF) { + cnt = _niread(fileno(f), buf, len); + if (cnt < 0) { + f->_flag |= _IOERR; + if (!(my_flag(f) & _IONORAISE)) + raisecond(_readerr, 0L); + } + if (cnt == 0 && len) + f->_flag |= _IOEOF; + return (cnt); + } + cnt = 0; + while (len > 0) { + if (f->_cnt <= 0) { + if (usg_filbuf(f) == EOF) + break; + f->_cnt++; + f->_ptr--; + } + n = f->_cnt >= len ? len : f->_cnt; + buf = (void *)movebytes(f->_ptr, buf, n); + f->_ptr += n; + f->_cnt -= n; + cnt += n; + len -= n; + } + if (!ferror(f)) + return (cnt); + if (!(my_flag(f) & _IONORAISE)) + raisecond(_readerr, 0L); + return (-1); +} + +#else + +EXPORT int +fileread(f, buf, len) + register FILE *f; + void *buf; + int len; +{ + int cnt; + + down2(f, _IOREAD, _IORW); + + if (my_flag(f) & _IOUNBUF) + return (_niread(fileno(f), buf, len)); + cnt = fread(buf, 1, len, f); + + if (!ferror(f)) + return (cnt); + if (!(my_flag(f) & _IONORAISE)) + raisecond(_readerr, 0L); + return (-1); +} + +#endif /* HAVE_USG_STDIO */ diff --git a/librols/stdio/filereopen.c b/librols/stdio/filereopen.c new file mode 100644 index 0000000..537edfc --- /dev/null +++ b/librols/stdio/filereopen.c @@ -0,0 +1,104 @@ +/* + * 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. + * + */ + +/* @(#)filereopen.c 1.15 04/08/08 Copyright 1986, 1995 J. Schilling */ +/* + * open new file on old stream + * + * Copyright (c) 1986, 1995 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 "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using fseeko()/ftello() + * instead of fseek()/ftell() if available. + */ + +LOCAL char *fmtab[] = { + "", /* 0 FI_NONE */ + "r", /* 1 FI_READ */ + "r+", /* 2 FI_WRITE **1) */ + "r+", /* 3 FI_READ | FI_WRITE */ + "b", /* 4 FI_NONE | FI_BINARY */ + "rb", /* 5 FI_READ | FI_BINARY */ + "r+b", /* 6 FI_WRITE | FI_BINARY **1) */ + "r+b", /* 7 FI_READ | FI_WRITE | FI_BINARY */ + +/* + FI_APPEND */ "", /* 0 FI_NONE */ +/* ... */ "r", /* 1 FI_READ */ + "a", /* 2 FI_WRITE **1) */ + "a+", /* 3 FI_READ | FI_WRITE */ + "b", /* 4 FI_NONE | FI_BINARY */ + "rb", /* 5 FI_READ | FI_BINARY */ + "ab", /* 6 FI_WRITE | FI_BINARY **1) */ + "a+b", /* 7 FI_READ | FI_WRITE | FI_BINARY */ + }; +/* + * NOTES: + * 1) there is no fopen() mode that opens for writing + * without creating/truncating at the same time. + * + * "w" will create/trunc files with fopen() + * "a" will create files with fopen() + */ + +EXPORT FILE * +filereopen(name, mode, fp) + const char *name; + const char *mode; + FILE *fp; +{ + int ret; + int omode = 0; + int flag = 0; + + if (!_cvmod(mode, &omode, &flag)) + return ((FILE *) NULL); + + /* + * create/truncate file if necessary + */ + if ((ret = _openfd(name, omode)) < 0) + return ((FILE *) NULL); + close(ret); + + fp = freopen(name, + fmtab[flag & (FI_READ | FI_WRITE | FI_BINARY | FI_APPEND)], fp); + + if (fp != (FILE *) NULL) { + set_my_flag(fp, 0); /* must clear it if fp is reused */ + + if (flag & FI_APPEND) { + (void) fseek(fp, (off_t)0, SEEK_END); + } + if (flag & FI_UNBUF) { + setbuf(fp, NULL); + add_my_flag(fp, _IOUNBUF); + } + } + return (fp); +} diff --git a/librols/stdio/fileseek.c b/librols/stdio/fileseek.c new file mode 100644 index 0000000..6ea0b17 --- /dev/null +++ b/librols/stdio/fileseek.c @@ -0,0 +1,53 @@ +/* + * 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. + * + */ + +/* @(#)fileseek.c 1.12 04/08/08 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" + +/* + * Note that because of a definition in schilyio.h we are using fseeko()/ftello() + * instead of fseek()/ftell() if available. + */ + +static char _seekerr[] = "file_seek_err"; + +EXPORT int +fileseek(f, pos) + register FILE *f; + off_t pos; +{ + int ret; + + down(f); + ret = fseek(f, pos, SEEK_SET); + if (ret < 0 && !(my_flag(f) & _IONORAISE)) + raisecond(_seekerr, 0L); + return (ret); +} diff --git a/librols/stdio/filesize.c b/librols/stdio/filesize.c new file mode 100644 index 0000000..cecb52b --- /dev/null +++ b/librols/stdio/filesize.c @@ -0,0 +1,47 @@ +/* + * 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. + * + */ + +/* @(#)filesize.c 1.13 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" +#include <statdefs.h> + +EXPORT off_t +filesize(f) + register FILE *f; +{ + struct stat buf; + + down(f); + if (fstat(fileno(f), &buf) < 0) { + raisecond("filesize", 0L); + return (-1); + } + return (buf.st_size); +} diff --git a/librols/stdio/filestat.c b/librols/stdio/filestat.c new file mode 100644 index 0000000..f9ba8db --- /dev/null +++ b/librols/stdio/filestat.c @@ -0,0 +1,42 @@ +/* + * 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. + * + */ + +/* @(#)filestat.c 1.9 04/08/08 Copyright 1985 J. Schilling */ +/* + * Copyright (c) 1985 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 "schilyio.h" +#include <statdefs.h> + +EXPORT int +filestat(f, stbuf) + FILE *f; + struct stat *stbuf; +{ + down(f); + return (fstat(fileno(f), stbuf)); +} diff --git a/librols/stdio/filewrite.c b/librols/stdio/filewrite.c new file mode 100644 index 0000000..dd3603f --- /dev/null +++ b/librols/stdio/filewrite.c @@ -0,0 +1,107 @@ +/* + * 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. + * + */ + +/* @(#)filewrite.c 1.14 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +static char _writeerr[] = "file_write_err"; + +#ifdef HAVE_USG_STDIO + +EXPORT int +filewrite(f, vbuf, len) + register FILE *f; + void *vbuf; + int len; +{ + register int n; + int cnt; + char *buf = vbuf; + + down2(f, _IOWRT, _IORW); + + if (f->_flag & _IONBF) { + cnt = write(fileno(f), buf, len); + if (cnt < 0) { + f->_flag |= _IOERR; + if (!(my_flag(f) & _IONORAISE)) + raisecond(_writeerr, 0L); + } + return (cnt); + } + cnt = 0; + while (len > 0) { + if (f->_cnt <= 0) { + if (usg_flsbuf((unsigned char) *buf++, f) == EOF) + break; + cnt++; + if (--len == 0) + break; + } + if ((n = f->_cnt >= len ? len : f->_cnt) > 0) { + f->_ptr = (unsigned char *)movebytes(buf, f->_ptr, n); + buf += n; + f->_cnt -= n; + cnt += n; + len -= n; + } + } + if (!ferror(f)) + return (cnt); + if (!(my_flag(f) & _IONORAISE)) + raisecond(_writeerr, 0L); + return (-1); +} + +#else + +EXPORT int +filewrite(f, vbuf, len) + register FILE *f; + void *vbuf; + int len; +{ + int cnt; + char *buf = vbuf; + + down2(f, _IOWRT, _IORW); + + if (my_flag(f) & _IOUNBUF) + return (write(fileno(f), buf, len)); + cnt = fwrite(buf, 1, len, f); + + if (!ferror(f)) + return (cnt); + if (!(my_flag(f) & _IONORAISE)) + raisecond(_writeerr, 0L); + return (-1); +} + +#endif /* HAVE_USG_STDIO */ diff --git a/librols/stdio/flag.c b/librols/stdio/flag.c new file mode 100644 index 0000000..a9571c6 --- /dev/null +++ b/librols/stdio/flag.c @@ -0,0 +1,142 @@ +/* + * 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. + * + */ + +/* @(#)flag.c 2.10 05/06/12 Copyright 1986-2003 J. Schilling */ +/* + * Copyright (c) 1986-2003 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 "schilyio.h" +#include <stdxlib.h> + +#ifdef DO_MYFLAG + +#define FL_INIT 10 + +EXPORT int _io_glflag; /* global default flag */ +LOCAL int _fl_inc = 10; /* increment for expanding flag struct */ +EXPORT int _fl_max = FL_INIT; /* max fd currently in _io_myfl */ +LOCAL _io_fl _io_smyfl[FL_INIT]; /* initial static space */ +EXPORT _io_fl *_io_myfl = _io_smyfl; /* init to static space */ + +LOCAL int _more_flags __PR((FILE *)); + +LOCAL int +_more_flags(fp) + FILE *fp; +{ + register int f = fileno(fp); + register int n = _fl_max; + register _io_fl *np; + + while (n <= f) + n += _fl_inc; + + if (_io_myfl == _io_smyfl) { + np = (_io_fl *) malloc(n * sizeof (*np)); + fillbytes(np, n * sizeof (*np), '\0'); + movebytes(_io_smyfl, np, sizeof (_io_smyfl)/sizeof (*np)); + } else { + np = (_io_fl *) realloc(_io_myfl, n * sizeof (*np)); + if (np) + fillbytes(&np[_fl_max], (n-_fl_max)*sizeof (*np), '\0'); + } + if (np) { + _io_myfl = np; + _fl_max = n; + return (_io_get_my_flag(fp)); + } else { + return (_IONORAISE); + } +} + +EXPORT int +_io_get_my_flag(fp) + register FILE *fp; +{ + register int f = fileno(fp); + register _io_fl *fl; + + if (f >= _fl_max) + return (_more_flags(fp)); + + fl = &_io_myfl[f]; + + if (fl->fl_io == 0 || fl->fl_io == fp) + return (fl->fl_flags); + + while (fl && fl->fl_io != fp) + fl = fl->fl_next; + + if (fl == 0) + return (0); + + return (fl->fl_flags); +} + +EXPORT void +_io_set_my_flag(fp, flag) + FILE *fp; + int flag; +{ + register int f = fileno(fp); + register _io_fl *fl; + register _io_fl *fl2; + + if (f >= _fl_max) + (void) _more_flags(fp); + + fl = &_io_myfl[f]; + + if (fl->fl_io != (FILE *)0) { + fl2 = fl; + + while (fl && fl->fl_io != fp) + fl = fl->fl_next; + if (fl == 0) { + if ((fl = (_io_fl *) malloc(sizeof (*fl))) == 0) + return; + fl->fl_next = fl2->fl_next; + fl2->fl_next = fl; + } + } + fl->fl_io = fp; + fl->fl_flags = flag; +} + +EXPORT void +_io_add_my_flag(fp, flag) + FILE *fp; + int flag; +{ + int oflag = _io_get_my_flag(fp); + + oflag |= flag; + + _io_set_my_flag(fp, oflag); +} + +#endif /* DO_MYFLAG */ diff --git a/librols/stdio/flush.c b/librols/stdio/flush.c new file mode 100644 index 0000000..9d9f2fa --- /dev/null +++ b/librols/stdio/flush.c @@ -0,0 +1,38 @@ +/* + * 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. + * + */ + +/* @(#)flush.c 1.7 04/08/08 Copyright 1986 J. Schilling */ +/* + * Copyright (c) 1986 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 "schilyio.h" + +EXPORT int +flush() +{ + return (fflush(stdout)); +} diff --git a/librols/stdio/fpipe.c b/librols/stdio/fpipe.c new file mode 100644 index 0000000..72f3ee9 --- /dev/null +++ b/librols/stdio/fpipe.c @@ -0,0 +1,53 @@ +/* + * 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. + * + */ + +/* @(#)fpipe.c 1.12 04/08/08 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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 "schilyio.h" + +EXPORT int +fpipe(pipef) + FILE *pipef[]; +{ + int filedes[2]; + + if (pipe(filedes) < 0) + return (0); + + if ((pipef[0] = _fcons((FILE *)0, + filedes[0], FI_READ|FI_CLOSE)) != (FILE *)0) { + if ((pipef[1] = _fcons((FILE *)0, + filedes[1], FI_WRITE|FI_CLOSE)) != (FILE *)0) { + return (1); + } + fclose(pipef[0]); + } + close(filedes[1]); + return (0); +} diff --git a/librols/stdio/niread.c b/librols/stdio/niread.c new file mode 100644 index 0000000..2f025fa --- /dev/null +++ b/librols/stdio/niread.c @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +/* @(#)niread.c 1.12 04/08/08 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Non interruptable read + * + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" +#include <errno.h> + +EXPORT int +_niread(f, buf, count) + int f; + void *buf; + int count; +{ + int ret; + int oerrno = geterrno(); + + while ((ret = read(f, buf, count)) < 0 && geterrno() == EINTR) { + /* + * Set back old 'errno' so we don't change the errno visible + * to the outside if we did not fail. + */ + seterrno(oerrno); + } + return (ret); +} diff --git a/librols/stdio/niwrite.c b/librols/stdio/niwrite.c new file mode 100644 index 0000000..a5ebd85 --- /dev/null +++ b/librols/stdio/niwrite.c @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +/* @(#)niwrite.c 1.5 04/08/08 Copyright 1986, 2001-2003 J. Schilling */ +/* + * Non interruptable write + * + * Copyright (c) 1986, 2001-2003 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 "schilyio.h" +#include <errno.h> + +EXPORT int +_niwrite(f, buf, count) + int f; + void *buf; + int count; +{ + int ret; + int oerrno = geterrno(); + + while ((ret = write(f, buf, count)) < 0 && geterrno() == EINTR) { + /* + * Set back old 'errno' so we don't change the errno visible + * to the outside if we did not fail. + */ + seterrno(oerrno); + } + return (ret); +} diff --git a/librols/stdio/nixread.c b/librols/stdio/nixread.c new file mode 100644 index 0000000..2d83987 --- /dev/null +++ b/librols/stdio/nixread.c @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +/* @(#)nixread.c 1.12 04/08/08 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Non interruptable extended read + * + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" +#include <errno.h> + +EXPORT int +_nixread(f, buf, count) + int f; + void *buf; + int count; +{ + register char *p = (char *)buf; + register int ret; + register int total = 0; + int oerrno = geterrno(); + + while (count > 0) { + while ((ret = read(f, p, count)) < 0) { + if (geterrno() == EINTR) { + /* + * Set back old 'errno' so we don't change the + * errno visible to the outside if we did + * not fail. + */ + seterrno(oerrno); + continue; + } + return (ret); /* Any other error */ + } + if (ret == 0) /* Something went wrong */ + break; + + total += ret; + count -= ret; + p += ret; + } + return (total); +} diff --git a/librols/stdio/nixwrite.c b/librols/stdio/nixwrite.c new file mode 100644 index 0000000..b9fa4df --- /dev/null +++ b/librols/stdio/nixwrite.c @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +/* @(#)nixwrite.c 1.5 04/08/08 Copyright 1986, 2001-2003 J. Schilling */ +/* + * Non interruptable extended write + * + * Copyright (c) 1986, 2001-2003 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 "schilyio.h" +#include <errno.h> + +EXPORT int +_nixwrite(f, buf, count) + int f; + void *buf; + int count; +{ + register char *p = (char *)buf; + register int ret; + register int total = 0; + int oerrno = geterrno(); + + while (count > 0) { + while ((ret = write(f, p, count)) < 0) { + if (geterrno() == EINTR) { + /* + * Set back old 'errno' so we don't change the + * errno visible to the outside if we did + * not fail. + */ + seterrno(oerrno); + continue; + } + return (ret); /* Any other error */ + } + if (ret == 0) /* EOF */ + break; + + total += ret; + count -= ret; + p += ret; + } + return (total); +} diff --git a/librols/stdio/openfd.c b/librols/stdio/openfd.c new file mode 100644 index 0000000..d0e110c --- /dev/null +++ b/librols/stdio/openfd.c @@ -0,0 +1,44 @@ +/* + * 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. + * + */ + +/* @(#)openfd.c 1.9 04/08/08 Copyright 1986, 1995 J. Schilling */ +/* + * Copyright (c) 1986, 1995 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 "schilyio.h" + +#if defined(_openfd) && !defined(USE_LARGEFILES) +# undef _openfd +#endif + +EXPORT int +_openfd(name, omode) + const char *name; + int omode; +{ + return (open(name, omode, 0666)); +} diff --git a/librols/stdio/peekc.c b/librols/stdio/peekc.c new file mode 100644 index 0000000..ce98557 --- /dev/null +++ b/librols/stdio/peekc.c @@ -0,0 +1,47 @@ +/* + * 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. + * + */ + +/* @(#)peekc.c 1.7 04/08/08 Copyright 1986, 1996-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1996-2003 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 "schilyio.h" + +EXPORT int +peekc(f) + FILE *f; +{ + int c; + + down2(f, _IOREAD, _IORW); + + if (ferror(f)) + return (EOF); + if ((c = getc(f)) != EOF) + ungetc(c, f); + return (c); +} diff --git a/librols/stdio/schilyio.h b/librols/stdio/schilyio.h new file mode 100644 index 0000000..c97f845 --- /dev/null +++ b/librols/stdio/schilyio.h @@ -0,0 +1,248 @@ +/* + * 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. + * + */ + +/* @(#)schilyio.h 2.22 04/09/04 Copyright 1986, 1995-2003 J. Schilling */ +/* + * Copyright (c) 1986, 1995-2003 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. + */ + +#ifndef _STDIO_SCHILYIO_H +#define _STDIO_SCHILYIO_H + +#include <mconfig.h> +#include <stdio.h> +#include <standard.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <schily.h> + +#ifdef NO_USG_STDIO +# ifdef HAVE_USG_STDIO +# undef HAVE_USG_STDIO +# endif +#endif + +/*#if _LFS_LARGEFILE*/ +#ifdef HAVE_LARGEFILES +/* + * XXX We may need to put this code to a more global place to allow all + * XXX users of fseek()/ftell() to automaticaly use fseeko()/ftello() + * XXX if the latter are available. + * + * If HAVE_LARGEFILES is defined, it is guaranteed that fseeko()/ftello() + * both are available. + */ +# define fseek fseeko +# define ftell ftello + +#else /* !HAVE_LARGEFILES */ +/* + * If HAVE_LARGEFILES is not defined, we depend on specific tests for + * fseeko()/ftello() which must have been done before the tests for + * Large File support have been done. + * Note that this only works if the tests used below are really done before + * the Large File autoconf test is run. This is because autoconf does no + * clean testing but instead cumulatively modifes the envivonment used for + * testing. + */ +#ifdef HAVE_FSEEKO +# define fseek fseeko +#endif +#ifdef HAVE_FTELLO +# define ftell ftello +#endif + +#endif + +/* + * speed things up... + */ +#ifndef _OPENFD_SRC +#ifdef _openfd +#undef _openfd +#endif +#define _openfd(name, omode) (open(name, omode, 0666)) +#endif + +#define DO_MYFLAG /* use local flags */ + +/* + * Flags used during fileopen(), ... by _fcons()/ _cvmod() + */ +#define FI_NONE 0x0000 /* no flags defined */ + +#define FI_READ 0x0001 /* open for reading */ +#define FI_WRITE 0x0002 /* open for writing */ +#define FI_BINARY 0x0004 /* open in binary mode */ +#define FI_APPEND 0x0008 /* append on each write */ + +#define FI_CREATE 0x0010 /* create if nessecary */ +#define FI_TRUNC 0x0020 /* truncate file on open */ +#define FI_UNBUF 0x0080 /* dont't buffer io */ +#define FI_CLOSE 0x1000 /* close file on error */ + +/* + * local flags + */ +#define _IONORAISE 01 /* do no raisecond() on errors */ +#define _IOUNBUF 02 /* do unbuffered i/o */ + +#ifdef DO_MYFLAG + +struct _io_flags { + FILE *fl_io; /* file pointer */ + struct _io_flags /* pointer to next struct */ + *fl_next; /* if more file pointer to same fd */ + int fl_flags; /* my flags */ +}; + +typedef struct _io_flags _io_fl; + +extern int _io_glflag; /* global default flag */ +extern _io_fl *_io_myfl; /* array of structs to hold my flags */ +extern int _fl_max; /* max fd currently in _io_myfl */ + +/* + * if fileno > max + * expand + * else if map[fileno].pointer == 0 + * return 0 + * else if map[fileno].pointer == p + * return map[fileno].flags + * else + * search list + */ +#define flp(p) (&_io_myfl[fileno(p)]) + +#ifdef MY_FLAG_IS_MACRO +#define my_flag(p) ((int)fileno(p) >= _fl_max ? \ + _io_get_my_flag(p) : \ + ((flp(p)->fl_io == 0 || flp(p)->fl_io == p) ? \ + flp(p)->fl_flags : \ + _io_get_my_flag(p))) +#else +#define my_flag(p) _io_get_my_flag(p) +#endif + +#define set_my_flag(p, v) _io_set_my_flag(p, v) +#define add_my_flag(p, v) _io_add_my_flag(p, v) + +extern int _io_get_my_flag __PR((FILE *)); +extern void _io_set_my_flag __PR((FILE *, int)); +extern void _io_add_my_flag __PR((FILE *, int)); + +#else /* DO_MYFLAG */ + +#define my_flag(p) _IONORAISE /* Always noraise */ +#define set_my_flag(p, v) /* Ignore */ +#define add_my_flag(p, v) /* Ignore */ + +#endif /* DO_MYFLAG */ + +#ifdef HAVE_USG_STDIO + +/* + * Use the right filbuf()/flsbuf() function. + */ +#ifdef HAVE___FILBUF +# define usg_filbuf(fp) __filbuf(fp) +# define usg_flsbuf(c, fp) __flsbuf(c, fp) +/* + * Define prototypes to verify if our interface is right + */ +extern int __filbuf __PR((FILE *)); +/*extern int __flsbuf __PR(());*/ +#else +# ifdef HAVE__FILBUF +# define usg_filbuf(fp) _filbuf(fp) +# define usg_flsbuf(c, fp) _flsbuf(c, fp) +/* + * Define prototypes to verify if our interface is right + */ +extern int _filbuf __PR((FILE *)); +/*extern int _flsbuf __PR(());*/ +# else +/* + * no filbuf() but this will not happen on USG_STDIO systems. + */ +# endif +#endif +/* + * Do not check this because flsbuf()'s 1st parameter may be + * int SunOS + * unsigned int Apollo + * unsigned char HP-UX-11 + * + * Note that the interface is now checked by autoconf. + */ +/*extern int _flsbuf __PR((int, FILE *));*/ +#else +/* + * If we are on a non USG system we cannot down file pointers + */ +#undef DO_DOWN +#endif + +#ifndef DO_DOWN +/* + * No stream checking + */ +#define down(f) +#define down1(f, fl1) +#define down2(f, fl1, fl2) +#else +/* + * Do stream checking (works only on USG stdio) + * + * New version of USG stdio. + * _iob[] holds only a small amount of pointers. + * Aditional space is allocated. + * We may check only if the file pointer is != NULL + * and if iop->_flag refers to a stream with appropriate modes. + * If _iob[] gets expanded by malloc() we cannot check upper bound. + */ +#define down(f) ((f) == 0 || (f)->_flag == 0 ? \ + (raisecond(_badfile, 0L), (FILE *)0) : (f)) + +#define down1(f, fl1) ((f) == 0 || (f)->_flag == 0 ? \ + (raisecond(_badfile, 0L), (FILE *)0) : \ + (((f)->_flag & fl1) != fl1 ? \ + (raisecond(_badop, 0L), (FILE *)0) : \ + (f))) + +#define down2(f, fl1, fl2) ((f) == 0 || (f)->_flag == 0 ? \ + (raisecond(_badfile, 0L), (FILE *)0) : \ + (((f)->_flag & fl1) != fl1 && \ + ((f)->_flag & fl2) != fl2 ? \ + (raisecond(_badop, 0L), (FILE *)0) : \ + (f))) +#endif /* DO_DOWN */ + +extern char _badfile[]; +extern char _badmode[]; +extern char _badop[]; + +#endif /* _STDIO_SCHILYIO_H */ diff --git a/librols/strcatl.c b/librols/strcatl.c new file mode 100644 index 0000000..ef393f1 --- /dev/null +++ b/librols/strcatl.c @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +/* @(#)strcatl.c 1.12 03/10/29 Copyright 1985, 1989, 1995-2003 J. Schilling */ +/* + * list version of strcat() + * + * concatenates all past first parameter until a NULL pointer is reached + * + * WARNING: a NULL constant is not a NULL pointer, so a caller must + * cast a NULL constant to a pointer: (char *)NULL + * + * returns pointer past last character (to '\0' byte) + * + * Copyright (c) 1985, 1989, 1995-2003 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 <vadefs.h> +#include <standard.h> +#include <schily.h> + +/* VARARGS3 */ +#ifdef PROTOTYPES +EXPORT char * +strcatl(char *to, ...) +#else +EXPORT char * +strcatl(to, va_alist) + char *to; + va_dcl +#endif +{ + va_list args; + register char *p; + register char *tor = to; + +#ifdef PROTOTYPES + va_start(args, to); +#else + va_start(args); +#endif + while ((p = va_arg(args, char *)) != NULL) { + while ((*tor = *p++) != '\0') { + tor++; + } + } + *tor = '\0'; + va_end(args); + return (tor); +} diff --git a/librols/strdup.c b/librols/strdup.c new file mode 100644 index 0000000..1bc5968 --- /dev/null +++ b/librols/strdup.c @@ -0,0 +1,62 @@ +/* + * 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. + * + */ + +/* @(#)strdup.c 1.1 03/02/27 Copyright 2003 J. Schilling */ +/* + * strdup() to be used if missing on libc + * + * Copyright (c) 2003 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 <standard.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <schily.h> +#include <libport.h> + +#ifndef HAVE_STRDUP + +EXPORT char * +strdup(s) + const char *s; +{ + unsigned i = strlen(s) + 1; + char *res = malloc(i); + + if (res == NULL) + return (NULL); + if (i > 16) { + movebytes(s, res, (int) i); + } else { + char *s2 = res; + + while ((*s2++ = *s++) != '\0') + ; + } + return (res); +} +#endif /* HAVE_STRDUP */ diff --git a/librols/streql.c b/librols/streql.c new file mode 100644 index 0000000..4b9a117 --- /dev/null +++ b/librols/streql.c @@ -0,0 +1,53 @@ +/* + * 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. + * + */ + +/* @(#)streql.c 1.7 03/06/15 Copyright 1985, 1995-2003 J. Schilling */ +/* + * Check if two strings are equal + * + * Copyright (c) 1985, 1995-2003 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 <standard.h> +#include <schily.h> + +EXPORT int +streql(a, b) + const char *a; + const char *b; +{ + register const char *s1 = a; + register const char *s2 = b; + + if (s1 == NULL || s2 == NULL) + return (FALSE); + + while (*s1 == *s2++) + if (*s1++ == '\0') + return (TRUE); + + return (FALSE); +} diff --git a/librols/swabbytes.c b/librols/swabbytes.c new file mode 100644 index 0000000..f2c9a57 --- /dev/null +++ b/librols/swabbytes.c @@ -0,0 +1,55 @@ +/* + * 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. + * + */ + +/* @(#)swabbytes.c 1.6 03/06/15 Copyright 1988, 1995-2003 J. Schilling */ +/* + * swab bytes in memory + * + * Copyright (c) 1988, 1995-2003 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 <standard.h> +#include <schily.h> + +#define DO8(a) a; a; a; a; a; a; a; a; + +EXPORT void +swabbytes(vp, cnt) + void *vp; + register int cnt; +{ + register char *bp = (char *)vp; + register char c; + + cnt /= 2; /* even count only */ + while ((cnt -= 8) >= 0) { + DO8(c = *bp++; bp[-1] = *bp; *bp++ = c;); + } + cnt += 8; + while (--cnt >= 0) { + c = *bp++; bp[-1] = *bp; *bp++ = c; + } +} diff --git a/librols/usleep.c b/librols/usleep.c new file mode 100644 index 0000000..780f7e3 --- /dev/null +++ b/librols/usleep.c @@ -0,0 +1,139 @@ +/* + * 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. + * + */ + +/* @(#)usleep.c 1.17 03/06/15 Copyright 1995-2003 J. Schilling */ +/* + * Copyright (c) 1995-2003 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> +#define usleep __nothing_ /* prototype in unistd.h may be different */ +#include <standard.h> +#include <stdxlib.h> +#include <timedefs.h> +#ifdef HAVE_POLL_H +# include <poll.h> +#else +# ifdef HAVE_SYS_POLL_H +# include <sys/poll.h> +# endif +#endif +#ifdef HAVE_SYS_SYSTEMINFO_H +#include <sys/systeminfo.h> +#endif +#include <libport.h> +#undef usleep + +#ifndef HAVE_USLEEP +EXPORT int usleep __PR((int usec)); +#endif + +#ifdef OPENSERVER +/* + * Don't use the usleep() from libc on SCO's OPENSERVER. + * It will kill our processes with SIGALRM. + * SCO has a usleep() prototype in unistd.h, for this reason we + * #define usleep to __nothing__ before including unistd.h + */ +#undef HAVE_USLEEP +#endif + +#ifdef apollo +/* + * Apollo sys5.3 usleep is broken. Define a version based on time_$wait. + */ +#include <apollo/base.h> +#include <apollo/time.h> +#undef HAVE_USLEEP +#endif + +#if !defined(HAVE_USLEEP) + +EXPORT int +usleep(usec) + int usec; +{ +#if defined(apollo) + /* + * Need to check apollo before HAVE_SELECT, because Apollo has select, + * but it's time wait feature is also broken :-( + */ +#define HAVE_USLEEP + /* + * XXX Do these vars need to be static on Domain/OS ??? + */ + static time_$clock_t DomainDelay; + static status_$t DomainStatus; + + /* + * DomainDelay is a 48 bit value that defines how many 4uS periods to + * delay. Since the input value range is 32 bits, the upper 16 bits of + * DomainDelay must be zero. So we just divide the input value by 4 to + * determine how many "ticks" to wait + */ + DomainDelay.c2.high16 = 0; + DomainDelay.c2.low32 = usec / 4; + time_$wait(time_$relative, DomainDelay, &DomainStatus); +#endif /* Apollo */ + +#if defined(HAVE_SELECT) && !defined(HAVE_USLEEP) +#define HAVE_USLEEP + + struct timeval tv; + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; + select(0, 0, 0, 0, &tv); +#endif + +#if defined(HAVE_POLL) && !defined(HAVE_USLEEP) +#define HAVE_USLEEP + + if (poll(0, 0, usec/1000) < 0) + comerr("poll delay failed.\n"); + +#endif + +#if defined(HAVE_NANOSLEEP) && !defined(HAVE_USLEEP) +#define HAVE_USLEEP + + struct timespec ts; + + ts.tv_sec = usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + + nanosleep(&ts, 0); +#endif + + +#if !defined(HAVE_USLEEP) +#define HAVE_USLEEP + + sleep((usec+500000)/1000000); +#endif + + return (0); +} +#endif diff --git a/libunls/CMakeLists.txt b/libunls/CMakeLists.txt new file mode 100644 index 0000000..29cb311 --- /dev/null +++ b/libunls/CMakeLists.txt @@ -0,0 +1,12 @@ +PROJECT (LIBunls C) +INCLUDE_DIRECTORIES(../include ../libhfs_iso ../wodim ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +ADD_DEFINITIONS(-DHAVE_CONFIG_H) + + IF(HAVE_ICONV_H) +ADD_DEFINITIONS(-DUSE_ICONV) + ENDIF(HAVE_ICONV_H) + + +SET(LIBunls_SRCS nls_base.c nls_config.c nls_cp10000.c nls_cp10006.c nls_cp10007.c nls_cp10029.c nls_cp10079.c nls_cp10081.c nls_cp1250.c nls_cp1251.c nls_cp437.c nls_cp737.c nls_cp775.c nls_cp850.c nls_cp852.c nls_cp855.c nls_cp857.c nls_cp860.c nls_cp861.c nls_cp862.c nls_cp863.c nls_cp864.c nls_cp865.c nls_cp866.c nls_cp869.c nls_cp874.c nls_file.c nls_iso8859-1.c nls_iso8859-14.c nls_iso8859-15.c nls_iso8859-2.c nls_iso8859-3.c nls_iso8859-4.c nls_iso8859-5.c nls_iso8859-6.c nls_iso8859-7.c nls_iso8859-8.c nls_iso8859-9.c nls_koi8-r.c nls_koi8-u.c nls_iconv.c) +#SET_SOURCE_FILES_PROPERTIES(${LIBunls_SRCS} PROPERTIES ) +ADD_LIBRARY (unls STATIC ${LIBunls_SRCS}) diff --git a/libunls/nls.h b/libunls/nls.h new file mode 100644 index 0000000..1165036 --- /dev/null +++ b/libunls/nls.h @@ -0,0 +1,130 @@ +/* + * 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. + * + */ + +/* @(#)nls.h 1.7 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * Thanks to Georgy Salnikov <sge@nmr.nioch.nsc.ru> + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ + +#ifndef _NLS_H +#define _NLS_H + +#include <unls.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT + +#define CONFIG_NLS_CODEPAGE_437 +#define CONFIG_NLS_CODEPAGE_737 +#define CONFIG_NLS_CODEPAGE_775 +#define CONFIG_NLS_CODEPAGE_850 +#define CONFIG_NLS_CODEPAGE_852 +#define CONFIG_NLS_CODEPAGE_855 +#define CONFIG_NLS_CODEPAGE_857 +#define CONFIG_NLS_CODEPAGE_860 +#define CONFIG_NLS_CODEPAGE_861 +#define CONFIG_NLS_CODEPAGE_862 +#define CONFIG_NLS_CODEPAGE_863 +#define CONFIG_NLS_CODEPAGE_864 +#define CONFIG_NLS_CODEPAGE_865 +#define CONFIG_NLS_CODEPAGE_866 +#define CONFIG_NLS_CODEPAGE_869 +#define CONFIG_NLS_CODEPAGE_874 +#define CONFIG_NLS_CODEPAGE_1250 +#define CONFIG_NLS_CODEPAGE_1251 +#define CONFIG_NLS_ISO8859_1 +#define CONFIG_NLS_ISO8859_2 +#define CONFIG_NLS_ISO8859_3 +#define CONFIG_NLS_ISO8859_4 +#define CONFIG_NLS_ISO8859_5 +#define CONFIG_NLS_ISO8859_6 +#define CONFIG_NLS_ISO8859_7 +#define CONFIG_NLS_ISO8859_8 +#define CONFIG_NLS_ISO8859_9 +#define CONFIG_NLS_ISO8859_14 +#define CONFIG_NLS_ISO8859_15 +#define CONFIG_NLS_KOI8_R +#define CONFIG_NLS_KOI8_U + +#define CONFIG_NLS_CODEPAGE_10000 +#define CONFIG_NLS_CODEPAGE_10006 +#define CONFIG_NLS_CODEPAGE_10007 +#define CONFIG_NLS_CODEPAGE_10029 +#define CONFIG_NLS_CODEPAGE_10079 +#define CONFIG_NLS_CODEPAGE_10081 + +extern int init_unls_iso8859_1(void); +extern int init_unls_iso8859_2(void); +extern int init_unls_iso8859_3(void); +extern int init_unls_iso8859_4(void); +extern int init_unls_iso8859_5(void); +extern int init_unls_iso8859_6(void); +extern int init_unls_iso8859_7(void); +extern int init_unls_iso8859_8(void); +extern int init_unls_iso8859_9(void); +extern int init_unls_iso8859_14(void); +extern int init_unls_iso8859_15(void); +extern int init_unls_cp437(void); +extern int init_unls_cp737(void); +extern int init_unls_cp775(void); +extern int init_unls_cp850(void); +extern int init_unls_cp852(void); +extern int init_unls_cp855(void); +extern int init_unls_cp857(void); +extern int init_unls_cp860(void); +extern int init_unls_cp861(void); +extern int init_unls_cp862(void); +extern int init_unls_cp863(void); +extern int init_unls_cp864(void); +extern int init_unls_cp865(void); +extern int init_unls_cp866(void); +extern int init_unls_cp869(void); +extern int init_unls_cp874(void); +extern int init_unls_cp1250(void); +extern int init_unls_cp1251(void); +extern int init_unls_koi8_r(void); +extern int init_unls_koi8_u(void); + +extern int init_unls_cp10000(void); +extern int init_unls_cp10006(void); +extern int init_unls_cp10007(void); +extern int init_unls_cp10029(void); +extern int init_unls_cp10079(void); +extern int init_unls_cp10081(void); +extern int init_unls_file(char *name); + +#ifdef USE_ICONV +extern int init_nls_iconv(char *name); +#endif + +#endif /* _NLS_H */ diff --git a/libunls/nls_base.c b/libunls/nls_base.c new file mode 100644 index 0000000..e89aa44 --- /dev/null +++ b/libunls/nls_base.c @@ -0,0 +1,263 @@ +/* + * 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. + * + */ + +/* @(#)nls_base.c 1.5 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * Thanks to Georgy Salnikov <sge@nmr.nioch.nsc.ru> + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls.c + * + * Native language support--charsets and unicode translations. + * By Gordon Chaffee 1996, 1997 + * + */ + +#include <mconfig.h> +#include <stdio.h> +#include <strdefs.h> +#include <errno.h> +#include "nls.h" + +static struct unls_table *tables = (struct unls_table *) NULL; + +int +register_unls(struct unls_table *unls) +{ + struct unls_table ** tmp = &tables; + + if (!unls) + return (-EINVAL); + if (unls->unls_next) + return (-EBUSY); + while (*tmp) { + if (unls == *tmp) { + return (-EBUSY); + } + tmp = &(*tmp)->unls_next; + } + unls->unls_next = tables; + tables = unls; + return (0); +} + +int +unregister_unls(struct unls_table *unls) +{ + struct unls_table ** tmp = &tables; + + while (*tmp) { + if (unls == *tmp) { + *tmp = unls->unls_next; + return (0); + } + tmp = &(*tmp)->unls_next; + } + return (-EINVAL); +} + +struct unls_table * +find_unls(char *charset) +{ + struct unls_table *unls = tables; + while (unls) { + if (strcmp(unls->unls_name, charset) == 0) + return (unls); + unls = unls->unls_next; + } + return (NULL); +} + +void +list_unls() +{ + struct unls_table *unls = tables; + while (unls) { + fprintf(stderr, "%s\n", unls->unls_name); + unls = unls->unls_next; + } +} + +struct unls_table * +load_unls(char *charset) +{ + struct unls_table *unls; + + unls = find_unls(charset); + if (unls) { + return (unls); + } + + return (NULL); +} + +void +unload_unls(struct unls_table *nls) +{ +} + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x80, 0x00}, {0x81, 0x00}, {0x82, 0x00}, {0x83, 0x00}, + {0x84, 0x00}, {0x85, 0x00}, {0x86, 0x00}, {0x87, 0x00}, + {0x88, 0x00}, {0x89, 0x00}, {0x8a, 0x00}, {0x8b, 0x00}, + {0x8c, 0x00}, {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0x00}, + /* 0x90*/ + {0x90, 0x00}, {0x91, 0x00}, {0x92, 0x00}, {0x93, 0x00}, + {0x94, 0x00}, {0x95, 0x00}, {0x96, 0x00}, {0x97, 0x00}, + {0x98, 0x00}, {0x99, 0x00}, {0x9a, 0x00}, {0x9b, 0x00}, + {0x9c, 0x00}, {0x9d, 0x00}, {0x9e, 0x00}, {0x9f, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0xa1, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa4, 0x00}, {0xa5, 0x00}, {0xa6, 0x00}, {0xa7, 0x00}, + {0xa8, 0x00}, {0xa9, 0x00}, {0xaa, 0x00}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0xaf, 0x00}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00}, + {0xb4, 0x00}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00}, + {0xb8, 0x00}, {0xb9, 0x00}, {0xba, 0x00}, {0xbb, 0x00}, + {0xbc, 0x00}, {0xbd, 0x00}, {0xbe, 0x00}, {0xbf, 0x00}, + /* 0xc0*/ + {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00}, + {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00}, + /* 0xd0*/ + {0xd0, 0x00}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00}, + {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0xd7, 0x00}, + {0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0xdd, 0x00}, {0xde, 0x00}, {0xdf, 0x00}, + /* 0xe0*/ + {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00}, + {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00}, + {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, + {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00}, + /* 0xf0*/ + {0xf0, 0x00}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00}, + {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0xf7, 0x00}, + {0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0xfd, 0x00}, {0xfe, 0x00}, {0xff, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00 +}; + + +static struct unls_table default_table = { + "default", + page_uni2charset, + charset2uni, + NULL +}; + + + +/* Returns a simple default translation table */ +struct unls_table * +load_unls_default() +{ + return (&default_table); +} diff --git a/libunls/nls_config.c b/libunls/nls_config.c new file mode 100644 index 0000000..ec2b9f6 --- /dev/null +++ b/libunls/nls_config.c @@ -0,0 +1,156 @@ +/* + * 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. + * + */ + +/* @(#)nls_config.c 1.5 05/05/01 2000,2001 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * This file contains code taken from nls_base.c to avoid loops + * in dependency reported by tsort. + * + * Thanks to Georgy Salnikov <sge@nmr.nioch.nsc.ru> + * + * Code taken from the Linux kernel. + */ +/* + * 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 "nls.h" + +int +init_unls() +{ +#ifdef CONFIG_NLS_ISO8859_1 + init_unls_iso8859_1(); +#endif +#ifdef CONFIG_NLS_ISO8859_2 + init_unls_iso8859_2(); +#endif +#ifdef CONFIG_NLS_ISO8859_3 + init_unls_iso8859_3(); +#endif +#ifdef CONFIG_NLS_ISO8859_4 + init_unls_iso8859_4(); +#endif +#ifdef CONFIG_NLS_ISO8859_5 + init_unls_iso8859_5(); +#endif +#ifdef CONFIG_NLS_ISO8859_6 + init_unls_iso8859_6(); +#endif +#ifdef CONFIG_NLS_ISO8859_7 + init_unls_iso8859_7(); +#endif +#ifdef CONFIG_NLS_ISO8859_8 + init_unls_iso8859_8(); +#endif +#ifdef CONFIG_NLS_ISO8859_9 + init_unls_iso8859_9(); +#endif +#ifdef CONFIG_NLS_ISO8859_14 + init_unls_iso8859_14(); +#endif +#ifdef CONFIG_NLS_ISO8859_15 + init_unls_iso8859_15(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_437 + init_unls_cp437(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_737 + init_unls_cp737(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_775 + init_unls_cp775(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_850 + init_unls_cp850(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_852 + init_unls_cp852(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_855 + init_unls_cp855(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_857 + init_unls_cp857(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_860 + init_unls_cp860(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_861 + init_unls_cp861(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_862 + init_unls_cp862(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_863 + init_unls_cp863(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_864 + init_unls_cp864(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_865 + init_unls_cp865(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_866 + init_unls_cp866(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_869 + init_unls_cp869(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_874 + init_unls_cp874(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_1250 + init_unls_cp1250(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_1251 + init_unls_cp1251(); +#endif +#ifdef CONFIG_NLS_KOI8_R + init_unls_koi8_r(); +#endif +#ifdef CONFIG_NLS_KOI8_U + init_unls_koi8_u(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_10000 + init_unls_cp10000(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_10006 + init_unls_cp10006(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_10007 + init_unls_cp10007(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_10029 + init_unls_cp10029(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_10079 + init_unls_cp10079(); +#endif +#ifdef CONFIG_NLS_CODEPAGE_10081 + init_unls_cp10081(); +#endif + return (0); +} diff --git a/libunls/nls_cp10000.c b/libunls/nls_cp10000.c new file mode 100644 index 0000000..cc4a5b5 --- /dev/null +++ b/libunls/nls_cp10000.c @@ -0,0 +1,607 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp10000.c 1.3 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code generated by James Pearson j.pearson@ge.ucl.ac.uk 26/4/2000 + * based on a script by Gordon Chaffee <chaffee@bmrc.berkeley.edu> + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp10000.c + * + * Charset cp10000 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc4, 0x00}, {0xc5, 0x00}, {0xc7, 0x00}, {0xc9, 0x00}, + {0xd1, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xe1, 0x00}, + {0xe0, 0x00}, {0xe2, 0x00}, {0xe4, 0x00}, {0xe3, 0x00}, + {0xe5, 0x00}, {0xe7, 0x00}, {0xe9, 0x00}, {0xe8, 0x00}, + /* 0x90*/ + {0xea, 0x00}, {0xeb, 0x00}, {0xed, 0x00}, {0xec, 0x00}, + {0xee, 0x00}, {0xef, 0x00}, {0xf1, 0x00}, {0xf3, 0x00}, + {0xf2, 0x00}, {0xf4, 0x00}, {0xf6, 0x00}, {0xf5, 0x00}, + {0xfa, 0x00}, {0xf9, 0x00}, {0xfb, 0x00}, {0xfc, 0x00}, + /* 0xa0*/ + {0x20, 0x20}, {0xb0, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa7, 0x00}, {0x22, 0x20}, {0xb6, 0x00}, {0xdf, 0x00}, + {0xae, 0x00}, {0xa9, 0x00}, {0x22, 0x21}, {0xb4, 0x00}, + {0xa8, 0x00}, {0x60, 0x22}, {0xc6, 0x00}, {0xd8, 0x00}, + /* 0xb0*/ + {0x1e, 0x22}, {0xb1, 0x00}, {0x64, 0x22}, {0x65, 0x22}, + {0xa5, 0x00}, {0xb5, 0x00}, {0x02, 0x22}, {0x11, 0x22}, + {0x0f, 0x22}, {0xc0, 0x03}, {0x2b, 0x22}, {0xaa, 0x00}, + {0xba, 0x00}, {0xa9, 0x03}, {0xe6, 0x00}, {0xf8, 0x00}, + /* 0xc0*/ + {0xbf, 0x00}, {0xa1, 0x00}, {0xac, 0x00}, {0x1a, 0x22}, + {0x92, 0x01}, {0x48, 0x22}, {0x06, 0x22}, {0xab, 0x00}, + {0xbb, 0x00}, {0x26, 0x20}, {0xa0, 0x00}, {0xc0, 0x00}, + {0xc3, 0x00}, {0xd5, 0x00}, {0x52, 0x01}, {0x53, 0x01}, + /* 0xd0*/ + {0x13, 0x20}, {0x14, 0x20}, {0x1c, 0x20}, {0x1d, 0x20}, + {0x18, 0x20}, {0x19, 0x20}, {0xf7, 0x00}, {0xca, 0x25}, + {0xff, 0x00}, {0x78, 0x01}, {0x44, 0x20}, {0xac, 0x20}, + {0x39, 0x20}, {0x3a, 0x20}, {0x01, 0xfb}, {0x02, 0xfb}, + /* 0xe0*/ + {0x21, 0x20}, {0xb7, 0x00}, {0x1a, 0x20}, {0x1e, 0x20}, + {0x30, 0x20}, {0xc2, 0x00}, {0xca, 0x00}, {0xc1, 0x00}, + {0xcb, 0x00}, {0xc8, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, + {0xcf, 0x00}, {0xcc, 0x00}, {0xd3, 0x00}, {0xd4, 0x00}, + /* 0xf0*/ + {0xff, 0xf8}, {0xd2, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xd9, 0x00}, {0x31, 0x01}, {0xc6, 0x02}, {0xdc, 0x02}, + {0xaf, 0x00}, {0xd8, 0x02}, {0xd9, 0x02}, {0xda, 0x02}, + {0xb8, 0x00}, {0xdd, 0x02}, {0xdb, 0x02}, {0xc7, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xca, 0xc1, 0xa2, 0xa3, 0x00, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0x00, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0xd8, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0xe0, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char pagef8[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, /* 0xf8-0xff */ +}; + +static unsigned char pagefb[256] = { + 0x00, 0xde, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, page22, NULL, NULL, page25, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + pagef8, NULL, NULL, pagefb, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xe7, /* 0x80-0x87 */ + 0xcb, 0xe5, 0x80, 0xcc, 0x81, 0x82, 0x83, 0xe9, /* 0x88-0x8f */ + 0xe6, 0xe8, 0xea, 0xed, 0xeb, 0xec, 0x84, 0xee, /* 0x90-0x97 */ + 0xf1, 0xef, 0x85, 0xcd, 0xf2, 0xf4, 0xf3, 0x86, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0x53, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x50, 0xba, 0xbb, 0xbc, 0xbd, 0xae, 0xaf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0x46, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd9, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0x49, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x8a, 0x8c, 0x8d, 0x8e, 0x96, 0x9a, 0x9f, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xbe, 0xbf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0x88, 0x8b, 0x9b, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x89, 0x90, 0x87, /* 0xe0-0xe7 */ + 0x91, 0x8f, 0x92, 0x94, 0x95, 0x93, 0x97, 0x99, /* 0xe8-0xef */ + 0xf0, 0x98, 0x9c, 0x9e, 0x9d, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp10000", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp10000() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp10006.c b/libunls/nls_cp10006.c new file mode 100644 index 0000000..8405fbe --- /dev/null +++ b/libunls/nls_cp10006.c @@ -0,0 +1,499 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp10006.c 1.3 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code generated by James Pearson j.pearson@ge.ucl.ac.uk 17/8/2000 + * based on a script by Gordon Chaffee <chaffee@bmrc.berkeley.edu> + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp10006.c + * + * Charset cp10006 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x10*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x00, 0x00}, + /* 0x80*/ + {0xc4, 0x00}, {0xb9, 0x00}, {0xb2, 0x00}, {0xc9, 0x00}, + {0xb3, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0x85, 0x03}, + {0xe0, 0x00}, {0xe2, 0x00}, {0xe4, 0x00}, {0x84, 0x03}, + {0xa8, 0x00}, {0xe7, 0x00}, {0xe9, 0x00}, {0xe8, 0x00}, + /* 0x90*/ + {0xea, 0x00}, {0xeb, 0x00}, {0xa3, 0x00}, {0x22, 0x21}, + {0xee, 0x00}, {0xef, 0x00}, {0x22, 0x20}, {0xbd, 0x00}, + {0x30, 0x20}, {0xf4, 0x00}, {0xf6, 0x00}, {0xa6, 0x00}, + {0xad, 0x00}, {0xf9, 0x00}, {0xfb, 0x00}, {0xfc, 0x00}, + /* 0xa0*/ + {0x20, 0x20}, {0x93, 0x03}, {0x94, 0x03}, {0x98, 0x03}, + {0x9b, 0x03}, {0x9e, 0x03}, {0xa0, 0x03}, {0xdf, 0x00}, + {0xae, 0x00}, {0xa9, 0x00}, {0xa3, 0x03}, {0xaa, 0x03}, + {0xa7, 0x00}, {0x60, 0x22}, {0xb0, 0x00}, {0xb7, 0x00}, + /* 0xb0*/ + {0x91, 0x03}, {0xb1, 0x00}, {0x64, 0x22}, {0x65, 0x22}, + {0xa5, 0x00}, {0x92, 0x03}, {0x95, 0x03}, {0x96, 0x03}, + {0x97, 0x03}, {0x99, 0x03}, {0x9a, 0x03}, {0x9c, 0x03}, + {0xa6, 0x03}, {0xab, 0x03}, {0xa8, 0x03}, {0xa9, 0x03}, + /* 0xc0*/ + {0xac, 0x03}, {0x9d, 0x03}, {0xac, 0x00}, {0x9f, 0x03}, + {0xa1, 0x03}, {0x48, 0x22}, {0xa4, 0x03}, {0xab, 0x00}, + {0xbb, 0x00}, {0x26, 0x20}, {0xa0, 0x00}, {0xa5, 0x03}, + {0xa7, 0x03}, {0x86, 0x03}, {0x88, 0x03}, {0x53, 0x01}, + /* 0xd0*/ + {0x13, 0x20}, {0x15, 0x20}, {0x1c, 0x20}, {0x1d, 0x20}, + {0x18, 0x20}, {0x19, 0x20}, {0xf7, 0x00}, {0x89, 0x03}, + {0x8a, 0x03}, {0x8c, 0x03}, {0x8e, 0x03}, {0xad, 0x03}, + {0xae, 0x03}, {0xaf, 0x03}, {0xcc, 0x03}, {0x8f, 0x03}, + /* 0xe0*/ + {0xcd, 0x03}, {0xb1, 0x03}, {0xb2, 0x03}, {0xc8, 0x03}, + {0xb4, 0x03}, {0xb5, 0x03}, {0xc6, 0x03}, {0xb3, 0x03}, + {0xb7, 0x03}, {0xb9, 0x03}, {0xbe, 0x03}, {0xba, 0x03}, + {0xbb, 0x03}, {0xbc, 0x03}, {0xbd, 0x03}, {0xbf, 0x03}, + /* 0xf0*/ + {0xc0, 0x03}, {0xce, 0x03}, {0xc1, 0x03}, {0xc3, 0x03}, + {0xc4, 0x03}, {0xb8, 0x03}, {0xc9, 0x03}, {0xc2, 0x03}, + {0xc7, 0x03}, {0xc5, 0x03}, {0xb6, 0x03}, {0xca, 0x03}, + {0xcb, 0x03}, {0x90, 0x03}, {0xb0, 0x03}, {0xa0, 0xf8}, +}; + +static unsigned char page00[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xca, 0x00, 0x00, 0x92, 0x00, 0xb4, 0x9b, 0xac, /* 0xa0-0xa7 */ + 0x8c, 0xa9, 0x00, 0xc7, 0xc2, 0x9c, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xae, 0xb1, 0x82, 0x84, 0x00, 0x00, 0x00, 0xaf, /* 0xb0-0xb7 */ + 0x00, 0x81, 0x00, 0xc8, 0x00, 0x97, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x00, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x00, 0x00, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0x00, 0x9d, 0x00, 0x9e, 0x9f, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x8b, 0x87, 0xcd, 0x00, /* 0x80-0x87 */ + 0xce, 0xd7, 0xd8, 0x00, 0xd9, 0x00, 0xda, 0xdf, /* 0x88-0x8f */ + 0xfd, 0xb0, 0xb5, 0xa1, 0xa2, 0xb6, 0xb7, 0xb8, /* 0x90-0x97 */ + 0xa3, 0xb9, 0xba, 0xa4, 0xbb, 0xc1, 0xa5, 0xc3, /* 0x98-0x9f */ + 0xa6, 0xc4, 0x00, 0xaa, 0xc6, 0xcb, 0xbc, 0xcc, /* 0xa0-0xa7 */ + 0xbe, 0xbf, 0xab, 0xbd, 0xc0, 0xdb, 0xdc, 0xdd, /* 0xa8-0xaf */ + 0xfe, 0xe1, 0xe2, 0xe7, 0xe4, 0xe5, 0xfa, 0xe8, /* 0xb0-0xb7 */ + 0xf5, 0xe9, 0xeb, 0xec, 0xed, 0xee, 0xea, 0xef, /* 0xb8-0xbf */ + 0xf0, 0xf2, 0xf7, 0xf3, 0xf4, 0xf9, 0xe6, 0xf8, /* 0xc0-0xc7 */ + 0xe3, 0xf6, 0xfb, 0xfc, 0xde, 0xe0, 0xf1, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0x00, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0x96, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char pagef8[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, page22, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + pagef8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x41, 0x41, 0x80, 0x8b, 0x8c, 0x43, 0x83, 0x45, /* 0x88-0x8f */ + 0x45, 0x45, 0x92, 0x93, 0x49, 0x49, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x4f, 0x85, 0x9b, 0x9c, 0x55, 0x55, 0x86, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0x53, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xcd, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xce, 0xd7, 0xd8, 0xd9, 0xdf, /* 0xd8-0xdf */ + 0xda, 0xb0, 0xb5, 0xbe, 0xa2, 0xb6, 0xbc, 0xa1, /* 0xe0-0xe7 */ + 0xb8, 0xb9, 0xa5, 0xba, 0xa4, 0xbb, 0xc1, 0xc3, /* 0xe8-0xef */ + 0xa6, 0xdf, 0xc4, 0xaa, 0xc6, 0xa3, 0xbf, 0xaa, /* 0xf0-0xf7 */ + 0xcc, 0xcb, 0xb7, 0xab, 0xbd, 0xb9, 0xcb, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x8a, 0x81, 0x82, 0x8e, 0x84, 0x9a, 0x9f, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xe7, 0xe4, 0xf5, 0xec, 0xea, 0xf0, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xf3, 0xfb, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xe1, 0xb1, 0xb2, 0xb3, 0xb4, 0xe2, 0xe5, 0xfa, /* 0xb0-0xb7 */ + 0xe8, 0xe9, 0xeb, 0xed, 0xe6, 0xfc, 0xe3, 0xf6, /* 0xb8-0xbf */ + 0xc0, 0xee, 0xc2, 0xef, 0xf2, 0xc5, 0xf4, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xf9, 0xf8, 0xc0, 0xdb, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xdc, /* 0xd0-0xd7 */ + 0xdd, 0xde, 0xe0, 0xdb, 0xdc, 0xdd, 0xde, 0xf1, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp10006", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp10006() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp10007.c b/libunls/nls_cp10007.c new file mode 100644 index 0000000..e743aad --- /dev/null +++ b/libunls/nls_cp10007.c @@ -0,0 +1,436 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp10007.c 1.3 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code generated by James Pearson j.pearson@ge.ucl.ac.uk 17/8/2000 + * based on a script by Gordon Chaffee <chaffee@bmrc.berkeley.edu> + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp10007.c + * + * Charset cp10007 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x10*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x00, 0x00}, + /* 0x80*/ + {0x10, 0x04}, {0x11, 0x04}, {0x12, 0x04}, {0x13, 0x04}, + {0x14, 0x04}, {0x15, 0x04}, {0x16, 0x04}, {0x17, 0x04}, + {0x18, 0x04}, {0x19, 0x04}, {0x1a, 0x04}, {0x1b, 0x04}, + {0x1c, 0x04}, {0x1d, 0x04}, {0x1e, 0x04}, {0x1f, 0x04}, + /* 0x90*/ + {0x20, 0x04}, {0x21, 0x04}, {0x22, 0x04}, {0x23, 0x04}, + {0x24, 0x04}, {0x25, 0x04}, {0x26, 0x04}, {0x27, 0x04}, + {0x28, 0x04}, {0x29, 0x04}, {0x2a, 0x04}, {0x2b, 0x04}, + {0x2c, 0x04}, {0x2d, 0x04}, {0x2e, 0x04}, {0x2f, 0x04}, + /* 0xa0*/ + {0x20, 0x20}, {0xb0, 0x00}, {0x90, 0x04}, {0xa3, 0x00}, + {0xa7, 0x00}, {0x22, 0x20}, {0xb6, 0x00}, {0x06, 0x04}, + {0xae, 0x00}, {0xa9, 0x00}, {0x22, 0x21}, {0x02, 0x04}, + {0x52, 0x04}, {0x60, 0x22}, {0x03, 0x04}, {0x53, 0x04}, + /* 0xb0*/ + {0x1e, 0x22}, {0xb1, 0x00}, {0x64, 0x22}, {0x65, 0x22}, + {0x56, 0x04}, {0xb5, 0x00}, {0x91, 0x04}, {0x08, 0x04}, + {0x04, 0x04}, {0x54, 0x04}, {0x07, 0x04}, {0x57, 0x04}, + {0x09, 0x04}, {0x59, 0x04}, {0x0a, 0x04}, {0x5a, 0x04}, + /* 0xc0*/ + {0x58, 0x04}, {0x05, 0x04}, {0xac, 0x00}, {0x1a, 0x22}, + {0x92, 0x01}, {0x48, 0x22}, {0x06, 0x22}, {0xab, 0x00}, + {0xbb, 0x00}, {0x26, 0x20}, {0xa0, 0x00}, {0x0b, 0x04}, + {0x5b, 0x04}, {0x0c, 0x04}, {0x5c, 0x04}, {0x55, 0x04}, + /* 0xd0*/ + {0x13, 0x20}, {0x14, 0x20}, {0x1c, 0x20}, {0x1d, 0x20}, + {0x18, 0x20}, {0x19, 0x20}, {0xf7, 0x00}, {0x1e, 0x20}, + {0x0e, 0x04}, {0x5e, 0x04}, {0x0f, 0x04}, {0x5f, 0x04}, + {0x16, 0x21}, {0x01, 0x04}, {0x51, 0x04}, {0x4f, 0x04}, + /* 0xe0*/ + {0x30, 0x04}, {0x31, 0x04}, {0x32, 0x04}, {0x33, 0x04}, + {0x34, 0x04}, {0x35, 0x04}, {0x36, 0x04}, {0x37, 0x04}, + {0x38, 0x04}, {0x39, 0x04}, {0x3a, 0x04}, {0x3b, 0x04}, + {0x3c, 0x04}, {0x3d, 0x04}, {0x3e, 0x04}, {0x3f, 0x04}, + /* 0xf0*/ + {0x40, 0x04}, {0x41, 0x04}, {0x42, 0x04}, {0x43, 0x04}, + {0x44, 0x04}, {0x45, 0x04}, {0x46, 0x04}, {0x47, 0x04}, + {0x48, 0x04}, {0x49, 0x04}, {0x4a, 0x04}, {0x4b, 0x04}, + {0x4c, 0x04}, {0x4d, 0x04}, {0x4e, 0x04}, {0xac, 0x20}, +}; + +static unsigned char page00[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xca, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xc7, 0xc2, 0x00, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xa6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0xdd, 0xab, 0xae, 0xb8, 0xc1, 0xa7, 0xba, /* 0x00-0x07 */ + 0xb7, 0xbc, 0xbe, 0xcb, 0xcd, 0x00, 0xd8, 0xda, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0x48-0x4f */ + 0x00, 0xde, 0xac, 0xaf, 0xb9, 0xcf, 0xb4, 0xbb, /* 0x50-0x57 */ + 0xc0, 0xbd, 0xbf, 0xcc, 0xce, 0x00, 0xd9, 0xdb, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xa2, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0xd7, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, page22, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xad, 0xae, 0xae, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xa7, 0xb5, 0xa2, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb8, 0xba, 0xba, 0xbc, 0xbc, 0xbe, 0xbe, /* 0xb8-0xbf */ + 0xb7, 0xc1, 0xc2, 0xc3, 0x46, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcd, 0xcd, 0xc1, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd8, 0xda, 0xda, 0xdc, 0xdd, 0xdd, 0x9f, /* 0xd8-0xdf */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0xe0-0xe7 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0xe8-0xef */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0xf0-0xf7 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x80-0x87 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x88-0x8f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x90-0x97 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xb4, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xac, 0xac, 0xad, 0xaf, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xc0, /* 0xb0-0xb7 */ + 0xb9, 0xb9, 0xbb, 0xbb, 0xbd, 0xbd, 0xbf, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xcf, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcc, 0xcc, 0xce, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd9, 0xd9, 0xdb, 0xdb, 0xdc, 0xde, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp10007", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp10007() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp10029.c b/libunls/nls_cp10029.c new file mode 100644 index 0000000..afdbac0 --- /dev/null +++ b/libunls/nls_cp10029.c @@ -0,0 +1,472 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp10029.c 1.3 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code generated by James Pearson j.pearson@ge.ucl.ac.uk 17/8/2000 + * based on a script by Gordon Chaffee <chaffee@bmrc.berkeley.edu> + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp10029.c + * + * Charset cp10029 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x10*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x00, 0x00}, + /* 0x80*/ + {0xc4, 0x00}, {0x00, 0x01}, {0x01, 0x01}, {0xc9, 0x00}, + {0x04, 0x01}, {0xd6, 0x00}, {0xdc, 0x00}, {0xe1, 0x00}, + {0x05, 0x01}, {0x0c, 0x01}, {0xe4, 0x00}, {0x0d, 0x01}, + {0x06, 0x01}, {0x07, 0x01}, {0xe9, 0x00}, {0x79, 0x01}, + /* 0x90*/ + {0x7a, 0x01}, {0x0e, 0x01}, {0xed, 0x00}, {0x0f, 0x01}, + {0x12, 0x01}, {0x13, 0x01}, {0x16, 0x01}, {0xf3, 0x00}, + {0x17, 0x01}, {0xf4, 0x00}, {0xf6, 0x00}, {0xf5, 0x00}, + {0xfa, 0x00}, {0x1a, 0x01}, {0x1b, 0x01}, {0xfc, 0x00}, + /* 0xa0*/ + {0x20, 0x20}, {0xb0, 0x00}, {0x18, 0x01}, {0xa3, 0x00}, + {0xa7, 0x00}, {0x22, 0x20}, {0xb6, 0x00}, {0xdf, 0x00}, + {0xae, 0x00}, {0xa9, 0x00}, {0x22, 0x21}, {0x19, 0x01}, + {0xa8, 0x00}, {0x60, 0x22}, {0x23, 0x01}, {0x2e, 0x01}, + /* 0xb0*/ + {0x2f, 0x01}, {0x2a, 0x01}, {0x64, 0x22}, {0x65, 0x22}, + {0x2b, 0x01}, {0x36, 0x01}, {0x02, 0x22}, {0x11, 0x22}, + {0x42, 0x01}, {0x3b, 0x01}, {0x3c, 0x01}, {0x3d, 0x01}, + {0x3e, 0x01}, {0x39, 0x01}, {0x3a, 0x01}, {0x45, 0x01}, + /* 0xc0*/ + {0x46, 0x01}, {0x43, 0x01}, {0xac, 0x00}, {0x1a, 0x22}, + {0x44, 0x01}, {0x47, 0x01}, {0x06, 0x22}, {0xab, 0x00}, + {0xbb, 0x00}, {0x26, 0x20}, {0xa0, 0x00}, {0x48, 0x01}, + {0x50, 0x01}, {0xd5, 0x00}, {0x51, 0x01}, {0x4c, 0x01}, + /* 0xd0*/ + {0x13, 0x20}, {0x14, 0x20}, {0x1c, 0x20}, {0x1d, 0x20}, + {0x18, 0x20}, {0x19, 0x20}, {0xf7, 0x00}, {0xca, 0x25}, + {0x4d, 0x01}, {0x54, 0x01}, {0x55, 0x01}, {0x58, 0x01}, + {0x39, 0x20}, {0x3a, 0x20}, {0x59, 0x01}, {0x56, 0x01}, + /* 0xe0*/ + {0x57, 0x01}, {0x60, 0x01}, {0x1a, 0x20}, {0x1e, 0x20}, + {0x61, 0x01}, {0x5a, 0x01}, {0x5b, 0x01}, {0xc1, 0x00}, + {0x64, 0x01}, {0x65, 0x01}, {0xcd, 0x00}, {0x7d, 0x01}, + {0x7e, 0x01}, {0x6a, 0x01}, {0xd3, 0x00}, {0xd4, 0x00}, + /* 0xf0*/ + {0x6b, 0x01}, {0x6e, 0x01}, {0xda, 0x00}, {0x6f, 0x01}, + {0x70, 0x01}, {0x71, 0x01}, {0x72, 0x01}, {0x73, 0x01}, + {0xdd, 0x00}, {0xfd, 0x00}, {0x37, 0x01}, {0x7b, 0x01}, + {0x41, 0x01}, {0x7c, 0x01}, {0x22, 0x01}, {0xc7, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xca, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0x00, 0xc7, 0xc2, 0x00, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xe7, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x83, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xf2, 0x00, 0x86, 0xf8, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x00, 0x87, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x8e, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x9c, 0x00, 0x9f, 0xf9, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x81, 0x82, 0x00, 0x00, 0x84, 0x88, 0x8c, 0x8d, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x8b, 0x91, 0x93, /* 0x08-0x0f */ + 0x00, 0x00, 0x94, 0x95, 0x00, 0x00, 0x96, 0x98, /* 0x10-0x17 */ + 0xa2, 0xab, 0x9d, 0x9e, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xfe, 0xae, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xb1, 0xb4, 0x00, 0x00, 0xaf, 0xb0, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xfa, /* 0x30-0x37 */ + 0x00, 0xbd, 0xbe, 0xb9, 0xba, 0xbb, 0xbc, 0x00, /* 0x38-0x3f */ + 0x00, 0xfc, 0xb8, 0xc1, 0xc4, 0xbf, 0xc0, 0xc5, /* 0x40-0x47 */ + 0xcb, 0x00, 0x00, 0x00, 0xcf, 0xd8, 0x00, 0x00, /* 0x48-0x4f */ + 0xcc, 0xce, 0x00, 0x00, 0xd9, 0xda, 0xdf, 0xe0, /* 0x50-0x57 */ + 0xdb, 0xde, 0xe5, 0xe6, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xe1, 0xe4, 0x00, 0x00, 0xe8, 0xe9, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xed, 0xf0, 0x00, 0x00, 0xf1, 0xf3, /* 0x68-0x6f */ + 0xf4, 0xf5, 0xf6, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8f, 0x90, 0xfb, 0xfd, 0xeb, 0xec, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, page22, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x81, 0x83, 0x84, 0x85, 0x86, 0xe7, /* 0x80-0x87 */ + 0x84, 0x89, 0x80, 0x89, 0x8c, 0x8c, 0x83, 0x8f, /* 0x88-0x8f */ + 0x8f, 0x91, 0xea, 0x91, 0x94, 0x94, 0x96, 0xee, /* 0x90-0x97 */ + 0x96, 0xef, 0x85, 0xcd, 0xf2, 0x9d, 0x9d, 0x86, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0x53, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xa2, 0xac, 0xad, 0xfe, 0xaf, /* 0xa8-0xaf */ + 0xaf, 0xb1, 0xb2, 0xb3, 0xb1, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xfc, 0xb9, 0xb9, 0xbb, 0xbb, 0xbd, 0xbd, 0xbf, /* 0xb8-0xbf */ + 0xbf, 0xc1, 0xc2, 0xc3, 0xc1, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xc5, 0xcc, 0xcd, 0xcc, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xcf, 0xd9, 0xd9, 0xdb, 0xdc, 0xdd, 0xdb, 0xdf, /* 0xd8-0xdf */ + 0xdf, 0xe1, 0xe2, 0xe3, 0xe1, 0xe5, 0xe5, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe8, 0xea, 0xeb, 0xeb, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xed, 0xf1, 0xf2, 0xf1, 0xf4, 0xf4, 0xf6, 0xf6, /* 0xf0-0xf7 */ + 0xf8, 0xf8, 0xb5, 0xfb, 0xfc, 0xfb, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x8a, 0x82, 0x82, 0x8e, 0x88, 0x9a, 0x9f, 0x87, /* 0x80-0x87 */ + 0x88, 0x8b, 0x8a, 0x8b, 0x8d, 0x8d, 0x8e, 0x90, /* 0x88-0x8f */ + 0x90, 0x93, 0x92, 0x93, 0x95, 0x95, 0x98, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9e, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xab, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xb0, /* 0xa8-0xaf */ + 0xb0, 0xb4, 0xb2, 0xb3, 0xb4, 0xfa, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xba, 0xba, 0xbc, 0xbc, 0xbe, 0xbe, 0xc0, /* 0xb8-0xbf */ + 0xc0, 0xc4, 0xc2, 0xc3, 0xc4, 0xcb, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xce, 0x9b, 0xce, 0xd8, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xda, 0xda, 0xde, 0xdc, 0xdd, 0xde, 0xe0, /* 0xd8-0xdf */ + 0xe0, 0xe4, 0xe2, 0xe3, 0xe4, 0xe6, 0xe6, 0x87, /* 0xe0-0xe7 */ + 0xe9, 0xe9, 0x92, 0xec, 0xec, 0xf0, 0x97, 0x99, /* 0xe8-0xef */ + 0xf0, 0xf3, 0x9c, 0xf3, 0xf5, 0xf5, 0xf7, 0xf7, /* 0xf0-0xf7 */ + 0xf9, 0xf9, 0xfa, 0xfd, 0xb8, 0xfd, 0xae, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp10029", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp10029() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp10079.c b/libunls/nls_cp10079.c new file mode 100644 index 0000000..7b4a1ee --- /dev/null +++ b/libunls/nls_cp10079.c @@ -0,0 +1,571 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp10079.c 1.3 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code generated by James Pearson j.pearson@ge.ucl.ac.uk 17/8/2000 + * based on a script by Gordon Chaffee <chaffee@bmrc.berkeley.edu> + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp10079.c + * + * Charset cp10079 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x10*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x00, 0x00}, + /* 0x80*/ + {0xc4, 0x00}, {0xc5, 0x00}, {0xc7, 0x00}, {0xc9, 0x00}, + {0xd1, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xe1, 0x00}, + {0xe0, 0x00}, {0xe2, 0x00}, {0xe4, 0x00}, {0xe3, 0x00}, + {0xe5, 0x00}, {0xe7, 0x00}, {0xe9, 0x00}, {0xe8, 0x00}, + /* 0x90*/ + {0xea, 0x00}, {0xeb, 0x00}, {0xed, 0x00}, {0xec, 0x00}, + {0xee, 0x00}, {0xef, 0x00}, {0xf1, 0x00}, {0xf3, 0x00}, + {0xf2, 0x00}, {0xf4, 0x00}, {0xf6, 0x00}, {0xf5, 0x00}, + {0xfa, 0x00}, {0xf9, 0x00}, {0xfb, 0x00}, {0xfc, 0x00}, + /* 0xa0*/ + {0xdd, 0x00}, {0xb0, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa7, 0x00}, {0x22, 0x20}, {0xb6, 0x00}, {0xdf, 0x00}, + {0xae, 0x00}, {0xa9, 0x00}, {0x22, 0x21}, {0xb4, 0x00}, + {0xa8, 0x00}, {0x60, 0x22}, {0xc6, 0x00}, {0xd8, 0x00}, + /* 0xb0*/ + {0x1e, 0x22}, {0xb1, 0x00}, {0x64, 0x22}, {0x65, 0x22}, + {0xa5, 0x00}, {0xb5, 0x00}, {0x02, 0x22}, {0x11, 0x22}, + {0x0f, 0x22}, {0xc0, 0x03}, {0x2b, 0x22}, {0xaa, 0x00}, + {0xba, 0x00}, {0xa9, 0x03}, {0xe6, 0x00}, {0xf8, 0x00}, + /* 0xc0*/ + {0xbf, 0x00}, {0xa1, 0x00}, {0xac, 0x00}, {0x1a, 0x22}, + {0x92, 0x01}, {0x48, 0x22}, {0x06, 0x22}, {0xab, 0x00}, + {0xbb, 0x00}, {0x26, 0x20}, {0xa0, 0x00}, {0xc0, 0x00}, + {0xc3, 0x00}, {0xd5, 0x00}, {0x52, 0x01}, {0x53, 0x01}, + /* 0xd0*/ + {0x13, 0x20}, {0x14, 0x20}, {0x1c, 0x20}, {0x1d, 0x20}, + {0x18, 0x20}, {0x19, 0x20}, {0xf7, 0x00}, {0xca, 0x25}, + {0xff, 0x00}, {0x78, 0x01}, {0x44, 0x20}, {0xac, 0x20}, + {0xd0, 0x00}, {0xf0, 0x00}, {0xde, 0x00}, {0xfe, 0x00}, + /* 0xe0*/ + {0xfd, 0x00}, {0xb7, 0x00}, {0x1a, 0x20}, {0x1e, 0x20}, + {0x30, 0x20}, {0xc2, 0x00}, {0xca, 0x00}, {0xc1, 0x00}, + {0xcb, 0x00}, {0xc8, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, + {0xcf, 0x00}, {0xcc, 0x00}, {0xd3, 0x00}, {0xd4, 0x00}, + /* 0xf0*/ + {0xff, 0xf8}, {0xd2, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xd9, 0x00}, {0x31, 0x01}, {0xc6, 0x02}, {0xdc, 0x02}, + {0xaf, 0x00}, {0xd8, 0x02}, {0xd9, 0x02}, {0xda, 0x02}, + {0xb8, 0x00}, {0xdd, 0x02}, {0xdb, 0x02}, {0xc7, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xca, 0xc1, 0xa2, 0xa3, 0x00, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0xdc, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xa0, 0xde, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0xdd, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xe0, 0xdf, 0xd8, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char pagef8[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, page22, NULL, NULL, page25, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + pagef8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xe7, /* 0x80-0x87 */ + 0xcb, 0xe5, 0x80, 0xcc, 0x81, 0x82, 0x83, 0xe9, /* 0x88-0x8f */ + 0xe6, 0xe8, 0xea, 0xed, 0xeb, 0xec, 0x84, 0xee, /* 0x90-0x97 */ + 0xf1, 0xef, 0x85, 0xcd, 0xf2, 0xf4, 0xf3, 0x86, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0x53, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x50, 0xba, 0xbb, 0xbc, 0xbd, 0xae, 0xaf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0x46, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd9, 0xd9, 0xda, 0xdb, 0xdc, 0xdc, 0xde, 0xde, /* 0xd8-0xdf */ + 0xa0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0x49, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x8a, 0x8c, 0x8d, 0x8e, 0x96, 0x9a, 0x9f, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xe0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xbe, 0xbf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0x88, 0x8b, 0x9b, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd8, 0xda, 0xdb, 0xdd, 0xdd, 0xdf, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x89, 0x90, 0x87, /* 0xe0-0xe7 */ + 0x91, 0x8f, 0x92, 0x94, 0x95, 0x93, 0x97, 0x99, /* 0xe8-0xef */ + 0xf0, 0x98, 0x9c, 0x9e, 0x9d, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp10079", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp10079() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp10081.c b/libunls/nls_cp10081.c new file mode 100644 index 0000000..a4be758 --- /dev/null +++ b/libunls/nls_cp10081.c @@ -0,0 +1,571 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp10081.c 1.3 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code generated by James Pearson j.pearson@ge.ucl.ac.uk 17/8/2000 + * based on a script by Gordon Chaffee <chaffee@bmrc.berkeley.edu> + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp10081.c + * + * Charset cp10081 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x10*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x00, 0x00}, + /* 0x80*/ + {0xc4, 0x00}, {0xc5, 0x00}, {0xc7, 0x00}, {0xc9, 0x00}, + {0xd1, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xe1, 0x00}, + {0xe0, 0x00}, {0xe2, 0x00}, {0xe4, 0x00}, {0xe3, 0x00}, + {0xe5, 0x00}, {0xe7, 0x00}, {0xe9, 0x00}, {0xe8, 0x00}, + /* 0x90*/ + {0xea, 0x00}, {0xeb, 0x00}, {0xed, 0x00}, {0xec, 0x00}, + {0xee, 0x00}, {0xef, 0x00}, {0xf1, 0x00}, {0xf3, 0x00}, + {0xf2, 0x00}, {0xf4, 0x00}, {0xf6, 0x00}, {0xf5, 0x00}, + {0xfa, 0x00}, {0xf9, 0x00}, {0xfb, 0x00}, {0xfc, 0x00}, + /* 0xa0*/ + {0x20, 0x20}, {0xb0, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa7, 0x00}, {0x22, 0x20}, {0xb6, 0x00}, {0xdf, 0x00}, + {0xae, 0x00}, {0xa9, 0x00}, {0x22, 0x21}, {0xb4, 0x00}, + {0xa8, 0x00}, {0x60, 0x22}, {0xc6, 0x00}, {0xd8, 0x00}, + /* 0xb0*/ + {0x1e, 0x22}, {0xb1, 0x00}, {0x64, 0x22}, {0x65, 0x22}, + {0xa5, 0x00}, {0xb5, 0x00}, {0x02, 0x22}, {0x11, 0x22}, + {0x0f, 0x22}, {0xc0, 0x03}, {0x2b, 0x22}, {0xaa, 0x00}, + {0xba, 0x00}, {0xa9, 0x03}, {0xe6, 0x00}, {0xf8, 0x00}, + /* 0xc0*/ + {0xbf, 0x00}, {0xa1, 0x00}, {0xac, 0x00}, {0x1a, 0x22}, + {0x92, 0x01}, {0x48, 0x22}, {0x06, 0x22}, {0xab, 0x00}, + {0xbb, 0x00}, {0x26, 0x20}, {0xa0, 0x00}, {0xc0, 0x00}, + {0xc3, 0x00}, {0xd5, 0x00}, {0x52, 0x01}, {0x53, 0x01}, + /* 0xd0*/ + {0x13, 0x20}, {0x14, 0x20}, {0x1c, 0x20}, {0x1d, 0x20}, + {0x18, 0x20}, {0x19, 0x20}, {0xf7, 0x00}, {0xca, 0x25}, + {0xff, 0x00}, {0x78, 0x01}, {0x1e, 0x01}, {0x1f, 0x01}, + {0x30, 0x01}, {0x31, 0x01}, {0x5e, 0x01}, {0x5f, 0x01}, + /* 0xe0*/ + {0x21, 0x20}, {0xb7, 0x00}, {0x1a, 0x20}, {0x1e, 0x20}, + {0x30, 0x20}, {0xc2, 0x00}, {0xca, 0x00}, {0xc1, 0x00}, + {0xcb, 0x00}, {0xc8, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, + {0xcf, 0x00}, {0xcc, 0x00}, {0xd3, 0x00}, {0xd4, 0x00}, + /* 0xf0*/ + {0xff, 0xf8}, {0xd2, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xd9, 0x00}, {0xa0, 0xf8}, {0xc6, 0x02}, {0xdc, 0x02}, + {0xaf, 0x00}, {0xd8, 0x02}, {0xd9, 0x02}, {0xda, 0x02}, + {0xb8, 0x00}, {0xdd, 0x02}, {0xdb, 0x02}, {0xc7, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xca, 0xc1, 0xa2, 0xa3, 0x00, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0x00, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0xd8, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0xdb, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xdf, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0xe0, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char pagef8[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, page22, NULL, NULL, page25, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + pagef8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xe7, /* 0x80-0x87 */ + 0xcb, 0xe5, 0x80, 0xcc, 0x81, 0x82, 0x83, 0xe9, /* 0x88-0x8f */ + 0xe6, 0xe8, 0xea, 0xed, 0xeb, 0xec, 0x84, 0xee, /* 0x90-0x97 */ + 0xf1, 0xef, 0x85, 0xcd, 0xf2, 0xf4, 0xf3, 0x86, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0x53, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x50, 0xba, 0xbb, 0xbc, 0xbd, 0xae, 0xaf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0x46, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd9, 0xd9, 0xda, 0xda, 0xdc, 0x49, 0xde, 0xde, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x8a, 0x8c, 0x8d, 0x8e, 0x96, 0x9a, 0x9f, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xbe, 0xbf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0x88, 0x8b, 0x9b, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd8, 0xdb, 0xdb, 0x69, 0xdd, 0xdf, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x89, 0x90, 0x87, /* 0xe0-0xe7 */ + 0x91, 0x8f, 0x92, 0x94, 0x95, 0x93, 0x97, 0x99, /* 0xe8-0xef */ + 0xf0, 0x98, 0x9c, 0x9e, 0x9d, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp10081", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp10081() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp1250.c b/libunls/nls_cp1250.c new file mode 100644 index 0000000..7dfc390 --- /dev/null +++ b/libunls/nls_cp1250.c @@ -0,0 +1,343 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp1250.c 1.2 05/05/01 2002 Petr Balas */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp1250.c + * + * Charset cp1250 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xac, 0x20}, {0x00, 0x00}, {0x1a, 0x20}, {0x00, 0x00}, + {0x1e, 0x20}, {0x26, 0x20}, {0x20, 0x20}, {0x21, 0x20}, + {0x00, 0x00}, {0x30, 0x20}, {0x60, 0x01}, {0x39, 0x20}, + {0x5a, 0x01}, {0x64, 0x01}, {0x7d, 0x01}, {0x79, 0x01}, + /* 0x90*/ + {0x00, 0x00}, {0x18, 0x20}, {0x19, 0x20}, {0x1c, 0x20}, + {0x1d, 0x20}, {0x22, 0x20}, {0x13, 0x20}, {0x14, 0x20}, + {0x00, 0x00}, {0x22, 0x21}, {0x61, 0x01}, {0x3a, 0x20}, + {0x5b, 0x01}, {0x65, 0x01}, {0x7e, 0x01}, {0x7a, 0x01}, + /* 0xa0*/ + {0xa0, 0x00}, {0xc7, 0x02}, {0xd8, 0x02}, {0x41, 0x01}, + {0xa4, 0x00}, {0x04, 0x01}, {0xa6, 0x00}, {0xa7, 0x00}, + {0xa8, 0x00}, {0xa9, 0x00}, {0x5e, 0x01}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0x7b, 0x01}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xdb, 0x02}, {0x42, 0x01}, + {0xb4, 0x00}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00}, + {0xb8, 0x00}, {0x05, 0x01}, {0x5f, 0x01}, {0xbb, 0x00}, + {0x3d, 0x01}, {0xdd, 0x02}, {0x3e, 0x01}, {0x7c, 0x01}, + /* 0xc0*/ + {0x54, 0x01}, {0xc1, 0x00}, {0xc2, 0x00}, {0x02, 0x01}, + {0xc4, 0x00}, {0x39, 0x01}, {0x06, 0x01}, {0xc7, 0x00}, + {0x0c, 0x01}, {0xc9, 0x00}, {0x18, 0x01}, {0xcb, 0x00}, + {0x1a, 0x01}, {0xcd, 0x00}, {0xce, 0x00}, {0x0e, 0x01}, + /* 0xd0*/ + {0x10, 0x01}, {0x43, 0x01}, {0x47, 0x01}, {0xd3, 0x00}, + {0xd4, 0x00}, {0x50, 0x01}, {0xd6, 0x00}, {0xd7, 0x00}, + {0x58, 0x01}, {0x6e, 0x01}, {0xda, 0x00}, {0x70, 0x01}, + {0xdc, 0x00}, {0xdd, 0x00}, {0x62, 0x01}, {0xdf, 0x00}, + /* 0xe0*/ + {0x55, 0x01}, {0xe1, 0x00}, {0xe2, 0x00}, {0x03, 0x01}, + {0xe4, 0x00}, {0x3a, 0x01}, {0x07, 0x01}, {0xe7, 0x00}, + {0x0d, 0x01}, {0xe9, 0x00}, {0x19, 0x01}, {0xeb, 0x00}, + {0x1b, 0x01}, {0xed, 0x00}, {0xee, 0x00}, {0x0f, 0x01}, + /* 0xf0*/ + {0x11, 0x01}, {0x44, 0x01}, {0x48, 0x01}, {0xf3, 0x00}, + {0xf4, 0x00}, {0x51, 0x01}, {0xf6, 0x00}, {0xf7, 0x00}, + {0x59, 0x01}, {0x6f, 0x01}, {0xfa, 0x00}, {0x71, 0x01}, + {0xfc, 0x00}, {0xfd, 0x00}, {0x63, 0x01}, {0xd9, 0x02}, + }; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xda, 0x00, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + }; + +static unsigned char page01[256] = { + 0x00, 0x00, 0xc3, 0xe3, 0xa5, 0xb9, 0xc6, 0xe6, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xbc, 0xbe, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x40-0x47 */ + 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x50-0x57 */ + 0xd8, 0xf8, 0x8c, 0x9c, 0x00, 0x00, 0xaa, 0xba, /* 0x58-0x5f */ + 0x8a, 0x9a, 0xde, 0xfe, 0x8d, 0x9d, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x68-0x6f */ + 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8f, 0x9f, 0xaf, 0xbf, 0x8e, 0x9e, 0x00, /* 0x78-0x7f */ + + }; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */ + }; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + }; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + }; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, NULL, NULL, NULL, NULL, NULL, NULL, + }; + +#if 0 +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */ + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x80, 0x00, 0x82, 0x00, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x00, 0x89, 0x9a, 0x8b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x88-0x8f */ + 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xb3, 0xa4, 0xb9, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xba, 0xab, 0xac, 0xad, 0xae, 0xbf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbe, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xc0-0xc7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xc8-0xcf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, /* 0xd0-0xd7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ + }; + +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x80, 0x00, 0x82, 0x00, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x00, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x00, 0x99, 0x8a, 0x9b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xa3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xa5, 0xaa, 0xbb, 0xbc, 0xbd, 0xbc, 0xaf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* 0xd8-0xdf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xe0-0xe7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xe8-0xef */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7, /* 0xf0-0xf7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff, /* 0xf8-0xff */ + }; +#endif + +static struct unls_table table = { + "cp1250", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp1250() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp1251.c b/libunls/nls_cp1251.c new file mode 100644 index 0000000..89c9156 --- /dev/null +++ b/libunls/nls_cp1251.c @@ -0,0 +1,298 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp1251.c 1.2 05/05/01 2002 */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp1251.c + * + * Charset cp1251 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0A, 0x00}, {0x0B, 0x00}, + {0x0C, 0x00}, {0x0D, 0x00}, {0x0E, 0x00}, {0x0F, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1A, 0x00}, {0x1B, 0x00}, + {0x1C, 0x00}, {0x1D, 0x00}, {0x1E, 0x00}, {0x1F, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2A, 0x00}, {0x2B, 0x00}, + {0x2C, 0x00}, {0x2D, 0x00}, {0x2E, 0x00}, {0x2F, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3A, 0x00}, {0x3B, 0x00}, + {0x3C, 0x00}, {0x3D, 0x00}, {0x3E, 0x00}, {0x3F, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4A, 0x00}, {0x4B, 0x00}, + {0x4C, 0x00}, {0x4D, 0x00}, {0x4E, 0x00}, {0x4F, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5A, 0x00}, {0x5B, 0x00}, + {0x5C, 0x00}, {0x5D, 0x00}, {0x5E, 0x00}, {0x5F, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6A, 0x00}, {0x6B, 0x00}, + {0x6C, 0x00}, {0x6D, 0x00}, {0x6E, 0x00}, {0x6F, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7A, 0x00}, {0x7B, 0x00}, + {0x7C, 0x00}, {0x7D, 0x00}, {0x7E, 0x00}, {0x7F, 0x00}, + /* 0x80*/ + {0x02, 0x04}, {0x03, 0x04}, {0x1A, 0x20}, {0x53, 0x04}, + {0x1E, 0x20}, {0x26, 0x20}, {0x20, 0x20}, {0x21, 0x20}, + {0xAC, 0x20}, {0x30, 0x20}, {0x09, 0x04}, {0x39, 0x20}, + {0x0A, 0x04}, {0x0C, 0x04}, {0x0B, 0x04}, {0x0F, 0x04}, + /* 0x90*/ + {0x52, 0x04}, {0x18, 0x20}, {0x19, 0x20}, {0x1C, 0x20}, + {0x1D, 0x20}, {0x22, 0x20}, {0x13, 0x20}, {0x14, 0x20}, + {0x00, 0x00}, {0x22, 0x21}, {0x59, 0x04}, {0x3A, 0x20}, + {0x5A, 0x04}, {0x5C, 0x04}, {0x5B, 0x04}, {0x5F, 0x04}, + /* 0xA0*/ + {0xA0, 0x00}, {0x0E, 0x04}, {0x5E, 0x04}, {0x08, 0x04}, + {0xA4, 0x00}, {0x90, 0x04}, {0xA6, 0x00}, {0xA7, 0x00}, + {0x01, 0x04}, {0xA9, 0x00}, {0x04, 0x04}, {0xAB, 0x00}, + {0xAC, 0x00}, {0xAD, 0x00}, {0xAE, 0x00}, {0x07, 0x04}, + /* 0xB0*/ + {0xB0, 0x00}, {0xB1, 0x00}, {0x06, 0x04}, {0x56, 0x04}, + {0x91, 0x04}, {0xB5, 0x00}, {0xB6, 0x00}, {0xB7, 0x00}, + {0x51, 0x04}, {0x16, 0x21}, {0x54, 0x04}, {0xBB, 0x00}, + {0x58, 0x04}, {0x05, 0x04}, {0x55, 0x04}, {0x57, 0x04}, + /* 0xC0*/ + {0x10, 0x04}, {0x11, 0x04}, {0x12, 0x04}, {0x13, 0x04}, + {0x14, 0x04}, {0x15, 0x04}, {0x16, 0x04}, {0x17, 0x04}, + {0x18, 0x04}, {0x19, 0x04}, {0x1A, 0x04}, {0x1B, 0x04}, + {0x1C, 0x04}, {0x1D, 0x04}, {0x1E, 0x04}, {0x1F, 0x04}, + /* 0xD0*/ + {0x20, 0x04}, {0x21, 0x04}, {0x22, 0x04}, {0x23, 0x04}, + {0x24, 0x04}, {0x25, 0x04}, {0x26, 0x04}, {0x27, 0x04}, + {0x28, 0x04}, {0x29, 0x04}, {0x2A, 0x04}, {0x2B, 0x04}, + {0x2C, 0x04}, {0x2D, 0x04}, {0x2E, 0x04}, {0x2F, 0x04}, + /* 0xE0*/ + {0x30, 0x04}, {0x31, 0x04}, {0x32, 0x04}, {0x33, 0x04}, + {0x34, 0x04}, {0x35, 0x04}, {0x36, 0x04}, {0x37, 0x04}, + {0x38, 0x04}, {0x39, 0x04}, {0x3A, 0x04}, {0x3B, 0x04}, + {0x3C, 0x04}, {0x3D, 0x04}, {0x3E, 0x04}, {0x3F, 0x04}, + /* 0xF0*/ + {0x40, 0x04}, {0x41, 0x04}, {0x42, 0x04}, {0x43, 0x04}, + {0x44, 0x04}, {0x45, 0x04}, {0x46, 0x04}, {0x47, 0x04}, + {0x48, 0x04}, {0x49, 0x04}, {0x4A, 0x04}, {0x4B, 0x04}, + {0x4C, 0x04}, {0x4D, 0x04}, {0x4E, 0x04}, {0x4F, 0x04} +}; + + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0xa8, 0x80, 0x81, 0xaa, 0xbd, 0xb2, 0xaf, /* 0x00-0x07 */ + 0xa3, 0x8a, 0x8c, 0x8e, 0x8d, 0x00, 0xa1, 0x8f, /* 0x08-0x0f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */ + 0x00, 0xb8, 0x90, 0x83, 0xba, 0xbe, 0xb3, 0xbf, /* 0x50-0x57 */ + 0xbc, 0x9a, 0x9c, 0x9e, 0x9d, 0x00, 0xa2, 0x9f, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, page21, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2lower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x90, 0x83, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x9a, 0x8b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa2, 0xa2, 0xbc, 0xa4, 0xb4, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xb8, 0xa9, 0xba, 0xab, 0xac, 0xad, 0xae, 0xbf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbe, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xc0-0xc7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xc8-0xcf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */ + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x81, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x80, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x8a, 0x9b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb2, 0xa5, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xa8, 0xb9, 0xaa, 0xbb, 0xa3, 0xbd, 0xbd, 0xaf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xe0-0xe7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xe8-0xef */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xf0-0xf7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp1251", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp1251() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp437.c b/libunls/nls_cp437.c new file mode 100644 index 0000000..1dcd2ee --- /dev/null +++ b/libunls/nls_cp437.c @@ -0,0 +1,436 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp437.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp437.c + * + * Charset cp437 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe4, 0x00}, {0xe0, 0x00}, {0xe5, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xeb, 0x00}, {0xe8, 0x00}, {0xef, 0x00}, + {0xee, 0x00}, {0xec, 0x00}, {0xc4, 0x00}, {0xc5, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xe6, 0x00}, {0xc6, 0x00}, {0xf4, 0x00}, + {0xf6, 0x00}, {0xf2, 0x00}, {0xfb, 0x00}, {0xf9, 0x00}, + {0xff, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xa2, 0x00}, + {0xa3, 0x00}, {0xa5, 0x00}, {0xa7, 0x20}, {0x92, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xf1, 0x00}, {0xd1, 0x00}, {0xaa, 0x00}, {0xba, 0x00}, + {0xbf, 0x00}, {0x10, 0x23}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xb1, 0x03}, {0xdf, 0x00}, {0x93, 0x03}, {0xc0, 0x03}, + {0xa3, 0x03}, {0xc3, 0x03}, {0xb5, 0x00}, {0xc4, 0x03}, + {0xa6, 0x03}, {0x98, 0x03}, {0xa9, 0x03}, {0xb4, 0x03}, + {0x1e, 0x22}, {0xc6, 0x03}, {0xb5, 0x03}, {0x29, 0x22}, + /* 0xf0*/ + {0x61, 0x22}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0x20, 0x23}, {0x21, 0x23}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp437", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp437() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp737.c b/libunls/nls_cp737.c new file mode 100644 index 0000000..1cb4b44 --- /dev/null +++ b/libunls/nls_cp737.c @@ -0,0 +1,364 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp737.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp737.c + * + * Charset cp737 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x91, 0x03}, {0x92, 0x03}, {0x93, 0x03}, {0x94, 0x03}, + {0x95, 0x03}, {0x96, 0x03}, {0x97, 0x03}, {0x98, 0x03}, + {0x99, 0x03}, {0x9a, 0x03}, {0x9b, 0x03}, {0x9c, 0x03}, + {0x9d, 0x03}, {0x9e, 0x03}, {0x9f, 0x03}, {0xa0, 0x03}, + /* 0x90*/ + {0xa1, 0x03}, {0xa3, 0x03}, {0xa4, 0x03}, {0xa5, 0x03}, + {0xa6, 0x03}, {0xa7, 0x03}, {0xa8, 0x03}, {0xa9, 0x03}, + {0xb1, 0x03}, {0xb2, 0x03}, {0xb3, 0x03}, {0xb4, 0x03}, + {0xb5, 0x03}, {0xb6, 0x03}, {0xb7, 0x03}, {0xb8, 0x03}, + /* 0xa0*/ + {0xb9, 0x03}, {0xba, 0x03}, {0xbb, 0x03}, {0xbc, 0x03}, + {0xbd, 0x03}, {0xbe, 0x03}, {0xbf, 0x03}, {0xc0, 0x03}, + {0xc1, 0x03}, {0xc3, 0x03}, {0xc2, 0x03}, {0xc4, 0x03}, + {0xc5, 0x03}, {0xc6, 0x03}, {0xc7, 0x03}, {0xc8, 0x03}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xc9, 0x03}, {0xac, 0x03}, {0xad, 0x03}, {0xae, 0x03}, + {0xca, 0x03}, {0xaf, 0x03}, {0xcc, 0x03}, {0xcd, 0x03}, + {0xcb, 0x03}, {0xce, 0x03}, {0x86, 0x03}, {0x88, 0x03}, + {0x89, 0x03}, {0x8a, 0x03}, {0x8c, 0x03}, {0x8e, 0x03}, + /* 0xf0*/ + {0x8f, 0x03}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0xaa, 0x03}, {0xab, 0x03}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, /* 0x80-0x87 */ + 0xeb, 0xec, 0xed, 0x00, 0xee, 0x00, 0xef, 0xf0, /* 0x88-0x8f */ + 0x00, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, /* 0x90-0x97 */ + 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, /* 0x98-0x9f */ + 0x8f, 0x90, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, /* 0xa0-0xa7 */ + 0x96, 0x97, 0xf4, 0xf5, 0xe1, 0xe2, 0xe3, 0xe5, /* 0xa8-0xaf */ + 0x00, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, /* 0xb0-0xb7 */ + 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 0xb8-0xbf */ + 0xa7, 0xa8, 0xaa, 0xa9, 0xab, 0xac, 0xad, 0xae, /* 0xc0-0xc7 */ + 0xaf, 0xe0, 0xe4, 0xe8, 0xe6, 0xe7, 0xe9, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp737", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp737() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp775.c b/libunls/nls_cp775.c new file mode 100644 index 0000000..d34580d --- /dev/null +++ b/libunls/nls_cp775.c @@ -0,0 +1,364 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp775.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp775.c + * + * Charset cp775 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x06, 0x01}, {0xfc, 0x00}, {0xe9, 0x00}, {0x01, 0x01}, + {0xe4, 0x00}, {0x23, 0x01}, {0xe5, 0x00}, {0x07, 0x01}, + {0x42, 0x01}, {0x13, 0x01}, {0x56, 0x01}, {0x57, 0x01}, + {0x2b, 0x01}, {0x79, 0x01}, {0xc4, 0x00}, {0xc5, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xe6, 0x00}, {0xc6, 0x00}, {0x4d, 0x01}, + {0xf6, 0x00}, {0x22, 0x01}, {0xa2, 0x00}, {0x5a, 0x01}, + {0x5b, 0x01}, {0xd6, 0x00}, {0xdc, 0x00}, {0xf8, 0x00}, + {0xa3, 0x00}, {0xd8, 0x00}, {0xd7, 0x00}, {0xa4, 0x00}, + /* 0xa0*/ + {0x00, 0x01}, {0x2a, 0x01}, {0xf3, 0x00}, {0x7b, 0x01}, + {0x7c, 0x01}, {0x7a, 0x01}, {0x1d, 0x20}, {0xa6, 0x00}, + {0xa9, 0x00}, {0xae, 0x00}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0x41, 0x01}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x04, 0x01}, {0x0c, 0x01}, {0x18, 0x01}, + {0x16, 0x01}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x2e, 0x01}, {0x60, 0x01}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x72, 0x01}, {0x6a, 0x01}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x7d, 0x01}, + /* 0xd0*/ + {0x05, 0x01}, {0x0d, 0x01}, {0x19, 0x01}, {0x17, 0x01}, + {0x2f, 0x01}, {0x61, 0x01}, {0x73, 0x01}, {0x6b, 0x01}, + {0x7e, 0x01}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xd3, 0x00}, {0xdf, 0x00}, {0x4c, 0x01}, {0x43, 0x01}, + {0xf5, 0x00}, {0xd5, 0x00}, {0xb5, 0x00}, {0x44, 0x01}, + {0x36, 0x01}, {0x37, 0x01}, {0x3b, 0x01}, {0x3c, 0x01}, + {0x46, 0x01}, {0x12, 0x01}, {0x45, 0x01}, {0x19, 0x20}, + /* 0xf0*/ + {0xad, 0x00}, {0xb1, 0x00}, {0x1c, 0x20}, {0xbe, 0x00}, + {0xb6, 0x00}, {0xa7, 0x00}, {0xf7, 0x00}, {0x1e, 0x20}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0xb9, 0x00}, + {0xb3, 0x00}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x96, 0x9c, 0x9f, 0x00, 0xa7, 0xf5, /* 0xa0-0xa7 */ + 0x00, 0xa8, 0x00, 0xae, 0xaa, 0xf0, 0xa9, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0x00, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0xfb, 0x00, 0xaf, 0xac, 0xab, 0xf3, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe5, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x9d, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x84, 0x86, 0x91, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xa2, 0x00, 0xe4, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0xa0, 0x83, 0x00, 0x00, 0xb5, 0xd0, 0x80, 0x87, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xb6, 0xd1, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0xed, 0x89, 0x00, 0x00, 0xb8, 0xd3, /* 0x10-0x17 */ + 0xb7, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x95, 0x85, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xa1, 0x8c, 0x00, 0x00, 0xbd, 0xd4, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xe9, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0xea, 0xeb, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xad, 0x88, 0xe3, 0xe7, 0xee, 0xec, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0xe2, 0x93, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8b, /* 0x50-0x57 */ + 0x00, 0x00, 0x97, 0x98, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xbe, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xc7, 0xd7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xc6, 0xd6, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8d, 0xa5, 0xa3, 0xa4, 0xcf, 0xd8, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xef, 0x00, 0x00, 0xf2, 0xa6, 0xf7, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x8a, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x00, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0x00, 0xa3, 0x00, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0xe3, 0x00, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0x00, 0xea, 0x00, 0x00, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp775", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp775() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp850.c b/libunls/nls_cp850.c new file mode 100644 index 0000000..6f82ed0 --- /dev/null +++ b/libunls/nls_cp850.c @@ -0,0 +1,328 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp850.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp850.c + * + * Charset cp850 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe4, 0x00}, {0xe0, 0x00}, {0xe5, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xeb, 0x00}, {0xe8, 0x00}, {0xef, 0x00}, + {0xee, 0x00}, {0xec, 0x00}, {0xc4, 0x00}, {0xc5, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xe6, 0x00}, {0xc6, 0x00}, {0xf4, 0x00}, + {0xf6, 0x00}, {0xf2, 0x00}, {0xfb, 0x00}, {0xf9, 0x00}, + {0xff, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xf8, 0x00}, + {0xa3, 0x00}, {0xd8, 0x00}, {0xd7, 0x00}, {0x92, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xf1, 0x00}, {0xd1, 0x00}, {0xaa, 0x00}, {0xba, 0x00}, + {0xbf, 0x00}, {0xae, 0x00}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc0, 0x00}, + {0xa9, 0x00}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0xa2, 0x00}, {0xa5, 0x00}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0xe3, 0x00}, {0xc3, 0x00}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0xa4, 0x00}, + /* 0xd0*/ + {0xf0, 0x00}, {0xd0, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xc8, 0x00}, {0x31, 0x01}, {0xcd, 0x00}, {0xce, 0x00}, + {0xcf, 0x00}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0xa6, 0x00}, {0xcc, 0x00}, {0x80, 0x25}, + /* 0xe0*/ + {0xd3, 0x00}, {0xdf, 0x00}, {0xd4, 0x00}, {0xd2, 0x00}, + {0xf5, 0x00}, {0xd5, 0x00}, {0xb5, 0x00}, {0xfe, 0x00}, + {0xde, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, {0xd9, 0x00}, + {0xfd, 0x00}, {0xdd, 0x00}, {0xaf, 0x00}, {0xb4, 0x00}, + /* 0xf0*/ + {0xad, 0x00}, {0xb1, 0x00}, {0x17, 0x20}, {0xbe, 0x00}, + {0xb6, 0x00}, {0xa7, 0x00}, {0xf7, 0x00}, {0xb8, 0x00}, + {0xb0, 0x00}, {0xa8, 0x00}, {0xb7, 0x00}, {0xb9, 0x00}, + {0xb3, 0x00}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* 0xb8-0xbf */ + 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* 0xc8-0xcf */ + 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0xc6, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0xd0, 0xa4, 0x95, 0xa2, 0x93, 0xe4, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0xec, 0xe7, 0x98, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, NULL, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x00, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0xe3, 0x00, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp850", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp850() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp852.c b/libunls/nls_cp852.c new file mode 100644 index 0000000..040d5be --- /dev/null +++ b/libunls/nls_cp852.c @@ -0,0 +1,328 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp852.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp852.c + * + * Charset cp852 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe4, 0x00}, {0x6f, 0x01}, {0x07, 0x01}, {0xe7, 0x00}, + {0x42, 0x01}, {0xeb, 0x00}, {0x50, 0x01}, {0x51, 0x01}, + {0xee, 0x00}, {0x79, 0x01}, {0xc4, 0x00}, {0x06, 0x01}, + /* 0x90*/ + {0xc9, 0x00}, {0x39, 0x01}, {0x3a, 0x01}, {0xf4, 0x00}, + {0xf6, 0x00}, {0x3d, 0x01}, {0x3e, 0x01}, {0x5a, 0x01}, + {0x5b, 0x01}, {0xd6, 0x00}, {0xdc, 0x00}, {0x64, 0x01}, + {0x65, 0x01}, {0x41, 0x01}, {0xd7, 0x00}, {0x0d, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0x04, 0x01}, {0x05, 0x01}, {0x7d, 0x01}, {0x7e, 0x01}, + {0x18, 0x01}, {0x19, 0x01}, {0xac, 0x00}, {0x7a, 0x01}, + {0x0c, 0x01}, {0x5f, 0x01}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0xc1, 0x00}, {0xc2, 0x00}, {0x1a, 0x01}, + {0x5e, 0x01}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x7b, 0x01}, {0x7c, 0x01}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x02, 0x01}, {0x03, 0x01}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0xa4, 0x00}, + /* 0xd0*/ + {0x11, 0x01}, {0x10, 0x01}, {0x0e, 0x01}, {0xcb, 0x00}, + {0x0f, 0x01}, {0x47, 0x01}, {0xcd, 0x00}, {0xce, 0x00}, + {0x1b, 0x01}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x62, 0x01}, {0x6e, 0x01}, {0x80, 0x25}, + /* 0xe0*/ + {0xd3, 0x00}, {0xdf, 0x00}, {0xd4, 0x00}, {0x43, 0x01}, + {0x44, 0x01}, {0x48, 0x01}, {0x60, 0x01}, {0x61, 0x01}, + {0x54, 0x01}, {0xda, 0x00}, {0x55, 0x01}, {0x70, 0x01}, + {0xfd, 0x00}, {0xdd, 0x00}, {0x63, 0x01}, {0xb4, 0x00}, + /* 0xf0*/ + {0xad, 0x00}, {0xdd, 0x02}, {0xdb, 0x02}, {0xc7, 0x02}, + {0xd8, 0x02}, {0xa7, 0x00}, {0xf7, 0x00}, {0xb8, 0x00}, + {0xb0, 0x00}, {0xa8, 0x00}, {0xd9, 0x02}, {0x71, 0x01}, + {0x58, 0x01}, {0x59, 0x01}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0x00, 0x00, 0xae, 0xaa, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xf7, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xb5, 0xb6, 0x00, 0x8e, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0xd3, 0x00, 0xd6, 0xd7, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xe0, 0xe2, 0x00, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xe9, 0x00, 0x9a, 0xed, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x00, 0xa0, 0x83, 0x00, 0x84, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x00, 0x82, 0x00, 0x89, 0x00, 0xa1, 0x8c, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xa3, 0x00, 0x81, 0xec, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0xc6, 0xc7, 0xa4, 0xa5, 0x8f, 0x86, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xac, 0x9f, 0xd2, 0xd4, /* 0x08-0x0f */ + 0xd1, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xa8, 0xa9, 0xb7, 0xd8, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x91, 0x92, 0x00, 0x00, 0x95, 0x96, 0x00, /* 0x38-0x3f */ + 0x00, 0x9d, 0x88, 0xe3, 0xe4, 0x00, 0x00, 0xd5, /* 0x40-0x47 */ + 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x8a, 0x8b, 0x00, 0x00, 0xe8, 0xea, 0x00, 0x00, /* 0x50-0x57 */ + 0xfc, 0xfd, 0x97, 0x98, 0x00, 0x00, 0xb8, 0xad, /* 0x58-0x5f */ + 0xe6, 0xe7, 0xdd, 0xee, 0x9b, 0x9c, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x85, /* 0x68-0x6f */ + 0xeb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8d, 0xab, 0xbd, 0xbe, 0xa6, 0xa7, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf4, 0xfa, 0x00, 0xf2, 0x00, 0xf1, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x8a, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x00, 0x00, 0x00, 0x95, 0x00, 0x97, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x9b, 0x00, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0x00, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0xaa, 0x00, 0xac, 0x00, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0x00, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0x00, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0xe3, 0x00, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0xfc, 0x00, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp852", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp852() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp855.c b/libunls/nls_cp855.c new file mode 100644 index 0000000..56642df --- /dev/null +++ b/libunls/nls_cp855.c @@ -0,0 +1,328 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp855.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp855.c + * + * Charset cp855 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x52, 0x04}, {0x02, 0x04}, {0x53, 0x04}, {0x03, 0x04}, + {0x51, 0x04}, {0x01, 0x04}, {0x54, 0x04}, {0x04, 0x04}, + {0x55, 0x04}, {0x05, 0x04}, {0x56, 0x04}, {0x06, 0x04}, + {0x57, 0x04}, {0x07, 0x04}, {0x58, 0x04}, {0x08, 0x04}, + /* 0x90*/ + {0x59, 0x04}, {0x09, 0x04}, {0x5a, 0x04}, {0x0a, 0x04}, + {0x5b, 0x04}, {0x0b, 0x04}, {0x5c, 0x04}, {0x0c, 0x04}, + {0x5e, 0x04}, {0x0e, 0x04}, {0x5f, 0x04}, {0x0f, 0x04}, + {0x4e, 0x04}, {0x2e, 0x04}, {0x4a, 0x04}, {0x2a, 0x04}, + /* 0xa0*/ + {0x30, 0x04}, {0x10, 0x04}, {0x31, 0x04}, {0x11, 0x04}, + {0x46, 0x04}, {0x26, 0x04}, {0x34, 0x04}, {0x14, 0x04}, + {0x35, 0x04}, {0x15, 0x04}, {0x44, 0x04}, {0x24, 0x04}, + {0x33, 0x04}, {0x13, 0x04}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x45, 0x04}, {0x25, 0x04}, {0x38, 0x04}, + {0x18, 0x04}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x39, 0x04}, {0x19, 0x04}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x3a, 0x04}, {0x1a, 0x04}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0xa4, 0x00}, + /* 0xd0*/ + {0x3b, 0x04}, {0x1b, 0x04}, {0x3c, 0x04}, {0x1c, 0x04}, + {0x3d, 0x04}, {0x1d, 0x04}, {0x3e, 0x04}, {0x1e, 0x04}, + {0x3f, 0x04}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x1f, 0x04}, {0x4f, 0x04}, {0x80, 0x25}, + /* 0xe0*/ + {0x2f, 0x04}, {0x40, 0x04}, {0x20, 0x04}, {0x41, 0x04}, + {0x21, 0x04}, {0x42, 0x04}, {0x22, 0x04}, {0x43, 0x04}, + {0x23, 0x04}, {0x36, 0x04}, {0x16, 0x04}, {0x32, 0x04}, + {0x12, 0x04}, {0x4c, 0x04}, {0x2c, 0x04}, {0x16, 0x21}, + /* 0xf0*/ + {0xad, 0x00}, {0x4b, 0x04}, {0x2b, 0x04}, {0x37, 0x04}, + {0x17, 0x04}, {0x48, 0x04}, {0x28, 0x04}, {0x4d, 0x04}, + {0x2d, 0x04}, {0x49, 0x04}, {0x29, 0x04}, {0x47, 0x04}, + {0x27, 0x04}, {0xa7, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xfd, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0xae, 0x00, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0x85, 0x81, 0x83, 0x87, 0x89, 0x8b, 0x8d, /* 0x00-0x07 */ + 0x8f, 0x91, 0x93, 0x95, 0x97, 0x00, 0x99, 0x9b, /* 0x08-0x0f */ + 0xa1, 0xa3, 0xec, 0xad, 0xa7, 0xa9, 0xea, 0xf4, /* 0x10-0x17 */ + 0xb8, 0xbe, 0xc7, 0xd1, 0xd3, 0xd5, 0xd7, 0xdd, /* 0x18-0x1f */ + 0xe2, 0xe4, 0xe6, 0xe8, 0xab, 0xb6, 0xa5, 0xfc, /* 0x20-0x27 */ + 0xf6, 0xfa, 0x9f, 0xf2, 0xee, 0xf8, 0x9d, 0xe0, /* 0x28-0x2f */ + 0xa0, 0xa2, 0xeb, 0xac, 0xa6, 0xa8, 0xe9, 0xf3, /* 0x30-0x37 */ + 0xb7, 0xbd, 0xc6, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, /* 0x38-0x3f */ + 0xe1, 0xe3, 0xe5, 0xe7, 0xaa, 0xb5, 0xa4, 0xfb, /* 0x40-0x47 */ + 0xf5, 0xf9, 0x9e, 0xf1, 0xed, 0xf7, 0x9c, 0xde, /* 0x48-0x4f */ + 0x00, 0x84, 0x80, 0x82, 0x86, 0x88, 0x8a, 0x8c, /* 0x50-0x57 */ + 0x8e, 0x90, 0x92, 0x94, 0x96, 0x00, 0x98, 0x9a, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, page21, NULL, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x00, 0x81, 0x00, 0x83, 0x00, 0x85, 0x00, 0x87, /* 0x80-0x87 */ + 0x00, 0x89, 0x00, 0x8b, 0x00, 0x8d, 0x00, 0x8f, /* 0x88-0x8f */ + 0x00, 0x91, 0x00, 0x93, 0x00, 0x95, 0x00, 0x97, /* 0x90-0x97 */ + 0x00, 0x99, 0x00, 0x9b, 0x00, 0x9d, 0x00, 0x9f, /* 0x98-0x9f */ + 0x00, 0xa1, 0x00, 0xa3, 0x00, 0xa5, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0x00, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0x00, 0xb6, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0x00, 0xd3, 0x00, 0xd5, 0x00, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0x00, 0xea, 0x00, 0xec, 0x00, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0x00, 0xf2, 0x00, 0xf4, 0x00, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp855", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp855() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp857.c b/libunls/nls_cp857.c new file mode 100644 index 0000000..22f6af0 --- /dev/null +++ b/libunls/nls_cp857.c @@ -0,0 +1,292 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp857.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp857.c + * + * Charset cp857 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe4, 0x00}, {0xe0, 0x00}, {0xe5, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xeb, 0x00}, {0xe8, 0x00}, {0xef, 0x00}, + {0xee, 0x00}, {0x31, 0x01}, {0xc4, 0x00}, {0xc5, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xe6, 0x00}, {0xc6, 0x00}, {0xf4, 0x00}, + {0xf6, 0x00}, {0xf2, 0x00}, {0xfb, 0x00}, {0xf9, 0x00}, + {0x30, 0x01}, {0xd6, 0x00}, {0xdc, 0x00}, {0xf8, 0x00}, + {0xa3, 0x00}, {0xd8, 0x00}, {0x5e, 0x01}, {0x5f, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xf1, 0x00}, {0xd1, 0x00}, {0x1e, 0x01}, {0x1f, 0x01}, + {0xbf, 0x00}, {0xae, 0x00}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc0, 0x00}, + {0xa9, 0x00}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0xa2, 0x00}, {0xa5, 0x00}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0xe3, 0x00}, {0xc3, 0x00}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0xa4, 0x00}, + /* 0xd0*/ + {0xba, 0x00}, {0xaa, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xc8, 0x00}, {0x00, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, + {0xcf, 0x00}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0xa6, 0x00}, {0xcc, 0x00}, {0x80, 0x25}, + /* 0xe0*/ + {0xd3, 0x00}, {0xdf, 0x00}, {0xd4, 0x00}, {0xd2, 0x00}, + {0xf5, 0x00}, {0xd5, 0x00}, {0xb5, 0x00}, {0x00, 0x00}, + {0xd7, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, {0xd9, 0x00}, + {0xec, 0x00}, {0xff, 0x00}, {0xaf, 0x00}, {0xb4, 0x00}, + /* 0xf0*/ + {0xad, 0x00}, {0xb1, 0x00}, {0x00, 0x00}, {0xbe, 0x00}, + {0xb6, 0x00}, {0xa7, 0x00}, {0xf7, 0x00}, {0xb8, 0x00}, + {0xb0, 0x00}, {0xa8, 0x00}, {0xb7, 0x00}, {0xb9, 0x00}, + {0xb3, 0x00}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0xb8, 0xd1, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0xf7, 0xfb, 0xd0, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* 0xb8-0xbf */ + 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* 0xc8-0xcf */ + 0x00, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0xe8, /* 0xd0-0xd7 */ + 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0xc6, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0xec, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0xe4, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0xed, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa7, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x98, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x9f, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x00, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0x00, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0xe3, 0x00, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0x00, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp857", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp857() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp860.c b/libunls/nls_cp860.c new file mode 100644 index 0000000..467ec00 --- /dev/null +++ b/libunls/nls_cp860.c @@ -0,0 +1,400 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp860.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp860.c + * + * Charset cp860 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe3, 0x00}, {0xe0, 0x00}, {0xc1, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xca, 0x00}, {0xe8, 0x00}, {0xcd, 0x00}, + {0xd4, 0x00}, {0xec, 0x00}, {0xc3, 0x00}, {0xc2, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xc0, 0x00}, {0xc8, 0x00}, {0xf4, 0x00}, + {0xf5, 0x00}, {0xf2, 0x00}, {0xda, 0x00}, {0xf9, 0x00}, + {0xcc, 0x00}, {0xd5, 0x00}, {0xdc, 0x00}, {0xa2, 0x00}, + {0xa3, 0x00}, {0xd9, 0x00}, {0xa7, 0x20}, {0xd3, 0x00}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xf1, 0x00}, {0xd1, 0x00}, {0xaa, 0x00}, {0xba, 0x00}, + {0xbf, 0x00}, {0xd2, 0x00}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xb1, 0x03}, {0xdf, 0x00}, {0x93, 0x03}, {0xc0, 0x03}, + {0xa3, 0x03}, {0xc3, 0x03}, {0xb5, 0x00}, {0xc4, 0x03}, + {0xa6, 0x03}, {0x98, 0x03}, {0xa9, 0x03}, {0xb4, 0x03}, + {0x1e, 0x22}, {0xc6, 0x03}, {0xb5, 0x03}, {0x29, 0x22}, + /* 0xf0*/ + {0x61, 0x22}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0x20, 0x23}, {0x21, 0x23}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x91, 0x86, 0x8f, 0x8e, 0x00, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0x92, 0x90, 0x89, 0x00, 0x98, 0x8b, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0xa9, 0x9f, 0x8c, 0x99, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x9d, 0x96, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x84, 0x00, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x00, 0x8d, 0xa1, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x94, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x00, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, /* 0x80-0x87 */ + 0x00, 0x89, 0x00, 0x8b, 0x8c, 0x00, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x96, 0x00, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp860", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp860() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp861.c b/libunls/nls_cp861.c new file mode 100644 index 0000000..74bc73c --- /dev/null +++ b/libunls/nls_cp861.c @@ -0,0 +1,436 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp861.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp861.c + * + * Charset cp861 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe4, 0x00}, {0xe0, 0x00}, {0xe5, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xeb, 0x00}, {0xe8, 0x00}, {0xd0, 0x00}, + {0xf0, 0x00}, {0xde, 0x00}, {0xc4, 0x00}, {0xc5, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xe6, 0x00}, {0xc6, 0x00}, {0xf4, 0x00}, + {0xf6, 0x00}, {0xfe, 0x00}, {0xfb, 0x00}, {0xdd, 0x00}, + {0xfd, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xf8, 0x00}, + {0xa3, 0x00}, {0xd8, 0x00}, {0xa7, 0x20}, {0x92, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xc1, 0x00}, {0xcd, 0x00}, {0xd3, 0x00}, {0xda, 0x00}, + {0xbf, 0x00}, {0x10, 0x23}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xb1, 0x03}, {0xdf, 0x00}, {0x93, 0x03}, {0xc0, 0x03}, + {0xa3, 0x03}, {0xc3, 0x03}, {0xb5, 0x00}, {0xc4, 0x03}, + {0xa6, 0x03}, {0x98, 0x03}, {0xa9, 0x03}, {0xb4, 0x03}, + {0x1e, 0x22}, {0xc6, 0x03}, {0xb5, 0x03}, {0x29, 0x22}, + /* 0xf0*/ + {0x61, 0x22}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0x20, 0x23}, {0x21, 0x23}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0xa4, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, /* 0xc8-0xcf */ + 0x8b, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x9d, 0x00, 0xa7, 0x00, 0x9a, 0x97, 0x8d, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x00, 0xa1, 0x00, 0x00, /* 0xe8-0xef */ + 0x8c, 0x00, 0x00, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x00, 0xa3, 0x96, 0x81, 0x98, 0x95, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x8b, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x97, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x00, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp861", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp861() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp862.c b/libunls/nls_cp862.c new file mode 100644 index 0000000..b174b5b --- /dev/null +++ b/libunls/nls_cp862.c @@ -0,0 +1,472 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp862.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp862.c + * + * Charset cp862 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xd0, 0x05}, {0xd1, 0x05}, {0xd2, 0x05}, {0xd3, 0x05}, + {0xd4, 0x05}, {0xd5, 0x05}, {0xd6, 0x05}, {0xd7, 0x05}, + {0xd8, 0x05}, {0xd9, 0x05}, {0xda, 0x05}, {0xdb, 0x05}, + {0xdc, 0x05}, {0xdd, 0x05}, {0xde, 0x05}, {0xdf, 0x05}, + /* 0x90*/ + {0xe0, 0x05}, {0xe1, 0x05}, {0xe2, 0x05}, {0xe3, 0x05}, + {0xe4, 0x05}, {0xe5, 0x05}, {0xe6, 0x05}, {0xe7, 0x05}, + {0xe8, 0x05}, {0xe9, 0x05}, {0xea, 0x05}, {0xa2, 0x00}, + {0xa3, 0x00}, {0xa5, 0x00}, {0xa7, 0x20}, {0x92, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xf1, 0x00}, {0xd1, 0x00}, {0xaa, 0x00}, {0xba, 0x00}, + {0xbf, 0x00}, {0x10, 0x23}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xb1, 0x03}, {0xdf, 0x00}, {0x93, 0x03}, {0xc0, 0x03}, + {0xa3, 0x03}, {0xc3, 0x03}, {0xb5, 0x00}, {0xc4, 0x03}, + {0xa6, 0x03}, {0x98, 0x03}, {0xa9, 0x03}, {0xb4, 0x03}, + {0x1e, 0x22}, {0xc6, 0x03}, {0xb5, 0x03}, {0x29, 0x22}, + /* 0xf0*/ + {0x61, 0x22}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0x20, 0x23}, {0x21, 0x23}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0xa4, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page05[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0xd0-0xd7 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0xd8-0xdf */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0xe0-0xe7 */ + 0x98, 0x99, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, page03, NULL, page05, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp862", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp862() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp863.c b/libunls/nls_cp863.c new file mode 100644 index 0000000..da88111 --- /dev/null +++ b/libunls/nls_cp863.c @@ -0,0 +1,436 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp863.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp863.c + * + * Charset cp863 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xc2, 0x00}, {0xe0, 0x00}, {0xb6, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xeb, 0x00}, {0xe8, 0x00}, {0xef, 0x00}, + {0xee, 0x00}, {0x17, 0x20}, {0xc0, 0x00}, {0xa7, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xc8, 0x00}, {0xca, 0x00}, {0xf4, 0x00}, + {0xcb, 0x00}, {0xcf, 0x00}, {0xfb, 0x00}, {0xf9, 0x00}, + {0xa4, 0x00}, {0xd4, 0x00}, {0xdc, 0x00}, {0xa2, 0x00}, + {0xa3, 0x00}, {0xd9, 0x00}, {0xdb, 0x00}, {0x92, 0x01}, + /* 0xa0*/ + {0xa6, 0x00}, {0xb4, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xa8, 0x00}, {0xb8, 0x00}, {0xb3, 0x00}, {0xaf, 0x00}, + {0xce, 0x00}, {0x10, 0x23}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xbe, 0x00}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xb1, 0x03}, {0xdf, 0x00}, {0x93, 0x03}, {0xc0, 0x03}, + {0xa3, 0x03}, {0xc3, 0x03}, {0xb5, 0x00}, {0xc4, 0x03}, + {0xa6, 0x03}, {0x98, 0x03}, {0xa9, 0x03}, {0xb4, 0x03}, + {0x1e, 0x22}, {0xc6, 0x03}, {0xb5, 0x03}, {0x29, 0x22}, + /* 0xf0*/ + {0x61, 0x22}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0x20, 0x23}, {0x21, 0x23}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x9b, 0x9c, 0x98, 0x00, 0xa0, 0x8f, /* 0xa0-0xa7 */ + 0xa4, 0x00, 0x00, 0xae, 0xaa, 0x00, 0x00, 0xa7, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xa6, 0xa1, 0xe6, 0x86, 0xfa, /* 0xb0-0xb7 */ + 0xa5, 0x00, 0x00, 0xaf, 0xac, 0xab, 0xad, 0x00, /* 0xb8-0xbf */ + 0x8e, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0x91, 0x90, 0x92, 0x94, 0x00, 0x00, 0xa8, 0x95, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x9d, 0x00, 0x9e, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x00, 0x00, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xa2, 0x93, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x84, 0x00, 0x86, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x94, 0x95, 0x00, 0x00, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0xa0, 0xa1, 0x00, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp863", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp863() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp864.c b/libunls/nls_cp864.c new file mode 100644 index 0000000..cacd866 --- /dev/null +++ b/libunls/nls_cp864.c @@ -0,0 +1,427 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp864.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp864.c + * + * Charset cp864 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x6a, 0x06}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xb0, 0x00}, {0xb7, 0x00}, {0x19, 0x22}, {0x1a, 0x22}, + {0x92, 0x25}, {0x00, 0x25}, {0x02, 0x25}, {0x3c, 0x25}, + {0x24, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, {0x34, 0x25}, + {0x10, 0x25}, {0x0c, 0x25}, {0x14, 0x25}, {0x18, 0x25}, + /* 0x90*/ + {0xb2, 0x03}, {0x1e, 0x22}, {0xc6, 0x03}, {0xb1, 0x00}, + {0xbd, 0x00}, {0xbc, 0x00}, {0x48, 0x22}, {0xab, 0x00}, + {0xbb, 0x00}, {0xf7, 0xfe}, {0xf8, 0xfe}, {0x00, 0x00}, + {0x00, 0x00}, {0xfb, 0xfe}, {0xfc, 0xfe}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0xad, 0x00}, {0x82, 0xfe}, {0xa3, 0x00}, + {0xa4, 0x00}, {0x84, 0xfe}, {0x00, 0x00}, {0x00, 0x00}, + {0x8e, 0xfe}, {0x8f, 0xfe}, {0x95, 0xfe}, {0x99, 0xfe}, + {0x0c, 0x06}, {0x9d, 0xfe}, {0xa1, 0xfe}, {0xa5, 0xfe}, + /* 0xb0*/ + {0x60, 0x06}, {0x61, 0x06}, {0x62, 0x06}, {0x63, 0x06}, + {0x64, 0x06}, {0x65, 0x06}, {0x66, 0x06}, {0x67, 0x06}, + {0x68, 0x06}, {0x69, 0x06}, {0xd1, 0xfe}, {0x1b, 0x06}, + {0xb1, 0xfe}, {0xb5, 0xfe}, {0xb9, 0xfe}, {0x1f, 0x06}, + /* 0xc0*/ + {0xa2, 0x00}, {0x80, 0xfe}, {0x81, 0xfe}, {0x83, 0xfe}, + {0x85, 0xfe}, {0xca, 0xfe}, {0x8b, 0xfe}, {0x8d, 0xfe}, + {0x91, 0xfe}, {0x93, 0xfe}, {0x97, 0xfe}, {0x9b, 0xfe}, + {0x9f, 0xfe}, {0xa3, 0xfe}, {0xa7, 0xfe}, {0xa9, 0xfe}, + /* 0xd0*/ + {0xab, 0xfe}, {0xad, 0xfe}, {0xaf, 0xfe}, {0xb3, 0xfe}, + {0xb7, 0xfe}, {0xbb, 0xfe}, {0xbf, 0xfe}, {0xc1, 0xfe}, + {0xc5, 0xfe}, {0xcb, 0xfe}, {0xcf, 0xfe}, {0xa6, 0x00}, + {0xac, 0x00}, {0xf7, 0x00}, {0xd7, 0x00}, {0xc9, 0xfe}, + /* 0xe0*/ + {0x40, 0x06}, {0xd3, 0xfe}, {0xd7, 0xfe}, {0xdb, 0xfe}, + {0xdf, 0xfe}, {0xe3, 0xfe}, {0xe7, 0xfe}, {0xeb, 0xfe}, + {0xed, 0xfe}, {0xef, 0xfe}, {0xf3, 0xfe}, {0xbd, 0xfe}, + {0xcc, 0xfe}, {0xce, 0xfe}, {0xcd, 0xfe}, {0xe1, 0xfe}, + /* 0xf0*/ + {0x7d, 0xfe}, {0x51, 0x06}, {0xe5, 0xfe}, {0xe9, 0xfe}, + {0xec, 0xfe}, {0xf0, 0xfe}, {0xf2, 0xfe}, {0xd0, 0xfe}, + {0xd5, 0xfe}, {0xf5, 0xfe}, {0xf6, 0xfe}, {0xdd, 0xfe}, + {0xd9, 0xfe}, {0xf1, 0xfe}, {0xa0, 0x25}, {0x00, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x00, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0xc0, 0xa3, 0xa4, 0x00, 0xdb, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x97, 0xdc, 0xa1, 0x00, 0x00, /* 0xa8-0xaf */ + 0x80, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x98, 0x95, 0x94, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page06[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x60-0x67 */ + 0xb8, 0xb9, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x82, 0x83, 0x00, 0x00, 0x00, 0x91, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x85, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x8c, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x8f, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char pagefe[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, /* 0x78-0x7f */ + + 0xc1, 0xc2, 0xa2, 0xc3, 0xa5, 0xc4, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc7, 0xa8, 0xa9, /* 0x88-0x8f */ + 0x00, 0xc8, 0x00, 0xc9, 0x00, 0xaa, 0x00, 0xca, /* 0x90-0x97 */ + 0x00, 0xab, 0x00, 0xcb, 0x00, 0xad, 0x00, 0xcc, /* 0x98-0x9f */ + 0x00, 0xae, 0x00, 0xcd, 0x00, 0xaf, 0x00, 0xce, /* 0xa0-0xa7 */ + 0x00, 0xcf, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0xd2, /* 0xa8-0xaf */ + 0x00, 0xbc, 0x00, 0xd3, 0x00, 0xbd, 0x00, 0xd4, /* 0xb0-0xb7 */ + 0x00, 0xbe, 0x00, 0xd5, 0x00, 0xeb, 0x00, 0xd6, /* 0xb8-0xbf */ + 0x00, 0xd7, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xdf, 0xc5, 0xd9, 0xec, 0xee, 0xed, 0xda, /* 0xc8-0xcf */ + 0xf7, 0xba, 0x00, 0xe1, 0x00, 0xf8, 0x00, 0xe2, /* 0xd0-0xd7 */ + 0x00, 0xfc, 0x00, 0xe3, 0x00, 0xfb, 0x00, 0xe4, /* 0xd8-0xdf */ + 0x00, 0xef, 0x00, 0xe5, 0x00, 0xf2, 0x00, 0xe6, /* 0xe0-0xe7 */ + 0x00, 0xf3, 0x00, 0xe7, 0xf4, 0xe8, 0x00, 0xe9, /* 0xe8-0xef */ + 0xf5, 0xfd, 0xf6, 0xea, 0x00, 0xf9, 0xfa, 0x99, /* 0xf0-0xf7 */ + 0x9a, 0x00, 0x00, 0x9d, 0x9e, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, page03, NULL, NULL, page06, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, page22, NULL, NULL, page25, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, pagefe, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp864", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp864() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp865.c b/libunls/nls_cp865.c new file mode 100644 index 0000000..dfe37fd --- /dev/null +++ b/libunls/nls_cp865.c @@ -0,0 +1,436 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp865.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp865.c + * + * Charset cp865 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0xc7, 0x00}, {0xfc, 0x00}, {0xe9, 0x00}, {0xe2, 0x00}, + {0xe4, 0x00}, {0xe0, 0x00}, {0xe5, 0x00}, {0xe7, 0x00}, + {0xea, 0x00}, {0xeb, 0x00}, {0xe8, 0x00}, {0xef, 0x00}, + {0xee, 0x00}, {0xec, 0x00}, {0xc4, 0x00}, {0xc5, 0x00}, + /* 0x90*/ + {0xc9, 0x00}, {0xe6, 0x00}, {0xc6, 0x00}, {0xf4, 0x00}, + {0xf6, 0x00}, {0xf2, 0x00}, {0xfb, 0x00}, {0xf9, 0x00}, + {0xff, 0x00}, {0xd6, 0x00}, {0xdc, 0x00}, {0xf8, 0x00}, + {0xa3, 0x00}, {0xd8, 0x00}, {0xa7, 0x20}, {0x92, 0x01}, + /* 0xa0*/ + {0xe1, 0x00}, {0xed, 0x00}, {0xf3, 0x00}, {0xfa, 0x00}, + {0xf1, 0x00}, {0xd1, 0x00}, {0xaa, 0x00}, {0xba, 0x00}, + {0xbf, 0x00}, {0x10, 0x23}, {0xac, 0x00}, {0xbd, 0x00}, + {0xbc, 0x00}, {0xa1, 0x00}, {0xab, 0x00}, {0xa4, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0xb1, 0x03}, {0xdf, 0x00}, {0x93, 0x03}, {0xc0, 0x03}, + {0xa3, 0x03}, {0xc3, 0x03}, {0xb5, 0x00}, {0xc4, 0x03}, + {0xa6, 0x03}, {0x98, 0x03}, {0xa9, 0x03}, {0xb4, 0x03}, + {0x1e, 0x22}, {0xc6, 0x03}, {0xb5, 0x03}, {0x29, 0x22}, + /* 0xf0*/ + {0x61, 0x22}, {0xb1, 0x00}, {0x65, 0x22}, {0x64, 0x22}, + {0x20, 0x23}, {0x21, 0x23}, {0xf7, 0x00}, {0x48, 0x22}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x7f, 0x20}, {0xb2, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0x00, 0x9c, 0xaf, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0x00, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x9d, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x99, 0x9a, 0x00, 0x9c, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp865", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp865() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp866.c b/libunls/nls_cp866.c new file mode 100644 index 0000000..6c0be0d --- /dev/null +++ b/libunls/nls_cp866.c @@ -0,0 +1,364 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp866.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp866.c + * + * Charset cp866 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x10, 0x04}, {0x11, 0x04}, {0x12, 0x04}, {0x13, 0x04}, + {0x14, 0x04}, {0x15, 0x04}, {0x16, 0x04}, {0x17, 0x04}, + {0x18, 0x04}, {0x19, 0x04}, {0x1a, 0x04}, {0x1b, 0x04}, + {0x1c, 0x04}, {0x1d, 0x04}, {0x1e, 0x04}, {0x1f, 0x04}, + /* 0x90*/ + {0x20, 0x04}, {0x21, 0x04}, {0x22, 0x04}, {0x23, 0x04}, + {0x24, 0x04}, {0x25, 0x04}, {0x26, 0x04}, {0x27, 0x04}, + {0x28, 0x04}, {0x29, 0x04}, {0x2a, 0x04}, {0x2b, 0x04}, + {0x2c, 0x04}, {0x2d, 0x04}, {0x2e, 0x04}, {0x2f, 0x04}, + /* 0xa0*/ + {0x30, 0x04}, {0x31, 0x04}, {0x32, 0x04}, {0x33, 0x04}, + {0x34, 0x04}, {0x35, 0x04}, {0x36, 0x04}, {0x37, 0x04}, + {0x38, 0x04}, {0x39, 0x04}, {0x3a, 0x04}, {0x3b, 0x04}, + {0x3c, 0x04}, {0x3d, 0x04}, {0x3e, 0x04}, {0x3f, 0x04}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x61, 0x25}, {0x62, 0x25}, {0x56, 0x25}, + {0x55, 0x25}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x5c, 0x25}, {0x5b, 0x25}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0x5e, 0x25}, {0x5f, 0x25}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0x67, 0x25}, + /* 0xd0*/ + {0x68, 0x25}, {0x64, 0x25}, {0x65, 0x25}, {0x59, 0x25}, + {0x58, 0x25}, {0x52, 0x25}, {0x53, 0x25}, {0x6b, 0x25}, + {0x6a, 0x25}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, {0x80, 0x25}, + /* 0xe0*/ + {0x40, 0x04}, {0x41, 0x04}, {0x42, 0x04}, {0x43, 0x04}, + {0x44, 0x04}, {0x45, 0x04}, {0x46, 0x04}, {0x47, 0x04}, + {0x48, 0x04}, {0x49, 0x04}, {0x4a, 0x04}, {0x4b, 0x04}, + {0x4c, 0x04}, {0x4d, 0x04}, {0x4e, 0x04}, {0x4f, 0x04}, + /* 0xf0*/ + {0x01, 0x04}, {0x51, 0x04}, {0x04, 0x04}, {0x54, 0x04}, + {0x07, 0x04}, {0x57, 0x04}, {0x0e, 0x04}, {0x5e, 0x04}, + {0xb0, 0x00}, {0x19, 0x22}, {0xb7, 0x00}, {0x1a, 0x22}, + {0x16, 0x21}, {0xa4, 0x00}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x00, 0x00, 0xf4, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x30-0x37 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xf5, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, page21, page22, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0xf0, 0x00, 0xf2, 0x00, 0xf4, 0x00, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp866", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp866() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp869.c b/libunls/nls_cp869.c new file mode 100644 index 0000000..066f9e7 --- /dev/null +++ b/libunls/nls_cp869.c @@ -0,0 +1,328 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp869.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp869.c + * + * Charset cp869 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x86, 0x03}, {0x00, 0x00}, + {0xb7, 0x00}, {0xac, 0x00}, {0xa6, 0x00}, {0x18, 0x20}, + {0x19, 0x20}, {0x88, 0x03}, {0x15, 0x20}, {0x89, 0x03}, + /* 0x90*/ + {0x8a, 0x03}, {0xaa, 0x03}, {0x8c, 0x03}, {0x00, 0x00}, + {0x00, 0x00}, {0x8e, 0x03}, {0xab, 0x03}, {0xa9, 0x00}, + {0x8f, 0x03}, {0xb2, 0x00}, {0xb3, 0x00}, {0xac, 0x03}, + {0xa3, 0x00}, {0xad, 0x03}, {0xae, 0x03}, {0xaf, 0x03}, + /* 0xa0*/ + {0xca, 0x03}, {0x90, 0x03}, {0xcc, 0x03}, {0xcd, 0x03}, + {0x91, 0x03}, {0x92, 0x03}, {0x93, 0x03}, {0x94, 0x03}, + {0x95, 0x03}, {0x96, 0x03}, {0x97, 0x03}, {0xbd, 0x00}, + {0x98, 0x03}, {0x99, 0x03}, {0xab, 0x00}, {0xbb, 0x00}, + /* 0xb0*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x02, 0x25}, + {0x24, 0x25}, {0x9a, 0x03}, {0x9b, 0x03}, {0x9c, 0x03}, + {0x9d, 0x03}, {0x63, 0x25}, {0x51, 0x25}, {0x57, 0x25}, + {0x5d, 0x25}, {0x9e, 0x03}, {0x9f, 0x03}, {0x10, 0x25}, + /* 0xc0*/ + {0x14, 0x25}, {0x34, 0x25}, {0x2c, 0x25}, {0x1c, 0x25}, + {0x00, 0x25}, {0x3c, 0x25}, {0xa0, 0x03}, {0xa1, 0x03}, + {0x5a, 0x25}, {0x54, 0x25}, {0x69, 0x25}, {0x66, 0x25}, + {0x60, 0x25}, {0x50, 0x25}, {0x6c, 0x25}, {0xa3, 0x03}, + /* 0xd0*/ + {0xa4, 0x03}, {0xa5, 0x03}, {0xa6, 0x03}, {0xa7, 0x03}, + {0xa8, 0x03}, {0xa9, 0x03}, {0xb1, 0x03}, {0xb2, 0x03}, + {0xb3, 0x03}, {0x18, 0x25}, {0x0c, 0x25}, {0x88, 0x25}, + {0x84, 0x25}, {0xb4, 0x03}, {0xb5, 0x03}, {0x80, 0x25}, + /* 0xe0*/ + {0xb6, 0x03}, {0xb7, 0x03}, {0xb8, 0x03}, {0xb9, 0x03}, + {0xba, 0x03}, {0xbb, 0x03}, {0xbc, 0x03}, {0xbd, 0x03}, + {0xbe, 0x03}, {0xbf, 0x03}, {0xc0, 0x03}, {0xc1, 0x03}, + {0xc3, 0x03}, {0xc2, 0x03}, {0xc4, 0x03}, {0x84, 0x03}, + /* 0xf0*/ + {0xad, 0x00}, {0xb1, 0x00}, {0xc5, 0x03}, {0xc6, 0x03}, + {0xc7, 0x03}, {0xa7, 0x00}, {0xc8, 0x03}, {0x85, 0x03}, + {0xb0, 0x00}, {0xa8, 0x00}, {0xc9, 0x03}, {0xcb, 0x03}, + {0xb0, 0x03}, {0xce, 0x03}, {0xa0, 0x25}, {0xa0, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x8a, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0x97, 0x00, 0xae, 0x89, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0x99, 0x9a, 0x00, 0x00, 0x00, 0x88, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xaf, 0x00, 0xab, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0xef, 0xf7, 0x86, 0x00, /* 0x80-0x87 */ + 0x8d, 0x8f, 0x90, 0x00, 0x92, 0x00, 0x95, 0x98, /* 0x88-0x8f */ + 0xa1, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, /* 0x90-0x97 */ + 0xac, 0xad, 0xb5, 0xb6, 0xb7, 0xb8, 0xbd, 0xbe, /* 0x98-0x9f */ + 0xc6, 0xc7, 0x00, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, /* 0xa0-0xa7 */ + 0xd4, 0xd5, 0x91, 0x96, 0x9b, 0x9d, 0x9e, 0x9f, /* 0xa8-0xaf */ + 0xfc, 0xd6, 0xd7, 0xd8, 0xdd, 0xde, 0xe0, 0xe1, /* 0xb0-0xb7 */ + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, /* 0xb8-0xbf */ + 0xea, 0xeb, 0xed, 0xec, 0xee, 0xf2, 0xf3, 0xf4, /* 0xc0-0xc7 */ + 0xf6, 0xfa, 0xa0, 0xfb, 0xa2, 0xa3, 0xfd, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, /* 0x10-0x17 */ + 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, NULL, NULL, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x00, 0x9c, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0x00, 0x00, 0x00, 0xf5, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp869", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp869() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_cp874.c b/libunls/nls_cp874.c new file mode 100644 index 0000000..4867c2c --- /dev/null +++ b/libunls/nls_cp874.c @@ -0,0 +1,292 @@ +/* + * 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. + * + */ + +/* @(#)nls_cp874.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_cp874.c + * + * Charset cp874 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x26, 0x20}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x18, 0x20}, {0x19, 0x20}, {0x1c, 0x20}, + {0x1d, 0x20}, {0x22, 0x20}, {0x13, 0x20}, {0x14, 0x20}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x01, 0x0e}, {0x02, 0x0e}, {0x03, 0x0e}, + {0x04, 0x0e}, {0x05, 0x0e}, {0x06, 0x0e}, {0x07, 0x0e}, + {0x08, 0x0e}, {0x09, 0x0e}, {0x0a, 0x0e}, {0x0b, 0x0e}, + {0x0c, 0x0e}, {0x0d, 0x0e}, {0x0e, 0x0e}, {0x0f, 0x0e}, + /* 0xb0*/ + {0x10, 0x0e}, {0x11, 0x0e}, {0x12, 0x0e}, {0x13, 0x0e}, + {0x14, 0x0e}, {0x15, 0x0e}, {0x16, 0x0e}, {0x17, 0x0e}, + {0x18, 0x0e}, {0x19, 0x0e}, {0x1a, 0x0e}, {0x1b, 0x0e}, + {0x1c, 0x0e}, {0x1d, 0x0e}, {0x1e, 0x0e}, {0x1f, 0x0e}, + /* 0xc0*/ + {0x20, 0x0e}, {0x21, 0x0e}, {0x22, 0x0e}, {0x23, 0x0e}, + {0x24, 0x0e}, {0x25, 0x0e}, {0x26, 0x0e}, {0x27, 0x0e}, + {0x28, 0x0e}, {0x29, 0x0e}, {0x2a, 0x0e}, {0x2b, 0x0e}, + {0x2c, 0x0e}, {0x2d, 0x0e}, {0x2e, 0x0e}, {0x2f, 0x0e}, + /* 0xd0*/ + {0x30, 0x0e}, {0x31, 0x0e}, {0x32, 0x0e}, {0x33, 0x0e}, + {0x34, 0x0e}, {0x35, 0x0e}, {0x36, 0x0e}, {0x37, 0x0e}, + {0x38, 0x0e}, {0x39, 0x0e}, {0x3a, 0x0e}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x3f, 0x0e}, + /* 0xe0*/ + {0x40, 0x0e}, {0x41, 0x0e}, {0x42, 0x0e}, {0x43, 0x0e}, + {0x44, 0x0e}, {0x45, 0x0e}, {0x46, 0x0e}, {0x47, 0x0e}, + {0x48, 0x0e}, {0x49, 0x0e}, {0x4a, 0x0e}, {0x4b, 0x0e}, + {0x4c, 0x0e}, {0x4d, 0x0e}, {0x4e, 0x0e}, {0x4f, 0x0e}, + /* 0xf0*/ + {0x50, 0x0e}, {0x51, 0x0e}, {0x52, 0x0e}, {0x53, 0x0e}, + {0x54, 0x0e}, {0x55, 0x0e}, {0x56, 0x0e}, {0x57, 0x0e}, + {0x58, 0x0e}, {0x59, 0x0e}, {0x5a, 0x0e}, {0x5b, 0x0e}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page0e[256] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x00, 0x00, 0x93, 0x94, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, page0e, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "cp874", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_cp874() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_file.c b/libunls/nls_file.c new file mode 100644 index 0000000..434679a --- /dev/null +++ b/libunls/nls_file.c @@ -0,0 +1,189 @@ +/* + * 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. + * + */ + +/* @(#)nls_file.c 1.3 05/05/01 2000 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. + */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * nls_file: create a charset table from a input table file + * from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + * + * Only reads single byte to word matches. + * + * James Pearson (j.pearson@ge.ucl.ac.uk) 16-Aug-2000 + */ + +#include <mconfig.h> +#include <stdio.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <libport.h> +#include "nls.h" + +#define NUM 256 + +static void free_mem(struct unls_unicode *, unsigned char **); + +static void +free_mem(struct unls_unicode *charset2uni, unsigned char **page_uni2charset) +{ + int i; + + if (charset2uni) + free(charset2uni); + + if (page_uni2charset) { + for (i = 0; i < NUM; i++) { + if (page_uni2charset[i]) { + free(page_uni2charset[i]); + } + } + free(page_uni2charset); + } +} + +int +init_unls_file(char *filename) +{ + FILE *fp; + struct unls_unicode *charset2uni = NULL; + unsigned char **page_uni2charset = NULL; + char buf[1024]; + char *p; + unsigned int cp, uc; + struct unls_table *table; + int i, ok = 0; + + /* give up if no filename is given */ + if (filename == NULL) + return (-1); + + /* + * see if we already have a table with this name - built in tables + * have precedence of file tables - i.e. can't have the name of an + * existing table. Also, we may have already registered this file table + */ + if (find_unls(filename) != NULL) + return (-1); + + if ((fp = fopen(filename, "r")) == NULL) + return (-1); + + /* allocate memory for the forward conversion table */ + if ((charset2uni = (struct unls_unicode *) + malloc(sizeof (struct unls_unicode) * NUM)) == NULL) { + free_mem(charset2uni, page_uni2charset); + return (-1); + } + + /* any unknown character should be mapped to NULL */ + memset(charset2uni, 0, sizeof (struct unls_unicode) * NUM); + + /* + * some source files don't set the control characters 0x00 - 0x1f + * so set these by default + */ + for (i = 0; i < 32; i++) { + charset2uni[i].unls_low = i; + } + + /* also set DELETE (0x7f) by default */ + charset2uni[0x7f].unls_low = 0x7f; + + /* read each line of the file */ + while (fgets(buf, sizeof (buf), fp) != NULL) { + /* cut off any comments */ + if ((p = strchr(buf, '#')) != NULL) + *p = '\0'; + + /* look for two hex values */ + if (sscanf(buf, "%x%x", &cp, &uc) == 2) { + /* if they are not in range - fail */ + if (cp > 0xff || uc > 0xffff) { + continue; + } + + /* set the Unicode value for the given code point */ + charset2uni[cp].unls_low = uc & 0xff; + charset2uni[cp].unls_high = (uc >> 8) & 0xff; + + /* make sure we find at least one pair ... */ + ok = 1; + } + } + + fclose(fp); + + if (!ok) { + /* we haven't found anything ... */ + free_mem(charset2uni, page_uni2charset); + return (-1); + } + + /* allocate memory for the reverse table */ + if ((page_uni2charset = (unsigned char **) + malloc(sizeof (unsigned char *) * NUM)) == NULL) { + free_mem(charset2uni, page_uni2charset); + return (-1); + } + + memset(page_uni2charset, 0, sizeof (unsigned char *) * NUM); + + /* loop through the forward table, setting the reverse value */ + for (i = 0; i < NUM; i++) { + uc = charset2uni[i].unls_high; + cp = charset2uni[i].unls_low; + /* if the page doesn't exist, create a page */ + if (page_uni2charset[uc] == NULL) { + if ((page_uni2charset[uc] = + (unsigned char *) malloc(NUM)) == NULL) { + free_mem(charset2uni, page_uni2charset); + return (-1); + } + memset(page_uni2charset[uc], 0, NUM); + } + + /* set the reverse point in the page */ + page_uni2charset[uc][cp] = i; + } + + /* set up the table */ + if ((table = (struct unls_table *)malloc(sizeof (struct unls_table))) + == NULL) { + free_mem(charset2uni, page_uni2charset); + return (-1); + } + + /* give the table the file name, so we can find it again if needed */ + table->unls_name = strdup(filename); + table->unls_uni2cs = page_uni2charset; + table->unls_cs2uni = charset2uni; + table->unls_next = NULL; + + /* register the table */ + return (register_unls(table)); +} diff --git a/libunls/nls_iconv.c b/libunls/nls_iconv.c new file mode 100644 index 0000000..828e2af --- /dev/null +++ b/libunls/nls_iconv.c @@ -0,0 +1,101 @@ +/* + * 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. + * + */ + +/* @(#)nls_iconv.c 1.0 02/04/20 2002 J. Schilling */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * nls_iconv: create a pseudo-charset table to use iconv() provided by C + * library or libiconv by Bruno Haible + * The Unicode to charset table has only exact mappings. + * + * + * Jungshik Shin (jshin@mailaps.org) 04-Feb-2002 + */ + +#ifdef USE_ICONV +#include <mconfig.h> +#include <stdio.h> +#include <stdxlib.h> +#include <strdefs.h> +#include "nls.h" +#include <iconv.h> + +static void inc_use_count(void); +static void dec_use_count(void); + + +static void +inc_use_count() +{ + MOD_INC_USE_COUNT; +} + +static void +dec_use_count() +{ + MOD_DEC_USE_COUNT; +} + +int +init_nls_iconv(char *charset) +{ + iconv_t iconv_d; /* iconv conversion descriptor */ + struct unls_table *table; + + /* give up if no charset is given */ + if (charset == NULL) + return -1; + + /* see if we already have a table with this name - built in tables + have precedence over iconv() - i.e. can't have the name of an + existing table. Also, we may have already registered this file + table */ + if (find_unls(charset) != NULL) + return -1; + + if ((iconv_d = iconv_open("UCS-2BE", charset)) == (iconv_t) -1) + return -1; + + + /* set up the table */ + if ((table = (struct unls_table *)malloc(sizeof (struct unls_table))) + == NULL) { + return -1; + } + + /* give the table the file name, so we can find it again if needed */ + table->unls_name = strdup(charset); + table->unls_uni2cs = NULL; + table->unls_cs2uni = NULL; + table->unls_next = NULL; + table->iconv_d = iconv_d; + + /* register the table */ + return register_unls(table); +} +#endif diff --git a/libunls/nls_iso8859-1.c b/libunls/nls_iso8859-1.c new file mode 100644 index 0000000..9b376cb --- /dev/null +++ b/libunls/nls_iso8859-1.c @@ -0,0 +1,216 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-1.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-1.c + * + * Charset iso8859-1 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0xa1, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa4, 0x00}, {0xa5, 0x00}, {0xa6, 0x00}, {0xa7, 0x00}, + {0xa8, 0x00}, {0xa9, 0x00}, {0xaa, 0x00}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0xaf, 0x00}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00}, + {0xb4, 0x00}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00}, + {0xb8, 0x00}, {0xb9, 0x00}, {0xba, 0x00}, {0xbb, 0x00}, + {0xbc, 0x00}, {0xbd, 0x00}, {0xbe, 0x00}, {0xbf, 0x00}, + /* 0xc0*/ + {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00}, + {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00}, + /* 0xd0*/ + {0xd0, 0x00}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00}, + {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0xd7, 0x00}, + {0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0xdd, 0x00}, {0xde, 0x00}, {0xdf, 0x00}, + /* 0xe0*/ + {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00}, + {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00}, + {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, + {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00}, + /* 0xf0*/ + {0xf0, 0x00}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00}, + {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0xf7, 0x00}, + {0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0xfd, 0x00}, {0xfe, 0x00}, {0xff, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-1", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_1() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-14.c b/libunls/nls_iso8859-14.c new file mode 100644 index 0000000..ea7754e --- /dev/null +++ b/libunls/nls_iso8859-14.c @@ -0,0 +1,263 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-14.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-14.c + * + * Charset iso8859-14 translation tables. + * + * Generated automatically from the Unicode and charset table + * provided by the Unicode Organisation at + * http://www.unicode.org/ + * The Unicode to charset table has only exact mappings. + * + * Rhys Jones, Swansea University Computer Society + * rhys@sucs.swan.ac.uk + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x02, 0x1e}, {0x03, 0x1e}, {0xa3, 0x00}, + {0x0a, 0x01}, {0x0b, 0x01}, {0x0a, 0x1e}, {0xa7, 0x00}, + {0x80, 0x1e}, {0xa9, 0x00}, {0x82, 0x1e}, {0x0b, 0x1e}, + {0xf2, 0x1e}, {0xad, 0x00}, {0xae, 0x00}, {0x78, 0x01}, + /* 0xb0*/ + {0x1e, 0x1e}, {0x1f, 0x1e}, {0x20, 0x01}, {0x21, 0x01}, + {0x40, 0x1e}, {0x41, 0x1e}, {0xb6, 0x00}, {0x56, 0x1e}, + {0x81, 0x1e}, {0x57, 0x1e}, {0x83, 0x1e}, {0x60, 0x1e}, + {0xf3, 0x1e}, {0x84, 0x1e}, {0x85, 0x1e}, {0x61, 0x1e}, + /* 0xc0*/ + {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00}, + {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00}, + /* 0xd0*/ + {0x74, 0x01}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00}, + {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0x6a, 0x1e}, + {0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0xdd, 0x00}, {0x76, 0x01}, {0xdf, 0x00}, + /* 0xe0*/ + {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00}, + {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00}, + {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, + {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00}, + /* 0xf0*/ + {0x75, 0x01}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00}, + {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0x6b, 0x1e}, + {0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0xfd, 0x00}, {0x77, 0x01}, {0xff, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0x00, 0x00, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1, /* 0x18-0x1f */ + 0xb2, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xb4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xb9, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xbb, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xde, 0xfe, /* 0x70-0x77 */ + 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xa8, 0xb8, 0xaa, 0xba, 0xbd, 0xbe, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page1e[256] = { + 0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1, /* 0x18-0x1f */ + 0xb2, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xb4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xb9, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xbb, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xde, 0xfe, /* 0x70-0x77 */ + 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xa8, 0xb8, 0xaa, 0xba, 0xbd, 0xbe, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, page1e, NULL, + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +static struct unls_table table = { + "iso8859-14", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_14() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-15.c b/libunls/nls_iso8859-15.c new file mode 100644 index 0000000..8094f6c --- /dev/null +++ b/libunls/nls_iso8859-15.c @@ -0,0 +1,256 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-15.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-15.c + * + * Charset iso8859-15 translation tables. + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0xa1, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xac, 0x20}, {0xa5, 0x00}, {0x60, 0x01}, {0xa7, 0x00}, + {0x61, 0x01}, {0xa9, 0x00}, {0xaa, 0x00}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0xaf, 0x00}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00}, + {0x7d, 0x01}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00}, + {0x7e, 0x01}, {0xb9, 0x00}, {0xba, 0x00}, {0xbb, 0x00}, + {0x52, 0x01}, {0x53, 0x01}, {0x78, 0x01}, {0xbf, 0x00}, + /* 0xc0*/ + {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00}, + {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00}, + /* 0xd0*/ + {0xd0, 0x00}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00}, + {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0xd7, 0x00}, + {0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0xdd, 0x00}, {0xde, 0x00}, {0xdf, 0x00}, + /* 0xe0*/ + {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00}, + {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00}, + {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, + {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00}, + /* 0xf0*/ + {0xf0, 0x00}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00}, + {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0xf7, 0x00}, + {0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0xfd, 0x00}, {0xfe, 0x00}, {0xff, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0xba, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xbe, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +static struct unls_table table = { + "iso8859-15", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_15() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-2.c b/libunls/nls_iso8859-2.c new file mode 100644 index 0000000..e0c1052 --- /dev/null +++ b/libunls/nls_iso8859-2.c @@ -0,0 +1,288 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-2.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-2.c + * + * Charset iso8859-2 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x04, 0x01}, {0xd8, 0x02}, {0x41, 0x01}, + {0xa4, 0x00}, {0x3d, 0x01}, {0x5a, 0x01}, {0xa7, 0x00}, + {0xa8, 0x00}, {0x60, 0x01}, {0x5e, 0x01}, {0x64, 0x01}, + {0x79, 0x01}, {0xad, 0x00}, {0x7d, 0x01}, {0x7b, 0x01}, + /* 0xb0*/ + {0xb0, 0x00}, {0x05, 0x01}, {0xdb, 0x02}, {0x42, 0x01}, + {0xb4, 0x00}, {0x3e, 0x01}, {0x5b, 0x01}, {0xc7, 0x02}, + {0xb8, 0x00}, {0x61, 0x01}, {0x5f, 0x01}, {0x65, 0x01}, + {0x7a, 0x01}, {0xdd, 0x02}, {0x7e, 0x01}, {0x7c, 0x01}, + /* 0xc0*/ + {0x54, 0x01}, {0xc1, 0x00}, {0xc2, 0x00}, {0x02, 0x01}, + {0xc4, 0x00}, {0x39, 0x01}, {0x06, 0x01}, {0xc7, 0x00}, + {0x0c, 0x01}, {0xc9, 0x00}, {0x18, 0x01}, {0xcb, 0x00}, + {0x1a, 0x01}, {0xcd, 0x00}, {0xce, 0x00}, {0x0e, 0x01}, + /* 0xd0*/ + {0x10, 0x01}, {0x43, 0x01}, {0x47, 0x01}, {0xd3, 0x00}, + {0xd4, 0x00}, {0x50, 0x01}, {0xd6, 0x00}, {0xd7, 0x00}, + {0x58, 0x01}, {0x6e, 0x01}, {0xda, 0x00}, {0x70, 0x01}, + {0xdc, 0x00}, {0xdd, 0x00}, {0x62, 0x01}, {0xdf, 0x00}, + /* 0xe0*/ + {0x55, 0x01}, {0xe1, 0x00}, {0xe2, 0x00}, {0x03, 0x01}, + {0xe4, 0x00}, {0x3a, 0x01}, {0x07, 0x01}, {0xe7, 0x00}, + {0x0d, 0x01}, {0xe9, 0x00}, {0x19, 0x01}, {0xeb, 0x00}, + {0x1b, 0x01}, {0xed, 0x00}, {0xee, 0x00}, {0x0f, 0x01}, + /* 0xf0*/ + {0x11, 0x01}, {0x44, 0x01}, {0x48, 0x01}, {0xf3, 0x00}, + {0xf4, 0x00}, {0x51, 0x01}, {0xf6, 0x00}, {0xf7, 0x00}, + {0x59, 0x01}, {0x6f, 0x01}, {0xfa, 0x00}, {0x71, 0x01}, + {0xfc, 0x00}, {0xfd, 0x00}, {0x63, 0x01}, {0xd9, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xda, 0x00, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xa5, 0xb5, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x40-0x47 */ + 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x50-0x57 */ + 0xd8, 0xf8, 0xa6, 0xb6, 0x00, 0x00, 0xaa, 0xba, /* 0x58-0x5f */ + 0xa9, 0xb9, 0xde, 0xfe, 0xab, 0xbb, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x68-0x6f */ + 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0x00, 0xb4, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-2", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_2() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-3.c b/libunls/nls_iso8859-3.c new file mode 100644 index 0000000..833b08c --- /dev/null +++ b/libunls/nls_iso8859-3.c @@ -0,0 +1,288 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-3.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-3.c + * + * Charset iso8859-3 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x26, 0x01}, {0xd8, 0x02}, {0xa3, 0x00}, + {0xa4, 0x00}, {0x00, 0x00}, {0x24, 0x01}, {0xa7, 0x00}, + {0xa8, 0x00}, {0x30, 0x01}, {0x5e, 0x01}, {0x1e, 0x01}, + {0x34, 0x01}, {0xad, 0x00}, {0x00, 0x00}, {0x7b, 0x01}, + /* 0xb0*/ + {0xb0, 0x00}, {0x27, 0x01}, {0xb2, 0x00}, {0xb3, 0x00}, + {0xb4, 0x00}, {0xb5, 0x00}, {0x25, 0x01}, {0xb7, 0x00}, + {0xb8, 0x00}, {0x31, 0x01}, {0x5f, 0x01}, {0x1f, 0x01}, + {0x35, 0x01}, {0xbd, 0x00}, {0x00, 0x00}, {0x7c, 0x01}, + /* 0xc0*/ + {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0x00, 0x00}, + {0xc4, 0x00}, {0x0a, 0x01}, {0x08, 0x01}, {0xc7, 0x00}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00}, + /* 0xd0*/ + {0x00, 0x00}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00}, + {0xd4, 0x00}, {0x20, 0x01}, {0xd6, 0x00}, {0xd7, 0x00}, + {0x1c, 0x01}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0x6c, 0x01}, {0x5c, 0x01}, {0xdf, 0x00}, + /* 0xe0*/ + {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0x00, 0x00}, + {0xe4, 0x00}, {0x0b, 0x01}, {0x09, 0x01}, {0xe7, 0x00}, + {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, + {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00}, + /* 0xf0*/ + {0x00, 0x00}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00}, + {0xf4, 0x00}, {0x21, 0x01}, {0xf6, 0x00}, {0xf7, 0x00}, + {0x1d, 0x01}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0x6d, 0x01}, {0x5d, 0x01}, {0xd9, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0xa3, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0xb3, 0xb4, 0xb5, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0xc6, 0xe6, 0xc5, 0xe5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0xd8, 0xf8, 0xab, 0xbb, /* 0x18-0x1f */ + 0xd5, 0xf5, 0x00, 0x00, 0xa6, 0xb6, 0xa1, 0xb1, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xa9, 0xb9, 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, 0xaa, 0xba, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0xdd, 0xfd, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0xaf, 0xbf, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa2, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0xb3, 0xb4, 0xb5, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-3", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_3() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-4.c b/libunls/nls_iso8859-4.c new file mode 100644 index 0000000..20a7744 --- /dev/null +++ b/libunls/nls_iso8859-4.c @@ -0,0 +1,288 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-4.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-4.c + * + * Charset iso8859-4 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x04, 0x01}, {0x38, 0x01}, {0x56, 0x01}, + {0xa4, 0x00}, {0x28, 0x01}, {0x3b, 0x01}, {0xa7, 0x00}, + {0xa8, 0x00}, {0x60, 0x01}, {0x12, 0x01}, {0x22, 0x01}, + {0x66, 0x01}, {0xad, 0x00}, {0x7d, 0x01}, {0xaf, 0x00}, + /* 0xb0*/ + {0xb0, 0x00}, {0x05, 0x01}, {0xdb, 0x02}, {0x57, 0x01}, + {0xb4, 0x00}, {0x29, 0x01}, {0x3c, 0x01}, {0xc7, 0x02}, + {0xb8, 0x00}, {0x61, 0x01}, {0x13, 0x01}, {0x23, 0x01}, + {0x67, 0x01}, {0x4a, 0x01}, {0x7e, 0x01}, {0x4b, 0x01}, + /* 0xc0*/ + {0x00, 0x01}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00}, + {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0x2e, 0x01}, + {0x0c, 0x01}, {0xc9, 0x00}, {0x18, 0x01}, {0xcb, 0x00}, + {0x16, 0x01}, {0xcd, 0x00}, {0xce, 0x00}, {0x2a, 0x01}, + /* 0xd0*/ + {0x10, 0x01}, {0x45, 0x01}, {0x4c, 0x01}, {0x36, 0x01}, + {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0xd7, 0x00}, + {0xd8, 0x00}, {0x72, 0x01}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0x68, 0x01}, {0x6a, 0x01}, {0xdf, 0x00}, + /* 0xe0*/ + {0x01, 0x01}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00}, + {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0x2f, 0x01}, + {0x0d, 0x01}, {0xe9, 0x00}, {0x19, 0x01}, {0xeb, 0x00}, + {0x17, 0x01}, {0xed, 0x00}, {0xee, 0x00}, {0x2b, 0x01}, + /* 0xf0*/ + {0x11, 0x01}, {0x46, 0x01}, {0x4d, 0x01}, {0x37, 0x01}, + {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0xf7, 0x00}, + {0xf8, 0x00}, {0x73, 0x01}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0x69, 0x01}, {0x6b, 0x01}, {0xd9, 0x02}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0x00, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0xaa, 0xba, 0x00, 0x00, 0xcc, 0xec, /* 0x10-0x17 */ + 0xca, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xab, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xa5, 0xb5, 0xcf, 0xef, 0x00, 0x00, 0xc7, 0xe7, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf3, /* 0x30-0x37 */ + 0xa2, 0x00, 0x00, 0xa6, 0xb6, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf1, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0xbd, 0xbf, 0xd2, 0xf2, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xb3, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa9, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xac, 0xbc, /* 0x60-0x67 */ + 0xdd, 0xfd, 0xde, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd9, 0xf9, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, page02, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0x00, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0x00, 0xb4, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-4", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_4() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-5.c b/libunls/nls_iso8859-5.c new file mode 100644 index 0000000..8b84ea8 --- /dev/null +++ b/libunls/nls_iso8859-5.c @@ -0,0 +1,292 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-5.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-5.c + * + * Charset iso8859-5 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x01, 0x04}, {0x02, 0x04}, {0x03, 0x04}, + {0x04, 0x04}, {0x05, 0x04}, {0x06, 0x04}, {0x07, 0x04}, + {0x08, 0x04}, {0x09, 0x04}, {0x0a, 0x04}, {0x0b, 0x04}, + {0x0c, 0x04}, {0xad, 0x00}, {0x0e, 0x04}, {0x0f, 0x04}, + /* 0xb0*/ + {0x10, 0x04}, {0x11, 0x04}, {0x12, 0x04}, {0x13, 0x04}, + {0x14, 0x04}, {0x15, 0x04}, {0x16, 0x04}, {0x17, 0x04}, + {0x18, 0x04}, {0x19, 0x04}, {0x1a, 0x04}, {0x1b, 0x04}, + {0x1c, 0x04}, {0x1d, 0x04}, {0x1e, 0x04}, {0x1f, 0x04}, + /* 0xc0*/ + {0x20, 0x04}, {0x21, 0x04}, {0x22, 0x04}, {0x23, 0x04}, + {0x24, 0x04}, {0x25, 0x04}, {0x26, 0x04}, {0x27, 0x04}, + {0x28, 0x04}, {0x29, 0x04}, {0x2a, 0x04}, {0x2b, 0x04}, + {0x2c, 0x04}, {0x2d, 0x04}, {0x2e, 0x04}, {0x2f, 0x04}, + /* 0xd0*/ + {0x30, 0x04}, {0x31, 0x04}, {0x32, 0x04}, {0x33, 0x04}, + {0x34, 0x04}, {0x35, 0x04}, {0x36, 0x04}, {0x37, 0x04}, + {0x38, 0x04}, {0x39, 0x04}, {0x3a, 0x04}, {0x3b, 0x04}, + {0x3c, 0x04}, {0x3d, 0x04}, {0x3e, 0x04}, {0x3f, 0x04}, + /* 0xe0*/ + {0x40, 0x04}, {0x41, 0x04}, {0x42, 0x04}, {0x43, 0x04}, + {0x44, 0x04}, {0x45, 0x04}, {0x46, 0x04}, {0x47, 0x04}, + {0x48, 0x04}, {0x49, 0x04}, {0x4a, 0x04}, {0x4b, 0x04}, + {0x4c, 0x04}, {0x4d, 0x04}, {0x4e, 0x04}, {0x4f, 0x04}, + /* 0xf0*/ + {0x16, 0x21}, {0x51, 0x04}, {0x52, 0x04}, {0x53, 0x04}, + {0x54, 0x04}, {0x55, 0x04}, {0x56, 0x04}, {0x57, 0x04}, + {0x58, 0x04}, {0x59, 0x04}, {0x5a, 0x04}, {0x5b, 0x04}, + {0x5c, 0x04}, {0xa7, 0x00}, {0x5e, 0x04}, {0x5f, 0x04}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page21[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, page21, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-5", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_5() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-6.c b/libunls/nls_iso8859-6.c new file mode 100644 index 0000000..44e259b --- /dev/null +++ b/libunls/nls_iso8859-6.c @@ -0,0 +1,252 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-6.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-6.c + * + * Charset iso8859-6 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x60, 0x06}, {0x61, 0x06}, {0x62, 0x06}, {0x63, 0x06}, + {0x64, 0x06}, {0x65, 0x06}, {0x66, 0x06}, {0x67, 0x06}, + {0x68, 0x06}, {0x69, 0x06}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0xa4, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x0c, 0x06}, {0xad, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xb0*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x1b, 0x06}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x1f, 0x06}, + /* 0xc0*/ + {0x00, 0x00}, {0x21, 0x06}, {0x22, 0x06}, {0x23, 0x06}, + {0x24, 0x06}, {0x25, 0x06}, {0x26, 0x06}, {0x27, 0x06}, + {0x28, 0x06}, {0x29, 0x06}, {0x2a, 0x06}, {0x2b, 0x06}, + {0x2c, 0x06}, {0x2d, 0x06}, {0x2e, 0x06}, {0x2f, 0x06}, + /* 0xd0*/ + {0x30, 0x06}, {0x31, 0x06}, {0x32, 0x06}, {0x33, 0x06}, + {0x34, 0x06}, {0x35, 0x06}, {0x36, 0x06}, {0x37, 0x06}, + {0x38, 0x06}, {0x39, 0x06}, {0x3a, 0x06}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xe0*/ + {0x40, 0x06}, {0x41, 0x06}, {0x42, 0x06}, {0x43, 0x06}, + {0x44, 0x06}, {0x45, 0x06}, {0x46, 0x06}, {0x47, 0x06}, + {0x48, 0x06}, {0x49, 0x06}, {0x4a, 0x06}, {0x4b, 0x06}, + {0x4c, 0x06}, {0x4d, 0x06}, {0x4e, 0x06}, {0x4f, 0x06}, + /* 0xf0*/ + {0x50, 0x06}, {0x51, 0x06}, {0x52, 0x06}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page06[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x60-0x67 */ + 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, NULL, NULL, page06, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-6", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_6() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-7.c b/libunls/nls_iso8859-7.c new file mode 100644 index 0000000..cc1438a --- /dev/null +++ b/libunls/nls_iso8859-7.c @@ -0,0 +1,328 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-7.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-7.c + * + * Charset iso8859-7 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0xbd, 0x02}, {0xbc, 0x02}, {0xa3, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0xa6, 0x00}, {0xa7, 0x00}, + {0xa8, 0x00}, {0xa9, 0x00}, {0x00, 0x00}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0x00, 0x00}, {0x15, 0x20}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00}, + {0x84, 0x03}, {0x85, 0x03}, {0x86, 0x03}, {0xb7, 0x00}, + {0x88, 0x03}, {0x89, 0x03}, {0x8a, 0x03}, {0xbb, 0x00}, + {0x8c, 0x03}, {0xbd, 0x00}, {0x8e, 0x03}, {0x8f, 0x03}, + /* 0xc0*/ + {0x90, 0x03}, {0x91, 0x03}, {0x92, 0x03}, {0x93, 0x03}, + {0x94, 0x03}, {0x95, 0x03}, {0x96, 0x03}, {0x97, 0x03}, + {0x98, 0x03}, {0x99, 0x03}, {0x9a, 0x03}, {0x9b, 0x03}, + {0x9c, 0x03}, {0x9d, 0x03}, {0x9e, 0x03}, {0x9f, 0x03}, + /* 0xd0*/ + {0xa0, 0x03}, {0xa1, 0x03}, {0x00, 0x00}, {0xa3, 0x03}, + {0xa4, 0x03}, {0xa5, 0x03}, {0xa6, 0x03}, {0xa7, 0x03}, + {0xa8, 0x03}, {0xa9, 0x03}, {0xaa, 0x03}, {0xab, 0x03}, + {0xac, 0x03}, {0xad, 0x03}, {0xae, 0x03}, {0xaf, 0x03}, + /* 0xe0*/ + {0xb0, 0x03}, {0xb1, 0x03}, {0xb2, 0x03}, {0xb3, 0x03}, + {0xb4, 0x03}, {0xb5, 0x03}, {0xb6, 0x03}, {0xb7, 0x03}, + {0xb8, 0x03}, {0xb9, 0x03}, {0xba, 0x03}, {0xbb, 0x03}, + {0xbc, 0x03}, {0xbd, 0x03}, {0xbe, 0x03}, {0xbf, 0x03}, + /* 0xf0*/ + {0xc0, 0x03}, {0xc1, 0x03}, {0xc2, 0x03}, {0xc3, 0x03}, + {0xc4, 0x03}, {0xc5, 0x03}, {0xc6, 0x03}, {0xc7, 0x03}, + {0xc8, 0x03}, {0xc9, 0x03}, {0xca, 0x03}, {0xcb, 0x03}, + {0xcc, 0x03}, {0xcd, 0x03}, {0xce, 0x03}, {0x00, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page02[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa1, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page03[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0x00, /* 0x80-0x87 */ + 0xb8, 0xb9, 0xba, 0x00, 0xbc, 0x00, 0xbe, 0xbf, /* 0x88-0x8f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x90-0x97 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x98-0x9f */ + 0xd0, 0xd1, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xa0-0xa7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xa8-0xaf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xb0-0xb7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xb8-0xbf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xc0-0xc7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, page02, page03, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-7", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_7() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-8.c b/libunls/nls_iso8859-8.c new file mode 100644 index 0000000..6b69d32 --- /dev/null +++ b/libunls/nls_iso8859-8.c @@ -0,0 +1,292 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-8.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-8.c + * + * Charset iso8859-8 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0x00, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa4, 0x00}, {0xa5, 0x00}, {0xa6, 0x00}, {0xa7, 0x00}, + {0xa8, 0x00}, {0xa9, 0x00}, {0xd7, 0x00}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0x3e, 0x20}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00}, + {0xb4, 0x00}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00}, + {0xb8, 0x00}, {0xb9, 0x00}, {0xf7, 0x00}, {0xbb, 0x00}, + {0xbc, 0x00}, {0xbd, 0x00}, {0xbe, 0x00}, {0x00, 0x00}, + /* 0xc0*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xd0*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x17, 0x20}, + /* 0xe0*/ + {0xd0, 0x05}, {0xd1, 0x05}, {0xd2, 0x05}, {0xd3, 0x05}, + {0xd4, 0x05}, {0xd5, 0x05}, {0xd6, 0x05}, {0xd7, 0x05}, + {0xd8, 0x05}, {0xd9, 0x05}, {0xda, 0x05}, {0xdb, 0x05}, + {0xdc, 0x05}, {0xdd, 0x05}, {0xde, 0x05}, {0xdf, 0x05}, + /* 0xf0*/ + {0xe0, 0x05}, {0xe1, 0x05}, {0xe2, 0x05}, {0xe3, 0x05}, + {0xe4, 0x05}, {0xe5, 0x05}, {0xe6, 0x05}, {0xe7, 0x05}, + {0xe8, 0x05}, {0xe9, 0x05}, {0xea, 0x05}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page05[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page20[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, NULL, page05, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-8", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_8() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_iso8859-9.c b/libunls/nls_iso8859-9.c new file mode 100644 index 0000000..8229922 --- /dev/null +++ b/libunls/nls_iso8859-9.c @@ -0,0 +1,252 @@ +/* + * 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. + * + */ + +/* @(#)nls_iso8859-9.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_iso8859-9.c + * + * Charset iso8859-9 translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0x90*/ + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, + /* 0xa0*/ + {0xa0, 0x00}, {0xa1, 0x00}, {0xa2, 0x00}, {0xa3, 0x00}, + {0xa4, 0x00}, {0xa5, 0x00}, {0xa6, 0x00}, {0xa7, 0x00}, + {0xa8, 0x00}, {0xa9, 0x00}, {0xaa, 0x00}, {0xab, 0x00}, + {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0xaf, 0x00}, + /* 0xb0*/ + {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00}, + {0xb4, 0x00}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00}, + {0xb8, 0x00}, {0xb9, 0x00}, {0xba, 0x00}, {0xbb, 0x00}, + {0xbc, 0x00}, {0xbd, 0x00}, {0xbe, 0x00}, {0xbf, 0x00}, + /* 0xc0*/ + {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00}, + {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00}, + {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00}, + /* 0xd0*/ + {0x1e, 0x01}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00}, + {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0xd7, 0x00}, + {0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00}, + {0xdc, 0x00}, {0x30, 0x01}, {0x5e, 0x01}, {0xdf, 0x00}, + /* 0xe0*/ + {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00}, + {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00}, + {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, + {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00}, + /* 0xf0*/ + {0x1f, 0x01}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00}, + {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0xf7, 0x00}, + {0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00}, + {0xfc, 0x00}, {0x31, 0x01}, {0x5f, 0x01}, {0xff, 0x00}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; + +static unsigned char page01[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, page01, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "iso8859-9", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_iso8859_9() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_koi8-r.c b/libunls/nls_koi8-r.c new file mode 100644 index 0000000..6be6933 --- /dev/null +++ b/libunls/nls_koi8-r.c @@ -0,0 +1,364 @@ +/* + * 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. + * + */ + +/* @(#)nls_koi8-r.c 1.2 05/05/01 2000 J. Schilling */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_koi8-r.c + * + * Charset koi8-r translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x25}, {0x02, 0x25}, {0x0c, 0x25}, {0x10, 0x25}, + {0x14, 0x25}, {0x18, 0x25}, {0x1c, 0x25}, {0x24, 0x25}, + {0x2c, 0x25}, {0x34, 0x25}, {0x3c, 0x25}, {0x80, 0x25}, + {0x84, 0x25}, {0x88, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, + /* 0x90*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x20, 0x23}, + {0xa0, 0x25}, {0x19, 0x22}, {0x1a, 0x22}, {0x48, 0x22}, + {0x64, 0x22}, {0x65, 0x22}, {0xa0, 0x00}, {0x21, 0x23}, + {0xb0, 0x00}, {0xb2, 0x00}, {0xb7, 0x00}, {0xf7, 0x00}, + /* 0xa0*/ + {0x50, 0x25}, {0x51, 0x25}, {0x52, 0x25}, {0x51, 0x04}, + {0x53, 0x25}, {0x54, 0x25}, {0x55, 0x25}, {0x56, 0x25}, + {0x57, 0x25}, {0x58, 0x25}, {0x59, 0x25}, {0x5a, 0x25}, + {0x5b, 0x25}, {0x5c, 0x25}, {0x5d, 0x25}, {0x5e, 0x25}, + /* 0xb0*/ + {0x5f, 0x25}, {0x60, 0x25}, {0x61, 0x25}, {0x01, 0x04}, + {0x62, 0x25}, {0x63, 0x25}, {0x64, 0x25}, {0x65, 0x25}, + {0x66, 0x25}, {0x67, 0x25}, {0x68, 0x25}, {0x69, 0x25}, + {0x6a, 0x25}, {0x6b, 0x25}, {0x6c, 0x25}, {0xa9, 0x00}, + /* 0xc0*/ + {0x4e, 0x04}, {0x30, 0x04}, {0x31, 0x04}, {0x46, 0x04}, + {0x34, 0x04}, {0x35, 0x04}, {0x44, 0x04}, {0x33, 0x04}, + {0x45, 0x04}, {0x38, 0x04}, {0x39, 0x04}, {0x3a, 0x04}, + {0x3b, 0x04}, {0x3c, 0x04}, {0x3d, 0x04}, {0x3e, 0x04}, + /* 0xd0*/ + {0x3f, 0x04}, {0x4f, 0x04}, {0x40, 0x04}, {0x41, 0x04}, + {0x42, 0x04}, {0x43, 0x04}, {0x36, 0x04}, {0x32, 0x04}, + {0x4c, 0x04}, {0x4b, 0x04}, {0x37, 0x04}, {0x48, 0x04}, + {0x4d, 0x04}, {0x49, 0x04}, {0x47, 0x04}, {0x4a, 0x04}, + /* 0xe0*/ + {0x2e, 0x04}, {0x10, 0x04}, {0x11, 0x04}, {0x26, 0x04}, + {0x14, 0x04}, {0x15, 0x04}, {0x24, 0x04}, {0x13, 0x04}, + {0x25, 0x04}, {0x18, 0x04}, {0x19, 0x04}, {0x1a, 0x04}, + {0x1b, 0x04}, {0x1c, 0x04}, {0x1d, 0x04}, {0x1e, 0x04}, + /* 0xf0*/ + {0x1f, 0x04}, {0x2f, 0x04}, {0x20, 0x04}, {0x21, 0x04}, + {0x22, 0x04}, {0x23, 0x04}, {0x16, 0x04}, {0x12, 0x04}, + {0x2c, 0x04}, {0x2b, 0x04}, {0x17, 0x04}, {0x28, 0x04}, + {0x2d, 0x04}, {0x29, 0x04}, {0x27, 0x04}, {0x2a, 0x04}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "koi8-r", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_koi8_r() +{ + return (register_unls(&table)); +} diff --git a/libunls/nls_koi8-u.c b/libunls/nls_koi8-u.c new file mode 100644 index 0000000..2623236 --- /dev/null +++ b/libunls/nls_koi8-u.c @@ -0,0 +1,364 @@ +/* + * 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. + * + */ + +/* @(#)nls_koi8-u.c 1.2 05/05/01 2002 J. Schilling by Andy Shevchenko */ +/* + * Modifications to make the code portable Copyright (c) 2000 J. Schilling + * + * Code taken from the Linux kernel. + */ +/* + * 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. + */ +/* + * linux/fs/nls_koi8-u.c + * + * Charset koi8-u translation tables. + * Generated automatically from the Unicode and charset + * tables from the Unicode Organization (www.unicode.org). + * The Unicode to charset table has only exact mappings. + */ + +#include <mconfig.h> +#include "nls.h" + +static struct unls_unicode charset2uni[256] = { + /* 0x00*/ + {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00}, + {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00}, + {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00}, + {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, + /* 0x10*/ + {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00}, + {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00}, + {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, + {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00}, + /* 0x20*/ + {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00}, + {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, + {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, + {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00}, + /* 0x30*/ + {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, + {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, + {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, + {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, + /* 0x40*/ + {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, + {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00}, + {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, + {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00}, + /* 0x50*/ + {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00}, + {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00}, + {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00}, + /* 0x60*/ + {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00}, + {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00}, + {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00}, + {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00}, + /* 0x70*/ + {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00}, + {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00}, + {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00}, + {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00}, + /* 0x80*/ + {0x00, 0x25}, {0x02, 0x25}, {0x0c, 0x25}, {0x10, 0x25}, + {0x14, 0x25}, {0x18, 0x25}, {0x1c, 0x25}, {0x24, 0x25}, + {0x2c, 0x25}, {0x34, 0x25}, {0x3c, 0x25}, {0x80, 0x25}, + {0x84, 0x25}, {0x88, 0x25}, {0x8c, 0x25}, {0x90, 0x25}, + /* 0x90*/ + {0x91, 0x25}, {0x92, 0x25}, {0x93, 0x25}, {0x20, 0x23}, + {0xa0, 0x25}, {0x19, 0x22}, {0x1a, 0x22}, {0x48, 0x22}, + {0x64, 0x22}, {0x65, 0x22}, {0xa0, 0x00}, {0x21, 0x23}, + {0xb0, 0x00}, {0xb2, 0x00}, {0xb7, 0x00}, {0xf7, 0x00}, + /* 0xa0*/ + {0x50, 0x25}, {0x51, 0x25}, {0x52, 0x25}, {0x51, 0x04}, + {0x54, 0x04}, {0x54, 0x25}, {0x56, 0x04}, {0x57, 0x04}, + {0x57, 0x25}, {0x58, 0x25}, {0x59, 0x25}, {0x5a, 0x25}, + {0x5b, 0x25}, {0x91, 0x04}, {0x5d, 0x25}, {0x5e, 0x25}, + /* 0xb0*/ + {0x5f, 0x25}, {0x60, 0x25}, {0x61, 0x25}, {0x01, 0x04}, + {0x04, 0x04}, {0x63, 0x25}, {0x06, 0x04}, {0x07, 0x04}, + {0x66, 0x25}, {0x67, 0x25}, {0x68, 0x25}, {0x69, 0x25}, + {0x6a, 0x25}, {0x90, 0x04}, {0x6c, 0x25}, {0xa9, 0x00}, + /* 0xc0*/ + {0x4e, 0x04}, {0x30, 0x04}, {0x31, 0x04}, {0x46, 0x04}, + {0x34, 0x04}, {0x35, 0x04}, {0x44, 0x04}, {0x33, 0x04}, + {0x45, 0x04}, {0x38, 0x04}, {0x39, 0x04}, {0x3a, 0x04}, + {0x3b, 0x04}, {0x3c, 0x04}, {0x3d, 0x04}, {0x3e, 0x04}, + /* 0xd0*/ + {0x3f, 0x04}, {0x4f, 0x04}, {0x40, 0x04}, {0x41, 0x04}, + {0x42, 0x04}, {0x43, 0x04}, {0x36, 0x04}, {0x32, 0x04}, + {0x4c, 0x04}, {0x4b, 0x04}, {0x37, 0x04}, {0x48, 0x04}, + {0x4d, 0x04}, {0x49, 0x04}, {0x47, 0x04}, {0x4a, 0x04}, + /* 0xe0*/ + {0x2e, 0x04}, {0x10, 0x04}, {0x11, 0x04}, {0x26, 0x04}, + {0x14, 0x04}, {0x15, 0x04}, {0x24, 0x04}, {0x13, 0x04}, + {0x25, 0x04}, {0x18, 0x04}, {0x19, 0x04}, {0x1a, 0x04}, + {0x1b, 0x04}, {0x1c, 0x04}, {0x1d, 0x04}, {0x1e, 0x04}, + /* 0xf0*/ + {0x1f, 0x04}, {0x2f, 0x04}, {0x20, 0x04}, {0x21, 0x04}, + {0x22, 0x04}, {0x23, 0x04}, {0x16, 0x04}, {0x12, 0x04}, + {0x2c, 0x04}, {0x2b, 0x04}, {0x17, 0x04}, {0x28, 0x04}, + {0x2d, 0x04}, {0x29, 0x04}, {0x27, 0x04}, {0x2a, 0x04}, +}; + +static unsigned char page00[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page04[256] = { + 0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page22[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page23[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char page25[256] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0x00, 0xa5, 0x00, 0x00, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0x00, 0xb5, 0x00, 0x00, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static unsigned char *page_uni2charset[256] = { + page00, NULL, NULL, NULL, page04, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, page22, page23, NULL, page25, NULL, NULL, +}; + +#if 0 +static unsigned char charset2upper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */ + 0xa0, 0xa1, 0xa2, 0xb3, 0xa4, 0xa5, 0xb6, 0xb7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xbd, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */ +}; +#endif + +static struct unls_table table = { + "koi8-u", + page_uni2charset, + charset2uni, + NULL +}; + +int +init_unls_koi8_u() +{ + return (register_unls(&table)); +} diff --git a/libusal/CMakeLists.txt b/libusal/CMakeLists.txt new file mode 100644 index 0000000..b6fc8e4 --- /dev/null +++ b/libusal/CMakeLists.txt @@ -0,0 +1,10 @@ +PROJECT (LIBSCG C) +INCLUDE_DIRECTORIES(../include ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +include(../include/AddScgBits.cmake) +ADD_DEFINITIONS(-DUSE_RCMD_RSH) + +#SET(LIBSCG_SRCS rdummy.c usalsettarget.c usaltimes.c scsi-linux-ata.c scsi-linux-pg.c scsi-linux-sg.c scsierrs.c scsihack.c scsihelp.c scsiopen.c scsitransp.c) +SET(LIBSCG_SRCS usalsettarget.c usaltimes.c scsierrs.c scsihack.c scsihelp.c scsiopen.c scsitransp.c scsi-remote.c) +LINK_DIRECTORIES(../librols) +ADD_LIBRARY (usal STATIC ${LIBSCG_SRCS}) +TARGET_LINK_LIBRARIES(usal ${SCG_SELF_LIBS}) diff --git a/libusal/pg.h b/libusal/pg.h new file mode 100644 index 0000000..8e8bf18 --- /dev/null +++ b/libusal/pg.h @@ -0,0 +1,75 @@ +/* + * 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. + * + */ + +/* pg.h (c) 1998 Grant R. Guenther <grant@torque.net> + Under the terms of the GNU public license + + + pg.h defines the user interface to the generic ATAPI packet + command driver for parallel port ATAPI devices (pg). The + driver is loosely modelled after the generic SCSI driver, sg, + although the actual interface is different. + + The pg driver provides a simple character device interface for + sending ATAPI commands to a device. With the exception of the + ATAPI reset operation, all operations are performed by a pair + of read and write operations to the appropriate /dev/pgN device. + A write operation delivers a command and any outbound data in + a single buffer. Normally, the write will succeed unless the + device is offline or malfunctioning, or there is already another + command pending. If the write succeeds, it should be followed + immediately by a read operation, to obtain any returned data and + status information. A read will fail if there is no operation + in progress. + + As a special case, the device can be reset with a write operation, + and in this case, no following read is expected, or permitted. + + There are no ioctl() operations. Any single operation + may transfer at most PG_MAX_DATA bytes. Note that the driver must + copy the data through an internal buffer. In keeping with all + current ATAPI devices, command packets are assumed to be exactly + 12 bytes in length. + + To permit future changes to this interface, the headers in the + read and write buffers contain a single character "magic" flag. + Currently this flag must be the character "P". + +*/ + +#define PG_MAGIC 'P' +#define PG_RESET 'Z' +#define PG_COMMAND 'C' + +#define PG_MAX_DATA 32768 + +struct pg_write_hdr { + + char magic; /* == PG_MAGIC */ + char func; /* PG_RESET or PG_COMMAND */ + int dlen; /* number of bytes expected to transfer */ + int timeout; /* number of seconds before timeout */ + char packet[12]; /* packet command */ + +}; + +struct pg_read_hdr { + + char magic; /* == PG_MAGIC */ + char scsi; /* "scsi" status == sense key */ + int dlen; /* size of device transfer request */ + int duration; /* time in seconds command took */ + char pad[12]; /* not used */ + +}; + +/* end of pg.h */ diff --git a/libusal/rdummy.c b/libusal/rdummy.c new file mode 100644 index 0000000..4457e00 --- /dev/null +++ b/libusal/rdummy.c @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +/* @(#)rdummy.c 1.1 00/08/26 Copyright 2000 J. Schilling */ +/* + * usal Library + * dummy remote ops + * + * Copyright (c) 2000 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 <standard.h> +#include <schily.h> + +#include <usal/scsitransp.h> + +usal_ops_t *usal_remote(void); + +EXPORT usal_ops_t * +usal_remote() +{ +extern usal_ops_t usal_remote_ops; + + return (&usal_remote_ops); +} diff --git a/libusal/scsi-aix.c b/libusal/scsi-aix.c new file mode 100644 index 0000000..a7b4be6 --- /dev/null +++ b/libusal/scsi-aix.c @@ -0,0 +1,428 @@ +/* + * 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. + * + */ + +/* @(#)scsi-aix.c 1.36 04/01/14 Copyright 1997 J. Schilling */ +/* + * Interface for the AIX generic SCSI implementation. + * + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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 <sys/scdisk.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-aix.c-1.36"; /* The version for this transport*/ + + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local{ + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local*)((p)->local)) + +#define MAX_DMA_AIX (64*1024) + +static int do_usal_cmd(SCSI *usalp, struct usal_cmd *sp); +static int do_usal_sense(SCSI *usalp, struct usal_cmd *sp); + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "DKIOCMD", "SCSI transport for targets known by AIX drivers", + "", "bus,target,lun or UNIX device", "1,2,0 or /dev/rcd0@", FALSE, TRUE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[32]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) + goto openbydev; + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + + snprintf(devname, sizeof (devname), "/dev/rcd%d", tgt); + f = openx(devname, 0, 0, SC_DIAGNOSTIC); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'. Specify device number (1 for cd1) as target (1,0)", + devname); + return (0); + } + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + return (1); + } else { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Unable to scan on AIX"); + return (0); + } +openbydev: + if (device != NULL && *device != '\0' && busno >= 0 && tgt >= 0 && tlun >= 0) { + f = openx(device, 0, 0, SC_DIAGNOSTIC); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + devname); + return (0); + } + + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + usal_settarget(usalp, busno, tgt, tlun); + + return (++nopen); + } + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local== NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_AIX); +} + +#define palign(x, a) (((char *)(x)) + ((a) - 1 - (((UIntptr_t)((x)-1))%(a)))) + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ +/* assume having a modern AIX here */ +#ifdef HAVE_ALLOCA_H + usalp->bufbase = (void *)valloc((size_t)amt); + return (usalp->bufbase); +#else + void *ret; + int pagesize = getpagesize(); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + /* + * Damn AIX is a paged system but has no valloc() + */ + usalp->bufbase = ret = malloc((size_t)(amt+pagesize)); + if (ret == NULL) + return (ret); + ret = palign(ret, pagesize); + return (ret); +#endif +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + /* + * XXX Does this reset TGT or BUS ??? + */ + return (ioctl(usalp->fd, SCIORESET, IDLUN(usal_target(usalp), usal_lun(usalp)))); +} + +static int +do_usal_cmd(SCSI *usalp, struct usal_cmd *sp) +{ + struct sc_iocmd req; + int ret; + + if (sp->cdb_len > 12) + comerrno(EX_BAD, "Can't do %d byte command.\n", sp->cdb_len); + + fillbytes(&req, sizeof (req), '\0'); + + req.flags = SC_ASYNC; + if (sp->flags & SCG_RECV_DATA) { + req.flags |= B_READ; + } else if (sp->size > 0) { + req.flags |= B_WRITE; + } + req.data_length = sp->size; + req.buffer = sp->addr; + req.timeout_value = sp->timeout; + req.command_length = sp->cdb_len; + + movebytes(&sp->cdb, req.scsi_cdb, 12); + errno = 0; + ret = ioctl(usalp->fd, DKIOCMD, &req); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "ret: %d errno: %d (%s)\n", ret, errno, errmsgstr(errno)); + fprintf((FILE *)usalp->errfile, "data_length: %d\n", req.data_length); + fprintf((FILE *)usalp->errfile, "buffer: 0x%X\n", req.buffer); + fprintf((FILE *)usalp->errfile, "timeout_value: %d\n", req.timeout_value); + fprintf((FILE *)usalp->errfile, "status_validity: %d\n", req.status_validity); + fprintf((FILE *)usalp->errfile, "scsi_bus_status: 0x%X\n", req.scsi_bus_status); + fprintf((FILE *)usalp->errfile, "adapter_status: 0x%X\n", req.adapter_status); + fprintf((FILE *)usalp->errfile, "adap_q_status: 0x%X\n", req.adap_q_status); + fprintf((FILE *)usalp->errfile, "q_tag_msg: 0x%X\n", req.q_tag_msg); + fprintf((FILE *)usalp->errfile, "flags: 0X%X\n", req.flags); + } + if (ret < 0) { + sp->ux_errno = geterrno(); + /* + * Check if SCSI command cound not be send at all. + */ + if (sp->ux_errno == ENOTTY || sp->ux_errno == ENXIO || + sp->ux_errno == EINVAL || sp->ux_errno == EACCES) { + return (-1); + } + } else { + sp->ux_errno = 0; + } + ret = 0; + sp->sense_count = 0; + sp->resid = 0; /* AIX is the same rubbish as Linux here */ + + fillbytes(&sp->scb, sizeof (sp->scb), '\0'); + fillbytes(&sp->u_sense.cmd_sense, sizeof (sp->u_sense.cmd_sense), '\0'); + + if (req.status_validity == 0) { + sp->error = SCG_NO_ERROR; + return (0); + } + if (req.status_validity & 1) { + sp->u_scb.cmd_scb[0] = req.scsi_bus_status; + sp->error = SCG_RETRYABLE; + } + if (req.status_validity & 2) { + if (req.adapter_status & SC_NO_DEVICE_RESPONSE) { + sp->error = SCG_FATAL; + + } else if (req.adapter_status & SC_CMD_TIMEOUT) { + sp->error = SCG_TIMEOUT; + + } else if (req.adapter_status != 0) { + sp->error = SCG_RETRYABLE; + } + } + + return (ret); +} + +static int +do_usal_sense(SCSI *usalp, struct usal_cmd *sp) +{ + int ret; + struct usal_cmd s_cmd; + + fillbytes((caddr_t)&s_cmd, sizeof (s_cmd), '\0'); + s_cmd.addr = sp->u_sense.cmd_sense; + s_cmd.size = sp->sense_len; + s_cmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA; + s_cmd.cdb_len = SC_G0_CDBLEN; + s_cmd.sense_len = CCS_SENSE_LEN; + s_cmd.cdb.g0_cdb.cmd = SC_REQUEST_SENSE; + s_cmd.cdb.g0_cdb.lun = sp->cdb.g0_cdb.lun; + s_cmd.cdb.g0_cdb.count = sp->sense_len; + ret = do_usal_cmd(usalp, &s_cmd); + + if (ret < 0) + return (ret); + if (s_cmd.u_scb.cmd_scb[0] & 02) { + /* XXX ??? Check condition on request Sense ??? */ + } + sp->sense_count = sp->sense_len - s_cmd.resid; + return (ret); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + ret = do_usal_cmd(usalp, sp); + if (ret < 0) + return (ret); + if (sp->u_scb.cmd_scb[0] & 02) + ret = do_usal_sense(usalp, sp); + return (ret); +} diff --git a/libusal/scsi-amigaos.c b/libusal/scsi-amigaos.c new file mode 100644 index 0000000..991a4ab --- /dev/null +++ b/libusal/scsi-amigaos.c @@ -0,0 +1,771 @@ +/* + * 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. + * + */ + +/* @(#)scsi-amigaos.c 1.6 04/01/14 Copyright 1997,2000-2003 J. Schilling */ +/* + * Interface for the AmigaOS generic SCSI implementation. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997, 2000-2003 J. Schilling + * AmigaOS support code written by T. Langer + */ +/* + * 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. + */ + +#define BOOL int + +#include <strdefs.h> +#include <exec/ports.h> +#include <exec/io.h> +#include <exec/errors.h> +#include <devices/scsidisk.h> +#include <devices/timer.h> +#include <exec/semaphores.h> +#include <exec/memory.h> +#include <exec/execbase.h> +#include <clib/exec_protos.h> +#include <clib/alib_protos.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-amigaos.c-1.6"; /* The version for this transport */ +static char _usal_auth[] = "T. Langer"; + +#define MAX_SCG 8 /* Max # of SCSI controllers */ +#define MAX_TGT 8 +#define MAX_LUN 8 +#define MAX_DEV MAX_SCG*MAX_TGT*MAX_LUN + +struct usal_local{ + int usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; + +#define usallocal(p) ((struct usal_local*)((p)->local)) + +#define MAX_DMA_AMIGAOS (64*1024) + +static struct IOReq { + struct IOStdReq *ioReq; + int ref_count; +} request[MAX_DEV]; + +static char *devs[MAX_SCG]; +static struct MsgPort *ioMsgPort = NULL; +static struct timerequest *timer_io = NULL; +static struct MsgPort *timerMsgPort = NULL; +static int initialized = 0; +static int last_bus = -1; +/* my private var: for debug purpose only */ +static int ami_debug = 0; + +extern struct ExecBase *SysBase; +#define IOERR_TIMEOUT (-8) +#define CHECK_CONDITION 0x02 +#define DUNIT(b, t, l) (100 * b) + (10 * (l < 0 ? 0:l)) + t + +static void amiga_init(void); +static int amiga_open_scsi(int bus, int tgt, int lun, SCSI *usalp); +static void amiga_close_scsi(int fd); +static void amiga_close_scsi_all(void); +static void amiga_scan_devices(void); +static int amiga_find_device(char *device); +static int amiga_open_timer(void); +static void amiga_close_timer(void); +static int amiga_get_scsi_bus(char *device); + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: +/* return (_usal_auth_cdrkit);*/ + return (_usal_auth); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "Amiga SCSI", "Generic SCSI", + "", "bus,target,lun or xxx.device:b,t,l", "1,2,0 or scsi.device:1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + + if (initialized == 0) { + amiga_init(); + initialized = 1; + } + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + } + return (-1); + } + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + usallocal(usalp)->usalfiles[b][t][l] = -1; + } + } + } + } + + if (device == NULL || *device == '\0') { + + if (last_bus == -1) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "No scsi device found"); + return (-1); + } + if (busno < 0 && tgt < 0 && tlun < 0) { + /* cdrecord -scanbus */ + for (b = 0; b <= last_bus; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = amiga_open_scsi(b, t, l, usalp); + if (f != -1) { + usallocal(usalp)->usalfiles[b][t][l] = f; + nopen++; + } + } + } + } + } else { + /* cdrecord [-scanbus] dev=b,t,l */ + f = amiga_open_scsi(busno, tgt, tlun, usalp); + if (f != -1) { + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + nopen++; + } + } + } else { + if (busno < 0 && tgt < 0 && tlun < 0) { + /* cdrecord -scanbus dev=xxx.device */ + b = amiga_get_scsi_bus(device); + if (b != -1) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = amiga_open_scsi(b, t, l, usalp); + if (f != -1) { + usallocal(usalp)->usalfiles[b][t][l] = f; + nopen++; + } + } + } + } else { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Scsi device %s not found", device); + } + } else { + /* cdrecord [-scanbus] dev=xxx.device:b,t,l */ + /* + * this is a special case, in which the scsi device is accessed just by + * name, bus parameter from the command is ignored. + */ + b = amiga_get_scsi_bus(device); + if (b != -1) { + f = amiga_open_scsi(b, tgt, tlun, usalp); + if (f != -1) { + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + nopen++; + } + } else { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Scsi device %s not found", device); + } + } + } + + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + if (usallocal(usalp)->usalfiles[b][t][l] >= 0) + amiga_close_scsi(usallocal(usalp)->usalfiles[b][t][l]); + usallocal(usalp)->usalfiles[b][t][l] = -1; + } + } + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_AMIGAOS); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] != -1) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + /* XXX Is there really no reset function on AmigaOS? */ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + register struct IOStdReq *ioreq = NULL; + struct SCSICmd Cmd; + int ret = 0; + struct usal_cmd *sp = usalp->scmd; + + sp->error = SCG_NO_ERROR; + sp->sense_count = 0; + sp->u_scb.cmd_scb[0] = 0; + sp->resid = 0; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + ioreq = request[usalp->fd].ioReq; + if (ioreq == NULL) { + sp->error = SCG_FATAL; + return (0); + } + ioreq->io_Length = sizeof (struct SCSICmd); + ioreq->io_Data = &Cmd; + ioreq->io_Command = HD_SCSICMD; + + Cmd.scsi_Flags = SCSIF_AUTOSENSE; /* We set the SCSI cmd len */ + if (sp->flags & SCG_RECV_DATA) + Cmd.scsi_Flags |= SCSIF_READ; + else if (sp->size > 0) + Cmd.scsi_Flags |= SCSIF_WRITE; + + Cmd.scsi_Command = sp->cdb.cmd_cdb; + Cmd.scsi_CmdLength = sp->cdb_len; + Cmd.scsi_Data = (UWORD *) sp->addr; + Cmd.scsi_Length = sp->size; + Cmd.scsi_Actual = 0; + + Cmd.scsi_SenseData = sp->u_sense.cmd_sense; + Cmd.scsi_SenseLength = sp->sense_len; + Cmd.scsi_SenseActual = 0; + Cmd.scsi_Status = 0; + + do_scsi_cmd(ioreq, sp->timeout); + + fillbytes(&sp->scb, sizeof (sp->scb), '\0'); + sp->resid = Cmd.scsi_Length - Cmd.scsi_Actual; + + if (sp->resid < 0) + sp->resid = 0; + sp->sense_count = Cmd.scsi_SenseActual; + if (sp->sense_count < 0) + sp->sense_count; + + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + sp->u_scb.cmd_scb[0] = Cmd.scsi_Status; + + if (ioreq->io_Error) + sp->ux_errno = EIO; + + if (ami_debug) + printf("ioreq->io_Error: %ld; status %ld\n", ioreq->io_Error, Cmd.scsi_Status); + + switch (ioreq->io_Error) { + case 0: + sp->error = SCG_NO_ERROR; + break; + case IOERR_TIMEOUT: + sp->error = SCG_TIMEOUT; + break; + case HFERR_DMA: + case IOERR_UNITBUSY: + case HFERR_Phase: + case HFERR_Parity: + case HFERR_BadStatus: + if (Cmd.scsi_Status == CHECK_CONDITION) { + sp->error = SCG_NO_ERROR; + } else { + sp->error = SCG_RETRYABLE; + } + break; + default: + /* XXX was kann sonst noch passieren? */ + sp->error = SCG_FATAL; + break; + } + + return (ret); +} + +static int +do_scsi_cmd(struct IOStdReq *scsi_io, int timeout) +{ + ULONG scsi_flag = 0; + ULONG timer_flag = 0; + ULONG wait_sigs = 0; + ULONG wait_ret = 0; + int ret = 0; + + scsi_flag = 1L<<scsi_io->io_Message.mn_ReplyPort->mp_SigBit; + wait_sigs = scsi_flag; + + SetSignal(0L, scsi_flag); + SendIO((struct IORequest *)scsi_io); + if (timer_io) { + timer_flag = 1L<<timerMsgPort->mp_SigBit; + wait_sigs |= timer_flag; + timer_io->tr_time.tv_secs = timeout; + SetSignal(0L, timer_flag); + SendIO((struct IORequest *)timer_io); + } + + wait_ret = Wait(wait_sigs); + + if (wait_ret & scsi_flag) { + WaitIO((struct IORequest *)scsi_io); + if (timer_io) { + if (!CheckIO((struct IORequest *) timer_io)) { + AbortIO((struct IORequest *)timer_io); + WaitIO((struct IORequest *)timer_io); + } + } + } else if (wait_ret & timer_flag) { + WaitIO((struct IORequest *)timer_io); + if (!CheckIO((struct IORequest *) scsi_io)) { + AbortIO((struct IORequest *)scsi_io); + if (scsi_io->io_Error == IOERR_ABORTED) { + WaitIO((struct IORequest *)scsi_io); + } + } + scsi_io->io_Error = IOERR_TIMEOUT; + } + + return (scsi_io->io_Error); +} + +/*--------------------------------------------------------------------------*/ + +/* strlwr: seems not to be implemented in ixemul */ +static char * +strlwr(char *s) +{ + unsigned char *s1; + + s1 = (unsigned char *)s; + while (*s1) { + if ((*s1 > ('A'-1)) && (*s1 < ('Z'+1))) + *s1 += 'a'-'A'; + s1++; + } + return (s); +} + +/* + * amiga specific functions + */ +static void +amiga_init() +{ + memset(request, 0, sizeof (request)); + amiga_scan_devices(); + if (ami_debug) + printf("scanning bus. %ld device(s) found\n", last_bus + 1); + + atexit(amiga_close_scsi_all); +} + +static void +amiga_scan_devices() +{ + /* + * searching all known scsi devices + * for first there is only a (full) support for scsi.device and amithlon.device. + * This are devices i tested. + * All the other devices have to be specified by name (i.e. cdrecord dev=blabla.device:0,0,0) + * but didn't appear in the scanbus list. Later they should/may be also added to the + * main_dev_list (after testing). + */ + const char *main_dev_list[] = { "scsi.device", "amithlon.device", NULL }; + + int i; + char **main_dev; + + main_dev = (char **)main_dev_list; + while (*main_dev) { + if (last_bus == MAX_SCG - 1) + break; + if (amiga_find_device(*main_dev)) { + last_bus++; + devs[last_bus] = strdup(*main_dev); + for (i = 2; i < MAX_SCG; i++) { + char tmp[256]; + if (last_bus == MAX_SCG - 1) + break; + if (i == 2) { + sprintf(tmp, "2nd.%s", *main_dev); + } else if (i == 3) { + sprintf(tmp, "3rd.%s", *main_dev); + } else { + sprintf(tmp, "%ldth.%s", i, *main_dev); + } + if (amiga_find_device(tmp)) { + last_bus++; + devs[last_bus] = strdup(tmp); + } else { + break; + } + } + } + main_dev++; + } +} + +static void +amiga_close_scsi(int fd) +{ + if (request[fd].ref_count > 0) { + request[fd].ref_count--; + if (request[fd].ref_count == 0) { + CloseDevice((struct IORequest *) request[fd].ioReq); + DeleteStdIO(request[fd].ioReq); + request[fd].ioReq = NULL; + if (ami_debug) { + printf("closing device fd %ld\n", fd); + } + } + } +} + +static void +amiga_close_scsi_all() +{ + int i; + + for (i = 0; i < MAX_DEV; i++) { + if (request[i].ioReq != NULL) { + if (ami_debug) { + printf("closing device fd %ld\n", i); + } + CloseDevice((struct IORequest *) request[i].ioReq); + DeleteStdIO(request[i].ioReq); + request[i].ioReq = NULL; + } + } + + if (ioMsgPort) { + DeletePort(ioMsgPort); + ioMsgPort = NULL; + } + amiga_close_timer(); + + for (i = 0; i < MAX_SCG; i++) { + free(devs[i]); + } +} + +static int +amiga_open_scsi(int bus, int tgt, int lun, SCSI *usalp) +{ + int fd = bus * MAX_TGT * MAX_LUN + tgt * MAX_LUN + lun; + int unit = DUNIT(bus, tgt, lun); + char *dev = devs[bus]; + + if (dev == NULL) { + if (usalp->errstr) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "No scsi device found at bus %ld\n", bus); + } + return (-1); + } + + if (ioMsgPort == NULL) { + ioMsgPort = CreatePort(NULL, 0); + } + + if (ioMsgPort != NULL) { + if (request[fd].ioReq == NULL) { + request[fd].ioReq = CreateStdIO(ioMsgPort); + } + + if (request[fd].ioReq != NULL) { + if (ami_debug) + printf("trying %s, unit %ld\n", dev, unit); + if (OpenDevice(dev, unit, (struct IORequest *)request[fd].ioReq, 0L)) { + if (usalp->errstr) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open %s\n", dev); + } + if (request[fd].ref_count == 0) { + DeleteStdIO(request[fd].ioReq); + request[fd].ioReq = NULL; + } + fd = -1; + } else { + request[fd].ref_count++; + if (ami_debug) + printf("opening %s, unit %ld as fd %ld count %ld\n", dev, unit, fd, request[fd].ref_count); + } + } else { + if (usalp->errstr) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot create IOReq"); + } + } + } else { + if (usalp->errstr) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open Message Port"); + } + } + + return (fd); +} + +static int +amiga_open_timer() +{ + int ret = 0; + + /* we need the timer to catch scsi timeouts */ + if (timer_io == NULL) { + if (ami_debug) + printf("opening timer\n"); + + timerMsgPort = CreatePort(NULL, 0); + if (timerMsgPort) { + timer_io = (struct timerequest *)CreateExtIO(timerMsgPort, sizeof (struct timerequest)); + if (timer_io) { + if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) { + printf("Warning: can't open timer device\n"); + DeleteExtIO((struct IORequest *) timer_io); + DeletePort(timerMsgPort); + timer_io = NULL; + timerMsgPort = NULL; + ret = 1; + } else { + timer_io->tr_node.io_Command = TR_ADDREQUEST; + timer_io->tr_time.tv_micro = 0; + } + } else { + printf("Warning: can't create timer request\n"); + DeletePort(timerMsgPort); + timerMsgPort = NULL; + ret = 1; + } + } else { + printf("Warning: can't create timer port\n"); + ret = 1; + } + } + return (ret); +} + +static void +amiga_close_timer() +{ + if (timer_io) { + if (ami_debug) + printf("closing timer\n"); + + AbortIO((struct IORequest *) timer_io); + WaitIO((struct IORequest *) timer_io); + CloseDevice((struct IORequest *)timer_io); + DeleteExtIO((struct IORequest *) timer_io); + DeletePort(timerMsgPort); + timer_io = NULL; + timerMsgPort = NULL; + } +} + +static int +amiga_get_scsi_bus(char *device) +{ + int i; + char *tmp = strdup(device); + + strlwr(tmp); + for (i = 0; i <= last_bus; i++) { + if (strcmp(devs[i], tmp) == 0) { + return (i); + } + } + + if (amiga_find_device(tmp)) { + devs[i] = tmp; + last_bus = i; + return (i); + } + + return (-1); +} + +static int +amiga_find_device(char *device) +{ + char tmp[256]; + struct Node *DeviceLibNode = SysBase->DeviceList.lh_Head; + + if (ami_debug) + printf("looking for %s ", device); + + Forbid(); + while (DeviceLibNode->ln_Succ) { + DeviceLibNode = DeviceLibNode->ln_Succ; + strcpy(tmp, DeviceLibNode->ln_Name); + strlwr(tmp); + if (strcmp(tmp, device) == 0) { + if (ami_debug) + printf(" ... found\n"); + return (1); + } + } + Permit(); + + if (ami_debug) + printf(" ... not found\n"); + + return (0); +} diff --git a/libusal/scsi-apollo.c b/libusal/scsi-apollo.c new file mode 100644 index 0000000..c368468 --- /dev/null +++ b/libusal/scsi-apollo.c @@ -0,0 +1,550 @@ +/* + * 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. + * + */ + +/* @(#)scsi-apollo.c 1.5 04/01/14 Copyright 1997,2000 J. Schilling */ +/* + * Code to support Apollo Domain/OS 10.4.1 + * + * Copyright (c) 1997,2000 J. Schilling + * Apollo support code written by Paul Walker. + */ +/* + * 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 <apollo/base.h> +#include <apollo/scsi.h> +#include <assert.h> +#define DomainScsiTimeout 100000 + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-apollo.c-1.5"; /* The version for this transport */ + + +#define MAX_SCG 1 /* Max # of SCSI controllers */ +#define MAX_TGT 1 /* Max # of SCSI targets */ +#define MAX_LUN 1 /* Max # of SCSI logical units */ + +struct usal_local { + scsi_$handle_t handle; + unsigned char *DomainSensePointer; + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; + +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#ifndef SG_MAX_SENSE +#define SG_MAX_SENSE 16 /* Too small for CCS / SCSI-2 */ +#endif /* But cannot be changed */ + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return ("Paul Walker"); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "scsi_$do_command_2", "SCSI transport from Apollo DomainOS drivers", + "", "DomainOS driver name", "A DomainOS device node name", FALSE, TRUE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + register int nopen = 0; + status_$t status; + + if (usalp->debug > 1) + printf("Entered scsi_open, usalp=%p, device='%s'\n", usalp, device); + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + } + if (device == NULL || *device == '\0') { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, "Must give device name"); + return (0); + } + + scsi_$acquire(device, strlen(device), &usallocal(usalp)->handle, &status); + if (status.all) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, "Cannot open '%s', status %08x", device, status.all); + return (0); + } + /* + * Allocate the sense buffer + */ + usallocal(usalp)->DomainSensePointer = (Uchar *)valloc((size_t) (SCG_MAX_SENSE + getpagesize())); + assert(status.all == 0); + /* + * Wire the sense buffer + */ + scsi_$wire(usallocal(usalp)->handle, (caddr_t)(usallocal(usalp)->DomainSensePointer), SCG_MAX_SENSE, &status); + assert(status.all == 0); + + if (usallocal(usalp)->usalfiles[0][0][0] == -1) + usallocal(usalp)->usalfiles[0][0][0] = 1; + usal_settarget(usalp, 0, 0, 0); + return (++nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + status_$t status; + + if (usalp->debug > 1) + printf("Entering scsi_close\n"); + scsi_$release(usallocal(usalp)->handle, &status); + /* + * should also unwire the sense buffer + */ + return (status.all); +} + + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + status_$t status; + scsi_$info_t info; + + scsi_$get_info(usallocal(usalp)->handle, sizeof (info), &info, &status); + if (status.all) { + /* + * Should have some better error handling here + */ + printf("scsi_$get_info returned %08x\n", status.all); + return (0); + } + return (info.max_xfer); +} + + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + void *ret; + + if (usalp->debug > 1) + printf("scsi_getbuf: %ld bytes\n", amt); + ret = valloc((size_t)amt); + if (ret == NULL) + return (ret); + usalp->bufbase = ret; + return (ret); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->debug > 1) + printf("Entering scsi_freebuf\n"); + + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (usalp->debug > 1) + printf("Entered scsi_havebus: usalp=%p, busno=%d\n", usalp, busno); + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (usalp->debug > 1) + printf("Entered scsi_fileno: usalp=%p, busno=%d, tgt=%d, tlun=%d\n", usalp, busno, tgt, tlun); + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + if (usalp->debug > 1) + printf("exiting scsi_fileno, returning %d\n", usallocal(usalp)->usalfiles[busno][tgt][tlun]); + return ((int) usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + if (usalp->debug > 1) + printf("Entering scsi_initiator\n"); + + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + status_$t status; + + if (usalp->debug > 0) + printf("Entering scsi_reset\n"); + + if (what == SCG_RESET_NOP) + return (0); + + if (what == SCG_RESET_TGT) { + scsi_$reset_device(usallocal(usalp)->handle, &status); + if (status.all) + printf("Error - scsi_$reset_device failed, status is 0x%08x\n", status.all); + return (status.all); + } else { + errno = EINVAL; + return (-1); + } +} + +static void +scsi_do_sense(SCSI *usalp, struct usal_cmd *sp) +{ + scsi_$op_status_t op_status; + static scsi_$cdb_t sense_cdb; + static linteger sense_cdb_size; + static linteger sense_buffer_size; + static scsi_$operation_id_t sense_op_id; + static status_$t sense_status; + static pinteger sense_return_count; + int i; + + /* + * Issue the sense command (wire, issue, wait, unwire + */ + sense_buffer_size = sp->sense_len; + sense_cdb_size = SC_G0_CDBLEN; + memset(sense_cdb.all, 0, sense_cdb_size); /* Assuming Apollo sense */ + /* structure is correct */ + /* size */ + sense_cdb.g0.cmd = SC_REQUEST_SENSE; + sense_cdb.g0.lun = sp->cdb.g0_cdb.lun; + sense_cdb.g0.len = sp->sense_len; + scsi_$do_command_2(usallocal(usalp)->handle, sense_cdb, sense_cdb_size, (caddr_t) (usallocal(usalp)->DomainSensePointer), sense_buffer_size, scsi_read, &sense_op_id, &sense_status); + if (sense_status.all) { + printf("Error executing sense command, status is 0x%08x\n", sense_status.all); + } + scsi_$wait(usallocal(usalp)->handle, DomainScsiTimeout, true, sense_op_id, 1, &op_status, &sense_return_count, &sense_status); + /* + * Print the sense information if debug is on, or if the information is + * "unusual" + */ + if (usalp->debug > 0 || + /* + * I don't prinqqt info for sense codes 0, 2, 5, 6 because + * they aren't interesting + */ + (((u_char *) usallocal(usalp)->DomainSensePointer)[2] == 1) || + (((u_char *) usallocal(usalp)->DomainSensePointer)[2] == 3) || + (((u_char *) usallocal(usalp)->DomainSensePointer)[2] == 4) || + (((u_char *) usallocal(usalp)->DomainSensePointer)[2] >= 7)) { + printf(" Sense dump:\n"); + for (i = 0; i < sp->sense_len; i++) + printf(" %02x", ((u_char *) usallocal(usalp)->DomainSensePointer)[i]); + printf("\n"); + } + if (((u_char *) usallocal(usalp)->DomainSensePointer)[2] == 5) { + /* + * Illegal command + */ + printf("Illegal command detected, ASC=0x%02x, ASQ=0x%02x\n", ((u_char *) usallocal(usalp)->DomainSensePointer)[12], ((u_char *) usallocal(usalp)->DomainSensePointer)[13]); + } + /* + * Copy the sense information to the driver + */ + memcpy(sp->u_sense.cmd_sense, usallocal(usalp)->DomainSensePointer, sp->sense_len); + sp->sense_count = sp->sense_len; +} + + +static int +usalo_send(SCSI *usalp) +{ + linteger buffer_length; + linteger cdb_len; + scsi_$operation_id_t operation; + scsi_$wait_index_t wait_index; + scsi_$op_status_t op_status; + pinteger return_count; + status_$t status; + char *ascii_wait_status; + int i; + struct usal_cmd *sp = usalp->scmd; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + if (usalp->debug > 0) { + printf("Entered usalo_send, usalp=%p, sp=%p\n", usalp, sp); + printf("usalcmd dump:\n"); + printf(" addr=%p\n", sp->addr); + printf(" size=0x%x\n", sp->size); + printf(" flags=0x%x\n", sp->flags); + printf(" cdb_len=%d\n", sp->cdb_len); + printf(" sense_len=%d\n", sp->sense_len); + printf(" timeout=%d\n", sp->timeout); + printf(" kdebug=%d\n", sp->kdebug); + printf(" CDB:"); + for (i = 0; i < sp->cdb_len; i++) + printf(" %02x", sp->cdb.cmd_cdb[i]); + printf("\n"); + } + + /* + * Assume complete transfer, so residual count = 0 + */ + sp->resid = 0; + buffer_length = sp->size; + if (sp->addr) { + if (usalp->debug > 0) + printf(" wiring 0x%x bytes at 0x%x\n", buffer_length, sp->addr); + scsi_$wire(usallocal(usalp)->handle, sp->addr, buffer_length, &status); + if (status.all) { + /* + * Need better error handling + */ + printf("scsi_$wire failed, 0x%08x\n", status.all); + } + } + cdb_len = sp->cdb_len; + scsi_$do_command_2(usallocal(usalp)->handle, /* device handle*/ + *(scsi_$cdb_t *) &(sp->cdb.cmd_cdb[0]), /* SCSI CDB */ + cdb_len, /* CDB len */ + sp->addr, /* DMA buf */ + buffer_length, /* DMA len */ + (sp->flags & SCG_RECV_DATA) ? scsi_read : scsi_write, + &operation, /* OP ID */ + &status); /* Status ret */ + + if (status.all) { + /* + * Need better error handling + */ + printf("scsi_$do_command failed, 0x%08x\n", status.all); + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } else if (usalp->debug > 0) { + printf("Command submitted, operation=0x%x\n", operation); + } + wait_index = scsi_$wait(usallocal(usalp)->handle, /* device handle*/ + sp->timeout * 1000, /* timeout */ + 0, /* async enable */ + operation, /* OP ID */ + 1, /* max count */ + &op_status, /* status list */ + &return_count, /* count ret */ + &status); /* Status ret */ + if (status.all) { + /* + * Need better error handling + */ + printf("scsi_$wait failed, 0x%08x\n", status.all); + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } else { + if (usalp->debug > 0) { + printf("wait_index=%d, return_count=%d, op_status: op=0x%x, cmd_status=0x%x, op_status=0x%x\n", + wait_index, return_count, op_status.op, op_status.cmd_status, op_status.op_status); + } + switch (wait_index) { + + case scsi_device_advance: + ascii_wait_status = "scsi_device_advance"; + break; + case scsi_timeout: + ascii_wait_status = "scsi_timeout"; + break; + case scsi_async_fault: + ascii_wait_status = "scsi_async_fault"; + break; + default: + ascii_wait_status = "unknown"; + break; + } + /* + * See if the scsi_$wait terminated "abnormally" + */ + if (wait_index != scsi_device_advance) { + printf("scsi_$wait terminated abnormally, status='%s'\n", ascii_wait_status); + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } + /* + * Normal termination, what's the scoop? + */ + assert(return_count == 1); + switch (op_status.cmd_status.all) { + + case status_$ok: + switch (op_status.op_status) { + + case scsi_good_status: + sp->error = SCG_NO_ERROR; + sp->ux_errno = 0; + break; + case scsi_busy: + sp->error = SCG_NO_ERROR; + sp->ux_errno = 0; + break; + case scsi_check_condition: + if (usalp->debug > 0) + printf("SCSI ERROR - CheckCondition\n"); + scsi_do_sense(usalp, sp); + /* + * If this was a media error, then call it retryable, + * instead of no error + */ + if ((((u_char *) usallocal(usalp)->DomainSensePointer)[0] == 0xf0) && + (((u_char *) usallocal(usalp)->DomainSensePointer)[2] == 0x03)) { + if (usalp->debug > 0) + printf(" (retryable)\n"); + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + } else { + /* printf(" (no error)\n"); */ + sp->error = SCG_NO_ERROR; + sp->ux_errno = 0; + } + break; + default: + /* + * I fault out in this case because I want to know + * about this error, and this guarantees that it will + * get attention. + */ + printf("Unhandled Domain/OS op_status error: status=%08x\n", + op_status.op_status); + exit(EXIT_FAILURE); + } + break; + /* + * Handle recognized error conditions by copying the error + * code over + */ + case scsi_$operation_timeout: + printf("SCSI ERROR - Timeout\n"); + scsi_do_sense(usalp, sp); + sp->error = SCG_TIMEOUT; + sp->ux_errno = EIO; + break; + case scsi_$dma_underrun: + /* + * This condition seems to occur occasionaly. I no longer + * complain because it doesn't seem to matter. + */ + if (usalp->debug > 0) + printf("SCSI ERROR - Underrun\n"); + scsi_do_sense(usalp, sp); + sp->resid = sp->size; /* We don't have the right number */ + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + case scsi_$hdwr_failure: /* received when both scanners were active */ + printf("SCSI ERROR - Hardware Failure\n"); + scsi_do_sense(usalp, sp); + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + default: + printf("\nUnhandled Domain/OS cmd_status error: status=%08x\n", op_status.cmd_status.all); + error_$print(op_status.cmd_status); + exit(EXIT_FAILURE); + } + } + if (sp->addr) { + if (usalp->debug > 0) + printf(" unwiring buffer\n"); + scsi_$unwire(usallocal(usalp)->handle, sp->addr, buffer_length, sp->flags & SCG_RECV_DATA, &status); + if (status.all) { + /* + * Need better error handling + */ + printf("scsi_$unwire failed, 0x%08x\n", status.all); + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } + } + return (0); +} diff --git a/libusal/scsi-beos.c b/libusal/scsi-beos.c new file mode 100644 index 0000000..78b649e --- /dev/null +++ b/libusal/scsi-beos.c @@ -0,0 +1,414 @@ +/* + * 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. + * + */ + +/* @(#)scsi-beos.c 1.23 06/02/05 Copyright 1998 J. Schilling */ +/* + * Interface for the BeOS user-land raw SCSI implementation. + * + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * First version done by swetland@be.com + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998 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. + */ + + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-beos.c-1.23"; /* The version for this transport*/ + +/* + * There are also defines for: + * B_BEOS_VERSION_4 + * B_BEOS_VERSION_4_5 + * + * in BeOS 5 + */ +#ifndef B_BEOS_VERSION_5 +/* + * New BeOS seems to include <be/kernel/OS.h> from device/scsi.h + */ + +/* nasty hack to avoid broken def of bool in SupportDefs.h */ +#define _SUPPORT_DEFS_H + +#ifndef _SYS_TYPES_H +typedef unsigned long ulong; +typedef unsigned int uint; +typedef unsigned short ushort; +#endif /* _SYS_TYPES_H */ + +#include <BeBuild.h> +#include <sys/types.h> +#include <Errors.h> + + +/*-------------------------------------------------------------*/ +/*----- Shorthand type formats --------------------------------*/ + +typedef signed char int8; +typedef unsigned char uint8; +typedef volatile signed char vint8; +typedef volatile unsigned char vuint8; + +typedef short int16; +typedef unsigned short uint16; +typedef volatile short vint16; +typedef volatile unsigned short vuint16; + +typedef long int32; +typedef unsigned long uint32; +typedef volatile long vint32; +typedef volatile unsigned long vuint32; + +typedef long long int64; +typedef unsigned long long uint64; +typedef volatile long long vint64; +typedef volatile unsigned long long vuint64; + +typedef volatile long vlong; +typedef volatile int vint; +typedef volatile short vshort; +typedef volatile char vchar; + +typedef volatile unsigned long vulong; +typedef volatile unsigned int vuint; +typedef volatile unsigned short vushort; +typedef volatile unsigned char vuchar; + +typedef unsigned char uchar; +typedef unsigned short unichar; + + + +/*-------------------------------------------------------------*/ +/*----- Descriptive formats -----------------------------------*/ +typedef int32 status_t; +typedef int64 bigtime_t; +typedef uint32 type_code; +typedef uint32 perform_code; + +/* end nasty hack */ + +#endif /* ! B_BEOS_VERSION_5 */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <usal/usalio.h> + +/* this is really really dumb (tm) */ +/*#undef sense*/ +/*#undef scb*/ +#include <device/scsi.h> + +#undef bool +#include <drivers/CAM.h> + +struct _fdmap_ { + struct _fdmap_ *next; + int bus; + int targ; + int lun; + int fd; +}; + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "CAM", "Generic transport independent SCSI (BeOS CAM variant)", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); +#ifdef nonono + int tlun = usal_lun(usalp); +#endif + +#ifdef nonono + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } +#endif + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + return (1); +} + +static int +usalo_close(SCSI *usalp) +{ + struct _fdmap_ *f; + struct _fdmap_ *fnext; + + for (f = (struct _fdmap_ *)usalp->local; f; f = fnext) { + usalp->local = 0; + fnext = f->next; + close(f->fd); + free(f); + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (128*1024); + return (256*1024); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = malloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + struct stat sb; + char buf[128]; + + if (busno < 8) + snprintf(buf, sizeof (buf), "/dev/bus/scsi/%d", busno); + else + snprintf(buf, sizeof (buf), "/dev/disk/ide/atapi/%d", busno-8); + if (stat(buf, &sb)) + return (FALSE); + return (TRUE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + struct _fdmap_ *f; + char buf[128]; + int fd; + + for (f = (struct _fdmap_ *)usalp->local; f; f = f->next) { + if (f->bus == busno && f->targ == tgt && f->lun == tlun) + return (f->fd); + } + if (busno < 8) { + snprintf(buf, sizeof (buf), + "/dev/bus/scsi/%d/%d/%d/raw", + busno, tgt, tlun); + } else { + char *tgtstr = (tgt == 0) ? "master" : (tgt == 1) ? "slave" : "dummy"; + snprintf(buf, sizeof (buf), + "/dev/disk/ide/atapi/%d/%s/%d/raw", + busno-8, tgtstr, tlun); + } + fd = open(buf, 0); + + if (fd >= 0) { + f = (struct _fdmap_ *) malloc(sizeof (struct _fdmap_)); + f->bus = busno; + f->targ = tgt; + f->lun = tlun; + f->fd = fd; + f->next = (struct _fdmap_ *)usalp->local; + usalp->local = f; + } + return (fd); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + /* + * XXX Should check for ATAPI + */ + return (-1); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int e; + int scsi_error; + int cam_error; + raw_device_command rdc; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + memcpy(rdc.command, &(sp->cdb), 12); + rdc.command_length = sp->cdb_len; + rdc.data = sp->addr; + rdc.data_length = sp->size; + rdc.sense_data_length = sp->sense_len; + rdc.sense_data = sp->u_sense.cmd_sense; + rdc.flags = sp->flags & SCG_RECV_DATA ? B_RAW_DEVICE_DATA_IN : 0; + if (sp->size > 0) + rdc.flags |= B_RAW_DEVICE_REPORT_RESIDUAL; + rdc.timeout = sp->timeout * 1000000; + + sp->error = SCG_NO_ERROR; + sp->sense_count = 0; + sp->u_scb.cmd_scb[0] = 0; + sp->resid = 0; + + if (usalp->debug > 0) { + fprintf(stderr, "SEND(%d): cmd %02x, cdblen = %d, datalen = %ld, senselen = %ld\n", + usalp->fd, rdc.command[0], rdc.command_length, + rdc.data_length, rdc.sense_data_length); + } + e = ioctl(usalp->fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof (rdc)); + if (usalp->debug > 0) { + fprintf(stderr, "SEND(%d): -> %d CAM Status %02X SCSI status %02X\n", e, rdc.cam_status, rdc.scsi_status); + } + sp->ux_errno = 0; +#ifdef DEBUG + fprintf(stderr, "err %d errno %x CAM %X SL %d DL %d/%d FL %X\n", + e, geterrno(), rdc.cam_status, + rdc.sense_data_length, rdc.data_length, sp->size, rdc.flags); +#endif + if (!e) { + cam_error = rdc.cam_status; + scsi_error = rdc.scsi_status; + sp->u_scb.cmd_scb[0] = scsi_error; + if (sp->size > 0) + sp->resid = sp->size - rdc.data_length; + + switch (cam_error & CAM_STATUS_MASK) { + + case CAM_REQ_CMP: + sp->error = SCG_NO_ERROR; + break; + + case CAM_REQ_CMP_ERR: + sp->sense_count = sp->sense_len; /* XXX */ + sp->error = SCG_NO_ERROR; + sp->ux_errno = EIO; + break; + + case CAM_CMD_TIMEOUT: + sp->error = SCG_TIMEOUT; + sp->ux_errno = EIO; + + case CAM_SEL_TIMEOUT: + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + break; + + default: + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + } + } else { + sp->error = SCG_FATAL; + sp->ux_errno = geterrno(); + sp->resid = sp->size; + } + return (0); +} diff --git a/libusal/scsi-bsd-os.c b/libusal/scsi-bsd-os.c new file mode 100644 index 0000000..5719505 --- /dev/null +++ b/libusal/scsi-bsd-os.c @@ -0,0 +1,443 @@ +/* + * 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. + * + */ + +/* @(#)scsi-bsd-os.c 1.28 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the BSD/OS user-land raw SCSI implementation. + * + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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. + */ + +#undef sense + +#define scsi_sense bsdi_scsi_sense +#define scsi_inquiry bsdi_scsi_inquiry + +/* + * Must use -I/sys... + * The next two files are in /sys/dev/scsi + */ +#include <dev/scsi/scsi.h> +#include <dev/scsi/scsi_ioctl.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-bsd-os.c-1.28"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#include <machine/param.h> + +#define MAX_DMA_BSDI MAXPHYS /* More makes problems */ + + +static BOOL usal_setup(SCSI *usalp, int f, int busno, int tgt, int tlun); + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SCSIRAWCDB", "Generic SCSI for devices known by BSDi", + "", "devname:@,lun", "/dev/rsr0a:@,0", FALSE, TRUE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[64]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) + goto openbydev; + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + + snprintf(devname, sizeof (devname), + "/dev/su%d-%d-%d", busno, tgt, tlun); + f = open(devname, O_RDWR|O_NONBLOCK); + if (f < 0) { + goto openbydev; + } + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + return (1); + + } else for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + snprintf(devname, sizeof (devname), + "/dev/su%d-%d-%d", b, t, l); + f = open(devname, O_RDWR|O_NONBLOCK); +/* fprintf(stderr, "open (%s) = %d\n", devname, f);*/ + + if (f < 0) { + if (errno != ENOENT && + errno != ENXIO && + errno != ENODEV) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + devname); + return (0); + } + } else { + if (usal_setup(usalp, f, b, t, l)) + nopen++; + } + } + } + } + /* + * Could not open /dev/su-* or got dev=devname:b,l,l / dev=devname:@,l + * We do the apropriate tests and try our best. + */ +openbydev: + if (nopen == 0) { + if (device == NULL || device[0] == '\0') + return (0); + f = open(device, O_RDWR|O_NONBLOCK); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + device); + return (0); + } + if (tlun == -2) { /* If 'lun' is not known, we reject */ + close(f); + errno = EINVAL; + return (0); + } + busno = 0; /* use fake number, we cannot get it */ + tgt = 0; /* use fake number, we cannot get it */ + usal_settarget(usalp, busno, tgt, tlun); + /* 'lun' has been specified on command line */ + if (usal_setup(usalp, f, busno, tgt, tlun)) + nopen++; + } + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static BOOL +usal_setup(SCSI *usalp, int f, int busno, int tgt, int tlun) +{ + int Bus; + int Target; + int Lun; + BOOL onetarget = FALSE; + + if (usal_scsibus(usalp) >= 0 && usal_target(usalp) >= 0 && usal_lun(usalp) >= 0) + onetarget = TRUE; + + /* + * Unfortunately there is no way to get the right values from kernel. + */ + Bus = busno; + Target = tgt; + Lun = tlun; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Bus: %d Target: %d Lun: %d\n", Bus, Target, Lun); + } + + if (Bus >= MAX_SCG || Target >= MAX_TGT || Lun >= MAX_LUN) { + close(f); + return (FALSE); + } + + if (usallocal(usalp)->usalfiles[Bus][Target][Lun] == (short)-1) + usallocal(usalp)->usalfiles[Bus][Target][Lun] = (short)f; + + if (onetarget) { + if (Bus == busno && Target == tgt && Lun == tlun) { + return (TRUE); + } else { + usallocal(usalp)->usalfiles[Bus][Target][Lun] = (short)-1; + close(f); + } + } + return (FALSE); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = MAX_DMA_BSDI; + + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = malloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + /* + * Cannot reset on BSD/OS + */ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + scsi_user_cdb_t suc; + int ret = 0; + +/* fprintf((FILE *)usalp->errfile, "f: %d\n", f);*/ + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + /* Zero the structure... */ + fillbytes(&suc, sizeof (suc), '\0'); + + /* Read or write? */ + if (sp->flags & SCG_RECV_DATA) { + suc.suc_flags |= SUC_READ; + } else if (sp->size > 0) { + suc.suc_flags |= SUC_WRITE; + } + + suc.suc_timeout = sp->timeout; + + suc.suc_cdblen = sp->cdb_len; + movebytes(sp->cdb.cmd_cdb, suc.suc_cdb, suc.suc_cdblen); + + suc.suc_datalen = sp->size; + suc.suc_data = sp->addr; + + if (ioctl(usalp->fd, SCSIRAWCDB, &suc) < 0) { + ret = -1; + sp->ux_errno = geterrno(); + if (sp->ux_errno != ENOTTY) + ret = 0; + } else { + sp->ux_errno = 0; + if (suc.suc_sus.sus_status != STS_GOOD) + sp->ux_errno = EIO; + } + fillbytes(&sp->scb, sizeof (sp->scb), '\0'); + fillbytes(&sp->u_sense.cmd_sense, sizeof (sp->u_sense.cmd_sense), '\0'); +#if 0 + /* + * Unfortunalety, BSD/OS has no idea of DMA residual count. + */ + sp->resid = req.datalen - req.datalen_used; + sp->sense_count = req.senselen_used; +#else + sp->resid = 0; + sp->sense_count = sizeof (suc.suc_sus.sus_sense); +#endif + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + movebytes(suc.suc_sus.sus_sense, sp->u_sense.cmd_sense, sp->sense_count); + sp->u_scb.cmd_scb[0] = suc.suc_sus.sus_status; + + switch (suc.suc_sus.sus_status) { + + case STS_GOOD: + sp->error = SCG_NO_ERROR; break; + case STS_CMD_TERMINATED:sp->error = SCG_TIMEOUT; break; + case STS_BUSY: sp->error = SCG_RETRYABLE; break; + case STS_CHECKCOND: sp->error = SCG_RETRYABLE; break; + case STS_QUEUE_FULL: sp->error = SCG_RETRYABLE; break; + default: sp->error = SCG_FATAL; break; + } + + return (ret); +} + +#define sense u_sense.Sense + +#undef scsi_sense +#undef scsi_inquiry diff --git a/libusal/scsi-bsd.c b/libusal/scsi-bsd.c new file mode 100644 index 0000000..6e6c240 --- /dev/null +++ b/libusal/scsi-bsd.c @@ -0,0 +1,992 @@ +/* + * 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. + * + */ + +/* @(#)scsi-bsd.c 1.42 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the NetBSD/FreeBSD/OpenBSD generic SCSI implementation. + * + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * The SCSI tranport of the generic *BSD implementation is very + * similar to the SCSI command transport of the + * 6 years older usal driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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. + */ + +#ifndef HAVE_CAMLIB_H + +#undef sense +#include <sys/scsiio.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-bsd.c-1.42"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +/*#define MAX_DMA_BSD (32*1024)*/ +#define MAX_DMA_BSD (60*1024) /* More seems to make problems */ + +#if defined(__NetBSD__) && defined(TYPE_ATAPI) +/* + * NetBSD 1.3 has a merged SCSI/ATAPI system, so this structure + * is slightly different. + */ +#define MAYBE_ATAPI +#define SADDR_ISSCSI(a) ((a).type == TYPE_SCSI) + +#define SADDR_BUS(a) (SADDR_ISSCSI(a)?(a).addr.scsi.scbus:(MAX_SCG-1)) +#define SADDR_TARGET(a) (SADDR_ISSCSI(a)?(a).addr.scsi.target:(a).addr.atapi.atbus*2+(a).addr.atapi.drive) +#define SADDR_LUN(a) (SADDR_ISSCSI(a)?(a).addr.scsi.lun:0) +#else + +#if defined(__OpenBSD__) && defined(TYPE_ATAPI) +#define SADDR_ISSCSI(a) ((a).type == TYPE_SCSI) +#else +#define SADDR_ISSCSI(a) (1) +#endif + +#define SADDR_BUS(a) (a).scbus +#define SADDR_TARGET(a) (a).target +#define SADDR_LUN(a) (a).lun +#endif /* __NetBSD__ && TYPE_ATAPI */ + +static BOOL usal_setup(SCSI *usalp, int f, int busno, int tgt, int tlun); + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SCIOCCOMMAND", "SCSI for devices known by *BSD", + "", "device or bus,target,lun", "/dev/rcd0a:@ or 1,2,0", FALSE, TRUE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[64]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) + goto openbydev; + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + + snprintf(devname, sizeof (devname), + "/dev/su%d-%d-%d", busno, tgt, tlun); + f = open(devname, O_RDWR); + if (f < 0) { + goto openbydev; + } + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + return (1); + + } else for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + snprintf(devname, sizeof (devname), + "/dev/su%d-%d-%d", b, t, l); + f = open(devname, O_RDWR); +/* fprintf(stderr, "open (%s) = %d\n", devname, f);*/ + + if (f < 0) { + if (errno != ENOENT && + errno != ENXIO && + errno != ENODEV) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + devname); + return (0); + } + } else { + if (usal_setup(usalp, f, b, t, l)) + nopen++; + } + } + } + } + /* + * Could not open /dev/su-* or got dev=devname:b,l,l / dev=devname:@,l + * We do the apropriate tests and try our best. + */ +openbydev: + if (nopen == 0) { + struct scsi_addr saddr; + + if (device == NULL || device[0] == '\0') + return (0); + f = open(device, O_RDWR); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + device); + return (0); + } + if (tgt == -2) { + if (ioctl(f, SCIOCIDENTIFY, &saddr) < 0) { + close(f); + errno = EINVAL; + return (0); + } + busno = SADDR_BUS(saddr); + tgt = SADDR_TARGET(saddr); + if ((tlun >= 0) && (tlun != SADDR_LUN(saddr))) { + close(f); + errno = EINVAL; + return (0); + } + tlun = SADDR_LUN(saddr); + usal_settarget(usalp, busno, tgt, tlun); + } + if (usal_setup(usalp, f, busno, tgt, tlun)) + nopen++; + } + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static BOOL +usal_setup(SCSI *usalp, int f, int busno, int tgt, int tlun) +{ + struct scsi_addr saddr; + int Bus; + int Target; + int Lun; + BOOL onetarget = FALSE; + + if (usal_scsibus(usalp) >= 0 && usal_target(usalp) >= 0 && usal_lun(usalp) >= 0) + onetarget = TRUE; + + if (ioctl(f, SCIOCIDENTIFY, &saddr) < 0) { + errmsg("Cannot get SCSI addr.\n"); + close(f); + return (FALSE); + } + Bus = SADDR_BUS(saddr); + Target = SADDR_TARGET(saddr); + Lun = SADDR_LUN(saddr); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Bus: %d Target: %d Lun: %d\n", Bus, Target, Lun); + } + + if (Bus >= MAX_SCG || Target >= MAX_TGT || Lun >= MAX_LUN) { + close(f); + return (FALSE); + } + + if (usallocal(usalp)->usalfiles[Bus][Target][Lun] == (short)-1) + usallocal(usalp)->usalfiles[Bus][Target][Lun] = (short)f; + + if (onetarget) { + if (Bus == busno && Target == tgt && Lun == tlun) { + return (TRUE); + } else { + usallocal(usalp)->usalfiles[Bus][Target][Lun] = (short)-1; + close(f); + } + } + return (FALSE); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = MAX_DMA_BSD; + + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ +#ifdef MAYBE_ATAPI + struct scsi_addr saddr; + + if (ioctl(usalp->fd, SCIOCIDENTIFY, &saddr) < 0) + return (-1); + + if (!SADDR_ISSCSI(saddr)) + return (TRUE); +#endif + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + /* + * XXX Does this reset TGT or BUS ??? + */ + return (ioctl(usalp->fd, SCIOCRESET, 0)); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + scsireq_t req; + register long *lp1; + register long *lp2; + int ret = 0; + +/* fprintf((FILE *)usalp->errfile, "fd: %d\n", usalp->fd);*/ + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + req.flags = SCCMD_ESCAPE; /* We set the SCSI cmd len */ + if (sp->flags & SCG_RECV_DATA) + req.flags |= SCCMD_READ; + else if (sp->size > 0) + req.flags |= SCCMD_WRITE; + + req.timeout = sp->timeout * 1000; + lp1 = (long *)sp->cdb.cmd_cdb; + lp2 = (long *)req.cmd; + *lp2++ = *lp1++; + *lp2++ = *lp1++; + *lp2++ = *lp1++; + *lp2++ = *lp1++; + req.cmdlen = sp->cdb_len; + req.databuf = sp->addr; + req.datalen = sp->size; + req.datalen_used = 0; + fillbytes(req.sense, sizeof (req.sense), '\0'); + if (sp->sense_len > sizeof (req.sense)) + req.senselen = sizeof (req.sense); + else if (sp->sense_len < 0) + req.senselen = 0; + else + req.senselen = sp->sense_len; + req.senselen_used = 0; + req.status = 0; + req.retsts = 0; + req.error = 0; + + if (ioctl(usalp->fd, SCIOCCOMMAND, (void *)&req) < 0) { + ret = -1; + sp->ux_errno = geterrno(); + if (sp->ux_errno != ENOTTY) + ret = 0; + } else { + sp->ux_errno = 0; + if (req.retsts != SCCMD_OK) + sp->ux_errno = EIO; + } + fillbytes(&sp->scb, sizeof (sp->scb), '\0'); + fillbytes(&sp->u_sense.cmd_sense, sizeof (sp->u_sense.cmd_sense), '\0'); + sp->resid = req.datalen - req.datalen_used; + sp->sense_count = req.senselen_used; + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + movebytes(req.sense, sp->u_sense.cmd_sense, sp->sense_count); + sp->u_scb.cmd_scb[0] = req.status; + + switch (req.retsts) { + + case SCCMD_OK: +#ifdef BSD_SCSI_SENSE_BUG + sp->u_scb.cmd_scb[0] = 0; + sp->ux_errno = 0; +#endif + sp->error = SCG_NO_ERROR; break; + case SCCMD_TIMEOUT: sp->error = SCG_TIMEOUT; break; + default: + case SCCMD_BUSY: sp->error = SCG_RETRYABLE; break; + case SCCMD_SENSE: sp->error = SCG_RETRYABLE; break; + case SCCMD_UNKNOWN: sp->error = SCG_FATAL; break; + } + + return (ret); +} +#define sense u_sense.Sense + +#else /* BSD_CAM */ +/* + * Interface for the FreeBSD CAM passthrough device. + * + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 1998 Kenneth D. Merry <ken@kdm.org> + * Copyright (c) 1998 Joerg Schilling <schilling@fokus.gmd.de> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#undef sense +#define scsi_sense CAM_scsi_sense +#define scsi_inquiry CAM_scsi_inquiry +#include <sys/param.h> +#include <cam/cam.h> +#include <cam/cam_ccb.h> +#include <cam/scsi/scsi_message.h> +#include <cam/scsi/scsi_pass.h> +#include <camlib.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-bsd.c-1.42"; /* The version for this transport*/ + +#define CAM_MAXDEVS 128 +struct usal_local { + struct cam_device *cam_devices[CAM_MAXDEVS + 1]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "CAM", "Generic transport independent SCSI (Common Access Method)", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +/* + * Build a list of everything we can find. + */ +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + char name[16]; + int unit; + int nopen = 0; + union ccb ccb; + int bufsize; + struct periph_match_pattern *match_pat; + int fd; + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (unit = 0; unit <= CAM_MAXDEVS; unit++) { + usallocal(usalp)->cam_devices[unit] = (struct cam_device *)-1; + } + } + + + /* + * If we're not scanning the bus, just open one device. + */ + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + usallocal(usalp)->cam_devices[0] = cam_open_btl(busno, tgt, tlun, O_RDWR, NULL); + if (usallocal(usalp)->cam_devices[0] == NULL) + return (-1); + nopen++; + return (nopen); + } + + /* + * First open the transport layer device. There's no point in the + * rest of this if we can't open it. + */ + + if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open of %s failed", XPT_DEVICE); + return (-1); + } + fillbytes(&ccb, sizeof (union ccb), '\0'); + + /* + * Get a list of up to CAM_MAXDEVS passthrough devices in the + * system. + */ + ccb.ccb_h.func_code = XPT_DEV_MATCH; + + /* + * Setup the result buffer. + */ + bufsize = sizeof (struct dev_match_result) * CAM_MAXDEVS; + ccb.cdm.match_buf_len = bufsize; + ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); + if (ccb.cdm.matches == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Couldn't malloc match buffer"); + close(fd); + return (-1); + } + ccb.cdm.num_matches = 0; + + /* + * Setup the pattern buffer. We're matching against all + * peripherals named "pass". + */ + ccb.cdm.num_patterns = 1; + ccb.cdm.pattern_buf_len = sizeof (struct dev_match_pattern); + ccb.cdm.patterns = (struct dev_match_pattern *)malloc( + sizeof (struct dev_match_pattern)); + if (ccb.cdm.patterns == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Couldn't malloc pattern buffer"); + close(fd); + free(ccb.cdm.matches); + return (-1); + } + ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH; + match_pat = &ccb.cdm.patterns[0].pattern.periph_pattern; + snprintf(match_pat->periph_name, sizeof (match_pat->periph_name), + "pass"); + match_pat->flags = PERIPH_MATCH_NAME; + + if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "CAMIOCOMMAND ioctl failed"); + close(fd); + free(ccb.cdm.matches); + free(ccb.cdm.patterns); + return (-1); + } + + if ((ccb.ccb_h.status != CAM_REQ_CMP) || + ((ccb.cdm.status != CAM_DEV_MATCH_LAST) && + (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { +/* errmsgno(EX_BAD, "Got CAM error 0x%X, CDM error %d.\n",*/ + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Got CAM error 0x%X, CDM error %d", + ccb.ccb_h.status, ccb.cdm.status); + close(fd); + free(ccb.cdm.matches); + free(ccb.cdm.patterns); + return (-1); + } + + free(ccb.cdm.patterns); + close(fd); + + for (unit = 0; unit < MIN(CAM_MAXDEVS, ccb.cdm.num_matches); unit++) { + struct periph_match_result *periph_result; + + /* + * We shouldn't have anything other than peripheral + * matches in here. If we do, it means an error in the + * device matching code in the transport layer. + */ + if (ccb.cdm.matches[unit].type != DEV_MATCH_PERIPH) { +/* errmsgno(EX_BAD, "Kernel error! got periph match type %d!!\n",*/ + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Kernel error! got periph match type %d!!", + ccb.cdm.matches[unit].type); + free(ccb.cdm.matches); + return (-1); + } + periph_result = &ccb.cdm.matches[unit].result.periph_result; + + snprintf(name, sizeof (name), + "/dev/%s%d", periph_result->periph_name, + periph_result->unit_number); + + /* + * cam_open_pass() avoids all lookup and translation from + * "regular device name" to passthrough unit number and + * just opens the device in question as a passthrough device. + */ + usallocal(usalp)->cam_devices[unit] = cam_open_pass(name, O_RDWR, NULL); + + /* + * If we get back NULL from the open routine, it wasn't + * able to open the given passthrough device for one reason + * or another. + */ + if (usallocal(usalp)->cam_devices[unit] == NULL) { +#ifdef OLD + errmsgno(EX_BAD, "Error opening /dev/%s%d\n", + periph_result->periph_name, + periph_result->unit_number); + errmsgno(EX_BAD, "%s\n", cam_errbuf); +#endif + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error opening /dev/%s%d Cam error '%s'", + periph_result->periph_name, + periph_result->unit_number, + cam_errbuf); + break; + } + nopen++; + } + + free(ccb.cdm.matches); + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int i; + + if (usalp->local == NULL) + return (-1); + + for (i = 0; i <= CAM_MAXDEVS; i++) { + if (usallocal(usalp)->cam_devices[i] != (struct cam_device *)-1) + cam_close_device(usallocal(usalp)->cam_devices[i]); + usallocal(usalp)->cam_devices[i] = (struct cam_device *)-1; + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ +#ifdef DFLTPHYS + return (DFLTPHYS); +#else + return (MAXPHYS); +#endif +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + int unit; + + if (usalp->local == NULL) + return (FALSE); + + /* + * There's a "cleaner" way to do this, using the matching code, but + * it would involve more code than this solution... + */ + for (unit = 0; usallocal(usalp)->cam_devices[unit] != (struct cam_device *)-1; unit++) { + if (usallocal(usalp)->cam_devices[unit] == NULL) + continue; + if (usallocal(usalp)->cam_devices[unit]->path_id == busno) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int unit, int tlun) +{ + int i; + + if (usalp->local == NULL) + return (-1); + + for (i = 0; usallocal(usalp)->cam_devices[i] != (struct cam_device *)-1; i++) { + if (usallocal(usalp)->cam_devices[i] == NULL) + continue; + if ((usallocal(usalp)->cam_devices[i]->path_id == busno) && + (usallocal(usalp)->cam_devices[i]->target_id == unit) && + (usallocal(usalp)->cam_devices[i]->target_lun == tlun)) + return (i); + } + return (-1); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + /* XXX synchronous reset command - is this wise? */ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + struct cam_device *dev; + union ccb ccb_space; + union ccb *ccb = &ccb_space; + int rv, result; + u_int32_t ccb_flags; + + if (usalp->fd < 0) { +#if 0 + fprintf((FILE *)usalp->errfile, + "attempt to reference invalid unit %d\n", usalp->fd); +#endif + sp->error = SCG_FATAL; + return (0); + } + + dev = usallocal(usalp)->cam_devices[usalp->fd]; + fillbytes(&ccb->ccb_h, sizeof (struct ccb_hdr), '\0'); + ccb->ccb_h.path_id = dev->path_id; + ccb->ccb_h.target_id = dev->target_id; + ccb->ccb_h.target_lun = dev->target_lun; + + /* Build the CCB */ + fillbytes(&(&ccb->ccb_h)[1], sizeof (struct ccb_scsiio), '\0'); + movebytes(sp->cdb.cmd_cdb, &ccb->csio.cdb_io.cdb_bytes, sp->cdb_len); + + /* + * Set the data direction flags. + */ + if (sp->size != 0) { + ccb_flags = (sp->flags & SCG_RECV_DATA) ? CAM_DIR_IN : + CAM_DIR_OUT; + } else { + ccb_flags = CAM_DIR_NONE; + } + + ccb_flags |= CAM_DEV_QFRZDIS; + + /* + * If you don't want to bother with sending tagged commands under CAM, + * we don't need to do anything to cdrecord. If you want to send + * tagged commands to those devices that support it, we'll need to set + * the tag action valid field like this in usalo_send(): + * + * ccb_flags |= CAM_DEV_QFRZDIS | CAM_TAG_ACTION_VALID; + */ + + cam_fill_csio(&ccb->csio, + /* retries */ 1, + /* cbfncp */ NULL, + /* flags */ ccb_flags, + /* tag_action */ MSG_SIMPLE_Q_TAG, + /* data_ptr */ (u_int8_t *)sp->addr, + /* dxfer_len */ sp->size, + /* sense_len */ SSD_FULL_SIZE, + /* cdb_len */ sp->cdb_len, + /* timeout */ sp->timeout * 1000); + + /* Run the command */ + errno = 0; + if ((rv = cam_send_ccb(dev, ccb)) == -1) { + return (rv); + } else { + /* + * Check for command status. Selection timeouts are fatal. + * For command timeouts, we pass back the appropriate + * error. If we completed successfully, there's (obviously) + * no error. We declare anything else "retryable". + */ + switch (ccb->ccb_h.status & CAM_STATUS_MASK) { + case CAM_SEL_TIMEOUT: + result = SCG_FATAL; + break; + case CAM_CMD_TIMEOUT: + result = SCG_TIMEOUT; + break; + case CAM_REQ_CMP: + result = SCG_NO_ERROR; + break; + default: + result = SCG_RETRYABLE; + break; + } + } + + sp->error = result; + if (result != SCG_NO_ERROR) + sp->ux_errno = EIO; + + /* Pass the result back up */ + fillbytes(&sp->scb, sizeof (sp->scb), '\0'); + fillbytes(&sp->u_sense.cmd_sense, sizeof (sp->u_sense.cmd_sense), '\0'); + sp->resid = ccb->csio.resid; + sp->sense_count = SSD_FULL_SIZE - ccb->csio.sense_resid; + + /* + * Determine how much room we have for sense data. + */ + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + + /* Copy the sense data out */ + movebytes(&ccb->csio.sense_data, &sp->u_sense.cmd_sense, sp->sense_count); + + sp->u_scb.cmd_scb[0] = ccb->csio.scsi_status; + + return (0); +} + +#undef scsi_sense +#undef scsi_inquiry +#define sense u_sense.Sense + +#endif /* BSD_CAM */ diff --git a/libusal/scsi-dos.c b/libusal/scsi-dos.c new file mode 100644 index 0000000..ecf36ce --- /dev/null +++ b/libusal/scsi-dos.c @@ -0,0 +1,562 @@ +/* + * 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. + * + */ + +/* @(#)scsi-dos.c 1.11 03/12/10 Copyright 1998-2003 J. Schilling, 2003 Alex Kopylov reanimatolog@yandex.ru */ +/* + * Interface for the MS-DOS ASPI managers. + * You need ASPI manager installed in your config.sys: + * aspi*.sys for SCSI devices + * oakaspi.sys for ATAPI devices + * usbaspi.sys for USB devices + * + * Made from Win32 ASPI library template. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998-2003 J. Schilling + * Copyright (c) 1999 A.L. Faber for the first implementation + * of this interface. + * Copyright (c) 2003 Alex Kopylov reanimatolog@yandex.ru + */ +/* + * 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 <dos.h> +#include <dpmi.h> +#include <go32.h> +#include <usal/aspi-dos.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-dos.c-1.11"; /* The version for this transport*/ + +#define MAX_SCG 8 +#define MAX_TGT 8 +#define MAX_LUN 8 + +struct usal_local { + int dummy; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#define MAX_DMA_DOS (63L*1024L) + +static BYTE busses = 1; +static DWORD SCSIMgrEntry = 0; +static int AspiLoaded = 0; + +static BOOL _callback_flag; +static _go32_dpmi_seginfo _callback_info; +static _go32_dpmi_registers _callback_regs; + +static BOOL SCSIMgrOpen(SCSI *); +static void SCSIMgrClose(void); +static int SCSIMgrSendSRB(SRB *, time_t); +static void SCSIMgrCallBack(_go32_dpmi_registers *regs); + +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "ASPI", "Generic transport independent SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + /* + * Check if variables are within the range + */ + if (tgt >= 0 && tgt >= 0 && tlun >= 0) { + /* + * This is the non -scanbus case. + */ + ; + } else if (tgt != -1 || tgt != -1 || tlun != -1) { + errno = EINVAL; + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + } + /* + * Try to open ASPI-Router + */ + if (!SCSIMgrOpen(usalp)) + return (-1); + + /* + * More than we have ... + */ + if (busno >= busses) { + SCSIMgrClose(); + return (-1); + } + + /* + * Install Exit Function which closes the ASPI-Router + */ + atexit(SCSIMgrClose); + + /* + * Success after all + */ + return (1); +} + +static int +usalo_close(SCSI *usalp) +{ + SCSIMgrClose(); + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_DOS); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = malloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static __SBOOL +usalo_havebus(SCSI *usalp, int busno) +{ + if (busno < 0 || busno >= busses) + return (FALSE); + + return (TRUE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= busses || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + /* + * Return fake + */ + return (1); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + SRB Srb; + int dos_memory_data_seg; + int dos_memory_data_sel; + DWORD dos_memory_data_ptr; + + /* + * Check if ASPI library is loaded + */ + if (!SCSIMgrEntry) { + errmsgno(EX_BAD, "error in usalo_send: ASPI driver not loaded.\n"); + sp->error = SCG_FATAL; + return (-1); + } + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + /* + * Initialize variables + */ + sp->error = SCG_NO_ERROR; + sp->sense_count = 0; + sp->u_scb.cmd_scb[0] = 0; + sp->resid = 0; + + memset(&Srb, 0, sizeof (Srb)); + + switch (sp->cdb_len) { + + case 6: + movebytes(&sp->cdb, &(Srb.Type.ExecSCSICmd.CmdLen._6.CDBByte), sp->cdb_len); + break; + case 10: + movebytes(&sp->cdb, &(Srb.Type.ExecSCSICmd.CmdLen._10.CDBByte), sp->cdb_len); + break; + case 12: + movebytes(&sp->cdb, &(Srb.Type.ExecSCSICmd.CmdLen._12.CDBByte), sp->cdb_len); + break; + default: + sp->error = SCG_FATAL; + sp->ux_errno = EINVAL; + fprintf((FILE *)usalp->errfile, + "Unsupported sp->cdb_len: %u. Fatal error in usalo_send, exiting...\n", sp->cdb_len); + return (-1); + } + + if ((dos_memory_data_seg = __dpmi_allocate_dos_memory((sp->size>>4)+1, &dos_memory_data_sel)) == -1) { + sp->error = SCG_FATAL; + return (-1); + } + dos_memory_data_ptr = dos_memory_data_seg<<16; + + _dosmemputb(sp->addr, sp->size, dos_memory_data_seg<<4); + + Srb.Cmd = SC_EXEC_SCSI_CMD; + Srb.HaId = usal_scsibus(usalp); + Srb.Type.ExecSCSICmd.Target = usal_target(usalp); + Srb.Type.ExecSCSICmd.Lun = usal_lun(usalp); + Srb.Type.ExecSCSICmd.BufLen = sp->size; + Srb.Type.ExecSCSICmd.BufPointer = (void *)dos_memory_data_ptr; + Srb.Type.ExecSCSICmd.CDBLen = sp->cdb_len; + if (sp->sense_len <= (SENSE_LEN+2)) + Srb.Type.ExecSCSICmd.SenseLen = sp->sense_len; + else + Srb.Type.ExecSCSICmd.SenseLen = (SENSE_LEN+2); + + /* + * Enable SCSIMgrCallBack() + */ + Srb.Flags |= SRB_POSTING; + Srb.Type.ExecSCSICmd.PostProc = (void *)(_callback_info.rm_offset|(_callback_info.rm_segment<<16)); + + /* + * Do we receive data from this ASPI command? + */ + if (sp->flags & SCG_RECV_DATA) { + + Srb.Flags |= SRB_DIR_IN; + } else { + /* + * Set direction to output + */ + if (sp->size > 0) { + Srb.Flags |= SRB_DIR_OUT; + } + } + + SCSIMgrSendSRB(&Srb, usalp->scmd->timeout); + Srb.Type.ExecSCSICmd.BufPointer = sp->addr; + _dosmemgetb(dos_memory_data_seg<<4, sp->size, sp->addr); + __dpmi_free_dos_memory(dos_memory_data_sel); + + if (Srb.Status == SS_PENDING) { /* Check if we got a timeout*/ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Timeout....\n"); + } + sp->error = SCG_TIMEOUT; + return (1); /* Return error */ + } + + /* + * Check ASPI command status + */ + if (Srb.Status != SS_COMP) { + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Error in usalo_send: Srb.Status is 0x%x\n", Srb.Status); + } + + switch (Srb.Status) { + + case SS_COMP: /* 0x01 SRB completed without error */ + sp->error = SCG_NO_ERROR; + sp->ux_errno = 0; + break; + + case SS_PENDING: /* 0x00 SRB being processed */ + case SS_ABORTED: /* 0x02 SRB aborted */ + case SS_ABORT_FAIL: /* 0x03 Unable to abort SRB */ + default: + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + + case SS_ERR: /* 0x04 SRB completed with error */ + /* + * If the SCSI Status byte is != 0, we definitely could send + * the command to the target. We signal NO transport error. + */ + sp->error = SCG_NO_ERROR; + sp->ux_errno = EIO; + if (Srb.Type.ExecSCSICmd.TargStat) + break; + + case SS_INVALID_CMD: /* 0x80 Invalid ASPI command */ + case SS_INVALID_HA: /* 0x81 Invalid host adapter number */ + case SS_NO_DEVICE: /* 0x82 SCSI device not installed */ + sp->error = SCG_FATAL; + sp->ux_errno = EINVAL; + break; + } + + sp->sense_count = Srb.Type.ExecSCSICmd.SenseLen; + if (sp->sense_count > sp->sense_len) + sp->sense_count = sp->sense_len; + + memset(&sp->u_sense.Sense, 0x00, sizeof (sp->u_sense.Sense)); + + switch (sp->cdb_len) { + + case 6: + memcpy(&sp->u_sense.Sense, Srb.Type.ExecSCSICmd.CmdLen._6.SenseArea, sp->sense_count); + break; + case 10: + memcpy(&sp->u_sense.Sense, Srb.Type.ExecSCSICmd.CmdLen._10.SenseArea, sp->sense_count); + break; + case 12: + memcpy(&sp->u_sense.Sense, Srb.Type.ExecSCSICmd.CmdLen._12.SenseArea, sp->sense_count); + break; + } + sp->u_scb.cmd_scb[0] = Srb.Type.ExecSCSICmd.TargStat; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Mapped to: error %d errno: %d\n", sp->error, sp->ux_errno); + } + return (1); + } + + return (0); +} + +static BOOL +SCSIMgrOpen(SCSI *usalp) +{ + int hSCSIMgr; + int dos_memory_seg; + int dos_memory_sel; + __dpmi_regs _regs; + SRB Srb; + + if (SCSIMgrEntry) { + AspiLoaded++; + return (TRUE); + } + + /* + * Open "SCSIMRG$" + */ + if (!_dos_open("SCSIMGR$", 0, &hSCSIMgr)) { + + /* Alloc 16 bytes DOS memory */ + if ((dos_memory_seg = __dpmi_allocate_dos_memory(1, &dos_memory_sel)) != -1) { + + /* Look for SCSIMgr entry point */ + memset(&_regs, 0, sizeof (_regs)); + _regs.x.ax = 0x4402; + _regs.x.bx = hSCSIMgr; + _regs.x.cx = 0x0004; + _regs.x.ds = dos_memory_seg; + _regs.x.dx = 0x0000; + if (!__dpmi_simulate_real_mode_interrupt(0x21, &_regs)) { + _dosmemgetb(dos_memory_seg<<4, 4, &SCSIMgrEntry); + } + + /* Free DOS memory */ + __dpmi_free_dos_memory(dos_memory_sel); + } + + /* Close "SCSIMRG$" */ + _dos_close(hSCSIMgr); + + /* Allocate real mode callback */ + _callback_info.pm_offset = (unsigned long)&SCSIMgrCallBack; + if (_go32_dpmi_allocate_real_mode_callback_retf(&_callback_info, &_callback_regs) == -1) { + fprintf((FILE *)usalp->errfile, "Cannot allocate callback address!\n"); + SCSIMgrEntry = 0; + } + } + + /* SCSIMgr entry point founded? */ + if (!SCSIMgrEntry) { + fprintf((FILE *)usalp->errfile, "Cannot open ASPI manager! Try to get one from http://bootcd.narod.ru/\n"); + return (FALSE); + } + + memset(&Srb, 0, sizeof (Srb)); + Srb.Cmd = SC_HA_INQUIRY; + + SCSIMgrSendSRB(&Srb, 10); + + if (usalp->debug) { + fprintf((FILE *)usalp->errfile, "Status : %ld\n", Srb.Status); + fprintf((FILE *)usalp->errfile, "hacount: %d\n", Srb.Type.HAInquiry.Count); + fprintf((FILE *)usalp->errfile, "SCSI id: %d\n", Srb.Type.HAInquiry.SCSI_ID); + fprintf((FILE *)usalp->errfile, "Manager: '%.16s'\n", Srb.Type.HAInquiry.ManagerId); + fprintf((FILE *)usalp->errfile, "Identif: '%.16s'\n", Srb.Type.HAInquiry.Identifier); + usal_prbytes("Unique:", Srb.Type.HAInquiry.Unique, 16); + } + + AspiLoaded++; + return (TRUE); +} + +static void +SCSIMgrClose() +{ + if (--AspiLoaded > 0) + return; + if (SCSIMgrEntry) { + _go32_dpmi_free_real_mode_callback(&_callback_info); + SCSIMgrEntry = 0; + } +} + +static int +SCSIMgrSendSRB(SRB *Srb, time_t timeout) +{ + int dos_memory_srb_seg; + int dos_memory_srb_sel; + DWORD dos_memory_srb_ptr; + struct timeval st; + struct timeval cr; + __dpmi_regs _regs; + + /* Alloc DOS memory */ + if ((dos_memory_srb_seg = __dpmi_allocate_dos_memory((sizeof (SRB) >> 4) + 1, &dos_memory_srb_sel)) == -1) { + Srb->Status = SS_NO_DEVICE; /* ??? fatal error */ + return (Srb->Status); + } + dos_memory_srb_ptr = dos_memory_srb_seg<<16; + + /* Copy SRB to DOS memory */ + _dosmemputb((void *)Srb, sizeof (SRB), dos_memory_srb_seg<<4); + + /* Reset callback flag */ + _callback_flag = 0; + + /* Call SCSIMgr */ + memset(&_regs, 0, sizeof (_regs)); + _regs.x.ip = SCSIMgrEntry & 0xffff; + _regs.x.cs = SCSIMgrEntry >> 16; + __dpmi_simulate_real_mode_procedure_retf_stack(&_regs, 2, &dos_memory_srb_ptr); + + /* Wait 'timeout' seconds for Srb->Status != SS_PENDING */ + gettimeofday(&st, NULL); + do { + _dosmemgetb(dos_memory_srb_seg << 4, sizeof (SRB), (void *)Srb); + gettimeofday(&cr, NULL); + } while ((Srb->Status == SS_PENDING) && (cr.tv_sec - st.tv_sec < timeout)); + + /* Free DOS memory */ + __dpmi_free_dos_memory(dos_memory_srb_sel); + + return (Srb->Status); +} + +static void +SCSIMgrCallBack(_go32_dpmi_registers *regs) +{ + _callback_flag = 1; +} diff --git a/libusal/scsi-hpux.c b/libusal/scsi-hpux.c new file mode 100644 index 0000000..f7eb553 --- /dev/null +++ b/libusal/scsi-hpux.c @@ -0,0 +1,363 @@ +/* + * 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. + * + */ + +/* @(#)scsi-hpux.c 1.31 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the HP-UX generic SCSI implementation. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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. + */ + +#undef sense +#include <sys/scsi.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-hpux.c-1.31"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#ifdef SCSI_MAXPHYS +# define MAX_DMA_HP SCSI_MAXPHYS +#else +# define MAX_DMA_HP (63*1024) /* Check if this is not too big */ +#endif + + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SIOC", "Generic SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[64]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + + snprintf(devname, sizeof (devname), + "/dev/rscsi/c%xt%xl%x", busno, tgt, tlun); + f = open(devname, O_RDWR); + if (f < 0) + return (-1); + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + return (1); + } else { + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { +/* for (l = 0; l < MAX_LUN; l++) {*/ + for (l = 0; l < 1; l++) { + snprintf(devname, sizeof (devname), + "/dev/rscsi/c%xt%xl%x", b, t, l); +/*fprintf(stderr, "name: '%s'\n", devname);*/ + f = open(devname, O_RDWR); + if (f >= 0) { + usallocal(usalp)->usalfiles[b][t][l] = (short)f; + nopen++; + } else if (usalp->debug > 0) { + errmsg("open '%s'\n", devname); + } + } + } + } + } + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_HP); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + return (ioctl(usalp->fd, SIOC_RESET_BUS, 0)); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + int flags; + struct sctl_io sctl_io; + + if ((usalp->fd < 0) || (sp->cdb_len > sizeof (sctl_io.cdb))) { + sp->error = SCG_FATAL; + return (0); + } + + fillbytes((caddr_t)&sctl_io, sizeof (sctl_io), '\0'); + + flags = 0; +/* flags = SCTL_INIT_WDTR|SCTL_INIT_SDTR;*/ + if (sp->flags & SCG_RECV_DATA) + flags |= SCTL_READ; + if ((sp->flags & SCG_DISRE_ENA) == 0) + flags |= SCTL_NO_ATN; + + sctl_io.flags = flags; + + movebytes(&sp->cdb, sctl_io.cdb, sp->cdb_len); + sctl_io.cdb_length = sp->cdb_len; + + sctl_io.data_length = sp->size; + sctl_io.data = sp->addr; + + if (sp->timeout == 0) + sctl_io.max_msecs = 0; + else + sctl_io.max_msecs = (sp->timeout * 1000) + 500; + + errno = 0; + sp->error = SCG_NO_ERROR; + sp->sense_count = 0; + sp->u_scb.cmd_scb[0] = 0; + sp->resid = 0; + + ret = ioctl(usalp->fd, SIOC_IO, &sctl_io); + if (ret < 0) { + sp->error = SCG_FATAL; + sp->ux_errno = errno; + return (ret); + } +if (usalp->debug > 0) +fprintf(stderr, "cdb_status: %X, size: %d xfer: %d\n", sctl_io.cdb_status, sctl_io.data_length, sctl_io.data_xfer); + + if (sctl_io.cdb_status == 0 || sctl_io.cdb_status == 0x02) + sp->resid = sp->size - sctl_io.data_xfer; + + if (sctl_io.cdb_status & SCTL_SELECT_TIMEOUT || + sctl_io.cdb_status & SCTL_INVALID_REQUEST) { + sp->error = SCG_FATAL; + } else if (sctl_io.cdb_status & SCTL_INCOMPLETE) { + sp->error = SCG_TIMEOUT; + } else if (sctl_io.cdb_status > 0xFF) { + errmsgno(EX_BAD, "SCSI problems: cdb_status: %X\n", sctl_io.cdb_status); + + } else if ((sctl_io.cdb_status & 0xFF) != 0) { + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + + sp->u_scb.cmd_scb[0] = sctl_io.cdb_status & 0xFF; + + sp->sense_count = sctl_io.sense_xfer; + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + + if (sctl_io.sense_status != S_GOOD) { + sp->sense_count = 0; + } else { + movebytes(sctl_io.sense, sp->u_sense.cmd_sense, sp->sense_count); + } + + } + return (ret); +} +#define sense u_sense.Sense diff --git a/libusal/scsi-linux-ata.c b/libusal/scsi-linux-ata.c new file mode 100644 index 0000000..3ec18b7 --- /dev/null +++ b/libusal/scsi-linux-ata.c @@ -0,0 +1,1188 @@ +/* + * 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. + * + */ + +/* @(#)scsi-linux-ata.c 1.7 04/06/12 Copyright 2002 J. Schilling */ +/* + * Interface for Linux generic SCSI implementation (sg). + * + * This is the interface for the broken Linux SCSI generic driver. + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 2002 J. Schilling + * + * Thanks to Alexander Kern <alex.kern@gmx.de> for the idea and first + * code fragments for supporting the CDROM_SEND_PACKET ioctl() from + * the cdrom.c kernel driver. Please note that this interface in priciple + * is completely unneeded but the Linux kernel is just a cluster of + * code and does not support planned orthogonal interface systems. + * For this reason we need CDROM_SEND_PACKET in order to work around a + * bug in the linux kernel that prevents to use PCATA drives because + * the kernel panics if you try to put ide-scsi on top of the PCATA + * driver. + */ +/* + * 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. + */ + +#ifdef USE_OLD_ATAPI + +#define ata_sccsid "obsolete ATAPI driver in cdrkit" + +static char _usal_atrans_version[] = "scsi-linux-ata.c-1.7"; /* The version for ATAPI transport*/ + +static char *usalo_aversion(SCSI *usalp, int what); +static int usalo_ahelp(SCSI *usalp, FILE *f); +static int usalo_aopen(SCSI *usalp, char *device); +static int usalo_aclose(SCSI *usalp); +static long usalo_amaxdma(SCSI *usalp, long amt); +static BOOL usalo_ahavebus(SCSI *usalp, int); +static int usalo_afileno(SCSI *usalp, int, int, int); +static int usalo_ainitiator_id(SCSI *usalp); +static int usalo_aisatapi(SCSI *usalp); +static int usalo_areset(SCSI *usalp, int what); +static int usalo_asend(SCSI *usalp); + +static usal_ops_t ata_ops = { + usalo_asend, + usalo_aversion, + usalo_ahelp, + usalo_aopen, + usalo_aclose, + usalo_amaxdma, + usalo_getbuf, /* Shared with SG driver */ + usalo_freebuf, /* Shared with SG driver */ + usalo_ahavebus, + usalo_afileno, + usalo_ainitiator_id, + usalo_aisatapi, + usalo_areset, +}; + +#define HOST_EMPTY 0xF +#define HOST_SCSI 0x0 +#define HOST_IDE 0x1 +#define HOST_USB 0x2 +#define HOST_IEEE1389 0x3 +#define HOST_PARALLEL 0x4 +#define HOST_OTHER 0xE + + +#define typlocal(p, schillybus) usallocal(p)->bc[schillybus].typ +#define buslocal(p, schillybus) usallocal(p)->bc[schillybus].bus +#define hostlocal(p, schillybus) usallocal(p)->bc[schillybus].host + +#define MAX_DMA_ATA (131072-1) /* EINVAL (hart) ENOMEM (weich) bei mehr ... */ + /* Bei fehlerhaftem Sense Pointer kommt EFAULT */ + +static int usalo_send(SCSI * usalp); +static BOOL sg_amapdev(SCSI * usalp, int f, char *device, int *bus, + int *target, int *lun); +static BOOL sg_amapdev_scsi(SCSI * usalp, int f, int *busp, int *tgtp, + int *lunp, int *chanp, int *inop); +static int usalo_aget_first_free_shillybus(SCSI * usalp, int subsystem, + int host, int bus); +static int usalo_amerge(char *path, char *readedlink, char *buffer, int buflen); + +/* + * uncomment this when you will get a debug file #define DEBUG + */ +#ifdef DEBUG +#define LOGFILE "scsi-linux-ata.log" +#define log(a) sglog a + +static void sglog(const char *fmt, ...); + +#include <vadefs.h> + +/* VARARGS1 */ +static void +sglog(const char *fmt, ...) +{ + va_list args; + FILE *f = fopen(LOGFILE, "a"); + + if (f == NULL) + return; + + va_start(args, fmt); + vfprintf(f, fmt, args); + va_end(args); + fclose(f); +} +#else +#define log(a) +#endif /* DEBUG */ + +static int scan_internal(SCSI * usalp, int *fatal); + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_aversion(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_atrans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (ata_sccsid); + } + } + return ((char *)0); +} + +static int +usalo_ahelp(SCSI *usalp, FILE *f) +{ + __usal_help(f, "ATA", "ATA Packet specific SCSI transport", + "ATAPI:", "bus,target,lun", "ATAPI:1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_aopen(SCSI *usalp, char *device) +{ + int bus = usal_scsibus(usalp); + int target = usal_target(usalp); + int lun = usal_lun(usalp); + + register int f; + register int b; + register int t; + register int l; + int nopen = 0; + + if (usalp->overbose) + fprintf(stderr, "Warning: Using ATA Packet interface.\n"); + if (usalp->overbose) { + fprintf(stderr, "Warning: The related Linux kernel interface code seems to be unmaintained.\n"); + fprintf(stderr, "Warning: There is absolutely NO DMA, operations thus are slow.\n"); + } + + log(("\n<<<<<<<<<<<<<<<< LOGGING ON >>>>>>>>>>>>>>>>>\n")); + if (bus >= MAX_SCHILLY_HOSTS || target >= MAX_TGT || lun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for bus, target or lun '%d,%d,%d'", + bus, target, lun); + + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) { + return (0); + } + + usallocal(usalp)->usalfile = -1; + usallocal(usalp)->pgbus = -2; + usallocal(usalp)->SCSIbuf = (char *)-1; + usallocal(usalp)->pack_id = 5; + usallocal(usalp)->drvers = -1; + usallocal(usalp)->isold = -1; + usallocal(usalp)->xbufsize = 0L; + usallocal(usalp)->xbuf = NULL; + + + for (b = 0; b < MAX_SCHILLY_HOSTS; b++) { + typlocal(usalp, b) = HOST_EMPTY; + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short) -1; + } + } + } + + if (device != NULL && strcmp(device, "ATAPI") == 0) + goto atascan; + + /* if not scanning */ + if ((device != NULL && *device != '\0') || (bus == -2 && target == -2)) + goto openbydev; + +atascan: + if (scan_internal(usalp, &nopen)) { + if (usalp->errstr) + printf(usalp->errstr, "INFO: scan_internal(...) failed"); + return (-1); + } + return (nopen); + +openbydev: + if (device != NULL && strncmp(device, "ATAPI:", 6) == 0) + device += 6; + if (usalp->debug > 3) { + fprintf((FILE *) usalp->errfile, "INFO: do usalo_open openbydev"); + } + if (device != NULL && *device != '\0') { + int schilly_bus, + starget, + slun; + + f = sg_open_excl(device, O_RDONLY | O_NONBLOCK, FALSE); + + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", device); + return (0); + } + if (sg_amapdev(usalp, f, device, &schilly_bus, &starget, &slun)) { + usal_settarget(usalp, schilly_bus, starget, slun); + return (++nopen); + } + } + return (nopen); +} + +static int +scan_internal(SCSI *usalp, int *nopen) +{ + int i, + f; + int schilly_bus, + target, + lun; + char device[128]; + /* + * try always with devfs + * unfortunatelly the solution with test of existing + * of '/dev/.devfsd' don't work, because it root.root 700 + * and i don't like run suid root + */ + BOOL DEVFS = TRUE; + + if (DEVFS) { + for (i = 0; ; i++) { + sprintf(device, "/dev/cdroms/cdrom%i", i); + if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) { + if (errno != ENOENT && errno != ENXIO && errno != ENODEV && errno != EACCES) { + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "try open(%s) return %i, errno %i, cancel\n", device, f, errno); + } + return (-2); + } else if (errno == ENOENT || errno == ENODEV) { + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "try open(%s) return %i, errno %i\n", device, f, errno); + } + if (0 == i) { + DEVFS = FALSE; + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "DEVFS not detected, continuing with old dev\n"); + } + } + break; + } + if (usalp->debug > 4) { + if (errno == EACCES) { + fprintf((FILE *) usalp->errfile, + "errno (EACCESS), you don't have the needed rights for %s\n", + device); + } + fprintf((FILE *) usalp->errfile, + "try open(%s) return %i, errno %i, trying next cdrom\n", + device, f, errno); + } + } else { + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "try open(%s) return %i errno %i calling sg_mapdev(...)\n", + device, f, errno); + } + if (sg_amapdev(usalp, f, device, &schilly_bus, &target, &lun)) { + (++(*nopen)); + } else { + close(f); + } + } + } + } + if (!DEVFS) { + /* for /dev/sr0 - /dev/sr? */ + for (i = 0; i<16 ; i++) { + sprintf(device, "/dev/sr%i", i); + if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) { + if (errno != ENOENT && errno != ENXIO && errno != ENODEV && errno != EACCES) { + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "try open(%s) return %i, errno %i, cancel\n", + device, f, errno); + } + return (-2); + } + } else { + if (sg_amapdev(usalp, f, device, &schilly_bus, &target, &lun)) { + (++(*nopen)); + } else { + close(f); + } + } + } + + /* for /dev/hda - /dev/hdz */ + for (i = 'a'; i <= 'z'; i++) { + sprintf(device, "/dev/hd%c", i); + if ((f = open(device, O_RDONLY | O_NONBLOCK)) < 0) { + if (errno != ENOENT && errno != ENXIO && errno != EACCES) { + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "try open(%s) return %i, errno %i, cancel\n", + device, f, errno); + } + return (-2); + } + } else { + /* ugly hack, make better, when you can. Alex */ + if (0 > ioctl(f, CDROM_DRIVE_STATUS, CDSL_CURRENT)) { + if (usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "%s is not a cdrom, skipping\n", + device); + } + close(f); + } else if (sg_amapdev(usalp, f, device, &schilly_bus, &target, &lun)) { + (++(*nopen)); + } else { + close(f); + } + } + } + } + return (0); +} + +static int +usalo_aclose(SCSI *usalp) +{ + register int f; + register int h; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (h = 0; h < MAX_SCHILLY_HOSTS; h++) { + typlocal(usalp, h) = (HOST_EMPTY); + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[h][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[h][t][l] = (short) -1; + } + } + } + + if (usallocal(usalp)->xbuf != NULL) { + free(usallocal(usalp)->xbuf); + usallocal(usalp)->xbufsize = 0L; + usallocal(usalp)->xbuf = NULL; + } + log(("<<<<<<<<<<<<<<<< LOGGING OFF >>>>>>>>>>>>>>>>>\n\n")); + return (0); +} + +static int +usalo_aget_first_free_shillybus(SCSI *usalp, int subsystem, int host, int bus) +{ + int first_free_schilly_bus; + + for (first_free_schilly_bus = 0; + first_free_schilly_bus < MAX_SCHILLY_HOSTS; + first_free_schilly_bus++) { + + if (typlocal(usalp, first_free_schilly_bus) == HOST_EMPTY || + (typlocal(usalp, first_free_schilly_bus) == subsystem && + hostlocal(usalp, first_free_schilly_bus) == host && + buslocal(usalp, first_free_schilly_bus) == bus)) + break; + } + + if (first_free_schilly_bus >= MAX_SCHILLY_HOSTS) { + errmsgno(EX_BAD, "ERROR: in usalo_get_first_free_shillybus(...). Too many CDROMs, more than %i", + MAX_SCHILLY_HOSTS); + errmsgno(EX_BAD, "Increase MAX_SCHILLY_HOSTS in scsi-linux-ata.c and recompile!"); + return (-1); + } + return (first_free_schilly_bus); +} + +static int +usalo_amerge(char *path, char *readedlink, char *buffer, int buflen) +{ + char *aa; + +#define TOKEN_ARRAY 20 +#define LAST_CHAR(x) (x)[strlen((x))-1] +#define ONE_CHAR_BACK(x) (x)[strlen((x))-1] = '\0' + char *ppa[TOKEN_ARRAY]; + char *pa; + + int i; + int len; + char seps[] = "/"; + char *last_slash; + + if (!path || !readedlink || !buffer) + return (-EINVAL); + + if ('/' == readedlink[0]) { + aa = (char *) malloc(strlen(readedlink) + 1); + if (!aa) + return (-ENOMEM); + + strcpy(aa, readedlink); + } else { + aa = (char *) malloc(strlen(path) + strlen(readedlink) + 1); + if (!aa) + return (-ENOMEM); + + strcpy(aa, path); + if (LAST_CHAR(aa) == '/') { + ONE_CHAR_BACK(aa); + } + last_slash = strrchr(aa, '/'); + if (last_slash == NULL) + strcpy(aa, "/"); + else + *(++last_slash) = '\0'; + strcat(aa, readedlink); + } + memset(ppa, 0x00, sizeof (ppa)); + + for (i = 0, pa = strtok(aa, seps); + i < TOKEN_ARRAY && pa != NULL; + ++i, pa = strtok(NULL, seps)) { + ppa[i] = pa; + } + + if (i == TOKEN_ARRAY) { + free(aa); + return (-ENOMEM); + } + for (i = 0; i < TOKEN_ARRAY && ppa[i]; i++) { + if (strcmp(ppa[i], "..") == 0) { + ppa[i] = NULL; + if (i > 1) + ppa[i - 1] = NULL; + } + } + + /* dry run */ + len = 0; + for (i = 0; i < TOKEN_ARRAY; i++) { + if (ppa[i]) { + len += 1; + len += strlen(ppa[i]); + } + } + if (0 == len) + len = 1; + + if (len + 1 <= buflen) { + strcpy(buffer, ""); + for (i = 0; i < TOKEN_ARRAY; i++) { + if (ppa[i]) { + strcat(buffer, "/"); + strcat(buffer, ppa[i]); + } + } + + if (strlen(buffer) == 0) + strcpy(buffer, "/"); + } + free(aa); + + return (len + 1); +} + +/* + * /dev/cdroms/cdrom0 first CD-ROM + * /dev/cdroms/cdrom1 second CD-ROM + * + * + * SCSI Devices + * + * To uniquely identify any SCSI device requires the following information: + * + * controller (host adapter) + * bus (SCSI channel) + * target (SCSI ID) + * unit (Logical Unit Number) + * + * All SCSI devices are placed under /dev/scsi (assuming devfs is mounted on /dev). + * Hence, a SCSI device with the following parameters: + * c=1,b=2,t=3,u=4 would appear as: + * + * /dev/scsi/host1/bus2/target3/lun4 device directory + * + * Inside this directory, a number of device entries may be created, + * depending on which SCSI device-type drivers were installed. + * + * See the section on the disc naming scheme to see what entries + * the SCSI disc driver creates. + * + * See the section on the tape naming scheme to see what entries + * the SCSI tape driver creates. + * + * The SCSI CD-ROM driver creates: cd + * The SCSI generic driver creates: generic + * + * IDE Devices + * + * To uniquely identify any IDE device requires the following information: + * + * controller + * bus (0/1 aka. primary/secondary) + * target (0/1 aka. master/slave) + * unit + * + * All IDE devices are placed under /dev/ide, and uses a similar + * naming scheme to the SCSI subsystem. + * + * + * Example /dev/cdroms/cdrom0 -> /dev/scsi/host1/bus2/target3/lun4/cd + * Example /dev/cdroms/cdrom1 -> /dev/ide/host1/bus0/target1/lun4/cd + * + */ +static BOOL +sg_amapdev(SCSI *usalp, int f, char *device, int *schillybus, int *target, + int *lun) +{ + struct host { + char host[4]; + char host_no; + }; + struct bus { + char bus[3]; + char bus_no; + }; + struct target { + char target[6]; + char target_no; + }; + struct lun { + char lun[3]; + char lun_no; + }; + + int h, + b, + t, + l; + +#define TOKEN_DEV "dev" +#define TOKEN_SUBSYSTEM_SCSI "scsi" +#define TOKEN_SUBSYSTEM_IDE "ide" +#define TOKEN_HOST "host" +#define TOKEN_BUS "bus" +#define TOKEN_TARGET "target" +#define TOKEN_LUN "lun" +#define TOKEN_CD "cd" + +#define ID_TOKEN_DEV 0 +#define ID_TOKEN_SUBSYSTEM 1 +#define ID_TOKEN_HOST 2 +#define ID_TOKEN_BUS 3 +#define ID_TOKEN_TARGET 4 +#define ID_TOKEN_LUN 5 +#define ID_TOKEN_CD 6 +#define ID_TOKEN_LAST ID_TOKEN_CD +#define ID_TOKEN_MAX ID_TOKEN_LAST + 2 +#define CHARTOINT(x) (abs(atoi(&x))) + + char *token[ID_TOKEN_MAX], + *seps = "/"; + int i, + result; + struct stat buf; + +#ifndef MAX_PATH +#define MAX_PATH 260 +#endif +#define LOCAL_MAX_PATH MAX_PATH + char tmp[LOCAL_MAX_PATH], + tmp1[LOCAL_MAX_PATH]; + int first_free_schilly_bus; + int subsystem = HOST_EMPTY; + + /* old DEV */ + typedef struct { + char prefix[2]; + char device; + } old_dev; + /* strtok need char* instead of const char* */ + result = stat(device, &buf); + if (result || !S_ISBLK(buf.st_mode)) + return (FALSE); + + result = lstat(device, &buf); + if (!result && S_ISLNK(buf.st_mode)) { + result = readlink(device, tmp, LOCAL_MAX_PATH); + if (result > 0 && result < LOCAL_MAX_PATH) { + tmp[result] = '\0'; + + result = usalo_amerge(device, tmp, tmp1, LOCAL_MAX_PATH); + if (result > 0 && result < LOCAL_MAX_PATH) { + tmp1[result] = '\0'; + strcpy(tmp, tmp1); + } else { + errmsgno(EX_BAD, + "ERROR: with link merging! base %s link %s, result of merging %i\n", + device, tmp, result); + return (FALSE); + } + } else { + errmsgno(EX_BAD, + "ERROR: with link reading! link %s, result of readlink %i\n", + device, result); + return (FALSE); + } + } else { + strncpy(tmp, device, sizeof (tmp)); + } + if (usalp->debug > 3) { + fprintf((FILE *) usalp->errfile, "INFO: %s -> %s\n", device, tmp); + } + memset(token, 0x00, sizeof (token)); + i = 0; + token[i] = strtok(tmp, seps); + while (token[i] != NULL && (++i) && i < ID_TOKEN_MAX) { + token[i] = strtok(NULL, seps); + } + + if (i == ID_TOKEN_MAX || + !(token[ID_TOKEN_DEV]) || + strcmp(token[ID_TOKEN_DEV], TOKEN_DEV)) { + + errmsgno(EX_BAD, "ERROR: unknown format\n"); + errmsgno(EX_BAD, "EXAMPLE: /dev/scsi/host1/bus2/target3/lun4/cd\n"); + errmsgno(EX_BAD, "EXAMPLE: /dev/ide/host0/bus0/target1/lun0/cd\n"); + errmsgno(EX_BAD, "EXAMPLE: /dev/hda or /dev/sr0\n"); + return (FALSE); + } + if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_SCSI)) || + !(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) { + h = CHARTOINT(((struct host *) token[ID_TOKEN_HOST])->host_no); + b = CHARTOINT(((struct bus *) token[ID_TOKEN_BUS])->bus_no); + t = CHARTOINT(((struct target *) token[ID_TOKEN_TARGET])->target_no); + l = CHARTOINT(((struct lun *) token[ID_TOKEN_LUN])->lun_no); +#ifdef PARANOID + if (strncmp(token[ID_TOKEN_HOST], TOKEN_HOST, strlen(TOKEN_HOST))) { + log(("ERROR: invalid host specified\n")); + return (FALSE); + } + if (strncmp(token[ID_TOKEN_BUS], TOKEN_BUS, strlen(TOKEN_BUS))) { + log(("ERROR: invalid bus specified\n")); + return (FALSE); + } + if (strncmp(token[ID_TOKEN_TARGET], TOKEN_TARGET, strlen(TOKEN_TARGET))) { + log(("ERROR: invalid target specified\n")); + return (FALSE); + } + if (strncmp(token[ID_TOKEN_LUN], TOKEN_LUN, strlen(TOKEN_LUN))) { + log(("ERROR: invalid lun specified\n")); + return (FALSE); + } + if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) { + if (b > 1 || t > 1) { + log(("ERROR: invalid bus or target for IDE specified\n")); + return (FALSE); + } + } +#endif /* PARANOID */ + + if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_IDE))) { + subsystem = HOST_IDE; + } else if (!(strcmp(token[ID_TOKEN_SUBSYSTEM], TOKEN_SUBSYSTEM_SCSI))) { + subsystem = HOST_SCSI; + } else { + subsystem = HOST_OTHER; + } + } else if (!token[ID_TOKEN_HOST] && + strlen(token[ID_TOKEN_SUBSYSTEM]) == sizeof (old_dev)) { + char j; + + old_dev *pDev = (old_dev *) token[ID_TOKEN_SUBSYSTEM]; + + if (strncmp(pDev->prefix, "hd", 2) == 0) { + j = pDev->device - ('a'); + + subsystem = HOST_IDE; + h = j / 4; + b = (j % 4) / 2; + t = (j % 4) % 2; + l = 0; + } else if (strncmp(pDev->prefix, "sr", 2) == 0) { +#ifdef nonono + if (pDev->device >= '0' && pDev->device <= '9') + j = pDev->device - ('0'); + else + j = pDev->device - ('a'); + + + h = j / 4; + b = (j % 4) / 2; + t = (j % 4) % 2; + l = 0; +#endif /* nonono */ + /* other solution, with ioctl */ + int Chan = 0, + Ino = 0, + Bus = 0, + Target = 0, + Lun = 0; + + subsystem = HOST_SCSI; + sg_amapdev_scsi(usalp, f, &Bus, &Target, &Lun, &Chan, &Ino); + + /* For old kernels try to make the best guess. */ +#ifdef nonono + int n; + Ino |= Chan << 8; + n = sg_mapbus(usalp, Bus, Ino); + if (Bus == -1) { + Bus = n; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "SCSI Bus: %d (mapped from %d)\n", + Bus, Ino); + } + } +/* It is me too high ;-()*/ +#endif /* nonono */ + h = Ino; + b = Chan; + t = Target; + l = Lun; + } else { + errmsgno(EX_BAD, "ERROR: unknow subsystem (%s) in (%s)\n", + token[ID_TOKEN_SUBSYSTEM], device); + return (FALSE); + } + } else { + errmsgno(EX_BAD, "ERROR: unknow subsystem (%s) in (%s)\n", + token[ID_TOKEN_SUBSYSTEM], device); + return (FALSE); + } + + if (usalp->verbose) + printf(usalp->errstr, "INFO: subsystem %s: h %i, b %i, t %i, l %i", + token[ID_TOKEN_SUBSYSTEM], h, b, t, l); + + first_free_schilly_bus = usalo_aget_first_free_shillybus(usalp, subsystem, h, b); + if (-1 == first_free_schilly_bus) { + return (FALSE); + } + if (usallocal(usalp)->usalfiles[first_free_schilly_bus][t][l] != (-1)) { + errmsgno(EX_BAD, "ERROR: this cdrom is already mapped %s(%d,%d,%d)\n", + device, first_free_schilly_bus, t, l); + return (FALSE); + } else { + usallocal(usalp)->usalfiles[first_free_schilly_bus][t][l] = f; + typlocal(usalp, first_free_schilly_bus) = subsystem; + hostlocal(usalp, first_free_schilly_bus) = h; + buslocal(usalp, first_free_schilly_bus) = b; + *schillybus = first_free_schilly_bus; + *target = t; + *lun = l; + + if (usalp->debug > 1) { + fprintf((FILE *) usalp->errfile, + "INFO: /dev/%s, (host%d/bus%d/target%d/lun%d) will be mapped on the schilly bus No %d (%d,%d,%d)\n", + token[ID_TOKEN_SUBSYSTEM], h, b, t, l, + first_free_schilly_bus, first_free_schilly_bus, t, l); + } + } + return (TRUE); +} + +static BOOL +sg_amapdev_scsi(SCSI *usalp, int f, int *busp, int *tgtp, int *lunp, + int *chanp, int *inop) +{ + struct sg_id { + long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */ + long l2; /* Unique id */ + } sg_id; + int Chan; + int Ino; + int Bus; + int Target; + int Lun; + + if (ioctl(f, SCSI_IOCTL_GET_IDLUN, &sg_id)) + return (FALSE); + + if (usalp->debug > 0) { + fprintf((FILE *) usalp->errfile, + "INFO: l1: 0x%lX l2: 0x%lX\n", sg_id.l1, sg_id.l2); + } + if (ioctl(f, SCSI_IOCTL_GET_BUS_NUMBER, &Bus) < 0) { + Bus = -1; + } + Target = sg_id.l1 & 0xFF; + Lun = (sg_id.l1 >> 8) & 0xFF; + Chan = (sg_id.l1 >> 16) & 0xFF; + Ino = (sg_id.l1 >> 24) & 0xFF; + if (usalp->debug > 0) { + fprintf((FILE *) usalp->errfile, + "INFO: Bus: %d Target: %d Lun: %d Chan: %d Ino: %d\n", + Bus, Target, Lun, Chan, Ino); + } + *busp = Bus; + *tgtp = Target; + *lunp = Lun; + if (chanp) + *chanp = Chan; + if (inop) + *inop = Ino; + return (TRUE); +} + +static long +usalo_amaxdma(SCSI *usalp, long amt) +{ + /* + * EINVAL (hart) ENOMEM (weich) bei mehr ... + * Bei fehlerhaftem Sense Pointer kommt EFAULT + */ + return (MAX_DMA_ATA); +} + +static BOOL +usalo_ahavebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCHILLY_HOSTS) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_afileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCHILLY_HOSTS || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int) usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_ainitiator_id(SCSI *usalp) +{ + printf(usalp->errstr, "NOT IMPELEMENTED: usalo_initiator_id"); + return (-1); +} + +static int +usalo_aisatapi(SCSI *usalp) +{ + int schillybus = usalp->addr.scsibus; + int typ = typlocal(usalp, schillybus); + if (typ == HOST_EMPTY) + return (-1); + if (typ != HOST_SCSI) + return (1); + else + return (0); +} + +static int +usalo_areset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + + if (what == SCG_RESET_TGT || what == SCG_RESET_BUS) + return (ioctl(what, CDROMRESET)); + + return (-1); +} + +static int +usalo_asend(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret, + i; + struct cdrom_generic_command sg_cgc; + struct request_sense sense_cgc; + +#ifdef DEBUG + char tmp_send[340], + tmp_read[340], + tmp_sense[340], + tmp1[30]; + int j; + char *p; +#endif + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } + if (sp->cdb_len > CDROM_PACKET_SIZE) { + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } + /* initialize */ + fillbytes((caddr_t) & sg_cgc, sizeof (sg_cgc), '\0'); + fillbytes((caddr_t) & sense_cgc, sizeof (sense_cgc), '\0'); + + if (sp->flags & SCG_RECV_DATA) { + sg_cgc.data_direction = CGC_DATA_READ; + } else if (sp->size > 0) { + sg_cgc.data_direction = CGC_DATA_WRITE; + } else { + sg_cgc.data_direction = CGC_DATA_NONE; + } +#if LINUX_VERSION_CODE >= 0x020403 + if (sp->flags & SCG_SILENT) { + sg_cgc.quiet = 1; + } +#endif + for (i = 0; i < sp->cdb_len; i++) { + sg_cgc.cmd[i] = sp->cdb.cmd_cdb[i]; + } + + sg_cgc.buflen = sp->size; + sg_cgc.buffer = (unsigned char *)sp->addr; + + if (sp->sense_len > sizeof (sense_cgc)) + sense_cgc.add_sense_len = sizeof (sense_cgc) - 8; + else + sense_cgc.add_sense_len = sp->sense_len - 8; + + sg_cgc.sense = &sense_cgc; +#if LINUX_VERSION_CODE >= 0x020403 + sg_cgc.timeout = sp->timeout * 1000; +#endif +#ifdef DEBUG + strcpy(tmp_send, "send cmd:\n"); + for (j = 0; j < sp->cdb_len; j++) { + sprintf(tmp1, " %02X", sp->cdb.cmd_cdb[j]); + strcat(tmp_send, tmp1); + } + strcat(tmp_send, "\n"); + + if (sg_cgc.data_direction == CGC_DATA_WRITE) { + int z; + + sprintf(tmp1, "data_write: %i bytes\n", sp->size); + strcat(tmp_send, tmp1); + for (j = 0, z = 1; j < 80 && j < sp->size; j++, z++) { + if (z > 16) { + z = 1; + strcat(tmp_send, "\n"); + } + sprintf(tmp1, " %02X", (unsigned char) (sp->addr[j])); + strcat(tmp_send, tmp1); + } + strcat(tmp_send, "\n"); + + if (sp->size > 80) { + strcat(tmp_send, "...\n"); + } + } +#endif /* DEBUG */ + if ((ret = ioctl(usalp->fd, CDROM_SEND_PACKET, &sg_cgc)) < 0) + sp->ux_errno = geterrno(); + + if (ret < 0 && usalp->debug > 4) { + fprintf((FILE *) usalp->errfile, + "ioctl(CDROM_SEND_PACKET) ret: %d\n", ret); + } + /* + * copy scsi data back + */ + if (sp->flags & SCG_RECV_DATA && ((void *) sp->addr != (void *) sg_cgc.buffer)) { + memcpy(sp->addr, sg_cgc.buffer, (sp->size < sg_cgc.buflen) ? sp->size : sg_cgc.buflen); + if (sg_cgc.buflen > sp->size) + sp->resid = sg_cgc.buflen - sp->size; + } + sp->error = SCG_NO_ERROR; +#ifdef DEBUG + if (ret < 0) { + switch (sp->ux_errno) { + case ENOTTY: + p = "ENOTTY"; + break; + case EINVAL: + p = "EINVAL"; + break; + case ENXIO: + p = "ENXIO"; + break; + case EACCES: + p = "EACCES"; + break; + case EIO: + p = "EIO"; + break; + case ENOMEDIUM: + p = "ENOMEDIUM"; + break; + case EDRIVE_CANT_DO_THIS: + p = "EDRIVE_CANT_DO_THIS"; + break; + default: + p = "UNKNOW"; + }; + log(("%s", tmp_send)); + log(("ERROR: returns %i errno %i(%s)\n", ret, sp->ux_errno, p)); + } +#endif /* DEBUG */ + if (ret < 0) { + /* + * Check if SCSI command cound not be send at all. + * Linux usually returns EINVAL for an unknoen ioctl. + * In case somebody from the Linux kernel team learns that the + * corect errno would be ENOTTY, we check for this errno too. + */ + if (sp->ux_errno == EINVAL) { + /* + * Try to work around broken Linux kernel design... + * If SCSI Sense Key is 0x05 (Illegal request), Linux + * returns a useless EINVAL making it close to + * impossible distinct from "Illegal ioctl()" or + * "Invalid parameter". + */ + if ((((Uchar *)sg_cgc.sense)[0] != 0) || + (((Uchar *)sg_cgc.sense)[2] != 0)) + sp->ux_errno = EIO; + + } else if ((sp->ux_errno == ENOTTY || sp->ux_errno == EINVAL)) { + /* + * May be "Illegal ioctl()". + */ + return (-1); + } + if (sp->ux_errno == ENXIO || sp->ux_errno == EACCES) { + return (-1); + } + } else if (ret == 0) { +#ifdef DEBUG + if (sg_cgc.data_direction == CGC_DATA_READ) { + int z; + + sprintf(tmp_read, "data_read: %i bytes\n", sp->size); + for (j = 0, z = 1; j < 80 && j < sp->size; j++, z++) { + if (z > 16) { + z = 1; + strcat(tmp_read, "\n"); + } + sprintf(tmp1, " %02X", (unsigned char) (sp->addr[j])); + strcat(tmp_read, tmp1); + } + strcat(tmp_read, "\n"); + if (sp->size > 80) { + strcat(tmp_read, "...\n"); + } + } +#endif /* DEBUG */ + } + /* + * copy sense back + */ + if (ret < 0 && sg_cgc.sense->error_code) { + sp->sense_count = sense_cgc.add_sense_len + 8; +#ifdef DEBUG + sprintf(tmp_sense, "sense_data: length %i\n", sp->sense_count); + for (j = 0; j < sp->sense_count; j++) { + sprintf(tmp1, " %02X", (((unsigned char *) (&sense_cgc))[j])); + strcat(tmp_sense, tmp1); + } + log(("%s\n", tmp_sense)); + + sprintf(tmp_sense, "sense_data: error code 0x%02X, sense key 0x%02X," + " additional length %i, ASC 0x%02X, ASCQ 0x%02X\n", + sg_cgc.sense->error_code, sg_cgc.sense->sense_key, + sg_cgc.sense->add_sense_len, sg_cgc.sense->asc, + sg_cgc.sense->ascq); + + log(("%s\n", tmp_sense)); +#endif /* DEBUG */ + memcpy(sp->u_sense.cmd_sense, /* (caddr_t) */ &sense_cgc, SCG_MAX_SENSE); + sp->u_scb.cmd_scb[0] = ST_CHK_COND; + + switch (sg_cgc.sense->sense_key) { + case SC_UNIT_ATTENTION: + case SC_NOT_READY: + sp->error = SCG_RETRYABLE; /* may be BUS_BUSY */ + sp->u_scb.cmd_scb[0] |= ST_BUSY; + break; + case SC_ILLEGAL_REQUEST: + break; + default: + break; + } + } else { + sp->u_scb.cmd_scb[0] = 0x00; + } + + sp->resid = 0; + return (0); +} +#endif /* USE_OLD_ATAPI */ diff --git a/libusal/scsi-linux-pg.c b/libusal/scsi-linux-pg.c new file mode 100644 index 0000000..00edf5d --- /dev/null +++ b/libusal/scsi-linux-pg.c @@ -0,0 +1,587 @@ +/* + * 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. + * + */ + +/* @(#)scsi-linux-pg.c 1.43 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the Linux PARIDE implementation. + * + * We emulate the functionality of the usal driver, via the pg driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 J. Schilling + * Copyright (c) 1998 Grant R. Guenther <grant@torque.net> + * Under the terms of the GNU public license. + */ +/* + * 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 <string.h> +#ifdef HAVE_LINUX_PG_H +#include <linux/pg.h> +#else +#include "pg.h" /* Use local version as Linux sometimes doesn't have */ +#endif /* installed. Now libusal always supports PP SCSI */ + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version_pg[] = "scsi-linux-pg.c-1.43"; /* The version for this transport*/ + +#ifdef USE_PG_ONLY + +#define MAX_SCG 1 /* Max # of SCSI controllers */ +#define MAX_TGT 8 +#define MAX_LUN 8 + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; + short buscookies[MAX_SCG]; + int pgbus; + char *SCSIbuf; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#else + +#define usalo_version pg_version +#define usalo_help pg_help +#define usalo_open pg_open +#define usalo_close pg_close +#define usalo_send pg_send +#define usalo_maxdma pg_maxdma +#define usalo_initiator_id pg_initiator_id +#define usalo_isatapi pg_isatapi +#define usalo_reset pg_reset + +static char *pg_version(SCSI *usalp, int what); +static int pg_help(SCSI *usalp, FILE *f); +static int pg_open(SCSI *usalp, char *device); +static int pg_close(SCSI *usalp); +static long pg_maxdma(SCSI *usalp, long amt); +static int pg_initiator_id(SCSI *usalp); +static int pg_isatapi(SCSI *usalp); +static int pg_reset(SCSI *usalp, int what); +static int pg_send(SCSI *usalp); + +#endif + +static int do_usal_cmd(SCSI *usalp, struct usal_cmd *sp); +static int do_usal_sense(SCSI *usalp, struct usal_cmd *sp); + + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version_pg); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (___sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "pg", "SCSI transport for ATAPI over Parallel Port", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; +#ifdef USE_PG_ONLY + register int t; + register int l; +#endif + register int nopen = 0; + char devname[32]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + +#ifndef USE_PG_ONLY + /* + * We need to find a fake bus number for the parallel port interface. + * Unfortunatly, the buscookie array may contain holes if + * SCSI_IOCTL_GET_BUS_NUMBER works, so we are searching backwards + * for some place for us. + * XXX Should add extra space in buscookies for a "PP bus". + */ + + if (usallocal(usalp)->buscookies[MAX_SCG-1] != (short)-1) + return (0); /* No space for pgbus */ + + for (b = MAX_SCG-1; b >= 0; b--) { + if (usallocal(usalp)->buscookies[b] != (short)-1) { + usallocal(usalp)->pgbus = ++b; + break; + } + } + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "PP Bus: %d\n", usallocal(usalp)->pgbus); + } +#else + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + usallocal(usalp)->pgbus = -2; + usallocal(usalp)->SCSIbuf = (char *)-1; + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } +#endif + if (usallocal(usalp)->pgbus < 0) + usallocal(usalp)->pgbus = 0; + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) + goto openbydev; + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { +#ifndef USE_PG_ONLY + if (usallocal(usalp)->pgbus != busno) + return (0); +#endif + snprintf(devname, sizeof (devname), "/dev/pg%d", tgt); + f = sg_open_excl(devname, O_RDWR | O_NONBLOCK); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", devname); + return (0); + } + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; + return (1); + } else { + tlun = 0; + for (tgt = 0; tgt < MAX_TGT; tgt++) { + snprintf(devname, sizeof (devname), "/dev/pg%d", tgt); + f = sg_open_excl(devname, O_RDWR | O_NONBLOCK); + if (f < 0) { + /* + * Set up error string but let us clear it later + * if at least one open succeeded. + */ + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '/dev/pg*'"); + if (errno != ENOENT && errno != ENXIO && errno != ENODEV) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", devname); + return (0); + } + } else { + usallocal(usalp)->usalfiles[usallocal(usalp)->pgbus][tgt][tlun] = f; + nopen++; + } + } + } + if (nopen > 0 && usalp->errstr) + usalp->errstr[0] = '\0'; + +openbydev: + if (device != NULL && *device != '\0') { + char *p; + + if (tlun < 0) + return (0); + f = open(device, O_RDWR | O_NONBLOCK); +/* if (f < 0 && errno == ENOENT) {*/ + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + device); + return (0); + } + + p = device + strlen(device) -1; + tgt = *p - '0'; + if (tgt < 0 || tgt > 9) + return (0); + usallocal(usalp)->usalfiles[usallocal(usalp)->pgbus][tgt][tlun] = f; + usal_settarget(usalp, usallocal(usalp)->pgbus, tgt, tlun); + + return (++nopen); + } + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + if (usallocal(usalp)->pgbus < 0) + return (0); + b = usallocal(usalp)->pgbus; + usallocal(usalp)->buscookies[b] = (short)-1; + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (PG_MAX_DATA); +} + +#ifdef USE_PG_ONLY + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + char *ret; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + ret = valloc((size_t)(amt+getpagesize())); + if (ret == NULL) + return (ret); + usalp->bufbase = ret; + ret += getpagesize(); + usallocal(usalp)->SCSIbuf = ret; + return ((void *)ret); + +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} +#endif /* USE_PG_ONLY */ + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (TRUE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + struct pg_write_hdr hdr = {PG_MAGIC, PG_RESET, 0}; + + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + /* + * XXX Does this reset TGT or BUS ??? + */ + return (write(usalp->fd, (char *)&hdr, sizeof (hdr))); + +} + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a):(b)) +#endif + +#define RHSIZE sizeof (struct pg_read_hdr) +#define WHSIZE sizeof (struct pg_write_hdr) +#define LEAD MAX(RHSIZE, WHSIZE) + +static int +do_usal_cmd(SCSI *usalp, struct usal_cmd *sp) +{ + + char local[LEAD+PG_MAX_DATA]; + int use_local, i, r; + int inward = (sp->flags & SCG_RECV_DATA); + + struct pg_write_hdr *whp; + struct pg_read_hdr *rhp; + char *dbp; + + if (sp->cdb_len > 12) + comerrno(EX_BAD, "Can't do %d byte command.\n", sp->cdb_len); + + if (sp->addr == usallocal(usalp)->SCSIbuf) { + use_local = 0; + dbp = sp->addr; + } else { + use_local = 1; + dbp = &local[LEAD]; + if (!inward) + movebytes(sp->addr, dbp, sp->size); + } + + whp = (struct pg_write_hdr *)(dbp - WHSIZE); + rhp = (struct pg_read_hdr *)(dbp - RHSIZE); + + whp->magic = PG_MAGIC; + whp->func = PG_COMMAND; + whp->dlen = sp->size; + whp->timeout = sp->timeout; + + for (i = 0; i < 12; i++) { + if (i < sp->cdb_len) + whp->packet[i] = sp->cdb.cmd_cdb[i]; + else + whp->packet[i] = 0; + } + + i = WHSIZE; + if (!inward) + i += sp->size; + + r = write(usalp->fd, (char *)whp, i); + + if (r < 0) { /* command was not sent */ + sp->ux_errno = geterrno(); + if (sp->ux_errno == ETIME) { + /* + * If the previous command timed out, we cannot send + * any further command until the command in the drive + * is ready. So we behave as if the drive did not + * respond to the command. + */ + sp->error = SCG_FATAL; + return (0); + } + return (-1); + } + + if (r != i) + errmsg("usalo_send(%s) wrote %d bytes (expected %d).\n", + usalp->cmdname, r, i); + + sp->ux_errno = 0; + sp->sense_count = 0; + + r = read(usalp->fd, (char *)rhp, RHSIZE+sp->size); + + if (r < 0) { + sp->ux_errno = geterrno(); + if (sp->ux_errno == ETIME) { + sp->error = SCG_TIMEOUT; + return (0); + } + sp->error = SCG_FATAL; + return (-1); + } + + i = rhp->dlen; + if (i > sp->size) { + /* + * "DMA overrun" should be handled in the kernel. + * However this may happen with flaky PP adapters. + */ + errmsgno(EX_BAD, + "DMA (read) overrun by %d bytes (requested %d bytes).\n", + i - sp->size, sp->size); + sp->resid = sp->size - i; + sp->error = SCG_RETRYABLE; + i = sp->size; + } else { + sp->resid = sp->size - i; + } + + if (use_local && inward) + movebytes(dbp, sp->addr, i); + + fillbytes(&sp->scb, sizeof (sp->scb), '\0'); + fillbytes(&sp->u_sense.cmd_sense, sizeof (sp->u_sense.cmd_sense), '\0'); + + sp->error = SCG_NO_ERROR; + i = rhp->scsi?2:0; +/* i = rhp->scsi;*/ + sp->u_scb.cmd_scb[0] = i; + if (i & 2) { + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + /* + * If there is no DMA overrun and there is a + * SCSI Status byte != 0 then the SCSI cdb transport was OK + * and sp->error must be SCG_NO_ERROR. + */ +/* sp->error = SCG_RETRYABLE;*/ + } + + return (0); + +} + +static int +do_usal_sense(SCSI *usalp, struct usal_cmd *sp) +{ + int ret; + struct usal_cmd s_cmd; + + fillbytes((caddr_t)&s_cmd, sizeof (s_cmd), '\0'); + s_cmd.addr = (caddr_t)sp->u_sense.cmd_sense; + s_cmd.size = sp->sense_len; + s_cmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA; + s_cmd.cdb_len = SC_G0_CDBLEN; + s_cmd.sense_len = CCS_SENSE_LEN; + s_cmd.cdb.g0_cdb.cmd = SC_REQUEST_SENSE; + s_cmd.cdb.g0_cdb.lun = sp->cdb.g0_cdb.lun; + s_cmd.cdb.g0_cdb.count = sp->sense_len; + ret = do_usal_cmd(usalp, &s_cmd); + + if (ret < 0) + return (ret); + + sp->sense_count = sp->sense_len - s_cmd.resid; + return (ret); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + ret = do_usal_cmd(usalp, sp); + if (ret < 0) + return (ret); + if (sp->u_scb.cmd_scb[0] & 2) + ret = do_usal_sense(usalp, sp); + return (ret); +} + +/* end of scsi-linux-pg.c */ + +#ifndef USE_PG_ONLY + +#undef usalo_version +#undef usalo_help +#undef usalo_open +#undef usalo_close +#undef usalo_send +#undef usalo_maxdma +#undef usalo_initiator_id +#undef usalo_isatapi +#undef usalo_reset + +#endif diff --git a/libusal/scsi-linux-sg.c b/libusal/scsi-linux-sg.c new file mode 100644 index 0000000..81d33d4 --- /dev/null +++ b/libusal/scsi-linux-sg.c @@ -0,0 +1,1754 @@ +/* + * 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. + * + */ + +/* @(#)scsi-linux-sg.c 1.86 05/11/22 Copyright 1997 J. Schilling */ +/* + * Interface for Linux generic SCSI implementation (sg). + * + * This is the interface for the broken Linux SCSI generic driver. + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * Design flaws of the sg driver: + * - cannot see if SCSI command could not be send + * - cannot get SCSI status byte + * - cannot get real dma count of tranfer + * - cannot get number of bytes valid in auto sense data + * - to few data in auto sense (CCS/SCSI-2/SCSI-3 needs >= 18) + * + * This code contains support for the sg driver version 2 by + * H. Eißfeld & J. Schilling + * Although this enhanced version has been announced to Linus and Alan, + * there was no reaction at all. + * + * About half a year later there occured a version in the official + * Linux that was also called version 2. The interface of this version + * looks like a playground - the enhancements from this version are + * more or less useless for a portable real-world program. + * + * With Linux 2.4 the official version of the sg driver is called 3.x + * and seems to be usable again. The main problem now is the curious + * interface that is provided to raise the DMA limit from 32 kB to a + * more reasonable value. To do this in a reliable way, a lot of actions + * are required. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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 <linux/version.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/utsname.h> + +#ifndef LINUX_VERSION_CODE /* Very old kernel? */ +# define LINUX_VERSION_CODE 0 +#endif + +#if LINUX_VERSION_CODE >= 0x01031a /* <linux/scsi.h> introduced in 1.3.26 */ +#if LINUX_VERSION_CODE >= 0x020000 /* <scsi/scsi.h> introduced somewhere. */ +/* Need to fine tune the ifdef so we get the transition point right. */ +#include <scsi/scsi.h> +#else +#include <linux/scsi.h> +#endif +#else /* LINUX_VERSION_CODE == 0 Very old kernel? */ +#define __KERNEL__ /* Some Linux Include files are inconsistent */ +#include <linux/fs.h> /* From ancient versions, really needed? */ +#undef __KERNEL__ +#include "block/blk.h" /* From ancient versions, really needed? */ +#include "scsi/scsi.h" +#endif + +#if defined(HAVE_BROKEN_SCSI_SG_H) || \ + defined(HAVE_BROKEN_SRC_SCSI_SG_H) +/* + * Be very careful in case that the Linux Kernel maintainers + * unexpectedly fix the bugs in the Linux Lernel include files. + * Only introduce the attempt for a workaround in case the include + * files are broken anyway. + */ +#define __user +#endif +#include "scsi/sg.h" +#if defined(HAVE_BROKEN_SCSI_SG_H) || \ + defined(HAVE_BROKEN_SRC_SCSI_SG_H) +#undef __user +#endif + +#undef sense /* conflict in struct cdrom_generic_command */ +#include <linux/cdrom.h> + +#if defined(CDROM_PACKET_SIZE) && defined(CDROM_SEND_PACKET) +#define USE_OLD_ATAPI +#endif + +#include <glob.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-linux-sg.c-1.86"; /* The version for this transport*/ + +#ifndef SCSI_IOCTL_GET_BUS_NUMBER +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 +#endif + +/* + * XXX There must be a better way than duplicating things from system include + * XXX files. This is stolen from /usr/src/linux/drivers/scsi/scsi.h + */ +#ifndef DID_OK +#define DID_OK 0x00 /* NO error */ +#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */ +#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */ +#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */ +#define DID_BAD_TARGET 0x04 /* BAD target. */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody. */ +#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */ +#endif + +/* + * These indicate the error that occurred, and what is available. + */ +#ifndef DRIVER_BUSY +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 + +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 +#endif + +/* + * XXX Should add extra space in buscookies and usalfiles for a "PP bus" + * XXX and for two or more "ATAPI busses". + */ +#define MAX_SCG 1256 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +#ifdef USE_OLD_ATAPI +/* + * # of virtual buses (schilly_host number) + */ +#define MAX_SCHILLY_HOSTS MAX_SCG +typedef struct { + Uchar typ:4; + Uchar bus:4; + Uchar host:8; +} ata_buscookies; +#endif + +struct usal_local { + int usalfile; /* Used for SG_GET_BUFSIZE ioctl()*/ + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; + char *filenames[MAX_SCG][MAX_TGT][MAX_LUN]; + short buscookies[MAX_SCG]; + int pgbus; + int pack_id; /* Should be a random number */ + int drvers; + short isold; + short flags; + long xbufsize; + char *xbuf; + char *SCSIbuf; +#ifdef USE_OLD_ATAPI + ata_buscookies bc[MAX_SCHILLY_HOSTS]; +#endif +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +/* + * Flag definitions + */ + +#ifdef SG_BIG_BUFF +#define MAX_DMA_LINUX SG_BIG_BUFF /* Defined in include/scsi/sg.h */ +#else +#define MAX_DMA_LINUX (4*1024) /* Old Linux versions */ +#endif + +#ifndef SG_MAX_SENSE +# define SG_MAX_SENSE 16 /* Too small for CCS / SCSI-2 */ +#endif /* But cannot be changed */ + +#if !defined(__i386) && !defined(i386) && !defined(mc68000) +#define MISALIGN +#endif +/*#define MISALIGN*/ +/*#undef SG_GET_BUFSIZE*/ + + +#ifdef MISALIGN +static int sg_getint(int *ip); +#endif +static int usalo_send(SCSI *usalp); +#ifdef SG_IO +static int sg_rwsend(SCSI *usalp); +#endif +static void sg_clearnblock(int f); +static BOOL sg_setup(SCSI *usalp, int f, int busno, int tgt, int tlun, + int ataidx, char *origname); +static void sg_initdev(SCSI *usalp, int f); +static int sg_mapbus(SCSI *usalp, int busno, int ino); +static BOOL sg_mapdev(SCSI *usalp, int f, int *busp, int *tgtp, int *lunp, + int *chanp, int *inop, int ataidx); +#if defined(SG_SET_RESERVED_SIZE) && defined(SG_GET_RESERVED_SIZE) +static long sg_raisedma(SCSI *usalp, long newmax); +#endif +static void sg_settimeout(int f, int timeout); + +int sg_open_excl(char *device, int mode, BOOL beQuiet); + +static BOOL get_max_secs(char *dirpath, int *outval); + +#if defined(USE_PG) && !defined(USE_PG_ONLY) +#include "scsi-linux-pg.c" +#endif +#ifdef USE_OLD_ATAPI +#include "scsi-linux-ata.c" +#endif + +BOOL check_linux_26() { + int gen, tmp; + struct utsname buf; + return ( 0==uname( &buf ) && sscanf(buf.release, "%d.%d", &gen, &tmp)>1 && tmp>=6); +} + +int sg_open_excl(char *device, int mode, BOOL beQuiet) +{ + int f; + int i=0; + long interval = beQuiet ? 400000 : 1000000; + + f = open(device, mode|O_EXCL); + /* try to reopen locked/busy devices up to five times */ + for (i = 0; (i < 5) && (f == -1 && errno == EBUSY); i++) { + if(!beQuiet) + fprintf(stderr, "Error trying to open %s exclusively (%s)... %s\n", + device, strerror(errno), + (i<4)?"retrying in 1 second.":"giving up."); + usleep(interval + interval * rand()/(RAND_MAX+1.0)); + f = open(device, mode|O_EXCL); + } + if(i==5 && !beQuiet) { + FILE *g = fopen("/proc/mounts", "r"); + if(g) { + char buf[80]; + unsigned int len=strlen(device); + while(!feof(g) && !ferror(g)) { + if(fgets(buf, 79, g) && 0==strncmp(device, buf, len)) { + fprintf(stderr, "WARNING: %s seems to be mounted!\n", device); + } + } + fclose(g); + } + } + return f; +} + +#if 0 +// Dead code, that sysfs parts may become deprecated soon +void map_sg_to_block(char *device, int len) { + char globpat[100]; + glob_t globbuf; + snprintf(globpat, 100, "/sys/class/scsi_generic/%s/device/block:*", device+5); + memset(&globbuf, 0, sizeof(glob_t)); + if(0==glob(globpat, GLOB_DOOFFS | GLOB_NOSORT, NULL, &globbuf)) { + char *p = strrchr(globbuf.gl_pathv[0], ':'); + if(p) snprintf(device, len, "/dev/%s", p+1); + } + globfree(&globbuf); +} +#endif + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { +#ifdef USE_PG +#error pg-junk + /* + * If we only have a Parallel port or only opened a handle + * for PP, just return PP version. + */ + if (usallocal(usalp)->pgbus == 0 || + (usal_scsibus(usalp) >= 0 && + usal_scsibus(usalp) == usallocal(usalp)->pgbus)) + return (pg_version(usalp, what)); +#endif + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + case SCG_KVERSION: + { + static char kv[16]; + int n; + + if (usallocal(usalp)->drvers >= 0) { + n = usallocal(usalp)->drvers; + snprintf(kv, sizeof (kv), + "%d.%d.%d", + n/10000, (n%10000)/100, n%100); + + return (kv); + } + } + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "sg", "Generic transport independent SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); +#ifdef USE_PG + pg_help(usalp, f); +#endif +#ifdef USE_OLD_ATAPI + usalo_ahelp(usalp, f); +#endif + __usal_help(f, "ATA", "ATA Packet specific SCSI transport using sg interface", + "ATA:", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +#define in_scanmode (busno < 0 && tgt < 0 && tlun < 0) + +/* + * b/t/l is chopped of the device string. + */ +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int i; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[64]; + int fake_atabus=0; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + struct stat statbuf; + if(check_linux_26() && 0!=stat("/sys/kernel", &statbuf)) { + static int warn_sysfs=1; + if(warn_sysfs) { + warn_sysfs=0; + fprintf(stderr, "\nWarning, sysfs is not mounted on /sys!\n" + "It is recommended to mount sysfs to allow better device configuration\n"); + sleep(5); + } + } + + if (device != NULL && *device != '\0') { + fake_atabus=0; + if(0==strncmp(device, "OLDATAPI", 8)) { + device+=3; + usalp->ops = &ata_ops; + return (SCGO_OPEN(usalp, device)); + } + else if(0==strncmp(device, "ATAPI", 5)) { + if(check_linux_26()) { + device+=5; + fake_atabus=1; + fprintf(stderr, "WARNING: the ATAPI: method is considered deprecated on modern kernels!\n" + "Mapping device specification to ATA: method now.\n" + "To force the old ATAPI: method, replace ATAPI: with OLDATAPI:\n"); + } + else { + usalp->ops = &ata_ops; + return (SCGO_OPEN(usalp, device)); + } + } + else if(0==strncmp(device, "ATA", 3)) { + fprintf(stderr, "WARNING: the ATA: method is considered deprecated on modern kernels!\n" + "Use --devices to display the native names.\n"); + fake_atabus=1; + device+=3; + } + if(device[0]==':') + device++; + + } + else if( ! in_scanmode ) { + fprintf(stderr, "WARNING: the deprecated pseudo SCSI syntax found as device specification.\n" + "Support for that may cease in the future versions of wodim. For now,\n" + "the device will be mapped to a block device file where possible.\n" + "Run \"wodim --devices\" for details.\n" ); + sleep(5); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + usallocal(usalp)->usalfile = -1; + usallocal(usalp)->pgbus = -2; + usallocal(usalp)->SCSIbuf = (char *)-1; + usallocal(usalp)->pack_id = 5; + usallocal(usalp)->drvers = -1; + usallocal(usalp)->isold = -1; + usallocal(usalp)->flags = 0; + usallocal(usalp)->xbufsize = 0L; + usallocal(usalp)->xbuf = NULL; + + for (b = 0; b < MAX_SCG; b++) { + usallocal(usalp)->buscookies[b] = (short)-1; + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + usallocal(usalp)->filenames[b][t][l] = NULL; + } + } + } + } + + if (device != NULL && *device != '\0') + { + /* open ONE directly */ + b = -1; + if (device && strncmp(device, "/dev/hd", 7) == 0 && device[8]=='\0') { + b = device[7] - 'a'; + if (b < 0 || b > 25) + b = -1; + } + if(b>=0 && fake_atabus) + b+=1000; + + f = sg_open_excl(device, O_RDWR | O_NONBLOCK, FALSE); + + if (f < 0) { + /* + * The pg driver has the same rules to decide whether + * to use openbydev. If we cannot open the device, it + * makes no sense to try the /dev/pg* driver. + */ + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + device); + return (0); + } + sg_clearnblock(f); + /* get some fake SCSI data */ + sg_mapdev(usalp, f, &busno, &tgt, &tlun, 0, 0, b); + usal_settarget(usalp, busno, tgt, tlun); + if (sg_setup(usalp, f, busno, tgt, tlun, b, device)) + return (++nopen); + } + else { + /* scan and maybe keep one open, sg_setup decides */ +#define HDX 0 +#define SCD 1 +#define SG 2 + int h; +/* +retry_scan_open: +*/ + for(h=HDX; h <= (fake_atabus ? HDX : SG) ; h++) { + char *pattern = NULL; + unsigned int first = 0, last = 0; + switch(h) { + case(HDX): + { + pattern="/dev/hd%c"; + first='a'; + last='z'; + break; + } + case(SCD): + { + if(!check_linux_26()) + continue; + pattern="/dev/scd%d"; + first=0; + last=255; + break; + } + case(SG): + { + if(check_linux_26()) + continue; +#if 0 + /* + * Don't touch it on 2.6 until we have a proper locking scheme + */ + if(nopen<=0) + fprintf(stderr, "Warning, using /dev/sg* for SG_IO operation. This method is considered harmful.\n"); + else if(found_scd) + continue; +#endif + pattern="/dev/sg%d"; + first=0; + last=255; + break; + } + } + for(i=first; i<=last; i++) { + snprintf(devname, sizeof (devname), pattern, i); + f = sg_open_excl(devname, O_RDWR | O_NONBLOCK, in_scanmode); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", devname); + } else { + if(h == HDX) { // double-check the capabilities on ATAPI devices + int iparm; + + if (ioctl(f, SG_GET_TIMEOUT, &iparm) < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "SCSI unsupported with '%s'", devname); + close(f); + continue; + } + } + sg_clearnblock(f); /* Be very proper about this */ + + /* construct the fake bus number hint, keep it readable */ + b=-1; + if(h==HDX) { + b=i-'a'; + if(!fake_atabus) + b+=1000; + } + + /* sg_setup returns false in scan mode, true if one single target was specified and opened */ + if (sg_setup(usalp, f, busno, tgt, tlun, b, devname)) + return (++nopen); + + if (in_scanmode) + nopen++; + } + } + + if (nopen > 0 && usalp->errstr) + usalp->errstr[0] = '\0'; + + /* that's crap, should not be reached in non-scan mode. + * Let's see whether it can be mapped to an atapi + * device to emulate some old cludge's behaviour. + if(!in_scanmode && busno < 1000 && busno >=0) { + fake_atabus=1; + fprintf(stderr, "Unable to open this SCSI ID. Trying to map to old ATA syntax." + "This workaround will disappear in the near future. Fix your configuration."); + goto retry_scan_open; + } + */ + } + } + + if (usalp->debug > 0) for (b = 0; b < MAX_SCG; b++) { + fprintf((FILE *)usalp->errfile, + "Bus: %d cookie: %X\n", + b, usallocal(usalp)->buscookies[b]); + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + if (usallocal(usalp)->usalfiles[b][t][l] != (short)-1) { + fprintf((FILE *)usalp->errfile, + "file (%d,%d,%d): %d\n", + b, t, l, usallocal(usalp)->usalfiles[b][t][l]); + } + } + } + } + + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + if (b == usallocal(usalp)->pgbus) + continue; + usallocal(usalp)->buscookies[b] = (short)-1; + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + if(usallocal(usalp)->filenames[b][t][l]) { + free(usallocal(usalp)->filenames[b][t][l]); + usallocal(usalp)->filenames[b][t][l]=NULL; + } + } + } + } + if (usallocal(usalp)->xbuf != NULL) { + free(usallocal(usalp)->xbuf); + usallocal(usalp)->xbufsize = 0L; + usallocal(usalp)->xbuf = NULL; + } +#ifdef USE_PG + pg_close(usalp); +#endif + return (0); +} + +/* + * The Linux kernel becomes more and more unmaintainable. + * Every year, a new incompatible SCSI transport interface is added. + * Each of them has it's own contradictory constraints. + * While you cannot have O_NONBLOCK set during operation, at least one + * of the drivers requires O_NONBLOCK to be set during open(). + * This is used to clear O_NONBLOCK immediately after open() succeeded. + */ +static void +sg_clearnblock(int f) +{ + int n; + + n = fcntl(f, F_GETFL); + n &= ~O_NONBLOCK; + fcntl(f, F_SETFL, n); +} + +/*! + * + * Return: TRUE when single target is chosen and was opened successfully, FALSE otherwise (on scans, etc). + */ + +static BOOL +sg_setup(SCSI *usalp, int f, int busno, int tgt, int tlun, int ataidx, char *origname) +{ + int n; + int Chan; + int Ino; + int Bus; + int Target; + int Lun; + BOOL onetarget = FALSE; + +#ifdef SG_GET_VERSION_NUM + if (usallocal(usalp)->drvers < 0) { + usallocal(usalp)->drvers = 0; + if (ioctl(f, SG_GET_VERSION_NUM, &n) >= 0) { + usallocal(usalp)->drvers = n; + if (usalp->overbose) { + fprintf((FILE *)usalp->errfile, + "Linux sg driver version: %d.%d.%d\n", + n/10000, (n%10000)/100, n%100); + } + } + } +#endif + if (usal_scsibus(usalp) >= 0 && usal_target(usalp) >= 0 && usal_lun(usalp) >= 0) + onetarget = TRUE; + + sg_mapdev(usalp, f, &Bus, &Target, &Lun, &Chan, &Ino, ataidx); + /* + * For old kernels try to make the best guess. + */ + Ino |= Chan << 8; + n = sg_mapbus(usalp, Bus, Ino); + if (Bus == -1) { + Bus = n; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "SCSI Bus: %d (mapped from %d)\n", Bus, Ino); + } + } + + if (Bus < 0 || Bus >= MAX_SCG || Target < 0 || Target >= MAX_TGT || + Lun < 0 || Lun >= MAX_LUN) { + return (FALSE); + } + + if (usallocal(usalp)->usalfiles[Bus][Target][Lun] == (short)-1) + usallocal(usalp)->usalfiles[Bus][Target][Lun] = (short)f; + + if (usallocal(usalp)->filenames[Bus][Target][Lun] == NULL) + usallocal(usalp)->filenames[Bus][Target][Lun] = strdup(origname); + + if (onetarget) { + if (Bus == busno && Target == tgt && Lun == tlun) { + sg_initdev(usalp, f); + usallocal(usalp)->usalfile = f; /* remember file for ioctl's */ + return (TRUE); + } else { + usallocal(usalp)->usalfiles[Bus][Target][Lun] = (short)-1; + close(f); + } + } else { + /* + * SCSI bus scanning may cause other generic SCSI activities to + * fail because we set the default timeout and clear command + * queues (in case of the old sg driver interface). + */ + sg_initdev(usalp, f); + if (usallocal(usalp)->usalfile < 0) + usallocal(usalp)->usalfile = f; /* remember file for ioctl's */ + } + return (FALSE); +} + +static void +sg_initdev(SCSI *usalp, int f) +{ + struct sg_rep { + struct sg_header hd; + unsigned char rbuf[100]; + } sg_rep; + int n; + int i; + struct stat sb; + + sg_settimeout(f, usalp->deftimeout); + + /* + * If it's a block device, don't read.... pre Linux-2.4 /dev/sg* + * definitely is a character device and we only need to clear the + * queue for old /dev/sg* versions. If somebody ever implements + * raw disk access for Linux, this test may fail. + */ + if (fstat(f, &sb) >= 0 && S_ISBLK(sb.st_mode)) + return; + + /* Eat any unwanted garbage from prior use of this device */ + + n = fcntl(f, F_GETFL); /* Be very proper about this */ + fcntl(f, F_SETFL, n|O_NONBLOCK); + + fillbytes((caddr_t)&sg_rep, sizeof (struct sg_header), '\0'); + sg_rep.hd.reply_len = sizeof (struct sg_header); + + /* + * This is really ugly. + * We come here if 'f' is related to a raw device. If Linux + * will ever have raw devices for /dev/hd* we may get problems. + * As long as there is no clean way to find out whether the + * filedescriptor 'f' is related to an old /dev/sg* or to + * /dev/hd*, we must assume that we found an old /dev/sg* and + * clean it up. Unfortunately, reading from /dev/hd* will + * Access the medium. + */ + for (i = 0; i < 1000; i++) { /* Read at least 32k from /dev/sg* */ + int ret; + + ret = read(f, &sg_rep, sizeof (struct sg_rep)); + if (ret > 0) + continue; + if (ret == 0 || errno == EAGAIN || errno == EIO) + break; + if (ret < 0 && i > 10) /* Stop on repeated unknown error */ + break; + } + fcntl(f, F_SETFL, n); +} + +static int +sg_mapbus(SCSI *usalp, int busno, int ino) +{ + register int i; + + if (busno >= 0 && busno < MAX_SCG) { + /* + * SCSI_IOCTL_GET_BUS_NUMBER worked. + * Now we have the problem that Linux does not properly number + * SCSI busses. The Bus number that Linux creates really is + * the controller (card) number. I case of multi SCSI bus + * cards we are lost. + */ + if (usallocal(usalp)->buscookies[busno] == (short)-1) { + usallocal(usalp)->buscookies[busno] = ino; + return (busno); + } + /* + * if (usallocal(usalp)->buscookies[busno] != (short)ino) + errmsgno(EX_BAD, "Warning Linux Bus mapping botch.\n"); + */ + return (busno); + + } else for (i = 0; i < MAX_SCG; i++) { + if (usallocal(usalp)->buscookies[i] == (short)-1) { + usallocal(usalp)->buscookies[i] = ino; + return (i); + } + + if (usallocal(usalp)->buscookies[i] == ino) + return (i); + } + return (0); +} + +static BOOL +sg_mapdev(SCSI *usalp, int f, int *busp, int *tgtp, int *lunp, int *chanp, + int *inop, int ataidx) +{ + struct sg_id { + long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */ + long l2; /* Unique id */ + } sg_id; + int Chan; + int Ino; + int Bus; + int Target; + int Lun; + + if (ataidx >= 0) { + /* + * The badly designed /dev/hd* interface maps everything + * to 0,0,0 so we need to do the mapping ourselves. + */ + *busp = (ataidx/1000) * 1000; + *tgtp = ataidx%1000; + *lunp = 0; + if (chanp) + *chanp = 0; + if (inop) + *inop = 0; + return (TRUE); + } + if (ioctl(f, SCSI_IOCTL_GET_IDLUN, &sg_id)) + return (FALSE); + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "l1: 0x%lX l2: 0x%lX\n", sg_id.l1, sg_id.l2); + } + if (ioctl(f, SCSI_IOCTL_GET_BUS_NUMBER, &Bus) < 0) { + Bus = -1; + } + + Target = sg_id.l1 & 0xFF; + Lun = (sg_id.l1 >> 8) & 0xFF; + Chan = (sg_id.l1 >> 16) & 0xFF; + Ino = (sg_id.l1 >> 24) & 0xFF; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Bus: %d Target: %d Lun: %d Chan: %d Ino: %d\n", + Bus, Target, Lun, Chan, Ino); + } + *busp = Bus; + *tgtp = Target; + *lunp = Lun; + if (chanp) + *chanp = Chan; + if (inop) + *inop = Ino; + return (TRUE); +} + +#if defined(SG_SET_RESERVED_SIZE) && defined(SG_GET_RESERVED_SIZE) +/* + * The way Linux does DMA resouce management is a bit curious. + * It totally deviates from all other OS and forces long ugly code. + * If we are opening all drivers for a SCSI bus scan operation, we need + * to set the limit for all open devices. + * This may use up all kernel memory ... so do the job carefully. + * + * A big problem is that SG_SET_RESERVED_SIZE does not return any hint + * on whether the request did fail. The only way to find if it worked + * is to use SG_GET_RESERVED_SIZE to read back the current values. + */ +static long +sg_raisedma(SCSI *usalp, long newmax) +{ + register int b; + register int t; + register int l; + register int f; + int val; + int old; + + /* + * First try to raise the DMA limit to a moderate value that + * most likely does not use up all kernel memory. + */ + val = 126*1024; + + if (val > MAX_DMA_LINUX) { + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + if ((f = SCGO_FILENO(usalp, b, t, l)) < 0) + continue; + old = 0; + if (ioctl(f, SG_GET_RESERVED_SIZE, &old) < 0) + continue; + if (val > old) + ioctl(f, SG_SET_RESERVED_SIZE, &val); + } + } + } + } + + /* + * Now to raise the DMA limit to what we really need. + */ + if (newmax > val) { + val = newmax; + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + if ((f = SCGO_FILENO(usalp, b, t, l)) < 0) + continue; + old = 0; + if (ioctl(f, SG_GET_RESERVED_SIZE, &old) < 0) + continue; + if (val > old) + ioctl(f, SG_SET_RESERVED_SIZE, &val); + } + } + } + } + + /* + * To make sure we did not fail (the ioctl does not report errors) + * we need to check the DMA limits. We return the smallest value. + */ + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + if ((f = SCGO_FILENO(usalp, b, t, l)) < 0) + continue; + if (ioctl(f, SG_GET_RESERVED_SIZE, &val) < 0) + continue; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Target (%d,%d,%d): DMA max %d old max: %ld\n", + b, t, l, val, newmax); + } + if (val < newmax) + newmax = val; + } + } + } + return ((long)newmax); +} +#endif + +static char *freadstring(char *fn, char *out, int len) { + char *ret; + FILE *fd=fopen(fn, "r"); + out[0]='\0'; + if(!fd) return NULL; + ret = fgets(out, len, fd); + fclose(fd); + return ret; +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + struct stat stbuf; + long maxdma = MAX_DMA_LINUX; + +#if defined(SG_SET_RESERVED_SIZE) && defined(SG_GET_RESERVED_SIZE) + /* + * Use the curious new kernel interface found on Linux >= 2.2.10 + * This interface first appeared in 2.2.6 but it was not working. + */ + if (usallocal(usalp)->drvers >= 20134) + maxdma = sg_raisedma(usalp, amt); +#endif + /* + * First try the modern kernel 2.6.1x way to detect the real maximum + * DMA for this specific device, then try the other methods. + */ + if(0==fstat(usallocal(usalp)->usalfile, &stbuf)) { + /* that's ugly, there are so many symlinks in sysfs but none from + * major:minor to the relevant directory */ + long int major, minor, i; + major=stbuf.st_rdev>>8; + minor=stbuf.st_rdev&0xFF; + if (usalp->debug > 0) + fprintf(stderr, "Looking for data for major:minor: %ld:%ld\n", major, minor); + glob_t globbuf; + memset(&globbuf, 0, sizeof(glob_t)); + /* *dev files contain the major:minor strings to compare */ + glob("/sys/class/scsi_generic/*/device/block*/queue/max_sectors_kb", GLOB_DOOFFS | GLOB_NOSORT, NULL, &globbuf); + glob("/sys/block/*/device/block*/queue/max_sectors_kb", GLOB_DOOFFS | GLOB_NOSORT | GLOB_APPEND, NULL, &globbuf); + for(i=0;i<globbuf.gl_pathc; i++) { + char *cut, *ende; + char buf[64]; + cut=strstr(globbuf.gl_pathv[i], "/device/")+4; + *cut='\0'; + freadstring(globbuf.gl_pathv[i], buf, sizeof(buf)); + if(strtol(buf, &ende, 10) == major && ende && atoi(ende) == minor) { + *cut='i'; + freadstring(globbuf.gl_pathv[i], buf, sizeof(buf)); + return(1024*atoi(buf)); + } + + } + globfree(&globbuf); + } +#ifdef SG_GET_BUFSIZE + /* + * We assume that all /dev/sg instances use the same + * maximum buffer size. + */ + maxdma = ioctl(usallocal(usalp)->usalfile, SG_GET_BUFSIZE, 0); +#endif + if (maxdma < 0) { +#ifdef USE_PG + /* + * If we only have a Parallel port, just return PP maxdma. + */ + if (usallocal(usalp)->pgbus == 0) + return (pg_maxdma(usalp, amt)); +#endif + if (usallocal(usalp)->usalfile >= 0) + maxdma = MAX_DMA_LINUX; + } +#ifdef USE_PG + if (usal_scsibus(usalp) == usallocal(usalp)->pgbus) + return (pg_maxdma(usalp, amt)); + if ((usal_scsibus(usalp) < 0) && (pg_maxdma(usalp, amt) < maxdma)) + return (pg_maxdma(usalp, amt)); +#endif + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + char *ret; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + /* + * For performance reason, we allocate pagesize() + * bytes before the SCSI buffer to avoid + * copying the whole buffer contents when + * setting up the /dev/sg data structures. + */ + ret = valloc((size_t)(amt+getpagesize())); + if (ret == NULL) + return (ret); + usalp->bufbase = ret; + ret += getpagesize(); + usallocal(usalp)->SCSIbuf = ret; + return ((void *)ret); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ +#ifdef USE_PG + if (usal_scsibus(usalp) == usallocal(usalp)->pgbus) + return (pg_initiator_id(usalp)); +#endif + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return -1; +#if 0 + /* + * Who exactly needs this information? Just for some bitching in wodim? + * Is this an _abstraction_ layer or spam layer? + */ +#ifdef USE_PG + if (usal_scsibus(usalp) == usallocal(usalp)->pgbus) + return (pg_isatapi(usalp)); +#endif + + /* + * The /dev/hd* interface always returns TRUE for SG_EMULATED_HOST. + * So this is completely useless. + */ + if (usallocal(usalp)->flags & LF_ATA) + return (-1); + +#ifdef SG_EMULATED_HOST + { + int emulated = FALSE; + + /* + * XXX Should we use this at all? + * XXX The badly designed /dev/hd* interface always + * XXX returns TRUE, even when used with e.g. /dev/sr0. + */ + if (ioctl(usalp->fd, SG_EMULATED_HOST, &emulated) >= 0) + return (emulated != 0); + } +#endif + return (-1); +#endif +} + +static int +usalo_reset(SCSI *usalp, int what) +{ +#ifdef SG_SCSI_RESET + int f = usalp->fd; + int func = -1; +#endif +#ifdef USE_PG + if (usal_scsibus(usalp) == usallocal(usalp)->pgbus) + return (pg_reset(usalp, what)); +#endif + /* + * Do we have a SCSI reset in the Linux sg driver? + */ +#ifdef SG_SCSI_RESET + /* + * Newer Linux sg driver seem to finally implement it... + */ +#ifdef SG_SCSI_RESET_NOTHING + func = SG_SCSI_RESET_NOTHING; + if (ioctl(f, SG_SCSI_RESET, &func) >= 0) { + if (what == SCG_RESET_NOP) + return (0); +#ifdef SG_SCSI_RESET_DEVICE + if (what == SCG_RESET_TGT) { + func = SG_SCSI_RESET_DEVICE; + if (ioctl(f, SG_SCSI_RESET, &func) >= 0) + return (0); + } +#endif +#ifdef SG_SCSI_RESET_BUS + if (what == SCG_RESET_BUS) { + func = SG_SCSI_RESET_BUS; + if (ioctl(f, SG_SCSI_RESET, &func) >= 0) + return (0); + } +#endif + } +#endif +#endif + return (-1); +} + +static void +sg_settimeout(int f, int tmo) +{ +#ifndef HZ + static int HZ=0; + if (!HZ) + HZ = sysconf(_SC_CLK_TCK); +#endif + tmo *= HZ; + if (tmo) + tmo += HZ/2; + + if (ioctl(f, SG_SET_TIMEOUT, &tmo) < 0) + comerr("Cannot set SG_SET_TIMEOUT.\n"); +} + +/* + * Get misaligned int. + * Needed for all recent processors (sparc/ppc/alpha) + * because the /dev/sg design forces us to do misaligned + * reads of integers. + */ +#ifdef MISALIGN +static int +sg_getint(int *ip) +{ + int ret; + register char *cp = (char *)ip; + register char *tp = (char *)&ret; + register int i; + + for (i = sizeof (int); --i >= 0; ) + *tp++ = *cp++; + + return (ret); +} +#define GETINT(a) sg_getint(&(a)) +#else +#define GETINT(a) (a) +#endif + +#ifdef SG_IO +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + sg_io_hdr_t sg_io; + struct timeval to; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } + if (usallocal(usalp)->isold > 0) { + return (sg_rwsend(usalp)); + } + fillbytes((caddr_t)&sg_io, sizeof (sg_io), '\0'); + + sg_io.interface_id = 'S'; + + if (sp->flags & SCG_RECV_DATA) { + sg_io.dxfer_direction = SG_DXFER_FROM_DEV; + } else if (sp->size > 0) { + sg_io.dxfer_direction = SG_DXFER_TO_DEV; + } else { + sg_io.dxfer_direction = SG_DXFER_NONE; + } + sg_io.cmd_len = sp->cdb_len; + if (sp->sense_len > SG_MAX_SENSE) + sg_io.mx_sb_len = SG_MAX_SENSE; + else + sg_io.mx_sb_len = sp->sense_len; + sg_io.dxfer_len = sp->size; + sg_io.dxferp = sp->addr; + sg_io.cmdp = sp->cdb.cmd_cdb; + sg_io.sbp = sp->u_sense.cmd_sense; + sg_io.timeout = sp->timeout*1000; + sg_io.flags |= SG_FLAG_DIRECT_IO; + + ret = ioctl(usalp->fd, SG_IO, &sg_io); + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "ioctl ret: %d\n", ret); + } + + if (ret < 0) { + sp->ux_errno = geterrno(); + /* + * Check if SCSI command cound not be send at all. + * Linux usually returns EINVAL for an unknoen ioctl. + * In case somebody from the Linux kernel team learns that the + * corect errno would be ENOTTY, we check for this errno too. + */ + if ((sp->ux_errno == ENOTTY || sp->ux_errno == EINVAL) && + usallocal(usalp)->isold < 0) { + usallocal(usalp)->isold = 1; + return (sg_rwsend(usalp)); + } + if (sp->ux_errno == ENXIO || + sp->ux_errno == EINVAL || sp->ux_errno == EACCES) { + return (-1); + } + } + + sp->u_scb.cmd_scb[0] = sg_io.status; + sp->sense_count = sg_io.sb_len_wr; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "host_status: %02X driver_status: %02X\n", + sg_io.host_status, sg_io.driver_status); + } + + switch (sg_io.host_status) { + + case DID_OK: + /* + * If there is no DMA overrun and there is a + * SCSI Status byte != 0 then the SCSI cdb transport + * was OK and sp->error must be SCG_NO_ERROR. + */ + if ((sg_io.driver_status & DRIVER_SENSE) != 0) { + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + + if (sp->u_sense.cmd_sense[0] != 0 && + sp->u_scb.cmd_scb[0] == 0) { + /* + * The Linux SCSI system up to 2.4.xx + * trashes the status byte in the + * kernel. This is true at least for + * ide-scsi emulation. Until this gets + * fixed, we need this hack. + */ + sp->u_scb.cmd_scb[0] = ST_CHK_COND; + if (sp->sense_count == 0) + sp->sense_count = SG_MAX_SENSE; + + if ((sp->u_sense.cmd_sense[2] == 0) && + (sp->u_sense.cmd_sense[12] == 0) && + (sp->u_sense.cmd_sense[13] == 0)) { + /* + * The Linux SCSI system will + * send a request sense for + * even a dma underrun error. + * Clear CHECK CONDITION state + * in case of No Sense. + */ + sp->u_scb.cmd_scb[0] = 0; + sp->u_sense.cmd_sense[0] = 0; + sp->sense_count = 0; + } + } + } + break; + + case DID_NO_CONNECT: /* Arbitration won, retry NO_CONNECT? */ + sp->error = SCG_RETRYABLE; + break; + case DID_BAD_TARGET: + sp->error = SCG_FATAL; + break; + + case DID_TIME_OUT: + __usal_times(usalp); + + if (sp->timeout > 1 && usalp->cmdstop->tv_sec == 0) { + sp->u_scb.cmd_scb[0] = 0; + sp->error = SCG_FATAL; /* a selection timeout */ + } else { + sp->error = SCG_TIMEOUT; + } + break; + + default: + to.tv_sec = sp->timeout; + to.tv_usec = 500000; + __usal_times(usalp); + + if (usalp->cmdstop->tv_sec < to.tv_sec || + (usalp->cmdstop->tv_sec == to.tv_sec && + usalp->cmdstop->tv_usec < to.tv_usec)) { + + sp->ux_errno = 0; + sp->error = SCG_TIMEOUT; /* a timeout */ + } else { + sp->error = SCG_RETRYABLE; + } + break; + } + if (sp->error && sp->ux_errno == 0) + sp->ux_errno = EIO; + + sp->resid = sg_io.resid; + return (0); +} +#else +# define sg_rwsend usalo_send +#endif + +static int +sg_rwsend(SCSI *usalp) +{ + int f = usalp->fd; + struct usal_cmd *sp = usalp->scmd; + struct sg_rq *sgp; + struct sg_rq *sgp2; + int i; + int pack_len; + int reply_len; + int amt = sp->cdb_len; + struct sg_rq { + struct sg_header hd; + unsigned char buf[MAX_DMA_LINUX+SCG_MAX_CMD]; + } sg_rq; +#ifdef SG_GET_BUFSIZE /* We may use a 'sg' version 2 driver */ + char driver_byte; + char host_byte; + char msg_byte; + char status_byte; +#endif + + if (f < 0) { + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } +#ifdef USE_PG + if (usal_scsibus(usalp) == usallocal(usalp)->pgbus) + return (pg_send(usalp)); +#endif + if (sp->timeout != usalp->deftimeout) + sg_settimeout(f, sp->timeout); + + + sgp2 = sgp = &sg_rq; + if (sp->addr == usallocal(usalp)->SCSIbuf) { + sgp = (struct sg_rq *) + (usallocal(usalp)->SCSIbuf - (sizeof (struct sg_header) + amt)); + sgp2 = (struct sg_rq *) + (usallocal(usalp)->SCSIbuf - (sizeof (struct sg_header))); + } else { + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "DMA addr: 0x%8.8lX size: %d - using copy buffer\n", + (long)sp->addr, sp->size); + } + if (sp->size > (int)(sizeof (sg_rq.buf) - SCG_MAX_CMD)) { + + if (usallocal(usalp)->xbuf == NULL) { + usallocal(usalp)->xbufsize = usalp->maxbuf; + usallocal(usalp)->xbuf = + malloc(usallocal(usalp)->xbufsize + + SCG_MAX_CMD + + sizeof (struct sg_header)); + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Allocated DMA copy buffer, addr: 0x%8.8lX size: %ld\n", + (long)usallocal(usalp)->xbuf, + usalp->maxbuf); + } + } + if (usallocal(usalp)->xbuf == NULL || + sp->size > usallocal(usalp)->xbufsize) { + errno = ENOMEM; + return (-1); + } + sgp2 = sgp = (struct sg_rq *)usallocal(usalp)->xbuf; + } + } + + /* + * This is done to avoid misaligned access of sgp->some_int + */ + pack_len = sizeof (struct sg_header) + amt; + reply_len = sizeof (struct sg_header); + if (sp->flags & SCG_RECV_DATA) { + reply_len += sp->size; + } else { + pack_len += sp->size; + } + +#ifdef MISALIGN + /* + * sgp->some_int may be misaligned if (sp->addr == SCSIbuf) + * This is no problem on Intel porocessors, however + * all other processors don't like it. + * sizeof (struct sg_header) + amt is usually not a multiple of + * sizeof (int). For this reason, we fill in the values into sg_rq + * which is always corectly aligned and then copy it to the real + * location if this location differs from sg_rq. + * Never read/write directly to sgp->some_int !!!!! + */ + fillbytes((caddr_t)&sg_rq, sizeof (struct sg_header), '\0'); + + sg_rq.hd.pack_len = pack_len; + sg_rq.hd.reply_len = reply_len; + sg_rq.hd.pack_id = usallocal(usalp)->pack_id++; +/* sg_rq.hd.result = 0; not needed because of fillbytes() */ + + if ((caddr_t)&sg_rq != (caddr_t)sgp) + movebytes((caddr_t)&sg_rq, (caddr_t)sgp, sizeof (struct sg_header)); +#else + fillbytes((caddr_t)sgp, sizeof (struct sg_header), '\0'); + + sgp->hd.pack_len = pack_len; + sgp->hd.reply_len = reply_len; + sgp->hd.pack_id = usallocal(usalp)->pack_id++; +/* sgp->hd.result = 0; not needed because of fillbytes() */ +#endif + if (amt == 12) + sgp->hd.twelve_byte = 1; + + + for (i = 0; i < amt; i++) { + sgp->buf[i] = sp->cdb.cmd_cdb[i]; + } + if (!(sp->flags & SCG_RECV_DATA)) { + if ((void *)sp->addr != (void *)&sgp->buf[amt]) + movebytes(sp->addr, &sgp->buf[amt], sp->size); + amt += sp->size; + } +#ifdef SG_GET_BUFSIZE + sgp->hd.want_new = 1; /* Order new behaviour */ + sgp->hd.cdb_len = sp->cdb_len; /* Set CDB length */ + if (sp->sense_len > SG_MAX_SENSE) + sgp->hd.sense_len = SG_MAX_SENSE; + else + sgp->hd.sense_len = sp->sense_len; +#endif + i = sizeof (struct sg_header) + amt; + if ((amt = write(f, sgp, i)) < 0) { /* write */ + sg_settimeout(f, usalp->deftimeout); + return (-1); + } else if (amt != i) { + errmsg("usalo_send(%s) wrote %d bytes (expected %d).\n", + usalp->cmdname, amt, i); + } + + if (sp->addr == usallocal(usalp)->SCSIbuf) { + movebytes(sgp, sgp2, sizeof (struct sg_header)); + sgp = sgp2; + } + sgp->hd.sense_buffer[0] = 0; + if ((amt = read(f, sgp, reply_len)) < 0) { /* read */ + sg_settimeout(f, usalp->deftimeout); + return (-1); + } + + if (sp->flags & SCG_RECV_DATA && ((void *)sgp->buf != (void *)sp->addr)) { + movebytes(sgp->buf, sp->addr, sp->size); + } + sp->ux_errno = GETINT(sgp->hd.result); /* Unaligned read */ + sp->error = SCG_NO_ERROR; + +#ifdef SG_GET_BUFSIZE + if (sgp->hd.grant_new) { + sp->sense_count = sgp->hd.sense_len; + pack_len = GETINT(sgp->hd.sg_cmd_status); /* Unaligned read */ + driver_byte = (pack_len >> 24) & 0xFF; + host_byte = (pack_len >> 16) & 0xFF; + msg_byte = (pack_len >> 8) & 0xFF; + status_byte = pack_len & 0xFF; + + switch (host_byte) { + + case DID_OK: + if ((driver_byte & DRIVER_SENSE || + sgp->hd.sense_buffer[0] != 0) && + status_byte == 0) { + /* + * The Linux SCSI system up to 2.4.xx + * trashes the status byte in the + * kernel. This is true at least for + * ide-scsi emulation. Until this gets + * fixed, we need this hack. + */ + status_byte = ST_CHK_COND; + if (sgp->hd.sense_len == 0) + sgp->hd.sense_len = SG_MAX_SENSE; + + if ((sp->u_sense.cmd_sense[2] == 0) && + (sp->u_sense.cmd_sense[12] == 0) && + (sp->u_sense.cmd_sense[13] == 0)) { + /* + * The Linux SCSI system will + * send a request sense for + * even a dma underrun error. + * Clear CHECK CONDITION state + * in case of No Sense. + */ + sp->u_scb.cmd_scb[0] = 0; + sp->u_sense.cmd_sense[0] = 0; + sp->sense_count = 0; + } + } + break; + + case DID_NO_CONNECT: /* Arbitration won, retry NO_CONNECT? */ + sp->error = SCG_RETRYABLE; + break; + + case DID_BAD_TARGET: + sp->error = SCG_FATAL; + break; + + case DID_TIME_OUT: + sp->error = SCG_TIMEOUT; + break; + + default: + sp->error = SCG_RETRYABLE; + + if ((driver_byte & DRIVER_SENSE || + sgp->hd.sense_buffer[0] != 0) && + status_byte == 0) { + status_byte = ST_CHK_COND; + sp->error = SCG_NO_ERROR; + } + if (status_byte != 0 && sgp->hd.sense_len == 0) { + sgp->hd.sense_len = SG_MAX_SENSE; + sp->error = SCG_NO_ERROR; + } + break; + + } + if ((host_byte != DID_OK || status_byte != 0) && sp->ux_errno == 0) + sp->ux_errno = EIO; + sp->u_scb.cmd_scb[0] = status_byte; + if (status_byte & ST_CHK_COND) { + sp->sense_count = sgp->hd.sense_len; + movebytes(sgp->hd.sense_buffer, sp->u_sense.cmd_sense, sp->sense_count); + } + } else +#endif + { + if (GETINT(sgp->hd.result) == EBUSY) { /* Unaligned read */ + struct timeval to; + + to.tv_sec = sp->timeout; + to.tv_usec = 500000; + __usal_times(usalp); + + if (sp->timeout > 1 && usalp->cmdstop->tv_sec == 0) { + sp->u_scb.cmd_scb[0] = 0; + sp->ux_errno = EIO; + sp->error = SCG_FATAL; /* a selection timeout */ + } else if (usalp->cmdstop->tv_sec < to.tv_sec || + (usalp->cmdstop->tv_sec == to.tv_sec && + usalp->cmdstop->tv_usec < to.tv_usec)) { + + sp->ux_errno = EIO; + sp->error = SCG_TIMEOUT; /* a timeout */ + } else { + sp->error = SCG_RETRYABLE; /* may be BUS_BUSY */ + } + } + + if (sp->flags & SCG_RECV_DATA) + sp->resid = (sp->size + sizeof (struct sg_header)) - amt; + else + sp->resid = 0; /* sg version1 cannot return DMA resid count */ + + if (sgp->hd.sense_buffer[0] != 0) { + sp->scb.chk = 1; + sp->sense_count = SG_MAX_SENSE; + movebytes(sgp->hd.sense_buffer, sp->u_sense.cmd_sense, sp->sense_count); + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + } + } + + if (usalp->verbose > 0 && usalp->debug > 0) { +#ifdef SG_GET_BUFSIZE + fprintf((FILE *)usalp->errfile, + "status: 0x%08X pack_len: %d, reply_len: %d pack_id: %d result: %d wn: %d gn: %d cdb_len: %d sense_len: %d sense[0]: %02X\n", + GETINT(sgp->hd.sg_cmd_status), + GETINT(sgp->hd.pack_len), + GETINT(sgp->hd.reply_len), + GETINT(sgp->hd.pack_id), + GETINT(sgp->hd.result), + sgp->hd.want_new, + sgp->hd.grant_new, + sgp->hd.cdb_len, + sgp->hd.sense_len, + sgp->hd.sense_buffer[0]); +#else + fprintf((FILE *)usalp->errfile, + "pack_len: %d, reply_len: %d pack_id: %d result: %d sense[0]: %02X\n", + GETINT(sgp->hd.pack_len), + GETINT(sgp->hd.reply_len), + GETINT(sgp->hd.pack_id), + GETINT(sgp->hd.result), + sgp->hd.sense_buffer[0]); +#endif +#ifdef DEBUG + fprintf((FILE *)usalp->errfile, "sense: "); + for (i = 0; i < 16; i++) + fprintf((FILE *)usalp->errfile, "%02X ", sgp->hd.sense_buffer[i]); + fprintf((FILE *)usalp->errfile, "\n"); +#endif + } + + if (sp->timeout != usalp->deftimeout) + sg_settimeout(f, usalp->deftimeout); + return (0); +}; + +#define HAVE_NAT_NAMES +static char * usalo_natname(SCSI *usalp, int busno, int tgt, int tlun) { + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) + return "BADID"; + return usallocal(usalp)->filenames[busno][tgt][tlun]; +} diff --git a/libusal/scsi-mac-iokit.c b/libusal/scsi-mac-iokit.c new file mode 100644 index 0000000..7e5ee4f --- /dev/null +++ b/libusal/scsi-mac-iokit.c @@ -0,0 +1,539 @@ +/* + * 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. + * + */ + +/* @(#)scsi-mac-iokit.c 1.10 05/05/15 Copyright 1997,2001-2004 J. Schilling */ +/* + * Interface to the Darwin IOKit SCSI drivers + * + * Notes: Uses the IOKit/scsi-commands/SCSITaskLib interface + * + * As of October 2001, this interface does not support SCSI parallel bus + * (old-fashioned SCSI). It does support ATAPI, Firewire, and USB. + * + * First version done by Constantine Sapuntzakis <csapuntz@Stanford.EDU> + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997,2001-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. + */ + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-mac-iokit.c-1.10"; /* The version for this transport */ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +#include <statdefs.h> +#include <mach/mach.h> +#include <Carbon/Carbon.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/scsi-commands/SCSITaskLib.h> +#include <mach/mach_error.h> + +struct usal_local { + MMCDeviceInterface **mmcDeviceInterface; + SCSITaskDeviceInterface **scsiTaskDeviceInterface; + mach_port_t masterPort; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#define MAX_DMA_NEXT (32*1024) +#if 0 +#define MAX_DMA_NEXT (64*1024) /* Check if this is not too big */ +#endif + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SCSITaskDeviceInterface", "Apple SCSI", + "", "Mac Prom device name", "IOCompactDiscServices/0", + FALSE, FALSE); + return (0); +} + + +/* + * Valid Device names: + * IOCompactDiscServices + * IODVDServices + * IOSCSIPeripheralDeviceNub + * + * Also a / and a number can be appended to refer to something + * more than the first device (e.g. IOCompactDiscServices/5 for the 5th + * compact disc attached) + */ +static int +usalo_open(SCSI *usalp, char *device) +{ + mach_port_t masterPort = NULL; + io_iterator_t scsiObjectIterator = NULL; + IOReturn ioReturnValue = kIOReturnSuccess; + CFMutableDictionaryRef dict = NULL; + io_object_t scsiDevice = NULL; + HRESULT plugInResult; + IOCFPlugInInterface **plugInInterface = NULL; + MMCDeviceInterface **mmcDeviceInterface = NULL; + SCSITaskDeviceInterface **scsiTaskDeviceInterface = NULL; + SInt32 score = 0; + int err = -1; + char *realdevice = NULL, *tmp; + int driveidx = 1, idx = 1; + + if (device == NULL) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Please specify a device name (e.g. IOCompactDiscServices/0)"); + goto out; + } + + realdevice = tmp = strdup(device); + tmp = strchr(tmp, '/'); + if (tmp != NULL) { + *tmp++ = '\0'; + driveidx = atoi(tmp); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + goto out; + } + + ioReturnValue = IOMasterPort(bootstrap_port, &masterPort); + + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Couldn't get a master IOKit port. Error %d", + ioReturnValue); + goto out; + } + + dict = IOServiceMatching(realdevice); + if (dict == NULL) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Couldn't create dictionary for searching"); + goto out; + } + + ioReturnValue = IOServiceGetMatchingServices(masterPort, dict, + &scsiObjectIterator); + dict = NULL; + + if (scsiObjectIterator == NULL || + (ioReturnValue != kIOReturnSuccess)) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "No matching device %s found.", device); + goto out; + } + + if (driveidx <= 0) + driveidx = 1; + + idx = 1; + while ((scsiDevice = IOIteratorNext(scsiObjectIterator)) != NULL) { + if (idx == driveidx) + break; + IOObjectRelease(scsiDevice); + scsiDevice = NULL; + idx++; + } + + if (scsiDevice == NULL) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "No matching device found. Iterator failed."); + goto out; + } + + ioReturnValue = IOCreatePlugInInterfaceForService(scsiDevice, + kIOMMCDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugInInterface, &score); + if (ioReturnValue != kIOReturnSuccess) { + goto try_generic; + } + + plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, + CFUUIDGetUUIDBytes(kIOMMCDeviceInterfaceID), + (LPVOID)&mmcDeviceInterface); + + if (plugInResult != KERN_SUCCESS) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Unable to get MMC Interface: 0x%lX", + (long)plugInResult); + + goto out; + } + + scsiTaskDeviceInterface = + (*mmcDeviceInterface)->GetSCSITaskDeviceInterface(mmcDeviceInterface); + + if (scsiTaskDeviceInterface == NULL) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Failed to get taskDeviceInterface"); + goto out; + } + + goto init; + +try_generic: + ioReturnValue = IOCreatePlugInInterfaceForService(scsiDevice, + kIOSCSITaskDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugInInterface, &score); + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Unable to get plugin Interface: %x", + ioReturnValue); + goto out; + } + + plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, + CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID), + (LPVOID)&scsiTaskDeviceInterface); + + if (plugInResult != KERN_SUCCESS) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Unable to get generic Interface: 0x%lX", + (long)plugInResult); + + goto out; + } + +init: + ioReturnValue = + (*scsiTaskDeviceInterface)->ObtainExclusiveAccess(scsiTaskDeviceInterface); + + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Unable to get exclusive access to device"); + goto out; + } + + if (mmcDeviceInterface) { + (*mmcDeviceInterface)->AddRef(mmcDeviceInterface); + } + (*scsiTaskDeviceInterface)->AddRef(scsiTaskDeviceInterface); + usallocal(usalp)->mmcDeviceInterface = mmcDeviceInterface; + usallocal(usalp)->scsiTaskDeviceInterface = scsiTaskDeviceInterface; + usallocal(usalp)->masterPort = masterPort; + usal_settarget(usalp, 0, 0, 0); + err = 1; + +out: + if (scsiTaskDeviceInterface != NULL) { + (*scsiTaskDeviceInterface)->Release(scsiTaskDeviceInterface); + } + + if (plugInInterface != NULL) { + (*plugInInterface)->Release(plugInInterface); + } + + if (scsiDevice != NULL) { + IOObjectRelease(scsiDevice); + } + + if (scsiObjectIterator != NULL) { + IOObjectRelease(scsiObjectIterator); + } + + if (err < 0) { + if (usalp->local) { + free(usalp->local); + usalp->local = NULL; + } + + if (masterPort) { + mach_port_deallocate(mach_task_self(), masterPort); + } + } + + if (dict != NULL) { + CFRelease(dict); + } + + if (realdevice != NULL) { + free(realdevice); + } + return (err); +} + +static int +usalo_close(SCSI *usalp) +{ + SCSITaskDeviceInterface **sc; + MMCDeviceInterface **mmc; + + if (usalp->local == NULL) + return (-1); + + sc = usallocal(usalp)->scsiTaskDeviceInterface; + (*sc)->ReleaseExclusiveAccess(sc); + (*sc)->Release(sc); + usallocal(usalp)->scsiTaskDeviceInterface = NULL; + + mmc = usallocal(usalp)->mmcDeviceInterface; + if (mmc != NULL) + (*mmc)->Release(mmc); + + mach_port_deallocate(mach_task_self(), usallocal(usalp)->masterPort); + + free(usalp->local); + usalp->local = NULL; + + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = MAX_DMA_NEXT; +#ifdef SGIOCMAXDMA + int m; + + if (ioctl(usallocal(usalp)->usalfile, SGIOCMAXDMA, &m) >= 0) { + maxdma = m; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "maxdma: %d\n", maxdma); + } + } +#endif + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = malloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + if (busno == 0) + return (TRUE); + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + return (-1); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + + errno = 0; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + SCSITaskDeviceInterface **sc = NULL; + SCSITaskInterface **cmd = NULL; + IOVirtualRange iov; + SCSI_Sense_Data senseData; + SCSITaskStatus status; + UInt64 bytesTransferred; + IOReturn ioReturnValue; + int ret = 0; + + if (usalp->local == NULL) { + return (-1); + } + + sc = usallocal(usalp)->scsiTaskDeviceInterface; + + cmd = (*sc)->CreateSCSITask(sc); + if (cmd == NULL) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Failed to create SCSI task"); + ret = -1; + + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + goto out; + } + + + iov.address = (IOVirtualAddress) sp->addr; + iov.length = sp->size; + + ioReturnValue = (*cmd)->SetCommandDescriptorBlock(cmd, + sp->cdb.cmd_cdb, sp->cdb_len); + + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "SetCommandDescriptorBlock failed with status %x", + ioReturnValue); + ret = -1; + goto out; + } + + ioReturnValue = (*cmd)->SetScatterGatherEntries(cmd, &iov, 1, sp->size, + (sp->flags & SCG_RECV_DATA) ? + kSCSIDataTransfer_FromTargetToInitiator : + kSCSIDataTransfer_FromInitiatorToTarget); + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "SetScatterGatherEntries failed with status %x", + ioReturnValue); + ret = -1; + goto out; + } + + ioReturnValue = (*cmd)->SetTimeoutDuration(cmd, sp->timeout * 1000); + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "SetTimeoutDuration failed with status %x", + ioReturnValue); + ret = -1; + goto out; + } + + memset(&senseData, 0, sizeof (senseData)); + + seterrno(0); + ioReturnValue = (*cmd)->ExecuteTaskSync(cmd, + &senseData, &status, &bytesTransferred); + + sp->resid = sp->size - bytesTransferred; + sp->error = SCG_NO_ERROR; + sp->ux_errno = geterrno(); + + if (ioReturnValue != kIOReturnSuccess) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Command execution failed with status %x", + ioReturnValue); + sp->error = SCG_RETRYABLE; + ret = -1; + goto out; + } + + memset(&sp->scb, 0, sizeof (sp->scb)); + memset(&sp->u_sense.cmd_sense, 0, sizeof (sp->u_sense.cmd_sense)); + if (senseData.VALID_RESPONSE_CODE != 0 || status == 0x02) { + /* + * There is no sense length - we need to asume that + * we always get 18 bytes. + */ + sp->sense_count = kSenseDefaultSize; + memmove(&sp->u_sense.cmd_sense, &senseData, kSenseDefaultSize); + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + } + + sp->u_scb.cmd_scb[0] = status; + + /* ??? */ + if (status == kSCSITaskStatus_No_Status) { + sp->error = SCG_RETRYABLE; + ret = -1; + goto out; + } + /* + * XXX Is it possible to have other senseful SCSI transport error codes? + */ + +out: + if (cmd != NULL) { + (*cmd)->Release(cmd); + } + + return (ret); +} diff --git a/libusal/scsi-next.c b/libusal/scsi-next.c new file mode 100644 index 0000000..bfbe2b3 --- /dev/null +++ b/libusal/scsi-next.c @@ -0,0 +1,419 @@ +/* + * 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. + * + */ + +/* @(#)scsi-next.c 1.32 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the NeXT Step generic SCSI implementation. + * + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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 <bsd/dev/scsireg.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-next.c-1.32"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; + int usalfile; + int max_scsibus; + int cur_scsibus; + int cur_target; + int cur_lun; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +/*#define MAX_DMA_NEXT (32*1024)*/ +#define MAX_DMA_NEXT (64*1024) /* Check if this is not too big */ + + +static BOOL usal_setup(SCSI *usalp, int busno, int tgt, int tlun, BOOL ex); + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SGIOCREQ", "Generic SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int i; + char devname[64]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + usallocal(usalp)->usalfile = -1; + usallocal(usalp)->max_scsibus = -1; + usallocal(usalp)->cur_scsibus = -1; + usallocal(usalp)->cur_target = -1; + usallocal(usalp)->cur_lun = -1; + } + + for (i = 0; i < 4; i++) { + snprintf(devname, sizeof (devname), "/dev/sg%d", i); + f = open(devname, O_RDWR); + if (usalp->debug > 0) + errmsg("open(devname: '%s') : %d\n", devname, f); + if (f < 0) + continue; + usallocal(usalp)->usalfile = f; + break; + + } + if (f >= 0) { + if (usallocal(usalp)->max_scsibus < 0) { + for (i = 0; i < MAX_SCG; i++) { + if (!SCGO_HAVEBUS(usalp, i)) + break; + } + usallocal(usalp)->max_scsibus = i; + } + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "maxbus: %d\n", usallocal(usalp)->max_scsibus); + } + if (usallocal(usalp)->max_scsibus <= 0) { + usallocal(usalp)->max_scsibus = 1; + usallocal(usalp)->cur_scsibus = 0; + } + + ioctl(f, SGIOCENAS); + if (busno > 0 && tgt > 0 && tlun > 0) + usal_setup(usalp, busno, tgt, tlun, TRUE); + return (1); + } + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '/dev/sg*'"); + return (0); +} + +static int +usalo_close(SCSI *usalp) +{ + if (usalp->local == NULL) + return (-1); + + if (usallocal(usalp)->usalfile >= 0) + close(usallocal(usalp)->usalfile); + usallocal(usalp)->usalfile = -1; + return (0); +} + +static BOOL +usal_setup(SCSI *usalp, int busno, int tgt, int tlun, BOOL ex) +{ + scsi_adr_t sadr; + + sadr.sa_target = tgt; + sadr.sa_lun = tlun; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usal_setup curbus %d -> %d\n", usallocal(usalp)->cur_scsibus, busno); + } + + if (usalp->debug > 0 && ((usallocal(usalp)->cur_scsibus < 0 || usallocal(usalp)->cur_scsibus != busno))) + fprintf((FILE *)usalp->errfile, "setting SCSI bus to: %d\n", busno); + if ((usallocal(usalp)->cur_scsibus < 0 || usallocal(usalp)->cur_scsibus != busno) && + ioctl(usallocal(usalp)->usalfile, SGIOCCNTR, &busno) < 0) { + + usallocal(usalp)->cur_scsibus = -1; /* Driver is in undefined state */ + if (ex) +/* comerr("Cannot set SCSI bus\n");*/ + errmsg("Cannot set SCSI bus\n"); + return (FALSE); + } + usallocal(usalp)->cur_scsibus = busno; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "setting target/lun to: %d/%d\n", tgt, tlun); + } + if (ioctl(usallocal(usalp)->usalfile, SGIOCSTL, &sadr) < 0) { + if (ex) + comerr("Cannot set SCSI address\n"); + return (FALSE); + } + usallocal(usalp)->cur_scsibus = busno; + usallocal(usalp)->cur_target = tgt; + usallocal(usalp)->cur_lun = tlun; + return (TRUE); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = MAX_DMA_NEXT; +#ifdef SGIOCMAXDMA + int m; + + if (ioctl(usallocal(usalp)->usalfile, SGIOCMAXDMA, &m) >= 0) { + maxdma = m; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "maxdma: %d\n", maxdma); + } + } +#endif + return (maxdma); +} +#ifdef XXX +#define SGIOCENAS _IO('s', 2) /* enable autosense */ +#define SGIOCDAS _IO('s', 3) /* disable autosense */ +#define SGIOCRST _IO('s', 4) /* reset SCSI bus */ +#define SGIOCCNTR _IOW('s', 6, int) /* select controller */ +#define SGIOCGAS _IOR('s', 7, int) /* get autosense */ +#define SGIOCMAXDMA _IOR('s', 8, int) /* max DMA size */ +#define SGIOCNUMTARGS _IOR('s', 9, int) /* # of targets/bus */ +#endif + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + if (usallocal(usalp)->max_scsibus > 0 && busno >= usallocal(usalp)->max_scsibus) + return (FALSE); + + return (usal_setup(usalp, busno, 0, 0, FALSE)); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + if (usallocal(usalp)->max_scsibus > 0 && busno >= usallocal(usalp)->max_scsibus) + return (-1); + + if (usalp->local == NULL) + return (-1); + + if ((busno != usallocal(usalp)->cur_scsibus) || (tgt != usallocal(usalp)->cur_target) || (tlun != usallocal(usalp)->cur_lun)) { + if (!usal_setup(usalp, busno, tgt, tlun, FALSE)) + return (-1); + } + return (usallocal(usalp)->usalfile); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + return (ioctl(usalp->fd, SGIOCRST, 0)); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + struct scsi_req req; + register long *lp1; + register long *lp2; + int ret = 0; + + if (usalp->fd < 0 || (sp->cdb_len > sizeof (req.sr_cdb))) { + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + return (0); + } + fillbytes(&req, sizeof (req), '\0'); + movebytes(sp->cdb.cmd_cdb, &req.sr_cdb, sp->cdb_len); + if (sp->size) { + req.sr_dma_dir = SR_DMA_WR; + if (sp->flags & SCG_RECV_DATA) + req.sr_dma_dir = SR_DMA_RD; + } + req.sr_addr = sp->addr; + req.sr_dma_max = sp->size; + req.sr_ioto = sp->timeout; + if (ioctl(usalp->fd, SGIOCREQ, (void *)&req) < 0) { + ret = -1; + sp->ux_errno = geterrno(); + if (sp->ux_errno != ENOTTY) + ret = 0; + } else { + sp->ux_errno = 0; + } + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "dma_dir: %X\n", req.sr_dma_dir); + fprintf((FILE *)usalp->errfile, "dma_addr: %X\n", req.sr_addr); + fprintf((FILE *)usalp->errfile, "io_time: %d\n", req.sr_ioto); + fprintf((FILE *)usalp->errfile, "io_status: %d\n", req.sr_io_status); + fprintf((FILE *)usalp->errfile, "scsi_status: %X\n", req.sr_scsi_status); + fprintf((FILE *)usalp->errfile, "dma_xfer: %d\n", req.sr_dma_xfr); + } + sp->u_scb.cmd_scb[0] = req.sr_scsi_status; + sp->sense_count = sizeof (esense_reply_t); + if (sp->sense_count > sp->sense_len) + sp->sense_count = sp->sense_len; + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + if (sp->sense_count < 0) + sp->sense_count = 0; + movebytes(&req.sr_esense, sp->u_sense.cmd_sense, sp->sense_count); + sp->resid = sp->size - req.sr_dma_xfr; + + switch (req.sr_io_status) { + + case SR_IOST_GOOD: sp->error = SCG_NO_ERROR; break; + + case SR_IOST_CHKSNV: sp->sense_count = 0; + case SR_IOST_CHKSV: sp->error = SCG_RETRYABLE; + break; + + case SR_IOST_SELTO: + case SR_IOST_DMAOR: + sp->error = SCG_FATAL; break; + + case SR_IOST_IOTO: sp->error = SCG_TIMEOUT; break; + + case SR_IOST_PERM: + case SR_IOST_NOPEN: + sp->error = SCG_FATAL; + ret = (-1); + break; + + default: sp->error = SCG_RETRYABLE; break; + + } + return (ret); +} diff --git a/libusal/scsi-openserver.c b/libusal/scsi-openserver.c new file mode 100644 index 0000000..d192302 --- /dev/null +++ b/libusal/scsi-openserver.c @@ -0,0 +1,1015 @@ +/* + * 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. + * + */ + +/* @(#)scsi-openserver.c 1.31 04/01/15 Copyright 1998 J. Schilling, Santa Cruz Operation */ +/* + * Interface for the SCO SCSI implementation. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998 J. Schilling, Santa Cruz Operation + */ +/* + * 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. + */ + +#undef sense + +#include <sys/scsicmd.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-openserver.c-1.31"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of cdrom devices */ +#define MAX_TGT 16 /* Not really needed */ +#define MAX_LUN 8 /* Not really needed */ + +#define MAX_DMA (64*1024) + +#define MAXPATH 256 /* max length of devicepath */ +#define MAXLINE 80 /* max length of input line */ +#define MAXSCSI 99 /* max number of mscsi lines */ +#define MAXDRVN 10 /* max length of drivername */ + +#define DEV_DIR "/tmp" +#define DEV_NAME "usal.s%1dt%1dl%1d" + +/* + * --------------------------------------------------------------------- + * We will only deal with cdroms by default! Only if you set a specific + * environment variable, we will scan "all" devices ! + * Set LIBSCG_SCAN_ALL to any value to enable access to all your SCSI + * devices. + * + * The upcoming support for USB will be for USB 1.1, so as this is not + * tested yet, we will currently ignore drives connect to the USB stack + * (usbha controller) regardless of having set LIBSCG_SCAN_ALL or not! + */ + +#define DEV_ROOT "/dev/dsk/0s0" + +#define DEV_SDSK "/dev/rdsk/%ds0" +#define DEV_SROM "/dev/rcd%d" +#define DEV_STP "/dev/xStp%d" +#define DEV_SFLP "/dev/rdsk/fp%dh" + +#define SCAN_DEV "%s%s%d%d%d%d" + +#define SCSI_CFG "/etc/sconf -r" /* no. of configured devices */ +#define SCSI_DEV "/etc/sconf -g %d" /* read line 'n' of mscsi tbl */ + +#define DRV_ATAPI "wd" /* SCO OpenServer IDE driver */ +#define DRV_USB "usbha" /* SCO OpenServer USB driver */ +#define DRV_NOHA "noha" /* IDE/ATAPI device configured, */ + /* but missing ! */ + + +#define T_DISK "Sdsk" /* SCO OpenServer SCSI disk */ +#define T_CDROM "Srom" /* SCO OpenServer SCSI cdrom */ +#define T_TAPE "Stp" /* SCO OpenServer SCSI tape */ +#define T_FLOPPY "Sflp" /* SCO OpenServer SCSI floppy */ + + +/* + * --------------------------------------------------------------------- + * Environment variables to control certain functionality + */ + +#define SCAN_ALL "LIBSCG_SCAN_ALL" /* enable access for all devices */ +#define SCSI_USER_CMD "LIBSCG_SCSIUSERCMD" /* use old SCSIUSERCMD ioctl() */ +#define DMA_OVERRIDE "LIBSCG_MAX_DMA" /* override MAX_DMA value */ +#define ENABLE_USB "LIBSCG_ENABLE_USB" /* enable access of USB devices */ + +static int scan_all = 0; /* don't scan all devices by default */ +static int scsiusercmd = 0; /* use SCSIUSERCMD2 ioctl by default */ +static int enable_usb = 0; /* don't scan USB devices by default */ +static long max_dma = MAX_DMA; /* use MAX_DMA DMA buffer by default */ + + +/* + * --------------------------------------------------------------------- + * There are two scsi passthrough ioctl() on SCO OpenServer 5.0.[45], + * while there is only one available on SCO OpenServer 5.0.[02]. + * + * The SCSIUSERCMD ioctl is available on all OpenServer 5 + * + * The SCSIUSERCMD2 ioctl which executes the usercmd and reads the sense + * in one go, is only available from 5.0.4 onwards. + * + * By default we will use the SCSIUSERCMD2 ioctl(), in order to execute + * the SCSIUSERCMD ioctl() instead set the environment variable + * LIBSCG_SCSIUSERCMD to any value. Using the olderSCSIUSERCMD ioctl() will + * if the SCSI commands returns a CHECK CONDITION status, run a seperate + * REQUEST_SENSE command immediately. But we need to remember that in a + * multi-tasking environment, there might be other code which has accessed + * the device in between these two steps and therefore the sense code + * is no longer valid !!! + * + * NOTE: There are problems with the usage of AHA 154X controllers + * and SCSIUSERCMD2 such as nonsense (weird) output on cdrecord -scanbus + * + */ + + +typedef struct usal2sdi { + + int valid; + int open; + int atapi; + int fd; + int lmscsi; + +} usal2sdi_t; + +static usal2sdi_t sdidevs [MAX_SCG][MAX_TGT][MAX_LUN]; + +typedef struct amscsi { + char typ[MAXDRVN]; + char drv[MAXDRVN]; + int hba; + int bus; + int usal; + int tgt; + int lun; + char dev[MAXPATH]; + +} amscsi_t; + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +static int sort_mscsi(const void *l1, const void *l2); +static int openserver_init(SCSI *usalp); +static void cp_usal2sco(struct scsicmd2 *sco, struct usal_cmd *usal); +static void cp_sco2usal(struct scsicmd2 *sco, struct usal_cmd *usal); + +/* + * ------------------------------------------------------------------------- + * SCO OpenServer does not have a generic scsi device driver, which can + * be used to access any configured scsi device. But we can use the "Sxxx" + * scsi peripherial drivers passthrough ioctl() (SCSIUSERCMD / SCSIUSERCMD2) + * to send scsi user comands to any target device controlled by the + * corresponding target driver. + * + * This passthrough implementation for libusal currently allows to + * handle the following devices classes: + * + * 1. DISK handled by Sdsk + * 2. CD-ROM handled by Srom + * 3. TAPES handled by Stp + * 4. FLOPPY handled by Sflp + * + * NOTE: The libusal OpenServer passthrough routines have changed with + * cdrecord-1.8 to enable the -scanbus option. Therefore the + * addressing scheme is now the same as used on many other platforms + * like Solaris, Linux etc. + * + * =============================================================== + * RUN 'cdrecord -scanbus' TO SEE THE DEVICE ADDRESSES YOU CAN USE + * =============================================================== + * + */ + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SCSIUSERCMD/SCSIUSERCMD2", "Generic SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +/* + * --------------------------------------------------------------- + * This routine sorts the amscsi_t lines on the following columns + * in ascending order: + * + * 1. drv - driver name + * 2. bus - scsibus per controller + * 3. tgt - target id of device + * 4. lun - lun of the device + * + */ + + +static int +sort_mscsi(const void *l1, const void *l2) +{ + amscsi_t *t1 = (amscsi_t *) l1; + amscsi_t *t2 = (amscsi_t *) l2; + + if (strcmp(t1->drv, t2->drv) == 0) { + if (t1->bus < t2->bus) { + return (-1); + + } else if (t1->bus > t2->bus) { + return (1); + + } else if (t1->tgt < t2->tgt) { + return (-1); + + } else if (t1->tgt > t2->tgt) { + return (1); + + } else if (t1->lun < t2->lun) { + return (-1); + + } else if (t1->lun > t2->lun) { + return (1); + } else { + return (0); + } + } else { + return (strcmp(t1->drv, t2->drv)); + } +} + +/* + * --------------------------------------------------------------- + * This routine is introduced to find all scsi devices which are + * currently configured into the kernel. This is done by reading + * the dynamic kernel mscsi tables and parse the resulting lines. + * As the output of 'sconf' is not directly usable the information + * found is to be sorted and re-arranged to be used with the libusal + * routines. + * + * NOTE: One problem is currently still not solved ! If you don't + * have a media in your CD-ROM/CD-Writer we are not able to + * do an open() and therefore will set the drive to be not + * available (valid=0). + * + * This will for example cause cdrecord to not list the drive + * in the -scanbus output. + * + */ + +static int +openserver_init(SCSI *usalp) +{ + FILE *cmd; + int nusal = -1, lhba = -1, lbus = -1; + int nSrom = -1, nSdsk = -1, nStp = -1, nSflp = -1; + int atapi, fd, nopen = 0; + int pos = 0, len = 0, nlm = 0; + int s = 0, t = 0, l = 0; + int ide_rootdisk = 0; + long dma_override = 0; + int mscsi; + char sconf[MAXLINE]; + char lines[MAXLINE]; + char drvid[MAXDRVN]; + amscsi_t cmtbl[MAXSCSI]; + char dname[MAXPATH]; + char **evsave; +extern char **environ; + + + for (s = 0; s < MAX_SCG; s++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + sdidevs[s][t][l].valid = 0; + sdidevs[s][t][l].open = -1; + sdidevs[s][t][l].atapi = -1; + sdidevs[s][t][l].fd = -1; + sdidevs[s][t][l].lmscsi = -1; + } + } + } + + /* Check whether we want to use the older SCSIUSERCMD ioctl() */ + + if (getenv(SCSI_USER_CMD) != NULL) { + scsiusercmd = 1; + } + + /* + * Check whether we want to scan all devices + */ + if (getenv(SCAN_ALL) != NULL) { + scan_all = 1; + } + + /* + * Check whether we want to use USB devices + */ + if (getenv(ENABLE_USB) != NULL) { + enable_usb = 1; + } + + /* + * Check whether we want to override the MAX_DMA value + */ + if (getenv(DMA_OVERRIDE) != NULL) { + dma_override = atol(getenv(DMA_OVERRIDE)); + if ((dma_override >= 1) && (dma_override <= (256))) + max_dma = dma_override * 1024; + } + + + /* read sconf -r and get number of kernel mscsi lines ! */ + + evsave = environ; + environ = 0; + if ((cmd = popen(SCSI_CFG, "r")) == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error popen() for \"%s\"", + SCSI_CFG); + environ = evsave; + return (-1); + } + environ = evsave; + + if (fgets(lines, MAXLINE, cmd) == NULL) { + errno = EIO; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error reading popen() for \"%s\"", + SCSI_CFG); + return (-1); + } else + nlm = atoi(lines); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + fprintf((FILE *)usalp->errfile, "mscsi lines = %d\n", nlm); + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + } + + if (pclose(cmd) == -1) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error pclose() for \"%s\"", + SCSI_CFG); + return (-1); + } + + for (l = 0; l < nlm; l++) { + + /* initialize cmtbl entry */ + + cmtbl[l].hba = -1; + cmtbl[l].bus = -1; + cmtbl[l].tgt = -1; + cmtbl[l].lun = -1; + cmtbl[l].usal = -1; + + memset(cmtbl[l].typ, '\0', MAXDRVN); + memset(cmtbl[l].drv, '\0', MAXDRVN); + memset(cmtbl[l].dev, '\0', MAXDRVN); + + /* read sconf -g 'n' and get line of kernel mscsi table! */ + /* the order the lines will be received in will determine */ + /* the device name we can use to open the device */ + + snprintf(sconf, sizeof (sconf), + SCSI_DEV, l + 1); /* enumeration starts with 1 */ + + evsave = environ; + environ = 0; + if ((cmd = popen(sconf, "r")) == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error popen() for \"%s\"", + sconf); + environ = evsave; + return (-1); + } + environ = evsave; + + if (fgets(lines, MAXLINE, cmd) == NULL) + break; + + if (pclose(cmd) == -1) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error pclose() for \"%s\"", + sconf); + return (-1); + } + + sscanf(lines, SCAN_DEV, cmtbl[l].typ, + cmtbl[l].drv, + &cmtbl[l].hba, + &cmtbl[l].bus, + &cmtbl[l].tgt, + &cmtbl[l].lun); + + if (strstr(cmtbl[l].typ, T_DISK) != NULL) { + snprintf(cmtbl[l].dev, sizeof (cmtbl[l].dev), + DEV_SDSK, ++nSdsk); + } + + if (strstr(cmtbl[l].typ, T_CDROM) != NULL) { + snprintf(cmtbl[l].dev, sizeof (cmtbl[l].dev), + DEV_SROM, ++nSrom); + } + + if (strstr(cmtbl[l].typ, T_TAPE) != NULL) { + snprintf(cmtbl[l].dev, sizeof (cmtbl[l].dev), + DEV_STP, ++nStp); + } + + if (strstr(cmtbl[l].typ, T_FLOPPY) != NULL) { + snprintf(cmtbl[l].dev, sizeof (cmtbl[l].dev), + DEV_SFLP, ++nSflp); + } + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "%-4s = %5s(%d,%d,%d,%d) -> %s\n", + cmtbl[l].typ, + cmtbl[l].drv, + cmtbl[l].hba, + cmtbl[l].bus, + cmtbl[l].tgt, + cmtbl[l].lun, + cmtbl[l].dev); + } + + } + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + fprintf((FILE *)usalp->errfile, "%2d DISK \n", nSdsk + 1); + fprintf((FILE *)usalp->errfile, "%2d CD-ROM\n", nSrom + 1); + fprintf((FILE *)usalp->errfile, "%2d TAPE \n", nStp + 1); + fprintf((FILE *)usalp->errfile, "%2d FLOPPY\n", nSflp + 1); + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + } + + /* ok, now let's sort this array of scsi devices */ + + qsort((void *) cmtbl, nlm, sizeof (amscsi_t), sort_mscsi); + + if (usalp->debug > 0) { + for (l = 0; l < nlm; l++) + fprintf((FILE *)usalp->errfile, + "%-4s = %5s(%d,%d,%d,%d) -> %s\n", + cmtbl[l].typ, + cmtbl[l].drv, + cmtbl[l].hba, + cmtbl[l].bus, + cmtbl[l].tgt, + cmtbl[l].lun, + cmtbl[l].dev); + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + } + + /* find root disk controller to make it usal 0 */ + + /* + * if we have disk(s) found in the mscsi table, we still + * don't know if the rootdisk is among these, there can + * be a IDE rootdisk as well, but it's not listed in + * the mscsi table. + */ + + t = 0; + if (nSdsk > 0) { + for (l = 0; l < nlm; l++) + if (strcmp(cmtbl[l].dev, DEV_ROOT) == 0) + t = l; + } else { + + /* + * we haven't found a disk in mscsi, so we definitely + * have an IDE disk on a wd adapter as IDE disks are + * not listed as SCSI disks in the kernel mscsi table + */ + ide_rootdisk = 1; + + } + + if (!(ide_rootdisk) && (usalp->debug > 0)) { + fprintf((FILE *)usalp->errfile, + "root = %5s(%d,%d,%d,%d) -> %s\n", + cmtbl[t].drv, + cmtbl[t].hba, + cmtbl[t].bus, + cmtbl[t].tgt, + cmtbl[t].lun, + cmtbl[t].dev); + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + } + + /* calculate usal from drv, hba and bus */ + + strcpy(drvid, ""); + + for (l = 0, s = t; l < nlm; l++, s = (t + l) % nlm) { + + if (strcmp(drvid, cmtbl[s].drv) != 0) { + strcpy(drvid, cmtbl[s].drv); + lhba = cmtbl[s].hba; + lbus = cmtbl[s].bus; + cmtbl[s].usal = ++nusal; + + } else if (cmtbl[s].hba != lhba) { + lhba = cmtbl[s].hba; + lbus = cmtbl[s].bus; + cmtbl[s].usal = ++nusal; + + } else if (cmtbl[s].bus != lbus) { + lbus = cmtbl[s].bus; + cmtbl[s].usal = ++nusal; + } else { + cmtbl[s].usal = nusal; + } + sdidevs[cmtbl[s].usal][cmtbl[s].tgt][cmtbl[s].lun].open = 0; + + /* check whether we want to open all devices or it's a CDROM */ + + if ((scan_all) || (strcmp(cmtbl[s].typ, T_CDROM) == 0)) + sdidevs[cmtbl[s].usal][cmtbl[s].tgt][cmtbl[s].lun].valid = 1; + + /* check whether we have an IDE/ATAPI device */ + + if (strcmp(cmtbl[s].drv, DRV_ATAPI) == 0) + sdidevs[cmtbl[s].usal][cmtbl[s].tgt][cmtbl[s].lun].atapi = 1; + + /* don't open a USB device if enable_usb is not set */ + + if (strcmp(cmtbl[s].drv, DRV_USB) == 0) + sdidevs[cmtbl[s].usal][cmtbl[s].tgt][cmtbl[s].lun].valid = enable_usb; + + /* don't open a IDE/ATAPI device which is missing but configured */ + + if (strcmp(cmtbl[s].drv, DRV_NOHA) == 0) + sdidevs[cmtbl[s].usal][cmtbl[s].tgt][cmtbl[s].lun].valid = 0; + + + sdidevs[cmtbl[s].usal][cmtbl[s].tgt][cmtbl[s].lun].lmscsi = s; + + } + + + /* open all yet valid device nodes */ + + for (s = 0; s < MAX_SCG; s++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + + if (sdidevs[s][t][l].valid == 0) + continue; + + /* Open pass-through device node */ + + mscsi = sdidevs[s][t][l].lmscsi; + + strcpy(dname, cmtbl[mscsi].dev); + + /* + * ------------------------------------------------------------------ + * NOTE: If we can't open the device, we will set the device invalid! + * ------------------------------------------------------------------ + */ + errno = 0; + if ((fd = open(dname, (O_RDONLY | O_NONBLOCK))) < 0) { + sdidevs[s][t][l].valid = 0; + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "%5s(%d,%d,%d,%d) -> %s open() failed: errno = %d (%s)\n", + cmtbl[mscsi].drv, + cmtbl[mscsi].hba, + cmtbl[mscsi].bus, + cmtbl[mscsi].tgt, + cmtbl[mscsi].lun, + cmtbl[mscsi].dev, + errno, + strerror(errno)); + } + continue; + } + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "%d,%d,%d => %5s(%d,%d,%d,%d) -> %d : %s \n", + s, t, l, + cmtbl[mscsi].drv, + cmtbl[mscsi].hba, + cmtbl[mscsi].bus, + cmtbl[mscsi].tgt, + cmtbl[mscsi].lun, + cmtbl[mscsi].usal, + cmtbl[mscsi].dev); + } + + sdidevs[s][t][l].fd = fd; + sdidevs[s][t][l].open = 1; + nopen++; + usallocal(usalp)->usalfiles[s][t][l] = (short) fd; + } + } + } + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + fprintf((FILE *)usalp->errfile, "nopen = %d devices \n", nopen); + fprintf((FILE *)usalp->errfile, "-------------------- \n"); + } + + return (nopen); +} + + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + int f, b, t, l; + int nopen = 0; + char devname[64]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if (*device != '\0') { /* we don't allow old dev usage */ + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' no longer supported on this OS"); + return (-1); + } + + return (openserver_init(usalp)); + +} + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + + sdidevs[b][t][l].fd = -1; + sdidevs[b][t][l].open = 0; + sdidevs[b][t][l].valid = 0; + + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (max_dma); +} + + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); + + /* + * We don't know the initiator ID yet, but we can if we parse the + * output of the command 'cat /dev/string/cfg | grep "%adapter"' + * + * Sample line: + * + * %adapter 0xE800-0xE8FF 11 - type=alad ha=0 bus=0 id=7 fts=sto + * + * This tells us that the alad controller 0 has an id of 7 ! + * The parsing should be done in openserver_init(). + * + */ +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (sdidevs[usal_scsibus(usalp)][usal_target(usalp)][usal_lun(usalp)].atapi); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); /* no scsi reset available */ +} + +static void +cp_usal2sco(struct scsicmd2 *sco, struct usal_cmd *usal) +{ + sco->cmd.data_ptr = (char *) usal->addr; + sco->cmd.data_len = usal->size; + sco->cmd.cdb_len = usal->cdb_len; + + sco->sense_len = usal->sense_len; + sco->sense_ptr = usal->u_sense.cmd_sense; + + if (!(usal->flags & SCG_RECV_DATA) && (usal->size > 0)) + sco->cmd.is_write = 1; + + if (usal->cdb_len == SC_G0_CDBLEN) + memcpy(sco->cmd.cdb, &usal->cdb.g0_cdb, usal->cdb_len); + + if (usal->cdb_len == SC_G1_CDBLEN) + memcpy(sco->cmd.cdb, &usal->cdb.g1_cdb, usal->cdb_len); + + if (usal->cdb_len == SC_G5_CDBLEN) + memcpy(sco->cmd.cdb, &usal->cdb.g5_cdb, usal->cdb_len); +} + + +static void +cp_sco2usal(struct scsicmd2 *sco, struct usal_cmd *usal) +{ + usal->size = sco->cmd.data_len; + + memset(&usal->scb, 0, sizeof (usal->scb)); + + if (sco->sense_len > SCG_MAX_SENSE) + usal->sense_count = SCG_MAX_SENSE; + else + usal->sense_count = sco->sense_len; + + usal->resid = 0; + + usal->u_scb.cmd_scb[0] = sco->cmd.target_sts; + +} + + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + struct scsicmd2 scsi_cmd; + int i; + Uchar sense_buf[SCG_MAX_SENSE]; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + memset(&scsi_cmd, 0, sizeof (scsi_cmd)); + memset(sense_buf, 0, sizeof (sense_buf)); + scsi_cmd.sense_ptr = sense_buf; + scsi_cmd.sense_len = sizeof (sense_buf); + cp_usal2sco(&scsi_cmd, sp); + + errno = 0; + sp->ux_errno = 0; + sp->error = SCG_NO_ERROR; + for (;;) { + int ioctlStatus; + struct scsicmd s_cmd; + + if (scsiusercmd) { /* Use SCSIUSERCMD ioctl() */ + if (usalp->debug > 1) { + fprintf((FILE *)usalp->errfile, "calling SCSIUSERCMD ioctl()\n"); + } + + if ((ioctlStatus = ioctl(usalp->fd, SCSIUSERCMD, &(scsi_cmd.cmd))) < 0) { + if (usalp->debug > 1) { + fprintf((FILE *)usalp->errfile, "returning from SCSIUSERCMD ioctl()\n"); + } + if (errno == EINTR) + continue; + + cp_sco2usal(&scsi_cmd, sp); + sp->ux_errno = errno; + if (errno == 0) + sp->ux_errno = EIO; + sp->error = SCG_RETRYABLE; + + return (0); + } + + if (usalp->debug > 1) { + fprintf((FILE *)usalp->errfile, "returning from SCSIUSERCMD ioctl()\n"); + } + cp_sco2usal(&scsi_cmd, sp); + sp->ux_errno = errno; + + if (scsi_cmd.cmd.target_sts & 0x02) { /* Check Condition & get Sense */ + + if (sp->sense_len > SCG_MAX_SENSE) + sp->sense_len = SCG_MAX_SENSE; + + memset((caddr_t)&s_cmd, 0, sizeof (s_cmd)); + + s_cmd.data_ptr = (caddr_t) sp->u_sense.cmd_sense; + s_cmd.data_len = sp->sense_len; + s_cmd.is_write = 0; + s_cmd.cdb[0] = SC_REQUEST_SENSE; + + while (((ioctlStatus = ioctl(usalp->fd, SCSIUSERCMD, &s_cmd)) < 0) && + (errno == EINTR)) + ; + + sp->sense_count = sp->sense_len; + sp->ux_errno = errno; + + if (errno == 0) + sp->ux_errno = EIO; + sp->error = SCG_NO_ERROR; + } + + if (usalp->debug > 0) { + if (errno != 0) + fprintf((FILE *)usalp->errfile, "ux_errno: %d (%s) \n", sp->ux_errno, strerror(sp->ux_errno)); + if (sp->u_scb.cmd_scb[0] != 0) + fprintf((FILE *)usalp->errfile, "tgt_stat: %d \n", sp->u_scb.cmd_scb[0]); + } + break; + + } else { /* Use SCSIUSERCMD2 ioctl() */ + if (usalp->debug > 1) { + fprintf((FILE *)usalp->errfile, "calling SCSIUSERCMD2 ioctl()\n"); + } + + if ((ioctlStatus = ioctl(usalp->fd, SCSIUSERCMD2, &scsi_cmd)) < 0) { + if (usalp->debug > 1) { + fprintf((FILE *)usalp->errfile, "returning from SCSIUSERCMD2 ioctl()\n"); + } + if (errno == EINTR) + continue; + + cp_sco2usal(&scsi_cmd, sp); + sp->ux_errno = errno; + if (errno == 0) + sp->ux_errno = EIO; + sp->error = SCG_RETRYABLE; + + return (0); + } + if (usalp->debug > 1) { + fprintf((FILE *)usalp->errfile, "returning from SCSIUSERCMD2 ioctl()\n"); + } + + cp_sco2usal(&scsi_cmd, sp); + sp->ux_errno = errno; + + if (scsi_cmd.cmd.target_sts & 0x02) { /* Check Condition */ + if (errno == 0) + sp->ux_errno = EIO; + sp->error = SCG_NO_ERROR; + } + + if (usalp->debug > 0) { + if (errno != 0) + fprintf((FILE *)usalp->errfile, "ux_errno: %d (%s) \n", sp->ux_errno, strerror(sp->ux_errno)); + if (sp->u_scb.cmd_scb[0] != 0) + fprintf((FILE *)usalp->errfile, "tgt_stat: %d \n", sp->u_scb.cmd_scb[0]); + } + break; + + } + } + + return (0); +} + +#define sense u_sense.Sense diff --git a/libusal/scsi-os2.c b/libusal/scsi-os2.c new file mode 100644 index 0000000..5758b8d --- /dev/null +++ b/libusal/scsi-os2.c @@ -0,0 +1,630 @@ +/* + * 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. + * + */ + +/* @(#)scsi-os2.c 1.25 04/01/15 Copyright 1998 J. Schilling, C. Wohlgemuth */ +/* + * Interface for the OS/2 ASPI-Router ASPIROUT.SYS ((c) D. Dorau). + * This additional driver is a prerequisite for using cdrecord. + * Get it from HOBBES or LEO. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * XXX it currently uses static SRB and for this reason is not reentrant + * + * Copyright (c) 1998 J. Schilling + * Copyright (c) 1998 C. Wohlgemuth for this interface. + */ +/* + * 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. + */ + +#undef sense + +/*#define DEBUG*/ + +/* For AspiRouter */ +#include "usal/srb_os2.h" + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-os2.c-1.25"; /* The version for this transport*/ + +#define FILE_OPEN 0x0001 +#define OPEN_SHARE_DENYREADWRITE 0x0010 +#define OPEN_ACCESS_READWRITE 0x0002 +#define DC_SEM_SHARED 0x01 +#define OBJ_TILE 0x0040 +#define PAG_READ 0x0001 +#define PAG_WRITE 0x0002 +#define PAG_COMMIT 0x0010 + +typedef unsigned long LHANDLE; +typedef unsigned long ULONG; +typedef unsigned char *PSZ; +typedef unsigned short USHORT; +typedef unsigned char UCHAR; + +typedef LHANDLE HFILE; +typedef ULONG HEV; + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + int dummy; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#define MAX_DMA_OS2 (63*1024) /* ASPI-Router allows up to 64k */ + +static void *buffer = NULL; +static HFILE driver_handle = 0; +static HEV postSema = 0; + +static BOOL open_driver(SCSI *usalp); +static BOOL close_driver(void); +static ULONG wait_post(ULONG ulTimeOut); +static BOOL init_buffer(void* mem); +static void exit_func(void); +static void set_error(SRB *srb, struct usal_cmd *sp); + + +static void +exit_func() +{ + if (!close_driver()) + fprintf(stderr, "Cannot close OS/2-ASPI-Router!\n"); +} + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "ASPI", "Generic transport independent SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + } + + if (!open_driver(usalp)) /* Try to open ASPI-Router */ + return (-1); + atexit(exit_func); /* Install Exit Function which closes the ASPI-Router */ + + /* + * Success after all + */ + return (1); +} + +static int +usalo_close(SCSI *usalp) +{ + exit_func(); + return (0); +} + +static long +usalo_maxdma(SCSI *cgp, long amt) +{ + long maxdma = MAX_DMA_OS2; + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + ULONG rc; + +#ifdef DEBUG + fprintf((FILE *)usalp->errfile, "usalo_getbuf: %ld bytes\n", amt); +#endif + rc = DosAllocMem(&buffer, amt, OBJ_TILE | PAG_READ | PAG_WRITE | PAG_COMMIT); + + if (rc) { + fprintf((FILE *)usalp->errfile, "Cannot allocate buffer.\n"); + return ((void *)0); + } + usalp->bufbase = buffer; + +#ifdef DEBUG + fprintf((FILE *)usalp->errfile, "Buffer allocated at: 0x%x\n", usalp->bufbase); +#endif + + /* Lock memory */ + if (init_buffer(usalp->bufbase)) + return (usalp->bufbase); + + fprintf((FILE *)usalp->errfile, "Cannot lock memory buffer.\n"); + return ((void *)0); /* Error */ +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase && DosFreeMem(usalp->bufbase)) { + fprintf((FILE *)usalp->errfile, + "Cannot free buffer memory for ASPI-Router!\n"); /* Free our memory buffer if not already done */ + } + if (buffer == usalp->bufbase) + buffer = NULL; + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + return (TRUE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + /* + * Return fake + */ + return (1); +} + + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + + +static int +usalo_reset(SCSI *usalp, int what) +{ + ULONG rc; /* return value */ + ULONG cbreturn; + ULONG cbParam; + BOOL success; +static SRB SRBlock; /* XXX makes it non reentrant */ + + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + /* + * XXX Does this reset TGT or BUS ??? + */ + SRBlock.cmd = SRB_Reset; /* reset device */ + SRBlock.ha_num = usal_scsibus(usalp); /* host adapter number */ + SRBlock.flags = SRB_Post; /* posting enabled */ + SRBlock.u.res.target = usal_target(usalp); /* target id */ + SRBlock.u.res.lun = usal_lun(usalp); /* target LUN */ + + rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof (SRB), &cbParam, + (void*) &SRBlock, sizeof (SRB), &cbreturn); + if (rc) { + fprintf((FILE *)usalp->errfile, + "DosDevIOCtl() failed in resetDevice.\n"); + return (1); /* DosDevIOCtl failed */ + } else { + success = wait_post(40000); /** wait for SRB being processed */ + if (success) + return (2); + } + if (SRBlock.status != SRB_Done) + return (3); +#ifdef DEBUG + fprintf((FILE *)usalp->errfile, + "resetDevice of host: %d target: %d lun: %d successful.\n", usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + fprintf((FILE *)usalp->errfile, + "SRBlock.ha_status: 0x%x, SRBlock.target_status: 0x%x, SRBlock.satus: 0x%x\n", + SRBlock.u.cmd.ha_status, SRBlock.u.cmd.target_status, SRBlock.status); +#endif + return (0); +} + +/* + * Set error flags + */ +static void +set_error(SRB *srb, struct usal_cmd *sp) +{ + switch (srb->status) { + + case SRB_InvalidCmd: /* 0x80 Invalid SCSI request */ + case SRB_InvalidHA: /* 0x81 Invalid host adapter number */ + case SRB_BadDevice: /* 0x82 SCSI device not installed */ + sp->error = SCG_FATAL; + sp->ux_errno = EINVAL; /* Should we ever return != EIO */ + sp->ux_errno = EIO; + break; + + + case SRB_Busy: /* 0x00 SCSI request in progress */ + case SRB_Aborted: /* 0x02 SCSI aborted by host */ + case SRB_BadAbort: /* 0x03 Unable to abort SCSI request */ + case SRB_Error: /* 0x04 SCSI request completed with error */ + default: + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + } +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + ULONG rc; /* return value */ +static SRB SRBlock; /* XXX makes it non reentrant */ + Ulong cbreturn; + Ulong cbParam; + UCHAR* ptr; + + if (usalp->fd < 0) { /* Set in usalo_open() */ + sp->error = SCG_FATAL; + return (0); + } + + if (sp->cdb_len > sizeof (SRBlock.u.cmd.cdb_st)) { /* commandsize too big */ + sp->error = SCG_FATAL; + sp->ux_errno = EINVAL; + fprintf((FILE *)usalp->errfile, + "sp->cdb_len > SRBlock.u.cmd.cdb_st. Fatal error in usalo_send, exiting...\n"); + return (-1); + } + + /* clear command block */ + fillbytes((caddr_t)&SRBlock.u.cmd.cdb_st, sizeof (SRBlock.u.cmd.cdb_st), '\0'); + /* copy cdrecord command into SRB */ + movebytes(&sp->cdb, &SRBlock.u.cmd.cdb_st, sp->cdb_len); + + /* Build SRB command block */ + SRBlock.cmd = SRB_Command; + SRBlock.ha_num = usal_scsibus(usalp); /* host adapter number */ + + SRBlock.flags = SRB_Post; /* flags */ + + SRBlock.u.cmd.target = usal_target(usalp); /* Target SCSI ID */ + SRBlock.u.cmd.lun = usal_lun(usalp); /* Target SCSI LUN */ + SRBlock.u.cmd.data_len = sp->size; /* # of bytes transferred */ + SRBlock.u.cmd.data_ptr = 0; /* pointer to data buffer */ + SRBlock.u.cmd.sense_len = sp->sense_len; /* length of sense buffer */ + + SRBlock.u.cmd.link_ptr = 0; /* pointer to next SRB */ + SRBlock.u.cmd.cdb_len = sp->cdb_len; /* SCSI command length */ + + /* Specify direction */ + if (sp->flags & SCG_RECV_DATA) { + SRBlock.flags |= SRB_Read; + } else { + if (sp->size > 0) { + SRBlock.flags |= SRB_Write; + if (usalp->bufbase != sp->addr) { /* Copy only if data not in ASPI-Mem */ + movebytes(sp->addr, usalp->bufbase, sp->size); + } + } else { + SRBlock.flags |= SRB_NoTransfer; + } + } + sp->error = SCG_NO_ERROR; + sp->sense_count = 0; + sp->u_scb.cmd_scb[0] = 0; + sp->resid = 0; + + /* execute SCSI command */ + rc = DosDevIOCtl(driver_handle, 0x92, 0x02, + (void*) &SRBlock, sizeof (SRB), &cbParam, + (void*) &SRBlock, sizeof (SRB), &cbreturn); + + if (rc) { /* An error occured */ + fprintf((FILE *)usalp->errfile, + "DosDevIOCtl() in sendCommand failed.\n"); + sp->error = SCG_FATAL; + sp->ux_errno = EIO; /* Später vielleicht errno einsetzen */ + return (rc); + } else { + /* Wait until the command is processed */ + rc = wait_post(sp->timeout*1000); + if (rc) { /* An error occured */ + if (rc == 640) { + /* Timeout */ + sp->error = SCG_TIMEOUT; + sp->ux_errno = EIO; + fprintf((FILE *)usalp->errfile, + "Timeout during SCSI-Command.\n"); + return (1); + } + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + fprintf((FILE *)usalp->errfile, + "Fatal Error during DosWaitEventSem().\n"); + return (1); + } + + /* The command is processed */ + if (SRBlock.status == SRB_Done) { /* succesful completion */ +#ifdef DEBUG + fprintf((FILE *)usalp->errfile, + "Command successful finished. SRBlock.status=0x%x\n\n", SRBlock.status); +#endif + sp->sense_count = 0; + sp->resid = 0; + if (sp->flags & SCG_RECV_DATA) { /* We read data */ + if (sp->addr && sp->size) { + if (usalp->bufbase != sp->addr) /* Copy only if data not in ASPI-Mem */ + movebytes(usalp->bufbase, sp->addr, SRBlock.u.cmd.data_len); + ptr = (UCHAR*)sp->addr; + sp->resid = sp->size - SRBlock.u.cmd.data_len; /*nicht übertragene bytes. Korrekt berechnet???*/ + } + } /* end of if (sp->flags & SCG_RECV_DATA) */ + if (SRBlock.u.cmd.target_status == SRB_CheckStatus) { /* Sense data valid */ + sp->sense_count = (int)SRBlock.u.cmd.sense_len; + if (sp->sense_count > sp->sense_len) + sp->sense_count = sp->sense_len; + + ptr = (UCHAR*)&SRBlock.u.cmd.cdb_st; + ptr += SRBlock.u.cmd.cdb_len; + + fillbytes(&sp->u_sense.Sense, sizeof (sp->u_sense.Sense), '\0'); + movebytes(ptr, &sp->u_sense.Sense, sp->sense_len); + + sp->u_scb.cmd_scb[0] = SRBlock.u.cmd.target_status; + sp->ux_errno = EIO; /* Später differenzieren? */ + } + return (0); + } + /* SCSI-Error occured */ + set_error(&SRBlock, sp); + + if (SRBlock.u.cmd.target_status == SRB_CheckStatus) { /* Sense data valid */ + sp->sense_count = (int)SRBlock.u.cmd.sense_len; + if (sp->sense_count > sp->sense_len) + sp->sense_count = sp->sense_len; + + ptr = (UCHAR*)&SRBlock.u.cmd.cdb_st; + ptr += SRBlock.u.cmd.cdb_len; + + fillbytes(&sp->u_sense.Sense, sizeof (sp->u_sense.Sense), '\0'); + movebytes(ptr, &sp->u_sense.Sense, sp->sense_len); + + sp->u_scb.cmd_scb[0] = SRBlock.u.cmd.target_status; + } + if (sp->flags & SCG_RECV_DATA) { + if (sp->addr && sp->size) { + if (usalp->bufbase != sp->addr) /* Copy only if data not in ASPI-Mem */ + movebytes(usalp->bufbase, sp->addr, SRBlock.u.cmd.data_len); + } + } +#ifdef really + sp->resid = SRBlock.u.cmd.data_len; /* XXXXX Got no Data ????? */ +#else + sp->resid = sp->size - SRBlock.u.cmd.data_len; +#endif + return (1); + } +} + +/*************************************************************************** + * * + * BOOL open_driver() * + * * + * Opens the ASPI Router device driver and sets device_handle. * + * Returns: * + * TRUE - Success * + * FALSE - Unsuccessful opening of device driver * + * * + * Preconditions: ASPI Router driver has be loaded * + * * + ***************************************************************************/ +static BOOL +open_driver(SCSI *usalp) +{ + ULONG rc; /* return value */ + ULONG ActionTaken; /* return value */ + USHORT openSemaReturn; /* return value */ + ULONG cbreturn; + ULONG cbParam; + + if (driver_handle) /* ASPI-Router already opened */ + return (TRUE); + + rc = DosOpen((PSZ) "aspirou$", /* open driver*/ + &driver_handle, + &ActionTaken, + 0, + 0, + FILE_OPEN, + OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, + NULL); + if (rc) { + fprintf((FILE *)usalp->errfile, + "Cannot open ASPI-Router!\n"); + + return (FALSE); /* opening failed -> return false*/ + } + + /* Init semaphore */ + if (DosCreateEventSem(NULL, &postSema, /* create event semaphore */ + DC_SEM_SHARED, 0)) { + DosClose(driver_handle); + fprintf((FILE *)usalp->errfile, + "Cannot create event semaphore!\n"); + + return (FALSE); + } + rc = DosDevIOCtl(driver_handle, 0x92, 0x03, /* pass semaphore handle */ + (void*) &postSema, sizeof (HEV), /* to driver */ + &cbParam, (void*) &openSemaReturn, + sizeof (USHORT), &cbreturn); + + if (rc||openSemaReturn) { /* Error */ + DosCloseEventSem(postSema); + DosClose(driver_handle); + return (FALSE); + } + return (TRUE); +} + +/*************************************************************************** + * * + * BOOL close_driver() * + * * + * Closes the device driver * + * Returns: * + * TRUE - Success * + * FALSE - Unsuccessful closing of device driver * + * * + * Preconditions: ASPI Router driver has be opened with open_driver * + * * + ***************************************************************************/ +static BOOL +close_driver() +{ + ULONG rc; /* return value */ + + if (driver_handle) { + rc = DosClose(driver_handle); + if (rc) + return (FALSE); /* closing failed -> return false */ + driver_handle = 0; + if (DosCloseEventSem(postSema)) + fprintf(stderr, "Cannot close event semaphore!\n"); + if (buffer && DosFreeMem(buffer)) { + fprintf(stderr, + "Cannot free buffer memory for ASPI-Router!\n"); /* Free our memory buffer if not already done */ + } + buffer = NULL; + } + return (TRUE); +} + +static ULONG +wait_post(ULONG ulTimeOut) +{ + ULONG count = 0; + ULONG rc; /* return value */ + +/* rc = DosWaitEventSem(postSema, -1);*/ /* wait forever*/ + rc = DosWaitEventSem(postSema, ulTimeOut); + DosResetEventSem(postSema, &count); + return (rc); +} + +static BOOL +init_buffer(void *mem) +{ + ULONG rc; /* return value */ + USHORT lockSegmentReturn; /* return value */ + Ulong cbreturn; + Ulong cbParam; + + rc = DosDevIOCtl(driver_handle, 0x92, 0x04, /* pass buffers pointer */ + (void*) mem, sizeof (void*), /* to driver */ + &cbParam, (void*) &lockSegmentReturn, + sizeof (USHORT), &cbreturn); + if (rc) + return (FALSE); /* DosDevIOCtl failed */ + if (lockSegmentReturn) + return (FALSE); /* Driver could not lock segment */ + return (TRUE); +} +#define sense u_sense.Sense diff --git a/libusal/scsi-osf.c b/libusal/scsi-osf.c new file mode 100644 index 0000000..79d0708 --- /dev/null +++ b/libusal/scsi-osf.c @@ -0,0 +1,445 @@ +/* + * 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. + * + */ + +/* @(#)scsi-osf.c 1.26 04/01/15 Copyright 1998 J. Schilling */ +/* + * Interface for Digital UNIX (OSF/1 generic SCSI implementation (/dev/cam). + * + * Created out of the hacks from: + * Stefan Traby <stefan@sime.com> and + * Bruno Achauer <bruno@tk.uni-linz.ac.at> + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998 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 <sys/types.h> +#include <io/common/iotypes.h> +#include <io/cam/cam.h> +#include <io/cam/uagt.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-osf.c-1.26"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + int usalfile; /* Used for ioctl() */ + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +static BOOL scsi_checktgt(SCSI *usalp, int f, int busno, int tgt, int tlun); + +/* + * I don't have any documentation about CAM + */ +#define MAX_DMA_OSF_CAM (64*1024) + +#ifndef AUTO_SENSE_LEN +# define AUTO_SENSE_LEN 32 /* SCG_MAX_SENSE */ +#endif + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "CAM", "Generic transport independent SCSI (Common Access Method)", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int b; + register int t; + register int l; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + usallocal(usalp)->usalfile = -1; + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = 0; + } + } + } + + if (usallocal(usalp)->usalfile != -1) /* multiple opens ??? */ + return (1); /* not yet ready .... */ + + if ((usallocal(usalp)->usalfile = open("/dev/cam", O_RDWR, 0)) < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '/dev/cam'"); + return (-1); + } + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + /* scsi_checktgt() ??? */ + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = 1; + return (1); + } + /* + * There seems to be no clean way to check whether + * a SCSI bus is present in the current system. + * scsi_checktgt() is used as a workaround for this problem. + */ + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + if (scsi_checktgt(usalp, usallocal(usalp)->usalfile, b, t, 0)) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = 1; + /* + * Found a target on this bus. + * Comment the 'break' for a complete scan. + */ + break; + } + } + } + return (1); +} + +static int +usalo_close(SCSI *usalp) +{ + if (usalp->local == NULL) + return (-1); + + if (usallocal(usalp)->usalfile >= 0) + close(usallocal(usalp)->usalfile); + usallocal(usalp)->usalfile = -1; + return (0); +} + +/* + * We send a test unit ready command to the target to check whether the + * OS is considering this target to be valid. + * XXX Is this really needed? We should rather let the cmd fail later. + */ +static BOOL +scsi_checktgt(SCSI *usalp, int f, int busno, int tgt, int tlun) +{ + struct usal_cmd *sp = usalp->scmd; + struct usal_cmd sc; + int ret; + int ofd = usalp->fd; + int obus = usal_scsibus(usalp); + int otgt = usal_target(usalp); + int olun = usal_lun(usalp); + + usal_settarget(usalp, busno, tgt, tlun); + usalp->fd = f; + + sc = *sp; + fillbytes((caddr_t)sp, sizeof (*sp), '\0'); + sp->addr = (caddr_t)0; + sp->size = 0; + sp->flags = SCG_DISRE_ENA | SCG_SILENT; + sp->cdb_len = SC_G0_CDBLEN; + sp->sense_len = CCS_SENSE_LEN; + sp->cdb.g0_cdb.cmd = SC_TEST_UNIT_READY; + sp->cdb.g0_cdb.lun = usal_lun(usalp); + + usalo_send(usalp); + usal_settarget(usalp, obus, otgt, olun); + usalp->fd = ofd; + + if (sp->error != SCG_FATAL) + return (TRUE); + ret = sp->ux_errno != EINVAL; + *sp = sc; + return (ret); +} + + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = MAX_DMA_OSF_CAM; + + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + if (usallocal(usalp)->usalfiles[busno][t][0] != 0) + return (TRUE); + } + return (FALSE); +} + + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (usalp->local == NULL) + return (-1); + + return ((busno < 0 || busno >= MAX_SCG) ? -1 : usallocal(usalp)->usalfile); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + CCB_SCSIIO ccb; + UAGT_CAM_CCB ua; + unsigned char *cdb; + CCB_RELSIM relsim; + UAGT_CAM_CCB relua; + int i; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + fillbytes(&ua, sizeof (UAGT_CAM_CCB), 0); + fillbytes(&ccb, sizeof (CCB_SCSIIO), 0); + + ua.uagt_ccb = (CCB_HEADER *) &ccb; + ua.uagt_ccblen = sizeof (CCB_SCSIIO); + ccb.cam_ch.my_addr = (CCB_HEADER *) &ccb; + ccb.cam_ch.cam_ccb_len = sizeof (CCB_SCSIIO); + + ua.uagt_snsbuf = ccb.cam_sense_ptr = sp->u_sense.cmd_sense; + ua.uagt_snslen = ccb.cam_sense_len = AUTO_SENSE_LEN; + + cdb = (unsigned char *) ccb.cam_cdb_io.cam_cdb_bytes; + + ccb.cam_timeout = sp->timeout; + + ccb.cam_data_ptr = ua.uagt_buffer = (Uchar *) sp->addr; + ccb.cam_dxfer_len = ua.uagt_buflen = sp->size; + ccb.cam_ch.cam_func_code = XPT_SCSI_IO; + ccb.cam_ch.cam_flags = 0; /* CAM_DIS_CALLBACK; */ + + if (sp->size == 0) { + ccb.cam_data_ptr = ua.uagt_buffer = (Uchar *) NULL; + ccb.cam_ch.cam_flags |= CAM_DIR_NONE; + } else { + if (sp->flags & SCG_RECV_DATA) { + ccb.cam_ch.cam_flags |= CAM_DIR_IN; + } else { + ccb.cam_ch.cam_flags |= CAM_DIR_OUT; + } + } + + ccb.cam_cdb_len = sp->cdb_len; + for (i = 0; i < sp->cdb_len; i++) + cdb[i] = sp->cdb.cmd_cdb[i]; + + ccb.cam_ch.cam_path_id = usal_scsibus(usalp); + ccb.cam_ch.cam_target_id = usal_target(usalp); + ccb.cam_ch.cam_target_lun = usal_lun(usalp); + + sp->sense_count = 0; + sp->ux_errno = 0; + sp->error = SCG_NO_ERROR; + + + if (ioctl(usalp->fd, UAGT_CAM_IO, (caddr_t) &ua) < 0) { + sp->ux_errno = geterrno(); + sp->error = SCG_FATAL; + if (usalp->debug > 0) { + errmsg("ioctl(fd, UAGT_CAM_IO, dev=%d,%d,%d) failed.\n", + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + } + return (0); + } + if (usalp->debug > 0) { + errmsgno(EX_BAD, "cam_status = 0x%.2X scsi_status = 0x%.2X dev=%d,%d,%d\n", + ccb.cam_ch.cam_status, + ccb.cam_scsi_status, + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + fflush(stderr); + } + switch (ccb.cam_ch.cam_status & CAM_STATUS_MASK) { + + case CAM_REQ_CMP: break; + + case CAM_SEL_TIMEOUT: sp->error = SCG_FATAL; + sp->ux_errno = EIO; + break; + + case CAM_CMD_TIMEOUT: sp->error = SCG_TIMEOUT; + sp->ux_errno = EIO; + break; + + default: sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + } + + sp->u_scb.cmd_scb[0] = ccb.cam_scsi_status; + + if (ccb.cam_ch.cam_status & CAM_AUTOSNS_VALID) { + sp->sense_count = MIN(ccb.cam_sense_len - ccb.cam_sense_resid, + SCG_MAX_SENSE); + sp->sense_count = MIN(sp->sense_count, sp->sense_len); + if (sp->sense_len < 0) + sp->sense_count = 0; + } + sp->resid = ccb.cam_resid; + + + /* + * this is perfectly wrong. + * But without this, we hang... + */ + if (ccb.cam_ch.cam_status & CAM_SIM_QFRZN) { + fillbytes(&relsim, sizeof (CCB_RELSIM), 0); + relsim.cam_ch.cam_ccb_len = sizeof (CCB_SCSIIO); + relsim.cam_ch.cam_func_code = XPT_REL_SIMQ; + relsim.cam_ch.cam_flags = CAM_DIR_IN | CAM_DIS_CALLBACK; + relsim.cam_ch.cam_path_id = usal_scsibus(usalp); + relsim.cam_ch.cam_target_id = usal_target(usalp); + relsim.cam_ch.cam_target_lun = usal_lun(usalp); + + relua.uagt_ccb = (struct ccb_header *) & relsim; /* wrong cast */ + relua.uagt_ccblen = sizeof (relsim); + relua.uagt_buffer = NULL; + relua.uagt_buflen = 0; + + if (ioctl(usalp->fd, UAGT_CAM_IO, (caddr_t) & relua) < 0) + errmsg("DEC CAM -> LMA\n"); + } + return (0); +} diff --git a/libusal/scsi-qnx.c b/libusal/scsi-qnx.c new file mode 100644 index 0000000..7342025 --- /dev/null +++ b/libusal/scsi-qnx.c @@ -0,0 +1,316 @@ +/* + * 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. + * + */ + +/* @(#)scsi-qnx.c 1.3 04/01/15 Copyright 1998-2003 J. Schilling */ +/* + * Interface for QNX (Neutrino generic SCSI implementation). + * First version adopted from the OSF-1 version by + * Kevin Chiles <kchiles@qnx.com> + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998-2003 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 <sys/mman.h> +#include <sys/types.h> +#include <sys/dcmd_cam.h> +#include <sys/cam_device.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-qnx.c-1.3"; /* The version for this transport*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + int fd; +}; + +#define usallocal(p) ((struct usal_local *)((p)->local)) +#define QNX_CAM_MAX_DMA (32*1024) + +#ifndef AUTO_SENSE_LEN +# define AUTO_SENSE_LEN 32 /* SCG_MAX_SENSE */ +#endif + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return ("Initial Version adopted from OSF-1 by QNX-people"); + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "CAM", "Generic transport independent SCSI (Common Access Method)", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int fd; + + if (device == NULL || *device == '\0') { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "'devname' must be specified on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + usallocal(usalp)->fd = -1; + } + + if (usallocal(usalp)->fd != -1) /* multiple open? */ + return (1); + + if ((usallocal(usalp)->fd = open(device, O_RDONLY, 0)) < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", device); + return (-1); + } + + usal_settarget(usalp, 0, 0, 0); + + return (1); +} + +static int +usalo_close(SCSI *usalp) +{ + if (usalp->local == NULL) + return (-1); + + if (usallocal(usalp)->fd >= 0) + close(usallocal(usalp)->fd); + usallocal(usalp)->fd = -1; + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = QNX_CAM_MAX_DMA; + + return (maxdma); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + void *addr; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "usalo_getbuf: %ld bytes\n", amt); + } + + if ((addr = mmap(NULL, amt, PROT_READ | PROT_WRITE | PROT_NOCACHE, + MAP_ANON | MAP_PHYS | MAP_NOX64K, NOFD, 0)) == MAP_FAILED) { + return (NULL); + } + + usalp->bufbase = addr; + return (addr); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + munmap(usalp->bufbase, QNX_CAM_MAX_DMA); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + return (FALSE); +} + + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (usalp->local == NULL) + return (-1); + + return ((busno < 0 || busno >= MAX_SCG) ? -1 : usallocal(usalp)->fd); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + cam_devinfo_t cinfo; + + if (devctl(usalp->fd, DCMD_CAM_DEVINFO, &cinfo, sizeof (cinfo), NULL) != EOK) { + return (TRUE); /* default to ATAPI */ + } + return ((cinfo.flags & DEV_ATAPI) ? TRUE : FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); +} + +static int +usalo_send(SCSI *usalp) +{ + int i; + struct usal_cmd *sp; + int icnt; + iov_t iov[3]; + CAM_PASS_THRU cpt; + + icnt = 1; + sp = usalp->scmd; + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + memset(&cpt, 0, sizeof (cpt)); + + sp->sense_count = 0; + sp->ux_errno = 0; + sp->error = SCG_NO_ERROR; + cpt.cam_timeout = sp->timeout; + cpt.cam_cdb_len = sp->cdb_len; + memcpy(cpt.cam_cdb, sp->cdb.cmd_cdb, sp->cdb_len); + + if (sp->sense_len != -1) { + cpt.cam_sense_len = sp->sense_len; + cpt.cam_sense_ptr = sizeof (cpt); /* XXX Offset from start of struct to data ??? */ + icnt++; + } else { + cpt.cam_flags |= CAM_DIS_AUTOSENSE; + } + + if (cpt.cam_dxfer_len = sp->size) { + icnt++; + cpt.cam_data_ptr = (paddr_t)sizeof (cpt) + cpt.cam_sense_len; + if (sp->flags & SCG_RECV_DATA) { + cpt.cam_flags |= CAM_DIR_IN; + } else { + cpt.cam_flags |= CAM_DIR_OUT; + } + } else { + cpt.cam_flags |= CAM_DIR_NONE; + } + + SETIOV(&iov[0], &cpt, sizeof (cpt)); + SETIOV(&iov[1], sp->u_sense.cmd_sense, cpt.cam_sense_len); + SETIOV(&iov[2], sp->addr, sp->size); + if (devctlv(usallocal(usalp)->fd, DCMD_CAM_PASS_THRU, icnt, icnt, iov, iov, NULL)) { + sp->ux_errno = geterrno(); + sp->error = SCG_FATAL; + if (usalp->debug > 0) { + errmsg("cam_io failed\n"); + } + return (0); + } + + sp->resid = cpt.cam_resid; + sp->u_scb.cmd_scb[0] = cpt.cam_scsi_status; + + switch (cpt.cam_status & CAM_STATUS_MASK) { + case CAM_REQ_CMP: + break; + + case CAM_SEL_TIMEOUT: + sp->error = SCG_FATAL; + sp->ux_errno = EIO; + break; + + case CAM_CMD_TIMEOUT: + sp->error = SCG_TIMEOUT; + sp->ux_errno = EIO; + break; + + default: + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + } + + if (cpt.cam_status & CAM_AUTOSNS_VALID) { + sp->sense_count = min(cpt.cam_sense_len - cpt.cam_sense_resid, + SCG_MAX_SENSE); + sp->sense_count = min(sp->sense_count, sp->sense_len); + if (sp->sense_len < 0) + sp->sense_count = 0; + } + + return (0); +} diff --git a/libusal/scsi-remote.c b/libusal/scsi-remote.c new file mode 100644 index 0000000..f9b40d6 --- /dev/null +++ b/libusal/scsi-remote.c @@ -0,0 +1,1213 @@ +/* + * 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. + * + */ + +#define USE_REMOTE +/* @(#)scsi-remote.c 1.18 06/01/12 Copyright 1990,2000-2003 J. Schilling */ +/* + * Remote SCSI user level command transport routines + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1990,2000-2003 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> + +#if !defined(HAVE_FORK) || !defined(HAVE_SOCKETPAIR) || !defined(HAVE_DUP2) +#undef USE_RCMD_RSH +#endif +/* + * We may work without getservbyname() if we restructure the code not to + * use the port number if we only use _rcmdrsh(). + */ +#if !defined(HAVE_GETSERVBYNAME) +#undef USE_REMOTE /* Cannot get rcmd() port # */ +#endif +#if (!defined(HAVE_NETDB_H) || !defined(HAVE_RCMD)) && !defined(USE_RCMD_RSH) +#undef USE_REMOTE /* There is no rcmd() */ +#endif + +#ifdef USE_REMOTE +#include <stdio.h> +#include <sys/types.h> +#include <fctldefs.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#include <errno.h> +#include <signal.h> +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <strdefs.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsitransp.h> + +#if defined(SIGDEFER) || defined(SVR4) +#define signal sigset +#endif + +/* + * On Cygwin, there are no privilleged ports. + * On UNIX, rcmd() uses privilleged port that only work for root. + */ +#ifdef IS_CYGWIN +#define privport_ok() (1) +#else +#ifdef HAVE_GETPPRIV +#define privport_ok() ppriv_ok() +#else +#define privport_ok() (geteuid() == 0) +#endif +#endif + +#define CMD_SIZE 80 + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +/*extern BOOL debug;*/ +LOCAL BOOL debug = 1; + +LOCAL char _usal_trans_version[] = "remote-1.18"; /* The version for remote SCSI */ +LOCAL char _usal_auth_cdrkit[] = "cdrkit-team"; /* The author for this module */ + +LOCAL int usalo_rsend __PR((SCSI *usalp)); +LOCAL char * usalo_rversion __PR((SCSI *usalp, int what)); +LOCAL int usalo_rhelp __PR((SCSI *usalp, FILE *f)); +LOCAL int usalo_ropen __PR((SCSI *usalp, char *device)); +LOCAL int usalo_rclose __PR((SCSI *usalp)); +LOCAL long usalo_rmaxdma __PR((SCSI *usalp, long amt)); +LOCAL void * usalo_rgetbuf __PR((SCSI *usalp, long amt)); +LOCAL void usalo_rfreebuf __PR((SCSI *usalp)); +LOCAL BOOL usalo_rhavebus __PR((SCSI *usalp, int busno)); +LOCAL int usalo_rfileno __PR((SCSI *usalp, int busno, int tgt, int tlun)); +LOCAL int usalo_rinitiator_id __PR((SCSI *usalp)); +LOCAL int usalo_risatapi __PR((SCSI *usalp)); +LOCAL int usalo_rreset __PR((SCSI *usalp, int what)); + +/* + * XXX We should rethink the fd parameter now that we introduced + * XXX the rscsirchar() function and most access of remfd is done + * XXX via usallocal(usalp)->remfd. + */ +LOCAL void rscsiabrt __PR((int sig)); +LOCAL int rscsigetconn __PR((SCSI *usalp, char *host)); +LOCAL char *rscsiversion __PR((SCSI *usalp, int fd, int what)); +LOCAL int rscsiopen __PR((SCSI *usalp, int fd, char *fname)); +LOCAL int rscsiclose __PR((SCSI *usalp, int fd)); +LOCAL int rscsimaxdma __PR((SCSI *usalp, int fd, long amt)); +LOCAL int rscsigetbuf __PR((SCSI *usalp, int fd, long amt)); +LOCAL int rscsifreebuf __PR((SCSI *usalp, int fd)); +LOCAL int rscsihavebus __PR((SCSI *usalp, int fd, int bus)); +LOCAL int rscsifileno __PR((SCSI *usalp, int fd, int busno, int tgt, int tlun)); +LOCAL int rscsiinitiator_id __PR((SCSI *usalp, int fd)); +LOCAL int rscsiisatapi __PR((SCSI *usalp, int fd)); +LOCAL int rscsireset __PR((SCSI *usalp, int fd, int what)); +LOCAL int rscsiscmd __PR((SCSI *usalp, int fd, struct usal_cmd *sp)); +LOCAL int rscsifillrbuf __PR((SCSI *usalp)); +LOCAL int rscsirchar __PR((SCSI *usalp, char *cp)); +LOCAL int rscsireadbuf __PR((SCSI *usalp, int fd, char *buf, int count)); +LOCAL void rscsivoidarg __PR((SCSI *usalp, int fd, int count)); +LOCAL int rscsicmd __PR((SCSI *usalp, int fd, char *name, char *cbuf)); +LOCAL void rscsisendcmd __PR((SCSI *usalp, int fd, char *name, char *cbuf)); +LOCAL int rscsigetline __PR((SCSI *usalp, int fd, char *line, int count)); +LOCAL int rscsireadnum __PR((SCSI *usalp, int fd)); +LOCAL int rscsigetstatus __PR((SCSI *usalp, int fd, char *name)); +LOCAL int rscsiaborted __PR((SCSI *usalp, int fd)); +#ifdef USE_RCMD_RSH +LOCAL int _rcmdrsh __PR((char **ahost, int inport, + const char *locuser, + const char *remuser, + const char *cmd, + const char *rsh)); +#ifdef HAVE_GETPPRIV +LOCAL BOOL ppriv_ok __PR((void)); +#endif +#endif + +/*--------------------------------------------------------------------------*/ + +#define READBUF_SIZE 128 + +struct usal_local { + int remfd; + char readbuf[READBUF_SIZE]; + char *readbptr; + int readbcnt; + BOOL isopen; + int rsize; + int wsize; + char *v_version; + char *v_author; + char *v_sccs_id; +}; + + +#define usallocal(p) ((struct usal_local *)((p)->local)) + +usal_ops_t remote_ops = { + usalo_rsend, /* "S" end */ + usalo_rversion, /* "V" ersion */ + usalo_rhelp, /* help */ + usalo_ropen, /* "O" pen */ + usalo_rclose, /* "C" lose */ + usalo_rmaxdma, /* "D" MA */ + usalo_rgetbuf, /* "M" alloc */ + usalo_rfreebuf, /* "F" free */ + usalo_rhavebus, /* "B" us */ + usalo_rfileno, /* "T" arget */ + usalo_rinitiator_id, /* "I" nitiator */ + usalo_risatapi, /* "A" tapi */ + usalo_rreset, /* "R" eset */ +}; + +/* + * Return our ops ptr. + */ +usal_ops_t * +usal_remote() +{ + return (&remote_ops); +} + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +LOCAL char * +usalo_rversion(usalp, what) + SCSI *usalp; + int what; +{ + int f; + + if (usalp->local == NULL) + return ((char *)0); + + f = usallocal(usalp)->remfd; + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + + case SCG_RVERSION: + if (usallocal(usalp)->v_version == NULL) + usallocal(usalp)->v_version = rscsiversion(usalp, f, SCG_VERSION); + return (usallocal(usalp)->v_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_RAUTHOR: + if (usallocal(usalp)->v_author == NULL) + usallocal(usalp)->v_author = rscsiversion(usalp, f, SCG_AUTHOR); + return (usallocal(usalp)->v_author); + case SCG_RSCCS_ID: + if (usallocal(usalp)->v_sccs_id == NULL) + usallocal(usalp)->v_sccs_id = rscsiversion(usalp, f, SCG_SCCS_ID); + return (usallocal(usalp)->v_sccs_id); + } + } + return ((char *)0); +} + +LOCAL int +usalo_rhelp(usalp, f) + SCSI *usalp; + FILE *f; +{ + __usal_help(f, "RSCSI", "Remote SCSI", + "REMOTE:", "rscsi@host:bus,target,lun", "REMOTE:rscsi@host:1,2,0", TRUE, FALSE); + return (0); +} + +LOCAL int +usalo_ropen(usalp, device) + SCSI *usalp; + char *device; +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int nopen = 0; + char devname[128]; + char *p; + + if (usalp->overbose) + fprintf(stderr, "Warning: Using remote SCSI interface.\n"); + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + + return (-1); + } + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + usallocal(usalp)->remfd = -1; + usallocal(usalp)->readbptr = usallocal(usalp)->readbuf; + usallocal(usalp)->readbcnt = 0; + usallocal(usalp)->isopen = FALSE; + usallocal(usalp)->rsize = 0; + usallocal(usalp)->wsize = 0; + usallocal(usalp)->v_version = NULL; + usallocal(usalp)->v_author = NULL; + usallocal(usalp)->v_sccs_id = NULL; + } + + if (device == NULL || (strncmp(device, "REMOTE", 6) != 0) || + (device = strchr(device, ':')) == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal remote device syntax"); + return (-1); + } + device++; + /* + * Save non user@host:device + */ + snprintf(devname, sizeof (devname), "%s", device); + + if ((p = strchr(devname, ':')) != NULL) + *p++ = '\0'; + + f = rscsigetconn(usalp, devname); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot get connection to remote host"); + return (-1); + } + usallocal(usalp)->remfd = f; + debug = usalp->debug; + if (rscsiopen(usalp, f, p) >= 0) { + nopen++; + usallocal(usalp)->isopen = TRUE; + } + return (nopen); +} + +LOCAL int +usalo_rclose(usalp) + SCSI *usalp; +{ + register int f; + int ret; + + if (usalp->local == NULL) + return (-1); + + if (usallocal(usalp)->v_version != NULL) { + free(usallocal(usalp)->v_version); + usallocal(usalp)->v_version = NULL; + } + if (usallocal(usalp)->v_author != NULL) { + free(usallocal(usalp)->v_author); + usallocal(usalp)->v_author = NULL; + } + if (usallocal(usalp)->v_sccs_id != NULL) { + free(usallocal(usalp)->v_sccs_id); + usallocal(usalp)->v_sccs_id = NULL; + } + + f = usallocal(usalp)->remfd; + if (f < 0 || !usallocal(usalp)->isopen) + return (0); + ret = rscsiclose(usalp, f); + usallocal(usalp)->isopen = FALSE; + close(f); + usallocal(usalp)->remfd = -1; + return (ret); +} + +LOCAL long +usalo_rmaxdma(usalp, amt) + SCSI *usalp; + long amt; +{ + if (usalp->local == NULL) + return (-1L); + + return (rscsimaxdma(usalp, usallocal(usalp)->remfd, amt)); +} + +LOCAL void * +usalo_rgetbuf(usalp, amt) + SCSI *usalp; + long amt; +{ + int ret; + + if (usalp->local == NULL) + return ((void *)0); + + ret = rscsigetbuf(usalp, usallocal(usalp)->remfd, amt); + if (ret < 0) + return ((void *)0); + +#ifdef HAVE_VALLOC + usalp->bufbase = (void *)valloc((size_t)amt); +#else + usalp->bufbase = (void *)malloc((size_t)amt); +#endif + if (usalp->bufbase == NULL) { + usalo_rfreebuf(usalp); + return ((void *)0); + } + return (usalp->bufbase); +} + +LOCAL void +usalo_rfreebuf(usalp) + SCSI *usalp; +{ + int f; + + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; + + if (usalp->local == NULL) + return; + + f = usallocal(usalp)->remfd; + if (f < 0 || !usallocal(usalp)->isopen) + return; + rscsifreebuf(usalp, f); +} + +LOCAL BOOL +usalo_rhavebus(usalp, busno) + SCSI *usalp; + int busno; +{ + if (usalp->local == NULL || busno < 0 || busno >= MAX_SCG) + return (FALSE); + + return (rscsihavebus(usalp, usallocal(usalp)->remfd, busno)); +} + +LOCAL int +usalo_rfileno(usalp, busno, tgt, tlun) + SCSI *usalp; + int busno; + int tgt; + int tlun; +{ + int f; + + if (usalp->local == NULL || + busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + f = usallocal(usalp)->remfd; + if (f < 0 || !usallocal(usalp)->isopen) + return (-1); + return (rscsifileno(usalp, f, busno, tgt, tlun)); +} + +LOCAL int +usalo_rinitiator_id(usalp) + SCSI *usalp; +{ + if (usalp->local == NULL) + return (-1); + + return (rscsiinitiator_id(usalp, usallocal(usalp)->remfd)); +} + +LOCAL int +usalo_risatapi(usalp) + SCSI *usalp; +{ + if (usalp->local == NULL) + return (-1); + + return (rscsiisatapi(usalp, usallocal(usalp)->remfd)); +} + +LOCAL int +usalo_rreset(usalp, what) + SCSI *usalp; + int what; +{ + if (usalp->local == NULL) + return (-1); + + return (rscsireset(usalp, usallocal(usalp)->remfd, what)); +} + +LOCAL int +usalo_rsend(usalp) + SCSI *usalp; +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + + if (usalp->local == NULL) + return (-1); + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + ret = rscsiscmd(usalp, usallocal(usalp)->remfd, usalp->scmd); + + return (ret); +} + +/*--------------------------------------------------------------------------*/ +LOCAL void +rscsiabrt(sig) + int sig; +{ + rscsiaborted((SCSI *)0, -1); +} + +LOCAL int +rscsigetconn(usalp, host) + SCSI *usalp; + char *host; +{ + static struct servent *sp = 0; + static struct passwd *pw = 0; + char *name = "root"; + char *p; + char *rscsi; + char *rsh; + int rscsisock; + char *rscsipeer; + char rscsiuser[128]; + + + signal(SIGPIPE, rscsiabrt); + if (sp == 0) { + sp = getservbyname("shell", "tcp"); + if (sp == 0) { + comerrno(EX_BAD, "shell/tcp: unknown service\n"); + /* NOTREACHED */ + } + pw = getpwuid(getuid()); + if (pw == 0) { + comerrno(EX_BAD, "who are you? No passwd entry found.\n"); + /* NOTREACHED */ + } + } + if ((p = strchr(host, '@')) != NULL) { + size_t d = p - host; + + if (d > sizeof (rscsiuser)) + d = sizeof (rscsiuser); + snprintf(rscsiuser, sizeof (rscsiuser), "%.*s", (int)d, host); + name = rscsiuser; + host = &p[1]; + } else { + name = pw->pw_name; + } + if (usalp->debug > 0) + errmsgno(EX_BAD, "locuser: '%s' rscsiuser: '%s' host: '%s'\n", + pw->pw_name, name, host); + rscsipeer = host; + + if ((rscsi = getenv("RSCSI")) == NULL) + rscsi = "/usr/sbin/netscsid"; + rsh = getenv("RSH"); + +#ifdef USE_RCMD_RSH + if (!privport_ok() || rsh != NULL) + rscsisock = _rcmdrsh(&rscsipeer, (unsigned short)sp->s_port, + pw->pw_name, name, rscsi, rsh); + else +#endif +#ifdef HAVE_RCMD + rscsisock = rcmd(&rscsipeer, (unsigned short)sp->s_port, + pw->pw_name, name, rscsi, 0); +#else + rscsisock = _rcmdrsh(&rscsipeer, (unsigned short)sp->s_port, + pw->pw_name, name, rscsi, rsh); +#endif + + return (rscsisock); +} + +LOCAL char * +rscsiversion(usalp, fd, what) + SCSI *usalp; + int fd; + int what; +{ + char cbuf[CMD_SIZE]; + char *p; + int ret; + + snprintf(cbuf, sizeof (cbuf), "V%d\n", what); + ret = rscsicmd(usalp, fd, "version", cbuf); + p = malloc(ret); + if (p == NULL) + return (p); + rscsireadbuf(usalp, fd, p, ret); + return (p); +} + +LOCAL int +rscsiopen(usalp, fd, fname) + SCSI *usalp; + int fd; + char *fname; +{ + char cbuf[CMD_SIZE]; + int ret; + int bus; + int chan; + int tgt; + int lun; + + snprintf(cbuf, sizeof (cbuf), "O%s\n", fname?fname:""); + ret = rscsicmd(usalp, fd, "open", cbuf); + if (ret < 0) + return (ret); + + bus = rscsireadnum(usalp, fd); + chan = rscsireadnum(usalp, fd); + tgt = rscsireadnum(usalp, fd); + lun = rscsireadnum(usalp, fd); + + usal_settarget(usalp, bus, tgt, lun); + return (ret); +} + +LOCAL int +rscsiclose(usalp, fd) + SCSI *usalp; + int fd; +{ + return (rscsicmd(usalp, fd, "close", "C\n")); +} + +LOCAL int +rscsimaxdma(usalp, fd, amt) + SCSI *usalp; + int fd; + long amt; +{ + char cbuf[CMD_SIZE]; + + snprintf(cbuf, sizeof (cbuf), "D%ld\n", amt); + return (rscsicmd(usalp, fd, "maxdma", cbuf)); +} + +LOCAL int +rscsigetbuf(usalp, fd, amt) + SCSI *usalp; + int fd; + long amt; +{ + char cbuf[CMD_SIZE]; + int size; + int ret; + + snprintf(cbuf, sizeof (cbuf), "M%ld\n", amt); + ret = rscsicmd(usalp, fd, "getbuf", cbuf); + if (ret < 0) + return (ret); + + size = ret + 1024; /* Add protocol overhead */ + +#ifdef SO_SNDBUF + if (size > usallocal(usalp)->wsize) while (size > 512 && + setsockopt(fd, SOL_SOCKET, SO_SNDBUF, + (char *)&size, sizeof (size)) < 0) { + size -= 512; + } + if (size > usallocal(usalp)->wsize) { + usallocal(usalp)->wsize = size; + if (usalp->debug > 0) + errmsgno(EX_BAD, "sndsize: %d\n", size); + } +#endif +#ifdef SO_RCVBUF + if (size > usallocal(usalp)->rsize) while (size > 512 && + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, + (char *)&size, sizeof (size)) < 0) { + size -= 512; + } + if (size > usallocal(usalp)->rsize) { + usallocal(usalp)->rsize = size; + if (usalp->debug > 0) + errmsgno(EX_BAD, "rcvsize: %d\n", size); + } +#endif + return (ret); +} + +LOCAL int +rscsifreebuf(usalp, fd) + SCSI *usalp; + int fd; +{ + return (rscsicmd(usalp, fd, "freebuf", "F\n")); +} + +LOCAL int +rscsihavebus(usalp, fd, busno) + SCSI *usalp; + int fd; + int busno; +{ + char cbuf[2*CMD_SIZE]; + + snprintf(cbuf, sizeof (cbuf), "B%d\n%d\n", + busno, + 0); + return (rscsicmd(usalp, fd, "havebus", cbuf)); +} + +LOCAL int +rscsifileno(usalp, fd, busno, tgt, tlun) + SCSI *usalp; + int fd; + int busno; + int tgt; + int tlun; +{ + char cbuf[3*CMD_SIZE]; + + snprintf(cbuf, sizeof (cbuf), "T%d\n%d\n%d\n%d\n", + busno, + 0, + tgt, + tlun); + return (rscsicmd(usalp, fd, "fileno", cbuf)); +} + +LOCAL int +rscsiinitiator_id(usalp, fd) + SCSI *usalp; + int fd; +{ + return (rscsicmd(usalp, fd, "initiator id", "I\n")); +} + +LOCAL int +rscsiisatapi(usalp, fd) + SCSI *usalp; + int fd; +{ + return (rscsicmd(usalp, fd, "isatapi", "A\n")); +} + +LOCAL int +rscsireset(usalp, fd, what) + SCSI *usalp; + int fd; + int what; +{ + char cbuf[CMD_SIZE]; + + snprintf(cbuf, sizeof (cbuf), "R%d\n", what); + return (rscsicmd(usalp, fd, "reset", cbuf)); +} + +LOCAL int +rscsiscmd(usalp, fd, sp) + SCSI *usalp; + int fd; + struct usal_cmd *sp; +{ + char cbuf[1600]; + int ret; + int amt = 0; + int voidsize = 0; + + ret = snprintf(cbuf, sizeof (cbuf), "S%d\n%d\n%d\n%d\n%d\n", + sp->size, sp->flags, + sp->cdb_len, sp->sense_len, + sp->timeout); + movebytes(sp->cdb.cmd_cdb, &cbuf[ret], sp->cdb_len); + ret += sp->cdb_len; + + if ((sp->flags & SCG_RECV_DATA) == 0 && sp->size > 0) { + amt = sp->size; + if ((ret + amt) <= sizeof (cbuf)) { + movebytes(sp->addr, &cbuf[ret], amt); + ret += amt; + amt = 0; + } + } + errno = 0; + if (_nixwrite(fd, cbuf, ret) != ret) + rscsiaborted(usalp, fd); + + if (amt > 0) { + if (_nixwrite(fd, sp->addr, amt) != amt) + rscsiaborted(usalp, fd); + } + + ret = rscsigetstatus(usalp, fd, "sendcmd"); + if (ret < 0) + return (ret); + + sp->resid = sp->size - ret; + sp->error = rscsireadnum(usalp, fd); + sp->ux_errno = rscsireadnum(usalp, fd); + *(Uchar *)&sp->scb = rscsireadnum(usalp, fd); + sp->sense_count = rscsireadnum(usalp, fd); + + if (sp->sense_count > SCG_MAX_SENSE) { + voidsize = sp->sense_count - SCG_MAX_SENSE; + sp->sense_count = SCG_MAX_SENSE; + } + if (sp->sense_count > 0) { + rscsireadbuf(usalp, fd, (char *)sp->u_sense.cmd_sense, sp->sense_count); + rscsivoidarg(usalp, fd, voidsize); + } + + if ((sp->flags & SCG_RECV_DATA) != 0 && ret > 0) + rscsireadbuf(usalp, fd, sp->addr, ret); + + return (0); +} + +LOCAL int +rscsifillrbuf(usalp) + SCSI *usalp; +{ + usallocal(usalp)->readbptr = usallocal(usalp)->readbuf; + + return (usallocal(usalp)->readbcnt = + _niread(usallocal(usalp)->remfd, + usallocal(usalp)->readbuf, READBUF_SIZE)); +} + +LOCAL int +rscsirchar(usalp, cp) + SCSI *usalp; + char *cp; +{ + if (--(usallocal(usalp)->readbcnt) < 0) { + if (rscsifillrbuf(usalp) <= 0) + return (usallocal(usalp)->readbcnt); + --(usallocal(usalp)->readbcnt); + } + *cp = *(usallocal(usalp)->readbptr)++; + return (1); +} + +LOCAL int +rscsireadbuf(usalp, fd, buf, count) + SCSI *usalp; + int fd; + char *buf; + int count; +{ + register int n = count; + register int amt = 0; + register int cnt; + + if (usallocal(usalp)->readbcnt > 0) { + cnt = usallocal(usalp)->readbcnt; + if (cnt > n) + cnt = n; + movebytes(usallocal(usalp)->readbptr, buf, cnt); + usallocal(usalp)->readbptr += cnt; + usallocal(usalp)->readbcnt -= cnt; + amt += cnt; + } + while (amt < n) { + if ((cnt = _niread(fd, &buf[amt], n - amt)) <= 0) { + return (rscsiaborted(usalp, fd)); + } + amt += cnt; + } + return (amt); +} + +LOCAL void +rscsivoidarg(usalp, fd, n) + SCSI *usalp; + int fd; + register int n; +{ + register int i; + register int amt; + char buf[512]; + + for (i = 0; i < n; i += amt) { + amt = sizeof (buf); + if ((n - i) < amt) + amt = n - i; + rscsireadbuf(usalp, fd, buf, amt); + } +} + +LOCAL int +rscsicmd(usalp, fd, name, cbuf) + SCSI *usalp; + int fd; + char *name; + char *cbuf; +{ + rscsisendcmd(usalp, fd, name, cbuf); + return (rscsigetstatus(usalp, fd, name)); +} + +LOCAL void +rscsisendcmd(usalp, fd, name, cbuf) + SCSI *usalp; + int fd; + char *name; + char *cbuf; +{ + int buflen = strlen(cbuf); + + errno = 0; + if (_nixwrite(fd, cbuf, buflen) != buflen) + rscsiaborted(usalp, fd); +} + +LOCAL int +rscsigetline(usalp, fd, line, count) + SCSI *usalp; + int fd; + char *line; + int count; +{ + register char *cp; + + for (cp = line; cp < &line[count]; cp++) { + if (rscsirchar(usalp, cp) != 1) + return (rscsiaborted(usalp, fd)); + + if (*cp == '\n') { + *cp = '\0'; + return (cp - line); + } + } + return (rscsiaborted(usalp, fd)); +} + +LOCAL int +rscsireadnum(usalp, fd) + SCSI *usalp; + int fd; +{ + char cbuf[CMD_SIZE]; + + rscsigetline(usalp, fd, cbuf, sizeof (cbuf)); + return (atoi(cbuf)); +} + +LOCAL int +rscsigetstatus(usalp, fd, name) + SCSI *usalp; + int fd; + char *name; +{ + char cbuf[CMD_SIZE]; + char code; + int number; + int count; + int voidsize = 0; + + rscsigetline(usalp, fd, cbuf, sizeof (cbuf)); + code = cbuf[0]; + number = atoi(&cbuf[1]); + + if (code == 'E' || code == 'F') { + rscsigetline(usalp, fd, cbuf, sizeof (cbuf)); + if (code == 'F') /* should close file ??? */ + rscsiaborted(usalp, fd); + + rscsigetline(usalp, fd, cbuf, sizeof (cbuf)); + count = atoi(cbuf); + if (count > 0) { + if (usalp->errstr == NULL) { + voidsize = count; + count = 0; + } else if (count > SCSI_ERRSTR_SIZE) { + voidsize = count - SCSI_ERRSTR_SIZE; + count = SCSI_ERRSTR_SIZE; + } + rscsireadbuf(usalp, fd, usalp->errstr, count); + rscsivoidarg(usalp, fd, voidsize); + } + if (usalp->debug > 0) + errmsgno(number, "Remote status(%s): %d '%s'.\n", + name, number, cbuf); + errno = number; + return (-1); + } + if (code != 'A') { + /* XXX Hier kommt evt Command not found ... */ + if (usalp->debug > 0) + errmsgno(EX_BAD, "Protocol error (got %s).\n", cbuf); + return (rscsiaborted(usalp, fd)); + } + return (number); +} + +LOCAL int +rscsiaborted(usalp, fd) + SCSI *usalp; + int fd; +{ + if ((usalp && usalp->debug > 0) || debug) + errmsgno(EX_BAD, "Lost connection to remote host ??\n"); + /* if fd >= 0 */ + /* close file */ + if (errno == 0) + errno = EIO; + return (-1); +} + +/*--------------------------------------------------------------------------*/ +#ifdef USE_RCMD_RSH +/* + * If we make a separate file for libschily, we would need these include files: + * + * socketpair(): sys/types.h + sys/socket.h + * dup2(): unixstd.h (hat auch sys/types.h) + * strrchr(): strdefs.h + * + * and make sure that we use sigset() instead of signal() if possible. + */ +#include <waitdefs.h> +LOCAL int +_rcmdrsh(ahost, inport, locuser, remuser, cmd, rsh) + char **ahost; + int inport; /* port is ignored */ + const char *locuser; + const char *remuser; + const char *cmd; + const char *rsh; +{ + struct passwd *pw; + int pp[2]; + int pid; + + if (rsh == 0) + rsh = "rsh"; + + /* + * Verify that 'locuser' is present on local host. + */ + if ((pw = getpwnam(locuser)) == NULL) { + errmsgno(EX_BAD, "Unknown user: %s\n", locuser); + return (-1); + } + /* XXX Check the existence for 'ahost' here? */ + + /* + * rcmd(3) creates a single socket to be used for communication. + * We need a bi-directional pipe to implement the same interface. + * On newer OS that implement bi-directional we could use pipe(2) + * but it makes no sense unless we find an OS that implements a + * bi-directional pipe(2) but no socketpair(). + */ + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pp) == -1) { + errmsg("Cannot create socketpair.\n"); + return (-1); + } + + pid = fork(); + if (pid < 0) { + return (-1); + } else if (pid == 0) { + const char *p; + const char *av0; + int xpid; + + (void) close(pp[0]); + if (dup2(pp[1], 0) == -1 || /* Pipe becomes 'stdin' */ + dup2(0, 1) == -1) { /* Pipe becomes 'stdout' */ + + errmsg("dup2 failed.\n"); + _exit(EX_BAD); + /* NOTREACHED */ + } + (void) close(pp[1]); /* We don't need this anymore*/ + + /* + * Become 'locuser' to tell the rsh program the local user id. + */ + if (getuid() != pw->pw_uid && + setuid(pw->pw_uid) == -1) { + errmsg("setuid(%lld) failed.\n", + (Llong)pw->pw_uid); + _exit(EX_BAD); + /* NOTREACHED */ + } + if (getuid() != geteuid() && +#ifdef HAVE_SETREUID + setreuid(-1, pw->pw_uid) == -1) { +#else +#ifdef HAVE_SETEUID + seteuid(pw->pw_uid) == -1) { +#else + setuid(pw->pw_uid) == -1) { +#endif +#endif + errmsg("seteuid(%lld) failed.\n", + (Llong)pw->pw_uid); + _exit(EX_BAD); + /* NOTREACHED */ + } + if (getuid() != geteuid() && + seteuid(pw->pw_uid) == -1) { + errmsg("seteuid(%lld) failed.\n", + (Llong)pw->pw_uid); + _exit(EX_BAD); + /* NOTREACHED */ + } + + /* + * Fork again to completely detach from parent + * and avoid the need to wait(2). + */ + if ((xpid = fork()) == -1) { + errmsg("rcmdsh: fork to lose parent failed.\n"); + _exit(EX_BAD); + /* NOTREACHED */ + } + if (xpid > 0) { + _exit(0); + /* NOTREACHED */ + } + + /* + * Always use remote shell programm (even for localhost). + * The client command may call getpeername() for security + * reasons and this would fail on a simple pipe. + */ + + + /* + * By default, 'rsh' handles terminal created signals + * but this is not what we like. + * For this reason, we tell 'rsh' to ignore these signals. + * Ignoring these signals is important to allow 'star' / 'sdd' + * to e.g. implement SIGQUIT as signal to trigger intermediate + * status printing. + * + * For now (late 2002), we know that the following programs + * are broken and do not implement signal handling correctly: + * + * rsh on SunOS-5.0...SunOS-5.9 + * ssh from ssh.com + * ssh from openssh.org + * + * Sun already did accept a bug report for 'rsh'. For the ssh + * commands we need to send out bug reports. Meanwhile it could + * help to call setsid() if we are running under X so the ssh + * X pop up for passwd reading will work. + */ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); +#ifdef SIGTSTP + signal(SIGTSTP, SIG_IGN); /* We would not be able to continue*/ +#endif + + av0 = rsh; + if ((p = strrchr(rsh, '/')) != NULL) + av0 = ++p; + execlp(rsh, av0, *ahost, "-l", remuser, cmd, (char *)NULL); + + errmsg("execlp '%s' failed.\n", rsh); + _exit(EX_BAD); + /* NOTREACHED */ + } else { + (void) close(pp[1]); + /* + * Wait for the intermediate child. + * The real 'rsh' program is completely detached from us. + */ + wait(0); + return (pp[0]); + } + return (-1); /* keep gcc happy */ +} + +#ifdef HAVE_GETPPRIV +#include <priv.h> + +LOCAL BOOL +ppriv_ok() +{ + priv_set_t *privset; + BOOL net_privaddr = FALSE; + + + if ((privset = priv_allocset()) == NULL) { + return (FALSE); + } + if (getppriv(PRIV_EFFECTIVE, privset) == -1) { + priv_freeset(privset); + return (FALSE); + } + if (priv_ismember(privset, PRIV_NET_PRIVADDR)) { + net_privaddr = TRUE; + } + priv_freeset(privset); + + return (net_privaddr); +} +#endif /* HAVE_GETPPRIV */ + +#endif /* USE_RCMD_RSH */ + +#endif /* USE_REMOTE */ diff --git a/libusal/scsi-sgi.c b/libusal/scsi-sgi.c new file mode 100644 index 0000000..b19a3ae --- /dev/null +++ b/libusal/scsi-sgi.c @@ -0,0 +1,479 @@ +/* + * 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. + * + */ + +/* @(#)scsi-sgi.c 1.36 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the SGI generic SCSI implementation. + * + * First Hacky implementation + * (needed libds, did not support bus scanning and had no error checking) + * from "Frank van Beek" <frank@neogeo.nl> + * + * Actual implementation supports all usal features. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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 <dslib.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-sgi.c-1.36"; /* The version for this transport*/ + +#ifdef USE_DSLIB + +struct dsreq * dsp = 0; +#define MAX_SCG 1 /* Max # of SCSI controllers */ + +#else + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +#endif + +#define MAX_DMA_SGI (256*1024) /* Check if this is not too big */ + + +#ifndef USE_DSLIB +static int usal_sendreq(SCSI *usalp, struct usal_cmd *sp, struct dsreq *dsp); +#endif + + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "DS", "Generic SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[64]; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + + snprintf(devname, sizeof (devname), + "/dev/scsi/sc%dd%dl%d", busno, tgt, tlun); +#ifdef USE_DSLIB + dsp = dsopen(devname, O_RDWR); + if (dsp == 0) + return (-1); +#else + f = open(devname, O_RDWR); + if (f < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", + devname); + return (-1); + } + usallocal(usalp)->usalfiles[busno][tgt][tlun] = f; +#endif + return (1); + } else { +#ifdef USE_DSLIB + return (-1); +#else + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { +/* for (l = 0; l < MAX_LUN; l++) {*/ + for (l = 0; l < 1; l++) { + snprintf(devname, sizeof (devname), + "/dev/scsi/sc%dd%dl%d", b, t, l); + f = open(devname, O_RDWR); + if (f >= 0) { + usallocal(usalp)->usalfiles[b][t][l] = (short)f; + nopen++; + } + } + } + } +#endif + } + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ +#ifndef USE_DSLIB + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } +#else + dsclose(dsp); +#endif + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_SGI); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = valloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ +#ifdef USE_DSLIB + if (dsp == NULL) + return (-1); + return (getfd(dsp)); +#else + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +#endif +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + /* + * Do we have a SCSI reset on SGI? + */ +#ifdef DS_RESET + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + /* + * XXX Does this reset TGT or BUS ??? + */ + return (ioctl(usalp->fd, DS_RESET, 0)); +#else + return (-1); +#endif +} + +#ifndef USE_DSLIB +static int +usal_sendreq(SCSI *usalp, struct usal_cmd *sp, struct dsreq *dsp) +{ + int ret; + int retries = 4; + Uchar status; + +/* if ((sp->flags & SCG_CMD_RETRY) == 0)*/ +/* retries = 0;*/ + + while (--retries > 0) { + ret = ioctl(usalp->fd, DS_ENTER, dsp); + if (ret < 0) { + RET(dsp) = DSRT_DEVSCSI; + return (-1); + } + /* + * SGI implementattion botch!!! + * If a target does not select the bus, + * the return code is DSRT_TIMEOUT + */ + if (RET(dsp) == DSRT_TIMEOUT) { + struct timeval to; + + to.tv_sec = TIME(dsp)/1000; + to.tv_usec = TIME(dsp)%1000; + __usal_times(usalp); + + if (sp->cdb.g0_cdb.cmd == SC_TEST_UNIT_READY && + usalp->cmdstop->tv_sec < to.tv_sec || + (usalp->cmdstop->tv_sec == to.tv_sec && + usalp->cmdstop->tv_usec < to.tv_usec)) { + + RET(dsp) = DSRT_NOSEL; + return (-1); + } + } + if (RET(dsp) == DSRT_NOSEL) + continue; /* retry noselect 3X */ + + status = STATUS(dsp); + switch (status) { + + case 0x08: /* BUSY */ + case 0x18: /* RESERV CONFLICT */ + if (retries > 0) + sleep(2); + continue; + case 0x00: /* GOOD */ + case 0x02: /* CHECK CONDITION */ + case 0x10: /* INTERM/GOOD */ + default: + return (status); + } + } + return (-1); /* failed retry limit */ +} +#endif + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + int i; + int amt = sp->cdb_len; + int flags; +#ifndef USE_DSLIB + struct dsreq ds; + struct dsreq *dsp = &ds; + + dsp->ds_iovbuf = 0; + dsp->ds_iovlen = 0; +#endif + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + flags = DSRQ_SENSE; + if (sp->flags & SCG_RECV_DATA) + flags |= DSRQ_READ; + else if (sp->size > 0) + flags |= DSRQ_WRITE; + + dsp->ds_flags = flags; + dsp->ds_link = 0; + dsp->ds_synch = 0; + dsp->ds_ret = 0; + + DATABUF(dsp) = sp->addr; + DATALEN(dsp) = sp->size; + CMDBUF(dsp) = (void *) &sp->cdb; + CMDLEN(dsp) = sp->cdb_len; + SENSEBUF(dsp) = (caddr_t)sp->u_sense.cmd_sense; + SENSELEN(dsp) = sizeof (sp->u_sense.cmd_sense); + TIME(dsp) = (sp->timeout * 1000) + 100; + + errno = 0; + sp->ux_errno = 0; + sp->sense_count = 0; + +#ifdef USE_DSLIB + ret = doscsireq(usalp->fd, dsp); +#else + ret = usal_sendreq(usalp, sp, dsp); +#endif + + if (RET(dsp) != DSRT_DEVSCSI) + ret = 0; + + if (RET(dsp)) { + if (RET(dsp) == DSRT_SHORT) { + sp->resid = DATALEN(dsp)- DATASENT(dsp); + } else if (errno) { + sp->ux_errno = errno; + } else { + sp->ux_errno = EIO; + } + + sp->u_scb.cmd_scb[0] = STATUS(dsp); + + sp->sense_count = SENSESENT(dsp); + if (sp->sense_count > SCG_MAX_SENSE) + sp->sense_count = SCG_MAX_SENSE; + + } + switch (RET(dsp)) { + + default: + sp->error = SCG_RETRYABLE; break; + + case 0: /* OK */ + case DSRT_SHORT: /* not implemented */ + sp->error = SCG_NO_ERROR; break; + + case DSRT_UNIMPL: /* not implemented */ + case DSRT_REVCODE: /* software obsolete must recompile */ + case DSRT_NOSEL: + sp->u_scb.cmd_scb[0] = 0; + sp->error = SCG_FATAL; break; + + case DSRT_TIMEOUT: + sp->u_scb.cmd_scb[0] = 0; + sp->error = SCG_TIMEOUT; break; + } + return (ret); +} diff --git a/libusal/scsi-sun.c b/libusal/scsi-sun.c new file mode 100644 index 0000000..9ea8da8 --- /dev/null +++ b/libusal/scsi-sun.c @@ -0,0 +1,1133 @@ +/* + * 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. + * + */ + +/* @(#)scsi-sun.c 1.83 05/11/20 Copyright 1988,1995,2000-2004 J. Schilling */ +/* + * SCSI user level command transport routines for + * the SCSI general driver 'usal'. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1988,1995,2000-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 <usal/usalio.h> + +#include <libport.h> /* Needed for gethostid() */ +#ifdef HAVE_SUN_DKIO_H +# include <sun/dkio.h> + +# define dk_cinfo dk_conf +# define dki_slave dkc_slave +# define DKIO_GETCINFO DKIOCGCONF +#endif +#ifdef HAVE_SYS_DKIO_H +# include <sys/dkio.h> + +# define DKIO_GETCINFO DKIOCINFO +#endif + +#define TARGET(slave) ((slave) >> 3) +#define LUN(slave) ((slave) & 07) + +/* + * Tht USCSI ioctl() is not usable on SunOS 4.x + */ +#ifdef __SVR4 +/*#define VOLMGT_DEBUG*/ +#include <volmgt.h> +#include <statdefs.h> +# define USE_USCSI +#endif + +static char _usal_trans_version[] = "usal-1.83"; /* The version for /dev/usal */ +static char _usal_utrans_version[] = "uscsi-1.83"; /* The version for USCSI */ + +#ifdef USE_USCSI +static int usalo_uhelp(SCSI *usalp, FILE *f); +static int usalo_uopen(SCSI *usalp, char *device); +static int usalo_volopen(SCSI *usalp, char *devname); +static int usalo_openmedia(SCSI *usalp, char *mname); +static int usalo_uclose(SCSI *usalp); +static int usalo_ucinfo(int f, struct dk_cinfo *cp, int debug); +static int usalo_ugettlun(int f, int *tgtp, int *lunp); +static long usalo_umaxdma(SCSI *usalp, long amt); +static int usalo_openide(void); +static BOOL usalo_uhavebus(SCSI *usalp, int); +static int usalo_ufileno(SCSI *usalp, int, int, int); +static int usalo_uinitiator_id(SCSI *usalp); +static int usalo_uisatapi(SCSI *usalp); +static int usalo_ureset(SCSI *usalp, int what); +static int usalo_usend(SCSI *usalp); + +static int have_volmgt = -1; + +static usal_ops_t sun_uscsi_ops = { + usalo_usend, + usalo_version, /* Shared with SCG driver */ + usalo_uhelp, + usalo_uopen, + usalo_uclose, + usalo_umaxdma, + usalo_getbuf, /* Shared with SCG driver */ + usalo_freebuf, /* Shared with SCG driver */ + usalo_uhavebus, + usalo_ufileno, + usalo_uinitiator_id, + usalo_uisatapi, + usalo_ureset, +}; +#endif + +/* + * Need to move this into an usal driver ioctl. + */ +/*#define MAX_DMA_SUN4M (1024*1024)*/ +#define MAX_DMA_SUN4M (124*1024) /* Currently max working size */ +/*#define MAX_DMA_SUN4C (126*1024)*/ +#define MAX_DMA_SUN4C (124*1024) /* Currently max working size */ +#define MAX_DMA_SUN3 (63*1024) +#define MAX_DMA_SUN386 (56*1024) +#define MAX_DMA_OTHER (32*1024) + +#define ARCH_MASK 0xF0 +#define ARCH_SUN2 0x00 +#define ARCH_SUN3 0x10 +#define ARCH_SUN4 0x20 +#define ARCH_SUN386 0x30 +#define ARCH_SUN3X 0x40 +#define ARCH_SUN4C 0x50 +#define ARCH_SUN4E 0x60 +#define ARCH_SUN4M 0x70 +#define ARCH_SUNX 0x80 + +/* + * We are using a "real" /dev/usal? + */ +#define scsi_xsend(usalp) ioctl((usalp)->fd, SCGIO_CMD, (usalp)->scmd) +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +struct usal_local { + union { + int SCG_files[MAX_SCG]; +#ifdef USE_USCSI + short usal_files[MAX_SCG][MAX_TGT][MAX_LUN]; +#endif + } u; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) +#define usalfiles(p) (usallocal(p)->u.SCG_files) + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: +#ifdef USE_USCSI + if (usalp->ops == &sun_uscsi_ops) + return (_usal_utrans_version); +#endif + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "usal", "Generic transport independent SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); +#ifdef USE_USCSI + usalo_uhelp(usalp, f); +#endif + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); +/* int tlun = usal_lun(usalp);*/ + register int f; + register int i; + register int nopen = 0; + char devname[32]; + + if (busno >= MAX_SCG) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno '%d'", busno); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { +#ifdef USE_USCSI + usalp->ops = &sun_uscsi_ops; + return (SCGO_OPEN(usalp, device)); +#else + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); +#endif + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, "No memory for usal_local"); + return (0); + } + + for (i = 0; i < MAX_SCG; i++) { + usalfiles(usalp)[i] = -1; + } + } + + + for (i = 0; i < MAX_SCG; i++) { + /* + * Skip unneeded devices if not in SCSI Bus scan open mode + */ + if (busno >= 0 && busno != i) + continue; + snprintf(devname, sizeof (devname), "/dev/usal%d", i); + f = open(devname, O_RDWR); + if (f < 0) { + if (errno != ENOENT && errno != ENXIO) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Cannot open '%s'", devname); + return (-1); + } + } else { + nopen++; + } + usalfiles(usalp)[i] = f; + } +#ifdef USE_USCSI + if (nopen <= 0) { + if (usalp->local != NULL) { + free(usalp->local); + usalp->local = NULL; + } + usalp->ops = &sun_uscsi_ops; + return (SCGO_OPEN(usalp, device)); + } +#endif + return (nopen); +} + +static int +usalo_close(SCSI *usalp) +{ + register int i; + + if (usalp->local == NULL) + return (-1); + + for (i = 0; i < MAX_SCG; i++) { + if (usalfiles(usalp)[i] >= 0) + close(usalfiles(usalp)[i]); + usalfiles(usalp)[i] = -1; + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + long maxdma = MAX_DMA_OTHER; +#if !defined(__i386_) && !defined(i386) + int cpu_type; +#endif + +#if defined(__i386_) || defined(i386) + maxdma = MAX_DMA_SUN386; +#else + cpu_type = gethostid() >> 24; + + switch (cpu_type & ARCH_MASK) { + + case ARCH_SUN4C: + case ARCH_SUN4E: + maxdma = MAX_DMA_SUN4C; + break; + + case ARCH_SUN4M: + case ARCH_SUNX: + maxdma = MAX_DMA_SUN4M; + break; + + default: + maxdma = MAX_DMA_SUN3; + } +#endif + +#ifndef __SVR4 + /* + * SunOS 4.x allows esp hardware on VME boards and thus + * limits DMA on esp to 64k-1 + */ + if (maxdma > MAX_DMA_SUN3) + maxdma = MAX_DMA_SUN3; +#endif + return (maxdma); +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + if (usalp->local == NULL) + return (FALSE); + + return (busno < 0 || busno >= MAX_SCG) ? FALSE : (usalfiles(usalp)[busno] >= 0); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (usalp->local == NULL) + return (-1); + + return ((busno < 0 || busno >= MAX_SCG) ? -1 : usalfiles(usalp)[busno]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + int id = -1; +#ifdef DKIO_GETCINFO + struct dk_cinfo conf; +#endif + +#ifdef DKIO_GETCINFO + if (usalp->fd < 0) + return (id); + if (ioctl(usalp->fd, DKIO_GETCINFO, &conf) < 0) + return (id); + if (TARGET(conf.dki_slave) != -1) + id = TARGET(conf.dki_slave); +#endif + return (id); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + if (what == SCG_RESET_NOP) + return (0); + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + return (ioctl(usalp->fd, SCGIORESET, 0)); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + usalp->bufbase = (void *)valloc((size_t)amt); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static int +usalo_send(SCSI *usalp) +{ + usalp->scmd->target = usal_target(usalp); + return (ioctl(usalp->fd, SCGIO_CMD, usalp->scmd)); +} + +/*--------------------------------------------------------------------------*/ +/* + * This is Sun USCSI interface code ... + */ +#ifdef USE_USCSI +#include <sys/scsi/impl/uscsi.h> + +/* + * Bit Mask definitions, for use accessing the status as a byte. + */ +#define STATUS_MASK 0x3E +#define STATUS_GOOD 0x00 +#define STATUS_CHECK 0x02 + +#define STATUS_RESERVATION_CONFLICT 0x18 +#define STATUS_TERMINATED 0x22 + +#ifdef nonono +#define STATUS_MASK 0x3E +#define STATUS_GOOD 0x00 +#define STATUS_CHECK 0x02 + +#define STATUS_MET 0x04 +#define STATUS_BUSY 0x08 +#define STATUS_INTERMEDIATE 0x10 +#define STATUS_SCSI2 0x20 +#define STATUS_INTERMEDIATE_MET 0x14 +#define STATUS_RESERVATION_CONFLICT 0x18 +#define STATUS_TERMINATED 0x22 +#define STATUS_QFULL 0x28 +#define STATUS_ACA_ACTIVE 0x30 +#endif + +static int +usalo_uhelp(SCSI *usalp, FILE *f) +{ + __usal_help(f, "USCSI", "SCSI transport for targets known by Solaris drivers", + "USCSI:", "bus,target,lun", "USCSI:1,2,0", TRUE, TRUE); + return (0); +} + +static int +usalo_uopen(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + register int f; + register int b; + register int t; + register int l; + register int nopen = 0; + char devname[32]; + + if (have_volmgt < 0) + have_volmgt = volmgt_running(); + + if (usalp->overbose) { + fprintf((FILE *)usalp->errfile, + "Warning: Using USCSI interface.\n"); + } +#ifndef SEEK_HOLE + /* + * SEEK_HOLE first appears in Solaris 11 Build 14, volmgt supports + * medialess drives since Build 21. Using SEEK_HOLD as indicator + * seems to be the best guess. + */ + if (usalp->overbose > 0 && have_volmgt) { + fprintf((FILE *)usalp->errfile, + "Warning: Volume management is running, medialess managed drives are invisible.\n"); + } +#endif + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) { + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + } + return (-1); + } + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, "No memory for usal_local"); + return (0); + } + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->u.usal_files[b][t][l] = (short)-1; + } + } + } + + if (device != NULL && strcmp(device, "USCSI") == 0) + goto uscsiscan; + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) + goto openbydev; + +uscsiscan: + if (busno >= 0 && tgt >= 0 && tlun >= 0) { + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) + return (-1); + + snprintf(devname, sizeof (devname), "/dev/rdsk/c%dt%dd%ds2", + busno, tgt, tlun); + f = open(devname, O_RDONLY | O_NDELAY); + if (f < 0 && geterrno() == EBUSY) + f = usalo_volopen(usalp, devname); + if (f < 0) { + snprintf(usalp->errstr, + SCSI_ERRSTR_SIZE, + "Cannot open '%s'", devname); + return (0); + } + usallocal(usalp)->u.usal_files[busno][tgt][tlun] = f; + return (1); + } else { + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + snprintf(devname, sizeof (devname), + "/dev/rdsk/c%dt%dd%ds2", + b, t, l); + f = open(devname, O_RDONLY | O_NDELAY); + if (f < 0 && geterrno() == EBUSY) { + f = usalo_volopen(usalp, devname); + /* + * Hack to mark inaccessible + * drives with fd == -2 + */ + if (f < 0 && + usallocal(usalp)->u.usal_files[b][t][l] < 0) + usallocal(usalp)->u.usal_files[b][t][l] = f; + } + if (f < 0 && errno != ENOENT && + errno != ENXIO && + errno != ENODEV) { + if (usalp->errstr) + snprintf(usalp->errstr, + SCSI_ERRSTR_SIZE, + "Cannot open '%s'", devname); + } + if (f < 0 && l == 0) + break; + if (f >= 0) { + nopen ++; + if (usallocal(usalp)->u.usal_files[b][t][l] == -1) + usallocal(usalp)->u.usal_files[b][t][l] = f; + else + close(f); + } + } + } + } + } +openbydev: + if (nopen == 0) { + int target; + int lun; + + if (device != NULL && strncmp(device, "USCSI:", 6) == 0) + device += 6; + if (device == NULL || device[0] == '\0') + return (0); + + f = open(device, O_RDONLY | O_NDELAY); + if (f < 0) + f = usalo_volopen(usalp, device); + if (f < 0) { + snprintf(usalp->errstr, + SCSI_ERRSTR_SIZE, + "Cannot open '%s'", device); + return (0); + } + + if (busno < 0) + busno = 0; /* Use Fake number if not specified */ + + if (usalo_ugettlun(f, &target, &lun) >= 0) { + if (tgt >= 0 && tlun >= 0) { + if (tgt != target || tlun != lun) { + close(f); + return (0); + } + } + tgt = target; + tlun = lun; + } else { + if (tgt < 0 || tlun < 0) { + close(f); + return (0); + } + } + + if (usallocal(usalp)->u.usal_files[busno][tgt][tlun] == -1) + usallocal(usalp)->u.usal_files[busno][tgt][tlun] = f; + usal_settarget(usalp, busno, tgt, tlun); + + return (++nopen); + } + return (nopen); +} + +static int +usalo_volopen(SCSI *usalp, char *devname) +{ + int oerr = geterrno(); + int f = -1; + char *name = NULL; /* Volume symbolic device name */ + char *symdev = NULL; /* /dev/... name based on "name" */ + char *mname = NULL; /* Volume media name based on "name" */ + + if (!have_volmgt) + return (-1); + +#ifdef VOLMGT_DEBUG + usalp->debug++; +#endif + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_volopen(%s)\n", devname); + } + + /* + * We come here because trying to open "devname" did not work. + * First try to translate between a symbolic name and a /dev/... + * based device name. Then translate back to a symbolic name. + */ + symdev = volmgt_symdev(devname); + if (symdev) + name = volmgt_symname(symdev); + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "volmgt_symdev(%s)=%s -> %s\n", devname, symdev, name); + } + + /* + * If "devname" is not a symbolic device name, then it must be + * a /dev/... based device name. Try to translate it into a + * symbolic name. Then translate back to a /dev/... name. + */ + if (name == NULL) { + name = volmgt_symname(devname); + if (name) + symdev = volmgt_symdev(name); + } + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "volmgt_symdev(%s)=%s -> %s\n", devname, symdev, name); + } + + /* + * If we have been able to translate to a symbolic device name, + * translate this name into a volume management media name that + * may be used for opening. + */ + if (name) + mname = media_findname(name); + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "symdev %s name %s mname %s\n", symdev, name, mname); + } + + /* + * Das scheint nur mit dem normierten /dev/rdsk/ *s2 Namen zu gehen. + */ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "volmgt_inuse(%s) %d\n", symdev, volmgt_inuse(symdev)); + } + if (mname) + f = usalo_openmedia(usalp, mname); + else if (name) + f = -2; /* Mark inaccessible drives with fd == -2 */ + + /* + * Besonderen Fehlertext oder fprintf/errfile bei non-scanbus Open und + * wenn errrno == EBUSY && kein Mapping? + */ + if (name) + free(name); + if (symdev) + free(symdev); + if (mname) + free(mname); + seterrno(oerr); +#ifdef VOLMGT_DEBUG + usalp->debug--; +#endif + return (f); +} + +static int +usalo_openmedia(SCSI *usalp, char *mname) +{ + int f = -1; + char *device = NULL; + struct stat sb; + + if (mname == NULL) + return (-1); + + /* + * Check whether the media name refers to a directory. + * In this case, the medium is partitioned and we need to + * check all partitions. + */ + if (stat(mname, &sb) >= 0) { + if (S_ISDIR(sb.st_mode)) { + char name[128]; + int i; + + /* + * First check partition '2', the whole disk. + */ + snprintf(name, sizeof (name), "%s/s2", mname); + f = open(name, O_RDONLY | O_NDELAY); + if (f >= 0) + return (f); + /* + * Now try all other partitions. + */ + for (i = 0; i < 16; i++) { + if (i == 2) + continue; + snprintf(name, sizeof (name), + "%s/s%d", mname, i); + if (stat(name, &sb) >= 0) + break; + } + if (i < 16) { + device = mname; + } + } else { + device = mname; + } + } + if (device) + f = open(device, O_RDONLY | O_NDELAY); + return (f); +} + +static int +usalo_uclose(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + f = usallocal(usalp)->u.usal_files[b][t][l]; + if (f >= 0) + close(f); + usallocal(usalp)->u.usal_files[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static int +usalo_ucinfo(int f, struct dk_cinfo *cp, int debug) +{ + fillbytes(cp, sizeof (*cp), '\0'); + + if (ioctl(f, DKIOCINFO, cp) < 0) + return (-1); + + if (debug <= 0) + return (0); + + fprintf(stderr, "cname: '%s'\n", cp->dki_cname); + fprintf(stderr, "ctype: 0x%04hX %hd\n", cp->dki_ctype, cp->dki_ctype); + fprintf(stderr, "cflags: 0x%04hX\n", cp->dki_flags); + fprintf(stderr, "cnum: %hd\n", cp->dki_cnum); +#ifdef __EVER__ + fprintf(stderr, "addr: %d\n", cp->dki_addr); + fprintf(stderr, "space: %d\n", cp->dki_space); + fprintf(stderr, "prio: %d\n", cp->dki_prio); + fprintf(stderr, "vec: %d\n", cp->dki_vec); +#endif + fprintf(stderr, "dname: '%s'\n", cp->dki_dname); + fprintf(stderr, "unit: %d\n", cp->dki_unit); + fprintf(stderr, "slave: %d %04o Tgt: %d Lun: %d\n", + cp->dki_slave, cp->dki_slave, + TARGET(cp->dki_slave), LUN(cp->dki_slave)); + fprintf(stderr, "partition: %hd\n", cp->dki_partition); + fprintf(stderr, "maxtransfer: %d (%d)\n", + cp->dki_maxtransfer, + cp->dki_maxtransfer * DEV_BSIZE); + return (0); +} + +static int +usalo_ugettlun(int f, int *tgtp, int *lunp) +{ + struct dk_cinfo ci; + + if (usalo_ucinfo(f, &ci, 0) < 0) + return (-1); + if (tgtp) + *tgtp = TARGET(ci.dki_slave); + if (lunp) + *lunp = LUN(ci.dki_slave); + return (0); +} + +static long +usalo_umaxdma(SCSI *usalp, long amt) +{ + register int b; + register int t; + register int l; + long maxdma = -1L; + int f; + struct dk_cinfo ci; + BOOL found_ide = FALSE; + + if (usalp->local == NULL) + return (-1L); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + if ((f = usallocal(usalp)->u.usal_files[b][t][l]) < 0) + continue; + if (usalo_ucinfo(f, &ci, usalp->debug) < 0) + continue; + if (maxdma < 0) + maxdma = (long)(ci.dki_maxtransfer * DEV_BSIZE); + if (maxdma > (long)(ci.dki_maxtransfer * DEV_BSIZE)) + maxdma = (long)(ci.dki_maxtransfer * DEV_BSIZE); + if (streql(ci.dki_cname, "ide")) + found_ide = TRUE; + } + } + } + +#if defined(__i386_) || defined(i386) + /* + * At least on Solaris 9 x86, DKIOCINFO returns a wrong value + * for dki_maxtransfer if the target is an ATAPI drive. + * Without DMA, it seems to work if we use 256 kB DMA size for ATAPI, + * but if we allow DMA, only 68 kB will work (for more we get a silent + * DMA residual count == DMA transfer count). + * For this reason, we try to figure out the correct value for 'ide' + * by retrieving the (correct) value from a ide hard disk. + */ + if (found_ide) { + if ((f = usalo_openide()) >= 0) { +#ifdef sould_we + long omaxdma = maxdma; +#endif + + if (usalo_ucinfo(f, &ci, usalp->debug) >= 0) { + if (maxdma < 0) + maxdma = (long)(ci.dki_maxtransfer * DEV_BSIZE); + if (maxdma > (long)(ci.dki_maxtransfer * DEV_BSIZE)) + maxdma = (long)(ci.dki_maxtransfer * DEV_BSIZE); + } + close(f); +#ifdef sould_we + /* + * The kernel returns 56 kB but we tested that 68 kB works. + */ + if (omaxdma > maxdma && maxdma == (112 * DEV_BSIZE)) + maxdma = 136 * DEV_BSIZE; +#endif + } else { + /* + * No IDE disk on this system? + */ + if (maxdma == (512 * DEV_BSIZE)) + maxdma = MAX_DMA_SUN386; + } + } +#endif + /* + * The Sun tape driver does not support to retrieve the max DMA count. + * Use the knwoledge about default DMA sizes in this case. + */ + if (maxdma < 0) + maxdma = usalo_maxdma(usalp, amt); + + return (maxdma); +} + +#if defined(__i386_) || defined(i386) +static int +usalo_openide() +{ + char buf[20]; + int b; + int t; + int f = -1; + + for (b = 0; b < 5; b++) { + for (t = 0; t < 2; t++) { + snprintf(buf, sizeof (buf), + "/dev/rdsk/c%dd%dp0", b, t); + if ((f = open(buf, O_RDONLY | O_NDELAY)) >= 0) + goto out; + } + } +out: + return (f); +} +#endif + +static BOOL +usalo_uhavebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (usalp->local == NULL || busno < 0 || busno >= MAX_SCG) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->u.usal_files[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_ufileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (usalp->local == NULL || + busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + return ((int)usallocal(usalp)->u.usal_files[busno][tgt][tlun]); +} + +static int +usalo_uinitiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_uisatapi(SCSI *usalp) +{ + char devname[32]; + char symlinkname[MAXPATHLEN]; + int len; + struct dk_cinfo ci; + + if (ioctl(usalp->fd, DKIOCINFO, &ci) < 0) + return (-1); + + snprintf(devname, sizeof (devname), "/dev/rdsk/c%dt%dd%ds2", + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + + symlinkname[0] = '\0'; + len = readlink(devname, symlinkname, sizeof (symlinkname)); + if (len > 0) + symlinkname[len] = '\0'; + + if (len >= 0 && strstr(symlinkname, "ide") != NULL) + return (TRUE); + else + return (FALSE); +} + +static int +usalo_ureset(SCSI *usalp, int what) +{ + struct uscsi_cmd req; + + if (what == SCG_RESET_NOP) + return (0); + + fillbytes(&req, sizeof (req), '\0'); + + if (what == SCG_RESET_TGT) { + req.uscsi_flags = USCSI_RESET | USCSI_SILENT; /* reset target */ + } else if (what != SCG_RESET_BUS) { + req.uscsi_flags = USCSI_RESET_ALL | USCSI_SILENT; /* reset bus */ + } else { + errno = EINVAL; + return (-1); + } + + return (ioctl(usalp->fd, USCSICMD, &req)); +} + +static int +usalo_usend(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + struct uscsi_cmd req; + int ret; +static uid_t cureuid = 0; /* XXX Hack until we have uid management */ + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + fillbytes(&req, sizeof (req), '\0'); + + req.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_RQENABLE; + + if (sp->flags & SCG_RECV_DATA) { + req.uscsi_flags |= USCSI_READ; + } else if (sp->size > 0) { + req.uscsi_flags |= USCSI_WRITE; + } + req.uscsi_buflen = sp->size; + req.uscsi_bufaddr = sp->addr; + req.uscsi_timeout = sp->timeout; + req.uscsi_cdblen = sp->cdb_len; + req.uscsi_rqbuf = (caddr_t) sp->u_sense.cmd_sense; + req.uscsi_rqlen = sp->sense_len; + req.uscsi_cdb = (caddr_t) &sp->cdb; + + if (cureuid != 0) + seteuid(0); +again: + errno = 0; + ret = ioctl(usalp->fd, USCSICMD, &req); + + if (ret < 0 && geterrno() == EPERM) { /* XXX Hack until we have uid management */ + cureuid = geteuid(); + if (seteuid(0) >= 0) + goto again; + } + if (cureuid != 0) + seteuid(cureuid); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "ret: %d errno: %d (%s)\n", ret, errno, errmsgstr(errno)); + fprintf((FILE *)usalp->errfile, "uscsi_flags: 0x%x\n", req.uscsi_flags); + fprintf((FILE *)usalp->errfile, "uscsi_status: 0x%x\n", req.uscsi_status); + fprintf((FILE *)usalp->errfile, "uscsi_timeout: %d\n", req.uscsi_timeout); + fprintf((FILE *)usalp->errfile, "uscsi_bufaddr: 0x%lx\n", (long)req.uscsi_bufaddr); + /* + * Cast auf int OK solange sp->size + * auch ein int bleibt. + */ + fprintf((FILE *)usalp->errfile, "uscsi_buflen: %d\n", (int)req.uscsi_buflen); + fprintf((FILE *)usalp->errfile, "uscsi_resid: %d\n", (int)req.uscsi_resid); + fprintf((FILE *)usalp->errfile, "uscsi_rqlen: %d\n", req.uscsi_rqlen); + fprintf((FILE *)usalp->errfile, "uscsi_rqstatus: 0x%x\n", req.uscsi_rqstatus); + fprintf((FILE *)usalp->errfile, "uscsi_rqresid: %d\n", req.uscsi_rqresid); + fprintf((FILE *)usalp->errfile, "uscsi_rqbuf ptr: 0x%lx\n", (long)req.uscsi_rqbuf); + fprintf((FILE *)usalp->errfile, "uscsi_rqbuf: "); + if (req.uscsi_rqbuf != NULL && req.uscsi_rqlen > req.uscsi_rqresid) { + int i; + int len = req.uscsi_rqlen - req.uscsi_rqresid; + + for (i = 0; i < len; i++) { + fprintf((FILE *)usalp->errfile, "0x%02X ", ((char *)req.uscsi_rqbuf)[i]); + } + fprintf((FILE *)usalp->errfile, "\n"); + } else { + fprintf((FILE *)usalp->errfile, "<data not available>\n"); + } + } + if (ret < 0) { + sp->ux_errno = geterrno(); + /* + * Check if SCSI command cound not be send at all. + */ + if (sp->ux_errno == ENOTTY && usalo_uisatapi(usalp) == TRUE) { + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "ENOTTY atapi: %d\n", usalo_uisatapi(usalp)); + } + sp->error = SCG_FATAL; + return (0); + } + if (errno == ENXIO) { + sp->error = SCG_FATAL; + return (0); + } + if (errno == ENOTTY || errno == EINVAL || errno == EACCES) { + return (-1); + } + } else { + sp->ux_errno = 0; + } + ret = 0; + sp->sense_count = req.uscsi_rqlen - req.uscsi_rqresid; + sp->resid = req.uscsi_resid; + sp->u_scb.cmd_scb[0] = req.uscsi_status; + + if ((req.uscsi_status & STATUS_MASK) == STATUS_GOOD) { + sp->error = SCG_NO_ERROR; + return (0); + } + if (req.uscsi_rqstatus == 0 && + ((req.uscsi_status & STATUS_MASK) == STATUS_CHECK)) { + sp->error = SCG_NO_ERROR; + return (0); + } + if (req.uscsi_status & (STATUS_TERMINATED | + STATUS_RESERVATION_CONFLICT)) { + sp->error = SCG_FATAL; + } + if (req.uscsi_status != 0) { + /* + * This is most likely wrong. There seems to be no way + * to produce SCG_RETRYABLE with USCSI. + */ + sp->error = SCG_RETRYABLE; + } + + return (ret); +} +#endif /* USE_USCSI */ diff --git a/libusal/scsi-unixware.c b/libusal/scsi-unixware.c new file mode 100644 index 0000000..4a149f1 --- /dev/null +++ b/libusal/scsi-unixware.c @@ -0,0 +1,922 @@ +/* + * 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. + * + */ + +/* @(#)scsi-unixware.c 1.36 04/01/15 Copyright 1998 J. Schilling, Santa Cruz Operation */ +/* + * Interface for the SCO UnixWare SCSI implementation. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998 J. Schilling, Santa Cruz Operation + */ +/* + * 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. + */ + +#undef sense +#undef SC_PARITY +#undef scb + +#include <sys/sysmacros.h> /* XXX Falsch, richtig -> sys/mkdev.h */ +#include <sys/scsi.h> +#include <sys/sdi_edt.h> +#include <sys/sdi.h> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-unixware.c-1.36"; /* The version for this transport*/ + +/* Max. number of usal scsibusses. The real limit would be */ +/* MAX_HBA * MAX_BUS (which would be 32 * 8 on UnixWare 2.1/7.x), */ +/* but given that we will hardly see such a beast, lets take 32 */ + +#define MAX_SCG 32 + + /* maximum defines for UnixWare 2.x/7.x from <sys/sdi_edt.h> */ + +#define MAX_TGT MAX_EXTCS /* Max # of target id's */ +#define MAX_LUN MAX_EXLUS /* Max # of lun's */ + +#define MAX_DMA (32*1024) +#ifdef __WHAT_TODO__ +#define MAX_DMA (16*1024) /* On UnixWare 2.1.x w/ AHA2940 HBA */ + /* the max DMA size is 16KB. */ +#endif + +#define MAXLINE 80 +#define MAXPATH 256 + +#define DEV_DIR "/tmp" +#define DEV_NAME "usal.s%1dt%1dl%1d" + +#define SCAN_HBA "%d:%d,%d,%d:%7s : %n" +#define SCAN_DEV "%d,%d,%d:%7s : %n" + +#define PRIM_HBA "/dev/hba/hba1" +#define SCSI_CFG "LC_ALL=C /etc/scsi/pdiconfig -l" + +#define SCAN_ALL "LIBSCG_SCAN_ALL" + +#define SDI_VALID 0x01 /* Entry may be used (non disk) */ +#define SDI_ATAPI 0x02 /* Connected via IDE HBA */ +#define SDI_INITIATOR 0x04 /* This is the initiator target ID */ + +typedef struct usal2sdi { + short open; + short flags; + short fd; + char hba; + char bus; + char tgt; + char lun; + + dev_t node; + dev_t major; + dev_t minor; +/*#define SCG_DEBUG*/ +#ifdef SCG_DEBUG + char type[20]; + char vend[40]; + char devn[32]; +#endif +} usal2sdi_t; + +static usal2sdi_t sdidevs [MAX_SCG][MAX_TGT][MAX_LUN]; +static BOOL sdiinit = FALSE; + +struct usal_local { + short usalfiles[MAX_SCG][MAX_TGT][MAX_LUN]; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +static int unixware_init(SCSI *usalp); +static int do_usal_cmd(SCSI *usalp, struct usal_cmd *sp); +static int do_usal_sense(SCSI *usalp, struct usal_cmd *sp); +static FILE *xpopen(char *cmd, char *type); +static int xpclose(FILE *f); + +/* + * ------------------------------------------------------------------------- + * SCO UnixWare 2.1.x / UnixWare 7 provides a scsi pass-through mechanism, + * which can be used to access any configured scsi device. + * + * NOTE: The libusal UnixWare passthrough routines have changed with + * cdrecord-1.8 to enable the -scanbus, -load, -eject option + * regardless of the status of media and the addressing + * scheme is now the same as used on many other platforms like + * Solaris, Linux etc. + * + * =============================================================== + * RUN 'cdrecord -scanbus' TO SEE THE DEVICE ADDRESSES YOU CAN USE + * =============================================================== + */ + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + * + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "SDI_SEND", "Generic SCSI", + "", "bus,target,lun", "1,2,0", TRUE, FALSE); + return (0); +} + +/* + * --------------------------------------------------------------- + * This routine is introduced to create all device nodes necessary + * to access any detected scsi device. It parses the output of + * /etc/scsi/pdiconfig -l and creates passthru device node for each + * found scsi device apart from the listed hba's. + * + */ + +static int +unixware_init(SCSI *usalp) +{ + FILE *cmd; + int hba = 0, bus = 0, usal = 0, tgt = 0, lun = 0; + int nusal = -1, lhba = -1, lbus = 0; + int atapi, fd, nopen = 0, pos = 0, len = 0; + int s, t, l; + int scan_disks; + char lines[MAXLINE]; + char class[MAXLINE]; + char ident[MAXLINE]; + char devnm[MAXPATH]; + char dname[MAXPATH]; + struct stat stbuf; + dev_t ptdev, major, minor, node; + char **evsave; +extern char **environ; + + /* Check for validity of primary hostbus adapter node */ + + if (stat(PRIM_HBA, &stbuf) < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Can not stat() primary hba (%s)", + PRIM_HBA); + return (-1); + } + + if (!S_ISCHR(stbuf.st_mode)) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Primary hba (%s) not a character device", + PRIM_HBA); + return (-1); + } + + major = getmajor(stbuf.st_rdev); + + /* + * Check whether we want to scan all devices + */ + if (getenv(SCAN_ALL) != NULL) { + scan_disks = 1; + } else { + scan_disks = 0; + } + + /* read pdiconfig output and get all attached scsi devices ! */ + + evsave = environ; + environ = 0; + if ((cmd = xpopen(SCSI_CFG, "r")) == NULL) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error popen() for \"%s\"", + SCSI_CFG); + environ = evsave; + return (-1); + } + environ = evsave; + + + for (;;) { + if (fgets(lines, MAXLINE, cmd) == NULL) + break; + + memset(class, '\0', sizeof (class)); + memset(ident, '\0', sizeof (ident)); + + if (lines[0] == ' ') { + sscanf(lines, SCAN_DEV, &bus, &tgt, &lun, class, &pos); + hba = lhba; + } else { + sscanf(lines, SCAN_HBA, &hba, &bus, &tgt, &lun, class, &pos); + nusal++; + lhba = hba; + atapi = 0; + } + + /* We can't sscanf() the ident string of the device */ + /* as it may contain characters sscanf() will */ + /* recognize as a delimiter. So do a strcpy() instead ! */ + + len = strlen(lines) - pos - 1; /* don't copy the '\n' */ + + strncpy(ident, &lines[pos], len); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "SDI -> %d:%d,%d,%d: %-7s : %s\n", + hba, bus, tgt, lun, class, ident); + } + if (bus != lbus) { + nusal++; + lbus = bus; + } + + usal = nusal; + + /* check whether we have a HBA or a SCSI device, don't */ + /* let HBA's be valid device for cdrecord, but mark */ + /* them as a controller (initiator = 1). */ + + /* Don't detect disks, opening a mounted disk can hang */ + /* the disk subsystem !!! So unless we set an */ + /* environment variable LIBSCG_SCAN_ALL, we will ignore */ + /* disks */ + + if (strstr(class, "HBA") == NULL) { + if (strstr(class, "DISK") != NULL) { + if (scan_disks) + sdidevs[usal][tgt][lun].flags |= SDI_VALID; + else + sdidevs[usal][tgt][lun].flags &= ~SDI_VALID; + } else { + sdidevs[usal][tgt][lun].flags |= SDI_VALID; + } + } else { + sdidevs[usal][tgt][lun].flags |= SDI_INITIATOR; + } + + + /* There is no real flag that shows a HBA as an ATAPI */ + /* controller, so as we know the driver is called 'ide' */ + /* we can check the ident string for the occurence of it*/ + + if (strstr(ident, "(ide,") != NULL) { + atapi = 1; + } + + /* + * Fill the sdidevs array with all we know now. + * Do not overwrite fields that may contain old state like + * sdidevs[usal][tgt][lun].open + */ + + if (atapi) + sdidevs[usal][tgt][lun].flags |= SDI_ATAPI; + else + sdidevs[usal][tgt][lun].flags &= ~SDI_ATAPI; + + sdidevs[usal][tgt][lun].hba = hba; + sdidevs[usal][tgt][lun].bus = bus; + sdidevs[usal][tgt][lun].tgt = tgt; + sdidevs[usal][tgt][lun].lun = lun; + +#ifdef SCG_DEBUG + strcpy(sdidevs[usal][tgt][lun].type, class); + strcpy(sdidevs[usal][tgt][lun].vend, ident); + + snprintf(sdidevs[usal][tgt][lun].devn, + sizeof (sdidevs[usal][tgt][lun].devn), + DEV_NAME, usal, tgt, lun); +#endif + snprintf(devnm, sizeof (devnm), + DEV_NAME, usal, tgt, lun); + + minor = SDI_MINOR(hba, tgt, lun, bus); + node = makedevice(major, minor); + + sdidevs[usal][tgt][lun].major = major; + sdidevs[usal][tgt][lun].minor = minor; + sdidevs[usal][tgt][lun].node = node; + + if (usalp->debug > 0) { + + fprintf((FILE *)usalp->errfile, + "h = %d; b = %d, s = %d, t = %d, l = %d, a = %d, ma = %d, mi = %2d, dev = '%s', id = '%s'\n", + hba, bus, usal, tgt, lun, + (sdidevs[usal][tgt][lun].flags & SDI_ATAPI) != 0, + sdidevs[usal][tgt][lun].major, + sdidevs[usal][tgt][lun].minor, + devnm, + ident); + } + + + } + + if (xpclose(cmd) == -1) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Error pclose() for \"%s\"", + SCSI_CFG); + return (-1); + } + + + /* create all temporary device nodes */ + + for (s = 0; s < MAX_SCG; s++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + + if ((sdidevs[s][t][l].flags & SDI_VALID) == 0) { + if (sdidevs[s][t][l].fd >= 0) { + close(sdidevs[s][t][l].fd); + } + sdidevs[s][t][l].fd = -1; + sdidevs[s][t][l].open = 0; + continue; + } + + /* Make pass-through interface device node */ + + snprintf(devnm, + sizeof (devnm), + DEV_NAME, s, t, l); + + snprintf(dname, sizeof (dname), + "%s/%s", DEV_DIR, devnm); + + ptdev = sdidevs[s][t][l].node; + + if (mknod(dname, S_IFCHR | 0700, ptdev) < 0) { + if (errno == EEXIST) { + unlink(dname); + + if (mknod(dname, S_IFCHR | 0700, ptdev) < 0) { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "mknod() error for \"%s\"", dname); + return (-1); + } + } else { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "mknod() error for \"%s\"", dname); + return (-1); + } + } + + /* Open pass-through device node */ + + if ((fd = open(dname, O_RDONLY)) < 0) { + if (errno == EBUSY && sdidevs[s][t][l].open > 0) { + /* + * Device has already been opened, just + * return the saved file desc. + */ + fd = sdidevs[s][t][l].fd; + } else { + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "can not open pass-through %s", dname); + return (-1); + } + } + + /* + * If for whatever reason we may open a pass through + * device more than once, this will waste fs's as we + * do not check for sdidevs[s][t][l].fd == -1. + */ + sdidevs[s][t][l].fd = fd; + sdidevs[s][t][l].open++; + nopen++; + usallocal(usalp)->usalfiles[s][t][l] = (short) fd; + + if (usalp->debug > 0) { + + fprintf((FILE *)usalp->errfile, + "s = %d, t = %d, l = %d, dev = %s, fd = %d\n", + s, t, l, + devnm, + sdidevs[s][t][l].fd); + } + + } + } + } + + return (nopen); +} + + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + int b, t, l; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + + if (!sdiinit) { + sdiinit = TRUE; + memset(sdidevs, 0, sizeof (sdidevs)); /* init tmp_structure */ + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + + sdidevs[b][t][l].flags = 0; + sdidevs[b][t][l].fd = -1; + sdidevs[b][t][l].open = 0; + } + } + } + } + + if (*device != '\0') { /* we don't allow old dev usage */ + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' no longer supported on this OS"); + return (-1); + } else { /* this is the new stuff */ + /* it will do the initialisation */ + /* and return the number of */ + /* detected devices to be used */ + /* with the new addressing */ + /* scheme. */ + + return (unixware_init(usalp)); + } + +} + + +static int +usalo_close(SCSI *usalp) +{ + register int f; + register int b; + register int t; + register int l; + + if (usalp->local == NULL) + return (-1); + + for (b = 0; b < MAX_SCG; b++) { + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) { + + f = usallocal(usalp)->usalfiles[b][t][l]; + if (f >= 0) { + if (sdidevs[b][t][l].open > 0) + sdidevs[b][t][l].open--; + if (sdidevs[b][t][l].open <= 0) { + if (sdidevs[b][t][l].fd >= 0) + close(sdidevs[b][t][l].fd); + sdidevs[b][t][l].fd = -1; + sdidevs[b][t][l].flags &= ~SDI_VALID; + } + } + usallocal(usalp)->usalfiles[b][t][l] = (short)-1; + } + } + } + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA); +} + + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = (void *) valloc((size_t)(amt)); + + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + register int t; + register int l; + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + if (usalp->local == NULL) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if (usallocal(usalp)->usalfiles[busno][t][l] >= 0) + return (TRUE); + } + return (FALSE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= MAX_SCG || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + if (usalp->local == NULL) + return (-1); + + return ((int)usallocal(usalp)->usalfiles[busno][tgt][tlun]); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + register int t; + register int l; + register int busno; + + busno = usal_scsibus(usalp); + + if (busno < 0 || busno >= MAX_SCG) + return (FALSE); + + for (t = 0; t < MAX_TGT; t++) { + for (l = 0; l < MAX_LUN; l++) + if ((sdidevs[busno][t][l].flags & SDI_INITIATOR) != 0) { + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_initiator_id: id = %d\n", t); + } + return (t); + } + } + + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + /* if the new address method is used we know if this is ATAPI */ + + return ((sdidevs[usal_scsibus(usalp)][usal_target(usalp)][usal_lun(usalp)].flags & SDI_ATAPI) != 0); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + int f = usalp->fd; + + errno = EINVAL; + +#if defined(SDI_TRESET) || defined(SDI_BRESET) + if (what == SCG_RESET_NOP) { + errno = 0; + return (0); + } + +#ifdef SDI_TRESET + if (what == SCG_RESET_TGT) { + errno = 0; + if (ioctl(f, SDI_TRESET, 0) >= 0) + return (0); + } +#endif + +#ifdef SDI_BRESET + if (what == SCG_RESET_BUS) { + errno = 0; + if (ioctl(f, SDI_BRESET, 0) >= 0) + return (0); + } +#endif + +#endif /* defined(SDI_TRESET) || defined(SDI_BRESET) */ + + return (-1); +} + +static int +do_usal_cmd(SCSI *usalp, struct usal_cmd *sp) +{ + int ret; + int i; + struct sb scsi_cmd; + struct scb *scbp; + + memset(&scsi_cmd, 0, sizeof (scsi_cmd)); + + scsi_cmd.sb_type = ISCB_TYPE; + scbp = &scsi_cmd.SCB; + + scbp->sc_cmdpt = (caddr_t) sp->cdb.cmd_cdb; + scbp->sc_cmdsz = sp->cdb_len; + + scbp->sc_datapt = sp->addr; + scbp->sc_datasz = sp->size; + + if (!(sp->flags & SCG_RECV_DATA) && (sp->size > 0)) + scbp->sc_mode = SCB_WRITE; + else + scbp->sc_mode = SCB_READ; + + scbp->sc_time = sp->timeout; + + sp->error = SCG_NO_ERROR; + errno = 0; + for (;;) { + if ((ret = ioctl(usalp->fd, SDI_SEND, &scsi_cmd)) < 0) { + if (errno == EAGAIN) { + sleep(1); + errno = 0; + continue; + } + sp->ux_errno = errno; + if (errno == 0) + sp->ux_errno = EIO; + sp->error = SCG_RETRYABLE; + +#ifdef __needed__ + if (errno == ENOTTY || errno == EINVAL || + errno == EACCES) { + return (-1); + } +#endif + return (ret); + } + break; + } + sp->ux_errno = errno; + sp->resid = scbp->sc_resid; + memset(&sp->u_scb.Scb, 0, sizeof (sp->u_scb.Scb)); + sp->u_scb.cmd_scb[0] = scbp->sc_status; + + if (sp->u_scb.cmd_scb[0] & 0x02) { + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + } + + switch (scbp->sc_comp_code) { + + case SDI_ASW : /* Job completed normally */ + case SDI_LINKF0 : /* Linked command done without flag */ + case SDI_LINKF1 : /* Linked command done with flag */ + + sp->error = SCG_NO_ERROR; + break; + + case SDI_CKSTAT : /* Check the status byte */ + + sp->error = SCG_NO_ERROR; + break; + + case SDI_NOALLOC : /* This block is not allocated */ + case SDI_NOTEQ : /* Addressed device not present */ + case SDI_OOS : /* Device is out of service */ + case SDI_NOSELE : /* The SCSI bus select failed */ + case SDI_SBRESC : /* SCSI bus reservation conflict */ + + sp->error = SCG_FATAL; + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + break; + + case SDI_QFLUSH : /* Job was flushed */ + case SDI_ABORT : /* Command was aborted */ + case SDI_RESET : /* Reset was detected on the bus */ + case SDI_CRESET : /* Reset was caused by this unit */ + case SDI_V2PERR : /* vtop failed */ + case SDI_HAERR : /* Host adapter error */ + case SDI_MEMERR : /* Memory fault */ + case SDI_SBUSER : /* SCSI bus error */ + case SDI_SCBERR : /* SCB error */ + case SDI_MISMAT : /* parameter mismatch */ + + case SDI_PROGRES : /* Job in progress */ + case SDI_UNUSED : /* Job not in use */ + + case SDI_ONEIC : /* More than one immediate request */ + case SDI_SFBERR : /* SFB error */ + case SDI_TCERR : /* Target protocol error detected */ + default: + sp->error = SCG_RETRYABLE; + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + break; + + case SDI_TIME : /* Job timed out */ + case SDI_TIME_NOABORT : /* Job timed out, but could not be aborted */ + + sp->error = SCG_TIMEOUT; + if (sp->ux_errno == 0) + sp->ux_errno = EIO; + break; + } + return (0); +} + + +static int +do_usal_sense(SCSI *usalp, struct usal_cmd *sp) +{ + int ret; + struct usal_cmd s_cmd; + + memset((caddr_t)&s_cmd, 0, sizeof (s_cmd)); + + s_cmd.addr = (caddr_t) sp->u_sense.cmd_sense; + s_cmd.size = sp->sense_len; + s_cmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA; + s_cmd.cdb_len = SC_G0_CDBLEN; + s_cmd.sense_len = CCS_SENSE_LEN; + + s_cmd.cdb.g0_cdb.cmd = SC_REQUEST_SENSE; + s_cmd.cdb.g0_cdb.lun = sp->cdb.g0_cdb.lun; + s_cmd.cdb.g0_cdb.count = sp->sense_len; + + ret = do_usal_cmd(usalp, &s_cmd); + + if (ret < 0) + return (ret); + + sp->sense_count = sp->sense_len - s_cmd.resid; + return (ret); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + + ret = do_usal_cmd(usalp, sp); + if (ret < 0) + return (ret); + + if (sp->u_scb.cmd_scb[0] & S_CKCON) + ret = do_usal_sense(usalp, sp); + + return (ret); +} + +#define sense u_sense.Sense +#undef SC_PARITY +#define SC_PARITY 0x09 +#define scb u_scb.Scb + +/*--------------------------------------------------------------------------*/ +#include <unixstd.h> +#include <waitdefs.h> +/* + * Simplified version of popen() + * This version of popen() is not usable more than once at a time. + * Needed because /etc/scsi/pdiconfig will not work if euid != uid + */ +static pid_t po_pid; + +static FILE * +xpopen(char *cmd, char *type) +{ + FILE *ret; + FILE *pp[2]; + + if (po_pid != 0) + return ((FILE *)NULL); + + if (*type != 'r') + return ((FILE *)NULL); + + if (fpipe(pp) == 0) + return ((FILE *)NULL); + + + if ((po_pid = fork()) == 0) { + setuid(0); + + fclose(pp[0]); + (void) rols_fexecl("/bin/sh", stdin, pp[1], stderr, + "sh", "-c", cmd, (char *)0); + _exit(1); + } + fclose(pp[1]); + + if (po_pid == (pid_t)-1) { + fclose(pp[0]); + return ((FILE *)NULL); + } + return (pp[0]); +} + +static int +xpclose(FILE *f) +{ + int ret = 0; + + if (po_pid == 0) + return (-1); + + fclose(f); + + if (waitpid(po_pid, &ret, 0) < 0) + ret = -1; + + po_pid = 0; + return (ret); +} diff --git a/libusal/scsi-vms.c b/libusal/scsi-vms.c new file mode 100644 index 0000000..ef29d76 --- /dev/null +++ b/libusal/scsi-vms.c @@ -0,0 +1,540 @@ +/* + * 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. + * + */ + +/* @(#)scsi-vms.c 1.33 04/01/15 Copyright 1997 J. Schilling */ +/* + * Interface for the VMS generic SCSI implementation. + * + * The idea for an elegant mapping to VMS device dontroller names + * is from Chip Dancy Chip.Dancy@hp.com. This allows up to + * 26 IDE controllers (DQ[A-Z][0-1]). + * + * This is a hack, that tries to emulate the functionality + * of the usal driver. + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1997 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 <iodef.h> +#include <ssdef.h> +#include <descrip.h> +#include <starlet.h> +#include <string.h> +#include <LIB$ROUTINES.H> + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-vms.c-1.33"; /* The version for this transport*/ + +#define VMS_MAX_DK 4 /* DK[A-D] VMS device controllers */ +#define VMS_MAX_GK 4 /* GK[A-D] VMS device controllers */ +#define VMS_MAX_DQ 26 /* DQ[A-Z] VMS device controllers */ + +#define VMS_DKRANGE_MAX VMS_MAX_DK +#define VMS_GKRANGE_MAX (VMS_DKRANGE_MAX + VMS_MAX_GK) +#define VMS_DQRANGE_MAX (VMS_GKRANGE_MAX + VMS_MAX_DQ) + +#define MAX_SCG VMS_DQRANGE_MAX /* Max # of SCSI controllers */ +#define MAX_TGT 16 +#define MAX_LUN 8 + +#define MAX_DMA_VMS (63*1024) /* Check if this is not too big */ +#define MAX_PHSTMO_VMS 300 +#define MAX_DSCTMO_VMS ((64*1024)-1) /* max value for OpenVMS/AXP 7.1 ehh*/ + +/* + * Define a mapping from the scsi busno to the three character + * VMS device controller. + * The valid busno values are broken into three ranges, one for each of + * the three supported devices: dk, gk, and dq. + * The vmschar[] and vmschar1[] arrays are subscripted by an offset + * corresponding to each of the three ranges [0,1,2] to provide the + * two characters of the VMS device. + * The offset of the busno value within its range is used to define the + * third character, using the vmschar2[] array. + */ +static char vmschar[] = {'d', 'g', 'd'}; +static char vmschar1[] = {'k', 'k', 'q'}; +static char vmschar2[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z'}; + + +static int do_usal_cmd(SCSI *usalp, struct usal_cmd *sp); +static int do_usal_sense(SCSI *usalp, struct usal_cmd *sp); + +#define DEVICE_NAMELEN 8 + +struct SCSI$DESC { + Uint SCSI$L_OPCODE; /* SCSI Operation Code */ + Uint SCSI$L_FLAGS; /* SCSI Flags Bit Map */ + char *SCSI$A_CMD_ADDR; /* ->SCSI command buffer */ + Uint SCSI$L_CMD_LEN; /* SCSI command length, bytes */ + char *SCSI$A_DATA_ADDR; /* ->SCSI data buffer */ + Uint SCSI$L_DATA_LEN; /* SCSI data length, bytes */ + Uint SCSI$L_PAD_LEN; /* SCSI pad length, bytes */ + Uint SCSI$L_PH_CH_TMOUT; /* SCSI phase change timeout */ + Uint SCSI$L_DISCON_TMOUT; /* SCSI disconnect timeout */ + Uint SCSI$L_RES_1; /* Reserved */ + Uint SCSI$L_RES_2; /* Reserved */ + Uint SCSI$L_RES_3; /* Reserved */ + Uint SCSI$L_RES_4; /* Reserved */ + Uint SCSI$L_RES_5; /* Reserved */ + Uint SCSI$L_RES_6; /* Reserved */ +}; + +#ifdef __ALPHA +#pragma member_alignment save +#pragma nomember_alignment +#endif + +struct SCSI$IOSB { + Ushort SCSI$W_VMS_STAT; /* VMS status code */ + Ulong SCSI$L_IOSB_TFR_CNT; /* Actual #bytes transferred */ + char SCSI$B_IOSB_FILL_1; + Uchar SCSI$B_IOSB_STS; /* SCSI device status */ +}; + +#ifdef __ALPHA +#pragma member_alignment restore +#endif + +#define SCSI$K_GOOD_STATUS 0 +#define SCSI$K_CHECK_CONDITION 0x2 +#define SCSI$K_CONDITION_MET 0x4 +#define SCSI$K_BUSY 0x8 +#define SCSI$K_INTERMEDIATE 0x10 +#define SCSI$K_INTERMEDIATE_C_MET 0x14 +#define SCSI$K_RESERVATION_CONFLICT 0x18 +#define SCSI$K_COMMAND_TERMINATED 0x22 +#define SCSI$K_QUEUE_FULL 0x28 + + +#define SCSI$K_WRITE 0X0 /* direction of transfer=write */ +#define SCSI$K_READ 0X1 /* direction of transfer=read */ +#define SCSI$K_FL_ENAB_DIS 0X2 /* enable disconnects */ +#define SCSI$K_FL_ENAB_SYNC 0X4 /* enable sync */ +#define GK_EFN 0 /* Event flag number */ + +static char gk_device[8]; /* XXX JS hoffentlich gibt es keinen Ueberlauf */ +static Ushort gk_chan; +static Ushort transfer_length; +static int i; +static int status; +static $DESCRIPTOR(gk_device_desc, gk_device); +static struct SCSI$IOSB gk_iosb; +static struct SCSI$DESC gk_desc; +static FILE *fp; + + +struct usal_local { + Ushort gk_chan; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "IO$_DIAGNOSE", "Generic SCSI", + "", "bus,target,lun", "1,2,0", FALSE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + char devname[DEVICE_NAMELEN]; + char buschar; + char buschar1; + char buschar2; + int range; + int range_offset; + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); + } + if (busno < 0 || tgt < 0 || tlun < 0) { + /* + * There is no real reason why we cannot scan on VMS, + * but for now it is not possible. + */ + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Unable to scan on VMS"); + return (0); + } + + if (usalp->local == NULL) { + usalp->local = malloc(sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + } + + if (busno < VMS_DKRANGE_MAX) { /* in the dk range? */ + range = 0; + range_offset = busno; + } else if (busno < VMS_GKRANGE_MAX) { /* in the gk range? */ + range = 1; + range_offset = busno - VMS_DKRANGE_MAX; + } else if (busno < VMS_DQRANGE_MAX) { /* in the dq range? */ + range = 2; + range_offset = busno - VMS_GKRANGE_MAX; + } + buschar = vmschar[range]; /* get first device char*/ + buschar1 = vmschar1[range]; /* get 2nd device char*/ + buschar2 = vmschar2[range_offset]; /* get controller char*/ + + snprintf(devname, sizeof (devname), "%c%c%c%d0%d:", + buschar, buschar1, buschar2, + tgt, tlun); + strcpy(gk_device, devname); + status = sys$assign(&gk_device_desc, &gk_chan, 0, 0); + if (!(status & 1)) { + fprintf((FILE *)usalp->errfile, + "Unable to access scsi-device \"%s\"\n", &gk_device[0]); + return (-1); + } + if (usalp->debug > 0) { + fp = fopen("cdrecord_io.log", "w", "rfm=stmlf", "rat=cr"); + if (fp == NULL) { + perror("Failing opening i/o-logfile"); + exit(SS$_NORMAL); + } + } + return (status); +} + +static int +usalo_close(SCSI *usalp) +{ + /* + * XXX close gk_chan ??? + */ + /* + * sys$dassgn() + */ + + status = sys$dassgn(gk_chan); + + return (status); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_VMS); +} + +static BOOL +usalo_havebus(SCSI *usalp, int busno) +{ + if (gk_chan == 0) + return (FALSE); + return (TRUE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (gk_chan == 0) + return (-1); + return (gk_chan); +} + +static int +usalo_initiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + int busno = usal_scsibus(usalp); + + if (busno >= 8) + return (TRUE); + + return (FALSE); +} + +static int +usalo_reset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = malloc((size_t)(amt)); /* XXX JS XXX valloc() ??? */ + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static int +do_usal_cmd(SCSI *usalp, struct usal_cmd *sp) +{ + char *cmdadr; + int notcmdretry; + int len; + Uchar scsi_sts; + int severity; + + /* XXX JS XXX This cannot be OK */ + notcmdretry = (sp->flags & SCG_CMD_RETRY)^SCG_CMD_RETRY; + /* error corrected ehh */ +/* + * XXX JS Wenn das notcmdretry Flag bei VMS auch 0x08 ist und Du darauf hoffst, + * XXX Dasz ich den Wert nie aendere, dann ist das richtig. + * XXX Siehe unten: Das gleiche gilt fuer SCG_RECV_DATA und SCG_DISRE_ENA !!! + */ + + cmdadr = (char *)sp->cdb.cmd_cdb; + /* XXX JS XXX This cannot be OK */ + gk_desc.SCSI$L_FLAGS = ((sp->flags & SCG_RECV_DATA) | + (sp->flags & SCG_DISRE_ENA)| + notcmdretry); + /* XXX siehe oben, das ist ein bitweises oder!!! */ + gk_desc.SCSI$A_DATA_ADDR = sp->addr; + gk_desc.SCSI$L_DATA_LEN = sp->size; + gk_desc.SCSI$A_CMD_ADDR = cmdadr; + gk_desc.SCSI$L_CMD_LEN = sp->cdb_len; + gk_desc.SCSI$L_PH_CH_TMOUT = sp->timeout; + gk_desc.SCSI$L_DISCON_TMOUT = sp->timeout; + if (gk_desc.SCSI$L_PH_CH_TMOUT > MAX_PHSTMO_VMS) + gk_desc.SCSI$L_PH_CH_TMOUT = MAX_PHSTMO_VMS; + if (gk_desc.SCSI$L_DISCON_TMOUT > MAX_DSCTMO_VMS) + gk_desc.SCSI$L_DISCON_TMOUT = MAX_DSCTMO_VMS; + gk_desc.SCSI$L_OPCODE = 1; /* SCSI Operation Code */ + gk_desc.SCSI$L_PAD_LEN = 0; /* SCSI pad length, bytes */ + gk_desc.SCSI$L_RES_1 = 0; /* Reserved */ + gk_desc.SCSI$L_RES_2 = 0; /* Reserved */ + gk_desc.SCSI$L_RES_3 = 0; /* Reserved */ + gk_desc.SCSI$L_RES_4 = 0; /* Reserved */ + gk_desc.SCSI$L_RES_5 = 0; /* Reserved */ + gk_desc.SCSI$L_RES_6 = 0; /* Reserved */ + if (usalp->debug > 0) { + fprintf(fp, "***********************************************************\n"); + fprintf(fp, "SCSI VMS-I/O parameters\n"); + fprintf(fp, "OPCODE: %d", gk_desc.SCSI$L_OPCODE); + fprintf(fp, " FLAGS: %d\n", gk_desc.SCSI$L_FLAGS); + fprintf(fp, "CMD:"); + for (i = 0; i < gk_desc.SCSI$L_CMD_LEN; i++) { + fprintf(fp, "%x ", sp->cdb.cmd_cdb[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DATA_LEN: %d\n", gk_desc.SCSI$L_DATA_LEN); + fprintf(fp, "PH_CH_TMOUT: %d", gk_desc.SCSI$L_PH_CH_TMOUT); + fprintf(fp, " DISCON_TMOUT: %d\n", gk_desc.SCSI$L_DISCON_TMOUT); + } + status = sys$qiow(GK_EFN, gk_chan, IO$_DIAGNOSE, &gk_iosb, 0, 0, + &gk_desc, sizeof (gk_desc), 0, 0, 0, 0); + + + if (usalp->debug > 0) { + fprintf(fp, "qiow-status: %i\n", status); + fprintf(fp, "VMS status code %i\n", gk_iosb.SCSI$W_VMS_STAT); + fprintf(fp, "Actual #bytes transferred %i\n", gk_iosb.SCSI$L_IOSB_TFR_CNT); + fprintf(fp, "SCSI device status %i\n", gk_iosb.SCSI$B_IOSB_STS); + if (gk_iosb.SCSI$L_IOSB_TFR_CNT != gk_desc.SCSI$L_DATA_LEN) { + fprintf(fp, "#bytes transferred != DATA_LEN\n"); + } + } + + if (!(status & 1)) { /* Fehlerindikation fuer sys$qiow() */ + sp->ux_errno = geterrno(); + /* schwerwiegender nicht SCSI bedingter Fehler => return (-1) */ + if (sp->ux_errno == ENOTTY || sp->ux_errno == ENXIO || + sp->ux_errno == EINVAL || sp->ux_errno == EACCES) { + return (-1); + } + if (sp->ux_errno == 0) + sp->ux_errno == EIO; + } else { + sp->ux_errno = 0; + } + + sp->resid = gk_desc.SCSI$L_DATA_LEN - gk_iosb.SCSI$L_IOSB_TFR_CNT; + + if (usalo_isatapi(usalp)) { + scsi_sts = ((gk_iosb.SCSI$B_IOSB_STS >> 4) & 0x7); + } else { + scsi_sts = gk_iosb.SCSI$B_IOSB_STS; + } + + if (gk_iosb.SCSI$W_VMS_STAT == SS$_NORMAL && scsi_sts == 0) { + sp->error = SCG_NO_ERROR; + if (usalp->debug > 0) { + fprintf(fp, "scsi_sts == 0\n"); + fprintf(fp, "gk_iosb.SCSI$B_IOSB_STS == 0\n"); + fprintf(fp, "sp->error %i\n", sp->error); + fprintf(fp, "sp->resid %i\n", sp->resid); + } + return (0); + } + + severity = gk_iosb.SCSI$W_VMS_STAT & 0x7; + + if (severity == 4) { + sp->error = SCG_FATAL; + if (usalp->debug > 0) { + fprintf(fp, "scsi_sts & 2\n"); + fprintf(fp, "gk_iosb.SCSI$B_IOSB_STS & 2\n"); + fprintf(fp, "gk_iosb.SCSI$W_VMS_STAT & 0x7 == SS$_FATAL\n"); + fprintf(fp, "sp->error %i\n", sp->error); + } + return (0); + } + if (gk_iosb.SCSI$W_VMS_STAT == SS$_TIMEOUT) { + sp->error = SCG_TIMEOUT; + if (usalp->debug > 0) { + fprintf(fp, "scsi_sts & 2\n"); + fprintf(fp, "gk_iosb.SCSI$B_IOSB_STS & 2\n"); + fprintf(fp, "gk_iosb.SCSI$W_VMS_STAT == SS$_TIMEOUT\n"); + fprintf(fp, "sp->error %i\n", sp->error); + } + return (0); + } + sp->error = SCG_RETRYABLE; + sp->u_scb.cmd_scb[0] = scsi_sts; + if (usalp->debug > 0) { + fprintf(fp, "scsi_sts & 2\n"); + fprintf(fp, "gk_iosb.SCSI$B_IOSB_STS & 2\n"); + fprintf(fp, "gk_iosb.SCSI$W_VMS_STAT != 0\n"); + fprintf(fp, "sp->error %i\n", sp->error); + } + return (0); +} + +static int +do_usal_sense(SCSI *usalp, struct usal_cmd *sp) +{ + int ret; + struct usal_cmd s_cmd; + + fillbytes((caddr_t)&s_cmd, sizeof (s_cmd), '\0'); + s_cmd.addr = (char *)sp->u_sense.cmd_sense; + s_cmd.size = sp->sense_len; + s_cmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA; + s_cmd.cdb_len = SC_G0_CDBLEN; + s_cmd.sense_len = CCS_SENSE_LEN; + s_cmd.cdb.g0_cdb.cmd = SC_REQUEST_SENSE; + s_cmd.cdb.g0_cdb.lun = sp->cdb.g0_cdb.lun; + s_cmd.cdb.g0_cdb.count = sp->sense_len; + ret = do_usal_cmd(usalp, &s_cmd); + + if (ret < 0) + return (ret); + if (s_cmd.u_scb.cmd_scb[0] & 02) { + /* XXX ??? Check condition on request Sense ??? */ + } + sp->sense_count = sp->sense_len - s_cmd.resid; + return (ret); +} + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + int ret; + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (0); + } + ret = do_usal_cmd(usalp, sp); + if (ret < 0) + return (ret); + if (sp->u_scb.cmd_scb[0] & 02) + ret = do_usal_sense(usalp, sp); + return (ret); +} diff --git a/libusal/scsi-wnt.c b/libusal/scsi-wnt.c new file mode 100644 index 0000000..ddce64b --- /dev/null +++ b/libusal/scsi-wnt.c @@ -0,0 +1,1848 @@ +/* + * 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. + * + */ + +/* @(#)scsi-wnt.c 1.45 04/07/19 Copyright 1998-2004 J. Schilling, A.L. Faber, J.A. Key */ +/* + * Interface for the Win32 ASPI library. + * You need wnaspi32.dll and aspi32.sys + * Both can be installed from ASPI_ME + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1998-2004 J. Schilling + * Copyright (c) 1999 A.L. Faber for the first implementation + * of this interface. + * TODO: + * - DMA resid handling + * - better handling of maxDMA + * - SCSI reset support + */ +/* + * 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 for Win32 ASPI AspiRouter + * + * NOTE: aspi-win32.h includes Windows.h and Windows.h includes + * Base.h which has a second typedef for BOOL. + * We define BOOL to make all local code use BOOL + * from Windows.h and use the hidden __SBOOL for + * our global interfaces. + */ +#define BOOL WBOOL /* This is the Win BOOL */ +#define format __format +#include <usal/aspi-win32.h> +#include <usal/spti-wnt.h> +#undef format + +#ifdef __CYGWIN32__ /* Use dlopen() */ +#include <dlfcn.h> +#endif + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_version[] = "scsi-wnt.c-1.45"; /* The version for this transport*/ +static char _usal_itrans_version[] = "SPTI-scsi-wnt.c-1.45"; /* The version for SPTI */ + +/* + * Local defines and constants + */ +/*#define DEBUG_WNTASPI*/ + +#define MAX_SCG 16 /* Max # of SCSI controllers */ +#define MAX_TGT 16 /* Max # of SCSI Targets */ +#define MAX_LUN 8 /* Max # of SCSI LUNs */ + +#ifdef DEBUG_WNTASPI +#endif + +struct usal_local { + int dummy; + char *filenames[MAX_SCG][MAX_TGT][MAX_LUN]; + char drive_wanted; +}; +#define usallocal(p) ((struct usal_local *)((p)->local)) + +/* + * Local variables + */ +static int busses; +static DWORD (*pfnGetASPI32SupportInfo)(void) = NULL; +static DWORD (*pfnSendASPI32Command)(LPSRB) = NULL; +static BOOL (*pfnGetASPI32Buffer)(PASPI32BUFF) = NULL; +static BOOL (*pfnFreeASPI32Buffer)(PASPI32BUFF) = NULL; +static BOOL (*pfnTranslateASPI32Address)(PDWORD, PDWORD) = NULL; + +static int DriverLoaded = 0; /* ASPI or SPTI */ +static HANDLE hAspiLib = NULL; /* Used for Loadlib */ + +#define MAX_DMA_WNT (63L*1024L) /* ASPI-Driver allows up to 64k ??? */ + +/* + * Local function prototypes + */ +static void exit_func(void); +#ifdef DEBUG_WNTASPI +static void DebugScsiSend(SCSI *usalp, SRB_ExecSCSICmd *s, int bDisplayBuffer); +#endif +static void copy_sensedata(SRB_ExecSCSICmd *cp, struct usal_cmd *sp); +static void set_error(SRB_ExecSCSICmd *cp, struct usal_cmd *sp); +static BOOL open_driver(SCSI *usalp); +static BOOL load_aspi(SCSI *usalp); +static BOOL close_driver(void); +static int ha_inquiry(SCSI *usalp, int id, SRB_HAInquiry *ip); +#ifdef __USED__ +static int resetSCSIBus(SCSI *usalp); +#endif +static int scsiabort(SCSI *usalp, SRB_ExecSCSICmd *sp); + + +/* SPTI Start ---------------------------------------------------------------*/ +/* + * From scsipt.c - Copyright (C) 1999 Jay A. Key + * Homepage: http://akrip.sourceforge.net/ + * Native NT support functions via the SCSI Pass Through interface instead + * of ASPI. Although based on information from the NT 4.0 DDK from + * Microsoft, the information has been sufficiently distilled to allow + * compilation w/o having the DDK installed. + * added to scsi-wnt.c by Richard Stemmer, rs@epost.de + * See http://www.ste-home.de/cdrtools-spti/ + */ + +#define PREFER_SPTI 1 /* Prefer SPTI if available, else try ASPI, force ASPI with dev=ASPI: */ +/* #define CREATE_NONSHARED 1 */ /* open CDROM-Device not SHARED if possible */ +/* #define _DEBUG_SCSIPT 1 */ +#ifdef _DEBUG_SCSIPT +FILE *usalp_errfile; /* File for SPTI-Debug-Messages */ +#endif + +#define SENSE_LEN_SPTI 32 /* Sense length for ASPI is only 14 */ +#define NUM_MAX_NTSCSI_DRIVES 26 /* a: ... z: */ +#define NUM_FLOPPY_DRIVES 2 +#define NUM_MAX_NTSCSI_HA NUM_MAX_NTSCSI_DRIVES + +#define NTSCSI_HA_INQUIRY_SIZE 36 + +#define SCSI_CMD_INQUIRY 0x12 + +typedef struct { + BYTE ha; /* SCSI Bus # */ + BYTE tgt; /* SCSI Target # */ + BYTE lun; /* SCSI Lun # */ + BYTE PortNumber; /* SCSI Card # (\\.\SCSI%d) */ + BYTE PathId; /* SCSI Bus/Channel # on card n */ + BYTE driveLetter; /* Win32 drive letter (e.g. c:) */ + BOOL bUsed; /* Win32 drive letter is used */ + HANDLE hDevice; /* Win32 handle for ioctl() */ + BYTE inqData[NTSCSI_HA_INQUIRY_SIZE]; +} DRIVE; + +typedef struct { + BYTE numAdapters; + DRIVE drive[NUM_MAX_NTSCSI_DRIVES]; +} SPTIGLOBAL; + +static int InitSCSIPT(SCSI *usalp); +static int DeinitSCSIPT(void); +static void GetDriveInformation(BYTE i, DRIVE *pDrive); +static BYTE SPTIGetNumAdapters(void); +static BYTE SPTIGetDeviceIndex(BYTE ha, BYTE tgt, BYTE lun); +static DWORD SPTIHandleHaInquiry(LPSRB_HAInquiry lpsrb); +static DWORD SPTIExecSCSICommand(LPSRB_ExecSCSICmd lpsrb, int sptTimeOutValue, BOOL bBeenHereBefore); +static HANDLE GetFileHandle(BYTE i, BOOL openshared); + +static BOOL bSCSIPTInit = FALSE; +static SPTIGLOBAL sptiglobal; +static BOOL UsingSPTI = FALSE; +static BOOL ForceAccess = FALSE; +static int sptihamax; +static USHORT sptihasortarr[NUM_MAX_NTSCSI_HA]; + +/* + * Initialization of SCSI Pass Through Interface code. Responsible for + * setting up the array of SCSI devices. This code will be a little + * different from the normal code -- it will query each drive letter from + * C: through Z: to see if it is a CD. When we identify a CD, we then + * send CDB with the INQUIRY command to it -- NT will automagically fill in + * the PathId, TargetId, and Lun for us. + */ +static int InitSCSIPT(SCSI *usalp) { + BYTE i; + BYTE j; + char buf[4]; + UINT uDriveType; + int retVal = 0; + USHORT hasortval; + char adapter_name[20]; + HANDLE fh; + ULONG returned; + BOOL status; + char InquiryBuffer[2048]; + PSCSI_ADAPTER_BUS_INFO ai; + BYTE bus; + int id_wanted=-1; + + if (bSCSIPTInit) + return (0); + + /* + * Detect all Busses on all SCSI-Adapters + * Fill up map array that allows us to later assign devices to + * bus numbers. + */ + sptihamax = 0; + i = 0; + do { + snprintf(adapter_name, sizeof (adapter_name), "\\\\.\\SCSI%d:", i); + fh = CreateFile(adapter_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, 0, NULL); + if (fh != INVALID_HANDLE_VALUE) { + status = DeviceIoControl(fh, + IOCTL_SCSI_GET_INQUIRY_DATA, + NULL, + 0, + InquiryBuffer, + 2048, + &returned, + FALSE); + if (status) { + ai = (PSCSI_ADAPTER_BUS_INFO) InquiryBuffer; + for (bus = 0; bus < ai->NumberOfBusses; bus++) { + sptihasortarr[sptihamax] = ((i<<8) | bus); + sptihamax++; + } + } + CloseHandle(fh); + } + i++; + } while (fh != INVALID_HANDLE_VALUE); + + errno = 0; + memset(&sptiglobal, 0, sizeof (SPTIGLOBAL)); + for (i = 0; i < NUM_MAX_NTSCSI_DRIVES; i++) + sptiglobal.drive[i].hDevice = INVALID_HANDLE_VALUE; + + for (i = NUM_FLOPPY_DRIVES; i < NUM_MAX_NTSCSI_DRIVES; i++) { + snprintf(buf, sizeof (buf), "%c:\\", (char)('A'+i)); + uDriveType = GetDriveType(buf); +#ifdef CDROM_ONLY + if (uDriveType == DRIVE_CDROM) { +#else + if (TRUE) { +#endif + GetDriveInformation(i, &sptiglobal.drive[i]); + + if (sptiglobal.drive[i].bUsed) { + retVal++; + hasortval = (sptiglobal.drive[i].PortNumber<<8) | sptiglobal.drive[i].PathId; + for (j = 0; j < sptihamax; j++) { + if (hasortval <= sptihasortarr[j]) + break; + } + if (j == sptihamax) { + sptihasortarr[j] = hasortval; + sptihamax++; + } else if (hasortval < sptihasortarr[j]) { + memmove(&sptihasortarr[j+1], &sptihasortarr[j], (sptihamax-j) * sizeof (USHORT)); + sptihasortarr[j] = hasortval; + sptihamax++; + } + + /* shortcut for device names, remember the hit */ + if(uDriveType==DRIVE_CDROM && usalp->local) { + /* printf("seen, %d at %d, %d, %d\n", sptiglobal.drive[i].driveLetter, sptiglobal.drive[i].ha, sptiglobal.drive[i].tgt, sptiglobal.drive[i].lun); */ + if(usallocal(usalp)->drive_wanted && *buf==toupper(usallocal(usalp)->drive_wanted)) + id_wanted=i; + /* don't keep the names, serial search in _natname is sufficient */ + } + } + } + } + /* looks like a workaround for diverging ASPI and SPTI hostadapter numbers, + most likely an attempt to keep the world of fake numbers + consistent; + EB */ + if (sptihamax > 0) { + for (i = NUM_FLOPPY_DRIVES; i < NUM_MAX_NTSCSI_DRIVES; i++) + if (sptiglobal.drive[i].bUsed) + for (j = 0; j < sptihamax; j++) { + if (sptihasortarr[j] == ((sptiglobal.drive[i].PortNumber<<8) | sptiglobal.drive[i].PathId)) { + sptiglobal.drive[i].ha = j; + break; + } + } + } + sptiglobal.numAdapters = SPTIGetNumAdapters(); + + bSCSIPTInit = TRUE; + if(id_wanted>0) { + usal_scsibus(usalp)=sptiglobal.drive[id_wanted].ha; + usal_target(usalp) =sptiglobal.drive[id_wanted].tgt; + usal_lun(usalp) =sptiglobal.drive[id_wanted].lun; + + //#if 1 + #ifdef _DEBUG_SCSIPT + fprintf(stderr, "named SCSIPT drive type %d found as %c, choosing %d, %d, %d\n", + uDriveType, + 'A'+id_wanted, + usal_scsibus(usalp), + usal_target(usalp), + usal_lun(usalp)); + #endif + } + + if (retVal > 0) + UsingSPTI = TRUE; + + return (retVal); +} + + +static int +DeinitSCSIPT(void) +{ + BYTE i; + + if (!bSCSIPTInit) + return (0); + + for (i = NUM_FLOPPY_DRIVES; i < NUM_MAX_NTSCSI_DRIVES; i++) { + if (sptiglobal.drive[i].bUsed) { + CloseHandle(sptiglobal.drive[i].hDevice); + } + } + + sptiglobal.numAdapters = SPTIGetNumAdapters(); + + memset(&sptiglobal, 0, sizeof (SPTIGLOBAL)); + bSCSIPTInit = FALSE; + return (-1); +} + + +/* + * Returns the number of "adapters" present. + */ +static BYTE +SPTIGetNumAdapters(void) +{ + BYTE buf[256]; + WORD i; + BYTE numAdapters = 0; + + memset(buf, 0, 256); + + /* + * PortNumber 0 should exist, so pre-mark it. This avoids problems + * when the primary IDE drives are on PortNumber 0, but can't be opened + * because of insufficient privelege (ie. non-admin). + */ + buf[0] = 1; + for (i = 0; i < NUM_MAX_NTSCSI_DRIVES; i++) { + if (sptiglobal.drive[i].bUsed) + buf[sptiglobal.drive[i].ha] = 1; + } + + for (i = 0; i <= 255; i++) + if (buf[i]) + numAdapters = (BYTE)(i + 1); + +/* numAdapters++; */ + + return (numAdapters); +} + +#include <ctype.h> +static BOOL +w2k_or_newer(void) +{ + OSVERSIONINFO osver; + + memset(&osver, 0, sizeof (osver)); + osver.dwOSVersionInfoSize = sizeof (osver); + GetVersionEx(&osver); + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { + /* + * Win2000 is NT-5.0, Win-XP is NT-5.1 + */ + if (osver.dwMajorVersion > 4) + return (TRUE); + } + return (FALSE); +} + +static BOOL +w2kstyle_create(void) +{ + OSVERSIONINFO osver; + +/* return FALSE; */ + memset(&osver, 0, sizeof (osver)); + osver.dwOSVersionInfoSize = sizeof (osver); + GetVersionEx(&osver); + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { + /* + * Win2000 is NT-5.0, Win-XP is NT-5.1 + */ + if (osver.dwMajorVersion > 4) + return (TRUE); + + if (osver.dwMajorVersion == 4) { /* NT-4.x */ + char *vers = osver.szCSDVersion; + + if (strlen(vers) == 0) + return (FALSE); + + /* + * Servicepack is installed, skip over non-digit part + */ + while (*vers != '\0' && !isdigit(*vers)) + vers++; + if (*vers == '\0') + return (FALSE); + + if (isdigit(vers[0]) && + (atoi(vers) >= 4 || isdigit(vers[1]))) /* Fom Service Pack 4 */ + return (TRUE); /* same as for W2K */ + } + } + return (FALSE); +} + + +/* + * Universal function to get a file handle to the CD device. Since + * NT 4.0 wants just the GENERIC_READ flag, and Win2K wants both + * GENERIC_READ and GENERIC_WRITE (why a read-only CD device needs + * GENERIC_WRITE access is beyond me...), the easist workaround is to just + * try them both. + */ +static HANDLE +GetFileHandle(BYTE i, BOOL openshared) +{ + char buf[12]; + HANDLE fh; + DWORD dwFlags = GENERIC_READ; + DWORD dwAccessMode = 0; + + dwAccessMode = FILE_SHARE_READ; + if (w2kstyle_create()) { /* if Win2K or greater, add GENERIC_WRITE */ + dwFlags |= GENERIC_WRITE; + dwAccessMode |= FILE_SHARE_WRITE; +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: GetFileHandle(): Setting for Win2K\n"); +#endif + } + snprintf(buf, sizeof (buf), "\\\\.\\%c:", (char)('A'+i)); +#ifdef CREATE_NONSHARED + if (openshared) { + fh = CreateFile(buf, dwFlags, dwAccessMode, NULL, + OPEN_EXISTING, 0, NULL); + } else { + fh = CreateFile(buf, dwFlags, 0, NULL, + OPEN_EXISTING, 0, NULL); + } + if (!openshared && fh == INVALID_HANDLE_VALUE && GetLastError() == ERROR_SHARING_VIOLATION) +#endif + fh = CreateFile(buf, dwFlags, dwAccessMode, NULL, + OPEN_EXISTING, 0, NULL); + if (fh == INVALID_HANDLE_VALUE) { + /* + * it went foobar somewhere, so try it with the GENERIC_WRITE + * bit flipped + */ + dwFlags ^= GENERIC_WRITE; + dwAccessMode ^= FILE_SHARE_WRITE; +#ifdef CREATE_NONSHARED + if (openshared) { + fh = CreateFile(buf, dwFlags, dwAccessMode, NULL, + OPEN_EXISTING, 0, NULL); + } else { + fh = CreateFile(buf, dwFlags, 0, NULL, + OPEN_EXISTING, 0, NULL); + } + if (!openshared && fh == INVALID_HANDLE_VALUE && GetLastError() == ERROR_SHARING_VIOLATION) +#endif + fh = CreateFile(buf, dwFlags, dwAccessMode, NULL, + OPEN_EXISTING, 0, NULL); + } +#ifdef _DEBUG_SCSIPT + if (fh == INVALID_HANDLE_VALUE) + fprintf(usalp_errfile, "SPTI: CreateFile() failed! -> %d\n", GetLastError()); + else + fprintf(usalp_errfile, "SPTI: CreateFile() returned %d\n", GetLastError()); +#endif + + return (fh); +} + + +/* + * fills in a pDrive structure with information from a SCSI_INQUIRY + * and obtains the ha:tgt:lun values via IOCTL_SCSI_GET_ADDRESS + */ +static void GetDriveInformation(BYTE i, DRIVE *pDrive) +{ + HANDLE fh; + BOOL status; + SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; + SCSI_ADDRESS scsiAddr; + ULONG length; + ULONG returned; + BYTE inqData[NTSCSI_HA_INQUIRY_SIZE]; + +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: Checking drive %c:", 'A'+i); +#endif + + fh = GetFileHandle(i, TRUE); /* No NONSHARED Create for inquiry */ + + if (fh == INVALID_HANDLE_VALUE) { +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, " : fh == INVALID_HANDLE_VALUE\n"); +#endif + return; + } + +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, " : Index %d: fh == %08X\n", i, fh); +#endif + + + /* + * Get the drive inquiry data + */ + memset(&swb, 0, sizeof (swb)); + memset(inqData, 0, sizeof (inqData)); + swb.spt.Length = sizeof (SCSI_PASS_THROUGH_DIRECT); + swb.spt.CdbLength = 6; + swb.spt.SenseInfoLength = 24; + swb.spt.DataIn = SCSI_IOCTL_DATA_IN; + swb.spt.DataTransferLength = 100; + swb.spt.TimeOutValue = 2; + swb.spt.DataBuffer = inqData; + swb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); + swb.spt.Cdb[0] = SCSI_CMD_INQUIRY; + swb.spt.Cdb[4] = NTSCSI_HA_INQUIRY_SIZE; + + length = sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER); + status = DeviceIoControl(fh, + IOCTL_SCSI_PASS_THROUGH_DIRECT, + &swb, + sizeof (swb), + &swb, + sizeof (swb), + &returned, + NULL); + + if (!status) { + CloseHandle(fh); +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: Error DeviceIoControl() -> %d\n", GetLastError()); +#endif + return; + } + + memcpy(pDrive->inqData, inqData, NTSCSI_HA_INQUIRY_SIZE); + + /* + * get the address (path/tgt/lun) of the drive via IOCTL_SCSI_GET_ADDRESS + */ + memset(&scsiAddr, 0, sizeof (SCSI_ADDRESS)); + scsiAddr.Length = sizeof (SCSI_ADDRESS); + if (DeviceIoControl(fh, IOCTL_SCSI_GET_ADDRESS, NULL, 0, + &scsiAddr, sizeof (SCSI_ADDRESS), &returned, + NULL)) { +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "Device %c: Port=%d, PathId=%d, TargetId=%d, Lun=%d\n", + (char)i+'A', scsiAddr.PortNumber, scsiAddr.PathId, + scsiAddr.TargetId, scsiAddr.Lun); +#endif + pDrive->bUsed = TRUE; + pDrive->ha = scsiAddr.PortNumber; /* preliminary */ + pDrive->PortNumber = scsiAddr.PortNumber; + pDrive->PathId = scsiAddr.PathId; + pDrive->tgt = scsiAddr.TargetId; + pDrive->lun = scsiAddr.Lun; + pDrive->driveLetter = i; + pDrive->hDevice = INVALID_HANDLE_VALUE; + + } else if (GetLastError() == 50) { /* support USB/FIREWIRE devices where this call is not supported assign drive letter as device ID */ + pDrive->bUsed = TRUE; + pDrive->ha = i; + pDrive->PortNumber = i+64; /* hopefully no conflict with other PortNumber */ + pDrive->PathId = 0; + pDrive->tgt = 0; + pDrive->lun = 0; + pDrive->driveLetter = i; + pDrive->hDevice = INVALID_HANDLE_VALUE; +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "USB/Firewire Device %c: Port=%d, TargetId=%d, Lun=%d\n", (char)i+'A', i, 0, 0); +#endif + } else { + pDrive->bUsed = FALSE; +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: Device %s: Error DeviceIoControl(): %d\n", (char)i+'A', GetLastError()); +#endif + CloseHandle(fh); + return; + } +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: Adding drive %c: (%d:%d:%d)\n", 'A'+i, + pDrive->ha, pDrive->tgt, pDrive->lun); +#endif + CloseHandle(fh); +} + + + +static DWORD +SPTIHandleHaInquiry(LPSRB_HAInquiry lpsrb) +{ + DWORD *pMTL; + + lpsrb->HA_Count = sptiglobal.numAdapters; + if (lpsrb->SRB_HaId >= sptiglobal.numAdapters) { + lpsrb->SRB_Status = SS_INVALID_HA; + return (SS_INVALID_HA); + } + lpsrb->HA_SCSI_ID = 7; /* who cares... we're not really an ASPI manager */ + memcpy(lpsrb->HA_ManagerId, "AKASPI v0.000001", 16); + memcpy(lpsrb->HA_Identifier, "SCSI Adapter ", 16); + lpsrb->HA_Identifier[13] = (char)('0'+lpsrb->SRB_HaId); + memset(lpsrb->HA_Unique, 0, 16); + lpsrb->HA_Unique[3] = 8; + pMTL = (LPDWORD)&lpsrb->HA_Unique[4]; + *pMTL = 64 * 1024; + + lpsrb->SRB_Status = SS_COMP; + return (SS_COMP); +} + +/* + * Looks up the index in the drive array for a given ha:tgt:lun triple + */ +static BYTE +SPTIGetDeviceIndex(BYTE ha, BYTE tgt, BYTE lun) +{ + BYTE i; + +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: SPTIGetDeviceIndex, %d, %d, %d\n", ha, + tgt, lun); +#endif + + for (i = NUM_FLOPPY_DRIVES; i < NUM_MAX_NTSCSI_DRIVES; i++) { + if (sptiglobal.drive[i].bUsed) { + DRIVE *lpd; + + lpd = &sptiglobal.drive[i]; + if ((lpd->ha == ha) && (lpd->tgt == tgt) && (lpd->lun == lun)) + return (i); + } + } + + return (0); +} + +/* + * Converts ASPI-style SRB to SCSI Pass Through IOCTL + */ + +static DWORD +SPTIExecSCSICommand(LPSRB_ExecSCSICmd lpsrb, int sptTimeOutValue, BOOL bBeenHereBefore) +{ + BOOL status; + SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; + ULONG length; + ULONG returned; + BYTE idx; + BYTE j; + + idx = SPTIGetDeviceIndex(lpsrb->SRB_HaId, lpsrb->SRB_Target, lpsrb->SRB_Lun); + + if (idx == 0) { + lpsrb->SRB_Status = SS_NO_DEVICE; + return (SS_NO_DEVICE); + } + + if (lpsrb->CDBByte[0] == SCSI_CMD_INQUIRY) { + lpsrb->SRB_Status = SS_COMP; + memcpy(lpsrb->SRB_BufPointer, sptiglobal.drive[idx].inqData, NTSCSI_HA_INQUIRY_SIZE); + return (SS_COMP); + } + + if (sptiglobal.drive[idx].hDevice == INVALID_HANDLE_VALUE) + sptiglobal.drive[idx].hDevice = GetFileHandle(sptiglobal.drive[idx].driveLetter, FALSE); + + memset(&swb, 0, sizeof (swb)); + swb.spt.Length = sizeof (SCSI_PASS_THROUGH); + swb.spt.CdbLength = lpsrb->SRB_CDBLen; + if (lpsrb->SRB_Flags & SRB_DIR_IN) + swb.spt.DataIn = SCSI_IOCTL_DATA_IN; + else if (lpsrb->SRB_Flags & SRB_DIR_OUT) + swb.spt.DataIn = SCSI_IOCTL_DATA_OUT; + else + swb.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; + swb.spt.DataTransferLength = lpsrb->SRB_BufLen; + swb.spt.TimeOutValue = sptTimeOutValue; + swb.spt.SenseInfoLength = lpsrb->SRB_SenseLen; + swb.spt.DataBuffer = lpsrb->SRB_BufPointer; + swb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); + memcpy(swb.spt.Cdb, lpsrb->CDBByte, lpsrb->SRB_CDBLen); + length = sizeof (swb); + +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: SPTIExecSCSICmd: calling DeviceIoControl()"); + fprintf(usalp_errfile, " : cmd == 0x%02X", swb.spt.Cdb[0]); +#endif + status = DeviceIoControl(sptiglobal.drive[idx].hDevice, + IOCTL_SCSI_PASS_THROUGH_DIRECT, + &swb, + length, + &swb, + length, + &returned, + NULL); + + lpsrb->SRB_SenseLen = swb.spt.SenseInfoLength; + memcpy(lpsrb->SenseArea, swb.ucSenseBuf, lpsrb->SRB_SenseLen); + if (status && swb.spt.ScsiStatus == 0) { + lpsrb->SRB_Status = SS_COMP; +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, " : SRB_Status == SS_COMP\n"); +#endif + } else { + DWORD dwErrCode; + + lpsrb->SRB_Status = SS_ERR; +/* lpsrb->SRB_TargStat = 0x0004;*/ + lpsrb->SRB_TargStat = swb.spt.ScsiStatus; + + dwErrCode = GetLastError(); +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, " : error == %d handle == %08X\n", dwErrCode, sptiglobal.drive[idx].hDevice); +#endif + /* + * KLUDGE ALERT! KLUDGE ALERT! KLUDGE ALERT! + * Whenever a disk changer switches disks, it may render the device + * handle invalid. We try to catch these errors here and recover + * from them. + */ + if (!bBeenHereBefore && + ((dwErrCode == ERROR_MEDIA_CHANGED) || (dwErrCode == ERROR_INVALID_HANDLE))) { + if (dwErrCode != ERROR_INVALID_HANDLE) + CloseHandle(sptiglobal.drive[idx].hDevice); + GetDriveInformation(idx, &sptiglobal.drive[idx]); + if (sptihamax > 0) { + if (sptiglobal.drive[idx].bUsed) + for (j = 0; j < sptihamax; j++) { + if (sptihasortarr[j] == + ((sptiglobal.drive[idx].PortNumber << 8) | sptiglobal.drive[idx].PathId)) { + sptiglobal.drive[idx].ha = j; + break; + } + } + } +#ifdef _DEBUG_SCSIPT + fprintf(usalp_errfile, "SPTI: SPTIExecSCSICommand: Retrying after ERROR_MEDIA_CHANGED\n"); +#endif + return (SPTIExecSCSICommand(lpsrb, sptTimeOutValue, TRUE)); + } + } + return (lpsrb->SRB_Status); +} +/* SPTI End -----------------------------------------------------------------*/ + + +static void +exit_func() +{ + if (!close_driver()) + errmsgno(EX_BAD, "Cannot close Win32-ASPI-Driver.\n"); +} + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_version(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + if (UsingSPTI) + return (_usal_itrans_version); + return (_usal_trans_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (__sccsid); + } + } + return ((char *)0); +} + +static int +usalo_help(SCSI *usalp, FILE *f) +{ + __usal_help(f, "ASPI", "Generic transport independent SCSI", + "ASPI:", "bus,target,lun", "ASPI:1,2,0", TRUE, FALSE); + __usal_help(f, "SPTI", "Generic SCSI for Windows NT/2000/XP", + "SPTI:", "bus,target,lun", "SPTI:1,2,0", TRUE, FALSE); + return (0); +} + +static int +usalo_open(SCSI *usalp, char *device) +{ + int busno = usal_scsibus(usalp); + int tgt = usal_target(usalp); + int tlun = usal_lun(usalp); + + /*usal_local(usalp)->drive_wanted = NULL; + for(i=0;i<MAX_SCG*MAX_TGT*MAX_LUN;i++) + usallocal(usalp)->filenames[i]=NULL; + */ + usalp->local = calloc(1, sizeof (struct usal_local)); + if (usalp->local == NULL) + return (0); + + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) { + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Illegal value for busno, target or lun '%d,%d,%d'", + busno, tgt, tlun); + return (-1); + } + + /* Explicite choice of Schilling syntax */ + if (device != NULL && (strcmp(device, "SPTI") == 0 || strcmp(device, "ASPI") == 0)) + goto devok; + + /* use device as drive letter */ + if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) { +/* + errno = EINVAL; + if (usalp->errstr) + snprintf(usalp->errstr, SCSI_ERRSTR_SIZE, + "Open by 'devname' not supported on this OS"); + return (-1); +*/ + + UsingSPTI = TRUE; + usallocal(usalp)->drive_wanted = *device; + + /* not the finest solution but prevents breaking on various + * places for no good reasons... */ + usal_scsibus(usalp)=0; + usal_target(usalp)=0; + usal_lun(usalp)=0; + goto openbydev; + } +devok: + if (DriverLoaded <= 0) { /* do not change access method on open driver */ + ForceAccess = FALSE; +#ifdef PREFER_SPTI + UsingSPTI = TRUE; +#else + UsingSPTI = FALSE; +#endif + if (!w2k_or_newer()) + UsingSPTI = FALSE; + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_open: Prefered SCSI transport: %s\n", + UsingSPTI ? "SPTI":"ASPI"); + } + if (device != NULL && strcmp(device, "SPTI") == 0) { + UsingSPTI = TRUE; + ForceAccess = TRUE; + } else if (device != NULL && strcmp(device, "ASPI") == 0) { + UsingSPTI = FALSE; + ForceAccess = TRUE; + } + if (device != NULL && usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_open: Selected SCSI transport: %s\n", + UsingSPTI ? "SPTI":"ASPI"); + } + } + + /* + * Check if variables are within the range + */ + if (tgt >= 0 && tgt >= 0 && tlun >= 0) { + /* + * This is the non -scanbus case. + */ + ; + } else if (tgt == -2 && tgt == -2 && + (tgt == -2 || tlun >= 0)) { + /* + * This is the dev=ASPI case. + */ + ; + } else if (tgt != -1 || tgt != -1 || tlun != -1) { + errno = EINVAL; + return (-1); + } + +openbydev: + /* + * Try to open ASPI-Router + */ + if (!open_driver(usalp)) + return (-1); + + /* + * More than we have ... + */ + if (busno >= busses) { + close_driver(); + return (-1); + } + + /* + * Install Exit Function which closes the ASPI-Router + */ + atexit(exit_func); + + /* + * Success after all + */ + return (1); +} + +static int +usalo_close(SCSI *usalp) +{ + int i; + /* + for(i=0;i<MAX_SCG*MAX_TGT*MAX_LUN;i++) { + if(usallocal(usalp)->filenames[i]) { + free(usallocal(usalp)->filenames[i]); + usallocal(usalp)->filenames[i]=NULL; + } + } + */ + if(usalp->local) { + free(usalp->local); + usalp->local=NULL; + } + //printf("closing\n"); + + exit_func(); + return (0); +} + +static long +usalo_maxdma(SCSI *usalp, long amt) +{ + return (MAX_DMA_WNT); +} + +static void * +usalo_getbuf(SCSI *usalp, long amt) +{ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "usalo_getbuf: %ld bytes\n", amt); + } + usalp->bufbase = malloc((size_t)(amt)); + return (usalp->bufbase); +} + +static void +usalo_freebuf(SCSI *usalp) +{ + if (usalp->bufbase) + free(usalp->bufbase); + usalp->bufbase = NULL; +} + +static __SBOOL +usalo_havebus(SCSI *usalp, int busno) +{ + if (busno < 0 || busno >= busses) + return (FALSE); + + return (TRUE); +} + +static int +usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + if (busno < 0 || busno >= busses || + tgt < 0 || tgt >= MAX_TGT || + tlun < 0 || tlun >= MAX_LUN) + return (-1); + + /* + * Return fake + */ + return (1); +} + + +static int +usalo_initiator_id(SCSI *usalp) +{ + SRB_HAInquiry s; + + if (ha_inquiry(usalp, usal_scsibus(usalp), &s) < 0) + return (-1); + return (s.HA_SCSI_ID); +} + +static int +usalo_isatapi(SCSI *usalp) +{ + return (-1); /* XXX Need to add real test */ +} + + +/* + * XXX usalo_reset not yet tested + */ +static int +usalo_reset(SCSI *usalp, int what) +{ + + DWORD Status = 0; + DWORD EventStatus = WAIT_OBJECT_0; + HANDLE Event = NULL; + SRB_BusDeviceReset s; + + if (what == SCG_RESET_NOP) { + if (UsingSPTI) + return (-1); + else + return (0); /* Can ASPI really reset? */ + } + if (what != SCG_RESET_BUS) { + errno = EINVAL; + return (-1); + } + if (UsingSPTI) { + fprintf((FILE *)usalp->errfile, + "Reset SCSI device not implemented with SPTI\n"); + return (-1); + } + + /* + * XXX Does this reset TGT or BUS ??? + */ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Attempting to reset SCSI device\n"); + } + + /* + * Check if ASPI library is loaded + */ + if (DriverLoaded <= 0) { + fprintf((FILE *)usalp->errfile, + "error in usalo_reset: ASPI driver not loaded !\n"); + return (-1); + } + + memset(&s, 0, sizeof (s)); /* Clear SRB_BesDeviceReset structure */ + + Event = CreateEvent(NULL, TRUE, FALSE, NULL); + + /* + * Set structure variables + */ + s.SRB_Cmd = SC_RESET_DEV; /* ASPI command code = SC_RESET_DEV */ + s.SRB_HaId = usal_scsibus(usalp); /* ASPI host adapter number */ + s.SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */ + s.SRB_Target = usal_target(usalp); /* Target's SCSI ID */ + s.SRB_Lun = usal_lun(usalp); /* Target's LUN number */ + s.SRB_PostProc = (LPVOID)Event; /* Post routine */ + + /* + * Initiate SCSI command + */ + Status = pfnSendASPI32Command((LPSRB)&s); + + /* + * Check status + */ + if (Status == SS_PENDING) { + /* + * Wait till command completes + */ + EventStatus = WaitForSingleObject(Event, INFINITE); + } + + + /**************************************************/ + /* Reset event to non-signaled state. */ + /**************************************************/ + + if (EventStatus == WAIT_OBJECT_0) { + /* + * Clear event + */ + ResetEvent(Event); + } + + /* + * Close the event handle + */ + CloseHandle(Event); + + /* + * Check condition + */ + if (s.SRB_Status != SS_COMP) { + fprintf((FILE *)usalp->errfile, + "ERROR! 0x%08X\n", s.SRB_Status); + + /* + * Indicate that error has occured + */ + return (-1); + } + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Reset SCSI device completed\n"); + } + + /* + * Everything went OK + */ + return (0); +} + + +#ifdef DEBUG_WNTASPI +static void +DebugScsiSend(SCSI *usalp, SRB_ExecSCSICmd *s, int bDisplayBuffer) +{ + int i; + + fprintf((FILE *)usalp->errfile, "\n\nDebugScsiSend\n"); + fprintf((FILE *)usalp->errfile, "s->SRB_Cmd = 0x%02x\n", s->SRB_Cmd); + fprintf((FILE *)usalp->errfile, "s->SRB_HaId = 0x%02x\n", s->SRB_HaId); + fprintf((FILE *)usalp->errfile, "s->SRB_Flags = 0x%02x\n", s->SRB_Flags); + fprintf((FILE *)usalp->errfile, "s->SRB_Target = 0x%02x\n", s->SRB_Target); + fprintf((FILE *)usalp->errfile, "s->SRB_Lun = 0x%02x\n", s->SRB_Lun); + fprintf((FILE *)usalp->errfile, "s->SRB_BufLen = 0x%02x\n", s->SRB_BufLen); + fprintf((FILE *)usalp->errfile, "s->SRB_BufPointer = %x\n", s->SRB_BufPointer); + fprintf((FILE *)usalp->errfile, "s->SRB_CDBLen = 0x%02x\n", s->SRB_CDBLen); + fprintf((FILE *)usalp->errfile, "s->SRB_SenseLen = 0x%02x\n", s->SRB_SenseLen); + fprintf((FILE *)usalp->errfile, "s->CDBByte ="); + for (i = 0; i < min(s->SRB_CDBLen, 16); i++) { + fprintf((FILE *)usalp->errfile, " %02X ", s->CDBByte[i]); + } + fprintf((FILE *)usalp->errfile, "\n"); + + /* + if (bDisplayBuffer != 0 && s->SRB_BufLen >= 8) { + + fprintf((FILE *)usalp->errfile, "s->SRB_BufPointer ="); + for (i = 0; i < 8; i++) { + fprintf((FILE *)usalp->errfile, + " %02X ", ((char *)s->SRB_BufPointer)[i]); + } + fprintf((FILE *)usalp->errfile, "\n"); + } +*/ + fprintf((FILE *)usalp->errfile, "Debug done\n"); +} +#endif + +static void +copy_sensedata(SRB_ExecSCSICmd *cp, struct usal_cmd *sp) +{ + sp->sense_count = cp->SRB_SenseLen; + if (sp->sense_count > sp->sense_len) + sp->sense_count = sp->sense_len; + + memset(&sp->u_sense.Sense, 0x00, sizeof (sp->u_sense.Sense)); + memcpy(&sp->u_sense.Sense, cp->SenseArea, sp->sense_count); + + sp->u_scb.cmd_scb[0] = cp->SRB_TargStat; +} + +/* + * Set error flags + */ +static void +set_error(SRB_ExecSCSICmd *cp, struct usal_cmd *sp) +{ + switch (cp->SRB_Status) { + + case SS_COMP: /* 0x01 SRB completed without error */ + sp->error = SCG_NO_ERROR; + sp->ux_errno = 0; + break; + + case SS_ERR: /* 0x04 SRB completed with error */ + /* + * If the SCSI Status byte is != 0, we definitely could send + * the command to the target. We signal NO transport error. + */ + sp->error = SCG_NO_ERROR; + sp->ux_errno = EIO; + if (cp->SRB_TargStat) + break; + + case SS_PENDING: /* 0x00 SRB being processed */ + /* + * XXX Could SS_PENDING happen ??? + */ + case SS_ABORTED: /* 0x02 SRB aborted */ + case SS_ABORT_FAIL: /* 0x03 Unable to abort SRB */ + default: + sp->error = SCG_RETRYABLE; + sp->ux_errno = EIO; + break; + + case SS_INVALID_CMD: /* 0x80 Invalid ASPI command */ + case SS_INVALID_HA: /* 0x81 Invalid host adapter number */ + case SS_NO_DEVICE: /* 0x82 SCSI device not installed */ + + case SS_INVALID_SRB: /* 0xE0 Invalid parameter set in SRB */ + case SS_ILLEGAL_MODE: /* 0xE2 Unsupported Windows mode */ + case SS_NO_ASPI: /* 0xE3 No ASPI managers */ + case SS_FAILED_INIT: /* 0xE4 ASPI for windows failed init */ + case SS_MISMATCHED_COMPONENTS: /* 0xE7 The DLLs/EXEs of ASPI don't */ + /* version check */ + case SS_NO_ADAPTERS: /* 0xE8 No host adapters to manager */ + + case SS_ASPI_IS_SHUTDOWN: /* 0xEA Call came to ASPI after */ + /* PROCESS_DETACH */ + case SS_BAD_INSTALL: /* 0xEB The DLL or other components */ + /* are installed wrong */ + sp->error = SCG_FATAL; + sp->ux_errno = EINVAL; + break; + +#ifdef XXX + case SS_OLD_MANAGER: /* 0xE1 ASPI manager doesn't support */ + /* windows */ +#endif + case SS_BUFFER_ALIGN: /* 0xE1 Buffer not aligned (replaces */ + /* SS_OLD_MANAGER in Win32) */ + sp->error = SCG_FATAL; + sp->ux_errno = EFAULT; + break; + + case SS_ASPI_IS_BUSY: /* 0xE5 No resources available to */ + /* execute command */ + sp->error = SCG_RETRYABLE; + sp->ux_errno = EBUSY; + break; + +#ifdef XXX + case SS_BUFFER_TO_BIG: /* 0xE6 Buffer size too big to handle*/ +#endif + case SS_BUFFER_TOO_BIG: /* 0xE6 Correct spelling of 'too' */ + case SS_INSUFFICIENT_RESOURCES: /* 0xE9 Couldn't allocate resources */ + /* needed to init */ + sp->error = SCG_RETRYABLE; + sp->ux_errno = ENOMEM; + break; + } +} + + +struct aspi_cmd { + SRB_ExecSCSICmd s; + char pad[32]; +}; + +static int +usalo_send(SCSI *usalp) +{ + struct usal_cmd *sp = usalp->scmd; + DWORD Status = 0; + DWORD EventStatus = WAIT_OBJECT_0; + HANDLE Event = NULL; + struct aspi_cmd ac; + SRB_ExecSCSICmd *s; + + s = &ac.s; + + /* + * Check if ASPI library is loaded + */ + if (DriverLoaded <= 0) { + errmsgno(EX_BAD, "error in usalo_send: ASPI driver not loaded.\n"); + sp->error = SCG_FATAL; + return (0); + } + + if (usalp->fd < 0) { + sp->error = SCG_FATAL; + return (-1); + } + + /* + * Initialize variables + */ + sp->error = SCG_NO_ERROR; + sp->sense_count = 0; + sp->u_scb.cmd_scb[0] = 0; + sp->resid = 0; + + memset(&ac, 0, sizeof (ac)); /* Clear SRB structure */ + + /* + * Check cbd_len > the maximum command pakket that can be handled by ASPI + */ + if (sp->cdb_len > 16) { + sp->error = SCG_FATAL; + sp->ux_errno = EINVAL; + fprintf((FILE *)usalp->errfile, + "sp->cdb_len > sizeof (SRB_ExecSCSICmd.CDBByte). Fatal error in usalo_send, exiting...\n"); + return (-1); + } + /* + * copy cdrecord command into SRB + */ + movebytes(&sp->cdb, &(s->CDBByte), sp->cdb_len); + + Event = CreateEvent(NULL, TRUE, FALSE, NULL); + + /* + * Fill ASPI structure + */ + s->SRB_Cmd = SC_EXEC_SCSI_CMD; /* SCSI Command */ + s->SRB_HaId = usal_scsibus(usalp); /* Host adapter number */ + s->SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */ + s->SRB_Target = usal_target(usalp); /* Target SCSI ID */ + s->SRB_Lun = usal_lun(usalp); /* Target SCSI LUN */ + s->SRB_BufLen = sp->size; /* # of bytes transferred */ + s->SRB_BufPointer = sp->addr; /* pointer to data buffer */ + s->SRB_CDBLen = sp->cdb_len; /* SCSI command length */ + s->SRB_PostProc = Event; /* Post proc event */ + if (UsingSPTI) + s->SRB_SenseLen = SENSE_LEN_SPTI; /* Length of sense buffer, SPTI returns SenseInfoLength */ + else + s->SRB_SenseLen = SENSE_LEN; /* fixed length 14 for ASPI */ + /* + * Do we receive data from this ASPI command? + */ + if (sp->flags & SCG_RECV_DATA) { + + s->SRB_Flags |= SRB_DIR_IN; + } else { + /* + * Set direction to output + */ + if (sp->size > 0) { + s->SRB_Flags |= SRB_DIR_OUT; + } + } + +#ifdef DEBUG_WNTASPI + /* + * Dump some debug information when enabled + */ + DebugScsiSend(usalp, s, TRUE); +/* DebugScsiSend(usalp, s, (s->SRB_Flags&SRB_DIR_OUT) == SRB_DIR_OUT);*/ +#endif + + /* + * ------------ Send SCSI command -------------------------- + */ + + ResetEvent(Event); /* Clear event handle */ + if (UsingSPTI) { +#ifdef _DEBUG_SCSIPT + usalp_errfile = (FILE *)usalp->errfile; +#endif + Status = SPTIExecSCSICommand(s, sp->timeout, FALSE); + } + else + Status = pfnSendASPI32Command((LPSRB)s); /* Initiate SCSI command */ + if (Status == SS_PENDING) { /* If in progress */ + /* + * Wait untill command completes, or times out. + */ + EventStatus = WaitForSingleObject(Event, sp->timeout*1000L); +/* EventStatus = WaitForSingleObject(Event, 10L);*/ + + if (EventStatus == WAIT_OBJECT_0) + ResetEvent(Event); /* Clear event, time out */ + + if (s->SRB_Status == SS_PENDING) { /* Check if we got a timeout */ + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Timeout....\n"); + } + scsiabort(usalp, s); + ResetEvent(Event); /* Clear event, time out */ + CloseHandle(Event); /* Close the event handle */ + + sp->error = SCG_TIMEOUT; + return (1); /* Return error */ + } + } + CloseHandle(Event); /* Close the event handle */ + + /* + * Check ASPI command status + */ + if (s->SRB_Status != SS_COMP) { + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Error in usalo_send: s->SRB_Status is 0x%x\n", s->SRB_Status); + } + + set_error(s, sp); /* Set error flags */ + copy_sensedata(s, sp); /* Copy sense and status */ + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Mapped to: error %d errno: %d\n", sp->error, sp->ux_errno); + } + return (1); + } + + /* + * Return success + */ + return (0); +} + +/*************************************************************************** + * * + * BOOL open_driver() * + * * + * Opens the ASPI Router device driver and sets device_handle. * + * Returns: * + * TRUE - Success * + * FALSE - Unsuccessful opening of device driver * + * * + * Preconditions: ASPI Router driver has be loaded * + * * + ***************************************************************************/ +static BOOL +open_driver(SCSI *usalp) +{ + DWORD astatus; + BYTE HACount; + BYTE ASPIStatus; + int i; + +#ifdef DEBUG_WNTASPI + fprintf((FILE *)usalp->errfile, "enter open_driver\n"); +#endif + + /* + * Check if ASPI library is already loaded yet + */ + if (DriverLoaded > 0) { + DriverLoaded++; + return (TRUE); + } + + /* + * Load the ASPI library or SPTI + */ +#ifdef _DEBUG_SCSIPT + usalp_errfile = (FILE *)usalp->errfile; +#endif +#ifdef PREFER_SPTI + if (UsingSPTI) + if (InitSCSIPT(usalp) > 0) DriverLoaded++; +#endif +#ifdef PREFER_SPTI + if ((!UsingSPTI || !ForceAccess) && DriverLoaded <= 0) { +#else + if (!UsingSPTI || !ForceAccess) { +#endif + if (load_aspi(usalp)) { + DriverLoaded++; + UsingSPTI = FALSE; + } + } + +#ifndef PREFER_SPTI + if ((UsingSPTI || !ForceAccess) && DriverLoaded <= 0) + if (InitSCSIPT(usalp) > 0) + DriverLoaded++; +#endif /*PREFER_SPTI*/ + + if (DriverLoaded <= 0) { + if (UsingSPTI) { + if (errno == 0) + errno = ENOSYS; + } + fprintf((FILE *)usalp->errfile, "Can not load %s driver! ", + UsingSPTI ? "SPTI":"ASPI"); + return (FALSE); + } + + if (UsingSPTI) { + if (usalp->debug > 0) + fprintf((FILE *)usalp->errfile, "using SPTI Transport\n"); + + if (!sptiglobal.numAdapters) + astatus = (DWORD)(MAKEWORD(0, SS_NO_ADAPTERS)); + else + astatus = (DWORD)(MAKEWORD(sptiglobal.numAdapters, SS_COMP)); + } else { + astatus = pfnGetASPI32SupportInfo(); + } + + ASPIStatus = HIBYTE(LOWORD(astatus)); + HACount = LOBYTE(LOWORD(astatus)); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "open_driver %lX HostASPIStatus=0x%x HACount=0x%x\n", astatus, ASPIStatus, HACount); + } + + if (ASPIStatus != SS_COMP && ASPIStatus != SS_NO_ADAPTERS) { + fprintf((FILE *)usalp->errfile, "Could not find any host adapters\n"); + fprintf((FILE *)usalp->errfile, "ASPIStatus == 0x%02X", ASPIStatus); + return (FALSE); + } + busses = HACount; + +#ifdef DEBUG_WNTASPI + fprintf((FILE *)usalp->errfile, "open_driver HostASPIStatus=0x%x HACount=0x%x\n", ASPIStatus, HACount); + fprintf((FILE *)usalp->errfile, "leaving open_driver\n"); +#endif + + for (i = 0; i < busses; i++) { + SRB_HAInquiry s; + + ha_inquiry(usalp, i, &s); + } + + /* + * Indicate that library loaded/initialized properly + */ + return (TRUE); +} + +static BOOL +load_aspi(SCSI *usalp) +{ +#ifdef __CYGWIN32__ + hAspiLib = dlopen("WNASPI32", RTLD_NOW); +#else + hAspiLib = LoadLibrary("WNASPI32"); +#endif + /* + * Check if ASPI library is loaded correctly + */ + if (hAspiLib == NULL) { +#ifdef not_done_later + fprintf((FILE *)usalp->errfile, "Can not load ASPI driver! "); +#endif + return (FALSE); + } + + /* + * Get a pointer to GetASPI32SupportInfo function + * and a pointer to SendASPI32Command function + */ +#ifdef __CYGWIN32__ + pfnGetASPI32SupportInfo = (DWORD(*)(void))dlsym(hAspiLib, "GetASPI32SupportInfo"); + pfnSendASPI32Command = (DWORD(*)(LPSRB))dlsym(hAspiLib, "SendASPI32Command"); +#else + pfnGetASPI32SupportInfo = (DWORD(*)(void))GetProcAddress(hAspiLib, "GetASPI32SupportInfo"); + pfnSendASPI32Command = (DWORD(*)(LPSRB))GetProcAddress(hAspiLib, "SendASPI32Command"); +#endif + + if ((pfnGetASPI32SupportInfo == NULL) || (pfnSendASPI32Command == NULL)) { + fprintf((FILE *)usalp->errfile, + "ASPI function not found in library! "); + return (FALSE); + } + + /* + * The following functions are currently not used by libusal. + * If we start to use them, we need to check whether the founctions + * could be found in the ASPI library that just has been loaded. + */ +#ifdef __CYGWIN32__ + pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))dlsym(hAspiLib, "GetASPI32Buffer"); + pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))dlsym(hAspiLib, "FreeASPI32Buffer"); + pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))dlsym(hAspiLib, "TranslateASPI32Address"); +#else + pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "GetASPI32Buffer"); + pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "FreeASPI32Buffer"); + pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))GetProcAddress(hAspiLib, "TranslateASPI32Address"); +#endif + return (TRUE); +} + +/*************************************************************************** + * * + * BOOL close_driver() * + * * + * Closes the device driver * + * Returns: * + * TRUE - Success * + * FALSE - Unsuccessful closing of device driver * + * * + * Preconditions: ASPI Router driver has be opened with open_driver * + * * + ***************************************************************************/ +static BOOL +close_driver() +{ + if (--DriverLoaded > 0) + return (TRUE); + /* + * If library is loaded + */ + DeinitSCSIPT(); + /* + * Clear all variables + */ + if (hAspiLib) { + pfnGetASPI32SupportInfo = NULL; + pfnSendASPI32Command = NULL; + pfnGetASPI32Buffer = NULL; + pfnFreeASPI32Buffer = NULL; + pfnTranslateASPI32Address = NULL; + + /* + * Free ASPI library, we do not need it any longer + */ +#ifdef __CYGWIN32__ + dlclose(hAspiLib); +#else + FreeLibrary(hAspiLib); +#endif + hAspiLib = NULL; + } + + /* + * Indicate that shutdown has been finished properly + */ + return (TRUE); +} + +static int +ha_inquiry(SCSI *usalp, int id, SRB_HAInquiry *ip) +{ + DWORD Status; + + ip->SRB_Cmd = SC_HA_INQUIRY; + ip->SRB_HaId = id; + ip->SRB_Flags = 0; + ip->SRB_Hdr_Rsvd = 0; + + if (UsingSPTI) + Status = SPTIHandleHaInquiry(ip); + else + Status = pfnSendASPI32Command((LPSRB)ip); + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, "Status : %ld\n", Status); + fprintf((FILE *)usalp->errfile, "hacount: %d\n", ip->HA_Count); + fprintf((FILE *)usalp->errfile, "SCSI id: %d\n", ip->HA_SCSI_ID); + fprintf((FILE *)usalp->errfile, "Manager: '%.16s'\n", ip->HA_ManagerId); + fprintf((FILE *)usalp->errfile, "Identif: '%.16s'\n", ip->HA_Identifier); + usal_prbytes("Unique:", ip->HA_Unique, 16); + } + if (ip->SRB_Status != SS_COMP) + return (-1); + return (0); +} + +#ifdef __USED__ +static int +resetSCSIBus(SCSI *usalp) +{ + DWORD Status; + HANDLE Event; + SRB_BusDeviceReset s; + + if (UsingSPTI) { + fprintf((FILE *)usalp->errfile, + "Reset SCSI bus not implemented with SPTI\n"); + return (FALSE); + } + + fprintf((FILE *)usalp->errfile, "Attempting to reset SCSI bus\n"); + + Event = CreateEvent(NULL, TRUE, FALSE, NULL); + + memset(&s, 0, sizeof (s)); /* Clear SRB_BesDeviceReset structure */ + + /* + * Set structure variables + */ + s.SRB_Cmd = SC_RESET_DEV; + s.SRB_PostProc = (LPVOID)Event; + + /* + * Clear event + */ + ResetEvent(Event); + + /* + * Initiate SCSI command + */ + Status = pfnSendASPI32Command((LPSRB)&s); + + /* + * Check status + */ + if (Status == SS_PENDING) { + /* + * Wait till command completes + */ + WaitForSingleObject(Event, INFINITE); + } + + /* + * Close the event handle + */ + CloseHandle(Event); + + /* + * Check condition + */ + if (s.SRB_Status != SS_COMP) { + fprintf((FILE *)usalp->errfile, "ERROR 0x%08X\n", s.SRB_Status); + + /* + * Indicate that error has occured + */ + return (FALSE); + } + + /* + * Everything went OK + */ + return (TRUE); +} +#endif /* __USED__ */ + +static int +scsiabort(SCSI *usalp, SRB_ExecSCSICmd *sp) +{ + DWORD Status = 0; + SRB_Abort s; + + if (UsingSPTI) { + fprintf((FILE *)usalp->errfile, + "Abort SCSI not implemented with SPTI\n"); + return (FALSE); + } + + if (usalp->debug > 0) { + fprintf((FILE *)usalp->errfile, + "Attempting to abort SCSI command\n"); + } + + /* + * Check if ASPI library is loaded + */ + if (DriverLoaded <= 0) { + fprintf((FILE *)usalp->errfile, + "error in scsiabort: ASPI driver not loaded !\n"); + return (FALSE); + } + + /* + * Set structure variables + */ + s.SRB_Cmd = SC_ABORT_SRB; /* ASPI command code = SC_ABORT_SRB */ + s.SRB_HaId = usal_scsibus(usalp); /* ASPI host adapter number */ + s.SRB_Flags = 0; /* Flags */ + s.SRB_ToAbort = (LPSRB)&sp; /* sp */ + + /* + * Initiate SCSI abort + */ + Status = pfnSendASPI32Command((LPSRB)&s); + + /* + * Check condition + */ + if (s.SRB_Status != SS_COMP) { + fprintf((FILE *)usalp->errfile, "Abort ERROR! 0x%08X\n", s.SRB_Status); + + /* + * Indicate that error has occured + */ + return (FALSE); + } + + if (usalp->debug > 0) + fprintf((FILE *)usalp->errfile, "Abort SCSI command completed\n"); + + /* + * Everything went OK + */ + return (TRUE); +} + + +#define HAVE_NAT_NAMES +static char * usalo_natname(SCSI *usalp, int busno, int tgt, int tlun) { + int i; + static char name[3]; + printf("hm, %d, %d, %d\n", busno, tgt, tlun); + if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) + return "BADID"; + for (i = NUM_FLOPPY_DRIVES; i < NUM_MAX_NTSCSI_DRIVES; i++) { + if(sptiglobal.drive[i].bUsed && + tlun == sptiglobal.drive[i].lun && + tgt == sptiglobal.drive[i].tgt && + busno == sptiglobal.drive[i].ha) + { + snprintf(name, 3, "%c:", 'A'+sptiglobal.drive[i].driveLetter); + return name; + } + } + return "BADID"; +} + diff --git a/libusal/scsierrs.c b/libusal/scsierrs.c new file mode 100644 index 0000000..154e418 --- /dev/null +++ b/libusal/scsierrs.c @@ -0,0 +1,1008 @@ +/* + * 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. + * + */ + +/* @(#)scsierrs.c 2.29 04/06/17 Copyright 1987-1996 J. Schilling */ +/* + * Error printing for scsitransp.c + * + * Copyright (c) 1987-1996 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 <unixstd.h> /* for sys/types.h needed in schily.h for sprintf() */ +#include <standard.h> +#include <schily.h> + +#include <usal/scsireg.h> +#include <usal/scsidefs.h> +#include <usal/usalcmd.h> /*XXX JS wird eigentlich nicht benoetigt!! */ + /*XXX JS kommt weg, wenn struct sense und status */ + /*XXX JS von usalio.h nach scsireg.h kommen */ +#include <usal/scsitransp.h> + +#define CTYPE_CCS 0 +#define CTYPE_MD21 1 +#define CTYPE_ACB4000 2 +#define CTYPE_SMO_C501 3 + +#define SMO_C501 + +const char *usal_sensemsg(int, int, int, const char **, char *, int maxcnt); +int usal__errmsg(SCSI *usalp, char *obuf, int maxcnt, struct scsi_sense *, + struct scsi_status *, int); +#if 0 +/* + * Map old non extended sense to sense key. + */ +static Uchar sd_adaptec_keys[] = { + 0, 4, 4, 4, 2, 2, 4, 4, /* 0x00-0x07 */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 0x08-0x0f */ + 4, 3, 3, 3, 3, 4, 3, 1, /* 0x10-0x17 */ + 1, 1, 3, 4, 3, 4, 3, 3, /* 0x18-0x1f */ + 5, 5, 5, 5, 5, 5, 5, 7, /* 0x20-0x27 */ + 6, 6, 6, 5, 4,11,11,11 /* 0x28-0x2f */ +}; +#define MAX_ADAPTEC_KEYS (sizeof (sd_adaptec_keys)) +#endif + +/* + * Deviations to CCS found on old pre CCS devices + */ +static const char *sd_adaptec_error_str[] = { + "\031\000ECC error during verify", /* 0x19 */ + "\032\000interleave error", /* 0x1a */ + "\034\000bad format on drive", /* 0x1c */ + "\035\000self test failed", /* 0x1d */ + "\036\000defective track", /* 0x1e */ + "\043\000volume overflow", /* 0x23 */ + "\053\000set limit violation", /* 0x2b */ + "\054\000error counter overflow", /* 0x2c */ + "\055\000initiator detected error", /* 0x2d */ + "\056\000scsi parity error", /* 0x2e */ + "\057\000adapter parity error", /* 0x2f */ + NULL +}; + +/* + * The sense codes of SCSI-1/CCS, SCSI-2 and SCSI-3 devices. + */ +static const char *sd_ccs_error_str[] = { + "\000\000no additional sense information", /* 00 00 */ + "\000\001filemark detected", /* 00 01 */ + "\000\002end-of-partition/medium detected", /* 00 02 */ + "\000\003setmark detected", /* 00 03 */ + "\000\004beginning-of-partition/medium detected", /* 00 04 */ + "\000\005end-of-data detected", /* 00 05 */ + "\000\006i/o process terminated", /* 00 06 */ + "\000\021audio play operation in progress", /* 00 11 */ + "\000\022audio play operation paused", /* 00 12 */ + "\000\023audio play operation successfully completed", /* 00 13 */ + "\000\024audio play operation stopped due to error", /* 00 14 */ + "\000\025no current audio status to return", /* 00 15 */ + "\000\026operation in progress", /* 00 16 */ + "\000\027cleaning requested", /* 00 17 */ + "\001\000no index/sector signal", /* 01 00 */ + "\002\000no seek complete", /* 02 00 */ + "\003\000peripheral device write fault", /* 03 00 */ + "\003\001no write current", /* 03 01 */ + "\003\002excessive write errors", /* 03 02 */ + "\004\000logical unit not ready, cause not reportable", /* 04 00 */ + "\004\001logical unit is in process of becoming ready", /* 04 01 */ + "\004\002logical unit not ready, initializing cmd. required", /* 04 02 */ + "\004\003logical unit not ready, manual intervention required", /* 04 03 */ + "\004\004logical unit not ready, format in progress", /* 04 04 */ + "\004\005logical unit not ready, rebuild in progress", /* 04 05 */ + "\004\006logical unit not ready, recalculation in progress", /* 04 06 */ + "\004\007logical unit not ready, operation in progress",/* 04 07 */ + "\004\010logical unit not ready, long write in progress", /* 04 08 */ + "\004\011logical unit not ready, self-test in progress",/* 04 09 */ + "\004\012asymmetric access code 3 (00-232) [proposed]", /* 04 0A */ + "\004\013asymmetric access code 1 (00-232) [proposed]", /* 04 0B */ + "\004\014asymmetric access code 2 (00-232) [proposed]", /* 04 0C */ + "\004\020auxiliary memory code 2 (99-148) [proposed]", /* 04 10 */ + "\005\000logical unit does not respond to selection", /* 05 00 */ + "\006\000no reference position found", /* 06 00 */ + "\007\000multiple peripheral devices selected", /* 07 00 */ + "\010\000logical unit communication failure", /* 08 00 */ + "\010\001logical unit communication time-out", /* 08 01 */ + "\010\002logical unit communication parity error", /* 08 02 */ + "\010\003logical unit communication crc error (ultra-dma/32)", /* 08 03 */ + "\010\004unreachable copy target", /* 08 04 */ + "\011\000track following error", /* 09 00 */ + "\011\001tracking servo failure", /* 09 01 */ + "\011\002focus servo failure", /* 09 02 */ + "\011\003spindle servo failure", /* 09 03 */ + "\011\004head select fault", /* 09 04 */ + "\012\000error log overflow", /* 0A 00 */ + "\013\000warning", /* 0B 00 */ + "\013\001warning - specified temperature exceeded", /* 0B 01 */ + "\013\002warning - enclosure degraded", /* 0B 02 */ + "\014\000write error", /* 0C 00 */ + "\014\001write error - recovered with auto reallocation", /* 0C 01 */ + "\014\002write error - auto reallocation failed", /* 0C 02 */ + "\014\003write error - recommend reassignment", /* 0C 03 */ + "\014\004compression check miscompare error", /* 0C 04 */ + "\014\005data expansion occurred during compression", /* 0C 05 */ + "\014\006block not compressible", /* 0C 06 */ + "\014\007write error - recovery needed", /* 0C 07 */ + "\014\010write error - recovery failed", /* 0C 08 */ + "\014\011write error - loss of streaming", /* 0C 09 */ + "\014\012write error - padding blocks added", /* 0C 0A */ + "\014\013auxiliary memory code 4 (99-148) [proposed]", /* 0C 0B */ + "\015\000error detected by third party temporary initiator", /* 0D 00 */ + "\015\001third party device failure", /* 0D 01 */ + "\015\002copy target device not reachable", /* 0D 02 */ + "\015\003incorrect copy target device type", /* 0D 03 */ + "\015\004copy target device data underrun", /* 0D 04 */ + "\015\005copy target device data overrun", /* 0D 05 */ +#ifdef __used__ + "\016\000", /* 0E 00 */ + "\017\000", /* 0F 00 */ +#endif + "\020\000id crc or ecc error", /* 10 00 */ + "\021\000unrecovered read error", /* 11 00 */ + "\021\001read retries exhausted", /* 11 01 */ + "\021\002error too long to correct", /* 11 02 */ + "\021\003multiple read errors", /* 11 03 */ + "\021\004unrecovered read error - auto reallocate failed", /* 11 04 */ + "\021\005l-ec uncorrectable error", /* 11 05 */ + "\021\006circ unrecovered error", /* 11 06 */ + "\021\007data re-synchronization error", /* 11 07 */ + "\021\010incomplete block read", /* 11 08 */ + "\021\011no gap found", /* 11 09 */ + "\021\012miscorrected error", /* 11 0A */ + "\021\013unrecovered read error - recommend reassignment", /* 11 0B */ + "\021\014unrecovered read error - recommend rewrite the data", /* 11 0C */ + "\021\015de-compression crc error", /* 11 0D */ + "\021\016cannot decompress using declared algorithm", /* 11 0E */ + "\021\017error reading upc/ean number", /* 11 0F */ + "\021\020error reading isrc number", /* 11 10 */ + "\021\021read error - loss of streaming", /* 11 11 */ + "\021\022auxiliary memory code 3 (99-148) [proposed]", /* 11 12 */ + "\022\000address mark not found for id field", /* 12 00 */ + "\023\000address mark not found for data field", /* 13 00 */ + "\024\000recorded entity not found", /* 14 00 */ + "\024\001record not found", /* 14 01 */ + "\024\002filemark or setmark not found", /* 14 02 */ + "\024\003end-of-data not found", /* 14 03 */ + "\024\004block sequence error", /* 14 04 */ + "\024\005record not found - recommend reassignment", /* 14 05 */ + "\024\006record not found - data auto-reallocated", /* 14 06 */ + "\025\000random positioning error", /* 15 00 */ + "\025\001mechanical positioning error", /* 15 01 */ + "\025\002positioning error detected by read of medium", /* 15 02 */ + "\026\000data synchronization mark error", /* 16 00 */ + "\026\001data sync error - data rewritten", /* 16 01 */ + "\026\002data sync error - recommend rewrite", /* 16 02 */ + "\026\003data sync error - data auto-reallocated", /* 16 03 */ + "\026\004data sync error - recommend reassignment", /* 16 04 */ + "\027\000recovered data with no error correction applied", /* 17 00 */ + "\027\001recovered data with retries", /* 17 01 */ + "\027\002recovered data with positive head offset", /* 17 02 */ + "\027\003recovered data with negative head offset", /* 17 03 */ + "\027\004recovered data with retries and/or circ applied", /* 17 04 */ + "\027\005recovered data using previous sector id", /* 17 05 */ + "\027\006recovered data without ecc - data auto-reallocated", /* 17 06 */ + "\027\007recovered data without ecc - recommend reassignment", /* 17 07 */ + "\027\010recovered data without ecc - recommend rewrite", /* 17 08 */ + "\027\011recovered data without ecc - data rewritten", /* 17 09 */ + "\030\000recovered data with error correction applied", /* 18 00 */ + "\030\001recovered data with error corr. & retries applied", /* 18 01 */ + "\030\002recovered data - data auto-reallocated", /* 18 02 */ + "\030\003recovered data with circ", /* 18 03 */ + "\030\004recovered data with l-ec", /* 18 04 */ + "\030\005recovered data - recommend reassignment", /* 18 05 */ + "\030\006recovered data - recommend rewrite", /* 18 06 */ + "\030\007recovered data with ecc - data rewritten", /* 18 07 */ + "\030\010recovered data with linking", /* 18 08 */ + "\031\000defect list error", /* 19 00 */ + "\031\001defect list not available", /* 19 01 */ + "\031\002defect list error in primary list", /* 19 02 */ + "\031\003defect list error in grown list", /* 19 03 */ + "\032\000parameter list length error", /* 1A 00 */ + "\033\000synchronous data transfer error", /* 1B 00 */ + "\034\000defect list not found", /* 1C 00 */ + "\034\001primary defect list not found", /* 1C 01 */ + "\034\002grown defect list not found", /* 1C 02 */ + "\035\000miscompare during verify operation", /* 1D 00 */ + "\036\000recovered id with ecc correction", /* 1E 00 */ + "\037\000partial defect list transfer", /* 1F 00 */ + "\040\000invalid command operation code", /* 20 00 */ + "\040\001access controls code 1 (99-314) [proposed]", /* 20 01 */ + "\040\002access controls code 2 (99-314) [proposed]", /* 20 02 */ + "\040\003access controls code 3 (99-314) [proposed]", /* 20 03 */ + "\040\004read type operation while in write capable state", /* 20 04 */ + "\040\005write type operation while in read capable state", /* 20 05 */ + "\040\006illegal command while in explicit address model", /* 20 06 */ + "\040\007illegal command while in implicit address model", /* 20 07 */ + "\040\010access controls code 5 (99-245) [proposed]", /* 20 08 */ + "\040\011access controls code 6 (99-245) [proposed]", /* 20 09 */ + "\040\012access controls code 7 (99-245) [proposed]", /* 20 0A */ + "\040\013access controls code 8 (99-245) [proposed]", /* 20 0B */ + "\041\000logical block address out of range", /* 21 00 */ + "\041\001invalid element address", /* 21 01 */ + "\041\002invalid address for write", /* 21 02 */ + "\042\000illegal function (use 20 00, 24 00, or 26 00)",/* 22 00 */ +#ifdef __used__ + "\043\000", /* 23 00 */ +#endif + "\044\000invalid field in cdb", /* 24 00 */ + "\044\001cdb decryption error", /* 24 01 */ + "\044\002invalid cdb field while in explicit block address model", /* 24 02 */ + "\044\003invalid cdb field while in implicit block address model", /* 24 03 */ + "\045\000logical unit not supported", /* 25 00 */ + "\046\000invalid field in parameter list", /* 26 00 */ + "\046\001parameter not supported", /* 26 01 */ + "\046\002parameter value invalid", /* 26 02 */ + "\046\003threshold parameters not supported", /* 26 03 */ + "\046\004invalid release of persistent reservation", /* 26 04 */ + "\046\005data decryption error", /* 26 05 */ + "\046\006too many target descriptors", /* 26 06 */ + "\046\007unsupported target descriptor type code", /* 26 07 */ + "\046\010too many segment descriptors", /* 26 08 */ + "\046\011unsupported segment descriptor type code", /* 26 09 */ + "\046\012unexpected inexact segment", /* 26 0A */ + "\046\013inline data length exceeded", /* 26 0B */ + "\046\014invalid operation for copy source or destination", /* 26 0C */ + "\046\015copy segment granularity violation", /* 26 0D */ + "\047\000write protected", /* 27 00 */ + "\047\001hardware write protected", /* 27 01 */ + "\047\002logical unit software write protected", /* 27 02 */ + "\047\003associated write protect", /* 27 03 */ + "\047\004persistent write protect", /* 27 04 */ + "\047\005permanent write protect", /* 27 05 */ + "\047\006conditional write protect", /* 27 06 */ + "\050\000not ready to ready change, medium may have changed", /* 28 00 */ + "\050\001import or export element accessed", /* 28 01 */ + "\051\000power on, reset, or bus device reset occurred",/* 29 00 */ + "\051\001power on occurred", /* 29 01 */ + "\051\002scsi bus reset occurred", /* 29 02 */ + "\051\003bus device reset function occurred", /* 29 03 */ + "\051\004device internal reset", /* 29 04 */ + "\051\005transceiver mode changed to single-ended", /* 29 05 */ + "\051\006transceiver mode changed to lvd", /* 29 06 */ + "\052\000parameters changed", /* 2A 00 */ + "\052\001mode parameters changed", /* 2A 01 */ + "\052\002log parameters changed", /* 2A 02 */ + "\052\003reservations preempted", /* 2A 03 */ + "\052\004reservations released", /* 2A 04 */ + "\052\005registrations preempted", /* 2A 05 */ + "\052\006asymmetric access code 6 (00-232) [proposed]", /* 2A 06 */ + "\052\007asymmetric access code 7 (00-232) [proposed]", /* 2A 07 */ + "\053\000copy cannot execute since host cannot disconnect", /* 2B 00 */ + "\054\000command sequence error", /* 2C 00 */ + "\054\001too many windows specified", /* 2C 01 */ + "\054\002invalid combination of windows specified", /* 2C 02 */ + "\054\003current program area is not empty", /* 2C 03 */ + "\054\004current program area is empty", /* 2C 04 */ + "\054\005illegal power condition request", /* 2C 05 */ + "\054\006persistent prevent conflict", /* 2C 06 */ + "\055\000overwrite error on update in place", /* 2D 00 */ + "\056\000insufficient time for operation", /* 2E 00 */ + "\057\000commands cleared by another initiator", /* 2F 00 */ + "\060\000incompatible medium installed", /* 30 00 */ + "\060\001cannot read medium - unknown format", /* 30 01 */ + "\060\002cannot read medium - incompatible format", /* 30 02 */ + "\060\003cleaning cartridge installed", /* 30 03 */ + "\060\004cannot write medium - unknown format", /* 30 04 */ + "\060\005cannot write medium - incompatible format", /* 30 05 */ + "\060\006cannot format medium - incompatible medium", /* 30 06 */ + "\060\007cleaning failure", /* 30 07 */ + "\060\010cannot write - application code mismatch", /* 30 08 */ + "\060\011current session not fixated for append", /* 30 09 */ + "\060\020medium not formatted", /* 30 10 */ + "\061\000medium format corrupted", /* 31 00 */ + "\061\001format command failed", /* 31 01 */ + "\061\002zoned formatting failed due to spare linking", /* 31 02 */ + "\062\000no defect spare location available", /* 32 00 */ + "\062\001defect list update failure", /* 32 01 */ + "\063\000tape length error", /* 33 00 */ + "\064\000enclosure failure", /* 34 00 */ + "\065\000enclosure services failure", /* 35 00 */ + "\065\001unsupported enclosure function", /* 35 01 */ + "\065\002enclosure services unavailable", /* 35 02 */ + "\065\003enclosure services transfer failure", /* 35 03 */ + "\065\004enclosure services transfer refused", /* 35 04 */ + "\066\000ribbon, ink, or toner failure", /* 36 00 */ + "\067\000rounded parameter", /* 37 00 */ + "\070\000event status notification", /* 38 00 */ + "\070\002esn - power management class event", /* 38 02 */ + "\070\004esn - media class event", /* 38 04 */ + "\070\006esn - device busy class event", /* 38 06 */ + "\071\000saving parameters not supported", /* 39 00 */ + "\072\000medium not present", /* 3A 00 */ + "\072\001medium not present - tray closed", /* 3A 01 */ + "\072\002medium not present - tray open", /* 3A 02 */ + "\072\003medium not present - loadable", /* 3A 03 */ + "\072\004medium not present - medium auxiliary memory accessible", /* 3A 04 */ + "\073\000sequential positioning error", /* 3B 00 */ + "\073\001tape position error at beginning-of-medium", /* 3B 01 */ + "\073\002tape position error at end-of-medium", /* 3B 02 */ + "\073\003tape or electronic vertical forms unit not ready", /* 3B 03 */ + "\073\004slew failure", /* 3B 04 */ + "\073\005paper jam", /* 3B 05 */ + "\073\006failed to sense top-of-form", /* 3B 06 */ + "\073\007failed to sense bottom-of-form", /* 3B 07 */ + "\073\010reposition error", /* 3B 08 */ + "\073\011read past end of medium", /* 3B 09 */ + "\073\012read past beginning of medium", /* 3B 0A */ + "\073\013position past end of medium", /* 3B 0B */ + "\073\014position past beginning of medium", /* 3B 0C */ + "\073\015medium destination element full", /* 3B 0D */ + "\073\016medium source element empty", /* 3B 0E */ + "\073\017end of medium reached", /* 3B 0F */ + "\073\021medium magazine not accessible", /* 3B 11 */ + "\073\022medium magazine removed", /* 3B 12 */ + "\073\023medium magazine inserted", /* 3B 13 */ + "\073\024medium magazine locked", /* 3B 14 */ + "\073\025medium magazine unlocked", /* 3B 15 */ + "\073\026mechanical positioning or changer error", /* 3B 16 */ +#ifdef __used__ + "\074\000", /* 3C 00 */ +#endif + "\075\000invalid bits in identify message", /* 3D 00 */ + "\076\000logical unit has not self-configured yet", /* 3E 00 */ + "\076\001logical unit failure", /* 3E 01 */ + "\076\002timeout on logical unit", /* 3E 02 */ + "\076\003logical unit failed self-test", /* 3E 03 */ + "\076\004logical unit unable to update self-test log", /* 3E 04 */ + "\077\000target operating conditions have changed", /* 3F 00 */ + "\077\001microcode has been changed", /* 3F 01 */ + "\077\002changed operating definition", /* 3F 02 */ + "\077\003inquiry data has changed", /* 3F 03 */ + "\077\004component device attached", /* 3F 04 */ + "\077\005device identifier changed", /* 3F 05 */ + "\077\006redundancy group created or modified", /* 3F 06 */ + "\077\007redundancy group deleted", /* 3F 07 */ + "\077\010spare created or modified", /* 3F 08 */ + "\077\011spare deleted", /* 3F 09 */ + "\077\012volume set created or modified", /* 3F 0A */ + "\077\013volume set deleted", /* 3F 0B */ + "\077\014volume set deassigned", /* 3F 0C */ + "\077\015volume set reassigned", /* 3F 0D */ + "\077\016reported luns data has changed", /* 3F 0E */ + "\077\017echo buffer overwritten", /* 3F 0F */ + "\077\020medium loadable", /* 3F 10 */ + "\077\021medium auxiliary memory accessible", /* 3F 11 */ + "\100\000ram failure (should use 40 nn)", /* 40 00 */ +#ifdef XXX + "\100\000nn diagnostic failure on component nn (80h-ffh)", /* 40 00 */ +#endif + "\100\000diagnostic failure on component nn (80h-ffh)", /* 40 00 */ + "\101\000data path failure (should use 40 nn)", /* 41 00 */ + "\102\000power-on or self-test failure (should use 40 nn)", /* 42 00 */ + "\103\000message error", /* 43 00 */ + "\104\000internal target failure", /* 44 00 */ + "\105\000select or reselect failure", /* 45 00 */ + "\106\000unsuccessful soft reset", /* 46 00 */ + "\107\000scsi parity error", /* 47 00 */ + "\107\001data phase crc error detected", /* 47 01 */ + "\107\002scsi parity error detected during st data phase", /* 47 02 */ + "\107\003information unit crc error detected", /* 47 03 */ + "\107\004asynchronous information protection error detected", /* 47 04 */ + "\110\000initiator detected error message received", /* 48 00 */ + "\111\000invalid message error", /* 49 00 */ + "\112\000command phase error", /* 4A 00 */ + "\113\000data phase error", /* 4B 00 */ + "\114\000logical unit failed self-configuration", /* 4C 00 */ +#ifdef XXX + "\115\000nn tagged overlapped commands (nn = queue tag)", /* 4D 00 */ +#endif + "\115\000tagged overlapped commands (nn = queue tag)", /* 4D 00 */ + "\116\000overlapped commands attempted", /* 4E 00 */ +#ifdef __used__ + "\117\000", /* 4F 00 */ +#endif + "\120\000write append error", /* 50 00 */ + "\120\001write append position error", /* 50 01 */ + "\120\002position error related to timing", /* 50 02 */ + "\121\000erase failure", /* 51 00 */ + "\121\001erase failure - incomplete erase operation detected", /* 51 01 */ + "\122\000cartridge fault", /* 52 00 */ + "\123\000media load or eject failed", /* 53 00 */ + "\123\001unload tape failure", /* 53 01 */ + "\123\002medium removal prevented", /* 53 02 */ + "\124\000scsi to host system interface failure", /* 54 00 */ + "\125\000system resource failure", /* 55 00 */ + "\125\001system buffer full", /* 55 01 */ + "\125\002insufficient reservation resources", /* 55 02 */ + "\125\003insufficient resources", /* 55 03 */ + "\125\004insufficient registration resources", /* 55 04 */ + "\125\005access controls code 4 (99-314) [proposed]", /* 55 05 */ + "\125\006auxiliary memory code 1 (99-148) [proposed]", /* 55 06 */ +#ifdef __used__ + "\126\000", /* 56 00 */ +#endif + "\127\000unable to recover table-of-contents", /* 57 00 */ + "\130\000generation does not exist", /* 58 00 */ + "\131\000updated block read", /* 59 00 */ + "\132\000operator request or state change input", /* 5A 00 */ + "\132\001operator medium removal request", /* 5A 01 */ + "\132\002operator selected write protect", /* 5A 02 */ + "\132\003operator selected write permit", /* 5A 03 */ + "\133\000log exception", /* 5B 00 */ + "\133\001threshold condition met", /* 5B 01 */ + "\133\002log counter at maximum", /* 5B 02 */ + "\133\003log list codes exhausted", /* 5B 03 */ + "\134\000rpl status change", /* 5C 00 */ + "\134\001spindles synchronized", /* 5C 01 */ + "\134\002spindles not synchronized", /* 5C 02 */ + "\135\000failure prediction threshold exceeded", /* 5D 00 */ + "\135\001media failure prediction threshold exceeded", /* 5D 01 */ + "\135\002logical unit failure prediction threshold exceeded", /* 5D 02 */ + "\135\003spare area exhaustion prediction threshold exceeded", /* 5D 03 */ + "\135\020hardware impending failure general hard drive failure",/* 5D 10 */ + "\135\021hardware impending failure drive error rate too high", /* 5D 11 */ + "\135\022hardware impending failure data error rate too high", /* 5D 12 */ + "\135\023hardware impending failure seek error rate too high", /* 5D 13 */ + "\135\024hardware impending failure too many block reassigns", /* 5D 14 */ + "\135\025hardware impending failure access times too high", /* 5D 15 */ + "\135\026hardware impending failure start unit times too high", /* 5D 16 */ + "\135\027hardware impending failure channel parametrics",/* 5D 17 */ + "\135\030hardware impending failure controller detected",/* 5D 18 */ + "\135\031hardware impending failure throughput performance", /* 5D 19 */ + "\135\032hardware impending failure seek time performance", /* 5D 1A */ + "\135\033hardware impending failure spin-up retry count", /* 5D 1B */ + "\135\034hardware impending failure drive calibration retry count", /* 5D 1C */ + "\135\040controller impending failure general hard drive failure", /* 5D 20 */ + "\135\041controller impending failure drive error rate too high", /* 5D 21 */ + "\135\042controller impending failure data error rate too high",/* 5D 22 */ + "\135\043controller impending failure seek error rate too high",/* 5D 23 */ + "\135\044controller impending failure too many block reassigns",/* 5D 24 */ + "\135\045controller impending failure access times too high", /* 5D 25 */ + "\135\046controller impending failure start unit times too high", /* 5D 26 */ + "\135\047controller impending failure channel parametrics", /* 5D 27 */ + "\135\050controller impending failure controller detected", /* 5D 28 */ + "\135\051controller impending failure throughput performance", /* 5D 29 */ + "\135\052controller impending failure seek time performance", /* 5D 2A */ + "\135\053controller impending failure spin-up retry count", /* 5D 2B */ + "\135\054controller impending failure drive calibration retry count", /* 5D 2C */ + "\135\060data channel impending failure general hard drive failure", /* 5D 30 */ + "\135\061data channel impending failure drive error rate too high", /* 5D 31 */ + "\135\062data channel impending failure data error rate too high", /* 5D 32 */ + "\135\063data channel impending failure seek error rate too high", /* 5D 33 */ + "\135\064data channel impending failure too many block reassigns", /* 5D 34 */ + "\135\065data channel impending failure access times too high", /* 5D 35 */ + "\135\066data channel impending failure start unit times too high", /* 5D 36 */ + "\135\067data channel impending failure channel parametrics", /* 5D 37 */ + "\135\070data channel impending failure controller detected", /* 5D 38 */ + "\135\071data channel impending failure throughput performance",/* 5D 39 */ + "\135\072data channel impending failure seek time performance", /* 5D 3A */ + "\135\073data channel impending failure spin-up retry count", /* 5D 3B */ + "\135\074data channel impending failure drive calibration retry count", /* 5D 3C */ + "\135\100servo impending failure general hard drive failure", /* 5D 40 */ + "\135\101servo impending failure drive error rate too high", /* 5D 41 */ + "\135\102servo impending failure data error rate too high", /* 5D 42 */ + "\135\103servo impending failure seek error rate too high", /* 5D 43 */ + "\135\104servo impending failure too many block reassigns", /* 5D 44 */ + "\135\105servo impending failure access times too high",/* 5D 45 */ + "\135\106servo impending failure start unit times too high", /* 5D 46 */ + "\135\107servo impending failure channel parametrics", /* 5D 47 */ + "\135\110servo impending failure controller detected", /* 5D 48 */ + "\135\111servo impending failure throughput performance", /* 5D 49 */ + "\135\112servo impending failure seek time performance",/* 5D 4A */ + "\135\113servo impending failure spin-up retry count", /* 5D 4B */ + "\135\114servo impending failure drive calibration retry count",/* 5D 4C */ + "\135\120spindle impending failure general hard drive failure", /* 5D 50 */ + "\135\121spindle impending failure drive error rate too high", /* 5D 51 */ + "\135\122spindle impending failure data error rate too high", /* 5D 52 */ + "\135\123spindle impending failure seek error rate too high", /* 5D 53 */ + "\135\124spindle impending failure too many block reassigns", /* 5D 54 */ + "\135\125spindle impending failure access times too high", /* 5D 55 */ + "\135\126spindle impending failure start unit times too high", /* 5D 56 */ + "\135\127spindle impending failure channel parametrics",/* 5D 57 */ + "\135\130spindle impending failure controller detected",/* 5D 58 */ + "\135\131spindle impending failure throughput performance", /* 5D 59 */ + "\135\132spindle impending failure seek time performance", /* 5D 5A */ + "\135\133spindle impending failure spin-up retry count",/* 5D 5B */ + "\135\134spindle impending failure drive calibration retry count", /* 5D 5C */ + "\135\140firmware impending failure general hard drive failure",/* 5D 60 */ + "\135\141firmware impending failure drive error rate too high", /* 5D 61 */ + "\135\142firmware impending failure data error rate too high", /* 5D 62 */ + "\135\143firmware impending failure seek error rate too high", /* 5D 63 */ + "\135\144firmware impending failure too many block reassigns", /* 5D 64 */ + "\135\145firmware impending failure access times too high", /* 5D 65 */ + "\135\146firmware impending failure start unit times too high", /* 5D 66 */ + "\135\147firmware impending failure channel parametrics", /* 5D 67 */ + "\135\150firmware impending failure controller detected", /* 5D 68 */ + "\135\151firmware impending failure throughput performance", /* 5D 69 */ + "\135\152firmware impending failure seek time performance", /* 5D 6A */ + "\135\153firmware impending failure spin-up retry count", /* 5D 6B */ + "\135\154firmware impending failure drive calibration retry count", /* 5D 6C */ + "\135\377failure prediction threshold exceeded (false)",/* 5D FF */ + "\136\000low power condition on", /* 5E 00 */ + "\136\001idle condition activated by timer", /* 5E 01 */ + "\136\002standby condition activated by timer", /* 5E 02 */ + "\136\003idle condition activated by command", /* 5E 03 */ + "\136\004standby condition activated by command", /* 5E 04 */ + "\136\101power state change to active", /* 5E 41 */ + "\136\102power state change to idle", /* 5E 42 */ + "\136\103power state change to standby", /* 5E 43 */ + "\136\105power state change to sleep", /* 5E 45 */ + "\136\107power state change to device control", /* 5E 47 */ +#ifdef __used__ + "\137\000", /* 5F 00 */ +#endif + "\140\000lamp failure", /* 60 00 */ + "\141\000video acquisition error", /* 61 00 */ + "\141\001unable to acquire video", /* 61 01 */ + "\141\002out of focus", /* 61 02 */ + "\142\000scan head positioning error", /* 62 00 */ + "\143\000end of user area encountered on this track", /* 63 00 */ + "\143\001packet does not fit in available space", /* 63 01 */ + "\144\000illegal mode for this track", /* 64 00 */ + "\144\001invalid packet size", /* 64 01 */ + "\145\000voltage fault", /* 65 00 */ + "\146\000automatic document feeder cover up", /* 66 00 */ + "\146\001automatic document feeder lift up", /* 66 01 */ + "\146\002document jam in automatic document feeder", /* 66 02 */ + "\146\003document miss feed automatic in document feeder", /* 66 03 */ + "\147\000configuration failure", /* 67 00 */ + "\147\001configuration of incapable logical units failed", /* 67 01 */ + "\147\002add logical unit failed", /* 67 02 */ + "\147\003modification of logical unit failed", /* 67 03 */ + "\147\004exchange of logical unit failed", /* 67 04 */ + "\147\005remove of logical unit failed", /* 67 05 */ + "\147\006attachment of logical unit failed", /* 67 06 */ + "\147\007creation of logical unit failed", /* 67 07 */ + "\147\010assign failure occurred", /* 67 08 */ + "\147\011multiply assigned logical unit", /* 67 09 */ + "\147\012asymmetric access code 4 (00-232) [proposed]", /* 67 0A */ + "\147\013asymmetric access code 5 (00-232) [proposed]", /* 67 0B */ + "\150\000logical unit not configured", /* 68 00 */ + "\151\000data loss on logical unit", /* 69 00 */ + "\151\001multiple logical unit failures", /* 69 01 */ + "\151\002parity/data mismatch", /* 69 02 */ + "\152\000informational, refer to log", /* 6A 00 */ + "\153\000state change has occurred", /* 6B 00 */ + "\153\001redundancy level got better", /* 6B 01 */ + "\153\002redundancy level got worse", /* 6B 02 */ + "\154\000rebuild failure occurred", /* 6C 00 */ + "\155\000recalculate failure occurred", /* 6D 00 */ + "\156\000command to logical unit failed", /* 6E 00 */ + "\157\000copy protection key exchange failure - authentication failure",/* 6F 00 */ + "\157\001copy protection key exchange failure - key not present", /* 6F 01 */ + "\157\002copy protection key exchange failure - key not established", /* 6F 02 */ + "\157\003read of scrambled sector without authentication", /* 6F 03 */ + "\157\004media region code is mismatched to logical unit region", /* 6F 04 */ + "\157\005drive region must be permanent/region reset count error", /* 6F 05 */ +#ifdef XXX + "\160\000nn decompression exception short algorithm id of nn", /* 70 00 */ +#endif + "\160\000decompression exception short algorithm id of nn", /* 70 00 */ + "\161\000decompression exception long algorithm id", /* 71 00 */ + "\162\000session fixation error", /* 72 00 */ + "\162\001session fixation error writing lead-in", /* 72 01 */ + "\162\002session fixation error writing lead-out", /* 72 02 */ + "\162\003session fixation error - incomplete track in session", /* 72 03 */ + "\162\004empty or partially written reserved track", /* 72 04 */ + "\162\005no more track reservations allowed", /* 72 05 */ + "\163\000cd control error", /* 73 00 */ + "\163\001power calibration area almost full", /* 73 01 */ + "\163\002power calibration area is full", /* 73 02 */ + "\163\003power calibration area error", /* 73 03 */ + "\163\004program memory area update failure", /* 73 04 */ + "\163\005program memory area is full", /* 73 05 */ + "\163\006rma/pma is almost full", /* 73 06 */ +#ifdef __used__ + "\164\000", /* 74 00 */ + "\165\000", /* 75 00 */ + "\166\000", /* 76 00 */ + "\167\000", /* 77 00 */ + "\170\000", /* 78 00 */ + "\171\000", /* 79 00 */ + "\172\000", /* 7A 00 */ + "\173\000", /* 7B 00 */ + "\174\000", /* 7C 00 */ + "\175\000", /* 7D 00 */ + "\176\000", /* 7E 00 */ + "\177\000", /* 7F 00 */ +#endif +#ifdef XXX + "\200\000start vendor unique", /* 80 00 */ +#endif + NULL +}; + +#ifdef SMO_C501 +static const char *sd_smo_c501_error_str[] = { + "\012\000disk not inserted", /* 0x0a */ + "\013\000load/unload failure", /* 0x0b */ + "\014\000spindle failure", /* 0x0c */ + "\015\000focus failure", /* 0x0d */ + "\016\000tracking failure", /* 0x0e */ + "\017\000bias magnet failure", /* 0x0f */ + "\043\000illegal function for medium type", /* 0x23 */ +/*XXX*/ "\070\000recoverable write error", /* 0x38 */ +/*XXX*/ "\071\000write error recovery failed", /* 0x39 */ + "\072\000defect list update failed", /* 0x3a */ + "\075\000defect list not available", /* 0x3d */ + "\200\000limited laser life", /* 0x80 */ + "\201\000laser focus coil over-current", /* 0x81 */ + "\202\000laser tracking coil over-current", /* 0x82 */ + "\203\000temperature alarm", /* 0x83 */ + NULL +}; +#endif + +static char *sd_sense_keys[] = { + "No Additional Sense", /* 0x00 */ + "Recovered Error", /* 0x01 */ + "Not Ready", /* 0x02 */ + "Medium Error", /* 0x03 */ + "Hardware Error", /* 0x04 */ + "Illegal Request", /* 0x05 */ + "Unit Attention", /* 0x06 */ + "Data Protect", /* 0x07 */ + "Blank Check", /* 0x08 */ + "Vendor Unique", /* 0x09 */ + "Copy Aborted", /* 0x0a */ + "Aborted Command", /* 0x0b */ + "Equal", /* 0x0c */ + "Volume Overflow", /* 0x0d */ + "Miscompare", /* 0x0e */ + "Reserved" /* 0x0f */ +}; + +#if 0 +static char *sd_cmds[] = { + "\000test unit ready", /* 0x00 */ + "\001rezero", /* 0x01 */ + "\003request sense", /* 0x03 */ + "\004format", /* 0x04 */ + "\007reassign", /* 0x07 */ + "\010read", /* 0x08 */ + "\012write", /* 0x0a */ + "\013seek", /* 0x0b */ + "\022inquiry", /* 0x12 */ + "\025mode select", /* 0x15 */ + "\026reserve", /* 0x16 */ + "\027release", /* 0x17 */ + "\030copy", /* 0x18 */ + "\032mode sense", /* 0x1a */ + "\033start/stop", /* 0x1b */ + "\036door lock", /* 0x1e */ + "\067read defect data", /* 0x37 */ + NULL +}; +#endif + + +const char * +usal_sensemsg(register int ctype, register int code, register int qual, + register const char **vec, char *sbuf, int maxcnt) +{ + register int i; + + /* + * Ignore controller type if error vec is supplied. + */ + if (vec == (const char **)NULL) switch (ctype) { + case DEV_MD21: + vec = sd_ccs_error_str; + break; + + case DEV_ACB40X0: + case DEV_ACB4000: + case DEV_ACB4010: + case DEV_ACB4070: + case DEV_ACB5500: + vec = sd_adaptec_error_str; + break; + +#ifdef SMO_C501 + case DEV_SONY_SMO: + vec = sd_smo_c501_error_str; + break; +#endif + + default: + vec = sd_ccs_error_str; + } + if (vec == (const char **)NULL) + return (""); + + for (i = 0; i < 2; i++) { + while (*vec != (char *) NULL) { + if (code == (Uchar)(*vec)[0] && + qual == (Uchar)(*vec)[1]) { + return (&(*vec)[2]); + } else { + vec++; /* Next entry */ + } + } + if (*vec == (char *) NULL) /* End of List: switch over */ + vec = sd_ccs_error_str; + } + if (code == 0x40) { + snprintf(sbuf, maxcnt, + "diagnostic failure on component 0x%X", qual); + return (sbuf); + } + if (code == 0x4D) { + snprintf(sbuf, maxcnt, + "tagged overlapped commands, queue tag is 0x%X", + qual); + return (sbuf); + } + if (code == 0x70) { + snprintf(sbuf, maxcnt, + "decompression exception short algorithm id of 0x%X", + qual); + return (sbuf); + } + if (qual != 0) + return ((char *)NULL); + + if (code < 0x80) { + snprintf(sbuf, maxcnt, "invalid sense code 0x%X", code); + return (sbuf); + } + snprintf(sbuf, maxcnt, "vendor unique sense code 0x%X", code); + return (sbuf); +} + +#undef sense /*XXX JS Hack, solange usalio.h noch nicht fertig ist */ +int +usal__errmsg(SCSI *usalp, char *obuf, int maxcnt, + register struct scsi_sense *sense, + register struct scsi_status *status, int sense_code) +{ + char sbuf[80]; + const char *sensemsg, *cmdname, *sensekey; +#define ext_sense ((struct scsi_ext_sense* ) sense) + register int blkno = 0; + register int code; + int badqual = 0; + int qual = 0; + int fru = 0; + int key = 0; + int segment = 0; + int blkvalid = 0; + int fm = 0; + int eom = 0; + int ili = 0; + int sksv = 0; + int n; + int sizeleft = maxcnt; + + sensekey = sensemsg = "[]"; + if (sense->code >= 0x70) { + if (sense_code >= 0) + code = sense_code; + else + code = ext_sense->sense_code; + segment = ext_sense->seg_num; + qual = ext_sense->qual_code; + fru = ext_sense->fru_code; + sksv = ext_sense->sksv; + } else { + code = sense->code; + } + if (status->chk == 0) { + sensemsg = "no sense"; + } else { + if (sense->code >= 0x70) { + key = ext_sense->key; + if (key < 0x10) + sensekey = sd_sense_keys[ext_sense->key]; + else + sensekey = "invalid sensekey"; + blkno = (ext_sense->info_1 << 24) | + (ext_sense->info_2 << 16) | + (ext_sense->info_3 << 8) | + ext_sense->info_4; + fm = ext_sense->fil_mk; + eom = ext_sense->eom; + ili = ext_sense->ili; + } else { + key = -1; + sensekey = "[]"; + blkno = (sense->high_addr << 16) | + (sense->mid_addr << 8) | + sense->low_addr; + fm = eom = 0; + } + blkvalid = sense->adr_val; + + sensemsg = usal_sensemsg(usalp->dev, code, qual, usalp->nonstderrs, sbuf, sizeof(sbuf)); + if (sensemsg == NULL) { + sensemsg = usal_sensemsg(usalp->dev, code, 0, usalp->nonstderrs, sbuf, sizeof(sbuf)); + badqual = 1; + } + } +/* + if (un->un_cmd < sizeof(scsi_cmds)) { + cmdname = scsi_cmds[un->un_cmd]; + } else { + cmdname = "unknown cmd"; + } +*/ + cmdname = ""; + n = snprintf(obuf, sizeleft, "%sSense Key: 0x%X %s%s, Segment %d\n", + cmdname, key, sensekey, + (sense->code == 0x71)?", deferred error":"", + segment); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + n = snprintf(obuf, sizeleft, "Sense Code: 0x%02X Qual 0x%02X %s%s%s%s Fru 0x%X\n", + code, qual, *sensemsg?"(":"", sensemsg, *sensemsg?")":"", + badqual? " [No matching qualifier]":"", + fru); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + n = snprintf(obuf, sizeleft, "Sense flags: Blk %d %s%s%s%s", + blkno, blkvalid?"(valid) ":"(not valid) ", + fm?"file mark detected ":"", + eom?"end of medium ":"", + ili?"illegal block length ":""); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + if (!sksv) { + n = snprintf(obuf, sizeleft, "\n"); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + return (maxcnt - sizeleft); + } + switch (key) { + + case SC_ILLEGAL_REQUEST: + n = snprintf(obuf, sizeleft, "error refers to %s part, bit ptr %d %s field ptr %d", + ext_sense->cd? "command":"data", + (int)ext_sense->bptr, + ext_sense->bpv? "(valid)":"(not valid)", + ext_sense->field_ptr[0] << 8 | + ext_sense->field_ptr[1]); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + break; + + case SC_RECOVERABLE_ERROR: + case SC_HARDWARE_ERROR: + case SC_MEDIUM_ERROR: + n = snprintf(obuf, sizeleft, "actual retry count %d", + ext_sense->field_ptr[0] << 8 | + ext_sense->field_ptr[1]); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + break; + + case SC_NOT_READY: + n = snprintf(obuf, sizeleft, "operation %d%% done", + (100*(ext_sense->field_ptr[0] << 8 | + ext_sense->field_ptr[1]))/(unsigned)65536); + if (n < 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + break; + } + n = snprintf(obuf, sizeleft, "\n"); + if (n <= 0) { + obuf[0] = '\0'; + return (maxcnt - sizeleft); + } + obuf += n; + sizeleft -= n; + return (maxcnt - sizeleft); +} + +#ifdef DEBUG +print_err(code, ctype) +{ + register int i; + register char **vec = (char **)NULL; + + switch (ctype) { + case CTYPE_MD21: + case CTYPE_CCS: + vec = sd_ccs_error_str; + break; + + case CTYPE_ACB4000: + vec = sd_adaptec_error_str; + break; + +#ifdef SMO_C501 + case CTYPE_SMO_C501: + vec = sd_smo_c501_error_str; + break; +#endif + +#ifdef CDD_521 + case DEV_CDD_521: + vec = sd_cdd_521_error_str; + break; +#endif + } + printf("error code: 0x%x", code); + if (vec == (char **)NULL) + return; + + for (i = 0; i < 2; i++) { + while (*vec != (char *) NULL) { + if (code == (Uchar)*vec[0]) { + printf(" (%s)", (char *)((int)(*vec)+1)); + return; + } else + vec++; + } + if (*vec == (char *) NULL) + vec = sd_ccs_error_str; + } +} + + +int main(int argc, char *argv[]) +{ + int i; + +#ifdef ACB + for (i = 0; i < 0x30; i++) { +/* printf("Code: 0x%x Key: 0x%x ", i, sd_adaptec_keys[i]);*/ + printf("Key: 0x%x %-16s ", sd_adaptec_keys[i], + sd_sense_keys[sd_adaptec_keys[i]] ); + js_print_err(i, CTYPE_ACB4000); + printf("\n"); + } +#else +/* for (i = 0; i < 0x84; i++) {*/ + for (i = 0; i < 0xd8; i++) { +/* print_err(i, CTYPE_SMO_C501);*/ + print_err(i, DEV_CDD_521); + printf("\n"); + } +#endif +} +#endif diff --git a/libusal/scsihack.c b/libusal/scsihack.c new file mode 100644 index 0000000..5427ad0 --- /dev/null +++ b/libusal/scsihack.c @@ -0,0 +1,483 @@ +/* + * 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. + * + */ + +/* @(#)scsihack.c 1.44 06/01/30 Copyright 1997,2000,2001 J. Schilling */ +/* + * Interface for other generic SCSI implementations. + * Emulate the functionality of /dev/usal? with the local + * SCSI user land implementation. + * + * To add a new hack, add something like: + * + * #ifdef __FreeBSD__ + * #define SCSI_IMPL + * #include some code + * #endif + * + * Warning: you may change this source or add new SCSI tranport + * implementations, but if you do that you need to change the + * _usal_version and _usal_auth* string that are returned by the + * SCSI transport code. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * If your version has been integrated into the main steam release, + * the return value will be set to "schily". + * + * Copyright (c) 1997,2000,2001 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> + +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> /* Include various defs needed with some OS */ +#endif +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <errno.h> +#include <timedefs.h> +#include <sys/ioctl.h> +#include <fctldefs.h> +#include <strdefs.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsitransp.h> +#include "usaltimes.h" + +#ifndef HAVE_ERRNO_DEF +extern int errno; +#endif + +static int usalo_send(SCSI *usalp); +static char *usalo_version(SCSI *usalp, int what); +static int usalo_help(SCSI *usalp, FILE *f); +static int usalo_open(SCSI *usalp, char *device); +static int usalo_close(SCSI *usalp); +static long usalo_maxdma(SCSI *usalp, long amt); +static void *usalo_getbuf(SCSI *usalp, long amt); +static void usalo_freebuf(SCSI *usalp); + +static BOOL usalo_havebus(SCSI *usalp, int busno); +static int usalo_fileno(SCSI *usalp, int busno, int tgt, int tlun); +static char * usalo_natname(SCSI *usalp, int busno, int tgt, int tlun); +static int usalo_initiator_id(SCSI *usalp); +static int usalo_isatapi(SCSI *usalp); +static int usalo_reset(SCSI *usalp, int what); + +static char _usal_auth_cdrkit[] = "cdrkit-team"; /* The author for this module */ + +usal_ops_t usal_std_ops = { + usalo_send, + usalo_version, + usalo_help, + usalo_open, + usalo_close, + usalo_maxdma, + usalo_getbuf, + usalo_freebuf, + usalo_havebus, + usalo_fileno, + usalo_initiator_id, + usalo_isatapi, + usalo_reset, + usalo_natname, +}; + +/*#undef sun*/ +/*#undef __sun*/ +/*#undef __sun__*/ + +#if defined(sun) || defined(__sun) || defined(__sun__) +#define SCSI_IMPL /* We have a SCSI implementation for Sun */ + +#include "scsi-sun.c" + +#endif /* Sun */ + + +#ifdef linux +#define SCSI_IMPL /* We have a SCSI implementation for Linux */ + +#ifdef not_needed /* We now have a local vrersion of pg.h */ +#ifndef HAVE_LINUX_PG_H /* If we are compiling on an old version */ +# undef USE_PG_ONLY /* there is no 'pg' driver and we cannot */ +# undef USE_PG /* include <linux/pg.h> which is needed */ +#endif /* by the pg transport code. */ +#endif + +#ifdef USE_PG_ONLY +#include "scsi-linux-pg.c" +#else +#include "scsi-linux-sg.c" +#endif + +#endif /* linux */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +#define SCSI_IMPL /* We have a SCSI implementation for *BSD */ + +#include "scsi-bsd.c" + +#endif /* *BSD */ + +#if defined(__bsdi__) /* We have a SCSI implementation for BSD/OS 3.x (and later?) */ +# include <sys/param.h> +# if (_BSDI_VERSION >= 199701) +# define SCSI_IMPL + +# include "scsi-bsd-os.c" + +# endif /* BSD/OS >= 3.0 */ +#endif /* BSD/OS */ + +#ifdef __sgi +#define SCSI_IMPL /* We have a SCSI implementation for SGI */ + +#include "scsi-sgi.c" + +#endif /* SGI */ + +#ifdef __hpux +#define SCSI_IMPL /* We have a SCSI implementation for HP-UX */ + +#include "scsi-hpux.c" + +#endif /* HP-UX */ + +#if defined(_IBMR2) || defined(_AIX) +#define SCSI_IMPL /* We have a SCSI implementation for AIX */ + +#include "scsi-aix.c" + +#endif /* AIX */ + +#if defined(__NeXT__) || defined(IS_MACOS_X) +#if defined(HAVE_BSD_DEV_SCSIREG_H) +/* + * This is the + */ +#define SCSI_IMPL /* We found a SCSI implementation for NextStep and Mac OS X */ + +#include "scsi-next.c" +#else + +#define SCSI_IMPL /* We found a SCSI implementation for Mac OS X (Darwin-1.4) */ + +#include "scsi-mac-iokit.c" + +#endif /* HAVE_BSD_DEV_SCSIREG_H */ + +#endif /* NEXT / Mac OS X */ + +#if defined(__osf__) +#define SCSI_IMPL /* We have a SCSI implementation for OSF/1 */ + +#include "scsi-osf.c" + +#endif /* OSF/1 */ + +#ifdef VMS +#define SCSI_IMPL /* We have a SCSI implementation for VMS */ + +#include "scsi-vms.c" + +#endif /* VMS */ + +#ifdef OPENSERVER +#define SCSI_IMPL /* We have a SCSI implementation for SCO OpenServer */ + +#include "scsi-openserver.c" + +#endif /* SCO */ + +#ifdef UNIXWARE +#define SCSI_IMPL /* We have a SCSI implementation for SCO UnixWare */ + +#include "scsi-unixware.c" + +#endif /* UNIXWARE */ + +#ifdef __OS2 +#define SCSI_IMPL /* We have a SCSI implementation for OS/2 */ + +#include "scsi-os2.c" + +#endif /* OS/2 */ + +#ifdef __BEOS__ +#define SCSI_IMPL /* Yep, BeOS does that funky scsi stuff */ +#include "scsi-beos.c" +#endif + +#ifdef __CYGWIN32__ +#define SCSI_IMPL /* Yep, we support WNT and W9? */ +#include "scsi-wnt.c" +#endif + +#ifdef apollo +#define SCSI_IMPL /* We have a SCSI implementation for Apollo Domain/OS */ +#include "scsi-apollo.c" +#endif + +#ifdef AMIGA /* We have a SCSI implementation for AmigaOS */ +#define SCSI_IMPL +#include "scsi-amigaos.c" +#endif + +#if defined(__QNXNTO__) || defined(__QNX__) +#define SCSI_IMPL /* We have a SCSI implementation for QNX */ +#include "scsi-qnx.c" +#endif /* QNX */ + +#ifdef __DJGPP__ /* We have a SCSI implementation for MS-DOS/DJGPP */ +#define SCSI_IMPL +#include "scsi-dos.c" +#endif + +#ifdef __NEW_ARCHITECTURE +#define SCSI_IMPL /* We have a SCSI implementation for XXX */ +/* + * Add new hacks here + */ +#include "scsi-new-arch.c" +#endif + + +#ifndef SCSI_IMPL +/* + * To make scsihack.c compile on all architectures. + * This does not mean that you may use it, but you can see + * if other problems exist. + */ +#define usalo_dversion usalo_version +#define usalo_dhelp usalo_help +#define usalo_dopen usalo_open +#define usalo_dclose usalo_close +#define usalo_dmaxdma usalo_maxdma +#define usalo_dgetbuf usalo_getbuf +#define usalo_dfreebuf usalo_freebuf +#define usalo_dhavebus usalo_havebus +#define usalo_dfileno usalo_fileno +#define usalo_dinitiator_id usalo_initiator_id +#define usalo_disatapi usalo_isatapi +#define usalo_dreset usalo_reset +#define usalo_dsend usalo_send +#endif /* SCSI_IMPL */ + +static int usalo_dsend(SCSI *usalp); +static char *usalo_dversion(SCSI *usalp, int what); +static int usalo_dhelp(SCSI *usalp, FILE *f); +static int usalo_nohelp(SCSI *usalp, FILE *f); +static int usalo_ropen(SCSI *usalp, char *device); +static int usalo_dopen(SCSI *usalp, char *device); +static int usalo_dclose(SCSI *usalp); +static long usalo_dmaxdma(SCSI *usalp, long amt); +static void *usalo_dgetbuf(SCSI *usalp, long amt); +static void usalo_dfreebuf(SCSI *usalp); +static BOOL usalo_dhavebus(SCSI *usalp, int busno); +static int usalo_dfileno(SCSI *usalp, int busno, int tgt, int tlun); +static int usalo_dinitiator_id(SCSI *usalp); +static int usalo_disatapi(SCSI *usalp); +static int usalo_dreset(SCSI *usalp, int what); + +usal_ops_t usal_remote_ops = { + usalo_dsend, + usalo_dversion, + usalo_nohelp, + usalo_ropen, + usalo_dclose, + usalo_dmaxdma, + usalo_dgetbuf, + usalo_dfreebuf, + usalo_dhavebus, + usalo_dfileno, + usalo_dinitiator_id, + usalo_disatapi, + usalo_dreset, + usalo_natname, +}; + +usal_ops_t usal_dummy_ops = { + usalo_dsend, + usalo_dversion, + usalo_dhelp, + usalo_dopen, + usalo_dclose, + usalo_dmaxdma, + usalo_dgetbuf, + usalo_dfreebuf, + usalo_dhavebus, + usalo_dfileno, + usalo_dinitiator_id, + usalo_disatapi, + usalo_dreset, + usalo_natname, +}; + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_trans_dversion[] = "scsihack.c-1.44"; /* The version for this transport*/ + +/* + * Return version information for the low level SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + */ +static char * +usalo_dversion(SCSI *usalp, int what) +{ + if (usalp != (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_trans_dversion); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (_sccsid); + } + } + return ((char *)0); +} + +static int +usalo_dhelp(SCSI *usalp, FILE *f) +{ + printf("None.\n"); + return (0); +} + +static int +usalo_nohelp(SCSI *usalp, FILE *f) +{ + return (0); +} + +static int +usalo_ropen(SCSI *usalp, char *device) +{ + comerrno(EX_BAD, "No remote SCSI transport available.\n"); + return (-1); /* Keep lint happy */ +} + +#ifndef SCSI_IMPL +static int +usalo_dopen(SCSI *usalp, char *device) +{ + comerrno(EX_BAD, "No local SCSI transport implementation for this architecture.\n"); + return (-1); /* Keep lint happy */ +} +#else +static int +usalo_dopen(SCSI *usalp, char *device) +{ + comerrno(EX_BAD, "SCSI open usage error.\n"); + return (-1); /* Keep lint happy */ +} +#endif /* SCSI_IMPL */ + +static int +usalo_dclose(SCSI *usalp) +{ + errno = EINVAL; + return (-1); +} + +static long +usalo_dmaxdma(SCSI *usalp, long amt) +{ + errno = EINVAL; + return (0L); +} + +static void * +usalo_dgetbuf(SCSI *usalp, long amt) +{ + errno = EINVAL; + return ((void *)0); +} + +static void +usalo_dfreebuf(SCSI *usalp) +{ +} + +static BOOL +usalo_dhavebus(SCSI *usalp, int busno) +{ + return (FALSE); +} + +static int +usalo_dfileno(SCSI *usalp, int busno, int tgt, int tlun) +{ + return (-1); +} + +#ifndef HAVE_NAT_NAMES /* to be defined in included source if supported */ +static char * usalo_natname(SCSI *usalp, int busno, int tgt, int tlun) { + static char namebuf[81]; + snprintf(namebuf, 80, "%d,%d,%d", usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + return namebuf; +} +#endif + +static int +usalo_dinitiator_id(SCSI *usalp) +{ + return (-1); +} + +static int +usalo_disatapi(SCSI *usalp) +{ + return (FALSE); +} + +static int +usalo_dreset(SCSI *usalp, int what) +{ + errno = EINVAL; + return (-1); +} + +static int +usalo_dsend(SCSI *usalp) +{ + errno = EINVAL; + return (-1); +} diff --git a/libusal/scsihelp.c b/libusal/scsihelp.c new file mode 100644 index 0000000..4ddebfa --- /dev/null +++ b/libusal/scsihelp.c @@ -0,0 +1,56 @@ +/* + * 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. + * + */ + +/* @(#)scsihelp.c 1.4 04/01/14 Copyright 2002 J. Schilling */ +/* + * usal Library + * Help subsystem + * + * Copyright (c) 2002 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 <schily.h> + +#include <usal/scsitransp.h> + +void __usal_help(FILE *f, char *name, char *tcomment, char *tind, char *tspec, + char *texample, BOOL mayscan, BOOL bydev); + +void +__usal_help(FILE *f, char *name, char *tcomment, char *tind, char *tspec, + char *texample, BOOL mayscan, BOOL bydev) +{ + fprintf(f, "\nTransport name: %s\n", name); + fprintf(f, "Transport descr.: %s\n", tcomment); + fprintf(f, "Transp. layer ind.: %s\n", tind); + fprintf(f, "Target specifier: %s\n", tspec); + fprintf(f, "Target example: %s\n", texample); + fprintf(f, "SCSI Bus scanning: %ssupported\n", mayscan? "":"not "); + fprintf(f, "Open via UNIX device: %ssupported\n", bydev? "":"not "); +} diff --git a/libusal/scsiopen.c b/libusal/scsiopen.c new file mode 100644 index 0000000..41dd1e9 --- /dev/null +++ b/libusal/scsiopen.c @@ -0,0 +1,464 @@ +/* + * 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. + * + */ + +/* @(#)scsiopen.c 1.95 04/01/14 Copyright 1995,2000 J. Schilling */ +/* + * SCSI command functions for cdrecord + * + * Copyright (c) 1995,2000 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. + */ + +/* + * NOTICE: The Philips CDD 521 has several firmware bugs. + * One of them is not to respond to a SCSI selection + * within 200ms if the general load on the + * SCSI bus is high. To deal with this problem + * most of the SCSI commands are send with the + * SCG_CMD_RETRY flag enabled. + * + * Note that the only legal place to assign + * values to usal_scsibus() usal_target() and usal_lun() + * is usal_settarget(). + */ +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#if defined(linux) || defined(__linux) || defined(__linux__) +extern BOOL check_linux_26(); +#endif + +#define strbeg(s1, s2) (strstr((s2), (s1)) == (s2)) + +extern int lverbose; + +SCSI *usal_open(char *scsidev, char *errs, int slen, int debug, int be_verbose); +int usal_help(FILE *f); +static int usal_scandev(char *devp, char *errs, int slen, int *busp, + int *tgtp, int *lunp); +int usal_close(SCSI * usalp); + +void usal_settimeout(SCSI * usalp, int timeout); + +SCSI *usal_smalloc(void); +void usal_sfree(SCSI *usalp); + +/* + * Open a SCSI device. + * + * Possible syntax is: + * + * Preferred: + * dev=target,lun / dev=scsibus,target,lun + * + * Needed on some systems: + * dev=devicename:target,lun / dev=devicename:scsibus,target,lun + * + * On systems that don't support SCSI Bus scanning this syntax helps: + * dev=devicename:@ / dev=devicename:@,lun + * or dev=devicename (undocumented) + * + * NOTE: As the 'lun' is part of the SCSI command descriptor block, it + * must always be known. If the OS cannot map it, it must be + * specified on command line. + */ +SCSI * +usal_open(char *scsidev, char *errs, int slen, int debug, int be_verbose) +{ + char devname[256]; + char *devp = NULL; + char *sdev = NULL; + int x1; + int bus = 0; + int tgt = 0; + int lun = 0; + int n = 0; + SCSI *usalp; + + if (errs) + errs[0] = '\0'; + usalp = usal_smalloc(); + if (usalp == NULL) { + if (errs) + snprintf(errs, slen, "No memory for SCSI structure"); + return ((SCSI *)0); + } + usalp->debug = debug; + usalp->overbose = be_verbose; + devname[0] = '\0'; + if (scsidev != NULL && scsidev[0] != '\0') { + sdev = scsidev; + if ((strncmp(scsidev, "HELP", 4) == 0) || + (strncmp(scsidev, "help", 4) == 0)) { + + return ((SCSI *)0); + } + if (strncmp(scsidev, "REMOTE", 6) == 0) { + /* + * REMOTE:user@host:scsidev or + * REMOTE(transp):user@host:scsidev + * e.g.: REMOTE(/usr/bin/ssh):user@host:scsidev + * + * We must send the complete device spec to the remote + * site to allow parsing on both sites. + */ + strncpy(devname, scsidev, sizeof (devname)-1); + devname[sizeof (devname)-1] = '\0'; + if (sdev[6] == '(' || sdev[6] == ':') + sdev = strchr(sdev, ':'); + else + sdev = NULL; + + if (sdev == NULL) { + /* + * This seems to be an illegal remote dev spec. + * Give it a chance with a standard parsing. + */ + sdev = scsidev; + devname[0] = '\0'; + } else { + /* + * Now try to go past user@host spec. + */ + if (sdev) + sdev = strchr(&sdev[1], ':'); + if (sdev) + sdev++; /* Device name follows ... */ + else + goto nulldevice; + } + } + if ((devp = strchr(sdev, ':')) == NULL) { + if (strchr(sdev, ',') == NULL) { + /* Notation form: 'devname' (undocumented) */ + /* Forward complete name to usal__open() */ + /* Fetch bus/tgt/lun values from OS */ + /* We may come here too with 'USCSI' */ + n = -1; + lun = -2; /* Lun must be known */ + if (devname[0] == '\0') { + strncpy(devname, scsidev, + sizeof (devname)-1); + devname[sizeof (devname)-1] = '\0'; + } + } else { + /* Basic notation form: 'bus,tgt,lun' */ + devp = sdev; + } + } else { + /* Notation form: 'devname:bus,tgt,lun'/'devname:@' */ + /* We may come here too with 'USCSI:' */ + if (devname[0] == '\0') { + /* + * Copy over the part before the ':' + */ + x1 = devp - scsidev; + if (x1 >= (int)sizeof (devname)) + x1 = sizeof (devname)-1; + strncpy(devname, scsidev, x1); + devname[x1] = '\0'; + } + devp++; + /* Check for a notation in the form 'devname:@' */ + if (devp[0] == '@') { + if (devp[1] == '\0') { + lun = -2; + } else if (devp[1] == ',') { + if (*astoi(&devp[2], &lun) != '\0') { + errno = EINVAL; + if (errs) + snprintf(errs, slen, + "Invalid lun specifier '%s'", + &devp[2]); + return ((SCSI *)0); + } + } + n = -1; + /* + * Got device:@ or device:@,lun + * Make sure not to call usal_scandev() + */ + devp = NULL; + } else if (devp[0] == '\0') { + /* + * Got USCSI: or ATAPI: + * Make sure not to call usal_scandev() + */ + devp = NULL; + } else if (strchr(sdev, ',') == NULL) { + /* We may come here with 'ATAPI:/dev/hdc' */ + strncpy(devname, scsidev, + sizeof (devname)-1); + devname[sizeof (devname)-1] = '\0'; + n = -1; + lun = -2; /* Lun must be known */ + /* + * Make sure not to call usal_scandev() + */ + devp = NULL; + } + } + } +nulldevice: + +/*fprintf(stderr, "10 scsidev '%s' sdev '%s' devp '%s' b: %d t: %d l: %d\n", scsidev, sdev, devp, bus, tgt, lun);*/ + + if (devp != NULL) { + n = usal_scandev(devp, errs, slen, &bus, &tgt, &lun); + if (n < 0) { + errno = EINVAL; + return ((SCSI *)0); + } + } + if (n >= 1 && n <= 3) { /* Got bus,target,lun or target,lun or tgt*/ + usal_settarget(usalp, bus, tgt, lun); + } else if (n == -1) { /* Got device:@, fetch bus/lun from OS */ + usal_settarget(usalp, -2, -2, lun); + } else if (devp != NULL) { + /* + * XXX May this happen after we allow tgt to repesent tgt,0 ? + */ + fprintf(stderr, "WARNING: device not valid, trying to use default target...\n"); + usal_settarget(usalp, 0, 6, 0); + } + if (be_verbose && scsidev != NULL) { + fprintf(stderr, "scsidev: '%s'\n", scsidev); + if (devname[0] != '\0') + fprintf(stderr, "devname: '%s'\n", devname); + fprintf(stderr, "scsibus: %d target: %d lun: %d\n", + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + } + if (debug > 0) { + fprintf(stderr, "usal__open(%s) %d,%d,%d\n", + devname, + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + } + if (usal__open(usalp, devname) <= 0) { + if (errs && usalp->errstr) + snprintf(errs, slen, "%s", usalp->errstr); + usal_sfree(usalp); + return ((SCSI *)0); + } + return (usalp); +} + +int +usal_help(FILE *f) +{ + SCSI *usalp; + + usalp = usal_smalloc(); + if (usalp != NULL) { +extern usal_ops_t usal_std_ops; + + usalp->ops = &usal_std_ops; + + printf("Supported SCSI transports for this platform:\n"); + SCGO_HELP(usalp, f); + usal_remote()->usalo_help(usalp, f); + usal_sfree(usalp); + } + return (0); +} + +/* + * Convert target,lun or scsibus,target,lun syntax. + * Check for bad syntax and invalid values. + * This is definitely better than using scanf() as it checks for syntax errors. + */ +static int +usal_scandev(char *devp, char *errs, int slen, int *busp, int *tgtp, int *lunp) +{ + int x1, x2, x3; + int n = 0; + char *p = devp; + + x1 = x2 = x3 = 0; + *busp = *tgtp = *lunp = 0; + + if (*p != '\0') { + p = astoi(p, &x1); + if (*p == ',') { + p++; + n++; + } else { + if (errs) + snprintf(errs, slen, "Invalid bus or target specifier in '%s'", devp); + return (-1); + } + } + if (*p != '\0') { + p = astoi(p, &x2); + if (*p == ',' || *p == '\0') { + if (*p != '\0') + p++; + n++; + } else { + if (errs) + snprintf(errs, slen, "Invalid target or lun specifier in '%s'", devp); + return (-1); + } + } + if (*p != '\0') { + p = astoi(p, &x3); + if (*p == '\0') { + n++; + } else { + if (errs) + snprintf(errs, slen, "Invalid lun specifier in '%s'", devp); + return (-1); + } + } + if (n == 3) { + *busp = x1; + *tgtp = x2; + *lunp = x3; + } + if (n == 2) { + *tgtp = x1; + *lunp = x2; + } + if (n == 1) { + *tgtp = x1; + } + + if (x1 < 0 || x2 < 0 || x3 < 0) { + if (errs) + snprintf(errs, slen, "Invalid value for bus, target or lun (%d,%d,%d)", + *busp, *tgtp, *lunp); + return (-1); + } + return (n); +} + +int +usal_close(SCSI *usalp) +{ + usal__close(usalp); + usal_sfree(usalp); + return (0); +} + +char * usal_natname(SCSI *usalp, int busno, int tgt, int tlun) { + return usalp->ops->usalo_natname(usalp, busno, tgt, tlun); +} + +int usal_fileno(SCSI *usalp, int busno, int tgt, int tlun) { + return usalp->ops->usalo_fileno(usalp, busno, tgt, tlun); +} + +void +usal_settimeout(SCSI *usalp, int timeout) +{ +#ifdef nonono + if (timeout >= 0) + usalp->deftimeout = timeout; +#else + usalp->deftimeout = timeout; +#endif +} + +SCSI * +usal_smalloc() +{ + SCSI *usalp; +extern usal_ops_t usal_dummy_ops; + + usalp = (SCSI *)malloc(sizeof (*usalp)); + if (usalp == NULL) + return ((SCSI *)0); + + fillbytes(usalp, sizeof (*usalp), 0); + usalp->ops = &usal_dummy_ops; + usal_settarget(usalp, -1, -1, -1); + usalp->fd = -1; + usalp->deftimeout = 20; + usalp->running = FALSE; + + usalp->cmdstart = (struct timeval *)malloc(sizeof (struct timeval)); + if (usalp->cmdstart == NULL) + goto err; + usalp->cmdstop = (struct timeval *)malloc(sizeof (struct timeval)); + if (usalp->cmdstop == NULL) + goto err; + usalp->scmd = (struct usal_cmd *)malloc(sizeof (struct usal_cmd)); + if (usalp->scmd == NULL) + goto err; + usalp->errstr = malloc(SCSI_ERRSTR_SIZE); + if (usalp->errstr == NULL) + goto err; + usalp->errptr = usalp->errbeg = usalp->errstr; + usalp->errstr[0] = '\0'; + usalp->errfile = (void *)stderr; + usalp->inq = (struct scsi_inquiry *)malloc(sizeof (struct scsi_inquiry)); + if (usalp->inq == NULL) + goto err; + usalp->cap = (struct scsi_capacity *)malloc(sizeof (struct scsi_capacity)); + if (usalp->cap == NULL) + goto err; + + return (usalp); +err: + usal_sfree(usalp); + return ((SCSI *)0); +} + +void +usal_sfree(SCSI *usalp) +{ + if (usalp->cmdstart) + free(usalp->cmdstart); + if (usalp->cmdstop) + free(usalp->cmdstop); + if (usalp->scmd) + free(usalp->scmd); + if (usalp->inq) + free(usalp->inq); + if (usalp->cap) + free(usalp->cap); + if (usalp->local) + free(usalp->local); + usal_freebuf(usalp); + if (usalp->errstr) + free(usalp->errstr); + free(usalp); +} diff --git a/libusal/scsitransp.c b/libusal/scsitransp.c new file mode 100644 index 0000000..b3cc502 --- /dev/null +++ b/libusal/scsitransp.c @@ -0,0 +1,1345 @@ +/* + * 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. + * + */ + +/* @(#)scsitransp.c 1.91 04/06/17 Copyright 1988,1995,2000-2004 J. Schilling */ +/*#ifndef lint*/ +static char sccsid[] = + "@(#)scsitransp.c 1.91 04/06/17 Copyright 1988,1995,2000-2004 J. Schilling"; +/*#endif*/ +/* + * SCSI user level command transport routines (generic part). + * + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + * + * Copyright (c) 1988,1995,2000-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 <stdxlib.h> +#include <unixstd.h> +#include <errno.h> +#include <timedefs.h> +#include <strdefs.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> +#include "usaltimes.h" + +#include <stdarg.h> + + +/* + * Warning: you may change this source, but if you do that + * you need to change the _usal_version and _usal_auth* string below. + * You may not return "schily" for an SCG_AUTHOR request anymore. + * Choose your name instead of "schily" and make clear that the version + * string is related to a modified source. + */ +static char _usal_version[] = CDRKIT_VERSION; /* The global libusal version */ +static char _usal_auth_cdrkit[] = "Cdrkit"; /* The author for this module */ + +#define DEFTIMEOUT 20 /* Default timeout for SCSI command transport */ + +char *usal_version(SCSI *usalp, int what); +int usal__open(SCSI *usalp, char *device); +int usal__close(SCSI *usalp); +BOOL usal_havebus(SCSI *usalp, int); +int usal_initiator_id(SCSI *usalp); +int usal_isatapi(SCSI *usalp); +int usal_reset(SCSI *usalp, int what); +void *usal_getbuf(SCSI *usalp, long); +void usal_freebuf(SCSI *usalp); +long usal_bufsize(SCSI *usalp, long); +void usal_setnonstderrs(SCSI *usalp, const char **); +BOOL usal_yes(char *); +#ifdef nonono +static void usal_sighandler(int); +#endif +int usal_cmd(SCSI *usalp); +void usal_vhead(SCSI *usalp); +int usal_svhead(SCSI *usalp, char *buf, int maxcnt); +int usal_vtail(SCSI *usalp); +int usal_svtail(SCSI *usalp, int *retp, char *buf, int maxcnt); +void usal_vsetup(SCSI *usalp); +int usal_getresid(SCSI *usalp); +int usal_getdmacnt(SCSI *usalp); +BOOL usal_cmd_err(SCSI *usalp); +void usal_printerr(SCSI *usalp); +void usal_fprinterr(SCSI *usalp, FILE *f); +int usal_sprinterr(SCSI *usalp, char *buf, int maxcnt); +int usal__sprinterr(SCSI *usalp, char *buf, int maxcnt); +void usal_printcdb(SCSI *usalp); +int usal_sprintcdb(SCSI *usalp, char *buf, int maxcnt); +void usal_printwdata(SCSI *usalp); +int usal_sprintwdata(SCSI *usalp, char *buf, int maxcnt); +void usal_printrdata(SCSI *usalp); +int usal_sprintrdata(SCSI *usalp, char *buf, int maxcnt); +void usal_printresult(SCSI *usalp); +int usal_sprintresult(SCSI *usalp, char *buf, int maxcnt); +void usal_printstatus(SCSI *usalp); +int usal_sprintstatus(SCSI *usalp, char *buf, int maxcnt); +void usal_fprbytes(FILE *, char *, unsigned char *, int); +void usal_fprascii(FILE *, char *, unsigned char *, int); +void usal_prbytes(char *, unsigned char *, int); +void usal_prascii(char *, unsigned char *, int); +int usal_sprbytes(char *buf, int maxcnt, char *, unsigned char *, int); +int usal_sprascii(char *buf, int maxcnt, char *, unsigned char *, int); +void usal_fprsense(FILE *f, unsigned char *, int); +int usal_sprsense(char *buf, int maxcnt, unsigned char *, int); +void usal_prsense(unsigned char *, int); +int usal_cmd_status(SCSI *usalp); +int usal_sense_key(SCSI *usalp); +int usal_sense_code(SCSI *usalp); +int usal_sense_qual(SCSI *usalp); +unsigned char *usal_sense_table(SCSI *usalp); +void usal_fprintdev(FILE *, struct scsi_inquiry *); +void usal_printdev(struct scsi_inquiry *); +int usal_printf(SCSI *usalp, const char *form, ...); +int usal_errflush(SCSI *usalp); +int usal_errfflush(SCSI *usalp, FILE *f); + +/* + * Return version information for the SCSI transport code. + * This has been introduced to make it easier to trace down problems + * in applications. + * + * If usalp is NULL, return general library version information. + * If usalp is != NULL, return version information for the low level transport. + */ +char * +usal_version(SCSI *usalp, int what) +{ + if (usalp == (SCSI *)0) { + switch (what) { + + case SCG_VERSION: + return (_usal_version); + /* + * If you changed this source, you are not allowed to + * return "schily" for the SCG_AUTHOR request. + */ + case SCG_AUTHOR: + return (_usal_auth_cdrkit); + case SCG_SCCS_ID: + return (sccsid); + default: + return ((char *)0); + } + } + return (SCGO_VERSION(usalp, what)); +} + +/* + * Call low level SCSI open routine from transport abstraction layer. + */ +int +usal__open(SCSI *usalp, char *device) +{ + int ret; + usal_ops_t *ops; +extern usal_ops_t usal_std_ops; + + usalp->ops = &usal_std_ops; + + if (device && strncmp(device, "REMOTE", 6) == 0) { + ops = usal_remote(); + if (ops != NULL) + usalp->ops = ops; + } + + ret = SCGO_OPEN(usalp, device); + if (ret < 0) + return (ret); + + /* + * Now make usalp->fd valid if possible. + * Note that usal_scsibus(usalp)/usal_target(usalp)/usal_lun(usalp) may have + * changed in SCGO_OPEN(). + */ + usal_settarget(usalp, usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + return (ret); +} + +/* + * Call low level SCSI close routine from transport abstraction layer. + */ +int +usal__close(SCSI *usalp) +{ + return (SCGO_CLOSE(usalp)); +} + +/* + * Retrieve max DMA count for this target. + */ +long +usal_bufsize(SCSI *usalp, long amt) +{ + long maxdma; + + maxdma = SCGO_MAXDMA(usalp, amt); + if (amt <= 0 || amt > maxdma) + amt = maxdma; + + usalp->maxdma = maxdma; /* Max possible */ + usalp->maxbuf = amt; /* Current value */ + + return (amt); +} + +/* + * Allocate a buffer that may be used for DMA. + */ +void * +usal_getbuf(SCSI *usalp, long amt) +{ + void *buf; + + if (amt <= 0 || amt > usal_bufsize(usalp, amt)) + return ((void *)0); + + buf = SCGO_GETBUF(usalp, amt); + usalp->bufptr = buf; + return (buf); +} + +/* + * Free DMA buffer. + */ +void +usal_freebuf(SCSI *usalp) +{ + SCGO_FREEBUF(usalp); + usalp->bufptr = NULL; +} + +/* + * Check if 'busno' is a valid SCSI bus number. + */ +BOOL +usal_havebus(SCSI *usalp, int busno) +{ + return (SCGO_HAVEBUS(usalp, busno)); +} + +/* + * Return SCSI initiator ID for current SCSI bus if available. + */ +int +usal_initiator_id(SCSI *usalp) +{ + return (SCGO_INITIATOR_ID(usalp)); +} + +/* + * Return a hint whether current SCSI target refers to a ATAPI device. + */ +int +usal_isatapi(SCSI *usalp) +{ + return (SCGO_ISATAPI(usalp)); +} + +/* + * Reset SCSI bus or target. + */ +int +usal_reset(SCSI *usalp, int what) +{ + return (SCGO_RESET(usalp, what)); +} + +/* + * Set up nonstd error vector for curren target. + * To clear additional error table, call usal_setnonstderrs(usalp, NULL); + * Note: do not use this when scanning the SCSI bus. + */ +void +usal_setnonstderrs(SCSI *usalp, const char **vec) +{ + usalp->nonstderrs = vec; +} + +/* + * Simple Yes/No answer checker. + */ +BOOL +usal_yes(char *msg) +{ + char okbuf[10]; + + printf("%s", msg); + flush(); + if (rols_getline(okbuf, sizeof (okbuf)) == EOF) + exit(EX_BAD); + if (streql(okbuf, "y") || streql(okbuf, "yes") || + streql(okbuf, "Y") || streql(okbuf, "YES")) + return (TRUE); + else + return (FALSE); +} + +#ifdef nonono +static void +usal_sighandler(int sig) +{ + printf("\n"); + if (scsi_running) { + printf("Running command: %s\n", scsi_command); + printf("Resetting SCSI - Bus.\n"); + if (usal_reset(usalp) < 0) + errmsg("Cannot reset SCSI - Bus.\n"); + } + if (usal_yes("EXIT ? ")) + exit(sig); +} +#endif + +/* + * Send a SCSI command. + * Do error checking and reporting depending on the values of + * usalp->verbose, usalp->debug and usalp->silent. + */ +int +usal_cmd(SCSI *usalp) +{ + int ret; + register struct usal_cmd *scmd = usalp->scmd; + + /* + * Reset old error messages in usalp->errstr + */ + usalp->errptr = usalp->errbeg = usalp->errstr; + + scmd->kdebug = usalp->kdebug; + if (scmd->timeout == 0 || scmd->timeout < usalp->deftimeout) + scmd->timeout = usalp->deftimeout; + if (usalp->disre_disable) + scmd->flags &= ~SCG_DISRE_ENA; + if (usalp->noparity) + scmd->flags |= SCG_NOPARITY; + + scmd->u_sense.cmd_sense[0] = 0; /* Paranioa */ + if (scmd->sense_len > SCG_MAX_SENSE) + scmd->sense_len = SCG_MAX_SENSE; + else if (scmd->sense_len < 0) + scmd->sense_len = 0; + + if (usalp->verbose) { + usal_vhead(usalp); + usal_errflush(usalp); + } + + if (usalp->running) { + if (usalp->curcmdname) { + fprintf(stderr, "Currently running '%s' command.\n", + usalp->curcmdname); + } + raisecond("SCSI ALREADY RUNNING !!", 0L); + } + usalp->cb_fun = NULL; + gettimeofday(usalp->cmdstart, (struct timezone *)0); + usalp->curcmdname = usalp->cmdname; + usalp->running = TRUE; + ret = SCGO_SEND(usalp); + usalp->running = FALSE; + __usal_times(usalp); + if (ret < 0) { + /* + * Old /dev/usal versions will not allow to access targets > 7. + * Include a workaround to make this non fatal. + */ + if (usal_target(usalp) < 8 || geterrno() != EINVAL) + comerr("Cannot send SCSI cmd via ioctl\n"); + if (scmd->ux_errno == 0) + scmd->ux_errno = geterrno(); + if (scmd->error == SCG_NO_ERROR) + scmd->error = SCG_FATAL; + if (usalp->debug > 0) { + errmsg("ret < 0 errno: %d ux_errno: %d error: %d\n", + geterrno(), scmd->ux_errno, scmd->error); + } + } + + ret = usal_vtail(usalp); + usal_errflush(usalp); + if (usalp->cb_fun != NULL) + (*usalp->cb_fun)(usalp->cb_arg); + return (ret); +} + +/* + * Fill the head of verbose printing into the SCSI error buffer. + * Action depends on SCSI verbose status. + */ +void +usal_vhead(SCSI *usalp) +{ + usalp->errptr += usal_svhead(usalp, usalp->errptr, usal_errrsize(usalp)); +} + +/* + * Fill the head of verbose printing into a buffer. + * Action depends on SCSI verbose status. + */ +int +usal_svhead(SCSI *usalp, char *buf, int maxcnt) +{ + register char *p = buf; + register int amt; + + if (usalp->verbose <= 0) + return (0); + + amt = snprintf(p, maxcnt, + "\nExecuting '%s' command on Bus %d Target %d, Lun %d timeout %ds\n", + /* XXX Really this ??? */ +/* usalp->cmdname, usal_scsibus(usalp), usal_target(usalp), usalp->scmd->cdb.g0_cdb.lun,*/ + usalp->cmdname, usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp), + usalp->scmd->timeout); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + + amt = usal_sprintcdb(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + + if (usalp->verbose > 1) { + amt = usal_sprintwdata(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + return (p - buf); +} + +/* + * Fill the tail of verbose printing into the SCSI error buffer. + * Action depends on SCSI verbose status. + */ +int +usal_vtail(SCSI *usalp) +{ + int ret; + + usalp->errptr += usal_svtail(usalp, &ret, usalp->errptr, usal_errrsize(usalp)); + return (ret); +} + +/* + * Fill the tail of verbose printing into a buffer. + * Action depends on SCSI verbose status. + */ +int +usal_svtail(SCSI *usalp, int *retp, char *buf, int maxcnt) +{ + register char *p = buf; + register int amt; + int ret; + + ret = usal_cmd_err(usalp) ? -1 : 0; + if (retp) + *retp = ret; + if (ret) { + if (usalp->silent <= 0 || usalp->verbose) { + amt = usal__sprinterr(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + } + if ((usalp->silent <= 0 || usalp->verbose) && usalp->scmd->resid) { + if (usalp->scmd->resid < 0) { + /* + * An operating system that does DMA the right way + * will not allow DMA overruns - it will stop DMA + * before bad things happen. + * A DMA residual count < 0 (-1) is a hint for a DMA + * overrun but does not affect the transfer count. + */ + amt = snprintf(p, maxcnt, "DMA overrun, "); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + amt = snprintf(p, maxcnt, "resid: %d\n", usalp->scmd->resid); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + if (usalp->verbose > 0 || (ret < 0 && usalp->silent <= 0)) { + amt = usal_sprintresult(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + return (p - buf); +} + +/* + * Set up SCSI error buffer with verbose print data. + * Action depends on SCSI verbose status. + */ +void +usal_vsetup(SCSI *usalp) +{ + usal_vhead(usalp); + usal_vtail(usalp); +} + +/* + * Return the residual DMA count for last command. + * If this count is < 0, then a DMA overrun occured. + */ +int +usal_getresid(SCSI *usalp) +{ + return (usalp->scmd->resid); +} + +/* + * Return the actual DMA count for last command. + */ +int +usal_getdmacnt(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (scmd->resid < 0) + return (scmd->size); + + return (scmd->size - scmd->resid); +} + +/* + * Test if last SCSI command got an error. + */ +BOOL +usal_cmd_err(SCSI *usalp) +{ + register struct usal_cmd *cp = usalp->scmd; + + if (cp->error != SCG_NO_ERROR || + cp->ux_errno != 0 || + *(Uchar *)&cp->scb != 0 || + cp->u_sense.cmd_sense[0] != 0) /* Paranioa */ + return (TRUE); + return (FALSE); +} + +/* + * Used to print error messges if the command itself has been run silently. + * + * print the following SCSI codes: + * + * - command transport status + * - CDB + * - SCSI status byte + * - Sense Bytes + * - Decoded Sense data + * - DMA status + * - SCSI timing + * + * to SCSI errfile. + */ +void +usal_printerr(SCSI *usalp) +{ + usal_fprinterr(usalp, (FILE *)usalp->errfile); +} + +/* + * print the following SCSI codes: + * + * - command transport status + * - CDB + * - SCSI status byte + * - Sense Bytes + * - Decoded Sense data + * - DMA status + * - SCSI timing + * + * to a file. + */ +void +usal_fprinterr(SCSI *usalp, FILE *f) +{ + char errbuf[SCSI_ERRSTR_SIZE]; + int amt; + + amt = usal_sprinterr(usalp, errbuf, sizeof (errbuf)); + if (amt > 0) { + filewrite(f, errbuf, amt); + fflush(f); + } +} + +/* + * print the following SCSI codes: + * + * - command transport status + * - CDB + * - SCSI status byte + * - Sense Bytes + * - Decoded Sense data + * - DMA status + * - SCSI timing + * + * into a buffer. + */ +int +usal_sprinterr(SCSI *usalp, char *buf, int maxcnt) +{ + int amt; + int osilent = usalp->silent; + int overbose = usalp->verbose; + + usalp->silent = 0; + usalp->verbose = 0; + amt = usal_svtail(usalp, NULL, buf, maxcnt); + usalp->silent = osilent; + usalp->verbose = overbose; + return (amt); +} + +/* + * print the following SCSI codes: + * + * - command transport status + * - CDB + * - SCSI status byte + * - Sense Bytes + * - Decoded Sense data + * + * into a buffer. + */ +int +usal__sprinterr(SCSI *usalp, char *buf, int maxcnt) +{ + register struct usal_cmd *cp = usalp->scmd; + register char *err; + char *cmdname = "SCSI command name not set by caller"; + char errbuf[64]; + register char *p = buf; + register int amt; + + switch (cp->error) { + + case SCG_NO_ERROR : err = "no error"; break; + case SCG_RETRYABLE: err = "retryable error"; break; + case SCG_FATAL : err = "fatal error"; break; + /* + * We need to cast timeval->* to long because + * of the broken sys/time.h in Linux. + */ + case SCG_TIMEOUT : snprintf(errbuf, sizeof (errbuf), + "cmd timeout after %ld.%03ld (%d) s", + (long)usalp->cmdstop->tv_sec, + (long)usalp->cmdstop->tv_usec/1000, + cp->timeout); + err = errbuf; + break; + default: snprintf(errbuf, sizeof (errbuf), + "error: %d", cp->error); + err = errbuf; + } + + if (usalp->cmdname != NULL && usalp->cmdname[0] != '\0') + cmdname = usalp->cmdname; + /*amt = serrmsgno(cp->ux_errno, p, maxcnt, "%s: scsi sendcmd: %s\n", cmdname, err); + if (amt < 0) + return (amt); + */ + amt=snprintf(p, maxcnt, "Errno: %d (%s), %s scsi sendcmd: %s\n", cp->ux_errno, strerror(cp->ux_errno), cmdname, err); + if(amt>=maxcnt || amt<0) + return (amt); + p += amt; + maxcnt -= amt; + + amt = usal_sprintcdb(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + + if (cp->error <= SCG_RETRYABLE) { + amt = usal_sprintstatus(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + + if (cp->scb.chk) { + amt = usal_sprsense(p, maxcnt, (Uchar *)&cp->sense, cp->sense_count); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + amt = usal__errmsg(usalp, p, maxcnt, &cp->sense, &cp->scb, -1); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + return (p - buf); +} + +/* + * XXX Do we need this function? + * + * print the SCSI Command descriptor block to XXX stderr. + */ +void +usal_printcdb(SCSI *usalp) +{ + usal_prbytes("CDB: ", usalp->scmd->cdb.cmd_cdb, usalp->scmd->cdb_len); +} + +/* + * print the SCSI Command descriptor block into a buffer. + */ +int +usal_sprintcdb(SCSI *usalp, char *buf, int maxcnt) +{ + int cnt; + + cnt = usal_sprbytes(buf, maxcnt, "CDB: ", usalp->scmd->cdb.cmd_cdb, usalp->scmd->cdb_len); + if (cnt < 0) + cnt = 0; + return (cnt); +} + +/* + * XXX Do we need this function? + * XXX usal_printrdata() is used. + * XXX We need to check if we should write to stderr or better to usal->errfile + * + * print the SCSI send data to stderr. + */ +void +usal_printwdata(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) == 0) { + fprintf(stderr, "Sending %d (0x%X) bytes of data.\n", + scmd->size, scmd->size); + usal_prbytes("Write Data: ", + (Uchar *)scmd->addr, + scmd->size > 100 ? 100 : scmd->size); + } +} + +/* + * print the SCSI send data into a buffer. + */ +int +usal_sprintwdata(SCSI *usalp, char *buf, int maxcnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + register char *p = buf; + register int amt; + + if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) == 0) { + amt = snprintf(p, maxcnt, + "Sending %d (0x%X) bytes of data.\n", + scmd->size, scmd->size); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + amt = usal_sprbytes(p, maxcnt, "Write Data: ", + (Uchar *)scmd->addr, + scmd->size > 100 ? 100 : scmd->size); + if (amt < 0) + return (amt); + p += amt; + } + return (p - buf); +} + +/* + * XXX We need to check if we should write to stderr or better to usal->errfile + * + * print the SCSI received data to stderr. + */ +void +usal_printrdata(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + register int trcnt = usal_getdmacnt(usalp); + + if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) != 0) { + fprintf(stderr, "Got %d (0x%X), expecting %d (0x%X) bytes of data.\n", + trcnt, trcnt, + scmd->size, scmd->size); + usal_prbytes("Received Data: ", + (Uchar *)scmd->addr, + trcnt > 100 ? 100 : trcnt); + } +} + +/* + * print the SCSI received data into a buffer. + */ +int +usal_sprintrdata(SCSI *usalp, char *buf, int maxcnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + register char *p = buf; + register int amt; + register int trcnt = usal_getdmacnt(usalp); + + if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) != 0) { + amt = snprintf(p, maxcnt, + "Got %d (0x%X), expecting %d (0x%X) bytes of data.\n", + trcnt, trcnt, + scmd->size, scmd->size); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + amt = usal_sprbytes(p, maxcnt, + "Received Data: ", + (Uchar *)scmd->addr, + trcnt > 100 ? 100 : trcnt); + if (amt < 0) + return (amt); + p += amt; + } + return (p - buf); +} + +/* + * XXX We need to check if we should write to stderr or better to usal->errfile + * + * print the SCSI timings and (depending on verbose) received data to stderr. + */ +void +usal_printresult(SCSI *usalp) +{ + fprintf(stderr, "cmd finished after %ld.%03lds timeout %ds\n", + (long)usalp->cmdstop->tv_sec, + (long)usalp->cmdstop->tv_usec/1000, + usalp->scmd->timeout); + if (usalp->verbose > 1) + usal_printrdata(usalp); + flush(); +} + +/* + * print the SCSI timings and (depending on verbose) received data into a buffer. + */ +int +usal_sprintresult(SCSI *usalp, char *buf, int maxcnt) +{ + register char *p = buf; + register int amt; + + amt = snprintf(p, maxcnt, + "cmd finished after %ld.%03lds timeout %ds\n", + (long)usalp->cmdstop->tv_sec, + (long)usalp->cmdstop->tv_usec/1000, + usalp->scmd->timeout); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + if (usalp->verbose > 1) { + amt = usal_sprintrdata(usalp, p, maxcnt); + if (amt < 0) + return (amt); + p += amt; + } + return (p - buf); +} + +/* + * XXX Do we need this function? + * + * print the SCSI status byte in human readable form to the SCSI error file. + */ +void +usal_printstatus(SCSI *usalp) +{ + char errbuf[SCSI_ERRSTR_SIZE]; + int amt; + + amt = usal_sprintstatus(usalp, errbuf, sizeof (errbuf)); + if (amt > 0) { + filewrite((FILE *)usalp->errfile, errbuf, amt); + fflush((FILE *)usalp->errfile); + } +} + +/* + * print the SCSI status byte in human readable form into a buffer. + */ +int +usal_sprintstatus(SCSI *usalp, char *buf, int maxcnt) +{ + register struct usal_cmd *cp = usalp->scmd; + char *err; + char *err2 = ""; + register char *p = buf; + register int amt; + + amt = snprintf(p, maxcnt, "status: 0x%x ", *(Uchar *)&cp->scb); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; +#ifdef SCSI_EXTENDED_STATUS + if (cp->scb.ext_st1) { + amt = snprintf(p, maxcnt, "0x%x ", ((Uchar *)&cp->scb)[1]); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + if (cp->scb.ext_st2) { + amt = snprintf(p, maxcnt, "0x%x ", ((Uchar *)&cp->scb)[2]); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } +#endif + switch (*(Uchar *)&cp->scb & 036) { + + case 0 : err = "GOOD STATUS"; break; + case 02 : err = "CHECK CONDITION"; break; + case 04 : err = "CONDITION MET/GOOD"; break; + case 010: err = "BUSY"; break; + case 020: err = "INTERMEDIATE GOOD STATUS"; break; + case 024: err = "INTERMEDIATE CONDITION MET/GOOD"; break; + case 030: err = "RESERVATION CONFLICT"; break; + default : err = "Reserved"; break; + } +#ifdef SCSI_EXTENDED_STATUS + if (cp->scb.ext_st1 && cp->scb.ha_er) + err2 = " host adapter detected error"; +#endif + amt = snprintf(p, maxcnt, "(%s%s)\n", err, err2); + if (amt < 0) + return (amt); + p += amt; + return (p - buf); +} + +/* + * print some bytes in hex to a file. + */ +void +usal_fprbytes(FILE *f, char *s, register Uchar *cp, register int n) +{ + fprintf(f, "%s", s); + while (--n >= 0) + fprintf(f, " %02X", *cp++); + fprintf(f, "\n"); +} + +/* + * print some bytes in ascii to a file. + */ +void +usal_fprascii(FILE *f, char *s, register Uchar *cp, register int n) +{ + register int c; + + fprintf(f, "%s", s); + while (--n >= 0) { + c = *cp++; + if (c >= ' ' && c < 0177) + fprintf(f, "%c", c); + else + fprintf(f, "."); + } + fprintf(f, "\n"); +} + +/* + * XXX We need to check if we should write to stderr or better to usal->errfile + * + * print some bytes in hex to stderr. + */ +void +usal_prbytes(char *s, register Uchar *cp, register int n) +{ + usal_fprbytes(stderr, s, cp, n); +} + +/* + * XXX We need to check if we should write to stderr or better to usal->errfile + * + * print some bytes in ascii to stderr. + */ +void +usal_prascii(char *s, register Uchar *cp, register int n) +{ + usal_fprascii(stderr, s, cp, n); +} + +/* + * print some bytes in hex into a buffer. + */ +int +usal_sprbytes(char *buf, int maxcnt, char *s, register Uchar *cp, register int n) +{ + register char *p = buf; + register int amt; + + amt = snprintf(p, maxcnt, "%s", s); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + + while (--n >= 0) { + amt = snprintf(p, maxcnt, " %02X", *cp++); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + amt = snprintf(p, maxcnt, "\n"); + if (amt < 0) + return (amt); + p += amt; + return (p - buf); +} + +/* + * print some bytes in ascii into a buffer. + */ +int +usal_sprascii(char *buf, int maxcnt, char *s, register Uchar *cp, register int n) +{ + register char *p = buf; + register int amt; + register int c; + + amt = snprintf(p, maxcnt, "%s", s); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + + while (--n >= 0) { + c = *cp++; + if (c >= ' ' && c < 0177) + amt = snprintf(p, maxcnt, "%c", c); + else + amt = snprintf(p, maxcnt, "."); + if (amt < 0) + return (amt); + p += amt; + maxcnt -= amt; + } + amt = snprintf(p, maxcnt, "\n"); + if (amt < 0) + return (amt); + p += amt; + return (p - buf); +} + +/* + * print the SCSI sense data for last command in hex to a file. + */ +void +usal_fprsense(FILE *f, Uchar *cp, int n) +{ + usal_fprbytes(f, "Sense Bytes:", cp, n); +} + +/* + * XXX We need to check if we should write to stderr or better to usal->errfile + * + * print the SCSI sense data for last command in hex to stderr. + */ +void +usal_prsense(Uchar *cp, int n) +{ + usal_fprsense(stderr, cp, n); +} + +/* + * print the SCSI sense data for last command in hex into a buffer. + */ +int +usal_sprsense(char *buf, int maxcnt, Uchar *cp, int n) +{ + return (usal_sprbytes(buf, maxcnt, "Sense Bytes:", cp, n)); +} + +/* + * Return the SCSI status byte for last command. + */ +int +usal_cmd_status(SCSI *usalp) +{ + struct usal_cmd *cp = usalp->scmd; + int cmdstatus = *(Uchar *)&cp->scb; + + return (cmdstatus); +} + +/* + * Return the SCSI sense key for last command. + */ +int +usal_sense_key(SCSI *usalp) +{ + register struct usal_cmd *cp = usalp->scmd; + int key = -1; + + if (!usal_cmd_err(usalp)) + return (0); + + if (cp->sense.code >= 0x70) + key = ((struct scsi_ext_sense *)&(cp->sense))->key; + return (key); +} + +/* + * Return all the SCSI sense table last command. + */ +unsigned char * +usal_sense_table(SCSI *usalp) +{ + register struct usal_cmd *cp = usalp->scmd; + + if(!usal_cmd_err(usalp)) + return (0); + + /* if (cp->sense.code >= 0x70) */ + return (unsigned char *) &(cp->sense); +} + + +/* + * Return the SCSI sense code for last command. + */ +int +usal_sense_code(SCSI *usalp) +{ + register struct usal_cmd *cp = usalp->scmd; + int code = -1; + + if (!usal_cmd_err(usalp)) + return (0); + + if (cp->sense.code >= 0x70) + code = ((struct scsi_ext_sense *)&(cp->sense))->sense_code; + else + code = cp->sense.code; + return (code); +} + +/* + * Return the SCSI sense qualifier for last command. + */ +int +usal_sense_qual(SCSI *usalp) +{ + register struct usal_cmd *cp = usalp->scmd; + + if (!usal_cmd_err(usalp)) + return (0); + + if (cp->sense.code >= 0x70) + return (((struct scsi_ext_sense *)&(cp->sense))->qual_code); + else + return (0); +} + +/* + * Print the device type from the SCSI inquiry buffer to file. + */ +void +usal_fprintdev(FILE *f, struct scsi_inquiry *ip) +{ + if (ip->removable) + fprintf(f, "Removable "); + if (ip->data_format >= 2) { + switch (ip->qualifier) { + + case INQ_DEV_PRESENT: + break; + case INQ_DEV_NOTPR: + fprintf(f, "not present "); + break; + case INQ_DEV_RES: + fprintf(f, "reserved "); + break; + case INQ_DEV_NOTSUP: + if (ip->type == INQ_NODEV) { + fprintf(f, "unsupported\n"); return; + } + fprintf(f, "unsupported "); + break; + default: + fprintf(f, "vendor specific %d ", + (int)ip->qualifier); + } + } + switch (ip->type) { + + case INQ_DASD: + fprintf(f, "Disk"); break; + case INQ_SEQD: + fprintf(f, "Tape"); break; + case INQ_PRTD: + fprintf(f, "Printer"); break; + case INQ_PROCD: + fprintf(f, "Processor"); break; + case INQ_WORM: + fprintf(f, "WORM"); break; + case INQ_ROMD: + fprintf(f, "CD-ROM"); break; + case INQ_SCAN: + fprintf(f, "Scanner"); break; + case INQ_OMEM: + fprintf(f, "Optical Storage"); break; + case INQ_JUKE: + fprintf(f, "Juke Box"); break; + case INQ_COMM: + fprintf(f, "Communication"); break; + case INQ_IT8_1: + fprintf(f, "IT8 1"); break; + case INQ_IT8_2: + fprintf(f, "IT8 2"); break; + case INQ_STARR: + fprintf(f, "Storage array"); break; + case INQ_ENCL: + fprintf(f, "Enclosure services"); break; + case INQ_SDAD: + fprintf(f, "Simple direct access"); break; + case INQ_OCRW: + fprintf(f, "Optical card r/w"); break; + case INQ_BRIDGE: + fprintf(f, "Bridging expander"); break; + case INQ_OSD: + fprintf(f, "Object based storage"); break; + case INQ_ADC: + fprintf(f, "Automation/Drive Interface"); break; + case INQ_WELLKNOWN: + fprintf(f, "Well known lun"); break; + + case INQ_NODEV: + if (ip->data_format >= 2) { + fprintf(f, "unknown/no device"); + break; + } else if (ip->qualifier == INQ_DEV_NOTSUP) { + fprintf(f, "unit not present"); + break; + } + default: + fprintf(f, "unknown device type 0x%x", + (int)ip->type); + } + fprintf(f, "\n"); +} + +/* + * Print the device type from the SCSI inquiry buffer to stdout. + */ +void +usal_printdev(struct scsi_inquiry *ip) +{ + usal_fprintdev(stdout, ip); +} + +/* + * print into the SCSI error buffer, adjust the next write pointer. + */ +/* VARARGS2 */ +int +usal_printf(SCSI *usalp, const char *form, ...) +{ + int cnt; + va_list args; + + va_start(args, form); + cnt = vsnprintf(usalp->errptr, usal_errrsize(usalp), form, args); + va_end(args); + + if (cnt < 0) { + usalp->errptr[0] = '\0'; + } else { + usalp->errptr += cnt; + } + return (cnt); +} + +/* + * Flush the SCSI error buffer to SCSI errfile. + * Clear error buffer after flushing. + */ +int +usal_errflush(SCSI *usalp) +{ + if (usalp->errfile == NULL) + return (0); + + return (usal_errfflush(usalp, (FILE *)usalp->errfile)); +} + +/* + * Flush the SCSI error buffer to a file. + * Clear error buffer after flushing. + */ +int +usal_errfflush(SCSI *usalp, FILE *f) +{ + int cnt; + + cnt = usalp->errptr - usalp->errbeg; + if (cnt > 0) { + filewrite(f, usalp->errbeg, cnt); + fflush(f); + usalp->errbeg = usalp->errptr; + } + return (cnt); +} diff --git a/libusal/usal/aspi-dos.h b/libusal/usal/aspi-dos.h new file mode 100644 index 0000000..3428ac8 --- /dev/null +++ b/libusal/usal/aspi-dos.h @@ -0,0 +1,169 @@ +/* + * 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. + * + */ + +/* @(#)aspi-dos.h 1.2 05/05/15 J. Schilling */ +#ifndef __ASPI16_H_ +#define __ASPI16_H_ + +#define PACKED __attribute__((packed)) +#define FAR +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + +//***************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//***************************************************************************** + +#define SENSE_LEN 14 // Default sense buffer length +#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI +#define SRB_POSTING 0x01 // Enable ASPI posting +#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting +#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host +#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target + +//***************************************************************************** +// %%% ASPI Command Definitions %%% +//***************************************************************************** + +#define SC_HA_INQUIRY 0x00 // Host adapter inquiry +#define SC_GET_DEV_TYPE 0x01 // Get device type +#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command +#define SC_ABORT_SRB 0x03 // Abort an SRB +#define SC_RESET_DEV 0x04 // SCSI bus device reset +#define SC_SET_HA_PARMS 0x05 // Set HA parameters +#define SC_GET_DISK_INFO 0x06 // Get Disk information + +//***************************************************************************** +// %%% SRB Status %%% +//***************************************************************************** + +#define SS_PENDING 0x00 // SRB being processed +#define SS_COMP 0x01 // SRB completed without error +#define SS_ABORTED 0x02 // SRB aborted +#define SS_ABORT_FAIL 0x03 // Unable to abort SRB +#define SS_ERR 0x04 // SRB completed with error + +#define SS_INVALID_CMD 0x80 // Invalid ASPI command +#define SS_INVALID_HA 0x81 // Invalid host adapter number +#define SS_NO_DEVICE 0x82 // SCSI device not installed + +//***************************************************************************** +// %%% Host Adapter Status %%% +//***************************************************************************** + +#define HASTAT_OK 0x00 // Host adapter did not detect an + // error +#define HASTAT_SEL_TO 0x11 // Selection Timeout +#define HASTAT_DO_DU 0x12 // Data overrun data underrun +#define HASTAT_BUS_FREE 0x13 // Unexpected bus free +#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence + // failure +#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was + // waiting to beprocessed. +#define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB. +#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the + // adapter received a MESSAGE +#define HASTAT_BUS_RESET 0x0E // A bus reset was detected. +#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected. +#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing + +typedef struct { + + BYTE Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD + BYTE Status; // 01/001 ASPI command status byte + BYTE HaId; // 02/002 ASPI host adapter number + BYTE Flags; // 03/003 ASPI request flags + DWORD Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + + union { + + struct { + + BYTE Count; // 08/008 Number of host adapters present + BYTE SCSI_ID; // 09/009 SCSI ID of host adapter + BYTE ManagerId[16]; // 0A/010 String describing the manager + BYTE Identifier[16]; // 1A/026 String describing the host adapter + BYTE Unique[16]; // 2A/042 Host Adapter Unique parameters + BYTE ExtBuffer[8]; // 3A/058 Extended inquiry data + + } PACKED HAInquiry; + + struct { + + BYTE Target; // 08/008 Target's SCSI ID + BYTE Lun; // 09/009 Target's LUN number + BYTE DeviceType; // 0A/010 Target's peripheral device type + + } PACKED GetDeviceType; + + struct { + + BYTE Target; // 08/008 Target's SCSI ID + BYTE Lun; // 09/009 Target's LUN number + DWORD BufLen; // 0A/010 Data Allocation Length + BYTE SenseLen; // 0E/014 Sense Allocation Length + BYTE FAR *BufPointer; // 0F/015 Data Buffer Pointer + DWORD Rsvd1; // 13/019 Reserved, MUST = 0 + BYTE CDBLen; // 17/023 CDB Length = 6/10/12 + BYTE HaStat; // 18/024 Host Adapter Status + BYTE TargStat; // 19/025 Target Status + VOID FAR *PostProc; // 1A/026 Post routine + BYTE Rsvd2[34]; // 1E/030 Reserved, MUST = 0 + + union { + + struct { + + BYTE CDBByte[6]; // 40/064 SCSI CDB + BYTE SenseArea[SENSE_LEN+2]; // 46/070 Request Sense buffer + + } PACKED _6; + + struct { + + BYTE CDBByte[10]; // 40/064 SCSI CDB + BYTE SenseArea[SENSE_LEN+2]; // 4A/074 Request Sense buffer + + } PACKED _10; + + struct { + + BYTE CDBByte[12]; // 40/064 SCSI CDB + BYTE SenseArea[SENSE_LEN+2]; // 4C/076 Request Sense buffer + + } PACKED _12; + + } PACKED CmdLen; + + } PACKED ExecSCSICmd; + + struct { + + VOID FAR *SRBToAbort; // 08/008 Pointer to SRB to abort + + } PACKED Abort; + + struct { + BYTE Target; // 08/008 Target's SCSI ID + BYTE Lun; // 09/009 Target's LUN number + BYTE ResetRsvd1[14]; // 0A/010 Reserved, MUST = 0 + BYTE HaStat; // 18/024 Host Adapter Status + BYTE TargStat; // 19/025 Target Status + VOID FAR *PostProc; // 1A/026 Post routine + BYTE ResetRsvd2[34]; // 1E/030 Reserved, MUST = 0 + } Reset; + } PACKED Type; + +} PACKED SRB; + +#endif /* __ASPI16_H_ */ diff --git a/libusal/usal/aspi-win32.h b/libusal/usal/aspi-win32.h new file mode 100644 index 0000000..865befe --- /dev/null +++ b/libusal/usal/aspi-win32.h @@ -0,0 +1,208 @@ +/* + * 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. + * + */ + +#ifndef __ASPI_WIN32_H_ +#define __ASPI_WIN32_H_ + +#include <Windows.h> + +/*************************************************************************** + ** SCSI MISCELLANEOUS EQUATES + ***************************************************************************/ +#define SENSE_LEN 14 /* Default sense buffer length */ +#define SRB_DIR_SCSI 0x00 /* Direction determined by SCSI */ +#define SRB_POSTING 0x01 /* Enable ASPI posting */ +#define SRB_ENABLE_RESIDUAL_COUNT 0x04 /* Enable residual byte count */ + /* reporting */ +#define SRB_DIR_IN 0x08 /* Transfer from SCSI target to */ + /* host */ +#define SRB_DIR_OUT 0x10 /* Transfer from host to SCSI */ + /* target */ +#define SRB_EVENT_NOTIFY 0x40 /* Enable ASPI event notification */ +#define RESIDUAL_COUNT_SUPPORTED 0x02 /* Extended buffer flag */ +#define MAX_SRB_TIMEOUT 1080001u /* 30 hour maximum timeout in sec */ +#define DEFAULT_SRB_TIMEOUT 1080001u /* use max.timeout by default */ + +/*************************************************************************** + ** ASPI command definitions + ***************************************************************************/ +#define SC_HA_INQUIRY 0x00 /* Host adapter inquiry */ +#define SC_GET_DEV_TYPE 0x01 /* Get device type */ +#define SC_EXEC_SCSI_CMD 0x02 /* Execute SCSI command */ +#define SC_ABORT_SRB 0x03 /* Abort an SRB */ +#define SC_RESET_DEV 0x04 /* SCSI bus device reset */ +#define SC_SET_HA_PARMS 0x05 /* Set HA parameters */ +#define SC_GET_DISK_INFO 0x06 /* Get Disk */ +#define SC_RESCAN_SCSI_BUS 0x07 /* Rebuild SCSI device map */ +#define SC_GETSET_TIMEOUTS 0x08 /* Get/Set target timeouts */ + + +/*************************************************************************** + ** SRB Status + ***************************************************************************/ +#define SS_PENDING 0x00 /* SRB being processed */ +#define SS_COMP 0x01 /* SRB completed without error */ +#define SS_ABORTED 0x02 /* SRB aborted */ +#define SS_ABORT_FAIL 0x03 /* Unable to abort SRB */ +#define SS_ERR 0x04 /* SRB completed with error */ +#define SS_INVALID_CMD 0x80 /* Invalid ASPI command */ +#define SS_INVALID_HA 0x81 /* Invalid host adapter number */ +#define SS_NO_DEVICE 0x82 /* SCSI device not installed */ +#define SS_INVALID_SRB 0xE0 /* Invalid parameter set in SRB */ +#define SS_OLD_MANAGER 0xE1 /* ASPI manager doesn't support */ + /* windows */ +#define SS_BUFFER_ALIGN 0xE1 /* Buffer not aligned (replaces */ + /* SS_OLD_MANAGER in Win32) */ +#define SS_ILLEGAL_MODE 0xE2 /* Unsupported Windows mode */ +#define SS_NO_ASPI 0xE3 /* No ASPI managers */ +#define SS_FAILED_INIT 0xE4 /* ASPI for windows failed init */ +#define SS_ASPI_IS_BUSY 0xE5 /* No resources available to */ + /* execute command */ +#define SS_BUFFER_TO_BIG 0xE6 /* Buffer size too big to handle */ +#define SS_BUFFER_TOO_BIG 0xE6 /* Correct spelling of 'too' */ +#define SS_MISMATCHED_COMPONENTS 0xE7 /* The DLLs/EXEs of ASPI don't */ + /* version check */ +#define SS_NO_ADAPTERS 0xE8 /* No host adapters to manager */ +#define SS_INSUFFICIENT_RESOURCES 0xE9 /* Couldn't allocate resources */ + /* needed to init */ +#define SS_ASPI_IS_SHUTDOWN 0xEA /* Call came to ASPI after */ + /* PROCESS_DETACH */ +#define SS_BAD_INSTALL 0xEB /* The DLL or other components */ + /* are installed wrong */ + +/*************************************************************************** + ** Host Adapter Status + ***************************************************************************/ +#define HASTAT_OK 0x00 /* No error detected by HA */ +#define HASTAT_SEL_TO 0x11 /* Selection Timeout */ +#define HASTAT_DO_DU 0x12 /* Data overrun/data underrun */ +#define HASTAT_BUS_FREE 0x13 /* Unexpected bus free */ +#define HASTAT_PHASE_ERR 0x14 /* Target bus phase sequence */ +#define HASTAT_TIMEOUT 0x09 /* Timed out while SRB was */ + /* waiting to be processed */ +#define HASTAT_COMMAND_TIMEOUT 0x0B /* Adapter timed out while */ + /* processing SRB */ +#define HASTAT_MESSAGE_REJECT 0x0D /* While processing the SRB, the */ + /* adapter received a MESSAGE */ +#define HASTAT_BUS_RESET 0x0E /* A bus reset was detected */ +#define HASTAT_PARITY_ERROR 0x0F /* A parity error was detected */ +#define HASTAT_REQUEST_SENSE_FAILED 0x10 /* The adapter failed in issuing */ + + +/*************************************************************************** + ** SRB - HOST ADAPTER INQUIRIY - SC_HA_INQUIRY (0) + ***************************************************************************/ +typedef struct { + BYTE SRB_Cmd; /* 00/000 ASPI command code == SC_HA_INQUIRY */ + BYTE SRB_Status; /* 01/001 ASPI command status byte */ + BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ + BYTE SRB_Flags; /* 03/003 ASPI request flags */ + DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ + BYTE HA_Count; /* 08/008 Number of host adapters present */ + BYTE HA_SCSI_ID; /* 09/009 SCSI ID of host adapter */ + BYTE HA_ManagerId[16]; /* 0a/010 String describing the manager */ + BYTE HA_Identifier[16]; /* 1a/026 String describing the host adapter */ + BYTE HA_Unique[16]; /* 2a/042 Host Adapter Unique parameters */ + WORD HA_Rsvd1; /* 3a/058 Reserved, must = 0 */ +} PACKED SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry; + + +/*************************************************************************** + ** SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) + ***************************************************************************/ +typedef struct +{ + BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_GET_DEV_TYPE */ + BYTE SRB_Status; /* 01/001 ASPI command status byte */ + BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ + BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */ + DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ + BYTE SRB_Target; /* 08/008 Target's SCSI ID */ + BYTE SRB_Lun; /* 09/009 Target's LUN number */ + BYTE SRB_DeviceType; /* 0a/010 Target's peripheral device type */ + BYTE SRB_Rsvd1; /* 0b/011 Reserved, must = 0 */ +} PACKED SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock; + + +/*************************************************************************** + ** SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) + ***************************************************************************/ +typedef struct +{ + BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_EXEC_SCSI_CMD */ + BYTE SRB_Status; /* 01/001 ASPI command status byte */ + BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ + BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */ + DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ + BYTE SRB_Target; /* 08/008 Target's SCSI ID */ + BYTE SRB_Lun; /* 09/009 Target's LUN */ + WORD SRB_Rsvd1; /* 0a/010 Reserved for alignment */ + DWORD SRB_BufLen; /* 0c/012 Data Allocation Length */ + BYTE FAR *SRB_BufPointer; /* 10/016 Data Buffer Pointer */ + BYTE SRB_SenseLen; /* 14/020 Sense Allocation Length */ + BYTE SRB_CDBLen; /* 15/021 CDB Length */ + BYTE SRB_HaStat; /* 16/022 Host Adapter Status */ + BYTE SRB_TargStat; /* 17/023 Target Status */ + VOID FAR *SRB_PostProc; /* 18/024 Post routine */ + BYTE SRB_Rsvd2[20]; /* 1c/028 Reserved, must = 0 */ + BYTE CDBByte[16]; /* 30/048 SCSI CDB */ + BYTE SenseArea[SENSE_LEN+2]; /* 40/064 Request Sense buffer */ +} PACKED SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd; + + +typedef struct +{ + BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_ABORT_SRB */ + BYTE SRB_Status; /* 01/001 ASPI command status byte */ + BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ + BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */ + DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ + void *SRB_ToAbort; /* 08/008 Pointer to SRB to abort */ +} PACKED SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort; + + +/*************************************************************************** + ** SRB - BUS DEVICE RESET - SC_RESET_DEV (4) + ***************************************************************************/ +typedef struct +{ + BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_RESET_DEV */ + BYTE SRB_Status; /* 01/001 ASPI command status byte */ + BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ + DWORD SRB_Flags; /* 04/004 Reserved */ + BYTE SRB_Target; /* 08/008 Target's SCSI ID */ + BYTE SRB_Lun; /* 09/009 Target's LUN number */ + BYTE SRB_Rsvd1[12]; /* 0A/010 Reserved for alignment */ + BYTE SRB_HaStat; /* 16/022 Host Adapter Status */ + BYTE SRB_TargStat; /* 17/023 Target Status */ + VOID FAR *SRB_PostProc; /* 18/024 Post routine */ + BYTE SRB_Rsvd2[36]; /* 1C/028 Reserved, must = 0 */ +} SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset; + +typedef struct tag_ASPI32BUFF +{ + PBYTE AB_BufPointer; + DWORD AB_BufLen; + DWORD AB_ZeroFill; + DWORD AB_Reserved; +} PACKED ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF; + +typedef struct +{ + BYTE SRB_Cmd; + BYTE SRB_Status; + BYTE SRB_HaId; + BYTE SRB_Flags; + DWORD SRB_Hdr_Rsvd; +} SRB, *PSRB, FAR *LPSRB; + +#endif diff --git a/libusal/usal/scsicdb.h b/libusal/usal/scsicdb.h new file mode 100644 index 0000000..2594776 --- /dev/null +++ b/libusal/usal/scsicdb.h @@ -0,0 +1,260 @@ +/* + * 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. + * + */ + +/* @(#)scsicdb.h 2.19 04/09/04 Copyright 1986 J. Schilling */ +/* + * Definitions for the SCSI Command Descriptor Block + * + * Copyright (c) 1986 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. + */ + +#ifndef _SCG_SCSICDB_H +#define _SCG_SCSICDB_H + +#ifndef _UTYPES_H +#include <utypes.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif +/* + * SCSI Operation codes. + */ +#define SC_TEST_UNIT_READY 0x00 +#define SC_REZERO_UNIT 0x01 +#define SC_REQUEST_SENSE 0x03 +#define SC_FORMAT 0x04 +#define SC_FORMAT_TRACK 0x06 +#define SC_REASSIGN_BLOCK 0x07 /* CCS only */ +#define SC_SEEK 0x0b +#define SC_TRANSLATE 0x0f /* ACB4000 only */ +#define SC_INQUIRY 0x12 /* CCS only */ +#define SC_MODE_SELECT 0x15 +#define SC_RESERVE 0x16 +#define SC_RELEASE 0x17 +#define SC_MODE_SENSE 0x1a +#define SC_START 0x1b +#define SC_READ_DEFECT_LIST 0x37 /* CCS only, group 1 */ +#define SC_READ_BUFFER 0x3c /* CCS only, group 1 */ + /* + * Note, these two commands use identical command blocks for all + * controllers except the Adaptec ACB 4000 which sets bit 1 of byte 1. + */ +#define SC_READ 0x08 +#define SC_WRITE 0x0a +#define SC_EREAD 0x28 /* 10 byte read */ +#define SC_EWRITE 0x2a /* 10 byte write */ +#define SC_WRITE_VERIFY 0x2e /* 10 byte write+verify */ +#define SC_WRITE_FILE_MARK 0x10 +#define SC_UNKNOWN 0xff /* cmd list terminator */ + + +/* + * Standard SCSI control blocks. + * These go in or out over the SCSI bus. + */ + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_g0cdb { /* scsi group 0 command description block */ + Uchar cmd; /* command code */ + Ucbit high_addr : 5; /* high part of block address */ + Ucbit lun : 3; /* logical unit number */ + Uchar mid_addr; /* middle part of block address */ + Uchar low_addr; /* low part of block address */ + Uchar count; /* transfer length */ + Ucbit link : 1; /* link (another command follows) */ + Ucbit fr : 1; /* flag request (interrupt at completion) */ + Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ + Ucbit rsvd : 3; /* reserved */ + Ucbit vu_56 : 1; /* vendor unique (byte 5 bit 6) */ + Ucbit vu_57 : 1; /* vendor unique (byte 5 bit 7) */ +}; + +#else /* Motorola byteorder */ + +struct scsi_g0cdb { /* scsi group 0 command description block */ + Uchar cmd; /* command code */ + Ucbit lun : 3; /* logical unit number */ + Ucbit high_addr : 5; /* high part of block address */ + Uchar mid_addr; /* middle part of block address */ + Uchar low_addr; /* low part of block address */ + Uchar count; /* transfer length */ + Ucbit vu_57 : 1; /* vendor unique (byte 5 bit 7) */ + Ucbit vu_56 : 1; /* vendor unique (byte 5 bit 6) */ + Ucbit rsvd : 3; /* reserved */ + Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ + Ucbit fr : 1; /* flag request (interrupt at completion) */ + Ucbit link : 1; /* link (another command follows) */ +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_g1cdb { /* scsi group 1 command description block */ + Uchar cmd; /* command code */ + Ucbit reladr : 1; /* address is relative */ + Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ + Ucbit lun : 3; /* logical unit number */ + Uchar addr[4]; /* logical block address */ + Uchar res6; /* reserved byte 6 */ + Uchar count[2]; /* transfer length */ + Ucbit link : 1; /* link (another command follows) */ + Ucbit fr : 1; /* flag request (interrupt at completion) */ + Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ + Ucbit rsvd : 3; /* reserved */ + Ucbit vu_96 : 1; /* vendor unique (byte 5 bit 6) */ + Ucbit vu_97 : 1; /* vendor unique (byte 5 bit 7) */ +}; + +#else /* Motorola byteorder */ + +struct scsi_g1cdb { /* scsi group 1 command description block */ + Uchar cmd; /* command code */ + Ucbit lun : 3; /* logical unit number */ + Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ + Ucbit reladr : 1; /* address is relative */ + Uchar addr[4]; /* logical block address */ + Uchar res6; /* reserved byte 6 */ + Uchar count[2]; /* transfer length */ + Ucbit vu_97 : 1; /* vendor unique (byte 5 bit 7) */ + Ucbit vu_96 : 1; /* vendor unique (byte 5 bit 6) */ + Ucbit rsvd : 3; /* reserved */ + Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ + Ucbit fr : 1; /* flag request (interrupt at completion) */ + Ucbit link : 1; /* link (another command follows) */ +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_g5cdb { /* scsi group 5 command description block */ + Uchar cmd; /* command code */ + Ucbit reladr : 1; /* address is relative */ + Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ + Ucbit lun : 3; /* logical unit number */ + Uchar addr[4]; /* logical block address */ + Uchar count[4]; /* transfer length */ + Uchar res10; /* reserved byte 10 */ + Ucbit link : 1; /* link (another command follows) */ + Ucbit fr : 1; /* flag request (interrupt at completion) */ + Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ + Ucbit rsvd : 3; /* reserved */ + Ucbit vu_B6 : 1; /* vendor unique (byte B bit 6) */ + Ucbit vu_B7 : 1; /* vendor unique (byte B bit 7) */ +}; + +#else /* Motorola byteorder */ + +struct scsi_g5cdb { /* scsi group 5 command description block */ + Uchar cmd; /* command code */ + Ucbit lun : 3; /* logical unit number */ + Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ + Ucbit reladr : 1; /* address is relative */ + Uchar addr[4]; /* logical block address */ + Uchar count[4]; /* transfer length */ + Uchar res10; /* reserved byte 10 */ + Ucbit vu_B7 : 1; /* vendor unique (byte B bit 7) */ + Ucbit vu_B6 : 1; /* vendor unique (byte B bit 6) */ + Ucbit rsvd : 3; /* reserved */ + Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ + Ucbit fr : 1; /* flag request (interrupt at completion) */ + Ucbit link : 1; /* link (another command follows) */ +}; +#endif + +#define g0_cdbaddr(cdb, a) ((cdb)->high_addr = (a) >> 16,\ + (cdb)->mid_addr = ((a) >> 8) & 0xFF,\ + (cdb)->low_addr = (a) & 0xFF) + +#define g1_cdbaddr(cdb, a) ((cdb)->addr[0] = (a) >> 24,\ + (cdb)->addr[1] = ((a) >> 16)& 0xFF,\ + (cdb)->addr[2] = ((a) >> 8) & 0xFF,\ + (cdb)->addr[3] = (a) & 0xFF) + +#define g5_cdbaddr(cdb, a) g1_cdbaddr(cdb, a) + + +#define g0_cdblen(cdb, len) ((cdb)->count = (len)) + +#define g1_cdblen(cdb, len) ((cdb)->count[0] = ((len) >> 8) & 0xFF,\ + (cdb)->count[1] = (len) & 0xFF) + +#define g5_cdblen(cdb, len) ((cdb)->count[0] = (len) >> 24L,\ + (cdb)->count[1] = ((len) >> 16L)& 0xFF,\ + (cdb)->count[2] = ((len) >> 8L) & 0xFF,\ + (cdb)->count[3] = (len) & 0xFF) + +/*#define XXXXX*/ +#ifdef XXXXX +#define i_to_long(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[3] = (i) & 0xFF) + +#define i_to_3_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[2] = (i) & 0xFF) + +#define i_to_4_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ + ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ + ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[3] = (i) & 0xFF) + +#define i_to_short(a, i) (((Uchar *)(a))[0] = ((i) >> 8) & 0xFF,\ + ((Uchar *)(a))[1] = (i) & 0xFF) + +#define a_to_u_short(a) ((unsigned short) \ + ((((Uchar*) a)[1] & 0xFF) | \ + (((Uchar*) a)[0] << 8 & 0xFF00))) + +#define a_to_3_byte(a) ((Ulong) \ + ((((Uchar*) a)[2] & 0xFF) | \ + (((Uchar*) a)[1] << 8 & 0xFF00) | \ + (((Uchar*) a)[0] << 16 & 0xFF0000))) + +#ifdef __STDC__ +#define a_to_u_long(a) ((Ulong) \ + ((((Uchar*) a)[3] & 0xFF) | \ + (((Uchar*) a)[2] << 8 & 0xFF00) | \ + (((Uchar*) a)[1] << 16 & 0xFF0000) | \ + (((Uchar*) a)[0] << 24 & 0xFF000000UL))) +#else +#define a_to_u_long(a) ((Ulong) \ + ((((Uchar*) a)[3] & 0xFF) | \ + (((Uchar*) a)[2] << 8 & 0xFF00) | \ + (((Uchar*) a)[1] << 16 & 0xFF0000) | \ + (((Uchar*) a)[0] << 24 & 0xFF000000))) +#endif +#endif /* XXXX */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCSICDB_H */ diff --git a/libusal/usal/scsidefs.h b/libusal/usal/scsidefs.h new file mode 100644 index 0000000..fc57c16 --- /dev/null +++ b/libusal/usal/scsidefs.h @@ -0,0 +1,136 @@ +/* + * 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. + * + */ + +/* @(#)scsidefs.h 1.28 04/09/04 Copyright 1988 J. Schilling */ +/* + * Definitions for SCSI devices i.e. for error strings in scsierrs.c + * + * Copyright (c) 1988 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. + */ + +#ifndef _SCG_SCSIDEFS_H +#define _SCG_SCSIDEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Disks + */ +#ifdef DEV_UNKNOWN +/* + * True64 defines DEV_UNKNOWN in /usr/include/sys/devio.h as "UNKNOWN" + */ +#undef DEV_UNKNOWN +#endif +#define DEV_UNKNOWN 0 +#define DEV_ACB40X0 1 +#define DEV_ACB4000 2 +#define DEV_ACB4010 3 +#define DEV_ACB4070 4 +#define DEV_ACB5500 5 +#define DEV_ACB4520A 6 +#define DEV_ACB4525 7 +#define DEV_MD21 8 +#define DEV_MD23 9 +#define DEV_NON_CCS_DSK 10 +#define DEV_CCS_GENDISK 11 + +/* + * Tapes + */ +#define DEV_MT02 100 +#define DEV_SC4000 101 + +/* + * Printer + */ +#define DEV_PRT 200 + +/* + * Processors + */ +#define DEV_PROC 300 + +/* + * Worm + */ +#define DEV_WORM 400 +#define DEV_RXT800S 401 + +/* + * CD-ROM + */ +#define DEV_CDROM 500 +#define DEV_MMC_CDROM 501 +#define DEV_MMC_CDR 502 +#define DEV_MMC_CDRW 503 +#define DEV_MMC_DVD 504 +#define DEV_MMC_DVD_WR 505 + +#define DEV_CDD_521_OLD 510 +#define DEV_CDD_521 511 +#define DEV_CDD_522 512 +#define DEV_PCD_600 513 +#define DEV_CDD_2000 514 +#define DEV_CDD_2600 515 +#define DEV_TYUDEN_EW50 516 +#define DEV_YAMAHA_CDR_100 520 +#define DEV_YAMAHA_CDR_400 521 +#define DEV_PLASMON_RF_4100 530 +#define DEV_SONY_CDU_924 540 +#define DEV_RICOH_RO_1420C 550 +#define DEV_RICOH_RO_1060C 551 +#define DEV_TEAC_CD_R50S 560 +#define DEV_MATSUSHITA_7501 570 +#define DEV_MATSUSHITA_7502 571 +#define DEV_PIONEER_DW_S114X 580 +#define DEV_PIONEER_DVDR_S101 581 + +/* + * Scanners + */ +#define DEV_HRSCAN 600 +#define DEV_MS300A 601 + +/* + * Optical memory + */ +#define DEV_SONY_SMO 700 + + +#define old_acb(d) (((d) == DEV_ACB40X0) || \ + ((d) == DEV_ACB4000) || ((d) == DEV_ACB4010) || \ + ((d) == DEV_ACB4070) || ((d) == DEV_ACB5500)) + +#define is_ccs(d) (!old_acb(d)) + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCSIDEFS_H */ diff --git a/libusal/usal/scsireg.h b/libusal/usal/scsireg.h new file mode 100644 index 0000000..9fc0ea3 --- /dev/null +++ b/libusal/usal/scsireg.h @@ -0,0 +1,1240 @@ +/* + * 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. + * + */ + +/* @(#)scsireg.h 1.31 04/09/04 Copyright 1987 J. Schilling */ +/* + * usefull definitions for dealing with CCS SCSI - devices + * + * Copyright (c) 1987 J. Schilling + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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. + */ + +#ifndef _SCG_SCSIREG_H +#define _SCG_SCSIREG_H + +#include <utypes.h> +#include <btorder.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_inquiry { + Ucbit type : 5; /* 0 */ + Ucbit qualifier : 3; /* 0 */ + + Ucbit type_modifier : 7; /* 1 */ + Ucbit removable : 1; /* 1 */ + + Ucbit ansi_version : 3; /* 2 */ + Ucbit ecma_version : 3; /* 2 */ + Ucbit iso_version : 2; /* 2 */ + + Ucbit data_format : 4; /* 3 */ + Ucbit res3_54 : 2; /* 3 */ + Ucbit termiop : 1; /* 3 */ + Ucbit aenc : 1; /* 3 */ + + Ucbit add_len : 8; /* 4 */ + Ucbit sense_len : 8; /* 5 */ /* only Emulex ??? */ + Ucbit res2 : 8; /* 6 */ + + Ucbit softreset : 1; /* 7 */ + Ucbit cmdque : 1; + Ucbit res7_2 : 1; + Ucbit linked : 1; + Ucbit sync : 1; + Ucbit wbus16 : 1; + Ucbit wbus32 : 1; + Ucbit reladr : 1; /* 7 */ + + char vendor_info[8]; /* 8 */ + char prod_ident[16]; /* 16 */ + char prod_revision[4]; /* 32 */ +#ifdef comment + char vendor_uniq[20]; /* 36 */ + char reserved[40]; /* 56 */ +#endif +}; /* 96 */ + +#else /* Motorola byteorder */ + +struct scsi_inquiry { + Ucbit qualifier : 3; /* 0 */ + Ucbit type : 5; /* 0 */ + + Ucbit removable : 1; /* 1 */ + Ucbit type_modifier : 7; /* 1 */ + + Ucbit iso_version : 2; /* 2 */ + Ucbit ecma_version : 3; + Ucbit ansi_version : 3; /* 2 */ + + Ucbit aenc : 1; /* 3 */ + Ucbit termiop : 1; + Ucbit res3_54 : 2; + Ucbit data_format : 4; /* 3 */ + + Ucbit add_len : 8; /* 4 */ + Ucbit sense_len : 8; /* 5 */ /* only Emulex ??? */ + Ucbit res2 : 8; /* 6 */ + Ucbit reladr : 1; /* 7 */ + Ucbit wbus32 : 1; + Ucbit wbus16 : 1; + Ucbit sync : 1; + Ucbit linked : 1; + Ucbit res7_2 : 1; + Ucbit cmdque : 1; + Ucbit softreset : 1; + char vendor_info[8]; /* 8 */ + char prod_ident[16]; /* 16 */ + char prod_revision[4]; /* 32 */ +#ifdef comment + char vendor_uniq[20]; /* 36 */ + char reserved[40]; /* 56 */ +#endif +}; /* 96 */ +#endif + +#ifdef __SCG_COMPAT__ +#define info vendor_info +#define ident prod_ident +#define revision prod_revision +#endif + +/* Peripheral Device Qualifier */ + +#define INQ_DEV_PRESENT 0x00 /* Physical device present */ +#define INQ_DEV_NOTPR 0x01 /* Physical device not present */ +#define INQ_DEV_RES 0x02 /* Reserved */ +#define INQ_DEV_NOTSUP 0x03 /* Logical unit not supported */ + +/* Peripheral Device Type */ + +#define INQ_DASD 0x00 /* Direct-access device (disk) */ +#define INQ_SEQD 0x01 /* Sequential-access device (tape) */ +#define INQ_PRTD 0x02 /* Printer device */ +#define INQ_PROCD 0x03 /* Processor device */ +#define INQ_OPTD 0x04 /* Write once device (optical disk) */ +#define INQ_WORM 0x04 /* Write once device (optical disk) */ +#define INQ_ROMD 0x05 /* CD-ROM device */ +#define INQ_SCAN 0x06 /* Scanner device */ +#define INQ_OMEM 0x07 /* Optical Memory device */ +#define INQ_JUKE 0x08 /* Medium Changer device (jukebox) */ +#define INQ_COMM 0x09 /* Communications device */ +#define INQ_IT8_1 0x0A /* IT8 */ +#define INQ_IT8_2 0x0B /* IT8 */ +#define INQ_STARR 0x0C /* Storage array device */ +#define INQ_ENCL 0x0D /* Enclosure services device */ +#define INQ_SDAD 0x0E /* Simplyfied direct-access device */ +#define INQ_OCRW 0x0F /* Optical card reader/writer device */ +#define INQ_BRIDGE 0x10 /* Bridging expander device */ +#define INQ_OSD 0x11 /* Object based storage device */ +#define INQ_ADC 0x12 /* Automation/Drive interface */ +#define INQ_WELLKNOWN 0x1E /* Well known logical unit */ +#define INQ_NODEV 0x1F /* Unknown or no device */ +#define INQ_NOTPR 0x1F /* Logical unit not present (SCSI-1) */ + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_header { + Ucbit sense_data_len : 8; + Uchar medium_type; + Ucbit res2 : 4; + Ucbit cache : 1; + Ucbit res : 2; + Ucbit write_prot : 1; + Uchar blockdesc_len; +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_header { + Ucbit sense_data_len : 8; + Uchar medium_type; + Ucbit write_prot : 1; + Ucbit res : 2; + Ucbit cache : 1; + Ucbit res2 : 4; + Uchar blockdesc_len; +}; +#endif + +struct scsi_modesel_header { + Ucbit sense_data_len : 8; + Uchar medium_type; + Ucbit res2 : 8; + Uchar blockdesc_len; +}; + +struct scsi_mode_blockdesc { + Uchar density; + Uchar nlblock[3]; + Ucbit res : 8; + Uchar lblen[3]; +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct acb_mode_data { + Uchar listformat; + Uchar ncyl[2]; + Uchar nhead; + Uchar start_red_wcurrent[2]; + Uchar start_precomp[2]; + Uchar landing_zone; + Uchar step_rate; + Ucbit : 2; + Ucbit hard_sec : 1; + Ucbit fixed_media : 1; + Ucbit : 4; + Uchar sect_per_trk; +}; + +#else /* Motorola byteorder */ + +struct acb_mode_data { + Uchar listformat; + Uchar ncyl[2]; + Uchar nhead; + Uchar start_red_wcurrent[2]; + Uchar start_precomp[2]; + Uchar landing_zone; + Uchar step_rate; + Ucbit : 4; + Ucbit fixed_media : 1; + Ucbit hard_sec : 1; + Ucbit : 2; + Uchar sect_per_trk; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_header { + Ucbit p_code : 6; + Ucbit res : 1; + Ucbit parsave : 1; + Uchar p_len; +}; + +/* + * This is a hack that allows mode pages without + * any further bitfileds to be defined bitorder independent. + */ +#define MP_P_CODE \ + Ucbit p_code : 6; \ + Ucbit p_res : 1; \ + Ucbit parsave : 1 + +#else /* Motorola byteorder */ + +struct scsi_mode_page_header { + Ucbit parsave : 1; + Ucbit res : 1; + Ucbit p_code : 6; + Uchar p_len; +}; + +/* + * This is a hack that allows mode pages without + * any further bitfileds to be defined bitorder independent. + */ +#define MP_P_CODE \ + Ucbit parsave : 1; \ + Ucbit p_res : 1; \ + Ucbit p_code : 6 + +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_01 { /* Error recovery Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Ucbit disa_correction : 1; /* Byte 2 */ + Ucbit term_on_rec_err : 1; + Ucbit report_rec_err : 1; + Ucbit en_early_corr : 1; + Ucbit read_continuous : 1; + Ucbit tranfer_block : 1; + Ucbit en_auto_reall_r : 1; + Ucbit en_auto_reall_w : 1; /* Byte 2 */ + Uchar rd_retry_count; /* Byte 3 */ + Uchar correction_span; + char head_offset_count; + char data_strobe_offset; + Uchar res; + Uchar wr_retry_count; + Uchar res_tape[2]; + Uchar recov_timelim[2]; +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_01 { /* Error recovery Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Ucbit en_auto_reall_w : 1; /* Byte 2 */ + Ucbit en_auto_reall_r : 1; + Ucbit tranfer_block : 1; + Ucbit read_continuous : 1; + Ucbit en_early_corr : 1; + Ucbit report_rec_err : 1; + Ucbit term_on_rec_err : 1; + Ucbit disa_correction : 1; /* Byte 2 */ + Uchar rd_retry_count; /* Byte 3 */ + Uchar correction_span; + char head_offset_count; + char data_strobe_offset; + Uchar res; + Uchar wr_retry_count; + Uchar res_tape[2]; + Uchar recov_timelim[2]; +}; +#endif + + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_02 { /* Device dis/re connect Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0E = 16 Bytes */ + Uchar buf_full_ratio; + Uchar buf_empt_ratio; + Uchar bus_inact_limit[2]; + Uchar disc_time_limit[2]; + Uchar conn_time_limit[2]; + Uchar max_burst_size[2]; /* Start SCSI-2 */ + Ucbit data_tr_dis_ctl : 2; + Ucbit : 6; + Uchar res[3]; +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_02 { /* Device dis/re connect Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0E = 16 Bytes */ + Uchar buf_full_ratio; + Uchar buf_empt_ratio; + Uchar bus_inact_limit[2]; + Uchar disc_time_limit[2]; + Uchar conn_time_limit[2]; + Uchar max_burst_size[2]; /* Start SCSI-2 */ + Ucbit : 6; + Ucbit data_tr_dis_ctl : 2; + Uchar res[3]; +}; +#endif + +#define DTDC_DATADONE 0x01 /* + * Target may not disconnect once + * data transfer is started until + * all data successfully transferred. + */ + +#define DTDC_CMDDONE 0x03 /* + * Target may not disconnect once + * data transfer is started until + * command completed. + */ + + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_03 { /* Direct access format Paramters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x16 = 24 Bytes */ + Uchar trk_per_zone[2]; + Uchar alt_sec_per_zone[2]; + Uchar alt_trk_per_zone[2]; + Uchar alt_trk_per_vol[2]; + Uchar sect_per_trk[2]; + Uchar bytes_per_phys_sect[2]; + Uchar interleave[2]; + Uchar trk_skew[2]; + Uchar cyl_skew[2]; + Ucbit : 3; + Ucbit inhibit_save : 1; + Ucbit fmt_by_surface : 1; + Ucbit removable : 1; + Ucbit hard_sec : 1; + Ucbit soft_sec : 1; + Uchar res[3]; +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_03 { /* Direct access format Paramters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x16 = 24 Bytes */ + Uchar trk_per_zone[2]; + Uchar alt_sec_per_zone[2]; + Uchar alt_trk_per_zone[2]; + Uchar alt_trk_per_vol[2]; + Uchar sect_per_trk[2]; + Uchar bytes_per_phys_sect[2]; + Uchar interleave[2]; + Uchar trk_skew[2]; + Uchar cyl_skew[2]; + Ucbit soft_sec : 1; + Ucbit hard_sec : 1; + Ucbit removable : 1; + Ucbit fmt_by_surface : 1; + Ucbit inhibit_save : 1; + Ucbit : 3; + Uchar res[3]; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_04 { /* Rigid disk Geometry Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x16 = 24 Bytes */ + Uchar ncyl[3]; + Uchar nhead; + Uchar start_precomp[3]; + Uchar start_red_wcurrent[3]; + Uchar step_rate[2]; + Uchar landing_zone[3]; + Ucbit rot_pos_locking : 2; /* Start SCSI-2 */ + Ucbit : 6; /* Start SCSI-2 */ + Uchar rotational_off; + Uchar res1; + Uchar rotation_rate[2]; + Uchar res2[2]; +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_04 { /* Rigid disk Geometry Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x16 = 24 Bytes */ + Uchar ncyl[3]; + Uchar nhead; + Uchar start_precomp[3]; + Uchar start_red_wcurrent[3]; + Uchar step_rate[2]; + Uchar landing_zone[3]; + Ucbit : 6; /* Start SCSI-2 */ + Ucbit rot_pos_locking : 2; /* Start SCSI-2 */ + Uchar rotational_off; + Uchar res1; + Uchar rotation_rate[2]; + Uchar res2[2]; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_05 { /* Flexible disk Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x1E = 32 Bytes */ + Uchar transfer_rate[2]; + Uchar nhead; + Uchar sect_per_trk; + Uchar bytes_per_phys_sect[2]; + Uchar ncyl[2]; + Uchar start_precomp[2]; + Uchar start_red_wcurrent[2]; + Uchar step_rate[2]; + Uchar step_pulse_width; + Uchar head_settle_delay[2]; + Uchar motor_on_delay; + Uchar motor_off_delay; + Ucbit spc : 4; + Ucbit : 4; + Ucbit : 5; + Ucbit mo : 1; + Ucbit ssn : 1; + Ucbit trdy : 1; + Uchar write_compensation; + Uchar head_load_delay; + Uchar head_unload_delay; + Ucbit pin_2_use : 4; + Ucbit pin_34_use : 4; + Ucbit pin_1_use : 4; + Ucbit pin_4_use : 4; + Uchar rotation_rate[2]; + Uchar res[2]; +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_05 { /* Flexible disk Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x1E = 32 Bytes */ + Uchar transfer_rate[2]; + Uchar nhead; + Uchar sect_per_trk; + Uchar bytes_per_phys_sect[2]; + Uchar ncyl[2]; + Uchar start_precomp[2]; + Uchar start_red_wcurrent[2]; + Uchar step_rate[2]; + Uchar step_pulse_width; + Uchar head_settle_delay[2]; + Uchar motor_on_delay; + Uchar motor_off_delay; + Ucbit trdy : 1; + Ucbit ssn : 1; + Ucbit mo : 1; + Ucbit : 5; + Ucbit : 4; + Ucbit spc : 4; + Uchar write_compensation; + Uchar head_load_delay; + Uchar head_unload_delay; + Ucbit pin_34_use : 4; + Ucbit pin_2_use : 4; + Ucbit pin_4_use : 4; + Ucbit pin_1_use : 4; + Uchar rotation_rate[2]; + Uchar res[2]; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_07 { /* Verify Error recovery */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Ucbit disa_correction : 1; /* Byte 2 */ + Ucbit term_on_rec_err : 1; + Ucbit report_rec_err : 1; + Ucbit en_early_corr : 1; + Ucbit res : 4; /* Byte 2 */ + Uchar ve_retry_count; /* Byte 3 */ + Uchar ve_correction_span; + char res2[5]; /* Byte 5 */ + Uchar ve_recov_timelim[2]; /* Byte 10 */ +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_07 { /* Verify Error recovery */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Ucbit res : 4; /* Byte 2 */ + Ucbit en_early_corr : 1; + Ucbit report_rec_err : 1; + Ucbit term_on_rec_err : 1; + Ucbit disa_correction : 1; /* Byte 2 */ + Uchar ve_retry_count; /* Byte 3 */ + Uchar ve_correction_span; + char res2[5]; /* Byte 5 */ + Uchar ve_recov_timelim[2]; /* Byte 10 */ +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_08 { /* Caching Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Ucbit disa_rd_cache : 1; /* Byte 2 */ + Ucbit muliple_fact : 1; + Ucbit en_wt_cache : 1; + Ucbit res : 5; /* Byte 2 */ + Ucbit wt_ret_pri : 4; /* Byte 3 */ + Ucbit demand_rd_ret_pri: 4; /* Byte 3 */ + Uchar disa_pref_tr_len[2]; /* Byte 4 */ + Uchar min_pref[2]; /* Byte 6 */ + Uchar max_pref[2]; /* Byte 8 */ + Uchar max_pref_ceiling[2]; /* Byte 10 */ +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_08 { /* Caching Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Ucbit res : 5; /* Byte 2 */ + Ucbit en_wt_cache : 1; + Ucbit muliple_fact : 1; + Ucbit disa_rd_cache : 1; /* Byte 2 */ + Ucbit demand_rd_ret_pri: 4; /* Byte 3 */ + Ucbit wt_ret_pri : 4; + Uchar disa_pref_tr_len[2]; /* Byte 4 */ + Uchar min_pref[2]; /* Byte 6 */ + Uchar max_pref[2]; /* Byte 8 */ + Uchar max_pref_ceiling[2]; /* Byte 10 */ +}; +#endif + +struct scsi_mode_page_09 { /* Peripheral device Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* >= 0x06 = 8 Bytes */ + Uchar interface_id[2]; /* Byte 2 */ + Uchar res[4]; /* Byte 4 */ + Uchar vendor_specific[1]; /* Byte 8 */ +}; + +#define PDEV_SCSI 0x0000 /* scsi interface */ +#define PDEV_SMD 0x0001 /* SMD interface */ +#define PDEV_ESDI 0x0002 /* ESDI interface */ +#define PDEV_IPI2 0x0003 /* IPI-2 interface */ +#define PDEV_IPI3 0x0004 /* IPI-3 interface */ + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_0A { /* Common device Control Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 8 Bytes */ + Ucbit rep_log_exeption: 1; /* Byte 2 */ + Ucbit res : 7; /* Byte 2 */ + Ucbit dis_queuing : 1; /* Byte 3 */ + Ucbit queuing_err_man : 1; + Ucbit res2 : 2; + Ucbit queue_alg_mod : 4; /* Byte 3 */ + Ucbit EAENP : 1; /* Byte 4 */ + Ucbit UAENP : 1; + Ucbit RAENP : 1; + Ucbit res3 : 4; + Ucbit en_ext_cont_all : 1; /* Byte 4 */ + Ucbit res4 : 8; + Uchar ready_aen_hold_per[2]; /* Byte 6 */ +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_0A { /* Common device Control Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 8 Bytes */ + Ucbit res : 7; /* Byte 2 */ + Ucbit rep_log_exeption: 1; /* Byte 2 */ + Ucbit queue_alg_mod : 4; /* Byte 3 */ + Ucbit res2 : 2; + Ucbit queuing_err_man : 1; + Ucbit dis_queuing : 1; /* Byte 3 */ + Ucbit en_ext_cont_all : 1; /* Byte 4 */ + Ucbit res3 : 4; + Ucbit RAENP : 1; + Ucbit UAENP : 1; + Ucbit EAENP : 1; /* Byte 4 */ + Ucbit res4 : 8; + Uchar ready_aen_hold_per[2]; /* Byte 6 */ +}; +#endif + +#define CTRL_QMOD_RESTRICT 0x0 +#define CTRL_QMOD_UNRESTRICT 0x1 + + +struct scsi_mode_page_0B { /* Medium Types Supported Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 8 Bytes */ + Uchar res[2]; /* Byte 2 */ + Uchar medium_one_supp; /* Byte 4 */ + Uchar medium_two_supp; /* Byte 5 */ + Uchar medium_three_supp; /* Byte 6 */ + Uchar medium_four_supp; /* Byte 7 */ +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_0C { /* Notch & Partition Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x16 = 24 Bytes */ + Ucbit res : 6; /* Byte 2 */ + Ucbit logical_notch : 1; + Ucbit notched_drive : 1; /* Byte 2 */ + Uchar res2; /* Byte 3 */ + Uchar max_notches[2]; /* Byte 4 */ + Uchar active_notch[2]; /* Byte 6 */ + Uchar starting_boundary[4]; /* Byte 8 */ + Uchar ending_boundary[4]; /* Byte 12 */ + Uchar pages_notched[8]; /* Byte 16 */ +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_0C { /* Notch & Partition Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x16 = 24 Bytes */ + Ucbit notched_drive : 1; /* Byte 2 */ + Ucbit logical_notch : 1; + Ucbit res : 6; /* Byte 2 */ + Uchar res2; /* Byte 3 */ + Uchar max_notches[2]; /* Byte 4 */ + Uchar active_notch[2]; /* Byte 6 */ + Uchar starting_boundary[4]; /* Byte 8 */ + Uchar ending_boundary[4]; /* Byte 12 */ + Uchar pages_notched[8]; /* Byte 16 */ +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_mode_page_0D { /* CD-ROM Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 8 Bytes */ + Uchar res; /* Byte 2 */ + Ucbit inact_timer_mult: 4; /* Byte 3 */ + Ucbit res2 : 4; /* Byte 3 */ + Uchar s_un_per_m_un[2]; /* Byte 4 */ + Uchar f_un_per_s_un[2]; /* Byte 6 */ +}; + +#else /* Motorola byteorder */ + +struct scsi_mode_page_0D { /* CD-ROM Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 8 Bytes */ + Uchar res; /* Byte 2 */ + Ucbit res2 : 4; /* Byte 3 */ + Ucbit inact_timer_mult: 4; /* Byte 3 */ + Uchar s_un_per_m_un[2]; /* Byte 4 */ + Uchar f_un_per_s_un[2]; /* Byte 6 */ +}; +#endif + +struct sony_mode_page_20 { /* Sony Format Mode Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Uchar format_mode; + Uchar format_type; +#define num_bands user_band_size /* Gilt bei Type 1 */ + Uchar user_band_size[4]; /* Gilt bei Type 0 */ + Uchar spare_band_size[2]; + Uchar res[2]; +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct toshiba_mode_page_20 { /* Toshiba Speed Control Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x01 = 3 Bytes */ + Ucbit speed : 1; + Ucbit res : 7; +}; + +#else /* Motorola byteorder */ + +struct toshiba_mode_page_20 { /* Toshiba Speed Control Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x01 = 3 Bytes */ + Ucbit res : 7; + Ucbit speed : 1; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct ccs_mode_page_38 { /* CCS Caching Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0E = 14 Bytes */ + + Ucbit cache_table_size: 4; /* Byte 3 */ + Ucbit cache_en : 1; + Ucbit res2 : 1; + Ucbit wr_index_en : 1; + Ucbit res : 1; /* Byte 3 */ + Uchar threshold; /* Byte 4 Prefetch threshold */ + Uchar max_prefetch; /* Byte 5 Max. prefetch */ + Uchar max_multiplier; /* Byte 6 Max. prefetch multiplier */ + Uchar min_prefetch; /* Byte 7 Min. prefetch */ + Uchar min_multiplier; /* Byte 8 Min. prefetch multiplier */ + Uchar res3[8]; /* Byte 9 */ +}; + +#else /* Motorola byteorder */ + +struct ccs_mode_page_38 { /* CCS Caching Parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0E = 14 Bytes */ + + Ucbit res : 1; /* Byte 3 */ + Ucbit wr_index_en : 1; + Ucbit res2 : 1; + Ucbit cache_en : 1; + Ucbit cache_table_size: 4; /* Byte 3 */ + Uchar threshold; /* Byte 4 Prefetch threshold */ + Uchar max_prefetch; /* Byte 5 Max. prefetch */ + Uchar max_multiplier; /* Byte 6 Max. prefetch multiplier */ + Uchar min_prefetch; /* Byte 7 Min. prefetch */ + Uchar min_multiplier; /* Byte 8 Min. prefetch multiplier */ + Uchar res3[8]; /* Byte 9 */ +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct cd_mode_page_05 { /* write parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x32 = 50 Bytes */ + Ucbit write_type : 4; /* Session write type (PACKET/TAO...)*/ + Ucbit test_write : 1; /* Do not actually write data */ + Ucbit LS_V : 1; /* Link size valid */ + Ucbit BUFE : 1; /* Enable Bufunderrun free rec. */ + Ucbit res_2_7 : 1; + Ucbit track_mode : 4; /* Track mode (Q-sub control nibble) */ + Ucbit copy : 1; /* 1st higher gen of copy prot track ~*/ + Ucbit fp : 1; /* Fixed packed (if in packet mode) */ + Ucbit multi_session : 2; /* Multi session write type */ + Ucbit dbtype : 4; /* Data block type */ + Ucbit res_4 : 4; /* Reserved */ + Uchar link_size; /* Link Size (default is 7) */ + Uchar res_6; /* Reserved */ + Ucbit host_appl_code : 6; /* Host application code of disk */ + Ucbit res_7 : 2; /* Reserved */ + Uchar session_format; /* Session format (DA/CDI/XA) */ + Uchar res_9; /* Reserved */ + Uchar packet_size[4]; /* # of user datablocks/fixed packet */ + Uchar audio_pause_len[2]; /* # of blocks where index is zero */ + Uchar media_cat_number[16]; /* Media catalog Number (MCN) */ + Uchar ISRC[14]; /* ISRC for this track */ + Uchar sub_header[4]; + Uchar vendor_uniq[4]; +}; + +#else /* Motorola byteorder */ + +struct cd_mode_page_05 { /* write parameters */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x32 = 50 Bytes */ + Ucbit res_2_7 : 1; + Ucbit BUFE : 1; /* Enable Bufunderrun free rec. */ + Ucbit LS_V : 1; /* Link size valid */ + Ucbit test_write : 1; /* Do not actually write data */ + Ucbit write_type : 4; /* Session write type (PACKET/TAO...)*/ + Ucbit multi_session : 2; /* Multi session write type */ + Ucbit fp : 1; /* Fixed packed (if in packet mode) */ + Ucbit copy : 1; /* 1st higher gen of copy prot track */ + Ucbit track_mode : 4; /* Track mode (Q-sub control nibble) */ + Ucbit res_4 : 4; /* Reserved */ + Ucbit dbtype : 4; /* Data block type */ + Uchar link_size; /* Link Size (default is 7) */ + Uchar res_6; /* Reserved */ + Ucbit res_7 : 2; /* Reserved */ + Ucbit host_appl_code : 6; /* Host application code of disk */ + Uchar session_format; /* Session format (DA/CDI/XA) */ + Uchar res_9; /* Reserved */ + Uchar packet_size[4]; /* # of user datablocks/fixed packet */ + Uchar audio_pause_len[2]; /* # of blocks where index is zero */ + Uchar media_cat_number[16]; /* Media catalog Number (MCN) */ + Uchar ISRC[14]; /* ISRC for this track */ + Uchar sub_header[4]; + Uchar vendor_uniq[4]; +}; + +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct cd_wr_speed_performance { + Uchar res0; /* Reserved */ + Ucbit rot_ctl_sel : 2; /* Rotational control selected */ + Ucbit res_1_27 : 6; /* Reserved */ + Uchar wr_speed_supp[2]; /* Supported write speed */ +}; + +struct cd_mode_page_2A { /* CD Cap / mech status */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x14 = 20 Bytes (MMC) */ + /* 0x18 = 24 Bytes (MMC-2) */ + /* 0x1C >= 28 Bytes (MMC-3) */ + Ucbit cd_r_read : 1; /* Reads CD-R media */ + Ucbit cd_rw_read : 1; /* Reads CD-RW media */ + Ucbit method2 : 1; /* Reads fixed packet method2 media */ + Ucbit dvd_rom_read : 1; /* Reads DVD ROM media */ + Ucbit dvd_r_read : 1; /* Reads DVD-R media */ + Ucbit dvd_ram_read : 1; /* Reads DVD-RAM media */ + Ucbit res_2_67 : 2; /* Reserved */ + Ucbit cd_r_write : 1; /* Supports writing CD-R media */ + Ucbit cd_rw_write : 1; /* Supports writing CD-RW media */ + Ucbit test_write : 1; /* Supports emulation write */ + Ucbit res_3_3 : 1; /* Reserved */ + Ucbit dvd_r_write : 1; /* Supports writing DVD-R media */ + Ucbit dvd_ram_write : 1; /* Supports writing DVD-RAM media */ + Ucbit res_3_67 : 2; /* Reserved */ + Ucbit audio_play : 1; /* Supports Audio play operation */ + Ucbit composite : 1; /* Deliveres composite A/V stream */ + Ucbit digital_port_2 : 1; /* Supports digital output on port 2 */ + Ucbit digital_port_1 : 1; /* Supports digital output on port 1 */ + Ucbit mode_2_form_1 : 1; /* Reads Mode-2 form 1 media (XA) */ + Ucbit mode_2_form_2 : 1; /* Reads Mode-2 form 2 media */ + Ucbit multi_session : 1; /* Reads multi-session media */ + Ucbit BUF : 1; /* Supports Buffer under. free rec. */ + Ucbit cd_da_supported : 1; /* Reads audio data with READ CD cmd */ + Ucbit cd_da_accurate : 1; /* READ CD data stream is accurate */ + Ucbit rw_supported : 1; /* Reads R-W sub channel information */ + Ucbit rw_deint_corr : 1; /* Reads de-interleved R-W sub chan */ + Ucbit c2_pointers : 1; /* Supports C2 error pointers */ + Ucbit ISRC : 1; /* Reads ISRC information */ + Ucbit UPC : 1; /* Reads media catalog number (UPC) */ + Ucbit read_bar_code : 1; /* Supports reading bar codes */ + Ucbit lock : 1; /* PREVENT/ALLOW may lock media */ + Ucbit lock_state : 1; /* Lock state 0=unlocked 1=locked */ + Ucbit prevent_jumper : 1; /* State of prev/allow jumper 0=pres */ + Ucbit eject : 1; /* Ejects disc/cartr with STOP LoEj */ + Ucbit res_6_4 : 1; /* Reserved */ + Ucbit loading_type : 3; /* Loading mechanism type */ + Ucbit sep_chan_vol : 1; /* Vol controls each channel separat */ + Ucbit sep_chan_mute : 1; /* Mute controls each channel separat*/ + Ucbit disk_present_rep: 1; /* Changer supports disk present rep */ + Ucbit sw_slot_sel : 1; /* Load empty slot in changer */ + Ucbit side_change : 1; /* Side change capable */ + Ucbit pw_in_lead_in : 1; /* Reads raw P-W sucode from lead in */ + Ucbit res_7 : 2; /* Reserved */ + Uchar max_read_speed[2]; /* Max. read speed in KB/s */ + Uchar num_vol_levels[2]; /* # of supported volume levels */ + Uchar buffer_size[2]; /* Buffer size for the data in KB */ + Uchar cur_read_speed[2]; /* Current read speed in KB/s */ + Uchar res_16; /* Reserved */ + Ucbit res_17_0 : 1; /* Reserved */ + Ucbit BCK : 1; /* Data valid on falling edge of BCK */ + Ucbit RCK : 1; /* Set: HIGH high LRCK=left channel */ + Ucbit LSBF : 1; /* Set: LSB first Clear: MSB first */ + Ucbit length : 2; /* 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c*/ + Ucbit res_17 : 2; /* Reserved */ + Uchar max_write_speed[2]; /* Max. write speed supported in KB/s*/ + Uchar cur_write_speed[2]; /* Current write speed in KB/s */ + + /* Byte 22 ... Only in MMC-2 */ + Uchar copy_man_rev[2]; /* Copy management revision supported*/ + Uchar res_24; /* Reserved */ + Uchar res_25; /* Reserved */ + + /* Byte 26 ... Only in MMC-3 */ + Uchar res_26; /* Reserved */ + Ucbit res_27_27 : 6; /* Reserved */ + Ucbit rot_ctl_sel : 2; /* Rotational control selected */ + Uchar v3_cur_write_speed[2]; /* Current write speed in KB/s */ + Uchar num_wr_speed_des[2]; /* # of wr speed perf descr. tables */ + struct cd_wr_speed_performance + wr_speed_des[1]; /* wr speed performance descriptor */ + /* Actually more (num_wr_speed_des) */ +}; + +#else /* Motorola byteorder */ + +struct cd_wr_speed_performance { + Uchar res0; /* Reserved */ + Ucbit res_1_27 : 6; /* Reserved */ + Ucbit rot_ctl_sel : 2; /* Rotational control selected */ + Uchar wr_speed_supp[2]; /* Supported write speed */ +}; + +struct cd_mode_page_2A { /* CD Cap / mech status */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x14 = 20 Bytes (MMC) */ + /* 0x18 = 24 Bytes (MMC-2) */ + /* 0x1C >= 28 Bytes (MMC-3) */ + Ucbit res_2_67 : 2; /* Reserved */ + Ucbit dvd_ram_read : 1; /* Reads DVD-RAM media */ + Ucbit dvd_r_read : 1; /* Reads DVD-R media */ + Ucbit dvd_rom_read : 1; /* Reads DVD ROM media */ + Ucbit method2 : 1; /* Reads fixed packet method2 media */ + Ucbit cd_rw_read : 1; /* Reads CD-RW media */ + Ucbit cd_r_read : 1; /* Reads CD-R media */ + Ucbit res_3_67 : 2; /* Reserved */ + Ucbit dvd_ram_write : 1; /* Supports writing DVD-RAM media */ + Ucbit dvd_r_write : 1; /* Supports writing DVD-R media */ + Ucbit res_3_3 : 1; /* Reserved */ + Ucbit test_write : 1; /* Supports emulation write */ + Ucbit cd_rw_write : 1; /* Supports writing CD-RW media */ + Ucbit cd_r_write : 1; /* Supports writing CD-R media */ + Ucbit BUF : 1; /* Supports Buffer under. free rec. */ + Ucbit multi_session : 1; /* Reads multi-session media */ + Ucbit mode_2_form_2 : 1; /* Reads Mode-2 form 2 media */ + Ucbit mode_2_form_1 : 1; /* Reads Mode-2 form 1 media (XA) */ + Ucbit digital_port_1 : 1; /* Supports digital output on port 1 */ + Ucbit digital_port_2 : 1; /* Supports digital output on port 2 */ + Ucbit composite : 1; /* Deliveres composite A/V stream */ + Ucbit audio_play : 1; /* Supports Audio play operation */ + Ucbit read_bar_code : 1; /* Supports reading bar codes */ + Ucbit UPC : 1; /* Reads media catalog number (UPC) */ + Ucbit ISRC : 1; /* Reads ISRC information */ + Ucbit c2_pointers : 1; /* Supports C2 error pointers */ + Ucbit rw_deint_corr : 1; /* Reads de-interleved R-W sub chan */ + Ucbit rw_supported : 1; /* Reads R-W sub channel information */ + Ucbit cd_da_accurate : 1; /* READ CD data stream is accurate */ + Ucbit cd_da_supported : 1; /* Reads audio data with READ CD cmd */ + Ucbit loading_type : 3; /* Loading mechanism type */ + Ucbit res_6_4 : 1; /* Reserved */ + Ucbit eject : 1; /* Ejects disc/cartr with STOP LoEj */ + Ucbit prevent_jumper : 1; /* State of prev/allow jumper 0=pres */ + Ucbit lock_state : 1; /* Lock state 0=unlocked 1=locked */ + Ucbit lock : 1; /* PREVENT/ALLOW may lock media */ + Ucbit res_7 : 2; /* Reserved */ + Ucbit pw_in_lead_in : 1; /* Reads raw P-W sucode from lead in */ + Ucbit side_change : 1; /* Side change capable */ + Ucbit sw_slot_sel : 1; /* Load empty slot in changer */ + Ucbit disk_present_rep: 1; /* Changer supports disk present rep */ + Ucbit sep_chan_mute : 1; /* Mute controls each channel separat*/ + Ucbit sep_chan_vol : 1; /* Vol controls each channel separat */ + Uchar max_read_speed[2]; /* Max. read speed in KB/s */ + Uchar num_vol_levels[2]; /* # of supported volume levels */ + Uchar buffer_size[2]; /* Buffer size for the data in KB */ + Uchar cur_read_speed[2]; /* Current read speed in KB/s */ + Uchar res_16; /* Reserved */ + Ucbit res_17 : 2; /* Reserved */ + Ucbit length : 2; /* 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c*/ + Ucbit LSBF : 1; /* Set: LSB first Clear: MSB first */ + Ucbit RCK : 1; /* Set: HIGH high LRCK=left channel */ + Ucbit BCK : 1; /* Data valid on falling edge of BCK */ + Ucbit res_17_0 : 1; /* Reserved */ + Uchar max_write_speed[2]; /* Max. write speed supported in KB/s*/ + Uchar cur_write_speed[2]; /* Current write speed in KB/s */ + + /* Byte 22 ... Only in MMC-2 */ + Uchar copy_man_rev[2]; /* Copy management revision supported*/ + Uchar res_24; /* Reserved */ + Uchar res_25; /* Reserved */ + + /* Byte 26 ... Only in MMC-3 */ + Uchar res_26; /* Reserved */ + Ucbit res_27_27 : 6; /* Reserved */ + Ucbit rot_ctl_sel : 2; /* Rotational control selected */ + Uchar v3_cur_write_speed[2]; /* Current write speed in KB/s */ + Uchar num_wr_speed_des[2]; /* # of wr speed perf descr. tables */ + struct cd_wr_speed_performance + wr_speed_des[1]; /* wr speed performance descriptor */ + /* Actually more (num_wr_speed_des) */ +}; + +#endif + +#define LT_CADDY 0 +#define LT_TRAY 1 +#define LT_POP_UP 2 +#define LT_RES3 3 +#define LT_CHANGER_IND 4 +#define LT_CHANGER_CART 5 +#define LT_RES6 6 +#define LT_RES7 7 + + +struct scsi_mode_data { + struct scsi_mode_header header; + struct scsi_mode_blockdesc blockdesc; + union pagex { + struct acb_mode_data acb; + struct scsi_mode_page_01 page1; + struct scsi_mode_page_02 page2; + struct scsi_mode_page_03 page3; + struct scsi_mode_page_04 page4; + struct scsi_mode_page_05 page5; + struct scsi_mode_page_07 page7; + struct scsi_mode_page_08 page8; + struct scsi_mode_page_09 page9; + struct scsi_mode_page_0A pageA; + struct scsi_mode_page_0B pageB; + struct scsi_mode_page_0C pageC; + struct scsi_mode_page_0D pageD; + struct sony_mode_page_20 sony20; + struct toshiba_mode_page_20 toshiba20; + struct ccs_mode_page_38 ccs38; + } pagex; +}; + +struct scsi_capacity { + Int32_t c_baddr; /* must convert byteorder!! */ + Int32_t c_bsize; /* must convert byteorder!! */ +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_def_header { + Ucbit : 8; + Ucbit format : 3; + Ucbit gdl : 1; + Ucbit mdl : 1; + Ucbit : 3; + Uchar length[2]; +}; + +#else /* Motorola byteorder */ + +struct scsi_def_header { + Ucbit : 8; + Ucbit : 3; + Ucbit mdl : 1; + Ucbit gdl : 1; + Ucbit format : 3; + Uchar length[2]; +}; +#endif + + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_format_header { + Ucbit res : 8; /* Adaptec 5500: 1 --> format track */ + Ucbit vu : 1; /* Vendor Unique */ + Ucbit immed : 1; /* Return Immediately from Format */ + Ucbit tryout : 1; /* Check if format parameters OK */ + Ucbit ipattern : 1; /* Init patter descriptor present */ + Ucbit serr : 1; /* Stop on error */ + Ucbit dcert : 1; /* Disable certification */ + Ucbit dmdl : 1; /* Disable manufacturer defect list */ + Ucbit enable : 1; /* Enable to use the next 3 bits */ + Uchar length[2]; /* Length of following list in bytes*/ +}; + +#else /* Motorola byteorder */ + +struct scsi_format_header { + Ucbit res : 8; /* Adaptec 5500: 1 --> format track */ + Ucbit enable : 1; /* Enable to use the next 3 bits */ + Ucbit dmdl : 1; /* Disable manufacturer defect list */ + Ucbit dcert : 1; /* Disable certification */ + Ucbit serr : 1; /* Stop on error */ + Ucbit ipattern : 1; /* Init patter descriptor present */ + Ucbit tryout : 1; /* Check if format parameters OK */ + Ucbit immed : 1; /* Return Immediately from Format */ + Ucbit vu : 1; /* Vendor Unique */ + Uchar length[2]; /* Length of following list in bytes*/ +}; +#endif + +struct scsi_def_bfi { + Uchar cyl[3]; + Uchar head; + Uchar bfi[4]; +}; + +struct scsi_def_phys { + Uchar cyl[3]; + Uchar head; + Uchar sec[4]; +}; + +struct scsi_def_list { + struct scsi_def_header hd; + union { + Uchar list_block[1][4]; + struct scsi_def_bfi list_bfi[1]; + struct scsi_def_phys list_phys[1]; + } def_list; +}; + +struct scsi_format_data { + struct scsi_format_header hd; + union { + Uchar list_block[1][4]; + struct scsi_def_bfi list_bfi[1]; + struct scsi_def_phys list_phys[1]; + } def_list; +}; + +#define def_block def_list.list_block +#define def_bfi def_list.list_bfi +#define def_phys def_list.list_phys + +#define SC_DEF_BLOCK 0 +#define SC_DEF_BFI 4 +#define SC_DEF_PHYS 5 +#define SC_DEF_VU 6 +#define SC_DEF_RES 7 + +struct scsi_format_cap_header { + Uchar res[3]; /* Reserved */ + Uchar len; /* Len (a multiple of 8) */ +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_format_cap_desc { + Uchar nblock[4]; /* Number of blocks */ + Ucbit desc_type : 2; /* Descriptor type */ + Ucbit fmt_type : 6; /* Format Taype */ + Uchar blen[3]; /* Logical block length */ +}; + +#else /* Motorola byteorder */ + +struct scsi_format_cap_desc { + Uchar nblock[4]; /* Number of blocks */ + Ucbit fmt_type : 6; /* Format Taype */ + Ucbit desc_type : 2; /* Descriptor type */ + Uchar blen[3]; /* Logical block length */ +}; +#endif + +/* + * Defines for 'fmt_type'. + */ +#define FCAP_TYPE_DVDPLUS_FULL 0x26 /* DVD+RW Full Format */ + +/* + * Defines for 'desc_type'. + * In case of FCAP_DESC_RES, the descriptor is a formatted capacity descriptor + * and the 'blen' field is type dependent. + * For all other cases, this is the Current/Maximum Capacity descriptor and + * the value of 'fmt_type' is reserved and must be zero. + */ +#define FCAP_DESC_RES 0 /* Reserved */ +#define FCAP_DESC_UNFORM 1 /* Unformatted Media */ +#define FCAP_DESC_FORM 2 /* Formatted Media */ +#define FCAP_DESC_NOMEDIA 3 /* No Media */ + +struct scsi_cap_data { + struct scsi_format_cap_header hd; + struct scsi_format_cap_desc list[1]; +}; + + +struct scsi_send_diag_cmd { + Uchar cmd; + Uchar addr[4]; + Ucbit : 8; +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_sector_header { + Uchar cyl[2]; + Uchar head; + Uchar sec; + Ucbit : 5; + Ucbit rp : 1; + Ucbit sp : 1; + Ucbit dt : 1; +}; + +#else /* Motorola byteorder */ + +struct scsi_sector_header { + Uchar cyl[2]; + Uchar head; + Uchar sec; + Ucbit dt : 1; + Ucbit sp : 1; + Ucbit rp : 1; + Ucbit : 5; +}; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCSIREG_H */ diff --git a/libusal/usal/scsisense.h b/libusal/usal/scsisense.h new file mode 100644 index 0000000..c5ee6ab --- /dev/null +++ b/libusal/usal/scsisense.h @@ -0,0 +1,216 @@ +/* + * 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. + * + */ + +/* @(#)scsisense.h 2.18 04/09/04 Copyright 1986 J. Schilling */ +/* + * Definitions for the SCSI status code and sense structure + * + * Copyright (c) 1986 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. + */ + +#ifndef _SCG_SCSISENSE_H +#define _SCG_SCSISENSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * SCSI status completion block. + */ +#define SCSI_EXTENDED_STATUS + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_status { + Ucbit vu_00 : 1; /* vendor unique */ + Ucbit chk : 1; /* check condition: sense data available */ + Ucbit cm : 1; /* condition met */ + Ucbit busy : 1; /* device busy or reserved */ + Ucbit is : 1; /* intermediate status sent */ + Ucbit vu_05 : 1; /* vendor unique */ +#define st_scsi2 vu_05 /* SCSI-2 modifier bit */ + Ucbit vu_06 : 1; /* vendor unique */ + Ucbit st_rsvd : 1; /* reserved */ + +#ifdef SCSI_EXTENDED_STATUS +#define ext_st1 st_rsvd /* extended status (next byte valid) */ + /* byte 1 */ + Ucbit ha_er : 1; /* host adapter detected error */ + Ucbit reserved: 6; /* reserved */ + Ucbit ext_st2 : 1; /* extended status (next byte valid) */ + /* byte 2 */ + Uchar byte2; /* third byte */ +#endif /* SCSI_EXTENDED_STATUS */ +}; + +#else /* Motorola byteorder */ + +struct scsi_status { + Ucbit st_rsvd : 1; /* reserved */ + Ucbit vu_06 : 1; /* vendor unique */ + Ucbit vu_05 : 1; /* vendor unique */ +#define st_scsi2 vu_05 /* SCSI-2 modifier bit */ + Ucbit is : 1; /* intermediate status sent */ + Ucbit busy : 1; /* device busy or reserved */ + Ucbit cm : 1; /* condition met */ + Ucbit chk : 1; /* check condition: sense data available */ + Ucbit vu_00 : 1; /* vendor unique */ +#ifdef SCSI_EXTENDED_STATUS +#define ext_st1 st_rsvd /* extended status (next byte valid) */ + /* byte 1 */ + Ucbit ext_st2 : 1; /* extended status (next byte valid) */ + Ucbit reserved: 6; /* reserved */ + Ucbit ha_er : 1; /* host adapter detected error */ + /* byte 2 */ + Uchar byte2; /* third byte */ +#endif /* SCSI_EXTENDED_STATUS */ +}; +#endif + +/* + * OLD Standard (Non Extended) SCSI Sense. Used mainly by the + * Adaptec ACB 4000 which is the only controller that + * does not support the Extended sense format. + */ +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_sense { /* scsi sense for error classes 0-6 */ + Ucbit code : 7; /* error class/code */ + Ucbit adr_val : 1; /* sense data is valid */ +#ifdef comment + Ucbit high_addr:5; /* high byte of block addr */ + Ucbit rsvd : 3; +#else + Uchar high_addr; /* high byte of block addr */ +#endif + Uchar mid_addr; /* middle byte of block addr */ + Uchar low_addr; /* low byte of block addr */ +}; + +#else /* Motorola byteorder */ + +struct scsi_sense { /* scsi sense for error classes 0-6 */ + Ucbit adr_val : 1; /* sense data is valid */ + Ucbit code : 7; /* error class/code */ +#ifdef comment + Ucbit rsvd : 3; + Ucbit high_addr:5; /* high byte of block addr */ +#else + Uchar high_addr; /* high byte of block addr */ +#endif + Uchar mid_addr; /* middle byte of block addr */ + Uchar low_addr; /* low byte of block addr */ +}; +#endif + +/* + * SCSI extended sense parameter block. + */ +#ifdef comment +#define SC_CLASS_EXTENDED_SENSE 0x7 /* indicates extended sense */ +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct scsi_ext_sense { /* scsi extended sense for error class 7 */ + /* byte 0 */ + Ucbit type : 7; /* fixed at 0x70 */ + Ucbit adr_val : 1; /* sense data is valid */ + /* byte 1 */ + Uchar seg_num; /* segment number, applies to copy cmd only */ + /* byte 2 */ + Ucbit key : 4; /* sense key, see below */ + Ucbit : 1; /* reserved */ + Ucbit ili : 1; /* incorrect length indicator */ + Ucbit eom : 1; /* end of media */ + Ucbit fil_mk : 1; /* file mark on device */ + /* bytes 3 through 7 */ + Uchar info_1; /* information byte 1 */ + Uchar info_2; /* information byte 2 */ + Uchar info_3; /* information byte 3 */ + Uchar info_4; /* information byte 4 */ + Uchar add_len; /* number of additional bytes */ + /* bytes 8 through 13, CCS additions */ + Uchar optional_8; /* CCS search and copy only */ + Uchar optional_9; /* CCS search and copy only */ + Uchar optional_10; /* CCS search and copy only */ + Uchar optional_11; /* CCS search and copy only */ + Uchar sense_code; /* sense code */ + Uchar qual_code; /* sense code qualifier */ + Uchar fru_code; /* Field replacable unit code */ + Ucbit bptr : 3; /* bit pointer for failure (if bpv) */ + Ucbit bpv : 1; /* bit pointer is valid */ + Ucbit : 2; + Ucbit cd : 1; /* pointers refer to command not data */ + Ucbit sksv : 1; /* sense key specific valid */ + Uchar field_ptr[2]; /* field pointer for failure */ + Uchar add_info[2]; /* round up to 20 bytes */ +}; + +#else /* Motorola byteorder */ + +struct scsi_ext_sense { /* scsi extended sense for error class 7 */ + /* byte 0 */ + Ucbit adr_val : 1; /* sense data is valid */ + Ucbit type : 7; /* fixed at 0x70 */ + /* byte 1 */ + Uchar seg_num; /* segment number, applies to copy cmd only */ + /* byte 2 */ + Ucbit fil_mk : 1; /* file mark on device */ + Ucbit eom : 1; /* end of media */ + Ucbit ili : 1; /* incorrect length indicator */ + Ucbit : 1; /* reserved */ + Ucbit key : 4; /* sense key, see below */ + /* bytes 3 through 7 */ + Uchar info_1; /* information byte 1 */ + Uchar info_2; /* information byte 2 */ + Uchar info_3; /* information byte 3 */ + Uchar info_4; /* information byte 4 */ + Uchar add_len; /* number of additional bytes */ + /* bytes 8 through 13, CCS additions */ + Uchar optional_8; /* CCS search and copy only */ + Uchar optional_9; /* CCS search and copy only */ + Uchar optional_10; /* CCS search and copy only */ + Uchar optional_11; /* CCS search and copy only */ + Uchar sense_code; /* sense code */ + Uchar qual_code; /* sense code qualifier */ + Uchar fru_code; /* Field replacable unit code */ + Ucbit sksv : 1; /* sense key specific valid */ + Ucbit cd : 1; /* pointers refer to command not data */ + Ucbit : 2; + Ucbit bpv : 1; /* bit pointer is valid */ + Ucbit bptr : 3; /* bit pointer for failure (if bpv) */ + Uchar field_ptr[2]; /* field pointer for failure */ + Uchar add_info[2]; /* round up to 20 bytes */ +}; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCSISENSE_H */ diff --git a/libusal/usal/scsitransp.h b/libusal/usal/scsitransp.h new file mode 100644 index 0000000..a4f2327 --- /dev/null +++ b/libusal/usal/scsitransp.h @@ -0,0 +1,264 @@ +/* + * 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. + * + */ + +/* @(#)scsitransp.h 1.54 03/05/03 Copyright 1995 J. Schilling */ +/* + * Definitions for commands that use functions from scsitransp.c + * + * Copyright (c) 1995 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. + */ + +#ifndef _SCG_SCSITRANSP_H +#define _SCG_SCSITRANSP_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct usal_scsi SCSI; + +typedef struct { + int scsibus; /* SCSI bus # for next I/O */ + int target; /* SCSI target # for next I/O */ + int lun; /* SCSI lun # for next I/O */ +} usal_addr_t; + +#ifndef _SCG_SCGOPS_H +#include <usal/usalops.h> +#endif + +typedef int (*usal_cb_t)(void *); + +struct usal_scsi { + usal_ops_t *ops; /* Ptr to low level SCSI transport ops */ + int fd; /* File descriptor for next I/O */ + usal_addr_t addr; /* SCSI address for next I/O */ + int flags; /* Libusal flags (see below) */ + int dflags; /* Drive specific flags (see below) */ + int kdebug; /* Kernel debug value for next I/O */ + int debug; /* Debug value for SCSI library */ + int silent; /* Be silent if value > 0 */ + int verbose; /* Be verbose if value > 0 */ + int overbose; /* Be verbose in open() if value > 0 */ + int disre_disable; + int deftimeout; + int noparity; /* Do not use SCSI parity fo next I/O */ + int dev; /* from scsi_cdr.c */ + struct usal_cmd *scmd; + char *cmdname; + char *curcmdname; + BOOL running; + int error; /* libusal error number */ + + long maxdma; /* Max DMA limit for this open instance */ + long maxbuf; /* Cur DMA buffer limit for this inst. */ + /* This is the size behind bufptr */ + struct timeval *cmdstart; + struct timeval *cmdstop; + const char **nonstderrs; + void *local; /* Local data from the low level code */ + void *bufbase; /* needed for scsi_freebuf() */ + void *bufptr; /* DMA buffer pointer for appl. use */ + char *errstr; /* Error string for scsi_open/sendmcd */ + char *errbeg; /* Pointer to begin of not flushed data */ + char *errptr; /* Actual write pointer into errstr */ + void *errfile; /* FILE to write errors to. NULL for not*/ + /* writing and leaving errs in errstr */ + usal_cb_t cb_fun; + void *cb_arg; + + struct scsi_inquiry *inq; + struct scsi_capacity *cap; +}; + +/* + * Macros for accessing members of the usal address structure. + * usal_settarget() is the only function that is allowed to modify + * the values of the SCSI address. + */ +#define usal_scsibus(usalp) (usalp)->addr.scsibus +#define usal_target(usalp) (usalp)->addr.target +#define usal_lun(usalp) (usalp)->addr.lun + +/* + * Flags for struct SCSI: + */ +/* NONE yet */ + +/* + * Drive specific flags for struct SCSI: + */ +#define DRF_MODE_DMA_OVR 0x0001 /* Drive gives DMA overrun */ + /* on mode sense */ + +#define SCSI_ERRSTR_SIZE 4096 + +/* + * Libusal error codes: + */ +#define SCG_ERRBASE 1000000 +#define SCG_NOMEM 1000001 + +/* + * Function codes for usal_version(): + */ +#define SCG_VERSION 0 /* libusal or transport version */ +#define SCG_AUTHOR 1 /* Author of above */ +#define SCG_SCCS_ID 2 /* SCCS id of above */ +#define SCG_RVERSION 10 /* Remote transport version */ +#define SCG_RAUTHOR 11 /* Remote transport author */ +#define SCG_RSCCS_ID 12 /* Remote transport SCCS ID */ +#define SCG_KVERSION 20 /* Kernel transport version */ + +/* + * Function codes for usal_reset(): + */ +#define SCG_RESET_NOP 0 /* Test if reset is supported */ +#define SCG_RESET_TGT 1 /* Reset Target only */ +#define SCG_RESET_BUS 2 /* Reset complete SCSI Bus */ + +/* + * Helpers for the error buffer in SCSI* + */ +#define usal_errsize(usalp) ((usalp)->errptr - (usalp)->errstr) +#define usal_errrsize(usalp) (SCSI_ERRSTR_SIZE - usal_errsize(usalp)) + +/* + * From scsitransp.c: + */ +extern char *usal_version(SCSI *usalp, int what); +extern int usal__open(SCSI *usalp, char *device); +extern int usal__close(SCSI *usalp); +extern BOOL usal_havebus(SCSI *usalp, int); +extern int usal_initiator_id(SCSI *usalp); +extern int usal_isatapi(SCSI *usalp); +extern int usal_reset(SCSI *usalp, int what); +extern void *usal_getbuf(SCSI *usalp, long); +extern void usal_freebuf(SCSI *usalp); +extern long usal_bufsize(SCSI *usalp, long); +extern void usal_setnonstderrs(SCSI *usalp, const char **); +extern BOOL usal_yes(char *); +extern int usal_cmd(SCSI *usalp); +extern void usal_vhead(SCSI *usalp); +extern int usal_svhead(SCSI *usalp, char *buf, int maxcnt); +extern int usal_vtail(SCSI *usalp); +extern int usal_svtail(SCSI *usalp, int *retp, char *buf, int maxcnt); +extern void usal_vsetup(SCSI *usalp); +extern int usal_getresid(SCSI *usalp); +extern int usal_getdmacnt(SCSI *usalp); +extern BOOL usal_cmd_err(SCSI *usalp); +extern void usal_printerr(SCSI *usalp); +#ifdef EOF /* stdio.h has been included */ +extern void usal_fprinterr(SCSI *usalp, FILE *f); +#endif +extern int usal_sprinterr(SCSI *usalp, char *buf, int maxcnt); +extern int usal__sprinterr(SCSI *usalp, char *buf, int maxcnt); +extern void usal_printcdb(SCSI *usalp); +extern int usal_sprintcdb(SCSI *usalp, char *buf, int maxcnt); +extern void usal_printwdata(SCSI *usalp); +extern int usal_sprintwdata(SCSI *usalp, char *buf, int maxcnt); +extern void usal_printrdata(SCSI *usalp); +extern int usal_sprintrdata(SCSI *usalp, char *buf, int maxcnt); +extern void usal_printresult(SCSI *usalp); +extern int usal_sprintresult(SCSI *usalp, char *buf, int maxcnt); +extern void usal_printstatus(SCSI *usalp); +extern int usal_sprintstatus(SCSI *usalp, char *buf, int maxcnt); +#ifdef EOF /* stdio.h has been included */ +extern void usal_fprbytes(FILE *, char *, unsigned char *, int); +extern void usal_fprascii(FILE *, char *, unsigned char *, int); +#endif +extern void usal_prbytes(char *, unsigned char *, int); +extern void usal_prascii(char *, unsigned char *, int); +extern int usal_sprbytes(char *buf, int maxcnt, char *, unsigned char *, int); +extern int usal_sprascii(char *buf, int maxcnt, char *, unsigned char *, int); +#ifdef EOF /* stdio.h has been included */ +extern void usal_fprsense(FILE *f, unsigned char *, int); +#endif +extern void usal_prsense(unsigned char *, int); +extern int usal_sprsense(char *buf, int maxcnt, unsigned char *, int); +extern int usal_cmd_status(SCSI *usalp); +extern int usal_sense_key(SCSI *usalp); +extern int usal_sense_code(SCSI *usalp); +extern int usal_sense_qual(SCSI *usalp); +#ifdef _SCG_SCSIREG_H +#ifdef EOF /* stdio.h has been included */ +extern void usal_fprintdev(FILE *, struct scsi_inquiry *); +#endif +extern void usal_printdev(struct scsi_inquiry *); +#endif +extern int usal_printf(SCSI *usalp, const char *form, ...); +extern int usal_errflush(SCSI *usalp); +#ifdef EOF /* stdio.h has been included */ +extern int usal_errfflush(SCSI *usalp, FILE *f); +#endif + +/* + * From scsierrmsg.c: + */ +extern const char *usal_sensemsg(int, int, int, const char **, char *, + int maxcnt); +#ifdef _SCG_SCSISENSE_H +extern int usal__errmsg(SCSI *usalp, char *obuf, int maxcnt, + struct scsi_sense *, struct scsi_status *, int); +#endif + +/* + * From scsiopen.c: + */ +#ifdef EOF /* stdio.h has been included */ +extern int usal_help(FILE *f); +#endif +extern SCSI *usal_open(char *scsidev, char *errs, int slen, int odebug, + int be_verbose); +extern int usal_close(SCSI * usalp); +extern void usal_settimeout(SCSI * usalp, int timeout); +extern SCSI *usal_smalloc(void); +extern void usal_sfree(SCSI *usalp); + +/* + * From usalsettarget.c: + */ +extern int usal_settarget(SCSI *usalp, int scsibus, int target, int lun); + +/* + * From scsi-remote.c: + */ +extern usal_ops_t *usal_remote(void); + +/* + * From scsihelp.c: + */ +#ifdef EOF /* stdio.h has been included */ +extern void __usal_help(FILE *f, char *name, char *tcomment, char *tind, + char *tspec, char *texample, BOOL mayscan, + BOOL bydev); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCSITRANSP_H */ diff --git a/libusal/usal/spti-wnt.h b/libusal/usal/spti-wnt.h new file mode 100644 index 0000000..3edbe8f --- /dev/null +++ b/libusal/usal/spti-wnt.h @@ -0,0 +1,143 @@ +/* + * 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. + * + */ + +/* + * distilled information from various header files from Microsoft's + * DDK for Windows NT 4.0 + */ +#ifndef _SCSIPT_H_INC +#define _SCSIPT_H_INC + +#include <windows.h> + +typedef struct { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + ULONG DataBufferOffset; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; + + +typedef struct { + USHORT Length; + UCHAR ScsiStatus; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + UCHAR CdbLength; + UCHAR SenseInfoLength; + UCHAR DataIn; + ULONG DataTransferLength; + ULONG TimeOutValue; + PVOID DataBuffer; + ULONG SenseInfoOffset; + UCHAR Cdb[16]; +} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; + + +typedef struct { + SCSI_PASS_THROUGH spt; + ULONG Filler; + UCHAR ucSenseBuf[32]; + UCHAR ucDataBuf[512]; +} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; + + +typedef struct { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR ucSenseBuf[32]; +} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; + + + +typedef struct { + UCHAR NumberOfLogicalUnits; + UCHAR InitiatorBusId; + ULONG InquiryDataOffset; +} SCSI_BUS_DATA, *PSCSI_BUS_DATA; + + +typedef struct { + UCHAR NumberOfBusses; + SCSI_BUS_DATA BusData[1]; +} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; + + +typedef struct { + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; + BOOLEAN DeviceClaimed; + ULONG InquiryDataLength; + ULONG NextInquiryDataOffset; + UCHAR InquiryData[1]; +} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; + + +typedef struct { + ULONG Length; + UCHAR PortNumber; + UCHAR PathId; + UCHAR TargetId; + UCHAR Lun; +} SCSI_ADDRESS, *PSCSI_ADDRESS; + + +/* + * method codes + */ +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +/* + * file access values + */ +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS 0x0001 +#define FILE_WRITE_ACCESS 0x0002 + + +#define IOCTL_SCSI_BASE 0x00000004 + +/* + * constants for DataIn member of SCSI_PASS_THROUGH* structures + */ +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +/* + * Standard IOCTL define + */ +#define CTL_CODE(DevType, Function, Method, Access) \ + (((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) + +#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#endif diff --git a/libusal/usal/srb_os2.h b/libusal/usal/srb_os2.h new file mode 100644 index 0000000..54f57ca --- /dev/null +++ b/libusal/usal/srb_os2.h @@ -0,0 +1,179 @@ +/* + * 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. + * + */ + +/* @(#)srb_os2.h 1.1 98/11/01 Copyright 1998 D. Dorau, C. Wohlgemuth J. Schilling */ +/* + * Definitions for ASPI-Router (ASPIROUT.SYS). + * + * Copyright (c) 1998 D. Dorau, C. Wohlgemuth + */ + +/* + * 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. + */ + +#pragma pack(1) + + /* SRB command */ +#define SRB_Inquiry 0x00 +#define SRB_Device 0x01 +#define SRB_Command 0x02 +#define SRB_Abort 0x03 +#define SRB_Reset 0x04 +#define SRB_Param 0x05 + + /* SRB status */ +#define SRB_Busy 0x00 /* SCSI request in progress */ +#define SRB_Done 0x01 /* SCSI request completed without error */ +#define SRB_Aborted 0x02 /* SCSI aborted by host */ +#define SRB_BadAbort 0x03 /* Unable to abort SCSI request */ +#define SRB_Error 0x04 /* SCSI request completed with error */ +#define SRB_BusyPost 0x10 /* SCSI request in progress with POST - Nokia */ +#define SRB_InvalidCmd 0x80 /* Invalid SCSI request */ +#define SRB_InvalidHA 0x81 /* Invalid Hhost adapter number */ +#define SRB_BadDevice 0x82 /* SCSI device not installed */ + + /* SRB flags */ +#define SRB_Post 0x01 /* Post vector valid */ +#define SRB_Link 0x02 /* Link vector valid */ +#define SRB_SG 0x04 /* Nokia: scatter/gather */ + /* S/G: n * (4 bytes length, 4 bytes addr) */ + /* No of s/g items not limited by HA spec. */ +#define SRB_NoCheck 0x00 /* determined by command, not checked */ +#define SRB_Read 0x08 /* target to host, length checked */ +#define SRB_Write 0x10 /* host to target, length checked */ +#define SRB_NoTransfer 0x18 /* no data transfer */ +#define SRB_DirMask 0x18 /* bit mask */ + + /* SRB host adapter status */ +#define SRB_NoError 0x00 /* No host adapter detected error */ +#define SRB_Timeout 0x11 /* Selection timeout */ +#define SRB_DataLength 0x12 /* Data over/underrun */ +#define SRB_BusFree 0x13 /* Unexpected bus free */ +#define SRB_BusSequence 0x14 /* Target bus sequence failure */ + + /* SRB target status field */ +#define SRB_NoStatus 0x00 /* No target status */ +#define SRB_CheckStatus 0x02 /* Check status (sense data valid) */ +#define SRB_LUN_Busy 0x08 /* Specified LUN is busy */ +#define SRB_Reserved 0x18 /* Reservation conflict */ + +#define MaxCDBStatus 64 /* max size of CDB + status */ + + +typedef struct SRb { + unsigned char cmd, /* 00 */ + status, /* 01 */ + ha_num, /* 02 */ + flags; /* 03 */ + unsigned long res_04_07; /* 04..07 */ + union { /* 08 */ + + /* SRB_Inquiry */ + struct { + unsigned char num_ha, /* 08 */ + ha_target, /* 09 */ + aspimgr_id[16], /* 0A..19 */ + host_id[16], /* 1A..29 */ + unique_id[16]; /* 2A..39 */ + } inq; + + /* SRB_Device */ + struct { + unsigned char target, /* 08 */ + lun, /* 09 */ + devtype; /* 0A */ + } dev; + + /* SRB_Command */ + struct { + unsigned char target, /* 08 */ + lun; /* 09 */ + unsigned long data_len; /* 0A..0D */ + unsigned char sense_len; /* 0E */ + unsigned long data_ptr; /* 0F..12 */ + unsigned long link_ptr; /* 13..16 */ + // void * _Seg16 data_ptr; /* 0F..12 */ + // void * _Seg16 link_ptr; /* 13..16 */ + unsigned char cdb_len, /* 17 */ + ha_status, /* 18 */ + target_status; /* 19 */ + unsigned char _Seg16postSRB[4]; + // void (* _Seg16 post) (SRB *); /* 1A..1D */ + unsigned char res_1E_29[12]; /* 1E..29 */ + unsigned char res_2A_3F[22]; /* 2A..3F */ + unsigned char cdb_st[64]; /* 40..7F CDB+status */ + unsigned char res_80_BF[64]; /* 80..BF */ + } cmd; + + /* SRB_Abort */ + struct { + unsigned char _Seg16srb[4]; + // void * _Seg16 srb; /* 08..0B */ + } abt; + + /* SRB_Reset */ + struct { + unsigned char target, /* 08 */ + lun, /* 09 */ + res_0A_17[14], /* 0A..17 */ + ha_status, /* 18 */ + target_status; /* 19 */ + } res; + + /* SRB_Param - unused by ASPI4OS2 */ + struct { + unsigned char unique[16]; /* 08..17 */ + } par; + + } u; +} SRB; + + +// SCSI sense codes +// Note! This list may not be complete. I did this compilation for use with tape drives. + +#define Sense_Current 0x70; // Current Error +#define Sense_Deferred 0x71; // Deferred Error +#define Sense_Filemark 0x80; // Filemark detected +#define Sense_EOM 0x40; // End of medium detected +#define Sense_ILI 0x20; // Incorrect length indicator + +// Sense Keys + +#define SK_NoSense 0x00; // No Sense +#define SK_RcvrdErr 0x01; // Recovered Error +#define SK_NotReady 0x02; // Not ready +#define SK_MedErr 0x03; // Medium Error +#define SK_HWErr 0x04; // Hardware Error +#define SK_IllReq 0x05; // Illegal Request +#define SK_UnitAtt 0x06; // Unit attention +#define SK_DataProt 0x07: // Data Protect +#define SK_BlankChk 0x08: // Blank Check +#define SK_VndSpec 0x09; // Vendor Specific +#define SK_CopyAbort 0x0A; // Copy Aborted +#define SK_AbtdCmd 0x0B; // Aborted Command +#define SK_Equal 0x0C; // Equal +#define SK_VolOvfl 0x0D; // Volume Overflow +#define SK_MisComp 0x0E; // Miscompare +#define SK_Reserved 0x0F; // Reserved diff --git a/libusal/usal/usalcmd.h b/libusal/usal/usalcmd.h new file mode 100644 index 0000000..47893ee --- /dev/null +++ b/libusal/usal/usalcmd.h @@ -0,0 +1,211 @@ +/* + * 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. + * + */ + +/* @(#)usalcmd.h 2.22 04/09/04 Copyright 1986 J. Schilling */ +/* + * Definitions for the SCSI 'usal_cmd' structure that has been created + * for the SCSI general driver 'usal' for SunOS and Solaris but + * now is used for wrapping general libusal SCSI transport requests. + * + * Copyright (c) 1986 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. + */ + +#ifndef _SCG_SCGCMD_H +#define _SCG_SCGCMD_H + +#include <utypes.h> +#include <btorder.h> + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ +#else +# if defined(_BIT_FIELDS_HTOL) /* Motorola byteorder */ +# else +/* + * #error will not work for all compilers (e.g. sunos4) + * The following line will abort compilation on all compilers + * if none of the above is defines. And that's what we want. + */ +error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined +# endif +#endif + +#include <usal/scsisense.h> +#include <usal/scsicdb.h> +#include <intcvt.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Leave these definitions here if possible to avoid the need to + * include scsireg.h which makes problems on some OS because these + * OS define the same types as in scsireg.h + */ + +/* + * SCSI status bits. + */ +#define ST_VU_00 0x01 /* Vendor unique */ +#define ST_CHK_COND 0x02 /* Check condition */ +#define ST_COND_MET 0x04 /* Condition met */ +#define ST_BUSY 0x08 /* Busy */ +#define ST_IS_SEND 0x10 /* Intermediate status send */ +#define ST_VU_05 0x20 /* Vendor unique */ +#define ST_VU_06 0x40 /* Vendor unique */ +#define ST_RSVD_07 0x80 /* Reserved */ + +/* + * Sense key values for extended sense. + */ +#define SC_NO_SENSE 0x00 +#define SC_RECOVERABLE_ERROR 0x01 +#define SC_NOT_READY 0x02 +#define SC_MEDIUM_ERROR 0x03 +#define SC_HARDWARE_ERROR 0x04 +#define SC_ILLEGAL_REQUEST 0x05 +#define SC_UNIT_ATTENTION 0x06 +#define SC_WRITE_PROTECT 0x07 +#define SC_BLANK_CHECK 0x08 +#define SC_VENDOR_UNIQUE 0x09 +#define SC_COPY_ABORTED 0x0A +#define SC_ABORTED_COMMAND 0x0B +#define SC_EQUAL 0x0C +#define SC_VOLUME_OVERFLOW 0x0D +#define SC_MISCOMPARE 0x0E +#define SC_RESERVED 0x0F + +/* + * Messages that SCSI can send. + */ +#define SC_COMMAND_COMPLETE 0x00 +#define SC_SYNCHRONOUS 0x01 +#define SC_SAVE_DATA_PTR 0x02 +#define SC_RESTORE_PTRS 0x03 +#define SC_DISCONNECT 0x04 +#define SC_ABORT 0x06 +#define SC_MSG_REJECT 0x07 +#define SC_NO_OP 0x08 +#define SC_PARITY 0x09 +#define SC_IDENTIFY 0x80 +#define SC_DR_IDENTIFY 0xc0 +#define SC_DEVICE_RESET 0x0c + +#define SC_G0_CDBLEN 6 /* Len of Group 0 commands */ +#define SC_G1_CDBLEN 10 /* Len of Group 1 commands */ +#define SC_G5_CDBLEN 12 /* Len of Group 5 commands */ + +#define SCG_MAX_CMD 24 /* 24 bytes max. size is supported */ +#define SCG_MAX_STATUS 3 /* XXX (sollte 4 allign.) Mamimum Status Len */ +#define SCG_MAX_SENSE 32 /* Mamimum Sense Len for auto Req. Sense */ + +#define DEF_SENSE_LEN 16 /* Default Sense Len */ +#define CCS_SENSE_LEN 18 /* Sense Len for CCS compatible devices */ + +struct usal_cmd { + caddr_t addr; /* Address of data in user space */ + int size; /* DMA count for data transfer */ + int flags; /* see below for definition */ + int cdb_len; /* Size of SCSI command in bytes */ + /* NOTE: rel 4 uses this field only */ + /* with commands not in group 1 or 2*/ + int sense_len; /* for intr() if -1 don't get sense */ + int timeout; /* timeout in seconds */ + /* NOTE: actual resolution depends */ + /* on driver implementation */ + int kdebug; /* driver kernel debug level */ + int resid; /* Bytes not transfered */ + int error; /* Error code from usalintr() */ + int ux_errno; /* UNIX error code */ +#ifdef comment +XXX struct scsi_status scb; ??? /* Status returnd by command */ +#endif + union { + struct scsi_status Scb; /* Status returnd by command */ + Uchar cmd_scb[SCG_MAX_STATUS]; + } u_scb; +#define scb u_scb.Scb +#ifdef comment +XXX struct scsi_sense sense; ??? /* Sense bytes from command */ +#endif + union { + struct scsi_sense Sense; /* Sense bytes from command */ + Uchar cmd_sense[SCG_MAX_SENSE]; + } u_sense; +#define sense u_sense.Sense + int sense_count; /* Number of bytes valid in sense */ + int target; /* SCSI target id */ + /* NOTE: The SCSI target id field */ + /* does not need to be filled unless */ + /* the low level transport is a real */ + /* usal driver. In this case the low */ + /* level transport routine of libusal */ + /* will fill in the needed value */ + union { /* SCSI command descriptor block */ + struct scsi_g0cdb g0_cdb; + struct scsi_g1cdb g1_cdb; + struct scsi_g5cdb g5_cdb; + Uchar cmd_cdb[SCG_MAX_CMD]; + } cdb; /* 24 bytes max. size is supported */ +}; + +#define dma_read flags /* 1 if DMA to Sun, 0 otherwise */ + +/* + * definition for flags field in usal_cmd struct + */ +#define SCG_RECV_DATA 0x0001 /* DMA direction to Sun */ +#define SCG_DISRE_ENA 0x0002 /* enable disconnect/reconnect */ +#define SCG_SILENT 0x0004 /* be silent on errors */ +#define SCG_CMD_RETRY 0x0008 /* enable retries */ +#define SCG_NOPARITY 0x0010 /* disable parity for this command */ + +/* + * definition for error field in usal_cmd struct + * + * The codes refer to SCSI general errors, not to device + * specific errors. Device specific errors are discovered + * by checking the sense data. + * The distinction between retryable and fatal is somewhat ad hoc. + */ +#define SCG_NO_ERROR 0 /* cdb transported without error */ + /* SCG_NO_ERROR incudes all commands */ + /* where the SCSI status is valid */ + +#define SCG_RETRYABLE 1 /* any other case e.g. SCSI bus busy */ + /* SCSI cdb could not be send, */ + /* includes DMA errors other than */ + /* DMA underrun */ + +#define SCG_FATAL 2 /* could not select target */ +#define SCG_TIMEOUT 3 /* driver timed out */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCGCMD_H */ diff --git a/libusal/usal/usalio.h b/libusal/usal/usalio.h new file mode 100644 index 0000000..7624775 --- /dev/null +++ b/libusal/usal/usalio.h @@ -0,0 +1,79 @@ +/* + * 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. + * + */ + +/* @(#)usalio.h 2.16 00/11/07 Copyright 1986 J. Schilling */ +/* + * Definitions for the SCSI general driver 'usal' + * + * Copyright (c) 1986 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. + */ + +#ifndef _SCG_SCGIO_H +#define _SCG_SCGIO_H + +#ifndef _SCG_SCGCMD_H +#include <usal/usalcmd.h> +#endif + +#if defined(SVR4) +#include <sys/ioccom.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__STDC__) || defined(SVR4) +#define SCGIOCMD _IOWR('G', 1, struct usal_cmd) /* do a SCSI cmd */ +#define SCGIORESET _IO('G', 2) /* reset SCSI bus */ +#define SCGIOGDISRE _IOR('G', 4, int) /* get sc disre Val*/ +#define SCGIOSDISRE _IOW('G', 5, int) /* set sc disre Val*/ +#define SCGIOIDBG _IO('G', 100) /* Inc Debug Val */ +#define SCGIODDBG _IO('G', 101) /* Dec Debug Val */ +#define SCGIOGDBG _IOR('G', 102, int) /* get Debug Val */ +#define SCGIOSDBG _IOW('G', 103, int) /* set Debug Val */ +#define SCIOGDBG _IOR('G', 104, int) /* get sc Debug Val*/ +#define SCIOSDBG _IOW('G', 105, int) /* set sc Debug Val*/ +#else +#define SCGIOCMD _IOWR(G, 1, struct usal_cmd) /* do a SCSI cmd */ +#define SCGIORESET _IO(G, 2) /* reset SCSI bus */ +#define SCGIOGDISRE _IOR(G, 4, int) /* get sc disre Val*/ +#define SCGIOSDISRE _IOW(G, 5, int) /* set sc disre Val*/ +#define SCGIOIDBG _IO(G, 100) /* Inc Debug Val */ +#define SCGIODDBG _IO(G, 101) /* Dec Debug Val */ +#define SCGIOGDBG _IOR(G, 102, int) /* get Debug Val */ +#define SCGIOSDBG _IOW(G, 103, int) /* set Debug Val */ +#define SCIOGDBG _IOR(G, 104, int) /* get sc Debug Val*/ +#define SCIOSDBG _IOW(G, 105, int) /* set sc Debug Val*/ +#endif + +#define SCGIO_CMD SCGIOCMD /* backward ccompatibility */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCGIO_H */ diff --git a/libusal/usal/usalops.h b/libusal/usal/usalops.h new file mode 100644 index 0000000..5e367a6 --- /dev/null +++ b/libusal/usal/usalops.h @@ -0,0 +1,85 @@ +/* + * 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. + * + */ + +/* @(#)usalops.h 1.5 02/10/19 Copyright 2000 J. Schilling */ +/* + * Copyright (c) 2000 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. + */ + +#ifndef _SCG_SCGOPS_H +#define _SCG_SCGOPS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct usal_ops { + int (*usalo_send)(SCSI *usalp); + + char * (*usalo_version)(SCSI *usalp, int what); +#ifdef EOF /* stdio.h has been included */ + int (*usalo_help)(SCSI *usalp, FILE *f); +#else + int (*usalo_help)(SCSI *usalp, void *f); +#endif + int (*usalo_open)(SCSI *usalp, char *device); + int (*usalo_close)(SCSI *usalp); + long (*usalo_maxdma)(SCSI *usalp, long amt); + void * (*usalo_getbuf)(SCSI *usalp, long amt); + void (*usalo_freebuf)(SCSI *usalp); + + + BOOL (*usalo_havebus)(SCSI *usalp, int busno); + int (*usalo_fileno)(SCSI *usalp, int busno, int tgt, int tlun); + + int (*usalo_initiator_id)(SCSI *usalp); + int (*usalo_isatapi)(SCSI *usalp); + int (*usalo_reset)(SCSI *usalp, int what); + + char * (*usalo_natname)(SCSI *usalp, int busno, int tgt, int tlun); +} usal_ops_t; + +#define SCGO_SEND(usalp) (*(usalp)->ops->usalo_send)(usalp) +#define SCGO_VERSION(usalp, what) (*(usalp)->ops->usalo_version)(usalp, what) +#define SCGO_HELP(usalp, f) (*(usalp)->ops->usalo_help)(usalp, f) +#define SCGO_OPEN(usalp, device) (*(usalp)->ops->usalo_open)(usalp, device) +#define SCGO_CLOSE(usalp) (*(usalp)->ops->usalo_close)(usalp) +#define SCGO_MAXDMA(usalp, amt) (*(usalp)->ops->usalo_maxdma)(usalp, amt) +#define SCGO_GETBUF(usalp, amt) (*(usalp)->ops->usalo_getbuf)(usalp, amt) +#define SCGO_FREEBUF(usalp) (*(usalp)->ops->usalo_freebuf)(usalp) +#define SCGO_HAVEBUS(usalp, busno) (*(usalp)->ops->usalo_havebus)(usalp, busno) +#define SCGO_FILENO(usalp, busno, tgt, tlun) (*(usalp)->ops->usalo_fileno)(usalp, busno, tgt, tlun) +#define SCGO_INITIATOR_ID(usalp) (*(usalp)->ops->usalo_initiator_id)(usalp) +#define SCGO_ISATAPI(usalp) (*(usalp)->ops->usalo_isatapi)(usalp) +#define SCGO_RESET(usalp, what) (*(usalp)->ops->usalo_reset)(usalp, what) + +extern int usal_fileno(SCSI *usalp, int busno, int tgt, int tlun); +extern char * usal_natname(SCSI *usalp, int busno, int tgt, int tlun); +#ifdef __cplusplus +} +#endif + +#endif /* _SCG_SCGOPS_H */ diff --git a/libusal/usalsettarget.c b/libusal/usalsettarget.c new file mode 100644 index 0000000..009805c --- /dev/null +++ b/libusal/usalsettarget.c @@ -0,0 +1,58 @@ +/* + * 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. + * + */ + +/* @(#)usalsettarget.c 1.2 04/01/14 Copyright 2000 J. Schilling */ +/* + * usal Library + * set target SCSI address + * + * This is the only place in libusal that is allowed to assign + * values to the usal address structure. + * + * Copyright (c) 2000 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 <standard.h> +#include <schily.h> + +#include <usal/scsitransp.h> + +int usal_settarget(SCSI *usalp, int, int, int); + +int +usal_settarget(SCSI *usalp, int busno, int tgt, int tlun) +{ + int fd = -1; + + if (usalp->ops != NULL) + fd = SCGO_FILENO(usalp, busno, tgt, tlun); + usalp->fd = fd; + usal_scsibus(usalp) = busno; + usal_target(usalp) = tgt; + usal_lun(usalp) = tlun; + return (fd); +} diff --git a/libusal/usaltimes.c b/libusal/usaltimes.c new file mode 100644 index 0000000..d8e28d7 --- /dev/null +++ b/libusal/usaltimes.c @@ -0,0 +1,60 @@ +/* + * 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. + * + */ + +/* @(#)usaltimes.c 1.1 00/08/25 Copyright 1995,2000 J. Schilling */ +/* + * SCSI user level command timing + * + * Copyright (c) 1995,2000 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 <standard.h> +#include <timedefs.h> +#include <schily.h> + +#include <usal/scsitransp.h> +#include "usaltimes.h" + +void __usal_times(SCSI *usalp); + +/* + * We don't like to make this a public interface to prevent bad users + * from making our timing incorrect. + */ +void +__usal_times(SCSI *usalp) +{ + struct timeval *stp = usalp->cmdstop; + + gettimeofday(stp, (struct timezone *)0); + stp->tv_sec -= usalp->cmdstart->tv_sec; + stp->tv_usec -= usalp->cmdstart->tv_usec; + while (stp->tv_usec < 0) { + stp->tv_sec -= 1; + stp->tv_usec += 1000000; + } +} diff --git a/libusal/usaltimes.h b/libusal/usaltimes.h new file mode 100644 index 0000000..cf0a207 --- /dev/null +++ b/libusal/usaltimes.h @@ -0,0 +1,34 @@ +/* + * 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. + * + */ + +/* @(#)usaltimes.h 1.1 00/08/25 Copyright 1995,2000 J. Schilling */ +/* + * SCSI user level command timing + * + * Copyright (c) 1995,2000 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. + */ + +extern void __usal_times(SCSI *usalp); diff --git a/misc/MKNOD.hpux b/misc/MKNOD.hpux new file mode 100755 index 0000000..92f812a --- /dev/null +++ b/misc/MKNOD.hpux @@ -0,0 +1,59 @@ +#!/bin/sh +################################################################ +# make SCSI device files according to: man scsi_ctl +# +# Copyright (c) 1997 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. +################################################################ + +mknod="echo mknod" +mkdir="echo mkdir -p" +chmod="echo chmod" + +mknod="/usr/sbin/mknod" +mkdir="mkdir -p" +chmod="chmod" + +scsi=/dev/scsi +rscsi=/dev/rscsi + +${mkdir} ${scsi} +${mkdir} ${rscsi} + +bus=0 +target=0 +lun=0 + +for bus in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do + for target in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do + for lun in 0 1 2 3 4 5 6 7; do +# +# Newer HP-UX versions seem to have +# /dev/rscsi/citxdy +# but it uses the "non-raw" interface type +# dev=c${bus}t${target}d${lun} +# We follow the HP-UX documentation and create +# /dev/rscsi/citxty with the raw bit set + + dev=c${bus}t${target}l${lun} + + $mknod ${scsi}/${dev} c 203 0x${bus}${target}${lun}00 + $chmod 0600 ${scsi}/${dev} + + $mknod ${rscsi}/${dev} c 203 0x${bus}${target}${lun}02 + $chmod 0600 ${rscsi}/${dev} + done + done +done diff --git a/misc/MKNOD.hpux-800 b/misc/MKNOD.hpux-800 new file mode 100755 index 0000000..f439412 --- /dev/null +++ b/misc/MKNOD.hpux-800 @@ -0,0 +1,92 @@ +#!/bin/sh +################################################################ +# mk node boot script for HP9000 800 series following man scsi_pt +# +# This script is provided WITHOUT ANY WARRANTY. +################################################################ + +PATH=/sbin:/usr/sbin:/usr/bin:. +export PATH + +case $1 in + +start_msg) + echo "Creating SCSI passthru (spt) driver nodes" + ;; + +stop_msg) + echo "Removing SCSI passthru (spt) driver nodes" + ;; + +start) + + hpser=`uname -m | awk -F / '{print substr($2, 1, 1);}'` + if [ $hpser -ne "8" ]; then + echo "spt driver only needed on HP 9000/800 series." + exit 0 + fi + + #mknod="echo mknod" + #mkdir="echo mkdir -p" + #chmod="echo chmod" + + mknod="/usr/sbin/mknod" + mkdir="mkdir -p" + chmod="chmod" + + sptlist="/tmp/spt.$$" + echo "Searching SCSI passthru drivers (spt) ..." + ioscan -kf -d spt | sed '1,2d' | awk '{print $3;}' > $sptlist + nctl=`wc -l < $sptlist` + echo "... found $nctl" + + if [ ! -s $sptlist ]; then + rm -f $sptlist + exit 0 + fi + + scsi=/dev/scsi + ${mkdir} ${scsi} + + rscsi=/dev/rscsi + ${mkdir} ${rscsi} + + cmajor=`lsdev -h -d spt | awk '{print $1;}'` + + for line in `cat $sptlist` ; do + + ctl=`echo $line | awk -F . '{print $1;}'` + bus=`ioscan -f -k -H $ctl -C ext_bus | sed '1,2d' | awk '{print $2;}'` + tgt=`echo $line | awk -F . '{print $2;}'` + hextgt=`printf "%x" $tgt` + + # make first scsi nodes + name="${scsi}/c${bus}t${tgt}l0" + echo "Creating $name" + ${mknod} $name c $cmajor 0x${bus}${hextgt}000 > /dev/null 2>&1 + ${chmod} 0600 $name > /dev/null 2>&1 + + # then rscsi nodes + rname="${rscsi}/c${bus}t${tgt}l0" + echo "Creating $rname" + # Old version, not working! + #${mknod} $rname c $cmajor 0x${bus}${hextgt}020 > /dev/null 2>&1 + ${mknod} $rname c $cmajor 0x${bus}${hextgt}000 > /dev/null 2>&1 + ${chmod} 0600 $rname > /dev/null 2>&1 + done + + rm -f $sptlist + exit 0 + + ;; + +stop) + ;; + +*) + echo usage: $0 "{start|stop}" + ;; +esac + +exit 0 + diff --git a/misc/burnstuff b/misc/burnstuff new file mode 100755 index 0000000..ce3cf82 --- /dev/null +++ b/misc/burnstuff @@ -0,0 +1,25 @@ +#!/bin/sh +# (C) Eduard Bloch, License: BSD, 3-clause +# very simple script to burn files on-the-fly in SAO mode; +# either from a certain directory, or from a list with graft-points +# ISO name is generated from the basename of the list/directory + +set -e + +case "$1" in + *.list) + name=${1%.list} + set -- -D -graft-points -path-list "$1" + ;; + *) + name="$1" + ;; +esac + +MOPTS=${MOPTS:-" -joliet-long -r -q -f -V $name "} +COPTS=${COPTS:-" fs=64m gracetime=5 -v -sao speed=16 -eject -multi -v -force - "} + +SIZE=$(genisoimage $MOPTS -print-size "$@")s + +echo "genisoimage $MOPTS $@ | wodim tsize=$SIZE $COPTS" +genisoimage $MOPTS "$@" | wodim tsize=$SIZE $COPTS diff --git a/misc/make_diskt@2.sh b/misc/make_diskt@2.sh new file mode 100644 index 0000000..a93c8ed --- /dev/null +++ b/misc/make_diskt@2.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# exit on all errors +set -e + +if [ ! -f "$1" ];then + echo "Usage: `basename $0` [imagefile.ext] [-o|-i]" + echo "-o will make the bottom of the image be on the outside of the disk" + echo "-i will make the bottom of the image be on the inside of the disk" + echo + echo "Image must be greyscale" + echo + echo "make sure the imagefile has the right x-y format" + echo "run cdrecord driveropts=tattooinfo -checkdrive" + echo "to find out" + exit 1 +fi + + +case "$2" in + -i) + convopts="-flip" + ;; + -o) + convopts="-flop" + ;; + *) + echo "error: arg2 must be -o or -i" + exit 1 + ;; +esac + +echo "Make sure the imagefile has the right size" +echo "run cdrecord dev=a,b,c driveropts=tattooinfo -checkdrive" +echo "to find out" +echo +echo -n "Converting $1 to disktattoo_image format: " + +## convert it tp ppm format +## note.. -flop = flip horizontally +convert $convopts "$1" "$1-TMP-$$.ppm" + +## We only need the data, which is the last line in a ppm file +## tail works mighty fine for this (insert evil dirty-coder-laughter here) +tail -n+4 "$1-TMP-$$.ppm" > "$1.disktattoo_image" + +## clean up like a good boy +rm "$1-TMP-$$.ppm" + +## notify user that we're done converting +echo "done" +echo + +## stop with stupid code commenting +echo "You may now burn '$1.disktattoo_image' to your cd with the command:" +echo "cdrecord driveropts=tattoofile=\"$1.disktattoo_image\" -checkdrive" diff --git a/misc/rc.pp b/misc/rc.pp new file mode 100755 index 0000000..734cfd5 --- /dev/null +++ b/misc/rc.pp @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Note: The adapter shell var must updated in order to reflect your actual hardware. +# The current value "friq" is the right value for the FreeCom PP adapter. +# See paride documentation for the list of other drivers. +# +adapter=friq + +case "$1" in + +'start') + echo "Starting Parallel Port IDE/ATAPI" + modprobe paride + modprobe "$adapter" +# modprobe pg +# modprobe pg verbose=2 drive0=0x378,0,0,-1,-1,0 + modprobe pg verbose=0 drive0=0x378,0,0,-1,-1,0 + ;; + +'stop') + echo "Stopping Parallel Port IDE/ATAPI" + rmmod pg + rmmod "$adapter" + rmmod paride + ;; + +*) + echo "Usage: rc.pp start|stop" +esac + +exit + +############################################################################### +When you load pg, you need to specify some parameters like: + + drive0=0x378,0,0,4,0,0 + +The parameters are: + + <prt>,<pro>,<uni>,<mod>,<slv>,<dly> + + Where, + + <prt> is the base of the parallel port address for + the corresponding drive. (required) + + <pro> is the protocol number for the adapter that + supports this drive. These numbers are + logged by 'paride' when the protocol modules + are initialised. (0 if not given) + + <uni> for those adapters that support chained + devices, this is the unit selector for the + chain of devices on the given port. It should + be zero for devices that don't support chaining. + (0 if not given) + + <mod> this can be -1 to choose the best mode, or one + of the mode numbers supported by the adapter. + (-1 if not given) + + <slv> ATAPI devices can be jumpered to master or slave. + Set this to 0 to choose the master drive, 1 to + choose the slave, -1 (the default) to choose the + first drive found. + + <dly> some parallel ports require the driver to + go more slowly. -1 sets a default value that + should work with the chosen protocol. Otherwise, + set this to a small integer, the larger it is + the slower the port i/o. In some cases, setting + this to zero will speed up the device. (default -1) + +EPP mode is best. Your BIOS may not give you that option, unfortunately. +What options does it support ? diff --git a/misc/shared_lib_patch_incomplete.diff b/misc/shared_lib_patch_incomplete.diff new file mode 100644 index 0000000..7921305 --- /dev/null +++ b/misc/shared_lib_patch_incomplete.diff @@ -0,0 +1,138 @@ +Index: wodim/CMakeLists.txt +=================================================================== +--- wodim/CMakeLists.txt (Revision 579) ++++ wodim/CMakeLists.txt (Arbeitskopie) +@@ -21,7 +21,17 @@ + + ADD_DEFINITIONS(-DHAVE_LIB_EDC_ECC -DCLONE_WRITE) + +-ADD_EXECUTABLE (wodim ${CDRECORD_SRCS}) ++SET(CDRECORD_SRCS wodim.c audiosize.c auinfo.c cdr_drv.c cdtext.c clone.c crc16.c cue.c diskid.c drv_7501.c drv_jvc.c drv_mmc.c drv_philips.c drv_simul.c drv_sony.c fifo.c isosize.c scsi_cdr_mmc4.c scsi_mmc4.c sector.c subchan.c wm_packet.c wm_session.c wm_track.c xio.c) ++SET(CDRECORD_COMMON_SRCS cd_misc.c defaults.c getnum.c misc.c modes.c movesect.c scsi_cdr.c scsi_mmc.c scsi_scan.c) ++ ++IF(SHLIB_STYLE) ++ ADD_EXECUTABLE (wodim ${CDRECORD_SRCS}) ++ ADD_LIBRARY (wodimstuff SHARED ${CDRECORD_COMMON_SRCS}) ++ LIST(APPEND EXTRA_LIBS wodimstuff) ++ELSE(SHLIB_STYLE) ++ ADD_EXECUTABLE (wodim ${CDRECORD_SRCS} ${CDRECORD_COMMON_SRCS}) ++ENDIF(SHLIB_STYLE) ++ + TARGET_LINK_LIBRARIES(wodim ${EXTRA_LIBS} deflt edc) + SET_TARGET_PROPERTIES(wodim PROPERTIES SKIP_BUILD_RPATH TRUE) + +Index: genisoimage/CMakeLists.txt +=================================================================== +--- genisoimage/CMakeLists.txt (Revision 579) ++++ genisoimage/CMakeLists.txt (Arbeitskopie) +@@ -27,6 +27,13 @@ + + SET(MKISOFS_MOST_SRCS apple.c boot.c cd_misc.c defaults.c desktop.c dvd_file.c dvd_reader.c eltorito.c exclude.c files.c fnmatch.c getnum.c hash.c ifo_read.c joliet.c mac_label.c match.c modes.c multi.c name.c rock.c scsi.c scsi_cdr.c stream.c tree.c udf.c vms.c volume.c write.c boot-alpha.c boot-hppa.c boot-mips.c md5.c jte.c rsync.c + boot-mipsel.c endian.c ) ++ ++IF(SHLIB_STYLE) ++ SET(MKISOFS_MOST_SRCS apple.c boot.c cd_misc.c defaults.c desktop.c dvd_file.c dvd_reader.c eltorito.c exclude.c files.c fnmatch.c getnum.c hash.c ifo_read.c joliet.c mac_label.c match.c modes.c multi.c name.c rock.c scsi.c scsi_cdr.c stream.c tree.c udf.c vms.c volume.c write.c boot-alpha.c boot-hppa.c boot-mips.c md5.c jte.c rsync.c ++ boot-mipsel.c endian.c ) ++ LIST ( APPEND EXTRA_LIBS wodimstuff ) ++ message(FATAL_ERROR "fixme, half done, see experimental branch, needs to change other tools to libwodimstuff, etc.") ++ENDIF(SHLIB_STYLE) + + INCLUDE(CheckFunctionExists) + SET(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) +@@ -37,7 +44,7 @@ + + + #SET_SOURCE_FILES_PROPERTIES(${MKISOFS_MOST_SRCS} PROPERTIES ) +-LINK_DIRECTORIES(../libhfs_iso ../librols ../libusal ../libunls ../libdeflt) ++LINK_DIRECTORIES(../libhfs_iso ../librols ../libusal ../libunls ../libdeflt ../wodim) + + ADD_EXECUTABLE (genisoimage genisoimage.c ${MKISOFS_MOST_SRCS}) + TARGET_LINK_LIBRARIES(genisoimage hfs_iso deflt ${MAGICLIBS} c unls z ${EXTRA_LIBICONV} ${EXTRA_LIBS}) +Index: libusal/CMakeLists.txt +=================================================================== +--- libusal/CMakeLists.txt (Revision 579) ++++ libusal/CMakeLists.txt (Arbeitskopie) +@@ -6,5 +6,9 @@ + #SET(LIBSCG_SRCS rdummy.c usalsettarget.c usaltimes.c scsi-linux-ata.c scsi-linux-pg.c scsi-linux-sg.c scsierrs.c scsihack.c scsihelp.c scsiopen.c scsitransp.c) + SET(LIBSCG_SRCS usalsettarget.c usaltimes.c scsierrs.c scsihack.c scsihelp.c scsiopen.c scsitransp.c scsi-remote.c) + LINK_DIRECTORIES(../librols) ++IF(SHLIB_STYLE) ++ADD_LIBRARY (usal SHARED ${LIBSCG_SRCS}) ++ELSE(SHLIB_STYLE) + ADD_LIBRARY (usal STATIC ${LIBSCG_SRCS}) ++ENDIF(SHLIB_STYLE) + TARGET_LINK_LIBRARIES(usal ${SCG_SELF_LIBS}) +Index: misc/shared_lib_patch_incomplete.diff +=================================================================== +--- misc/shared_lib_patch_incomplete.diff (Revision 579) ++++ misc/shared_lib_patch_incomplete.diff (Arbeitskopie) +@@ -1,31 +1,29 @@ + Index: wodim/CMakeLists.txt + =================================================================== +---- wodim/CMakeLists.txt (Revision 556) ++--- wodim/CMakeLists.txt (Revision 579) + +++ wodim/CMakeLists.txt (Arbeitskopie) +-@@ -21,8 +21,18 @@ ++@@ -21,7 +21,17 @@ + + ADD_DEFINITIONS(-DHAVE_LIB_EDC_ECC -DCLONE_WRITE) + + -ADD_EXECUTABLE (wodim ${CDRECORD_SRCS}) +--TARGET_LINK_LIBRARIES(wodim ${EXTRA_LIBS} deflt edc) +++SET(CDRECORD_SRCS wodim.c audiosize.c auinfo.c cdr_drv.c cdtext.c clone.c crc16.c cue.c diskid.c drv_7501.c drv_jvc.c drv_mmc.c drv_philips.c drv_simul.c drv_sony.c fifo.c isosize.c scsi_cdr_mmc4.c scsi_mmc4.c sector.c subchan.c wm_packet.c wm_session.c wm_track.c xio.c) +++SET(CDRECORD_COMMON_SRCS cd_misc.c defaults.c getnum.c misc.c modes.c movesect.c scsi_cdr.c scsi_mmc.c scsi_scan.c) + + + +IF(SHLIB_STYLE) +-+ SET(CDRECORD_SRCS wodim.c audiosize.c auinfo.c cdr_drv.c cdtext.c clone.c crc16.c cue.c diskid.c drv_7501.c drv_jvc.c drv_mmc.c drv_philips.c drv_simul.c drv_sony.c fifo.c isosize.c scsi_cdr_mmc4.c scsi_mmc4.c sector.c subchan.c wm_packet.c wm_session.c wm_track.c xio.c) +-+ SET(CDRECORD_COMMON_SRCS cd_misc.c defaults.c getnum.c misc.c modes.c movesect.c scsi_cdr.c scsi_mmc.c scsi_scan.c) + + ADD_EXECUTABLE (wodim ${CDRECORD_SRCS}) + + ADD_LIBRARY (wodimstuff SHARED ${CDRECORD_COMMON_SRCS}) +-+ TARGET_LINK_LIBRARIES(wodim ${EXTRA_LIBS} deflt edc wodimstuff) +++ LIST(APPEND EXTRA_LIBS wodimstuff) + +ELSE(SHLIB_STYLE) +-+ ADD_EXECUTABLE (wodim ${CDRECORD_SRCS}) +-+ TARGET_LINK_LIBRARIES(wodim ${EXTRA_LIBS} deflt edc) +++ ADD_EXECUTABLE (wodim ${CDRECORD_SRCS} ${CDRECORD_COMMON_SRCS}) + +ENDIF(SHLIB_STYLE) + + ++ TARGET_LINK_LIBRARIES(wodim ${EXTRA_LIBS} deflt edc) + SET_TARGET_PROPERTIES(wodim PROPERTIES SKIP_BUILD_RPATH TRUE) + +- INSTALL(TARGETS wodim DESTINATION bin) + Index: genisoimage/CMakeLists.txt + =================================================================== +---- genisoimage/CMakeLists.txt (Revision 556) ++--- genisoimage/CMakeLists.txt (Revision 579) + +++ genisoimage/CMakeLists.txt (Arbeitskopie) + @@ -27,6 +27,13 @@ + +@@ -52,7 +50,7 @@ + TARGET_LINK_LIBRARIES(genisoimage hfs_iso deflt ${MAGICLIBS} c unls z ${EXTRA_LIBICONV} ${EXTRA_LIBS}) + Index: libusal/CMakeLists.txt + =================================================================== +---- libusal/CMakeLists.txt (Revision 556) ++--- libusal/CMakeLists.txt (Revision 579) + +++ libusal/CMakeLists.txt (Arbeitskopie) + @@ -6,5 +6,9 @@ + #SET(LIBSCG_SRCS rdummy.c usalsettarget.c usaltimes.c scsi-linux-ata.c scsi-linux-pg.c scsi-linux-sg.c scsierrs.c scsihack.c scsihelp.c scsiopen.c scsitransp.c) +@@ -64,20 +62,3 @@ + ADD_LIBRARY (usal STATIC ${LIBSCG_SRCS}) + +ENDIF(SHLIB_STYLE) + TARGET_LINK_LIBRARIES(usal ${SCG_SELF_LIBS}) +-Index: librols/CMakeLists.txt +-=================================================================== +---- librols/CMakeLists.txt (Revision 556) +-+++ librols/CMakeLists.txt (Arbeitskopie) +-@@ -1,7 +1,11 @@ +- PROJECT (LIBROLS) +- INCLUDE_DIRECTORIES(../include ../libhfs_iso ${CMAKE_BINARY_DIR} ../wodim) +- +--SET(LIBROLS_SRCS astoi.c astoll.c astoull.c breakline.c cmpbytes.c comerr.c error.c fexec.c fillbytes.c getargs.c getav0.c getdomainname.c geterrno.c gethostid.c gethostname.c getpagesize.c handlecond.c movebytes.c raisecond.c rename.c saveargs.c seterrno.c spawn.c strcatl.c strdup.c streql.c swabbytes.c usleep.c stdio/cvmod.c stdio/dat.c stdio/fcons.c stdio/fcons64.c stdio/fdown.c stdio/fdup.c stdio/fdup64.c stdio/ffileread.c stdio/ffilewrite.c stdio/fgetline.c stdio/file_raise.c stdio/fileclose.c stdio/fileluopen.c stdio/fileluopen64.c stdio/filemopen.c stdio/filemopen64.c stdio/fileopen.c stdio/fileopen64.c stdio/filepos.c stdio/filepos64.c stdio/fileread.c stdio/filereopen.c stdio/filereopen64.c stdio/fileseek.c stdio/fileseek64.c stdio/filesize.c stdio/filesize64.c stdio/filestat.c stdio/filestat64.c stdio/filewrite.c stdio/flag.c stdio/flush.c stdio/fpipe.c stdio/niread.c stdio/niwrite.c stdio/nixread.c stdio/nixwrite.c stdio/openfd.c stdio/openfd64.c stdio/peekc.c ) +-+SET(LIBROLS_SRCS astoi.c astoll.c astoull.c breakline.c cmpbytes.c comerr.c error.c fexec.c fillbytes.c getargs.c getav0.c getdomainname.c geterrno.c gethostid.c gethostname.c getpagesize.c handlecond.c movebytes.c raisecond.c rename.c saveargs.c seterrno.c spawn.c strcatl.c strdup.c streql.c swabbytes.c usleep.c stdio/cvmod.c stdio/dat.c stdio/fcons.c stdio/fdown.c stdio/fdup.c stdio/ffileread.c stdio/ffilewrite.c stdio/fgetline.c stdio/file_raise.c stdio/fileclose.c stdio/fileluopen.c stdio/filemopen.c stdio/fileopen.c stdio/filepos.c stdio/fileread.c stdio/filereopen.c stdio/fileseek.c stdio/filesize.c stdio/filestat.c stdio/filewrite.c stdio/flag.c stdio/flush.c stdio/fpipe.c stdio/niread.c stdio/niwrite.c stdio/nixread.c stdio/nixwrite.c stdio/openfd.c stdio/peekc.c ) +- +-+IF(SHLIB_STYLE) +-+ADD_LIBRARY (rols SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../include/xconfig.h ${CMAKE_CURRENT_SOURCE_DIR}/../include/align.h ${LIBROLS_SRCS}) +-+ELSE(SHLIB_STYLE) +- ADD_LIBRARY (rols STATIC ${CMAKE_CURRENT_SOURCE_DIR}/../include/xconfig.h ${CMAKE_CURRENT_SOURCE_DIR}/../include/align.h ${LIBROLS_SRCS}) +-+ENDIF(SHLIB_STYLE) +- diff --git a/netscsid/CMakeLists.txt b/netscsid/CMakeLists.txt new file mode 100644 index 0000000..f6bddf1 --- /dev/null +++ b/netscsid/CMakeLists.txt @@ -0,0 +1,13 @@ +PROJECT (netscsid C) +INCLUDE_DIRECTORIES(../include ../wodim ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +INCLUDE(../include/AddScgBits.cmake) +INCLUDE(../include/AddSchilyBits.cmake) +INCLUDE(../include/AddNetworkBits.cmake) + +LINK_DIRECTORIES(../librols ../libusal ) +ADD_EXECUTABLE (netscsid netscsid.c) +#SET_SOURCE_FILES_PROPERTIES(netscsid.c ) +TARGET_LINK_LIBRARIES(netscsid ${EXTRA_LIBS} ) +#SET_TARGET_PROPERTIES(netscsid PROPERTIES SKIP_BUILD_RPATH TRUE) +INSTALL(TARGETS netscsid DESTINATION sbin) + diff --git a/netscsid/netscsid.c b/netscsid/netscsid.c new file mode 100644 index 0000000..df2f6b4 --- /dev/null +++ b/netscsid/netscsid.c @@ -0,0 +1,972 @@ +/* + * 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. + * + */ + +/* @(#)rscsi.c 1.29 05/05/16 Copyright 1994,2000-2002 J. Schilling*/ +/* + * Remote SCSI server + * + * Copyright (c) 1994,2000-2002 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. + */ + +/*#define FORCE_DEBUG*/ + +#include <mconfig.h> + +#include <stdio.h> +#include <stdxlib.h> +#include <unixstd.h> /* includes <sys/types.h> */ +#include <utypes.h> +#include <fctldefs.h> +#include <statdefs.h> +#include <strdefs.h> +#ifdef HAVE_SYS_SOCKET_H +#define USE_REMOTE +#include <sys/socket.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> /* BSD-4.2 & Linux need this for MAXHOSTNAMELEN */ +#endif +#include <errno.h> +#include <pwd.h> + +#include <standard.h> +#include <deflts.h> +#include <patmatch.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsitransp.h> + +#include <netinet/in.h> +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> /* BeOS does not have <arpa/inet.h> */ +#endif /* but inet_ntaoa() is in <netdb.h> */ +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif + +#ifdef USE_REMOTE +static void checkuser(void); +static char *getpeer(void); +static BOOL checktarget(void); +static void dorscsi(void); +static void scsiversion(void); +static void openscsi(void); +static void closescsi(void); +static void maxdma(void); +static void getbuf(void); +static void freebuf(void); +static void havebus(void); +static void scsifileno(void); +static void initiator_id(void); +static void isatapi(void); +static void scsireset(void); +static void sendcmd(void); + +static int fillrdbuf(void); +static int readchar(char *cp); + +static void readbuf(char *buf, int n); +static void voidarg(int n); +static void readarg(char *buf, int n); +static char *preparebuffer(int size); +static int checkscsi(char *decive); +static void rscsirespond(int ret, int err); +static void rscsireply(int ret); +static void rscsierror(int err, char *str, char *xstr); + +#define CMD_SIZE 80 + +static SCSI *scsi_ptr = NULL; +static char *Sbuf; +static long Sbufsize; + +static char *username; +static char *peername; + +static char *debug_name; +static FILE *debug_file; + +#define DEBUG(fmt) if (debug_file) fprintf(debug_file, fmt) +#define DEBUG1(fmt,a) if (debug_file) fprintf(debug_file, fmt, a) +#define DEBUG2(fmt,a1,a2) if (debug_file) fprintf(debug_file, fmt, a1, a2) +#define DEBUG3(fmt,a1,a2,a3) if (debug_file) fprintf(debug_file, fmt, a1, a2, a3) +#define DEBUG4(fmt,a1,a2,a3,a4) if (debug_file) fprintf(debug_file, fmt, a1, a2, a3, a4) +#define DEBUG5(fmt,a1,a2,a3,a4,a5) if (debug_file) fprintf(debug_file, fmt, a1, a2, a3, a4, a5) +#define DEBUG6(fmt,a1,a2,a3,a4,a5,a6) if (debug_file) fprintf(debug_file, fmt, a1, a2, a3, a4, a5, a6) +#endif /* USE_REMOTE */ + +int +main(int argc, char *argv[]) +{ + save_args(argc, argv); +#ifndef USE_REMOTE + comerrno(EX_BAD, "No remote SCSI support on this platform.\n"); +#else + argc--, argv++; + if (argc > 0 && strcmp(*argv, "-c") == 0) { + /* + * Skip params in case we have been installed as shell. + */ + argc--, argv++; + argc--, argv++; + } + /* + * WARNING you are only allowed to change the defaults configuration + * filename if you also change the documentation and add a statement + * that makes clear where the official location of the file is, why you + * did choose a nonstandard location and that the nonstandard location + * only refers to inofficial rscsi versions. + * + * I was forced to add this because some people change cdrecord without + * rational reason and then publish the result. As those people + * don't contribute work and don't give support, they are causing extra + * work for me and this way slow down the development. + */ + if (cfg_open("/etc/netscsid.conf") < 0) { + rscsierror(geterrno(), errmsgstr(geterrno()), + "Remote configuration error: Cannot open /etc/netscsid.conf"); +/* rscsirespond(-1, geterrno());*/ + exit(EX_BAD); + } + debug_name=cfg_get("DEBUG"); +#ifdef FORCE_DEBUG + if (debug_name == NULL && argc <= 0) + debug_name = "/tmp/RSCSI"; +#endif +#ifdef NONONO + /* + * Should we allow root to shoot himself into the foot? + * Allowing to write arbitrary files may be a security risk. + */ + if (argc > 0 && getuid() == 0) + debug_name = *argv; +#endif + + /* + * XXX If someone sets up debugging and allows the debug file to be + * XXX replaced by a symlink to e.g. /etc/passwd this would be a + * XXX security risk. But /etc/rscsi.conf is only writable by root + * XXX and for this reason a possible security risk would have been + * XXX introduced by the administrator. + */ + if (debug_name != NULL) { + /* Try to be careful when opening debug files, might be + * created in an unsafe location + * */ + int fd = open(debug_name, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0600); + if (fd > -1) + debug_file = fdopen(fd, "w"); + else { + rscsirespond(-1, geterrno()); + exit(EX_BAD); + } + } + + if (argc > 0) { + if (debug_file == 0) { + rscsirespond(-1, geterrno()); + exit(EX_BAD); + } + (void) setbuf(debug_file, (char *)0); + } + checkuser(); /* Check if we are called by a bad guy */ + peername = getpeer(); /* Get host name of caller */ + dorscsi(); +#endif /* USE_REMOTE */ + return (0); +} + +#ifdef USE_REMOTE +static void +checkuser() +{ + uid_t uid = getuid(); + char *uname; + struct passwd *pw; + + if (uid == 0) { + username = "root"; + DEBUG("rscsid: user id 0, name root\n"); + return; + } + pw = getpwuid(uid); + if (pw == NULL) + goto notfound; + + username = pw->pw_name; + DEBUG2("rscsid: user id %ld, name %s\n", (long)uid, username); + + cfg_restart(); + while ((uname = cfg_get_next("USER")) != NULL) { + if (0==strcmp(username, uname)) + return; + } +notfound: + DEBUG2("rscsid: Illegal user '%s' id %ld for RSCSI server\n", + username, (long)uid); + rscsierror(0, "Illegal user id for RSCSI server", NULL); + exit(EX_BAD); +} + +#ifndef NI_MAXHOST +#ifdef MAXHOSTNAMELEN /* XXX remove this and sys/param.h */ +#define NI_MAXHOST MAXHOSTNAMELEN +#else +#define NI_MAXHOST 64 +#endif +#endif + +static char * +getpeer() +{ +#ifdef HAVE_GETNAMEINFO +#ifdef HAVE_SOCKADDR_STORAGE + struct sockaddr_storage sa; +#else + char sa[256]; +#endif +#else + struct sockaddr sa; + struct hostent *he; +#endif + struct sockaddr *sap; + struct sockaddr_in *s; + socklen_t sasize = sizeof (sa); +static char buffer[NI_MAXHOST]; + + sap = (struct sockaddr *)&sa; + if (getpeername(STDIN_FILENO, sap, &sasize) < 0) { + int errsav = geterrno(); + struct stat sb; + + if (fstat(STDIN_FILENO, &sb) >= 0) { + if (S_ISFIFO(sb.st_mode)) { + DEBUG("rmt: stdin is a PIPE\n"); + return ("PIPE"); + } + DEBUG1("rscsid: stdin st_mode %0llo\n", (Llong)sb.st_mode); + } + + DEBUG1("rscsid: peername %s\n", errmsgstr(errsav)); + return ("ILLEGAL_SOCKET"); + } else { + s = (struct sockaddr_in *)&sa; +#ifdef AF_INET6 + if (s->sin_family != AF_INET && s->sin_family != AF_INET6) { +#else + if (s->sin_family != AF_INET) { +#endif +#ifdef AF_UNIX + /* + * AF_UNIX is not defined on BeOS + */ + if (s->sin_family == AF_UNIX) { + DEBUG("rmt: stdin is a PIPE (UNIX domain socket)\n"); + return ("PIPE"); + } +#endif + DEBUG1("rmt: stdin NOT_IP socket (sin_family: %d)\n", + s->sin_family); + return ("NOT_IP"); + } + +#ifdef HAVE_GETNAMEINFO + buffer[0] = '\0'; + if (debug_file && + getnameinfo(sap, sasize, buffer, sizeof (buffer), NULL, 0, + NI_NUMERICHOST) == 0) { + DEBUG1("rmt: peername %s\n", buffer); + } + buffer[0] = '\0'; + if (getnameinfo(sap, sasize, buffer, sizeof (buffer), NULL, 0, + 0) == 0) { + DEBUG1("rmt: peername %s\n", buffer); + return (buffer); + } + return ("CANNOT_MAP_ADDRESS"); +#else /* HAVE_GETNAMEINFO */ +#ifdef HAVE_INET_NTOA + (void) snprintf(buffer, sizeof(buffer), "%s", inet_ntoa(s->sin_addr)); +#else + (void) snprintf(buffer, sizeof(buffer), "%x", s->sin_addr.s_addr); +#endif + DEBUG1("rscsid: peername %s\n", buffer); + he = gethostbyaddr((char *)&s->sin_addr.s_addr, 4, AF_INET); + DEBUG1("rscsid: peername %s\n", he!=NULL?he->h_name:buffer); + if (he != NULL) + return (he->h_name); + return (buffer); +#endif /* HAVE_GETNAMEINFO */ + } +} + +static BOOL +checktarget() +{ + char *target; + char *user; + char *host; + char *p; + int bus; + int chan; + int tgt; + int lun; + + if (peername == NULL) + return (FALSE); + cfg_restart(); + while ((target = cfg_get_next("ACCESS")) != NULL) { + p = target; + while (*p == '\t') + p++; + user = p; + if ((p = strchr(p, '\t')) != NULL) + *p++ = '\0'; + else + continue; + if (0!=strcmp(username, user)) + continue; + + while (*p == '\t') + p++; + host = p; + if ((p = strchr(p, '\t')) != NULL) + *p++ = '\0'; + else + continue; + if (0!=strcmp(peername, host)) + continue; + + p = astoi(p, &bus); + if (*p != '\t') + continue; + p = astoi(p, &chan); + if (*p != '\t') + continue; + p = astoi(p, &tgt); + if (*p != '\t') + continue; + p = astoi(p, &lun); + + if (*p != '\t' && *p != '\n' && *p != '\r' && *p != '\0') + continue; + DEBUG6("ACCESS %s %s %d.%d,%d,%d\n", user, host, bus, chan, tgt, lun); + + if (bus != -1 && bus != usal_scsibus(scsi_ptr)) + continue; + if (tgt != -1 && tgt != usal_target(scsi_ptr)) + continue; + if (lun != -1 && lun != usal_lun(scsi_ptr)) + continue; + return (TRUE); + } + return (FALSE); +} + +static void +dorscsi() +{ + char c; + + while (readchar(&c) == 1) { + seterrno(0); + + switch (c) { + + case 'V': /* "V" ersion */ + scsiversion(); + break; + case 'O': /* "O" pen */ + openscsi(); + break; + case 'C': /* "C" lose */ + closescsi(); + break; + case 'D': /* "D" MA */ + maxdma(); + break; + case 'M': /* "M" alloc */ + getbuf(); + break; + case 'F': /* "F" free */ + freebuf(); + break; + case 'B': /* "B" us */ + havebus(); + break; + case 'T': /* "T" arget */ + scsifileno(); + break; + case 'I': /* "I" nitiator */ + initiator_id(); + break; + case 'A': /* "A" tapi */ + isatapi(); + break; + case 'R': /* "R" eset */ + scsireset(); + break; + case 'S': /* "S" end */ + sendcmd(); + break; + + default: + DEBUG1("rscsid: garbage command '%c'\n", c); + rscsierror(0, "Garbage command", NULL); + exit(EX_BAD); + } + } + exit(0); +} + +static void +scsiversion() +{ + int ret; + char *str; + char what[CMD_SIZE]; + + readarg(what, sizeof(what)); + DEBUG1("rscsid: V %s\n", what); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + str = usal_version(scsi_ptr, atoi(what)); + ret = strlen(str); + ret++; /* Include null char */ + rscsirespond(ret, geterrno()); + _nixwrite(STDOUT_FILENO, str, ret); +} + +static void +openscsi() +{ + char device[CMD_SIZE]; + char errstr[80]; + int debug = 0; + int lverbose = 0; + int ret = 0; + char rbuf[1600]; + + if (scsi_ptr != NULL) + (void) usal_close(scsi_ptr); + + readarg(device, sizeof(device)); + DEBUG1("rscsid: O %s\n", device); + if (strncmp(device, "REMOTE", 6) == 0) { + scsi_ptr = NULL; + seterrno(EINVAL); + } else if (!checkscsi(device)) { + scsi_ptr = NULL; + seterrno(EACCES); + } else { + scsi_ptr = usal_open(device, errstr, sizeof(errstr), debug, lverbose); + if (scsi_ptr == NULL) { + ret = -1; + } else { + scsi_ptr->silent = 1; + scsi_ptr->verbose = 0; + scsi_ptr->debug = 0; + scsi_ptr->kdebug = 0; + } + } + if (ret < 0) { + /* + * XXX This is currently the only place where we use the + * XXX extended error string. + */ + rscsierror(geterrno(), errmsgstr(geterrno()), errstr); +/* rscsirespond(ret, geterrno());*/ + return; + } + DEBUG4("rscsid:>A 0 %d.%d,%d,%d\n", + usal_scsibus(scsi_ptr), + 0, + usal_target(scsi_ptr), + usal_lun(scsi_ptr)); + + ret = snprintf(rbuf, sizeof(rbuf), "A0\n%d\n%d\n%d\n%d\n", + usal_scsibus(scsi_ptr), + 0, + usal_target(scsi_ptr), + usal_lun(scsi_ptr)); + (void) _nixwrite(STDOUT_FILENO, rbuf, ret); +} + +static void +closescsi() +{ + int ret; + char device[CMD_SIZE]; + + readarg(device, sizeof(device)); + DEBUG1("rscsid: C %s\n", device); + ret = usal_close(scsi_ptr); + rscsirespond(ret, geterrno()); + scsi_ptr = NULL; +} + +static void +maxdma() +{ + int ret; + char amt[CMD_SIZE]; + + readarg(amt, sizeof(amt)); + DEBUG1("rscsid: D %s\n", amt); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + ret = usal_bufsize(scsi_ptr, atol(amt)); + rscsirespond(ret, geterrno()); +} + +static void +getbuf() +{ + int ret = 0; + char amt[CMD_SIZE]; + + readarg(amt, sizeof(amt)); + DEBUG1("rscsid: M %s\n", amt); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + ret = usal_bufsize(scsi_ptr, atol(amt)); + if (preparebuffer(ret) == NULL) + ret = -1; + rscsirespond(ret, geterrno()); +} + +static void +freebuf() +{ + int ret = 0; + char dummy[CMD_SIZE]; + + readarg(dummy, sizeof(dummy)); + DEBUG1("rscsid: F %s\n", dummy); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + usal_freebuf(scsi_ptr); + Sbuf = NULL; + rscsirespond(ret, geterrno()); +} + +static void +havebus() +{ + int ret; + char bus[CMD_SIZE]; + char chan[CMD_SIZE]; + + readarg(bus, sizeof(bus)); + readarg(chan, sizeof(chan)); + DEBUG2("rscsid: B %s.%s\n", bus, chan); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + ret = usal_havebus(scsi_ptr, atol(bus)); + rscsirespond(ret, geterrno()); +} + +static void +scsifileno() +{ + int ret; + char bus[CMD_SIZE]; + char chan[CMD_SIZE]; + char tgt[CMD_SIZE]; + char lun[CMD_SIZE]; + + readarg(bus, sizeof(bus)); + readarg(chan, sizeof(chan)); + readarg(tgt, sizeof(tgt)); + readarg(lun, sizeof(lun)); + DEBUG4("rscsid: T %s.%s,%s,%s\n", bus, chan, tgt, lun); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + seterrno(0); + ret = usal_settarget(scsi_ptr, atoi(bus), atoi(tgt), atoi(lun)); + if (!checktarget()) { + usal_settarget(scsi_ptr, -1, -1, -1); + ret = -1; + } + if (geterrno() != 0) + rscsirespond(ret, geterrno()); + else + rscsireply(ret); +} + +static void +initiator_id() +{ + int ret; + char dummy[CMD_SIZE]; + + readarg(dummy, sizeof(dummy)); + DEBUG1("rscsid: I %s\n", dummy); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + seterrno(0); + ret = usal_initiator_id(scsi_ptr); + if (geterrno() != 0) + rscsirespond(ret, geterrno()); + else + rscsireply(ret); +} + +static void +isatapi() +{ + int ret; + char dummy[CMD_SIZE]; + + readarg(dummy, sizeof(dummy)); + DEBUG1("rscsid: A %s\n", dummy); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + seterrno(0); + ret = usal_isatapi(scsi_ptr); + if (geterrno() != 0) + rscsirespond(ret, geterrno()); + else + rscsireply(ret); +} + +static void +scsireset() +{ + int ret; + char what[CMD_SIZE]; + + readarg(what, sizeof(what)); + DEBUG1("rscsid: R %s\n", what); + if (scsi_ptr == NULL) { + rscsirespond(-1, EBADF); + return; + } + ret = usal_reset(scsi_ptr, atoi(what)); + rscsirespond(ret, geterrno()); +} + +static void +sendcmd() +{ + register struct usal_cmd *scmd; + int n; + int ret; + char count[CMD_SIZE]; + char flags[CMD_SIZE]; + char cdb_len[CMD_SIZE]; + char sense_len[CMD_SIZE]; + char timeout[CMD_SIZE]; + int csize; + int cflags; + int clen; + int ctimeout; + char rbuf[1600]; + char *p; + + /* + * S count\n + * flags\n + * cdb_len\n + * sense_len\n + * timeout\n + * <data if available> + * + * Timeout: + * - sss (e.g. 10) + * - sss.uuu (e.g. 10.23) + */ + readarg(count, sizeof(count)); + readarg(flags, sizeof(flags)); + readarg(cdb_len, sizeof(cdb_len)); + readarg(sense_len, sizeof(sense_len)); + readarg(timeout, sizeof(timeout)); + DEBUG5("rscsid: S %s %s %s %s %s", count, flags, cdb_len, sense_len, timeout); + csize = atoi(count); + cflags = atoi(flags); + clen = atoi(cdb_len); + + p = strchr(timeout, '.'); + if (p) + *p = '\0'; + ctimeout = atoi(timeout); + + if (scsi_ptr == NULL || clen > SCG_MAX_CMD || csize > Sbufsize) { + DEBUG("\n"); + voidarg(clen); + if ((cflags & SCG_RECV_DATA) == 0 && csize > 0) + voidarg(csize); + rscsirespond(-1, scsi_ptr==NULL ? EBADF : EINVAL); + return; + } + + scmd = scsi_ptr->scmd; + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = (caddr_t)Sbuf; + scmd->size = csize; + scmd->flags = cflags; + scmd->cdb_len = clen; + scmd->sense_len = atoi(sense_len); + scmd->timeout = ctimeout; + readbuf((char *)scmd->cdb.cmd_cdb, clen); + DEBUG6(" 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + scmd->cdb.cmd_cdb[0], + scmd->cdb.cmd_cdb[1], + scmd->cdb.cmd_cdb[2], + scmd->cdb.cmd_cdb[3], + scmd->cdb.cmd_cdb[4], + scmd->cdb.cmd_cdb[5]); + + if ((cflags & SCG_RECV_DATA) == 0 && csize > 0) + readbuf(Sbuf, scmd->size); + + scsi_ptr->cmdname = ""; + + ret = usal_cmd(scsi_ptr); + + n = 0; + if ((csize - scmd->resid) > 0) + n = csize - scmd->resid; + + /* + * A count\n + * error\n + * errno\n + * scb\n + * sense_count\n + * <data if available> + */ + DEBUG5("rscsid:>A %d %d %d %d %d\n", + n, + scmd->error, + scmd->ux_errno, + *(Uchar *)&scmd->scb, + scmd->sense_count); + + ret = snprintf(rbuf, sizeof(rbuf), "A%d\n%d\n%d\n%d\n%d\n", + n, + scmd->error, + scmd->ux_errno, + *(Uchar *)&scmd->scb, + scmd->sense_count); + + if (scmd->sense_count > 0) { + movebytes(scmd->u_sense.cmd_sense, &rbuf[ret], scmd->sense_count); + ret += scmd->sense_count; + } + if ((cflags & SCG_RECV_DATA) == 0) + n = 0; + if (n > 0 && ((ret + n) <= sizeof(rbuf))) { + movebytes(Sbuf, &rbuf[ret], n); + ret += n; + n = 0; + } + (void) _nixwrite(STDOUT_FILENO, rbuf, ret); + + if (n > 0) + (void) _nixwrite(STDOUT_FILENO, Sbuf, n); +} + +#define READB_SIZE 128 +static char readb[READB_SIZE]; +static char *readbptr; +static int readbcnt; + +static int +fillrdbuf() +{ + readbptr = readb; + + return (readbcnt = _niread(STDIN_FILENO, readb, READB_SIZE)); +} + +static int +readchar(char *cp) +{ + if (--readbcnt < 0) { + if (fillrdbuf() <= 0) + return (readbcnt); + --readbcnt; + } + *cp = *readbptr++; + return (1); +} + +static void +readbuf(register char *buf, register int n) +{ + register int i = 0; + register int amt; + + if (readbcnt > 0) { + amt = readbcnt; + if (amt > n) + amt = n; + movebytes(readbptr, buf, amt); + readbptr += amt; + readbcnt -= amt; + i += amt; + } + + for (; i < n; i += amt) { + amt = _niread(STDIN_FILENO, &buf[i], n - i); + if (amt <= 0) { + DEBUG("rscsid: premature eof\n"); + rscsierror(0, "Premature eof", NULL); + exit(EX_BAD); + } + } +} + +static void +voidarg(register int n) +{ + register int i; + register int amt; + char buf[512]; + + for (i = 0; i < n; i += amt) { + amt = sizeof(buf); + if ((n - i) < amt) + amt = n - i; + readbuf(buf, amt); + } +} + +static void +readarg(char *buf, int n) +{ + int i; + + for (i = 0; i < n; i++) { + if (readchar(&buf[i]) != 1) + exit(0); + if (buf[i] == '\n') + break; + } + buf[i] = '\0'; +} + +static char * +preparebuffer(int size) +{ + Sbufsize = size; + if ((Sbuf = usal_getbuf(scsi_ptr, Sbufsize)) == NULL) { + Sbufsize = 0L; + return (Sbuf); + } + size = Sbufsize + 1024; /* Add protocol overhead */ + +#ifdef SO_SNDBUF + while (size > 512 && + setsockopt(STDOUT_FILENO, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof (size)) < 0) + size -= 512; + DEBUG1("rscsid: sndsize: %d\n", size); +#endif +#ifdef SO_RCVBUF + while (size > 512 && + setsockopt(STDIN_FILENO, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof (size)) < 0) + size -= 512; + DEBUG1("rscsid: rcvsize: %d\n", size); +#endif + return (Sbuf); +} + +static int +checkscsi(char *device) +{ +#ifdef CHECKTAPE + if (strncmp(device, "/dev/rst", 8) == 0 || + strncmp(device, "/dev/nrst", 9) == 0 || + strcmp(device, "/dev/zero") == 0 || + strcmp(device, "/dev/null") == 0) + return (1); + return (0); +#else + return (1); +#endif +} + +static void +rscsirespond(int ret, int err) +{ + if (ret < 0) { + rscsierror(err, errmsgstr(err), NULL); + } else { + rscsireply(ret); + } +} + +static void +rscsireply(int ret) +{ + char rbuf[CMD_SIZE]; + + DEBUG1("rscsid:>A %d\n", ret); + (void) snprintf(rbuf, sizeof(rbuf), "A%d\n", ret); + (void) _nixwrite(STDOUT_FILENO, rbuf, strlen(rbuf)); +} + +static void +rscsierror(int err, char *str, char *xstr) +{ + char rbuf[1600]; + int xlen = 0; + int n; + + if (xstr != NULL) + xlen = strlen(xstr) + 1; + + DEBUG3("rscsid:>E %d (%s) [%s]\n", err, str, xstr?xstr:""); + n = snprintf(rbuf, sizeof(rbuf), "E%d\n%s\n%d\n", err, str, xlen); + + if (xlen > 0 && ((xlen + n) <= sizeof(rbuf))) { + movebytes(xstr, &rbuf[n], xlen); + n += xlen; + xlen = 0; + } + (void) _nixwrite(STDOUT_FILENO, rbuf, n); + if (xlen > 0) + (void) _nixwrite(STDOUT_FILENO, xstr, xlen); +} +#endif /* USE_REMOTE */ diff --git a/netscsid/netscsid.dfl b/netscsid/netscsid.dfl new file mode 100644 index 0000000..fe8c12b --- /dev/null +++ b/netscsid/netscsid.dfl @@ -0,0 +1,62 @@ +#ident @(#)rscsi.dfl 1.3 05/08/09 Copyr 2000 J. Schilling +# +# This file is /etc/rscsi.conf +# +# NOTE: If this file is not present, rscsi will reject to work. +# +# If no USER= entry is present, only root is allowed to run rscsi. +# If no ACCESS= entry is present, no device may to be used by remote users. + +# +# The file where debug info should go to. +# This is commented out by default to speed up the program. +# If you enable it make sure you substitute SAFE_DIR to a safe directory +# to debug to. +# +# Note that rscsi runs as root and thus may be able to overwrite any file. +# Be sure not to allow other people to replace the debug file by a symlink +# to e.g. /etc/passwd. +# +#DEBUG=SAFE_DIR/rscsi.dbg + +# +# Each USER= entry adds the listed user to the users who may run rscsi +# +# A typical passwd entry looks like this: +# rscsi:x:1999:1000:Remote SCSI:/export/home/rscsi:/opt/schily/sbin/rscsi +# +# Add entries for all valid remote users to /export/home/rscsi/.rhosts +# +# USER= entries are checked with a pattern matcher. USER=* matches all users. +# +USER=rscsi +#USER=joerg + +# +# Each ACCESS= entry adds a target or group of targets to the list of visible +# targets for all users that do remote SCSI access from a specific host. +# +# Username is the name of the user that runs rscsi. If you create +# different users, you may assign different permissions to different +# users from the same host. +# +# Hostname must be in the same notation as needed for .rhosts (e.g. in +# the way you will be listed by 'who' if you log in from this host). +# +# bus/chan/target/lun are the numbers from the scanbus output from +# cdrecord or sformat. If you use -1, you allow any value for this +# placeholder. +# +# local user name and remote host name are checked with a pattern matcher. +# ACCESS=* * .... matches all users from all hosts. +# +# NOTE: chan is currently not implementd (set it to 0 or -1) +# +# local remote +# user host bus chan target lun +# name name +# +#ACCESS=rscsi sparky -1 -1 -1 -1 +#ACCESS=rscsi sparky 0 -1 6 -1 +#ACCESS=rscsi sparky 1 -1 3 -1 +#ACCESS=rscsi sparky 1 -1 4 -1 diff --git a/readom/CMakeLists.txt b/readom/CMakeLists.txt new file mode 100644 index 0000000..81536d8 --- /dev/null +++ b/readom/CMakeLists.txt @@ -0,0 +1,19 @@ +PROJECT (READECD C) +INCLUDE_DIRECTORIES(../include ../wodim ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +INCLUDE(../include/AddScgBits.cmake) +INCLUDE(../include/AddSchilyBits.cmake) + +AUX_SOURCE_DIRECTORY(. readom_SRCS) + +LINK_DIRECTORIES(../librols ../libusal ../wodim) + +ADD_DEFINITIONS(-DCLONE_WRITE) + +ADD_EXECUTABLE (readom ${readom_SRCS}) +TARGET_LINK_LIBRARIES(readom wodimstuff ${EXTRA_LIBS}) +SET_TARGET_PROPERTIES(readom PROPERTIES SKIP_BUILD_RPATH TRUE) + +INSTALL(TARGETS readom DESTINATION bin) +INSTALL(FILES +readom.1 +DESTINATION ${MANSUBDIR}/man1) diff --git a/readom/io.c b/readom/io.c new file mode 100644 index 0000000..364e0ed --- /dev/null +++ b/readom/io.c @@ -0,0 +1,193 @@ +/* + * 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. + * + */ + +/* @(#)io.c 1.19 98/10/10 Copyright 1988 J. Schilling */ +/* + * Copyright (c) 1988 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 <vadefs.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <utypes.h> +#include <schily.h> +#include <ctype.h> + +struct disk { + int dummy; +}; + +static char *skipwhite(const char *); +static void prt_std(char *, long, long, long, struct disk *); +BOOL cvt_std(char *, long *, long, long, struct disk *); +extern BOOL getvalue(char *, long *, long, long, + void (*)(char *, long, long, long, struct disk *), + BOOL (*)(char *, long *, long, long, struct disk *), + struct disk *); +extern BOOL getlong(char *, long *, long, long); +extern BOOL getint(char *, int *, int, int); +extern BOOL yes(char *, ...); + +static +char *skipwhite(const char *s) +{ + register const Uchar *p = (const Uchar *)s; + + while (*p) { + if (!isspace(*p)) + break; + p++; + } + return ((char *)p); +} + +/* ARGSUSED */ + +BOOL +cvt_std(char *linep, long *lp, long mini, long maxi, struct disk *dp) +{ + long l = -1L; + +/* printf("cvt_std(\"%s\", %d, %d, %d);\n", linep, *lp, mini, maxi);*/ + + if (linep[0] == '?') { + printf("Enter a number in the range from %ld to %ld\n", + mini, maxi); + printf("The default radix is 10\n"); + printf("Precede number with '0x' for hexadecimal or with '0' for octal\n"); + printf("Shorthands are:\n"); + printf("\t'^' for minimum value (%ld)\n", mini); + printf("\t'$' for maximum value (%ld)\n", maxi); + printf("\t'+' for incrementing value to %ld\n", *lp + 1); + printf("\t'-' for decrementing value to %ld\n", *lp - 1); + return (FALSE); + } + if (linep[0] == '^' && *skipwhite(&linep[1]) == '\0') { + l = mini; + } else if (linep[0] == '$' && *skipwhite(&linep[1]) == '\0') { + l = maxi; + } else if (linep[0] == '+' && *skipwhite(&linep[1]) == '\0') { + if (*lp < maxi) + l = *lp + 1; + } else if (linep[0] == '-' && *skipwhite(&linep[1]) == '\0') { + if (*lp > mini) + l = *lp - 1; + } else if (*astol(linep, &l)) { + printf("Not a number: '%s'.\n", linep); + return (FALSE); + } + if (l < mini || l > maxi) { + printf("'%s' is out of range.\n", linep); + return (FALSE); + } + *lp = l; + return (TRUE); +} + +/* ARGSUSED */ +static void +prt_std(char *s, long l, long mini, long maxi, struct disk *dp) +{ + printf("%s %ld (%ld - %ld)/<cr>:", s, l, mini, maxi); +} + + +BOOL getvalue(char *s, long *lp, long mini, long maxi, + void (*prt)(char *, long, long, long, struct disk *), + BOOL (*cvt)(char *, long *, long, long, struct disk *), + struct disk *dp) +{ + char line[128]; + char *linep; + + for(;;) { + (*prt)(s, *lp, mini, maxi, dp); + flush(); + line[0] = '\0'; + if (rols_getline(line, 80) == EOF) + exit(EX_BAD); + + linep = skipwhite(line); + /* + * Nicht initialisierte Variablen + * duerfen nicht uebernommen werden + */ + if (linep[0] == '\0' && *lp != -1L) + return (FALSE); + + if (strlen(linep) == 0) { + /* Leere Eingabe */ + /* EMPTY */ + } else if ((*cvt)(linep, lp, mini, maxi, dp)) + return (TRUE); + } + /* NOTREACHED */ +} + + +BOOL getlong(char *s, long *lp, long mini, long maxi) +{ + return (getvalue(s, lp, mini, maxi, prt_std, cvt_std, (void *)0)); +} + + +BOOL getint(char *s, int *ip, int mini, int maxi) +{ + long l = *ip; + BOOL ret; + + ret = getlong(s, &l, (long)mini, (long)maxi); + *ip = l; + return (ret); +} + +/* VARARGS1 */ +BOOL yes(char *form, ...) +{ + va_list args; + char okbuf[10]; + +again: + va_start(args, form); + vprintf(form, args); + va_end(args); + flush(); + if (rols_getline(okbuf, sizeof(okbuf)) == EOF) + exit(EX_BAD); + if (okbuf[0] == '?') { + printf("Enter 'y', 'Y', 'yes' or 'YES' if you agree with the previous asked question.\n"); + printf("All other input will be handled as if the question has beed answered with 'no'.\n"); + goto again; + } + if(streql(okbuf, "y") || streql(okbuf, "yes") || + streql(okbuf, "Y") || streql(okbuf, "YES")) + return(TRUE); + else + return(FALSE); +} diff --git a/readom/readom.1 b/readom/readom.1 new file mode 100644 index 0000000..3bdc47b --- /dev/null +++ b/readom/readom.1 @@ -0,0 +1,497 @@ +.\" @(#)readom.1 1.23 06/01/12 Copyright 1996-2006 J. Schilling +.\" +.\" Modified version of readcd.1 by J. Schilling, 11/2006 +.\" +.\" 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 READOM 1 "Version 2.0" "J\*org Schilling" "Schily\'s USER COMMANDS" +.SH NAME +readom \- read or write data Compact Discs +.SH SYNOPSIS +.B readom +.BI dev= device +[ +.I options +] + +.SH DESCRIPTION +.B Readom +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 readom uses a modified libusal 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 readom +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 readom +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 libusal. +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 usal -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 input should +be taken from. Using '-' as filename will cause +.B readom +to use +.BR stdout " resp. " stdin . +.TP +.B \-w +Switch to write mode. If this option is not present, +.B readom +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 readom +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 readom +defaults to a transfer size of 256 kB. If libusal 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 readom +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 readom +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 readom +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 output 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 readom +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 + readom 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 + readom 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 genisoimage ) +to a DVD-RAM, call: +.PP + readom 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 genisoimage (1), +.BR rcmd (3), +.BR ssh (1). + +.SH NOTES +.PP +Unless you want to risk getting problems, +.B readom +should be run as root. If you don't want to allow users to become root on your system, +.B readom +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 readom. + +.SH DIAGNOSTICS +.PP +.PP +A typical error message for a SCSI command looks like: +.sp +.RS +.nf +readom: 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 readom +program described here is the Cdrkit spinoff from the original +.B readcd +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 readom, +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@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 of readcd 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@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@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 + diff --git a/readom/readom.c b/readom/readom.c new file mode 100644 index 0000000..d52fe5d --- /dev/null +++ b/readom/readom.c @@ -0,0 +1,2194 @@ +/* + * 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 */ +/* + * Skeleton for the use of the usal 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 <usal/usalcmd.h> +#include <usal/scsireg.h> +#include <usal/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 *usalp; + 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 *usalp, char *filename, char *sectors); +static void doit(SCSI *usalp); +static void read_disk(SCSI *usalp, parm_t *parmp); +#ifdef CLONE_WRITE +static void readcd_disk(SCSI *usalp, parm_t *parmp); +static void read_lin(SCSI *usalp, parm_t *parmp); +static int read_secheader(SCSI *usalp, long addr); +static int read_ftoc(SCSI *usalp, parm_t *parmp, BOOL do_sectype); +static void read_sectypes(SCSI *usalp, FILE *f); +static void get_sectype(SCSI *usalp, long addr, char *st); +#endif + +static void readc2_disk(SCSI *usalp, parm_t *parmp); +static int fread_data(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, + int cnt); +#ifdef CLONE_WRITE +static int fread_2448(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, + int cnt); +static int fread_2448_16(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, + int cnt); +static int fread_2352(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, + int cnt); +static int fread_lin(SCSI *usalp, 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 *usalp, 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 *usalp, caddr_t bp, long addr, int cnt); +#endif + +int write_scsi(SCSI *usalp, caddr_t bp, long addr, int cnt); +int write_g0(SCSI *usalp, caddr_t bp, long addr, int cnt); +int write_g1(SCSI *usalp, caddr_t bp, long addr, int cnt); + +#ifdef used +static void Xrequest_sense(SCSI *usalp); +#endif +static int read_retry(SCSI *usalp, caddr_t bp, long addr, long cnt, + int (*rfunc)(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt), + rparm_t *rp); +static void read_generic(SCSI *usalp, parm_t *parmp, + int (*rfunc)(SCSI *usalp, 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 *usalp, parm_t *parmp); +static int choice(int n); +static void ra(SCSI *usalp); + +int read_da(SCSI *usalp, caddr_t bp, long addr, int cnt, int framesize, + int subcode); +int read_cd(SCSI *usalp, caddr_t bp, long addr, int cnt, int framesize, + int data, int subch); + +static void oldmode(SCSI *usalp, int *errp, int *retrp); +static void domode(SCSI *usalp, int err, int retr); + +static void qpto96(Uchar *sub, Uchar *subq, int dop); +static void ovtime(SCSI *usalp); +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 clonemode; +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(void) { return (FALSE); } +/*XXX*/EXPORT BOOL cvt_bcyls(void) { return (FALSE); } +/*XXX*/EXPORT void print_defect_list(void) {} + +static void +usage(int ret) +{ + fprintf(stderr, "Usage:\treadom [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 *usalp; + 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, &clonemode, + &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 is not what you see here. This line is only a fake for too clever\n" + "GUIs and other frontend applications. In fact, this program is:\n", cdr_version); + + printf("readom " CDRKIT_VERSION " (" HOST_SYSTEM ")\n" + "Copyright (C) 1987, 1995-2006 Joerg Schilling\n" + "Copyright (C) 2006 Cdrkit maintainers\n" + "(modified version of <censored> -- " + "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 usal_remote() to force loading the remote SCSI transport + * library code that is located in librusal instead of the dummy + * remote routines that are located inside libusal. + */ + usal_remote(); + if (dev != NULL && + ((strncmp(dev, "HELP", 4) == 0) || + (strncmp(dev, "help", 4) == 0))) { + usal_help(stderr); + exit(0); + } + if ((usalp = usal_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 'wodim -scanbus'.%s\n", + geteuid() ? " Make sure you are root.":""); + errmsgno(EX_BAD, "For possible transport specifiers try 'wodim dev=help'.\n"); + exit(err); + } + } else { + if (scsibus == -1 && target >= 0 && lun >= 0) + scsibus = 0; + + usalp = usal_smalloc(); + usalp->debug = debug; + usalp->kdebug = kdebug; + + usal_settarget(usalp, scsibus, target, lun); + if (usal__open(usalp, NULL) <= 0) + comerr("Cannot open SCSI driver.\n"); + } + usalp->silent = silent; + usalp->verbose = verbose; + usalp->debug = debug; + usalp->kdebug = kdebug; + usal_settimeout(usalp, deftimeout); + + if (Sbufsize == 0) + Sbufsize = 256*1024L; + Sbufsize = usal_bufsize(usalp, Sbufsize); + if ((Sbuf = usal_getbuf(usalp, 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(usalp, stdout); + exit(0); + } + do_inquiry(usalp, FALSE); + allow_atapi(usalp, TRUE); /* Try to switch to 10 byte mode cmds */ + if (is_mmc(usalp, 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 (usalp->inq->data_format < 2) + usalp->inq->data_format = 2; + + if ((rspeed = get_curprofile(usalp)) >= 0) { + if (rspeed >= 0x08 && rspeed < 0x10) + is_cdrom = TRUE; + if (rspeed >= 0x10 && rspeed < 0x20) + is_dvd = TRUE; + } else { + BOOL dvd; + + mmc_check(usalp, NULL, NULL, NULL, NULL, &dvd, NULL); + if (dvd == FALSE) { + is_cdrom = TRUE; + } else { + char xb[32]; + + if (read_dvd_structure(usalp, (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(usalp, speed, speed, ROTCTL_CLV); + if (scsi_get_speed(usalp, &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.usalp = usalp; + 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(usalp); + comexit(0); + } + + if (is_suid) { + if (usalp->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 || clonemode) { + dorw(usalp, filename, sectors); + } else { + doit(usalp); + } + 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->usalp->running) + break; + if (i == 10) { + errmsgno(EX_BAD, + "Waiting for current SCSI command to finish.\n"); + } + usleep(100000); + } + + if (!exp->usalp->running) { + if (exp->oerr[2] != 0) { + domode(exp->usalp, exp->oerr[0], exp->oerr[1]); + } + if (exp->old_secsize > 0 && exp->old_secsize != 2048) + select_secsize(exp->usalp, 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(void) +{ + 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(void) +{ + 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 *usalp, 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(usalp, 60)) + comerrno(EX_BAD, "Device not ready.\n"); + +#ifdef CLONE_WRITE + if (fulltoc) { + if (params.name == NULL) + params.name = "/dev/null"; + read_ftoc(usalp, ¶ms, FALSE); + } else if (clonemode) { + if (!is_mmc(usalp, 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(usalp, ¶ms, TRUE) < 0) + comerrno(EX_BAD, "Read fulltoc problems.\n"); + readcd_disk(usalp, ¶ms); + } else +#endif + if (c2scan) { + noerror = TRUE; + if (retries == MAX_RETRY) + retries = 10; + if (params.name == NULL) + params.name = "/dev/null"; + readc2_disk(usalp, ¶ms); + } else if (do_write) + write_disk(usalp, ¶ms); + else + read_disk(usalp, ¶ms); +} + +static void +doit(SCSI *usalp) +{ + 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(usalp, 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:readom 19: lin 20: full toc\n"); +#endif + + getint("Enter selection:", &i, 0, 20); + if (didintr) + return; + + switch (i) { + + case 5: ovtime(usalp); break; + case 11: read_disk(usalp, 0); break; + case 12: write_disk(usalp, 0); break; + case 15: ra(usalp); break; +/* case 16: reada_disk(usalp, 0, 0); break;*/ + case 17: readc2_disk(usalp, ¶ms); break; +#ifdef CLONE_WRITE + case 18: readcd_disk(usalp, 0); break; + case 19: read_lin(usalp, 0); break; + case 20: read_ftoc(usalp, 0, FALSE); break; +#endif + } + } +} + +static void +read_disk(SCSI *usalp, parm_t *parmp) +{ + rparm_t rp; + + read_capacity(usalp); + print_capacity(usalp, stderr); + + rp.errors = 0; + rp.c2_errors = 0; + rp.c2_maxerrs = 0; + rp.c2_errsecs = 0; + rp.c2_badsecs = 0; + rp.secsize = usalp->cap->c_bsize; + + read_generic(usalp, parmp, fread_data, &rp, fdata_null); +} + +#ifdef CLONE_WRITE +static void +readcd_disk(SCSI *usalp, parm_t *parmp) +{ + rparm_t rp; + int osecsize = 2048; + int oerr = 0; + int oretr = 10; + int (*funcp)(SCSI *_usalp, rparm_t *_rp, caddr_t bp, long addr, int cnt); + + usalp->silent++; + if (read_capacity(usalp) >= 0) + osecsize = usalp->cap->c_bsize; + usalp->silent--; + if (osecsize != 2048) + select_secsize(usalp, 2048); + + read_capacity(usalp); + print_capacity(usalp, 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(usalp, NULL, NULL); + funcp = fread_2448; + + wait_unit_ready(usalp, 10); + if (fread_2448(usalp, &rp, Sbuf, 0, 0) < 0) { + errmsgno(EX_BAD, "read 2448 failed\n"); + if (rp.ismmc && + fread_2448_16(usalp, &rp, Sbuf, 0, 0) >= 0) { + errmsgno(EX_BAD, "read 2448_16 : OK\n"); + + funcp = fread_2448_16; + } + } + + oldmode(usalp, &oerr, &oretr); + exargs.oerr[0] = oerr; + exargs.oerr[1] = oretr; + exargs.oerr[2] = 0xFF; + if (parmp == NULL) /* XXX Nur am Anfang!!! */ + domode(usalp, -1, -1); + else + domode(usalp, nocorr?0x21:0x20, 10); + + read_generic(usalp, parmp, funcp, &rp, fdata_null); + if (osecsize != 2048) + select_secsize(usalp, osecsize); + domode(usalp, oerr, oretr); +} + +/* ARGSUSED */ +static void +read_lin(SCSI *usalp, parm_t *parmp) +{ + parm_t parm; + rparm_t rp; + + read_capacity(usalp); + print_capacity(usalp, 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(usalp, NULL, NULL); + domode(usalp, -1, -1); + read_generic(usalp, &parm, fread_lin, &rp, fdata_null); +} + +static int +read_secheader(SCSI *usalp, long addr) +{ + rparm_t rp; + int osecsize = 2048; + int ret = 0; + + usalp->silent++; + if (read_capacity(usalp) >= 0) + osecsize = usalp->cap->c_bsize; + usalp->silent--; + if (osecsize != 2048) + select_secsize(usalp, 2048); + + read_capacity(usalp); + + 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(usalp, NULL, NULL); + + wait_unit_ready(usalp, 10); + + fillbytes(Sbuf, 2352, '\0'); + if (fread_2352(usalp, &rp, Sbuf, addr, 1) < 0) { + ret = -1; + } + if (osecsize != 2048) + select_secsize(usalp, osecsize); + return (ret); +} + +/* ARGSUSED */ +static int +read_ftoc(SCSI *usalp, 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; + } + snprintf(filename, sizeof (filename), "%.*s.toc", len, parmp->name); + } + + tp = (struct tocheader *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc(usalp, xb, 0, sizeof (struct tocheader), 0, FMT_FULLTOC) < 0) { + if (usalp->silent == 0 || usalp->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(usalp, 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(usalp, 30); + read_toc(usalp, xb, 0, sizeof (struct tocheader), 0, FMT_FULLTOC); + wait_unit_ready(usalp, 30); + if (read_toc(usalp, xxb, 0, len+1, 0, FMT_FULLTOC) >= 0) { + goto itworked; + } + } + if (usalp->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(usalp, 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 *usalp, FILE *f) +{ + char sect; + + sect = SECT_AUDIO; + get_sectype(usalp, 4, §); + if (f != NULL) + filewrite(f, §, 1); + if (xdebug) + usal_prbytes("sec 0", (Uchar *)Sbuf, 16); + + sect = SECT_AUDIO; + get_sectype(usalp, usalp->cap->c_baddr-4, §); + if (f != NULL) + filewrite(f, §, 1); + if (xdebug) { + usal_prbytes("sec E", (Uchar *)Sbuf, 16); + fprintf(stderr, "baddr: %ld\n", (long)usalp->cap->c_baddr); + } +} + +static void +get_sectype(SCSI *usalp, 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 + + usalp->silent++; + for (i = 0; i < _MAX_TRY_ && read_secheader(usalp, raddr) < 0; i++) { + if (addr == 0) + raddr++; + else + raddr--; + } + usalp->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 *usalp, parm_t *parmp) +{ + rparm_t rp; + int osecsize = 2048; + int oerr = 0; + int oretr = 10; + + usalp->silent++; + if (read_capacity(usalp) >= 0) + osecsize = usalp->cap->c_bsize; + usalp->silent--; + if (osecsize != 2048) + select_secsize(usalp, 2048); + + read_capacity(usalp); + print_capacity(usalp, 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(usalp, NULL, NULL); + + oldmode(usalp, &oerr, &oretr); + exargs.oerr[0] = oerr; + exargs.oerr[1] = oretr; + exargs.oerr[2] = 0xFF; + domode(usalp, 0x21, 10); + + + read_generic(usalp, parmp, fread_c2, &rp, fdata_c2); + if (osecsize != 2048) + select_secsize(usalp, osecsize); + domode(usalp, 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)/usalp->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 *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt) +{ + return (read_g1(usalp, bp, addr, cnt)); +} + +#ifdef CLONE_WRITE +static int +fread_2448(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt) +{ + if (rp->ismmc) { + return (read_cd(usalp, 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(usalp, bp, addr, cnt, rp->secsize, + /* Sync + all headers + user data + EDC/ECC + all subch */ + 0x02)); + } +} + +static int +fread_2448_16(SCSI *usalp, 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(usalp, 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(usalp, bp, addr, cnt, rp->secsize, + /* Sync + all headers + user data + EDC/ECC + all subch */ + 0x02)); + } +} + +static int +fread_2352(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt) +{ + if (rp->ismmc) { + return (read_cd(usalp, 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(usalp, bp, addr, cnt, rp->secsize, + /* Sync + all headers + user data + EDC/ECC + all subch */ + 0x02)); + } +} + +static int +fread_lin(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt) +{ + if (addr != ULONG_C(0xF0000000)) + addr = ULONG_C(0xFFFFFFFF); + + return (read_cd(usalp, 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 *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt) +{ + if (rp->ismmc) { + return (read_cd(usalp, 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(usalp, 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)) { +/* usal_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); +/* usal_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 *usalp, caddr_t bp, long addr, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; +/* scmd->size = cnt*512;*/ + scmd->size = cnt*usalp->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 = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read extended"; + + return (usal_cmd(usalp)); +} +#endif + +#define G0_MAXADDR 0x1FFFFFL + +int +write_scsi(SCSI *usalp, caddr_t bp, long addr, int cnt) +{ + if (addr <= G0_MAXADDR) + return (write_g0(usalp, bp, addr, cnt)); + else + return (write_g1(usalp, bp, addr, cnt)); +} + +int +write_g0(SCSI *usalp, caddr_t bp, long addr, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (usalp->cap->c_bsize <= 0) + raisecond("capacity_not_set", 0L); + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt*usalp->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 = usal_lun(usalp); + g0_cdbaddr(&scmd->cdb.g0_cdb, addr); + scmd->cdb.g0_cdb.count = (Uchar)cnt; + + usalp->cmdname = "write_g0"; + + return (usal_cmd(usalp)); +} + +int +write_g1(SCSI *usalp, caddr_t bp, long addr, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (usalp->cap->c_bsize <= 0) + raisecond("capacity_not_set", 0L); + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt*usalp->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 = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "write_g1"; + + return (usal_cmd(usalp)); +} + +#ifdef used +static void +Xrequest_sense(SCSI *usalp) +{ + char sense_buf[32]; + struct usal_cmd ocmd; + int sense_count; + char *cmdsave; + register struct usal_cmd *scmd = usalp->scmd; + + cmdsave = usalp->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 = usal_lun(usalp); + scmd->cdb.g0_cdb.count = sizeof (sense_buf); + + usalp->cmdname = "request sense"; + + usal_cmd(usalp); + + sense_count = sizeof (sense_buf) - usal_getresid(usalp); + movebytes(&ocmd, scmd, sizeof (*scmd)); + scmd->sense_count = sense_count; + movebytes(sense_buf, (Uchar *)&scmd->sense, scmd->sense_count); + + usalp->cmdname = cmdsave; + usal_printerr(usalp); + usal_printresult(usalp); /* XXX restore key/code in future */ +} +#endif + +static int +read_retry(SCSI *usalp, caddr_t bp, long addr, long cnt, + int (*rfunc)(SCSI *usalp, rparm_t *rp, caddr_t bp, long addr, int cnt), + rparm_t *rp) +{ +/* int secsize = usalp->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(usalp, 120); + if (try >= 10) { /* First 10 retries without seek */ + if ((try % 8) == 0) { + fprintf(stderr, "+"); /* Read last sector */ + usalp->silent++; + (*rfunc)(usalp, rp, dummybuf, usalp->cap->c_baddr, 1); + usalp->silent--; + } else if ((try % 4) == 0) { + fprintf(stderr, "-"); /* Read first sector */ + usalp->silent++; + (*rfunc)(usalp, rp, dummybuf, 0, 1); + usalp->silent--; + } else { + fprintf(stderr, "~"); /* Read random sector */ + usalp->silent++; + (*rfunc)(usalp, rp, dummybuf, choice(usalp->cap->c_baddr), 1); + usalp->silent--; + } + if (didintr) + comexit(exsig); /* XXX besseres Konzept?!*/ + wait_unit_ready(usalp, 120); + } + if (didintr) + comexit(exsig); /* XXX besseres Konzept?!*/ + + fillbytes(bp, secsize, 0); + + usalp->silent++; + err = (*rfunc)(usalp, rp, bp, addr, 1); + usalp->silent--; + + if (err < 0) { + err = usalp->scmd->ux_errno; +/* fprintf(stderr, "\n");*/ +/* errmsgno(err, "Cannot read source disk\n");*/ + } else { + if (usal_getresid(usalp)) { + fprintf(stderr, "\nresid: %d\n", usal_getresid(usalp)); + 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 (usalp->silent <= 1 && lverbose > 0) + usal_printerr(usalp); + + 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 *usalp, parm_t *parmp, + int (*rfunc)(SCSI *usalp, 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 (usalp->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'; + + usalp->silent++; + if (read_capacity(usalp) >= 0) + end = usalp->cap->c_baddr + 1; + usalp->silent--; + + if ((end <= 0 && isrange) || (askrange && usal_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", + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp), + 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", + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + fprintf(stderr, "Enter filename [%s]: ", defname); flush(); + (void) rols_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); + + usalp->silent++; + if ((*rfunc)(usalp, rp, Sbuf, addr, cnt) < 0) { + usalp->silent--; + err = usalp->scmd->ux_errno; + if (quiet) { + fprintf(stderr, "\n"); + } else if (usalp->silent == 0) { + usal_printerr(usalp); + } + errmsgno(err, "Cannot read source disk\n"); + + if (read_retry(usalp, Sbuf, addr, cnt, rfunc, rp) < 0) + goto out; + } else { + usalp->silent--; + if (usal_getresid(usalp)) { + fprintf(stderr, "\nresid: %d\n", usal_getresid(usalp)); + 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/usalp->cap->c_bsize), + (double)((addr - start)/(1024.0/usalp->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 *usalp, 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(usalp) >= 0) { + end = usalp->cap->c_baddr + 1; + print_capacity(usalp, 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, + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + + addr = start = parmp->start; + if (parmp->end != -1 && parmp->end < end) + end = parmp->end; + cnt = Sbufsize / usalp->cap->c_bsize; + } else { + fprintf(stderr, "Copy from file to SCSI (%d,%d,%d) disk\n", + usal_scsibus(usalp), usal_target(usalp), usal_lun(usalp)); + fprintf(stderr, "Enter filename [%s]: ", defname); flush(); + (void) rols_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 / usalp->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 * usalp->cap->c_bsize)) < 0) + comerr("Cannot read '%s'\n", filename); + if (amt == 0) + break; + if ((amt / usalp->cap->c_bsize) < cnt) + cnt = amt / usalp->cap->c_bsize; + if (write_scsi(usalp, Sbuf, addr, cnt) < 0) + comerrno(usalp->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/usalp->cap->c_bsize), + (double)((addr - start)/(1024.0/usalp->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 *usalp) +{ +/* char filename[512];*/ + FILE *f; +/* long addr = 0L;*/ +/* long cnt;*/ +/* long end;*/ +/* int msec;*/ +/* int start;*/ +/* int err = 0;*/ + + select_secsize(usalp, 2352); + read_capacity(usalp); + print_capacity(usalp, stderr); + fillbytes(Sbuf, 50*2352, 0); + if (read_g1(usalp, Sbuf, 0, 50) < 0) + errmsg("read CD\n"); + f = fileopen("DDA", "wctb"); +/* filewrite(f, Sbuf, 50 * 2352 - usal_getresid(usalp));*/ + 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 *usalp, caddr_t bp, long addr, int cnt, int framesize, int subcode) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (usalp->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 = usal_lun(usalp); + g5_cdbaddr(&scmd->cdb.g5_cdb, addr); + g5_cdblen(&scmd->cdb.g5_cdb, cnt); + scmd->cdb.g5_cdb.res10 = subcode; + + usalp->cmdname = "read_da"; + + return (usal_cmd(usalp)); +} + +int +read_cd(SCSI *usalp, caddr_t bp, long addr, int cnt, int framesize, int data, + int subch) +{ + register struct usal_cmd *scmd = usalp->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 = usal_lun(usalp); + 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; + + usalp->cmdname = "read_cd"; + + return (usal_cmd(usalp)); +} + +static void +oldmode(SCSI *usalp, 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(usalp, 0x01, "CD error recovery parameter", + mode, (Uchar *)0, (Uchar *)cmode, (Uchar *)0, &len)) { + return; + } + if (xdebug) + usal_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) + usal_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 *usalp, 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(usalp, 0x01, "CD error recovery parameter", + mode, (Uchar *)0, (Uchar *)cmode, (Uchar *)0, &len)) { + return; + } + if (xdebug || (err == -1 && retr == -1)) { + usal_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)) + usal_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)) + usal_prbytes("Mode Select Data", mode, len); + mode_select(usalp, mode, len, 0, usalp->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 *usalp) +{ + register int i; + + usalp->silent++; + (void) test_unit_ready(usalp); + usalp->silent--; + if (test_unit_ready(usalp) < 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(usalp); + + if (didintr) + return; + } + + prstats(); + + /* + * ATAPI drives do not like seek_g0() + */ + usalp->silent++; + i = seek_g0(usalp, 0L); + usalp->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(usalp, 0L); + + if (didintr) + return; + } + + prstats(); + } + + usalp->silent++; + i = seek_g1(usalp, 0L); + usalp->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(usalp, 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(void) +{ + 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]); +} diff --git a/wodim/CMakeLists.txt b/wodim/CMakeLists.txt new file mode 100644 index 0000000..d6245c9 --- /dev/null +++ b/wodim/CMakeLists.txt @@ -0,0 +1,37 @@ +PROJECT (CDRECORD C) +INCLUDE_DIRECTORIES(../include ../libedc ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include) +INCLUDE(../include/AddScgBits.cmake) +include(../include/AddSchilyBits.cmake) + +#AUX_SOURCE_DIRECTORY(. CDRECORD_SRCS) +SET(CDRECORD_SRCS wodim.c audiosize.c auinfo.c cdr_drv.c cdtext.c clone.c crc16.c cue.c diskid.c drv_7501.c drv_jvc.c drv_mmc.c drv_philips.c drv_simul.c drv_sony.c fifo.c isosize.c scsi_cdr_mmc4.c scsi_mmc4.c sector.c subchan.c wm_packet.c wm_session.c wm_track.c xio.c) +SET(CDRECORD_COMMON_SRCS cd_misc.c defaults.c getnum.c misc.c modes.c movesect.c scsi_cdr.c scsi_mmc.c scsi_scan.c) + +INCLUDE(CheckIncludeFiles) + +#force libcap usage on Linux +CHECK_INCLUDE_FILES("sys/capability.h" HAVE_SYS_CAPABILITY_H) +IF(HAVE_SYS_CAPABILITY_H) + LIST(APPEND EXTRA_LIBS cap) +ELSE(HAVE_SYS_CAPABILITY_H) + IF(CMAKE_SYSTEM_NAME MATCHES "Linux") + MESSAGE(FATAL_ERROR "Error: found a Linux system but no libcap header. Install libcap-dev.") + ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") +ENDIF(HAVE_SYS_CAPABILITY_H) + +LINK_DIRECTORIES(../librols ../libusal ../libedc) + +ADD_DEFINITIONS(-DHAVE_LIB_EDC_ECC -DCLONE_WRITE -DDRV_DVD -DFIFO -DAUINFO -DUSE_LARGEFILES ) + + +ADD_EXECUTABLE (wodim ${CDRECORD_SRCS}) +ADD_LIBRARY (wodimstuff STATIC ${CDRECORD_COMMON_SRCS}) +LIST(APPEND EXTRA_LIBS wodimstuff) + +TARGET_LINK_LIBRARIES(wodim ${EXTRA_LIBS} edc) +SET_TARGET_PROPERTIES(wodim PROPERTIES SKIP_BUILD_RPATH TRUE) + +INSTALL(TARGETS wodim DESTINATION bin) +INSTALL(FILES + wodim.1 +DESTINATION ${MANSUBDIR}/man1) diff --git a/wodim/audiosize.c b/wodim/audiosize.c new file mode 100644 index 0000000..2cdad97 --- /dev/null +++ b/wodim/audiosize.c @@ -0,0 +1,289 @@ +/* + * 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. + * + */ + +/* @(#)audiosize.c 1.19 04/03/01 Copyright 1998-2004 J. Schilling */ +/* + * Copyright (c) 1998-2004 J. Schilling + * + * First .vaw implementation made by Dave Platt <dplatt@iq.nc.com> + * Current .wav implementation with additional help from Heiko Eißfeld. + */ +/* + * 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 <statdefs.h> +#include <unixstd.h> +#include <standard.h> +#include <utypes.h> +#include <strdefs.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include "auheader.h" + +typedef struct { + Uchar magic[4]; + Uchar hdr_size[4]; + Uchar data_size[4]; + Uchar encoding[4]; + Uchar sample_rate[4]; + Uchar channels[4]; +} sun_au_t; + +#define SUN_AU_MAGIC ".snd" +#define SUN_AU_UNKNOWN_LEN ((Uint)~0) +#define SUN_AU_ULAW8 1 /* American ISDN Telephonie */ +#define SUN_AU_LINEAR8 2 /* Linear PCM 8 bit/channel */ +#define SUN_AU_LINEAR16 3 /* Linear PCM 16 bit/channel */ +#define SUN_AU_LINEAR24 4 /* Linear PCM 24 bit/channel */ +#define SUN_AU_LINEAR32 5 /* Linear PCM 32 bit/channel */ +#define SUN_AU_FLOAT 6 /* 32 bit IEEE floatingpoint */ +#define SUN_AU_DOUBLE 7 /* 64 bit IEEE floatingpoint */ +#define SUN_AU_G721 23 /* 4 bit CCITT G.721 ADPCM */ +#define SUN_AU_G722 24 /* CCITT G.722 ADPCM */ +#define SUN_AU_G723_3 25 /* 3 bit CCITT G.723 ADPCM */ +#define SUN_AU_G723_5 26 /* 5 bit CCITT G.723 ADPCM */ +#define SUN_AU_ALAW8 27 /* International ISDN Tel. */ + +typedef struct { + Uchar ckid[4]; + Uchar cksize[4]; +} chunk_t; + +typedef struct { + Uchar wave[4]; +} riff_chunk; + +typedef struct { + Uchar fmt_tag[2]; + Uchar channels[2]; + Uchar sample_rate[4]; + Uchar av_byte_rate[4]; + Uchar block_size[2]; + Uchar bits_per_sample[2]; +} fmt_chunk; + +#define WAV_RIFF_MAGIC "RIFF" /* Magic for file format */ +#define WAV_WAVE_MAGIC "WAVE" /* Magic for Waveform Audio */ +#define WAV_FMT_MAGIC "fmt " /* Start of Waveform format */ +#define WAV_DATA_MAGIC "data" /* Start of data chunk */ +#define WAV_FORMAT_PCM 0x0001 /* Linear PCM format */ +#define WAV_FORMAT_ULAW 0x0101 /* American ISDN Telephonie */ +#define WAV_FORMAT_ALAW 0x0102 /* International ISDN Tel. */ +#define WAV_FORMAT_ADPCM 0x0103 /* ADPCM format */ + +#define le_a_to_u_short(a) ((unsigned short) \ + ((((unsigned char *)a)[0] & 0xFF) | \ + (((unsigned char *)a)[1] << 8 & 0xFF00))) + +#ifdef __STDC__ +#define le_a_to_u_long(a) ((unsigned long) \ + ((((unsigned char *)a)[0] & 0xFF) | \ + (((unsigned char *)a)[1] << 8 & 0xFF00) | \ + (((unsigned char *)a)[2] << 16 & 0xFF0000) | \ + (((unsigned char *)a)[3] << 24 & 0xFF000000UL))) +#else +#define le_a_to_u_long(a) ((unsigned long) \ + ((((unsigned char *)a)[0] & 0xFF) | \ + (((unsigned char *)a)[1] << 8 & 0xFF00) | \ + (((unsigned char *)a)[2] << 16 & 0xFF0000) | \ + (((unsigned char *)a)[3] << 24 & 0xFF000000))) +#endif + +BOOL is_auname(const char *name); +off_t ausize(int f); +BOOL is_wavname(const char *name); +off_t wavsize(int f); + +BOOL +is_auname(const char *name) +{ + const char *p; + + if ((p = strrchr(name, '.')) == NULL) + return (FALSE); + return (streql(p, ".au")); +} + +/* + * Read Sun audio header, leave file seek pointer past auheader. + */ +off_t +ausize(int f) +{ + sun_au_t hdr; + struct stat sb; + mode_t mode; + off_t size; + Int32_t val; + long ret = AU_BAD_HEADER; + + /* + * First check if a bad guy tries to call ausize() + * with an unappropriate file descriptor. + * return -1 in this case. + */ + if (isatty(f)) + return (-1L); + if (fstat(f, &sb) < 0) + return (-1L); + mode = sb.st_mode & S_IFMT; + if (!S_ISREG(mode) && !S_ISBLK(mode) && !S_ISCHR(mode)) + return (-1L); + + if (read(f, &hdr, sizeof (hdr)) != sizeof (hdr)) + goto err; + + if (strncmp((char *)hdr.magic, SUN_AU_MAGIC, 4) != 0) + goto err; + + ret = AU_BAD_CODING; + + val = a_to_u_4_byte(hdr.encoding); + if (val != SUN_AU_LINEAR16) + goto err; + + val = a_to_u_4_byte(hdr.channels); + if (val != 2) + goto err; + + val = a_to_u_4_byte(hdr.sample_rate); + if (val != 44100) + goto err; + + size = (off_t)a_to_u_4_byte(hdr.hdr_size); + if (size < (off_t)sizeof (hdr) || size > 512) + goto err; + lseek(f, size, SEEK_SET); + + /* + * Most .au files don't seem to honor the data_size field, + * so we use the whole file size without the header. + */ + size = sb.st_size - size; + return (size); + +err: + lseek(f, (off_t)0L, SEEK_SET); + return ((off_t)ret); +} + +BOOL +is_wavname(const char *name) +{ + const char *p; + + if ((p = strrchr(name, '.')) == NULL) + return (FALSE); + return (streql(p, ".wav") || streql(p, ".WAV")); +} + +/* + * Read WAV header, leave file seek pointer past WAV header. + */ +off_t +wavsize(int f) +{ + chunk_t chunk; + riff_chunk riff; + fmt_chunk fmt; + struct stat sb; + off_t cursor; + BOOL gotFormat; + mode_t mode; + off_t size; + long ret = AU_BAD_HEADER; + + /* + * First check if a bad guy tries to call wavsize() + * with an unappropriate file descriptor. + * return -1 in this case. + */ + + if (isatty(f)) + return (-1L); + if (fstat(f, &sb) < 0) + return (-1L); + mode = sb.st_mode & S_IFMT; + if (!S_ISREG(mode) && !S_ISBLK(mode) && !S_ISCHR(mode)) + return (-1L); + + cursor = (off_t)0; + gotFormat = FALSE; + + for (;;) { + if (read(f, &chunk, sizeof (chunk)) != sizeof (chunk)) + goto err; + size = (off_t)le_a_to_u_long(chunk.cksize); + + if (strncmp((char *)chunk.ckid, WAV_RIFF_MAGIC, 4) == 0) { + /* + * We found (first) RIFF header. Check if a WAVE + * magic follows. Set up size to be able to skip + * past this header. + */ + if (read(f, &riff, sizeof (riff)) != sizeof (riff)) + goto err; + if (strncmp((char *)riff.wave, WAV_WAVE_MAGIC, 4) != 0) + goto err; + size = (off_t)sizeof (riff); + + } else if (strncmp((char *)chunk.ckid, WAV_FMT_MAGIC, 4) == 0) { + /* + * We found WAVE "fmt " header. Check size (if it is + * valid for a WAVE file) and coding whether it is + * useable for a CD. + */ + if (size < (off_t)sizeof (fmt)) goto err; + if (sizeof (fmt) != read(f, &fmt, sizeof (fmt))) goto err; + if (le_a_to_u_short(fmt.channels) != 2 || + le_a_to_u_long(fmt.sample_rate) != 44100 || + le_a_to_u_short(fmt.bits_per_sample) != 16) { + ret = AU_BAD_CODING; + goto err; + } + gotFormat = TRUE; + + } else if (strncmp((char *)chunk.ckid, WAV_DATA_MAGIC, 4) == 0) { + /* + * We found WAVE "data" header. This contains the + * size value of the audio part. + */ + if (!gotFormat) { + ret = AU_BAD_CODING; + goto err; + } + if ((cursor + size + sizeof (chunk)) > sb.st_size) + size = sb.st_size - (cursor + sizeof (chunk)); + return (size); + } + cursor += size + sizeof (chunk); + lseek(f, cursor, SEEK_SET); /* Skip over current chunk */ + } +err: + lseek(f, (off_t)0L, SEEK_SET); + return (ret); +} diff --git a/wodim/auheader.h b/wodim/auheader.h new file mode 100644 index 0000000..3bfe932 --- /dev/null +++ b/wodim/auheader.h @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +/* @(#)auheader.h 1.2 98/05/09 Copyright 1998 J. Schilling */ +/* + * Copyright (c) 1998 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. + */ + +#ifndef _AUHEADER_H +#define _AUHEADER_H + +#define AU_BAD -1 +#define AU_BAD_HEADER -2 +#define AU_BAD_CODING -3 + + +#endif /* _AUHEADER_H */ diff --git a/wodim/auinfo.c b/wodim/auinfo.c new file mode 100644 index 0000000..8cf8aef --- /dev/null +++ b/wodim/auinfo.c @@ -0,0 +1,525 @@ +/* + * 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. + * + */ + +/* @(#)auinfo.c 1.23 04/03/01 Copyright 1998-2004 J. Schilling */ +/* + * Copyright (c) 1998-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 <stdxlib.h> +#include <unixstd.h> +#include <statdefs.h> +#include <stdio.h> +#include <standard.h> +#include <strdefs.h> +#include <deflts.h> +#include <utypes.h> +#include <schily.h> + +#include "cdtext.h" +#include "wodim.h" + +extern int debug; +extern int xdebug; + +BOOL auinfosize(char *name, track_t *trackp); +void auinfo(char *name, int track, track_t *trackp); +textptr_t *gettextptr(int track, track_t *trackp); +static char *savestr(char *name); +static char *readtag(char *name); +static char *readtstr(char *name); +void setmcn(char *mcn, track_t *trackp); +static void isrc_illchar(char *isrc, int c); +void setisrc(char *isrc, track_t *trackp); +void setindex(char *tindex, track_t *trackp); + +#ifdef XXX +int +main(int argc, char *argv[]) +{ +/* auinfo("/etc/default/cdrecord");*/ +/* auinfo("/mnt2/CD3/audio_01.inf");*/ + auinfo("/mnt2/CD3/audio_01.wav"); +} +#endif + +BOOL +auinfosize(char *name, track_t *trackp) +{ + const char *p; + const char *tlp; + struct stat sb; + long secs; + long nsamples; + Llong tracksize; + + if (!is_audio(trackp)) + return (FALSE); + + if ((trackp->flags & TI_USEINFO) == 0) + return (FALSE); + + if ((p = strrchr(name, '.')) == NULL) + return (FALSE); + if (!streql(p, ".inf") && !streql(p, ".INF")) + return (FALSE); + + /* + * First check if a bad guy tries to call auinfosize() + * while STDIN_FILENO is a TTY. + */ + if (isatty(STDIN_FILENO)) { + errmsgno(EX_BAD, + "WARNING: Stdin is connected to a terminal.\n"); + return (FALSE); + } + + if (stat(name, &sb) < 0) /* *.inf file not found */ + return (FALSE); + + if (sb.st_size > 10000) /* Too large for a *.inf file */ + return (FALSE); + + if (cfg_open(name) < 0) /* Cannot open *.inf file */ + return (FALSE); + + tlp = p = readtag("Tracklength"); + if (p == NULL) { /* Tracklength= Tag not found */ + errmsgno(EX_BAD, + "WARNING: %s does not contain a 'Tracklength=' tag.\n", + name); + cfg_close(); + return (FALSE); + } + + p = astol(p, &secs); + if (*p != '\0' && *p != ',') { + errmsgno(EX_BAD, + "WARNING: %s: 'Tracklength=' contains illegal parameter '%s'.\n", + name, tlp); + cfg_close(); + return (FALSE); + } + if (*p == ',') + p++; + p = astol(p, &nsamples); + if (*p != '\0') { + errmsgno(EX_BAD, + "WARNING: %s: 'Tracklength=' contains illegal parameter '%s'.\n", + name, tlp); + cfg_close(); + return (FALSE); + } + tracksize = (secs * 2352) + (nsamples * 4); + if (xdebug > 0) { + fprintf(stderr, "%s: Tracksize %lld bytes (%ld sectors, %ld samples)\n", + name, tracksize, secs, nsamples); + } + trackp->itracksize = tracksize; + cfg_close(); + return (TRUE); +} + +void +auinfo(char *name, int track, track_t *trackp) +{ + char infname[1024]; + char *p; + track_t *tp = &trackp[track]; + textptr_t *txp; + long l; + long tno = -1; + BOOL isdao = !is_tao(&trackp[0]); + + strncpy(infname, name, sizeof (infname)-1); + infname[sizeof (infname)-1] = '\0'; + p = strrchr(infname, '.'); + if (p != 0 && &p[4] < &name[sizeof (infname)]) { + strcpy(&p[1], "inf"); + } + + if (cfg_open(infname) == 0) { + + p = readtstr("CDINDEX_DISCID"); + p = readtag("CDDB_DISKID"); + + p = readtag("MCN"); + if (p && *p) { + setmcn(p, &trackp[0]); + txp = gettextptr(0, trackp); /* MCN is isrc for trk 0*/ + txp->tc_isrc = savestr(p); + } + + p = readtag("ISRC"); + if (p && *p) { + setisrc(p, &trackp[track]); + txp = gettextptr(track, trackp); + txp->tc_isrc = savestr(p); + } + + p = readtstr("Albumperformer"); + if (p && *p) { + txp = gettextptr(0, trackp); /* Album perf. in trk 0*/ + txp->tc_performer = savestr(p); + } + p = readtstr("Performer"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_performer = savestr(p); + } + p = readtstr("Albumtitle"); + if (p && *p) { + txp = gettextptr(0, trackp); /* Album title in trk 0*/ + txp->tc_title = savestr(p); + } + p = readtstr("Tracktitle"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_title = savestr(p); + } + p = readtstr("Songwriter"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_songwriter = savestr(p); + } + p = readtstr("Composer"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_composer = savestr(p); + } + p = readtstr("Arranger"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_arranger = savestr(p); + } + p = readtstr("Message"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_message = savestr(p); + } + p = readtstr("Diskid"); + if (p && *p) { + txp = gettextptr(0, trackp); /* Disk id is in trk 0*/ + txp->tc_title = savestr(p); + } + p = readtstr("Closed_info"); + if (p && *p) { + txp = gettextptr(track, trackp); + txp->tc_closed_info = savestr(p); + } + + p = readtag("Tracknumber"); + if (p && isdao) + astol(p, &tno); + + p = readtag("Trackstart"); + if (p && isdao) { + l = -1L; + astol(p, &l); + if (track == 1 && tno == 1 && l > 0) { + trackp[1].pregapsize = 150 + l; + printf("Track1 Start: '%s' (%ld)\n", p, l); + } + } + + p = readtag("Tracklength"); + + p = readtag("Pre-emphasis"); + if (p && *p) { + if (strncmp(p, "yes", 3) == 0) { + tp->flags |= TI_PREEMP; + if ((tp->tracktype & TOC_MASK) == TOC_DA) + tp->sectype = SECT_AUDIO_PRE; + + } else if (strncmp(p, "no", 2) == 0) { + tp->flags &= ~TI_PREEMP; + if ((tp->tracktype & TOC_MASK) == TOC_DA) + tp->sectype = SECT_AUDIO_NOPRE; + } + } + + p = readtag("Channels"); + p = readtag("Copy_permitted"); + if (p && *p) { + /* + * -useinfo always wins + */ + tp->flags &= ~(TI_COPY|TI_SCMS); + + if (strncmp(p, "yes", 3) == 0) + tp->flags |= TI_COPY; + else if (strncmp(p, "no", 2) == 0) + tp->flags |= TI_SCMS; + else if (strncmp(p, "once", 2) == 0) + tp->flags &= ~(TI_COPY|TI_SCMS); + } + p = readtag("Endianess"); + p = readtag("Index"); + if (p && *p && isdao) + setindex(p, &trackp[track]); + + p = readtag("Index0"); + if (p && isdao) { + Llong ts; + Llong ps; + + l = -2L; + astol(p, &l); + if (l == -1) { + trackp[track+1].pregapsize = 0; + } else if (l > 0) { + ts = tp->itracksize / tp->isecsize; + ps = ts - l; + if (ps > 0) + trackp[track+1].pregapsize = ps; + } + } + } + +} + +textptr_t * +gettextptr(int track, track_t *trackp) +{ + register textptr_t *txp; + + txp = (textptr_t *)trackp[track].text; + if (txp == NULL) { + txp = malloc(sizeof (textptr_t)); + if (txp == NULL) + comerr("Cannot malloc CD-Text structure.\n"); + fillbytes(txp, sizeof (textptr_t), '\0'); + trackp[track].text = txp; + } + return (txp); +} + +static char * +savestr(char *str) +{ + char *ret; + + ret = malloc(strlen(str)+1); + if (ret) + strcpy(ret, str); + else + comerr("Cannot malloc auinfo string.\n"); + return (ret); +} + +static char * +readtag(char *name) +{ + register char *p; + + p = cfg_get(name); + if (debug) + printf("%s '%s'\n", name, p); + return (p); +} + +static char * +readtstr(char *name) +{ + register char *p; + register char *p2; + + p = readtag(name); + if (p && *p == '\'') { + p2 = ++p; + while (*p2 != '\0') + p2++; + while (p2 > p && *p2 != '\'') + p2--; + *p2 = '\0'; + if (debug) + printf("%s '%s'\n", name, p); + } + return (p); +} + +/* + * Media catalog number is a 13 digit number. + */ +void +setmcn(char *mcn, track_t *trackp) +{ + register char *p; + + if (strlen(mcn) != 13) + comerrno(EX_BAD, "MCN '%s' has illegal length.\n", mcn); + + for (p = mcn; *p; p++) { + if (*p < '0' || *p > '9') + comerrno(EX_BAD, "MCN '%s' contains illegal character '%c'.\n", mcn, *p); + } + p = malloc(14); + strcpy(p, mcn); + trackp->isrc = p; + + if (debug) + printf("Track %d MCN: '%s'\n", (int)trackp->trackno, trackp->isrc); +} + +static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static void +isrc_illchar(char *isrc, int c) +{ + errmsgno(EX_BAD, "ISRC '%s' contains illegal character '%c'.\n", isrc, c); +} + +/* + * ISRC is 12 Byte: + * + * Country code 'C' (alpha) 2 Bytes + * Owner code 'O' (alphanumeric) 3 Bytes + * Year of record 'Y' (numeric) 2 Bytes + * Serial number 'S' (numeric) 5 Bytes + * + * CC-OOO-YY-SSSSS + */ +void +setisrc(char *isrc, track_t *trackp) +{ + char ibuf[13]; + char *ip; + char *p; + int i; + int len; + + if ((len = strlen(isrc)) != 12) { + for (p = isrc, i = 0; *p; p++) { + if (*p == '-') + i++; + } + if (((len - i) != 12) || i > 3) + comerrno(EX_BAD, "ISRC '%s' has illegal length.\n", isrc); + } + + /* + * The country code. + */ + for (p = isrc, ip = ibuf, i = 0; i < 2; p++, i++) { + *ip++ = *p; + if (!strchr(upper, *p)) { +/* goto illchar;*/ + /* + * Flag numbers but accept them. + */ + isrc_illchar(isrc, *p); + if (*p >= '0' && *p <= '9') + continue; + exit(EX_BAD); + } + } + if (*p == '-') + p++; + + /* + * The owner code. + */ + for (i = 0; i < 3; p++, i++) { + *ip++ = *p; + if (strchr(upper, *p)) + continue; + if (*p >= '0' && *p <= '9') + continue; + goto illchar; + } + if (*p == '-') + p++; + + /* + * The Year and the recording number (2 + 5 numbers). + */ + for (i = 0; i < 7; p++, i++) { + *ip++ = *p; + if (*p >= '0' && *p <= '9') + continue; + if (*p == '-' && i == 2) { + ip--; + i--; + continue; + } + goto illchar; + } + *ip = '\0'; + p = malloc(13); + strcpy(p, ibuf); + trackp->isrc = p; + + if (debug) + printf("Track %d ISRC: '%s'\n", (int)trackp->trackno, trackp->isrc); + return; +illchar: + isrc_illchar(isrc, *p); + exit(EX_BAD); +} + +void +setindex(char *tindex, track_t *trackp) +{ + char *p; + int i; + int nindex; + long idx; + long *idxlist; + + idxlist = malloc(100*sizeof (long)); + p = tindex; + idxlist[0] = 0; + i = 0; + while (*p) { + p = astol(p, &idx); + if (*p != '\0' && *p != ' ' && *p != '\t' && *p != ',') + goto illchar; + i++; + if (i > 99) + comerrno(EX_BAD, "Too many indices for track %d\n", (int)trackp->trackno); + idxlist[i] = idx; + if (*p == ',') + p++; + while (*p == ' ' || *p == '\t') + p++; + } + nindex = i; + + if (debug) + printf("Track %d %d Index: '%s'\n", (int)trackp->trackno, i, tindex); + + if (debug) { + for (i = 0; i <= nindex; i++) + printf("%d: %ld\n", i, idxlist[i]); + } + + trackp->nindex = nindex; + trackp->tindex = idxlist; + return; +illchar: + comerrno(EX_BAD, "Index '%s' contains illegal character '%c'.\n", tindex, *p); +} diff --git a/wodim/cd_misc.c b/wodim/cd_misc.c new file mode 100644 index 0000000..b9970bb --- /dev/null +++ b/wodim/cd_misc.c @@ -0,0 +1,144 @@ +/* + * 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. + * + */ + +/* @(#)cd_misc.c 1.10 01/10/29 Copyright 1997 J. Schilling */ +/* + * Misc CD support routines + * + * Copyright (c) 1997 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 <standard.h> +#include <utypes.h> /* Includes <sys/types.h> for caddr_t */ +#include <stdio.h> +#include <schily.h> + +#include "wodim.h" + +int from_bcd(int b); +int to_bcd(int i); +long msf_to_lba(int m, int s, int f, BOOL force_positive); +BOOL lba_to_msf(long lba, msf_t *mp); +void sec_to_msf(long sec, msf_t *mp); +void print_min_atip(long li, long lo); + +int +from_bcd(int b) +{ + return ((b & 0x0F) + 10 * (((b)>> 4) & 0x0F)); +} + +int +to_bcd(int i) +{ + return (i % 10 | ((i / 10) % 10) << 4); +} + +long +msf_to_lba(int m, int s, int f, BOOL force_positive) +{ + long ret = m * 60 + s; + + ret *= 75; + ret += f; + if (m < 90 || force_positive) + ret -= 150; + else + ret -= 450150; + return (ret); +} + +BOOL +lba_to_msf(long lba, msf_t *mp) +{ + int m; + int s; + int f; + +#ifdef __follow_redbook__ + if (lba >= -150 && lba < 405000) { /* lba <= 404849 */ +#else + if (lba >= -150) { +#endif + m = (lba + 150) / 60 / 75; + s = (lba + 150 - m*60*75) / 75; + f = (lba + 150 - m*60*75 - s*75); + + } else if (lba >= -45150 && lba <= -151) { + m = (lba + 450150) / 60 / 75; + s = (lba + 450150 - m*60*75) / 75; + f = (lba + 450150 - m*60*75 - s*75); + + } else { + mp->msf_min = -1; + mp->msf_sec = -1; + mp->msf_frame = -1; + + return (FALSE); + } + mp->msf_min = m; + mp->msf_sec = s; + mp->msf_frame = f; + + if (lba > 404849) /* 404850 -> 404999: lead out */ + return (FALSE); + return (TRUE); +} + +void +sec_to_msf(long sec, msf_t *mp) +{ + int m; + int s; + int f; + + m = (sec) / 60 / 75; + s = (sec - m*60*75) / 75; + f = (sec - m*60*75 - s*75); + + mp->msf_min = m; + mp->msf_sec = s; + mp->msf_frame = f; +} + +void +print_min_atip(long li, long lo) +{ + msf_t msf; + + if (li < 0) { + lba_to_msf(li, &msf); + + printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n", + li, msf.msf_min, msf.msf_sec, msf.msf_frame); + } + if (lo > 0) { + lba_to_msf(lo, &msf); + printf(" ATIP start of lead out: %ld (%02d:%02d/%02d)\n", + lo, msf.msf_min, msf.msf_sec, msf.msf_frame); + } +} diff --git a/wodim/cdr_drv.c b/wodim/cdr_drv.c new file mode 100644 index 0000000..a40afa3 --- /dev/null +++ b/wodim/cdr_drv.c @@ -0,0 +1,318 @@ +/* + * 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. + * + */ + +/* @(#)cdr_drv.c 1.36 04/03/02 Copyright 1997-2004 J. Schilling */ +/* + * CDR device abstraction layer + * + * Copyright (c) 1997-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 <stdxlib.h> +#include <unixstd.h> /* Include sys/types.h to make off_t available */ +#include <standard.h> +#include <schily.h> + +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "wodim.h" + +extern int xdebug; + +extern cdr_t cdr_oldcd; +extern cdr_t cdr_cd; +extern cdr_t cdr_mmc; +extern cdr_t cdr_mdvd; +extern cdr_t cdr_mmc_sony; +extern cdr_t cdr_cd_dvd; +extern cdr_t cdr_philips_cdd521O; +extern cdr_t cdr_philips_dumb; +extern cdr_t cdr_philips_cdd521; +extern cdr_t cdr_philips_cdd522; +extern cdr_t cdr_tyuden_ew50; +extern cdr_t cdr_kodak_pcd600; +extern cdr_t cdr_pioneer_dw_s114x; +extern cdr_t cdr_plasmon_rf4100; +extern cdr_t cdr_yamaha_cdr100; +extern cdr_t cdr_sony_cdu924; +extern cdr_t cdr_ricoh_ro1060; +extern cdr_t cdr_ricoh_ro1420; +extern cdr_t cdr_teac_cdr50; +extern cdr_t cdr_cw7501; +extern cdr_t cdr_cdr_simul; +extern cdr_t cdr_dvd_simul; + +cdr_t *drive_identify(SCSI *usalp, cdr_t *, struct scsi_inquiry *ip); +int drive_attach(SCSI *usalp, cdr_t *); +int attach_unknown(void); +int blank_dummy(SCSI *usalp, cdr_t *, long addr, int blanktype); +int format_dummy(SCSI *usalp, cdr_t *, int fmtflags); +int drive_getdisktype(SCSI *usalp, cdr_t *dp); +int cmd_ill(SCSI *usalp); +int cmd_dummy(SCSI *usalp, cdr_t *); +int no_sendcue(SCSI *usalp, cdr_t *, track_t *trackp); +int buf_dummy(SCSI *usalp, long *sp, long *fp); +BOOL set_cdrcmds(char *name, cdr_t **dpp); +cdr_t *get_cdrcmds(SCSI *usalp); + +/* + * List of CD-R drivers + */ +cdr_t *drivers[] = { + &cdr_cd_dvd, + &cdr_mmc, + &cdr_mdvd, + &cdr_mmc_sony, + &cdr_cd, + &cdr_oldcd, + &cdr_philips_cdd521O, + &cdr_philips_dumb, + &cdr_philips_cdd521, + &cdr_philips_cdd522, + &cdr_tyuden_ew50, + &cdr_kodak_pcd600, + &cdr_pioneer_dw_s114x, + &cdr_plasmon_rf4100, + &cdr_yamaha_cdr100, + &cdr_ricoh_ro1060, + &cdr_ricoh_ro1420, + &cdr_sony_cdu924, + &cdr_teac_cdr50, + &cdr_cw7501, + &cdr_cdr_simul, + &cdr_dvd_simul, + (cdr_t *)NULL, +}; + +cdr_t * +drive_identify(SCSI *usalp, cdr_t *dp, struct scsi_inquiry *ip) +{ + return (dp); +} + +int +drive_attach(SCSI *usalp, cdr_t *dp) +{ + return (0); +} + +int +attach_unknown() +{ + errmsgno(EX_BAD, "Unsupported drive type\n"); + return (-1); +} + +int +blank_dummy(SCSI *usalp, cdr_t *dp, long addr, int blanktype) +{ + printf("This drive or media does not support the 'BLANK media' command\n"); + return (-1); +} + +int +format_dummy(SCSI *usalp, cdr_t *dp, int fmtflags) +{ + printf("This drive or media does not support the 'FORMAT media' command\n"); + return (-1); +} + +int +drive_getdisktype(SCSI *usalp, cdr_t *dp) +{ +/* dstat_t *dsp = dp->cdr_dstat;*/ + return (0); +} + +int +cmd_ill(SCSI *usalp) +{ + errmsgno(EX_BAD, "Unspecified command not implemented for this drive.\n"); + return (-1); +} + +int +cmd_dummy(SCSI *usalp, cdr_t *dp) +{ + return (0); +} + +int +no_sendcue(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + errmsgno(EX_BAD, "SAO writing not available or not implemented for this drive.\n"); + return (-1); +} + +int +buf_dummy(SCSI *usalp, long *sp, long *fp) +{ + return (-1); +} + +BOOL +set_cdrcmds(char *name, cdr_t **dpp) +{ + cdr_t **d; + int n; + + for (d = drivers; *d != (cdr_t *)NULL; d++) { + if (streql((*d)->cdr_drname, name)) { + if (dpp != NULL) + *dpp = *d; + return (TRUE); + } + } + if (dpp == NULL) + return (FALSE); + + if (!streql("help", name)) + fprintf(stderr, "Illegal driver type '%s'.\n", name); + + fprintf(stderr, "Driver types:\n"); + for (d = drivers; *d != (cdr_t *)NULL; d++) { + fprintf(stderr, "%s%n", + (*d)->cdr_drname, &n); + fprintf(stderr, "%*s%s\n", + 20-n, "", + (*d)->cdr_drtext); + } + if (streql("help", name)) + exit(0); + exit(EX_BAD); + return (FALSE); /* Make lint happy */ +} + +cdr_t * +get_cdrcmds(SCSI *usalp) +{ + cdr_t *dp = (cdr_t *)0; + cdr_t *odp = (cdr_t *)0; + BOOL is_wr = FALSE; + BOOL is_cd = FALSE; + BOOL is_dvd = FALSE; + BOOL is_dvdplus = FALSE; + BOOL is_ddcd = FALSE; + BOOL is_cdwr = FALSE; + BOOL is_dvdwr = FALSE; + BOOL is_dvdpluswr = FALSE; + BOOL is_ddcdwr = FALSE; + + /* + * First check for SCSI-3/mmc-3 drives. + */ + if (get_proflist(usalp, &is_wr, &is_cd, &is_dvd, + &is_dvdplus, &is_ddcd) >= 0) { + + get_wproflist(usalp, &is_cdwr, &is_dvdwr, + &is_dvdpluswr, &is_ddcdwr); + if (xdebug) { + fprintf(stderr, + "Found MMC-3 %s CD: %s/%s DVD-: %s/%s DVD+: %s/%s DDCD: %s/%s.\n", + is_wr ? "writer": "reader", + is_cd?"r":"-", + is_cdwr?"w":"-", + is_dvd?"r":"-", + is_dvdwr?"w":"-", + is_dvdplus?"r":"-", + is_dvdpluswr?"w":"-", + is_ddcd?"r":"-", + is_ddcdwr?"w":"-"); + } + if (!is_wr) { + dp = &cdr_cd; + } else { + dp = &cdr_cd_dvd; + } + } else + /* + * First check for SCSI-3/mmc drives. + */ + if (is_mmc(usalp, &is_cdwr, &is_dvdwr)) { + if (xdebug) { + fprintf(stderr, "Found MMC drive CDWR: %d DVDWR: %d.\n", + is_cdwr, is_dvdwr); + } + + if (is_cdwr && is_dvdwr) + dp = &cdr_cd_dvd; + else + dp = &cdr_mmc; + + } else switch (usalp->dev) { + + case DEV_CDROM: dp = &cdr_oldcd; break; + case DEV_MMC_CDROM: dp = &cdr_cd; break; + case DEV_MMC_CDR: dp = &cdr_mmc; break; + case DEV_MMC_CDRW: dp = &cdr_mmc; break; + case DEV_MMC_DVD_WR: dp = &cdr_cd_dvd; break; + + case DEV_CDD_521_OLD: dp = &cdr_philips_cdd521O; break; + case DEV_CDD_521: dp = &cdr_philips_cdd521; break; + case DEV_CDD_522: + case DEV_CDD_2000: + case DEV_CDD_2600: dp = &cdr_philips_cdd522; break; + case DEV_TYUDEN_EW50: dp = &cdr_tyuden_ew50; break; + case DEV_PCD_600: dp = &cdr_kodak_pcd600; break; + case DEV_YAMAHA_CDR_100:dp = &cdr_yamaha_cdr100; break; + case DEV_MATSUSHITA_7501:dp = &cdr_cw7501; break; + case DEV_MATSUSHITA_7502: + case DEV_YAMAHA_CDR_400:dp = &cdr_mmc; break; + case DEV_PLASMON_RF_4100:dp = &cdr_plasmon_rf4100; break; + case DEV_SONY_CDU_924: dp = &cdr_sony_cdu924; break; + case DEV_RICOH_RO_1060C:dp = &cdr_ricoh_ro1060; break; + case DEV_RICOH_RO_1420C:dp = &cdr_ricoh_ro1420; break; + case DEV_TEAC_CD_R50S: dp = &cdr_teac_cdr50; break; + + case DEV_PIONEER_DW_S114X: dp = &cdr_pioneer_dw_s114x; break; + + default: dp = &cdr_mmc; + } + odp = dp; + + if (xdebug) { + fprintf(stderr, "Using driver '%s' for identify.\n", + dp != NULL ? + dp->cdr_drname : + "<no driver>"); + } + + if (dp != (cdr_t *)0) + dp = dp->cdr_identify(usalp, dp, usalp->inq); + + if (xdebug && dp != odp) { + fprintf(stderr, "Identify set driver to '%s'.\n", + dp != NULL ? + dp->cdr_drname : + "<no driver>"); + } + + return (dp); +} diff --git a/wodim/cdtext.c b/wodim/cdtext.c new file mode 100644 index 0000000..40df2a5 --- /dev/null +++ b/wodim/cdtext.c @@ -0,0 +1,546 @@ +/* + * 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. + * + */ + +/* @(#)cdtext.c 1.10 04/03/01 Copyright 1999-2004 J. Schilling */ +/* + * Generic CD-Text support functions + * + * Copyright (c) 1999-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 <stdxlib.h> +#include <unixstd.h> /* Include sys/types.h to make off_t available */ +#include <standard.h> +#include <utypes.h> +#include <strdefs.h> +#include <schily.h> + +#include <usal/scsitransp.h> /* For write_leadin() */ + +#include "cdtext.h" +#include "wodim.h" +#include "crc16.h" + +#define PTI_TITLE 0x80 /* Album name and Track titles */ +#define PTI_PERFORMER 0x81 /* Singer/player/conductor/orchestra */ +#define PTI_SONGWRITER 0x82 /* Name of the songwriter */ +#define PTI_COMPOSER 0x83 /* Name of the composer */ +#define PTI_ARRANGER 0x84 /* Name of the arranger */ +#define PTI_MESSAGE 0x85 /* Message from content provider or artist */ +#define PTI_DISK_ID 0x86 /* Disk identification information */ +#define PTI_GENRE 0x87 /* Genre identification / information */ +#define PTI_TOC 0x88 /* TOC information */ +#define PTI_TOC2 0x89 /* Second TOC */ +#define PTI_RES_8A 0x8A /* Reserved 8A */ +#define PTI_RES_8B 0x8B /* Reserved 8B */ +#define PTI_RES_8C 0x8C /* Reserved 8C */ +#define PTI_CLOSED_INFO 0x8D /* For internal use by content provider */ +#define PTI_ISRC 0x8E /* UPC/EAN code of album and ISRC for tracks */ +#define PTI_SIZE 0x8F /* Size information of the block */ + +extern int xdebug; + +typedef struct textpack { + Uchar pack_type; /* Pack Type indicator */ + char track_no; /* Track Number (0..99) */ + char seq_number; /* Sequence Number */ + char block_number; /* Block # / Char pos */ + char text[12]; /* CD-Text Data field */ + char crc[2]; /* CRC 16 */ +} txtpack_t; + +#define EXT_DATA 0x80 /* Extended data indicator in track_no */ +#define DBCC 0x80 /* Double byte char indicator in block */ + +/* + * CD-Text size example: + * + * 0 1 2 3 00 01 02 03 04 05 06 07 08 09 10 11 CRC16 + * + * 8F 00 2B 00 01 01 0D 03 0C 0C 00 00 00 00 01 00 7B 3D + * 8F 01 2C 00 00 00 00 00 00 00 12 03 2D 00 00 00 DA B7 + * 8F 02 2D 00 00 00 00 00 09 00 00 00 00 00 00 00 6A 24 + * + * charcode 1 + * first tr 1 + * last tr 13 + * Copyr 3 + * Pack Count 80= 12, 81 = 12, 86 = 1, 8e = 18, 8f = 3 + * last seq 0 = 2d + * languages 0 = 9 + */ + +typedef struct textsizes { + char charcode; + char first_track; + char last_track; + char copyr_flags; + char pack_count[16]; + char last_seqnum[8]; + char language_codes[8]; +} txtsize_t; + +typedef struct textargs { + txtpack_t *tp; + char *p; + txtsize_t *tsize; + int seqno; +} txtarg_t; + + +Uchar *textsub; +int textlen; + +BOOL checktextfile(char *fname); +static void setuptextdata(Uchar *bp, int len); +static BOOL cdtext_crc_ok(struct textpack *p); +void packtext(int tracks, track_t *trackp); +static BOOL anytext(int pack_type, int tracks, track_t *trackp); +static void fillup_pack(txtarg_t *ap); +static void fillpacks(txtarg_t *ap, char *from, int len, int track_no, int pack_type); +int write_cdtext(SCSI *usalp, cdr_t *dp, long startsec); +static void eight2six(Uchar *in, Uchar *out); +static void six2eight(Uchar *in, Uchar *out); + + +BOOL checktextfile(char *fname) +{ + FILE *f; + Uchar hbuf[4]; + Uchar *bp; + struct textpack *tp; + int len; + int crc; + int n; + int j; + off_t fs; + + if ((f = fileopen(fname, "rb")) == NULL) { + errmsg("Cannot open '%s'.\n", fname); + return (FALSE); + } + fs = filesize(f); + j = fs % sizeof (struct textpack); + if (j == 4) { + n = fileread(f, hbuf, 4); + if (n != 4) { + if (n < 0) + errmsg("Cannot read '%s'.\n", fname); + else + errmsgno(EX_BAD, "File '%s' is too small for CD-Text.\n", fname); + return (FALSE); + } + len = hbuf[0] * 256 + hbuf[1]; + len -= 2; + n = fs - 4; + if (n != len) { + errmsgno(EX_BAD, "Inconsistent CD-Text file '%s' length should be %d but is %lld\n", + fname, len+4, (Llong)fs); + return (FALSE); + } + } else if (j != 0) { + errmsgno(EX_BAD, "Inconsistent CD-Text file '%s' not a multiple of pack length\n", + fname); + return (FALSE); + } else { + len = fs; + } + printf("Text len: %d\n", len); + bp = malloc(len); + if (bp == NULL) { + errmsg("Cannot malloc CD-Text read buffer.\n"); + return (FALSE); + } + n = fileread(f, bp, len); + + tp = (struct textpack *)bp; + for (n = 0; n < len; n += sizeof (struct textpack), tp++) { + if (tp->pack_type < 0x80 || tp->pack_type > 0x8F) { + errmsgno(EX_BAD, "Illegal pack type 0x%02X pack #%ld in CD-Text file '%s'.\n", + tp->pack_type, (long)(n/sizeof (struct textpack)), fname); + return (FALSE); + } + crc = (tp->crc[0] & 0xFF) << 8 | (tp->crc[1] & 0xFF); + crc ^= 0xFFFF; + if (crc != calcCRC((Uchar *)tp, sizeof (*tp)-2)) { + if (cdtext_crc_ok(tp)) { + errmsgno(EX_BAD, + "Corrected CRC ERROR in pack #%ld (offset %d-%ld) in CD-Text file '%s'.\n", + (long)(n/sizeof (struct textpack)), + n+j, (long)(n+j+sizeof (struct textpack)), + fname); + } else { + errmsgno(EX_BAD, "CRC ERROR in pack #%ld (offset %d-%ld) in CD-Text file '%s'.\n", + (long)(n/sizeof (struct textpack)), + n+j, (long)(n+j+sizeof (struct textpack)), + fname); + return (FALSE); + } + } + } + setuptextdata(bp, len); + free(bp); + + return (TRUE); +} + +static void setuptextdata(Uchar *bp, int len) +{ + int n; + int i; + int j; + Uchar *p; + + if (xdebug) { + printf("%ld packs %% 4 = %ld\n", + (long)(len/sizeof (struct textpack)), + (long)(len/sizeof (struct textpack)) % 4); + } + i = (len/sizeof (struct textpack)) % 4; + if (i == 0) { + n = len; + } else if (i == 2) { + n = 2 * len; + } else { + n = 4 * len; + } + n = (n * 4) / 3; + p = malloc(n); + if (p == NULL) { + errmsg("Cannot malloc CD-Text write buffer.\n"); + } + for (i = 0, j = 0; j < n; ) { + eight2six(&bp[i%len], &p[j]); + i += 3; + j += 4; + } + textsub = p; + textlen = n; + +#ifdef DEBUG + { + Uchar sbuf[10000]; + struct textpack *tp; + FILE *f; + int crc; + + tp = (struct textpack *)bp; + p = sbuf; + for (n = 0; n < len; n += sizeof (struct textpack), tp++) { + crc = (tp->crc[0] & 0xFF) << 8 | (tp->crc[1] & 0xFF); + crc ^= 0xFFFF; + + printf("Pack:%3d ", n/ sizeof (struct textpack)); + printf("Pack type: %02X ", tp->pack_type & 0xFF); + printf("Track #: %2d ", tp->track_no & 0xFF); + printf("Sequence #:%3d ", tp->seq_number & 0xFF); + printf("Block #:%3d ", tp->block_number & 0xFF); + printf("CRC: %04X (%04X) ", crc, calcCRC((Uchar *)tp, sizeof (*tp)-2)); + printf("Text: '%.12s'\n", tp->text); + movebytes(tp->text, p, 12); + p += 12; + } + printf("len total: %d\n", n); + f = fileopen("cdtext.out", "wctb"); + if (f) { + filewrite(f, sbuf, p - sbuf); + fflush(f); + fclose(f); + } + } +#endif +} + +static BOOL cdtext_crc_ok(struct textpack *p) +{ + int crc; + struct textpack new; + + movebytes(p, &new, sizeof (struct textpack)); + new.crc[0] ^= 0xFF; + new.crc[1] ^= 0xFF; + crc = calcCRC((Uchar *)&new, sizeof (struct textpack)); + crc = flip_crc_error_corr((Uchar *)&new, sizeof (struct textpack), crc); + new.crc[0] ^= 0xFF; + new.crc[1] ^= 0xFF; + if (crc == 0) + movebytes(&new, p, 18); + + return (crc == 0); +} + + +void packtext(int tracks, track_t *trackp) +{ + int type; + int i; + struct textpack *tp; + struct textsizes tsize; + txtarg_t targ; + char sbuf[256*18]; + + fillbytes(sbuf, sizeof (sbuf), 0); + fillbytes(&tsize, sizeof (tsize), 0); + + tsize.charcode = CC_8859_1; /* ISO-8859-1 */ + tsize.first_track = trackp[1].trackno; + tsize.last_track = trackp[1].trackno + tracks - 1; +#ifdef __FOUND_ON_COMMERCIAL_CD__ + tsize.copyr_flags = 3; /* for titles/names */ +#else + tsize.copyr_flags = 0; /* no Copyr. limitat. */ +#endif + tsize.pack_count[0x0F] = 3; /* 3 size packs */ + tsize.last_seqnum[0] = 0; /* Start value only */ + tsize.language_codes[0] = LANG_ENGLISH; /* English */ + + tp = (struct textpack *)sbuf; + + targ.tp = tp; + targ.p = NULL; + targ.tsize = &tsize; + targ.seqno = 0; + + for (type = 0; type <= 0x0E; type++) { + register int maxtrk; + register char *s; + + if (!anytext(type, tracks, trackp)) + continue; + maxtrk = tsize.last_track; + if (type == 6) { + maxtrk = 0; + } + for (i = 0; i <= maxtrk; i++) { + s = trackp[i].text; + if (s) + s = ((textptr_t *)s)->textcodes[type]; + if (s) + fillpacks(&targ, s, strlen(s)+1, i, 0x80| type); + else + fillpacks(&targ, "", 1, i, 0x80| type); + + } + fillup_pack(&targ); + } + + /* + * targ.seqno overshoots by one and we add 3 size packs... + */ + tsize.last_seqnum[0] = targ.seqno + 2; + + for (i = 0; i < 3; i++) { + fillpacks(&targ, &((char *)(&tsize))[i*12], 12, i, 0x8f); + } + + setuptextdata((Uchar *)sbuf, targ.seqno*18); + +#ifdef DEBUG + { FILE *f; + + f = fileopen("cdtext.new", "wctb"); + if (f) { + filewrite(f, sbuf, targ.seqno*18); + fflush(f); + fclose(f); + } + } +#endif +} + +static BOOL anytext(int pack_type, int tracks, track_t *trackp) +{ + register int i; + register char *p; + + for (i = 0; i <= tracks; i++) { + if (trackp[i].text == NULL) + continue; + p = ((textptr_t *)(trackp[i].text))->textcodes[pack_type]; + if (p != NULL && *p != '\0') + return (TRUE); + } + return (FALSE); +} + +static void fillup_pack(register txtarg_t *ap) +{ + if (ap->p) { + fillbytes(ap->p, &ap->tp->text[12] - ap->p, '\0'); + fillcrc((Uchar *)ap->tp, sizeof (*ap->tp)); + ap->p = 0; + ap->tp++; + } +} + +static void fillpacks(register txtarg_t *ap, register char *from, int len, + int track_no, int pack_type) +{ + register int charpos; + register char *p; + register txtpack_t *tp; + + tp = ap->tp; + p = ap->p; + charpos = 0; + do { + if (p == 0) { + p = tp->text; + tp->pack_type = pack_type; + if (pack_type != 0x8f) + ap->tsize->pack_count[pack_type & 0x0F]++; + tp->track_no = track_no; + tp->seq_number = ap->seqno++; + if (charpos < 15) + tp->block_number = charpos; + else + tp->block_number = 15; + } + for (; --len >= 0 && p < &tp->text[12]; charpos++) { + *p++ = *from++; + } + len++; /* Overshoot compensation */ + + if (p >= &tp->text[12]) { + fillcrc((Uchar *)tp, sizeof (*tp)); + p = 0; + tp++; + } + } while (len > 0); + + ap->tp = tp; + ap->p = p; +} + +int write_cdtext(SCSI *usalp, cdr_t *dp, long startsec) +{ + char *bp = (char *)textsub; + int buflen = textlen; + long amount; + long bytes = 0; + long end = -150; + int secspt = textlen / 96; + int bytespt = textlen; + long maxdma = usalp->maxbuf; + int idx; + int secs; + int nbytes; + +/*maxdma = 4320;*/ + if (maxdma >= (2*textlen)) { + /* + * Try to make each CD-Text transfer use as much data + * as possible. + */ + bp = usalp->bufptr; + for (idx = 0; (idx + textlen) <= maxdma; idx += textlen) + movebytes(textsub, &bp[idx], textlen); + buflen = idx; + secspt = buflen / 96; + bytespt = buflen; +/*printf("textlen: %d buflen: %d secspt: %d\n", textlen, buflen, secspt);*/ + } else if (maxdma < buflen) { + /* + * We have more CD-Text data than we may transfer at once. + */ + secspt = maxdma / 96; + bytespt = secspt * 96; + } + while (startsec < end) { + if ((end - startsec) < secspt) { + secspt = end - startsec; + bytespt = secspt * 96; + } + idx = 0; + secs = secspt; + nbytes = bytespt; + do { /* loop over CD-Text data buffer */ + + if ((idx + nbytes) > buflen) { + nbytes = buflen - idx; + secs = nbytes / 96; + } +/*printf("idx: %d nbytes: %d secs: %d startsec: %ld\n",*/ +/*idx, nbytes, secs, startsec);*/ + amount = write_secs(usalp, dp, + (char *)&bp[idx], startsec, nbytes, secs, FALSE); + if (amount < 0) { + printf("write CD-Text data: error after %ld bytes\n", + bytes); + return (-1); + } + bytes += amount; + idx += amount; + startsec += secs; + } while (idx < buflen && startsec < end); + } + return (0); +} + + +/* + * 3 input bytes (8 bit based) are converted into 4 output bytes (6 bit based). + */ +static void eight2six(register Uchar *in, register Uchar *out) +{ + register int c; + + c = in[0]; + out[0] = (c >> 2) & 0x3F; + out[1] = (c & 0x03) << 4; + + c = in[1]; + out[1] |= (c & 0xF0) >> 4; + out[2] = (c & 0x0F) << 2; + + c = in[2]; + out[2] |= (c & 0xC0) >> 6; + out[3] = c & 0x3F; +} + +/* + * 4 input bytes (6 bit based) are converted into 3 output bytes (8 bit based). + */ +static void six2eight(register Uchar *in, register Uchar *out) +{ + register int c; + + c = in[0] & 0x3F; + out[0] = c << 2; + + c = in[1] & 0x3F; + out[0] |= c >> 4; + out[1] = c << 4; + + c = in[2] & 0x3F; + out[1] |= c >> 2; + out[2] = c << 6; + + c = in[3] & 0x3F; + out[2] |= c; +} diff --git a/wodim/cdtext.h b/wodim/cdtext.h new file mode 100644 index 0000000..89808c6 --- /dev/null +++ b/wodim/cdtext.h @@ -0,0 +1,143 @@ +/* + * 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. + * + */ + +/* @(#)cdtext.h 1.5 04/03/02 Copyright 1999-2004 J. Schilling */ +/* + * Generic CD-Text support definitions + * + * Copyright (c) 1999-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. + */ + +#ifndef CDTEXT_H +#define CDTEXT_H + +/* + * Strings for the CD-Text Pack Type indicators 0x80...0x8F + * We cannot use a plain structure here because we like to loop + * over all members. + */ +typedef struct textcodes { + char *textcodes[16]; +} textptr_t; + +#define tc_title textcodes[0x00] +#define tc_performer textcodes[0x01] +#define tc_songwriter textcodes[0x02] +#define tc_composer textcodes[0x03] +#define tc_arranger textcodes[0x04] +#define tc_message textcodes[0x05] +#define tc_diskid textcodes[0x06] +#define tc_genre textcodes[0x07] +#define tc_toc textcodes[0x08] +#define tc_toc2 textcodes[0x09] + +#define tc_closed_info textcodes[0x0d] +#define tc_isrc textcodes[0x0e] + +/* + * binaere Felder sind + * Disc ID (Wirklich ???) + * Genre ID + * TOC + * Second TOC + * Size information + */ + +/* + * Genre codes from Enhanced CD Specification page 21 + */ +#define GENRE_UNUSED 0 /* not used */ +#define GENRE_UNDEFINED 1 /* not defined */ +#define GENRE_ADULT_CONTEMP 2 /* Adult Contemporary */ +#define GENRE_ALT_ROCK 3 /* Alternative Rock */ +#define GENRE_CHILDRENS 4 /* Childrens Music */ +#define GENRE_CLASSIC 5 /* Classical */ +#define GENRE_CHRIST_CONTEMP 6 /* Contemporary Christian */ +#define GENRE_COUNTRY 7 /* Country */ +#define GENRE_DANCE 8 /* Dance */ +#define GENRE_EASY_LISTENING 9 /* Easy Listening */ +#define GENRE_EROTIC 10 /* Erotic */ +#define GENRE_FOLK 11 /* Folk */ +#define GENRE_GOSPEL 12 /* Gospel */ +#define GENRE_HIPHOP 13 /* Hip Hop */ +#define GENRE_JAZZ 14 /* Jazz */ +#define GENRE_LATIN 15 /* Latin */ +#define GENRE_MUSICAL 16 /* Musical */ +#define GENRE_NEWAGE 17 /* New Age */ +#define GENRE_OPERA 18 /* Opera */ +#define GENRE_OPERETTA 19 /* Operetta */ +#define GENRE_POP 20 /* Pop Music */ +#define GENRE_RAP 21 /* RAP */ +#define GENRE_REGGAE 22 /* Reggae */ +#define GENRE_ROCK 23 /* Rock Music */ +#define GENRE_RYTHMANDBLUES 24 /* Rhythm & Blues */ +#define GENRE_SOUNDEFFECTS 25 /* Sound Effects */ +#define GENRE_SPOKEN_WORD 26 /* Spoken Word */ +#define GENRE_WORLD_MUSIC 28 /* World Music */ +#define GENRE_RESERVED 29 /* Reserved is 29..32767 */ +#define GENRE_RIAA 32768 /* Registration by RIAA 32768..65535 */ + +/* + * Character codings used in CD-Text data. + * Korean and Mandarin Chinese to be defined in sept 1996 + */ +#define CC_8859_1 0x00 /* ISO 8859-1 */ +#define CC_ASCII 0x01 /* ISO 646, ASCII (7 bit) */ +#define CC_RESERVED_02 0x02 /* Reserved codes 0x02..0x7f */ +#define CC_KANJI 0x80 /* Music Shift-JIS Kanji */ +#define CC_KOREAN 0x81 /* Korean */ +#define CC_CHINESE 0x82 /* Mandarin Chinese */ +#define CC_RESERVED_83 0x83 /* Reserved codes 0x83..0xFF */ + + +/* + * The language code is encoded as specified in ANNEX 1 to part 5 of EBU + * Tech 32 58 -E (1991). + * + * The current language codes are guessed + */ +#define LANG_CZECH 6 /* 0x06 */ +#define LANG_DANISH 7 /* 0x07 */ +#define LANG_GERMAN 8 /* 0x08 */ +#define LANG_ENGLISH 9 /* 0x09 */ +#define LANG_SPANISH 10 /* 0x0A */ +#define LANG_FRENCH 15 /* 0x0F */ +#define LANG_ITALIAN 21 /* 0x15 */ +#define LANG_HUNGARIAN 27 /* 0x1B */ +#define LANG_DUTCH 29 /* 0x1D */ +#define LANG_NORWEGIAN 30 /* 0x1E */ +#define LANG_POLISH 32 /* 0x20 */ +#define LANG_PORTUGUESE 33 /* 0x21 */ +#define LANG_SLOVENE 38 /* 0x26 */ +#define LANG_FINNISH 39 /* 0x27 */ +#define LANG_SWEDISH 40 /* 0x28 */ +#define LANG_RUSSIAN 86 /* 0x56 */ +#define LANG_KOREAN 101 /* 0x65 */ +#define LANG_JAPANESE 105 /* 0x69 */ +#define LANG_GREEK 112 /* 0x70 */ +#define LANG_CHINESE 117 /* 0x75 */ + +#endif diff --git a/wodim/clone.c b/wodim/clone.c new file mode 100644 index 0000000..da8fb91 --- /dev/null +++ b/wodim/clone.c @@ -0,0 +1,270 @@ +/* + * 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. + * + */ + +/* @(#)clone.c 1.7 04/03/02 Copyright 2001-2004 J. Schilling */ +/* + * Clone Subchannel processing + * + * Copyright (c) 2001-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 <fctldefs.h> +#include <strdefs.h> +#include <unixstd.h> +#include <standard.h> +#include <btorder.h> +#include <utypes.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsitransp.h> + +#include "wodim.h" +#include "crc16.h" + +#include <usal/scsireg.h> +#include "scsimmc.h" + +/*#define SAO_RAW*/ + +void clone_toc(track_t *trackp); +void clone_tracktype(track_t *trackp); + +extern int lverbose; +extern int xdebug; + +extern Uchar _subq[110][12]; +extern int _nsubh; + + +static int ctrl_first; +static int ctrl_last; +static int sectype_first; +static int sectype_last; +static int disktype; +static long loutstart; + +/* + * Read Clone TOC description from full toc file. + */ +void clone_toc(track_t *trackp) +{ + char filename[1024]; + msf_t m; + msf_t mr; + struct tocheader *tp; + struct ftrackdesc *fp; + int f; + char buf[2048]; + int amt; + int len; + int i; + int j; + int ctrladr; + Uint first = 100; + Uint last = 0; + + len = strlen(trackp[1].filename); + if (len > (sizeof (filename)-5)) { + len = sizeof (filename)-5; + } + snprintf(filename, sizeof (filename), "%.*s.toc", len, trackp[1].filename); + + f = open(filename, O_RDONLY|O_BINARY); + if (f < 0) + comerr("Cannot open '%s'.\n", filename); + amt = read(f, buf, sizeof (buf)); + + if (amt == sizeof (buf)) + comerrno(EX_BAD, "TOC too large.\n"); + close(f); + tp = (struct tocheader *)buf; + len = a_to_u_2_byte(tp->len) + sizeof (struct tocheader)-2; + + if (xdebug) { + printf("Read %d bytes TOC len: %d first session: %d last session: %d\n", + amt, len, tp->first, tp->last); + } + + fp = (struct ftrackdesc *)&buf[4]; + + for (i = 4, j = 0; i < len; i += 11) { + fp = (struct ftrackdesc *)&buf[i]; + if (xdebug) + usal_prbytes("FT", (Uchar *)&buf[i], 11); + if (fp->sess_number != 1) + comerrno(EX_BAD, "Can only copy session # 1.\n"); + + if (fp->adr == 1) { + if (fp->point < first) { + first = fp->point; + ctrl_first = fp->control; + } + if (fp->point <= 99 && fp->point > last) { + last = fp->point; + ctrl_last = fp->control; + } + } + if (fp->adr != 1) { + switch (fp->point) { + + case 0xB0: + case 0xC0: + case 0xC1: + break; + default: + continue; + } + } + m.msf_min = fp->amin; + m.msf_sec = fp->asec; + m.msf_frame = fp->aframe; + + mr.msf_min = fp->pmin; + mr.msf_sec = fp->psec; + mr.msf_frame = fp->pframe; + + if (fp->point == 0xA0) { + disktype = mr.msf_sec; + mr.msf_sec = from_bcd(mr.msf_sec); /* convert to BCD */ + } + + if (fp->point == 0xA2) + loutstart = msf_to_lba(fp->pmin, fp->psec, fp->pframe, TRUE); + ctrladr = fp->control << 4; + ctrladr |= fp->adr; + + filltpoint(_subq[j], ctrladr, fp->point, &mr); + fillttime(_subq[j], &m); + _subq[j][6] = fp->res7; + if (fp->point == 0xC0 || fp->point == 0xC1) { + _subq[j][3] = m.msf_min; + _subq[j][4] = m.msf_sec; + _subq[j][5] = m.msf_frame; + } + if (fp->point == 0xC1) { + _subq[j][7] = mr.msf_min; + _subq[j][8] = mr.msf_sec; + _subq[j][9] = mr.msf_frame; + } + if (xdebug) + usal_prbytes("TOC ", _subq[j], 12); + j++; + } + _nsubh = j; + if (xdebug) { + printf("nsubheader %d lout: %ld track 1 secs: %ld\n", j, loutstart, trackp[1].tracksecs); + printf("first %u last %u ctrl first: %X ctrl last %X\n", first, last, ctrl_first, ctrl_last); + } + if (trackp->tracks != 1) + comerrno(EX_BAD, "Clone writing currently supports only one file argument.\n"); + if (loutstart > trackp[1].tracksecs) + comerrno(EX_BAD, "Clone writing TOC length %ld does not match track length %ld\n", + loutstart, trackp[1].tracksecs); + + if (amt > len) { + sectype_first = buf[len]; + sectype_last = buf[len+1]; + if (xdebug) { + printf("sectype first: %X sectype last %X\n", + sectype_first, sectype_last); + } + } +} + + +/* + * Set tracktypes for track 0 (lead-in) & track AA (lead-out) + * + * Control 0 = audio + * Control 1 = audio preemp + * Control 2 = audio copy + * Control 3 = audio copy preemp + * Control 4 = data + * Control 5 = packet data + */ +void clone_tracktype(track_t *trackp) +{ + int tracks = trackp->tracks; + int sectype; + + sectype = SECT_ROM; + if ((ctrl_first & TM_DATA) == 0) { + sectype = SECT_AUDIO; + + if ((ctrl_first & TM_PREEM) != 0) { + trackp[0].flags |= TI_PREEMP; + } else { + trackp[0].flags &= ~TI_PREEMP; + sectype |= ST_PREEMPMASK; + } + if ((ctrl_first & TM_ALLOW_COPY) != 0) { + trackp[0].flags |= TI_COPY; + } else { + trackp[0].flags &= ~TI_COPY; + } +/* XXX ??? flags |= TI_SCMS; */ + } else { + if ((ctrl_first & TM_INCREMENTAL) != 0) { + trackp[0].flags |= TI_PACKET; + } else { + trackp[0].flags &= ~TI_PACKET; + } + if (sectype_first != 0) + sectype = sectype_first; + } + trackp[0].sectype = sectype; + + sectype = SECT_ROM; + + if ((ctrl_last & TM_DATA) == 0) { + sectype = SECT_AUDIO; + + if ((ctrl_last & TM_PREEM) != 0) { + trackp[tracks+1].flags |= TI_PREEMP; + } else { + trackp[tracks+1].flags &= ~TI_PREEMP; + sectype |= ST_PREEMPMASK; + } + if ((ctrl_last & TM_ALLOW_COPY) != 0) { + trackp[tracks+1].flags |= TI_COPY; + } else { + trackp[tracks+1].flags &= ~TI_COPY; + } +/* XXX ??? flags |= TI_SCMS; */ + } else { + if ((ctrl_first & TM_INCREMENTAL) != 0) { + trackp[0].flags |= TI_PACKET; + } else { + trackp[0].flags &= ~TI_PACKET; + if (sectype_last != 0) + sectype = sectype_last; + } + } + trackp[tracks+1].sectype = sectype; +} diff --git a/wodim/crc16.c b/wodim/crc16.c new file mode 100644 index 0000000..8eecf04 --- /dev/null +++ b/wodim/crc16.c @@ -0,0 +1,160 @@ +/* + * 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. + * + */ + +/* @(#)crc16.c 1.6 04/03/02 Copyright 1998-2004 J. Schilling */ +/* + * Q-subchannel CRC subroutines + * + * Polynom is: p(x) = x ** 16 + x ** 12 + x ** 5 + 1 + * If computed over 12 bytes, the result must be zero. + * On the disk the CRC bits are inverted. + * + * Copyright (c) 1998-2003 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 <standard.h> +#include <utypes.h> +#include "crc16.h" + +static UInt16_t updcrc(Uint p_crc, UInt8_t *cp, Uint cnt); +UInt16_t calcCRC(Uchar *buf, Uint bsize); +UInt16_t fillcrc(Uchar *buf, Uint bsize); +UInt16_t flip_crc_error_corr(Uchar *b, Uint bsize, Uint p_crc); + + + /* number of bits in CRC: don't change it. */ +#define BPW 16 + + /* this the number of bits per char: don't change it. */ +#define BPB 8 + +static UInt16_t crctab[1<<BPB] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +}; + +#define SUBSIZE 96 /* 12 bytes with 8 bits */ + +static UInt16_t +updcrc(Uint p_crc, register UInt8_t *cp, register Uint cnt) +{ + register UInt16_t crc = p_crc; + + while (cnt-- > 0) { + crc = (crc<<BPB) ^ crctab[(crc>>(BPW-BPB)) ^ (*cp++)]; + } + return (crc); +} + +/*static UInt16_t*/ +UInt16_t +calcCRC(Uchar *buf, Uint bsize) +{ + return (updcrc(0x0000, (UInt8_t *)buf, bsize)); +} + +/* + * CRC für Q-Sub füllen + */ +UInt16_t +fillcrc(Uchar *buf, Uint bsize) +{ + UInt16_t crc = calcCRC(buf, bsize-2); + + /* + * Invert CRC bits for RED Book compliance. + */ + crc = crc ^ 0xFFFF; + + buf[bsize-2] = (crc >> 8) & 0xFF; + buf[bsize-1] = crc & 0xFF; + return (crc); +} + +static UInt8_t fliptab[BPB] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80, +}; + +UInt16_t +flip_crc_error_corr(Uchar *b, Uint bsize, Uint p_crc) +{ + register UInt16_t crc = p_crc; + register Uint btsize = bsize * BPB; + + if (crc != 0) { + int i; + + for (i = 0; i < btsize; i++) { + UInt8_t c; + + c = fliptab[i % BPB]; + b[i / BPB] ^= c; + if ((crc = calcCRC(b, bsize)) == 0) { + return (crc); + } + b[i / BPB] ^= c; + } + } + return (crc & 0xffff); +} diff --git a/wodim/crc16.h b/wodim/crc16.h new file mode 100644 index 0000000..c8f425c --- /dev/null +++ b/wodim/crc16.h @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +/* @(#)crc16.h 1.3 02/03/04 Copyright 1998-2002 J. Schilling */ +/* + * Q-subchannel CRC definitions + * + * Copyright (c) 1998-2002 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. + */ + +#ifndef _CRC16_H +#define _CRC16_H + +extern UInt16_t calcCRC(Uchar *buf, Uint bsize); +extern UInt16_t fillcrc(Uchar *buf, Uint bsize); +extern UInt16_t flip_crc_error_corr(Uchar *b, Uint bsize, Uint p_crc); + +#endif diff --git a/wodim/cue.c b/wodim/cue.c new file mode 100644 index 0000000..0eb88b3 --- /dev/null +++ b/wodim/cue.c @@ -0,0 +1,1198 @@ +/* + * 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. + * + */ + +/* @(#)cue.c 1.20 04/03/02 Copyright 2001-2004 J. Schilling */ +/* + * Cue sheet parser + * + * Copyright (c) 2001-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 <stdxlib.h> +#include <unixstd.h> +#include <standard.h> +#include <fctldefs.h> +#include <statdefs.h> +#include <vadefs.h> +#include <schily.h> +#include <strdefs.h> +#include <utypes.h> +#include <ctype.h> +#include <errno.h> + +#include "xio.h" +#include "cdtext.h" +#include "wodim.h" +#include "auheader.h" +#include "libport.h" + +typedef struct state { + char *filename; + void *xfp; + Llong trackoff; + Llong filesize; + int filetype; + int tracktype; + int sectype; + int dbtype; + int secsize; + int dataoff; + int state; + int track; + int index; + long index0; + long index1; /* Current index 1 value */ + long secoff; /* Old index 1 value */ + long pregapsize; + long postgapsize; + int flags; +} state_t; + +static char linebuf[4096]; +static char *fname; +static char *linep; +static char *wordendp; +static char wordendc; +static int olinelen; +static int linelen; +static int lineno; + +static char worddelim[] = "=:,/"; +static char nulldelim[] = ""; + +#define STATE_NONE 0 +#define STATE_POSTGAP 1 +#define STATE_TRACK 2 +#define STATE_FLAGS 3 +#define STATE_INDEX0 4 +#define STATE_INDEX1 5 + +typedef struct keyw { + char *k_name; + int k_type; +} keyw_t; + +/* + * Keywords (first word on line): + * CATALOG - global CATALOG <MCN> + * CDTEXTFILE - global CDTEXTFILE <fname> + * FILE - track static FILE <fame> <type> + * FLAGS - track static FLAGS <flag> ... + * INDEX - track static INDEX <#> <mm:ss:ff> + * ISRC - track static ISRC <ISRC> + * PERFORMER - global/static PERFORMER <string> + * POSTGAP - track locak POSTGAP <mm:ss:ff> + * PREGAP - track static PREGAP <mm:ss:ff> + * REM - anywhere REM <comment> + * SONGWRITER - global/static SONGWRITER <string> + * TITLE - global/static TITLE <string> + * TRACK - track static TRACK <#> <datatype> + * + * Order of keywords: + * CATALOG + * CDTEXTFILE + * PERFORMER | SONGWRITER | TITLE Doc says past FILE... + * FILE Must be past CATALOG + * ------- Repeat the following: mehrere FILE Commands? + * TRACK + * FLAGS | ISRC | PERFORMER | PREGAP | SONGWRITER | TITLE + * INDEX + * POSTGAP + */ + +#define K_G 0x10000 /* Global */ +#define K_T 0x20000 /* Track static */ +#define K_A (K_T | K_G) /* Global & Track static */ + +#define K_MCN (0 | K_G) /* Media catalog number */ +#define K_TEXTFILE (1 | K_G) /* CD-Text binary file */ +#define K_FILE (2 | K_T) /* Input data file */ +#define K_FLAGS (3 | K_T) /* Flags for ctrl nibble */ +#define K_INDEX (4 | K_T) /* Index marker for track */ +#define K_ISRC (5 | K_T) /* ISRC string for track */ +#define K_PERFORMER (6 | K_A) /* CD-Text Performer */ +#define K_POSTGAP (7 | K_T) /* Post gap for track (autogen) */ +#define K_PREGAP (8 | K_T) /* Pre gap for track (autogen) */ +#define K_REM (9 | K_A) /* Remark (Comment) */ +#define K_SONGWRITER (10| K_A) /* CD-Text Songwriter */ +#define K_TITLE (11| K_A) /* CD-Text Title */ +#define K_TRACK (12| K_T) /* Track marker */ + + +static keyw_t keywords[] = { + { "CATALOG", K_MCN }, + { "CDTEXTFILE", K_TEXTFILE }, + { "FILE", K_FILE }, + { "FLAGS", K_FLAGS }, + { "INDEX", K_INDEX }, + { "ISRC", K_ISRC }, + { "PERFORMER", K_PERFORMER }, + { "POSTGAP", K_POSTGAP }, + { "PREGAP", K_PREGAP }, + { "REM", K_REM }, + { "SONGWRITER", K_SONGWRITER }, + { "TITLE", K_TITLE }, + { "TRACK", K_TRACK }, + { NULL, 0 }, +}; + + +/* + * Filetypes - argument to FILE Keyword (one only): + * + * BINARY - Intel binary file (least significant byte first) + * MOTOTOLA - Motorola binary file (most significant byte first) + * AIFF - Audio AIFF file + * AU - Sun Audio file + * WAVE - Audio WAVE file + * MP3 - Audio MP3 file + */ +#define K_BINARY 100 +#define K_MOTOROLA 101 +#define K_AIFF 102 +#define K_AU 103 +#define K_WAVE 104 +#define K_MP3 105 +#define K_OGG 106 + +static keyw_t filetypes[] = { + { "BINARY", K_BINARY }, + { "MOTOROLA", K_MOTOROLA }, + { "AIFF", K_AIFF }, + { "AU", K_AU }, + { "WAVE", K_WAVE }, + { "MP3", K_MP3 }, + { "OGG", K_OGG }, + { NULL, 0 }, +}; + +/* + * Flags - argument to FLAGS Keyword (more than one allowed): + * DCP - Digital copy permitted + * 4CH - Four channel audio + * PRE - Pre-emphasis enabled (audio tracks only) + * SCMS - Serial copy management system (not supported by all recorders) + */ +#define K_DCP 1000 +#define K_4CH 1001 +#define K_PRE 1002 +#define K_SCMS 1003 + +static keyw_t flags[] = { + { "DCP", K_DCP }, + { "4CH", K_4CH }, + { "PRE", K_PRE }, + { "SCMS", K_SCMS }, + { NULL, 0 }, +}; + +/* + * Datatypes - argument to TRACK Keyword (one only): + * AUDIO - Audio/Music (2352) + * CDG - Karaoke CD+G (2448) + * MODE1/2048 - CDROM Mode1 Data (cooked) + * MODE1/2352 - CDROM Mode1 Data (raw) + * MODE2/2336 - CDROM-XA Mode2 Data + * MODE2/2352 - CDROM-XA Mode2 Data + * CDI/2336 - CDI Mode2 Data + * CDI/2352 - CDI Mode2 Data + */ +#define K_AUDIO 10000 +#define K_CDG 10001 +#define K_MODE1 10002 +#define K_MODE2 10003 +#define K_CDI 10004 + +static keyw_t dtypes[] = { + { "AUDIO", K_AUDIO }, + { "CDG", K_CDG }, + { "MODE1", K_MODE1 }, + { "MODE2", K_MODE2 }, + { "CDI", K_CDI }, + { NULL, 0 }, +}; + + +int parsecue(char *cuefname, track_t trackp[]); +void fparsecue(FILE *f, track_t trackp[]); +static void parse_mcn(track_t trackp[], state_t *sp); +static void parse_textfile(track_t trackp[], state_t *sp); +static void parse_file(track_t trackp[], state_t *sp); +static void parse_flags(track_t trackp[], state_t *sp); +static void parse_index(track_t trackp[], state_t *sp); +static void parse_isrc(track_t trackp[], state_t *sp); +static void parse_performer(track_t trackp[], state_t *sp); +static void parse_postgap(track_t trackp[], state_t *sp); +static void parse_pregap(track_t trackp[], state_t *sp); +static void parse_songwriter(track_t trackp[], state_t *sp); +static void parse_title(track_t trackp[], state_t *sp); +static void parse_track(track_t trackp[], state_t *sp); +static void parse_offset(long *lp); +static void newtrack(track_t trackp[], state_t *sp); + +static keyw_t *lookup(char *word, keyw_t table[]); +static void wdebug(void); +static FILE *cueopen(char *name); +static char *cuename(void); +static char *nextline(FILE *f); +static void ungetline(void); +static char *skipwhite(const char *s); +static char *peekword(void); +static char *lineend(void); +static char *markword(char *delim); +static char *getnextitem(char *delim); +static char *neednextitem(char *delim); +static char *nextword(void); +static char *needword(void); +static char *curword(void); +static char *nextitem(void); +static char *needitem(void); +static void checkextra(void); +static void cueabort(const char *fmt, ...); + +#ifdef CUE_MAIN +int debug; +int xdebug = 1; + +int write_secs(void); +int write_secs() { return (-1); } + +int +main(int argc, char *argv[]) +{ + int i; + track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */ + + save_args(argc, argv); + + fillbytes(track, sizeof (track), '\0'); + for (i = 0; i < MAX_TRACK+2; i++) + track[i].track = track[i].trackno = i; + track[0].tracktype = TOC_MASK; + + + parsecue(argv[1], track); + return (0); +} +#else +extern int xdebug; +#endif + +int +parsecue(char *cuefname, track_t trackp[]) +{ + FILE *f = cueopen(cuefname); + + fparsecue(f, trackp); + return (0); +} + +void +fparsecue(FILE *f, track_t trackp[]) +{ + char *word; + struct keyw *kp; + BOOL isglobal = TRUE; + state_t state; + + state.filename = NULL; + state.xfp = NULL; + state.trackoff = 0; + state.filesize = 0; + state.filetype = 0; + state.tracktype = 0; + state.sectype = 0; + state.dbtype = 0; + state.secsize = 0; + state.dataoff = 0; + state.state = STATE_NONE; + state.track = 0; + state.index = -1; + state.index0 = -1; + state.index1 = -1; + state.secoff = 0; + state.pregapsize = -1; + state.postgapsize = -1; + state.flags = 0; + + if (xdebug > 1) + printf("---> Entering CUE Parser...\n"); + do { + if (nextline(f) == NULL) { + /* + * EOF on CUE File + * Do post processing here + */ + if (state.state < STATE_INDEX1) + cueabort("Incomplete CUE file"); + if (state.xfp) + xclose(state.xfp); + if (xdebug > 1) { + printf("---> CUE Parser got EOF, found %d tracks.\n", + state.track); + } + return; + } + word = nextitem(); + if (*word == '\0') /* empty line */ + continue; + + if (xdebug > 1) + printf("\nKEY: '%s' %s\n", word, peekword()); + kp = lookup(word, keywords); + if (kp == NULL) + cueabort("Unknown CUE keyword '%s'", word); + + if ((kp->k_type & K_G) == 0) { + if (isglobal) + isglobal = FALSE; + } + if ((kp->k_type & K_T) == 0) { + if (!isglobal) + cueabort("Badly placed CUE keyword '%s'", word); + } +/* printf("%s-", isglobal ? "G" : "T");*/ +/* wdebug();*/ + + switch (kp->k_type) { + + case K_MCN: parse_mcn(trackp, &state); break; + case K_TEXTFILE: parse_textfile(trackp, &state); break; + case K_FILE: parse_file(trackp, &state); break; + case K_FLAGS: parse_flags(trackp, &state); break; + case K_INDEX: parse_index(trackp, &state); break; + case K_ISRC: parse_isrc(trackp, &state); break; + case K_PERFORMER: parse_performer(trackp, &state); break; + case K_POSTGAP: parse_postgap(trackp, &state); break; + case K_PREGAP: parse_pregap(trackp, &state); break; + case K_REM: break; + case K_SONGWRITER: parse_songwriter(trackp, &state); break; + case K_TITLE: parse_title(trackp, &state); break; + case K_TRACK: parse_track(trackp, &state); break; + + default: + cueabort("Panic: unknown CUE command '%s'", word); + } + } while (1); +} + +static void +parse_mcn(track_t trackp[], state_t *sp) +{ + char *word; + textptr_t *txp; + + if (sp->track != 0) + cueabort("CATALOG keyword must be before first TRACK"); + + word = needitem(); + setmcn(word, &trackp[0]); + txp = gettextptr(0, trackp); /* MCN is isrc for trk 0 */ + txp->tc_isrc = strdup(word); + + checkextra(); +} + +static void +parse_textfile(track_t trackp[], state_t *sp) +{ + char *word; + + if (sp->track != 0) + cueabort("CDTEXTFILE keyword must be before first TRACK"); + + word = needitem(); + + if (trackp[MAX_TRACK+1].flags & TI_TEXT) { + if (!checktextfile(word)) { + comerrno(EX_BAD, + "Cannot use '%s' as CD-Text file.\n", + word); + } + trackp[0].flags |= TI_TEXT; + } else { + errmsgno(EX_BAD, "Ignoring CDTEXTFILE '%s'.\n", word); + errmsgno(EX_BAD, "If you like to write CD-Text, call wodim -text.\n"); + } + + checkextra(); +} + +static void +parse_file(track_t trackp[], state_t *sp) +{ + char cname[1024]; + char newname[1024]; + struct keyw *kp; + char *word; + char *filetype; + struct stat st; +#ifdef hint + Llong lsize; +#endif + + if (sp->filename != NULL) + cueabort("Only one FILE allowed"); + + word = needitem(); + if (sp->xfp) + xclose(sp->xfp); + sp->xfp = xopen(word, O_RDONLY|O_BINARY, 0); + if (sp->xfp == NULL && geterrno() == ENOENT) { + char *p; + + if (strchr(word, '/') == 0 && + strchr(cuename(), '/') != 0) { + snprintf(cname, sizeof (cname), + "%s", cuename()); + p = strrchr(cname, '/'); + if (p) + *p = '\0'; + snprintf(newname, sizeof (newname), + "%s/%s", cname, word); + word = newname; + sp->xfp = xopen(word, O_RDONLY|O_BINARY, 0); + } + } + if (sp->xfp == NULL) + comerr("Cannot open FILE '%s'.\n", word); + + sp->filename = strdup(word); + sp->trackoff = 0; + sp->filesize = 0; + sp->flags &= ~TI_SWAB; /* Reset what we might set for FILE */ + + filetype = needitem(); + kp = lookup(filetype, filetypes); + if (kp == NULL) + cueabort("Unknown filetype '%s'", filetype); + + switch (kp->k_type) { + + case K_BINARY: + case K_MOTOROLA: + if (fstat(xfileno(sp->xfp), &st) >= 0 && + S_ISREG(st.st_mode)) { + sp->filesize = st.st_size; + } else { + cueabort("Unknown file size for FILE '%s'", + sp->filename); + } + break; + case K_AIFF: + cueabort("Unsupported filetype '%s'", kp->k_name); + break; + case K_AU: + sp->filesize = ausize(xfileno(sp->xfp)); + break; + case K_WAVE: + sp->filesize = wavsize(xfileno(sp->xfp)); + sp->flags |= TI_SWAB; + break; + case K_MP3: + case K_OGG: + cueabort("Unsupported filetype '%s'", kp->k_name); + break; + + default: cueabort("Panic: unknown filetype '%s'", filetype); + } + + if (sp->filesize == AU_BAD_CODING) { + cueabort("Inappropriate audio coding in '%s'", + sp->filename); + } + if (xdebug > 0) + printf("Track %d File '%s' Filesize %lld\n", + sp->track, sp->filename, sp->filesize); + + sp->filetype = kp->k_type; + + checkextra(); + + +#ifdef hint + trackp->itracksize = lsize; + if (trackp->itracksize != lsize) + comerrno(EX_BAD, "This OS cannot handle large audio images.\n"); +#endif +} + +static void +parse_flags(track_t trackp[], state_t *sp) +{ + struct keyw *kp; + char *word; + + if ((sp->state < STATE_TRACK) || + (sp->state >= STATE_INDEX0)) + cueabort("Badly placed FLAGS keyword"); + sp->state = STATE_FLAGS; + + do { + word = needitem(); + kp = lookup(word, flags); + if (kp == NULL) + cueabort("Unknown flag '%s'", word); + + switch (kp->k_type) { + + case K_DCP: sp->flags |= TI_COPY; break; + case K_4CH: sp->flags |= TI_QUADRO; break; + case K_PRE: sp->flags |= TI_PREEMP; break; + case K_SCMS: sp->flags |= TI_SCMS; break; + default: cueabort("Panic: unknown FLAG '%s'", word); + } + + } while (peekword() < lineend()); + + if (xdebug > 0) + printf("Track %d flags 0x%08X\n", sp->track, sp->flags); +} + +static void +parse_index(track_t trackp[], state_t *sp) +{ + char *word; + long l; + int track = sp->track; + + if (sp->state < STATE_TRACK) + cueabort("Badly placed INDEX keyword"); + + + word = needitem(); + if (*astolb(word, &l, 10) != '\0') + cueabort("Not a number '%s'", word); + if (l < 0 || l > 99) + cueabort("Illegal index '%s'", word); + + if ((sp->index < l) && + (((sp->index + 1) == l) || l == 1)) + sp->index = l; + else + cueabort("Badly placed INDEX %ld number", l); + + if (l > 0) + sp->state = STATE_INDEX1; + else + sp->state = STATE_INDEX0; + + parse_offset(&l); + + if (xdebug > 1) + printf("Track %d Index %d %ld\n", sp->track, sp->index, l); + + if (sp->index == 0) + sp->index0 = l; + if (sp->index == 1) { + sp->index1 = l; + trackp[track].nindex = 1; + newtrack(trackp, sp); + + if (xdebug > 1) { + printf("Track %d pregapsize %ld\n", + sp->track, trackp[track].pregapsize); + } + } + if (sp->index == 2) { + trackp[track].tindex = malloc(100*sizeof (long)); + trackp[track].tindex[1] = 0; + trackp[track].tindex[2] = l - sp->index1; + trackp[track].nindex = 2; + } + if (sp->index > 2) { + trackp[track].tindex[sp->index] = l - sp->index1; + trackp[track].nindex = sp->index; + } + + checkextra(); +} + +static void +parse_isrc(track_t trackp[], state_t *sp) +{ + char *word; + textptr_t *txp; + int track = sp->track; + + if (track == 0) + cueabort("ISRC keyword must be past first TRACK"); + + if ((sp->state < STATE_TRACK) || + (sp->state >= STATE_INDEX0)) + cueabort("Badly placed ISRC keyword"); + sp->state = STATE_FLAGS; + + word = needitem(); + setisrc(word, &trackp[track]); + txp = gettextptr(track, trackp); + txp->tc_isrc = strdup(word); + + checkextra(); +} + +static void +parse_performer(track_t trackp[], state_t *sp) +{ + char *word; + textptr_t *txp; + + word = needitem(); + txp = gettextptr(sp->track, trackp); + txp->tc_performer = strdup(word); + + checkextra(); +} + +static void +parse_postgap(track_t trackp[], state_t *sp) +{ + long l; + + if (sp->state < STATE_INDEX1) + cueabort("Badly placed POSTGAP keyword"); + sp->state = STATE_POSTGAP; + + parse_offset(&l); + sp->postgapsize = l; + + checkextra(); +} + +static void +parse_pregap(track_t trackp[], state_t *sp) +{ + long l; + + if ((sp->state < STATE_TRACK) || + (sp->state >= STATE_INDEX0)) + cueabort("Badly placed PREGAP keyword"); + sp->state = STATE_FLAGS; + + parse_offset(&l); + sp->pregapsize = l; + + checkextra(); +} + +static void +parse_songwriter(track_t trackp[], state_t *sp) +{ + char *word; + textptr_t *txp; + + word = needitem(); + txp = gettextptr(sp->track, trackp); + txp->tc_songwriter = strdup(word); + + checkextra(); +} + +static void +parse_title(track_t trackp[], state_t *sp) +{ + char *word; + textptr_t *txp; + + word = needitem(); + txp = gettextptr(sp->track, trackp); + txp->tc_title = strdup(word); + + checkextra(); +} + +static void +parse_track(track_t trackp[], state_t *sp) +{ + struct keyw *kp; + char *word; + long l; + long secsize = -1; + + if ((sp->state >= STATE_TRACK) && + (sp->state < STATE_INDEX1)) + cueabort("Badly placed TRACK keyword"); + sp->state = STATE_TRACK; + sp->index = -1; + + word = needitem(); + if (*astolb(word, &l, 10) != '\0') + cueabort("Not a number '%s'", word); + if (l <= 0 || l > 99) + cueabort("Illegal TRACK number '%s'", word); + + if ((sp->track < l) && + (((sp->track + 1) == l) || sp->track == 0)) + sp->track = l; + else + cueabort("Badly placed TRACK %ld number", l); + + word = needword(); + kp = lookup(word, dtypes); + if (kp == NULL) + cueabort("Unknown filetype '%s'", word); + + if (wordendc == '/') { + word = needitem(); + if (*astol(++word, &secsize) != '\0') + cueabort("Not a number '%s'", word); + } + + /* + * Reset all flags that may be set in TRACK & FLAGS lines + */ + sp->flags &= ~(TI_AUDIO|TI_COPY|TI_QUADRO|TI_PREEMP|TI_SCMS); + + if (kp->k_type == K_AUDIO) + sp->flags |= TI_AUDIO; + + switch (kp->k_type) { + + case K_CDG: + if (secsize < 0) + secsize = 2448; + case K_AUDIO: + if (secsize < 0) + secsize = 2352; + + sp->tracktype = TOC_DA; + sp->sectype = SECT_AUDIO; + sp->dbtype = DB_RAW; + sp->secsize = secsize; + sp->dataoff = 0; + if (secsize != 2352) + cueabort("Unsupported sector size %ld for audio", secsize); + break; + + case K_MODE1: + if (secsize < 0) + secsize = 2048; + + sp->tracktype = TOC_ROM; + sp->sectype = SECT_ROM; + sp->dbtype = DB_ROM_MODE1; + sp->secsize = secsize; + sp->dataoff = 16; + /* + * XXX Sector Size == 2352 ??? + * XXX It seems that there exist bin/cue pairs with this value + */ + if (secsize != 2048) + cueabort("Unsupported sector size %ld for data", secsize); + break; + + case K_MODE2: + case K_CDI: + sp->tracktype = TOC_ROM; + sp->sectype = SECT_MODE_2; + sp->dbtype = DB_ROM_MODE2; + sp->secsize = secsize; + sp->dataoff = 16; + if (secsize == 2352) { + sp->tracktype = TOC_XA2; + sp->sectype = SECT_MODE_2_MIX; + sp->sectype |= ST_MODE_RAW; + sp->dbtype = DB_RAW; + sp->dataoff = 0; + } else if (secsize != 2336) + cueabort("Unsupported sector size %ld for mode2", secsize); + if (kp->k_type == K_CDI) + sp->tracktype = TOC_CDI; + break; + + default: cueabort("Panic: unknown datatype '%s'", word); + } + + if (sp->flags & TI_PREEMP) + sp->sectype |= ST_PREEMPMASK; + sp->secsize = secsize; + + if (xdebug > 1) { + printf("Track %d Tracktype %s/%d\n", + sp->track, kp->k_name, sp->secsize); + } + + checkextra(); +} + +static void +parse_offset(long *lp) +{ + char *word; + char *p; + long m = -1; + long s = -1; + long f = -1; + + word = needitem(); + + if (strchr(word, ':') == NULL) { + if (*astol(word, lp) != '\0') + cueabort("Not a number '%s'", word); + return; + } + if (*(p = astolb(word, &m, 10)) != ':') + cueabort("Not a number '%s'", word); + if (m < 0 || m >= 160) + cueabort("Illegal minute value in '%s'", word); + p++; + if (*(p = astolb(p, &s, 10)) != ':') + cueabort("Not a number '%s'", p); + if (s < 0 || s >= 60) + cueabort("Illegal second value in '%s'", word); + p++; + if (*(p = astolb(p, &f, 10)) != '\0') + cueabort("Not a number '%s'", p); + if (f < 0 || f >= 75) + cueabort("Illegal frame value in '%s'", word); + + m = m * 60 + s; + m = m * 75 + f; + *lp = m; +} + +/*--------------------------------------------------------------------------*/ +static void +newtrack(track_t trackp[], state_t *sp) +{ + register int i; + register int track = sp->track; + Llong tracksize; + + if (xdebug > 1) + printf("-->Newtrack %d\n", track); + if (track > 1) { + tracksize = (sp->index1 - sp->secoff) * trackp[track-1].secsize; + + if (xdebug > 1) + printf(" trackoff %lld filesize %lld index1 %ld size %ld/%lld\n", + sp->trackoff, sp->filesize, sp->index1, + sp->index1 - sp->secoff, + tracksize); + + trackp[track-1].itracksize = tracksize; + trackp[track-1].tracksize = tracksize; + trackp[track-1].tracksecs = sp->index1 - sp->secoff; + + sp->trackoff += tracksize; + sp->secoff = sp->index1; + } + /* + * Make 'tracks' immediately usable in track structure. + */ + for (i = 0; i < MAX_TRACK+2; i++) + trackp[i].tracks = track; + + trackp[track].filename = sp->filename; + trackp[track].xfp = xopen(sp->filename, O_RDONLY|O_BINARY, 0); + trackp[track].trackstart = 0L; +/* +SEtzen wenn tracksecs bekannt sind +d.h. mit Index0 oder Index 1 vom nächsten track + + trackp[track].itracksize = tracksize; + trackp[track].tracksize = tracksize; + trackp[track].tracksecs = -1L; +*/ + tracksize = sp->filesize - sp->trackoff; + + trackp[track].itracksize = tracksize; + trackp[track].tracksize = tracksize; + trackp[track].tracksecs = (tracksize + sp->secsize - 1) / sp->secsize; + + if (xdebug > 1) + printf(" Remaining Filesize %lld (%lld secs)\n", + (sp->filesize-sp->trackoff), + (sp->filesize-sp->trackoff +sp->secsize - 1) / sp->secsize); + + if (sp->pregapsize >= 0) { +/* trackp[track].flags &= ~TI_PREGAP;*/ + sp->flags &= ~TI_PREGAP; + trackp[track].pregapsize = sp->pregapsize; + } else { +/* trackp[track].flags |= TI_PREGAP;*/ + if (track > 1) + sp->flags |= TI_PREGAP; + if (track == 1) + trackp[track].pregapsize = sp->index1 + 150; + else if (sp->index0 < 0) + trackp[track].pregapsize = -1; + else + trackp[track].pregapsize = sp->index1 - sp->index0; + } +/* trackp[track].padsecs = xxx*/ + + trackp[track].isecsize = sp->secsize; + trackp[track].secsize = sp->secsize; + trackp[track].flags = sp->flags | trackp[0].flags; + + trackp[track].secspt = 0; /* transfer size is set up in set_trsizes() */ +/* trackp[track].pktsize = pktsize; */ + trackp[track].pktsize = 0; + trackp[track].trackno = sp->track; + trackp[track].sectype = sp->sectype; + + trackp[track].dataoff = sp->dataoff; + trackp[track].tracktype = sp->tracktype; + trackp[track].dbtype = sp->dbtype; + + if (track == 1) { + trackp[0].tracktype &= ~TOC_MASK; + trackp[0].tracktype |= sp->tracktype; + + if (xdebug > 1) { + printf("Track %d Tracktype %X\n", + 0, trackp[0].tracktype); + } + } + if (xdebug > 1) { + printf("Track %d Tracktype %X\n", + track, trackp[track].tracktype); + } + trackp[track].nindex = 1; + trackp[track].tindex = 0; + + if (xdebug > 1) { + printf("Track %d flags 0x%08X\n", 0, trackp[0].flags); + printf("Track %d flags 0x%08X\n", track, trackp[track].flags); + } +} + +/*--------------------------------------------------------------------------*/ +static keyw_t * +lookup(char *word, keyw_t table[]) +{ + register keyw_t *kp = table; + + while (kp->k_name) { + if (streql(kp->k_name, word)) + return (kp); + kp++; + } + return (NULL); +} + +/*--------------------------------------------------------------------------*/ +/* + * Parser low level functions start here... + */ + +static void +wdebug() +{ +/* printf("WORD: '%s' rest '%s'\n", word, peekword());*/ + printf("WORD: '%s' rest '%s'\n", linep, peekword()); + printf("linep %lX peekword %lX end %lX\n", + (long)linep, (long)peekword(), (long)&linebuf[linelen]); +} + +static FILE * +cueopen(char *name) +{ + FILE *f; + + f = fileopen(name, "r"); + if (f == NULL) + comerr("Cannot open '%s'.\n", name); + + fname = name; + return (f); +} + +static char * +cuename() +{ + return (fname); +} + +static char * +nextline(FILE *f) +{ + register int len; + + do { + fillbytes(linebuf, sizeof (linebuf), '\0'); + len = rols_fgetline(f, linebuf, sizeof (linebuf)); + if (len < 0) + return (NULL); + if (len > 0 && linebuf[len-1] == '\r') { + linebuf[len-1] = '\0'; + len--; + } + linelen = len; + lineno++; + } while (linebuf[0] == '#'); + + olinelen = linelen; + linep = linebuf; + wordendp = linep; + wordendc = *linep; + + return (linep); +} + +static void +ungetline() +{ + linelen = olinelen; + linep = linebuf; + *wordendp = wordendc; + wordendp = linep; + wordendc = *linep; +} + +static char * +skipwhite(const char *s) +{ + register const Uchar *p = (const Uchar *)s; + + while (*p) { + if (!isspace(*p)) + break; + p++; + } + return ((char *)p); +} + +static char * +peekword() +{ + return (&wordendp[1]); +} + +static char * +lineend() +{ + return (&linebuf[linelen]); +} + +static char * +markword(char *delim) +{ + register BOOL quoted = FALSE; + register Uchar c; + register Uchar *s; + register Uchar *from; + register Uchar *to; + + for (s = (Uchar *)linep; (c = *s) != '\0'; s++) { + if (c == '"') { + quoted = !quoted; +/* strcpy((char *)s, (char *)&s[1]);*/ + for (to = s, from = &s[1]; *from; ) { + c = *from++; + if (c == '\\' && quoted && (*from == '\\' || *from == '"')) + c = *from++; + *to++ = c; + } + *to = '\0'; + c = *s; +linelen--; + } + if (!quoted && isspace(c)) + break; + if (!quoted && strchr(delim, c) && s > (Uchar *)linep) + break; + } + wordendp = (char *)s; + wordendc = (char)*s; + *s = '\0'; + + return (linep); +} + +static char * +getnextitem(char *delim) +{ + *wordendp = wordendc; + + linep = skipwhite(wordendp); + return (markword(delim)); +} + +static char * +neednextitem(char *delim) +{ + char *olinep = linep; + char *nlinep; + + nlinep = getnextitem(delim); + + if ((olinep == nlinep) || (*nlinep == '\0')) + cueabort("Missing text"); + + return (nlinep); +} + +static char * +nextword() +{ + return (getnextitem(worddelim)); +} + +static char * +needword() +{ + return (neednextitem(worddelim)); +} + +static char * +curword() +{ + return (linep); +} + +static char * +nextitem() +{ + return (getnextitem(nulldelim)); +} + +static char * +needitem() +{ + return (neednextitem(nulldelim)); +} + +static void +checkextra() +{ + if (peekword() < lineend()) + cueabort("Extra text '%s'", peekword()); +} + +/* VARARGS1 */ +static void cueabort(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, " on line %d in '%s'.\n", lineno, fname); + exit(EXIT_FAILURE); +} diff --git a/wodim/defaults.c b/wodim/defaults.c new file mode 100644 index 0000000..a09da6c --- /dev/null +++ b/wodim/defaults.c @@ -0,0 +1,139 @@ +/* + * Copyright 2006 Eduard Bloch + * + * This code emulates the interface of the original defaults.c file. However, + * it improves its behaviour and deals with corner cases: prepended and + * trailing spaces on variable and value, no requirement for using TABs + * anymore. No requirements to insert dummy values like -1 or "". + * + */ +/* + * 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 <stdlib.h> +#include <stdio.h> +#include <deflts.h> +#include <ctype.h> +#include <string.h> + +#define CFGPATH "/etc/wodim.conf" +/* The better way would be exporting the meta functions to getnum.h or so */ +extern int getnum(char *arg, long *valp); + +void +cdr_defaults(char **p_dev_name, int *p_speed, long *p_fifosize, + char **p_drv_opts) +{ + char *t; /* tmp */ + int wc=0; + char loc[256], sSpeed[11], sFs[11], sOpts[81]; + char *devcand=NULL; + + cfg_open(CFGPATH); + + if(p_dev_name && *p_dev_name) + devcand=*p_dev_name; + else if(NULL!=(t=getenv("CDR_DEVICE"))) + devcand=t; + else if(NULL!=(t=cfg_get("CDR_DEVICE"))) + devcand=strdup(t); /* needs to use it as a key later, same stat. memory */ + + if(devcand && NULL != (t=cfg_get(devcand))) { + /* extract them now, may be used later */ + wc=sscanf(t, "%255s %10s %10s %80s", loc, sSpeed, sFs, sOpts); + } + + if(p_dev_name) { + if(wc>0) + *p_dev_name = strdup(loc); + else if(devcand) /* small mem. leak possible, does not matter, checks for that would require more code size than we loose */ + *p_dev_name=strdup(devcand); + } + if(p_speed) { /* sth. to write back */ + char *bad; + int cfg_speed=-1; + + /* that value may be used twice */ + if(NULL!=(t=cfg_get("CDR_SPEED"))) { + cfg_speed=strtol(t,&bad,10); + if(*bad || cfg_speed<-1) { + fprintf(stderr, "Bad default CDR_SPEED setting (%s).\n", t); + exit(EXIT_FAILURE); + } + } + + if(*p_speed>0) { + /* ok, already set by the program arguments */ + } + else if(NULL!=(t=getenv("CDR_SPEED"))) { + *p_speed=strtol(t,&bad,10); + if(*bad || *p_speed<-1) { + fprintf(stderr, "Bad CDR_SPEED environment (%s).\n", t); + exit(EXIT_FAILURE); + } + } + else if(wc>1 && *sSpeed) { + *p_speed=strtol(sSpeed, &bad, 10); + if(*bad || *p_speed<-1) { + fprintf(stderr, "Bad speed (%s) in the config, drive description.\n", sSpeed); + exit(EXIT_FAILURE); + } + if(*p_speed==-1) + /* that's autodetect, use the config default as last ressort */ + *p_speed=cfg_speed; + } + else + *p_speed=cfg_speed; + } + if(p_fifosize) { /* sth. to write back */ + if(*p_fifosize>0) { + /* ok, already set by the user */ + } + else if(NULL!=(t=getenv("CDR_FIFOSIZE"))) { + if(getnum(t, p_fifosize)!=1 || *p_fifosize<-1) { + fprintf(stderr, "Bad CDR_FIFOSIZE environment (%s).\n", t); + exit(EXIT_FAILURE); + } + } + else if(wc>2 && *sFs && strcmp("-1", sFs)) { + if(getnum(sFs, p_fifosize)!=1 || *p_fifosize<-1) { + fprintf(stderr, "Bad fifo size (%s) in the config, device description.\n", sFs); + exit(EXIT_FAILURE); + } + } + else if(NULL!=(t=cfg_get("CDR_FIFOSIZE"))) { + if(getnum(t, p_fifosize)!=1 || *p_fifosize<-1) { + fprintf(stderr, "Bad speed default setting (%s).\n", t); + exit(EXIT_FAILURE); + } + } + if(NULL!=(t=cfg_get("CDR_MAXFIFOSIZE"))) { + long max; + if(getnum(t, &max)!=1 || *p_fifosize<-1) { + fprintf(stderr, "Bad CDR_MAXFIFOSIZE setting (%s).\n", t); + exit(EXIT_FAILURE); + } + if(*p_fifosize>max) + *p_fifosize=max; + } + } + + if(p_drv_opts && !*p_drv_opts && wc>3 && strcmp(sOpts, "\"\"")) + *p_drv_opts=strdup(sOpts); + + cfg_close(); + +} diff --git a/wodim/defaults.h b/wodim/defaults.h new file mode 100644 index 0000000..3a5c8f8 --- /dev/null +++ b/wodim/defaults.h @@ -0,0 +1,14 @@ +/* + * Copyright 2006 Eduard Bloch + * + * This code emulates the interface of the original defaults.c file. However, + * it improves its behaviour and deals with corner cases: prepended and + * trailing spaces on variable and value, no requirement for using TABs + * anymore. No requirements to insert dummy values like -1 or "". + * + */ +#ifndef _DEFAULTS_H_ +#define _DEFAULTS_H_ +extern int getnum(char *arg, long *valp); +void cdr_defaults(char **p_dev_name, int *p_speed, long *p_fifosize, char **p_drv_opts); +#endif diff --git a/wodim/diskid.c b/wodim/diskid.c new file mode 100644 index 0000000..70675a3 --- /dev/null +++ b/wodim/diskid.c @@ -0,0 +1,522 @@ +/* + * 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. + * + */ + +/* @(#)diskid.c 1.37 04/03/02 Copyright 1998-2004 J. Schilling */ +/* + * Disk Idientification Method + * + * Copyright (c) 1998-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 <utypes.h> + +#include "wodim.h" + +void pr_manufacturer(msf_t *mp, BOOL rw, BOOL audio); +static struct disk_man *man_ptr(msf_t *mp); +int manufacturer_id(msf_t *mp); +long disk_rcap(msf_t *mp, long maxblock, BOOL rw, BOOL audio); + +struct disk_man { + msf_t mi_msf; + char mi_num; + char *mi_name; +}; + +/* + * Illegal (old) Manufacturer. + */ +static char m_ill[] = "Unknown old Manufacturer code"; +static char m_illrw[] = "Illegal Manufacturer code"; + +/* + * Permanent codes. + */ +static char m_kingpro[] = "King Pro Mediatek Inc."; +static char m_custpo[] = "Customer Pressing Oosterhout"; +static char m_taeil[] = "Taeil Media Co.,Ltd."; +static char m_doremi[] = "Doremi Media Co., Ltd."; +static char m_xcitec[] = "Xcitec Inc."; +static char m_leaddata[] = "Lead Data Inc."; +static char m_fuji[] = "FUJI Photo Film Co., Ltd."; +static char m_hitachi[] = "Hitachi Maxell, Ltd."; +static char m_kodakjp[] = "Kodak Japan Limited"; +static char m_mitsui[] = "Mitsui Chemicals, Inc."; +static char m_pioneer[] = "Pioneer Video Corporation"; +static char m_plasmon[] = "Plasmon Data systems Ltd."; +static char m_princo[] = "Princo Corporation"; +static char m_ricoh[] = "Ricoh Company Limited"; +static char m_skc[] = "SKC Co., Ltd."; +static char m_tyuden[] = "Taiyo Yuden Company Limited"; +static char m_tdk[] = "TDK Corporation"; +static char m_mitsubishi[] = "Mitsubishi Chemical Corporation"; +static char m_auvistar[] = "Auvistar Industry Co.,Ltd."; +static char m_gigastore[] = "GIGASTORAGE CORPORATION"; +static char m_fornet[] = "FORNET INTERNATIONAL PTE LTD."; +static char m_cmc[] = "CMC Magnetics Corporation"; +static char m_odm[] = "Optical Disc Manufacturing Equipment"; +static char m_ritek[] = "Ritek Co."; + +/* + * Tentative codes. + */ +static char m_bestdisk[] = "Bestdisc Technology Corporation"; +static char m_wealth_fair[] = "WEALTH FAIR INVESTMENT LIMITED"; +static char m_general_mag[] = "General Magnetics Ld"; +static char m_mpo[] = "MPO"; +static char m_jvc[] = "VICTOR COMPANY OF JAPAN, LIMITED"; +static char m_vivistar[] = "VIVASTAR AG"; +static char m_taroko[] = "TAROKO INTERNATIONAL CO.,LTD."; +static char m_unidisc[] = "UNIDISC TECHNOLOGY CO.,LTD"; +static char m_hokodig[] = "Hong Kong Digital Technology Co., Ltd."; +static char m_viva[] = "VIVA MAGNETICS LIMITED"; +static char m_hile[] = "Hile Optical Disc Technology Corp."; +static char m_friendly[] = "Friendly CD-Tek Co."; +static char m_soundsound[] = "Sound Sound Multi-Media Development Limited"; +static char m_kdg[] = "kdg mediatech AG"; +static char m_seantram[] = "Seantram Technology Inc."; +static char m_eximpo[] = "EXIMPO"; +static char m_delphi[] = "DELPHI TECHNOLOGY INC."; +static char m_harmonic[] = "Harmonic Hall Optical Disc Ltd."; +static char m_guannyinn[] = "Guann Yinn Co.,Ltd."; +static char m_optime[] = "Opti.Me.S. S.p.A."; +static char m_nacar[] = "Nacar Media srl"; +static char m_optrom[] = "OPTROM.INC."; +static char m_audiodis[] = "AUDIO DISTRIBUTORS CO., LTD."; +static char m_acer[] = "Acer Media Technology, Inc."; +static char m_woongjin[] = "Woongjin Media corp"; +static char m_infodisk[] = "INFODISC Technology Co., Ltd."; +static char m_unitech[] = "UNITECH JAPAN INC."; +static char m_ams[] = "AMS Technology Inc."; +static char m_vanguard[] = "Vanguard Disc Inc."; +static char m_grandadv[] = "Grand Advance Technology Ltd."; +static char m_digitalstor[] = "DIGITAL STORAGE TECHNOLOGY CO.,LTD"; +static char m_matsushita[] = "Matsushita Electric Industrial Co.,Ltd."; +static char m_albrechts[] = "CDA Datenträger Albrechts GmbH."; +static char m_xalbrechts[] = "??? CDA Datenträger Albrechts GmbH."; + +static char m_prodisc[] = "Prodisc Technology Inc."; +static char m_postech[] = "POSTECH Corporation"; +#ifdef used +static char m_ncolumbia[] = "NIPPON COLUMBIA CO.,LTD."; +#endif +static char m_odc[] = "OPTICAL DISC CORPRATION"; +static char m_sony[] = "SONY Corporation"; +static char m_cis[] = "CIS Technology Inc."; +static char m_csitaly[] = "Computer Support Italy s.r.l."; +static char m_mmmm[] = "Multi Media Masters & Machinary SA"; + +/* + * Guessed codes. + */ +/*static char m_seantram[] = "Seantram Technology Inc.";*/ +static char m_advanced[] = "Advanced Digital Media"; +static char m_moser[] = "Moser Baer India Limited"; +static char m_nanya[] = "NAN-YA Plastics Corporation"; +static char m_shenzen[] = "SHENZEN SG&GAST DIGITAL OPTICAL DISCS"; + +static struct disk_man notable = + {{00, 00, 00}, -1, "unknown (not in table)" }; + +/* + * Old (illegal) code table. It lists single specific codes (97:xx:yy). + */ +static struct disk_man odman[] = { + /* + * Illegal (old) codes. + */ + {{97, 25, 00}, 80, "ILLEGAL OLD CODE: TDK ???" }, + {{97, 25, 15}, 0, m_ill }, + {{97, 27, 00}, 81, "ILLEGAL OLD CODE: Old Ritek Co.???" }, + {{97, 27, 25}, 0, m_ill }, + {{97, 30, 00}, 0, m_ill }, + {{97, 33, 00}, 82, "ILLEGAL OLD CODE: Old CDA Datenträger Albrechts GmbH." }, + {{97, 35, 44}, 0, m_ill }, + {{97, 39, 00}, 0, m_ill }, + {{97, 45, 36}, 83, "ILLEGAL OLD CODE: Old Kodak Photo CD" }, + {{97, 47, 00}, 0, m_ill }, + {{97, 47, 30}, 0, m_ill }, + {{97, 48, 14}, 0, m_ill }, + {{97, 48, 33}, 0, m_ill }, + {{97, 49, 00}, 0, m_ill }, + {{97, 54, 00}, 0, m_ill }, + {{97, 55, 06}, 0, m_ill }, + {{97, 57, 00}, 0, m_ill }, + /* + * List end marker + */ + {{00, 00, 00}, 0, NULL }, +}; + +#define noman (sizeof (oman)/sizeof (oman[0])) + +/* + * Actual code table. It lists code ranges (97:xx:y0 - 97:xx:y9). + * + * Note that dp->mi_msf.msf_frame needs to be always rounded down + * to 0 even for media that has e.g. 97:27/01 in the official table. + */ +static struct disk_man dman[] = { + /* + * Permanent codes. + */ + + {{97, 22, 10}, 53, m_seantram }, + {{97, 15, 00}, 26, m_tdk }, + {{97, 49, 30}, 47, m_optime }, + {{97, 28, 00}, 47, m_optime }, + {{97, 28, 40}, 36, m_kingpro }, + {{97, 23, 60}, 49, m_custpo }, + {{97, 29, 00}, 37, m_taeil }, + {{97, 26, 10}, 19, m_postech }, + {{97, 47, 40}, 19, m_postech }, + {{97, 24, 10}, 24, m_sony }, +/* {{97, 46, 10}, 24, m_sony },*/ + {{97, 23, 10}, 33, m_doremi }, + {{97, 25, 60}, 30, m_xcitec }, + {{97, 45, 60}, 30, m_xcitec }, + {{97, 26, 50}, 10, m_leaddata }, + {{97, 48, 60}, 10, m_leaddata }, + {{97, 26, 40}, 6, m_fuji }, + {{97, 46, 40}, 6, m_fuji }, + {{97, 25, 20}, 8, m_hitachi }, + {{97, 47, 10}, 8, m_hitachi }, + {{97, 27, 40}, 9, m_kodakjp }, + {{97, 48, 10}, 9, m_kodakjp }, + {{97, 27, 50}, 12, m_mitsui }, + {{97, 48, 50}, 12, m_mitsui }, + {{97, 27, 30}, 17, m_pioneer }, + {{97, 48, 30}, 17, m_pioneer }, + {{97, 27, 10}, 18, m_plasmon }, + {{97, 48, 20}, 18, m_plasmon }, + {{97, 27, 20}, 20, m_princo }, + {{97, 47, 20}, 20, m_princo }, + {{97, 27, 60}, 21, m_ricoh }, + {{97, 48, 00}, 21, m_ricoh }, + {{97, 26, 20}, 23, m_skc }, + {{97, 24, 00}, 25, m_tyuden }, + {{97, 46, 00}, 25, m_tyuden }, + {{97, 32, 00}, 26, m_tdk }, + {{97, 49, 00}, 26, m_tdk }, + {{97, 34, 20}, 11, m_mitsubishi }, + {{97, 50, 20}, 11, m_mitsubishi }, + {{97, 28, 30}, 1, m_auvistar }, + {{97, 46, 50}, 1, m_auvistar }, + {{97, 28, 10}, 7, m_gigastore }, + {{97, 49, 10}, 7, m_gigastore }, + {{97, 26, 00}, 5, m_fornet }, + {{97, 45, 00}, 5, m_fornet }, + {{97, 26, 60}, 3, m_cmc }, + {{97, 46, 60}, 3, m_cmc }, + {{97, 21, 40}, 16, m_odm }, + {{97, 31, 00}, 22, m_ritek }, + {{97, 47, 50}, 22, m_ritek }, + {{97, 28, 20}, 13, m_mmmm }, + {{97, 46, 20}, 13, m_mmmm }, + {{97, 32, 10}, 27, m_prodisc }, + + /* + * Tentative codes. + */ + {{97, 21, 30}, 67, m_bestdisk }, + {{97, 18, 10}, 66, m_wealth_fair }, + {{97, 29, 50}, 65, m_general_mag }, + {{97, 25, 00}, 64, m_mpo }, /* in reality 25/01 */ + {{97, 49, 40}, 63, m_jvc }, + {{97, 23, 40}, 63, m_jvc }, + {{97, 25, 40}, 62, m_vivistar }, + {{97, 18, 60}, 61, m_taroko }, + {{97, 29, 20}, 60, m_unidisc }, + {{97, 46, 10}, 59, m_hokodig }, /* XXX was m_sony */ + {{97, 22, 50}, 59, m_hokodig }, + {{97, 29, 40}, 58, m_viva }, + {{97, 29, 30}, 57, m_hile }, + {{97, 51, 50}, 57, m_hile }, + {{97, 28, 60}, 56, m_friendly }, + {{97, 21, 50}, 55, m_soundsound }, + {{97, 24, 40}, 54, m_kdg }, + {{97, 22, 30}, 52, m_eximpo }, + {{97, 28, 50}, 51, m_delphi }, + {{97, 29, 00}, 50, m_harmonic }, + {{97, 15, 10}, 22, m_ritek }, + {{97, 45, 50}, 48, m_guannyinn }, + {{97, 24, 50}, 48, m_guannyinn }, + {{97, 23, 20}, 46, m_nacar }, + {{97, 23, 50}, 45, m_optrom }, + {{97, 23, 30}, 44, m_audiodis }, + {{97, 22, 60}, 43, m_acer }, + {{97, 45, 20}, 43, m_acer }, + {{97, 15, 20}, 11, m_mitsubishi }, + {{97, 22, 00}, 39, m_woongjin }, + {{97, 25, 30}, 40, m_infodisk }, + {{97, 51, 20}, 40, m_infodisk }, + {{97, 24, 30}, 41, m_unitech }, + {{97, 25, 50}, 42, m_ams }, + {{97, 29, 10}, 38, m_vanguard }, + {{97, 50, 10}, 38, m_vanguard }, + {{97, 16, 30}, 35, m_grandadv }, + {{97, 31, 30}, 35, m_grandadv }, + {{97, 51, 10}, 35, m_grandadv }, + {{97, 49, 20}, 36, m_kingpro }, + {{97, 27, 00}, 34, m_digitalstor }, /* in reality 27/01 */ + {{97, 48, 40}, 34, m_digitalstor }, /* XXX was m_ncolumbia */ + {{97, 23, 00}, 31, m_matsushita }, + {{97, 49, 60}, 31, m_matsushita }, + {{97, 30, 10}, 32, m_albrechts }, /* XXX was m_ncolumbia */ + {{97, 50, 30}, 32, m_albrechts }, + {{97, 47, 60}, 27, m_prodisc }, +/* {{97, 30, 10}, 14, m_ncolumbia },*/ +/* {{97, 48, 40}, 14, m_ncolumbia },*/ + {{97, 26, 30}, 15, m_odc }, + {{97, 22, 40}, 2, m_cis }, + {{97, 45, 40}, 2, m_cis }, + {{97, 24, 20}, 4, m_csitaly }, + {{97, 46, 30}, 4, m_csitaly }, + + /* + * Guessed codes. + */ + {{97, 20, 10}, 32, m_xalbrechts }, /* XXX guess */ +/* {{97, 23, 40}, 32, m_xalbrechts },*/ /* Really is JVC */ + + /* + * New guessed codes (2002 ff.). + * Id code >= 68 referres to a new manufacturer. + */ +#define I_GUESS 105 + {{97, 22, 20}, 68, m_advanced }, + {{97, 42, 20}, 68, m_advanced }, + {{97, 24, 60}, 50, m_harmonic }, + {{97, 17, 00}, 69, m_moser }, + {{97, 15, 30}, 70, m_nanya }, + {{97, 16, 20}, 71, m_shenzen }, + {{97, 45, 10}, 41, m_unitech }, + + /* + * List end marker + */ + {{00, 00, 00}, 0, NULL }, +}; + +#define ndman (sizeof (dman)/sizeof (dman[0])) + +static struct disk_man * +man_ptr(msf_t *mp) +{ + struct disk_man * dp; + int frame; + int type; + + type = mp->msf_frame % 10; + frame = mp->msf_frame - type; + + dp = odman; + while (dp->mi_msf.msf_min != 0) { + if (mp->msf_min == dp->mi_msf.msf_min && + mp->msf_sec == dp->mi_msf.msf_sec && + mp->msf_frame == dp->mi_msf.msf_frame) { + return (dp); + } + dp++; + } + dp = dman; + while (dp->mi_msf.msf_min != 0) { + if (mp->msf_min == dp->mi_msf.msf_min && + mp->msf_sec == dp->mi_msf.msf_sec && + frame == dp->mi_msf.msf_frame) { + /* + * Note that dp->mi_msf.msf_frame is always rounded + * down to 0 even for media that has 97:27/01 in the + * official table. + */ + return (dp); + } + dp++; + } + return (NULL); +} + +void pr_manufacturer(msf_t *mp, BOOL rw, BOOL audio) +{ + struct disk_man * dp; + struct disk_man xdman; + int type; + char *tname; + +/* printf("pr_manufacturer rw: %d audio: %d\n", rw, audio);*/ + + type = mp->msf_frame % 10; + if (type < 5) { + tname = "Long strategy type (Cyanine, AZO or similar)"; + } else { + tname = "Short strategy type (Phthalocyanine or similar)"; + } + if (rw) { + tname = "Phase change"; + } + + dp = man_ptr(mp); + if (dp != NULL) { + if (dp->mi_num == 0 || dp->mi_num >= 80) { + if (!rw) { + tname = "unknown dye (old id code)"; + } else { + xdman = *dp; + dp = &xdman; + dp->mi_num = 0; + dp->mi_name = m_illrw; + } + } + } else { + tname = "unknown dye (reserved id code)"; + dp = ¬able; + } + printf("Disk type: %s\n", tname); + printf("Manuf. index: %d\n", dp->mi_num); + printf("Manufacturer: %s\n", dp->mi_name); + + if (mp->msf_min != 97) /* This may be garbage ATIP from a DVD */ + return; + + if (dp >= &dman[I_GUESS] && dp < &dman[ndman]) { + printf("Manufacturer is guessed because of the orange forum embargo.\n"); + printf("The orange forum likes to get money for recent information.\n"); + printf("The information for this media may not be correct.\n"); + } + if (dp == ¬able) { + printf("Manufacturer is unknown because of the orange forum embargo.\n"); + printf("As the orange forum likes to get money for recent information,\n"); + printf("it may be that this media does not use illegal manufacturer coding.\n"); + } +} + +int manufacturer_id(msf_t *mp) +{ + struct disk_man * dp; + + dp = man_ptr(mp); + if (dp != NULL) + return (dp->mi_num); + return (-1); +} + +struct disk_rcap { + msf_t ci_msf; /* Lead in start time */ + long ci_cap; /* Lead out start time */ + long ci_rcap; /* Abs max lead out start */ +}; + +static struct disk_rcap rcap[] = { + +#ifdef __redbook_only__ + {{97, 35, 44}, 359849, 404700 }, /*! Unknown 99 min (89:58/00)*/ +#endif + {{97, 35, 44}, 359849, 449700 }, /*! Unknown 99 min (99:58/00) */ + {{97, 31, 00}, 359849, 368923 }, /*! Arita CD-R 80 */ + {{97, 26, 50}, 359849, 369096 }, /*! Lead Data CD-R 80 */ + {{97, 26, 12}, 359849, 368000 }, /*X POSTECH 80 Min */ + {{97, 25, 00}, 359849, 374002 }, /* TDK 80 Minuten */ + {{97, 20, 14}, 359700, 376386 }, /*! Albrechts DataFile Plus */ + {{97, 35, 44}, 359100, 368791 }, /*! NoName BC-1 700 Mb/80 Min */ + + {{97, 26, 60}, 337350, 349030 }, /* Koch grün CD-R74PRO */ + {{97, 26, 50}, 337050, 351205 }, /* Saba */ + {{97, 26, 00}, 337050, 351411 }, /*!DGN (FORNET) */ + {{97, 22, 40}, 336631, 349971 }, /* Targa grün CD-R74 */ + {{97, 26, 50}, 336631, 351727 }, /*! Sunstar (Lead Data) */ + {{97, 26, 55}, 336631, 350474 }, /*! NoName ZAP (Lead Data) */ + + {{97, 27, 28}, 336601, 346489 }, /*! BTC CD-R (Princo) */ + {{97, 27, 30}, 336601, 351646 }, /*! Pioneer blau CDM-W74S */ + {{97, 27, 31}, 336601, 351379 }, /* Pioneer blau CDM-W74S */ + {{97, 27, 33}, 336601, 347029 }, /*! Pioneer braun CDM-V74S */ + {{97, 26, 40}, 336225, 346210 }, /* Fuji Silver Disk */ + {{97, 28, 10}, 336225, 348757 }, /*!GigaStorage Cursor CD-R */ + {{97, 31, 00}, 336225, 345460 }, /* Arita grün */ + {{97, 25, 28}, 336075, 352879 }, /* Maxell gold CD-R74G */ + {{97, 24, 01}, 336075, 346856 }, /*!Philips Premium Silver */ + {{97, 24, 00}, 336075, 346741 }, /* Philips grün CD-R74 */ + + {{97, 22, 41}, 335206, 349385 }, /* Octek grün */ + {{97, 34, 20}, 335100, 342460 }, /* Verbatim DataLifePlus */ + {{97, 33, 00}, 335100, 344634 }, /*!ITS Singapore (braun/grün) */ + {{97, 32, 19}, 335100, 343921 }, /*!Prodisc silber/silber */ + {{97, 25, 21}, 335100, 346013 }, /* Maxell grün CD-R74XL */ + {{97, 27, 00}, 335100, 353448 }, /* TDK grün CD-RXG74 */ + {{97, 27, 31}, 335100, 351862 }, /*!Maxell CD-R74MU (Musik) */ + {{97, 27, 33}, 335100, 351336 }, /* Pioneer RDD-74A */ + + {{97, 26, 60}, 334259, 349036 }, /* BASF grün */ + {{97, 28, 21}, 333976, 348217 }, /*! Noname-B (MMMM) */ + {{97, 28, 20}, 333976, 346485 }, /* Koch grün CD-R74 PRO */ + {{97, 32, 00}, 333975, 345736 }, /* Imation 3M */ + {{97, 32, 00}, 333975, 348835 }, /* TDK Reflex X CD-R74 */ + {{97, 30, 18}, 333899, 344857 }, /* HiSpace grün */ + {{97, 27, 66}, 333750, 352726 }, /*!Philips Megalife (Musik) */ + {{97, 28, 43}, 333750, 345344 }, /*!MMore CD-R */ + {{97, 27, 65}, 333750, 348343 }, /* Ricoh gold */ + + {{97, 27, 00}, 333750, 336246 }, /* BestMedia grün CD-R74 */ + {{97, 27, 28}, 333491, 347473 }, /* Fuji grün (alt) */ + {{97, 24, 48}, 333491, 343519 }, /* BASF (alt) */ + {{97, 27, 55}, 333235, 343270 }, /* Teac gold CD-R74 */ + {{97, 27, 45}, 333226, 343358 }, /* Kodak gold */ + {{97, 28, 20}, 333226, 346483 }, /* SAST grün */ + {{97, 27, 45}, 333226, 343357 }, /* Mitsumi gold */ + {{97, 28, 25}, 333226, 346481 }, /* Cedar Grün */ + {{97, 23, 00}, 333226, 346206 }, /* Fuji grün (alt) */ + {{97, 33, 00}, 333225, 349623 }, /* DataFile Albrechts */ + {{97, 24, 24}, 333198, 342536 }, /*!SUN CD Recordable */ + + {{97, 27, 19}, 332850, 348442 }, /* Plasmon gold PCD-R74 */ + {{97, 32, 00}, 96600, 106502 }, /* TDK 80mm (for music only) */ + + /* + * List end marker + */ + {{00, 00, 00}, 0L, 0L }, +}; + +long +disk_rcap(msf_t *mp, long maxblock, BOOL rw, BOOL audio) +{ + struct disk_rcap * dp; + + dp = rcap; + while (dp->ci_msf.msf_min != 0) { + if (mp->msf_min == dp->ci_msf.msf_min && + mp->msf_sec == dp->ci_msf.msf_sec && + mp->msf_frame == dp->ci_msf.msf_frame && + maxblock == dp->ci_cap) + return (dp->ci_rcap); + dp++; + } + return (0L); +} diff --git a/wodim/drv_7501.c b/wodim/drv_7501.c new file mode 100644 index 0000000..5083750 --- /dev/null +++ b/wodim/drv_7501.c @@ -0,0 +1,1030 @@ +/* + * 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. + * + */ + +/* @(#)drv_7501.c 1.16 05/05/16 Copyright 2003-2005 J. Schilling */ +/* + * Device driver for the Masushita CW-7501 + * + * Copyright (c) 2003-2005 J. Schilling + * + * Mode Pages: + * 0x01 error recovery Seite 100 + * 0x02 disconnect/reconnect Seite 107 + * 0x0D CD-ROM device parameter Seite 110 + * 0x0E CD-ROM Audio control Seite 112 + * 0x20 Speed & Tray position Seite 115 + * 0x21 Media catalog number Seite 124 + * 0x22 ISRC Seite 125 + * 0x23 Dummy/Write Information Seite 126 + * 0x24 CD-R disk information Seite 127 + */ +/* + * 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. + */ + +#ifndef DEBUG +#define DEBUG +#endif +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include <libport.h> + +#include "wodim.h" + +extern int silent; +extern int debug; +extern int verbose; +extern int lverbose; +extern int xdebug; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct cw7501_mode_page_20 { /* Speed control */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar speed; + Ucbit res : 7; + Ucbit traypos : 1; +}; + +#else /* Motorola byteorder */ + +struct cw7501_mode_page_20 { /* Speed control */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar speed; + Ucbit traypos : 1; + Ucbit res : 7; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct cw7501_mode_page_21 { /* MCN */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x12 = 20 Bytes */ + Ucbit control : 4; + Ucbit addr : 4; + Uchar res_3; + Uchar res_4; + Uchar mcn[15]; +}; + +#else /* Motorola byteorder */ + +struct cw7501_mode_page_21 { /* MCN */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x12 = 20 Bytes */ + Ucbit addr : 4; + Ucbit control : 4; + Uchar res_3; + Uchar res_4; + Uchar mcn[15]; +}; +#endif + + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct cw7501_mode_page_22 { /* ISRC */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x12 = 20 Bytes */ + Ucbit control : 4; + Ucbit addr : 4; + Uchar trackno; + Uchar res_4; + Uchar isrc[15]; +}; + +#else /* Motorola byteorder */ + +struct cw7501_mode_page_22 { /* ISRC */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x12 = 20 Bytes */ + Ucbit addr : 4; + Ucbit control : 4; + Uchar trackno; + Uchar res_4; + Uchar isrc[15]; +}; +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct cw7501_mode_page_23 { /* Dummy / Write information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar res; + Ucbit autopg : 1; + Ucbit dummy : 1; + Ucbit res3_72 : 6; +}; + +#else /* Motorola byteorder */ + +struct cw7501_mode_page_23 { /* Dummy / Write information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar res; + Ucbit res3_72 : 6; + Ucbit dummy : 1; + Ucbit autopg : 1; +}; +#endif + +struct cw7501_mode_page_24 { /* CD-R Disk information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0A = 12 Bytes */ + Uchar disktype; + Uchar res; + Uchar appl_code[4]; + Uchar disk_id[4]; +}; + +struct cw7501_mode_data { + struct scsi_mode_header header; + union cdd_pagex { + struct cw7501_mode_page_20 page20; + struct cw7501_mode_page_21 page21; + struct cw7501_mode_page_22 page22; + struct cw7501_mode_page_23 page23; + struct cw7501_mode_page_24 page24; + } pagex; +}; + +/* + * Mode for read track information + */ +#define TI_TRACKINFO_R 0 +#define TI_NWA 1 +#define TI_PMA 2 +#define TI_TRACKINFO 3 + +struct cw7501_nwa { + Uchar nwa_length[2]; + Uchar nwa_res; + Uchar nwa_trackno; + Uchar nwa_nwa[4]; + Uchar nwa_freeblocks[4]; +}; + +struct cw7501_cue { + Uchar cs_ctladr; /* CTL/ADR for this track */ + Uchar cs_tno; /* This track number */ + Uchar cs_index; /* Index within this track */ + Uchar cs_dataform; /* Data form */ + /* Bit 0..3 Physical Format */ + /* Bit 4 Alt Copy (SCMS) */ + /* Bit 5 SubC Audio + RAW96 sub */ + Uchar cs_extension; /* Reserved or MCN/ISRC */ + Uchar cs_min; /* Absolute time minutes */ + Uchar cs_sec; /* Absolute time seconds */ + Uchar cs_frame; /* Absolute time frames */ +}; + + +static int cw7501_attach(SCSI *usalp, cdr_t *dp); +static int cw7501_init(SCSI *usalp, cdr_t *dp); +static int cw7501_getdisktype(SCSI *usalp, cdr_t *dp); +static int cw7501_speed_select(SCSI *usalp, cdr_t *dp, int *speedp); +static int cw7501_next_wr_addr(SCSI *usalp, track_t *trackp, long *ap); +static int cw7501_write(SCSI *usalp, caddr_t bp, long sectaddr, long size, + int blocks, BOOL islast); +static int cw7501_write_leadin(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int cw7501_open_track(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int cw7501_close_track(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int cw7501_open_session(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int cw7501_gen_cue(track_t *trackp, void *vcuep, BOOL needgap); +static void fillcue(struct cw7501_cue *cp, int ca, int tno, int idx, + int dataform, int scms, msf_t *mp); +static int cw7501_send_cue(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int cw7501_fixate(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int cw7501_rezero(SCSI *usalp, int reset, int dwreset); +static int cw7501_read_trackinfo(SCSI *usalp, Uchar *bp, int count, + int track, int mode); +static int cw7501_write_dao(SCSI *usalp, Uchar *bp, int len, int disktype); +static int cw7501_reserve_track(SCSI *usalp, unsigned long); +static int cw7501_set_mode(SCSI *usalp, int phys_form, int control, + int subc, int alt, int trackno, int tindex, + int packet_size, int write_mode); +static int cw7501_finalize(SCSI *usalp, int pad, int fixed); + + +cdr_t cdr_cw7501 = { + 0, 0, + /* + * Prinzipiell geht auch: CDR_PACKET & CDR_SRAW96R + */ + CDR_TAO|CDR_SAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 2, 2, + "cw_7501", + "driver for Matsushita/Panasonic CW-7501", + 0, + (dstat_t *)0, + drive_identify, + cw7501_attach, + cw7501_init, + cw7501_getdisktype, + scsi_load, + scsi_unload, + buf_dummy, /* RD buffer cap not supp. */ + cmd_dummy, /* recovery_needed */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + cw7501_speed_select, + select_secsize, + cw7501_next_wr_addr, + cw7501_reserve_track, + cw7501_write, + cw7501_gen_cue, + cw7501_send_cue, + cw7501_write_leadin, + cw7501_open_track, + cw7501_close_track, + cw7501_open_session, + cmd_dummy, /* close seession */ + cmd_dummy, /* abort */ + read_session_offset, + cw7501_fixate, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +static const char *sd_cw7501_error_str[] = { + "\100\201diagnostic failure on ROM", /* 40 81 */ + "\100\202diagnostic failure on CPU internal RAM", /* 40 82 */ + "\100\203diagnostic failure on BUFFER RAM", /* 40 83 */ + "\100\204diagnostic failure on internal SCSI controller", /* 40 84 */ + "\100\205diagnostic failure on system mechanism", /* 40 85 */ + + "\210\000Illegal Que Sheet (DAO parameter)", /* 88 00 */ + "\211\000Inappropriate command", /* 89 00 */ + + "\250\000Audio Play operation Not in Progress", /* A8 00 */ + "\251\000Buffer Overrun", /* A9 00 */ + + "\300\000Unrecordable Disk", /* C0 00 */ + "\301\000Illegal Track Status", /* C1 00 */ + "\302\000Reserved track Status", /* C2 00 */ + "\304\000Illegal Reserve Length for Reserve Track Command", /* C4 00 */ + "\304\001Illegal Data Form for Reserve Track Command", /* C4 01 */ + "\304\002Unable to Reserve Track, Because Track Mode has been Changed", /* C4 02 */ + + "\305\000Buffer error during recording", /* C5 00 */ + "\307\000Disk Style mismatch", /* C7 00 */ + "\312\000Power Calibration error", /* CA 00 */ + "\313\000Write error (Fatal Error/Time out)", /* CB 00 */ + "\314\000Not enough space (Leadin/Leadout space)", /* CC 00 */ + "\315\000No track present to finalize", /* CD 00 */ + "\317\000Unable to recover damaged disk", /* CF 00 */ + + "\320\000PMA area full (1000 blocks)", /* D0 00 */ + "\321\000PCA area full (100 counts)", /* D1 00 */ + "\322\000Recovery failed", /* D2 00 */ + "\323\000Recovery needed", /* D3 00 */ + NULL +}; + +static int +cw7501_attach(SCSI *usalp, cdr_t *dp) +{ + usal_setnonstderrs(usalp, sd_cw7501_error_str); + return (0); +} + +static int +cw7501_init(SCSI *usalp, cdr_t *dp) +{ + return (cw7501_speed_select(usalp, dp, NULL)); +} + +static int +cw7501_getdisktype(SCSI *usalp, cdr_t *dp) +{ + Ulong maxb = 0; + Uchar buf[256]; + int ret; + dstat_t *dsp = dp->cdr_dstat; + + if (xdebug > 0) { + usalp->silent++; + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + ret = cw7501_read_trackinfo(usalp, buf, 32, 0, 0); + if (ret >= 0) + usal_prbytes("TI EXIST-R (0): ", buf, 32 -usal_getresid(usalp)); + + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + ret = cw7501_read_trackinfo(usalp, buf, 32, 0, 1); + if (ret >= 0) + usal_prbytes("TI NWA (1): ", buf, 32 -usal_getresid(usalp)); + + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + ret = cw7501_read_trackinfo(usalp, buf, 32, 0, 2); + if (ret >= 0) + usal_prbytes("TI PMA (2): ", buf, 32 -usal_getresid(usalp)); + + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + ret = cw7501_read_trackinfo(usalp, buf, 32, 0, 3); + if (ret >= 0) + usal_prbytes("TI EXIST-ROM (3): ", buf, 32 -usal_getresid(usalp)); + usalp->silent--; + } + + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + + usalp->silent++; + ret = cw7501_read_trackinfo(usalp, buf, 12, 0, TI_NWA); + if (ret < 0 && + (dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) { + + /* + * Try to clear the dummy bit to reset the virtual + * drive status. Not all drives support it even though + * it is mentioned in the MMC standard. + */ + if (lverbose) + printf("Trying to clear drive status.\n"); + cw7501_rezero(usalp, 0, 1); + wait_unit_ready(usalp, 60); + ret = cw7501_read_trackinfo(usalp, buf, 12, 0, TI_NWA); + } + usalp->silent--; + + if (ret >= 0) { + maxb = a_to_u_4_byte(&buf[8]); + if (maxb != 0) + maxb -= 150; + } + dsp->ds_maxblocks = maxb; + + return (drive_getdisktype(usalp, dp)); +} + + +static int +cw7501_speed_select(SCSI *usalp, cdr_t *dp, int *speedp) +{ + struct scsi_mode_page_header *mp; + char mode[256]; + int len = 20; + int page = 0x20; + struct cw7501_mode_page_20 *xp20; + struct cw7501_mode_data md; + int count; + int speed = 1; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) { + speed = *speedp; + } else { + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, page, "Speed information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + return (-1); + } + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp20 = (struct cw7501_mode_page_20 *)mp; + speed = xp20->speed; + } + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct cw7501_mode_page_20); + + md.pagex.page20.p_code = 0x20; + md.pagex.page20.p_len = 0x02; + md.pagex.page20.speed = speed; + + if (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2) < 0) + return (-1); + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct cw7501_mode_page_23); + + md.pagex.page23.p_code = 0x23; + md.pagex.page23.p_len = 0x02; + md.pagex.page23.dummy = dummy?1:0; + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +cw7501_next_wr_addr(SCSI *usalp, track_t *trackp, long *ap) +{ + struct cw7501_nwa *nwa; + Uchar buf[256]; + long next_addr; + int result = -1; + + + /* + * Reading info for current track may require doing the read_track_info + * with either the track number (if the track is currently being written) + * or with 0 (if the track hasn't been started yet and is invisible + */ + nwa = (struct cw7501_nwa *)buf; + + if (trackp != 0 && trackp->track > 0 && is_packet(trackp)) { + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + + usalp->silent++; + result = cw7501_read_trackinfo(usalp, buf, sizeof (*nwa), + trackp->trackno, + TI_NWA); + usalp->silent--; + } + + if (result < 0) { + if (cw7501_read_trackinfo(usalp, buf, sizeof (*nwa), + 0, TI_NWA) < 0) + return (-1); + } + if (usalp->verbose) + usal_prbytes("track info:", buf, + 12-usal_getresid(usalp)); + next_addr = a_to_4_byte(&nwa->nwa_nwa); + /* + * XXX Für TAO definitiv notwendig. + * XXX ABhängig von Auto-Pregap? + */ + /* XXX */ next_addr += 150; + if (ap) + *ap = next_addr; + return (0); +} + +static int +cw7501_write(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + if (lverbose > 1 && islast) + printf("\nWriting last record for this track.\n"); + + return (write_xg0(usalp, bp, 0, size, blocks)); +} + +static int +cw7501_write_leadin(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uint i; + long startsec = 0L; + + if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) { + if (debug || lverbose) { + printf("Sending CUE sheet...\n"); + flush(); + } + if ((*dp->cdr_send_cue)(usalp, dp, trackp) < 0) { + errmsgno(EX_BAD, "Cannot send CUE sheet.\n"); + return (-1); + } + + /* + * Next writable address function does not work in DAO + * mode for this writer, so we just assume -150. + */ + startsec = -150; + if (debug) + printf("SAO startsec: %ld\n", startsec); + + if (trackp[0].flags & TI_TEXT) { + errmsgno(EX_BAD, "CD-Text unsupported in CW-7501 - ignoring.\n"); + } else for (i = 1; i <= trackp->tracks; i++) { + trackp[i].trackstart += startsec +150; + } + } + return (0); +} + +static Uchar db2phys[] = { + 0x00, /* 0 2352 bytes of raw data */ + 0xFF, /* 1 2368 bytes (raw data + P/Q Subchannel) */ + 0xFF, /* 2 2448 bytes (raw data + P-W Subchannel) */ + 0xFF, /* 3 2448 bytes (raw data + P-W raw Subchannel)*/ + 0xFF, /* 4 - Reserved */ + 0xFF, /* 5 - Reserved */ + 0xFF, /* 6 - Reserved */ + 0xFF, /* 7 - Vendor specific */ + 0x02, /* 8 2048 bytes Mode 1 (ISO/IEC 10149) */ + 0x03, /* 9 2336 bytes Mode 2 (ISO/IEC 10149) */ + 0xFF, /* 10 2048 bytes Mode 2 (CD-ROM XA form 1) */ + 0x04, /* 11 2056 bytes Mode 2 (CD-ROM XA form 1) */ + 0xFF, /* 12 2324 bytes Mode 2 (CD-ROM XA form 2) */ + 0x08, /* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */ + 0xFF, /* 14 - Reserved */ + 0xFF, /* 15 - Vendor specific */ +}; + +static int +cw7501_open_track(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + struct scsi_mode_page_header *mp; + Uchar mode[256]; + int len = 0; + int page = 0x23; + struct cw7501_mode_page_23 *xp23; + + if (!is_tao(trackp) && !is_packet(trackp)) { + if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) { + if (lverbose) { + printf("Writing pregap for track %d at %ld\n", + (int)trackp->trackno, + trackp->trackstart-trackp->pregapsize); + } + /* + * XXX Do we need to check isecsize too? + */ + pad_track(usalp, dp, trackp, + trackp->trackstart-trackp->pregapsize, + (Llong)trackp->pregapsize*trackp->secsize, + FALSE, 0); + } + return (0); + } + + if (select_secsize(usalp, trackp->secsize) < 0) + return (-1); + + if (!get_mode_params(usalp, page, "Dummy/autopg information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + return (-1); + } + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp23 = (struct cw7501_mode_page_23 *)mp; + xp23->autopg = 1; + if (!set_mode_params(usalp, "Dummy/autopg page", mode, len, 0, trackp->secsize)) + return (-1); + + /* + * Set write modes for next track. + */ + if (cw7501_set_mode(usalp, db2phys[trackp->dbtype & 0x0F], + st2mode[trackp->sectype&ST_MASK] | (is_copy(trackp) ? TM_ALLOW_COPY : 0), + 0, is_scms(trackp) ? 1 : 0, + trackp->trackno, 1, 0, + /* write mode TAO */ 0x01) < 0) + return (-1); + + return (0); +} + + +static int +cw7501_close_track(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (!is_tao(trackp) && !is_packet(trackp)) { + return (0); + } + return (scsi_flush_cache(usalp, FALSE)); +} + +static int +cw7501_open_session(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + struct cw7501_mode_data md; + int count; + + if (select_secsize(usalp, 2048) < 0) + return (-1); + + /* + * Disable Auto Pregap when writing in SAO mode. + */ + if (!is_tao(trackp) && !is_packet(trackp)) { + struct scsi_mode_page_header *mp; + Uchar mode[256]; + int len = 0; + int page = 0x23; + struct cw7501_mode_page_23 *xp23; + + if (!get_mode_params(usalp, page, "Dummy/autopg information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + return (-1); + } + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp23 = (struct cw7501_mode_page_23 *)mp; + xp23->autopg = 0; + if (!set_mode_params(usalp, "Dummy/autopg page", mode, len, 0, trackp->secsize)) + return (-1); + + return (0); + } + + /* + * Set Disk Type and Disk ID. + */ + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct cw7501_mode_page_24); + + md.pagex.page24.p_code = 0x24; + md.pagex.page24.p_len = 0x0A; + md.pagex.page24.disktype = toc2sess[track_base(trackp)->tracktype & TOC_MASK]; + i_to_4_byte(&md.pagex.page24.disk_id, 0x12345); + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +cw7501_fixate(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (!is_tao(trackp) && !is_packet(trackp)) { + return (scsi_flush_cache(usalp, FALSE)); + } + /* + * 0x00 Finalize Disk (not appendable) + * 0x01 Finalize Session (allow next session) + * 0x10 Finalize track (variable packet writing) - Must fluch cache before + */ + return (cw7501_finalize(usalp, 0, (track_base(trackp)->tracktype & TOCF_MULTI) ? 0x01 : 0x00)); +} + +/*--------------------------------------------------------------------------*/ + +static int +cw7501_gen_cue(track_t *trackp, void *vcuep, BOOL needgap) +{ + int tracks = trackp->tracks; + int i; + struct cw7501_cue **cuep = vcuep; + struct cw7501_cue *cue; + struct cw7501_cue *cp; + int ncue = 0; + int icue = 0; + int pgsize; + msf_t m; + int ctl; + int df; + int scms; + + cue = malloc(1); + + for (i = 0; i <= tracks; i++) { + ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[i])) + ctl |= TM_ALLOW_COPY << 4; + df = db2phys[trackp[i].dbtype & 0x0F]; + + if (trackp[i].isrc) { /* MCN or ISRC */ + ncue += 2; + cue = realloc(cue, ncue * sizeof (*cue)); + cp = &cue[icue++]; + if (i == 0) { + cp->cs_ctladr = 0x02; + movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7); + cp = &cue[icue++]; + cp->cs_ctladr = 0x02; + movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7); + } else { + cp->cs_ctladr = 0x03; + cp->cs_tno = i; + movebytes(&trackp[i].isrc[0], &cp->cs_index, 6); + cp = &cue[icue++]; + cp->cs_ctladr = 0x03; + cp->cs_tno = i; + movebytes(&trackp[i].isrc[6], &cp->cs_index, 6); + } + } + if (i == 0) { /* Lead in */ + lba_to_msf(-150, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 0, df, 0, &m); + } else { + scms = 0; + + if (is_scms(&trackp[i])) + scms = 0x80; + pgsize = trackp[i].pregapsize; + if (pgsize == 0 && needgap) + pgsize++; + lba_to_msf(trackp[i].trackstart-pgsize, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 0, df, scms, &m); + + if (trackp[i].nindex == 1) { + lba_to_msf(trackp[i].trackstart, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 1, df, scms, &m); + } else { + int idx; + long *idxlist; + + ncue += trackp[i].nindex; + idxlist = trackp[i].tindex; + cue = realloc(cue, ncue * sizeof (*cue)); + + for (idx = 1; idx <= trackp[i].nindex; idx++) { + lba_to_msf(trackp[i].trackstart + idxlist[idx], &m); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, idx, df, scms, &m); + } + } + } + } + /* Lead out */ + ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4; + df = db2phys[trackp[tracks+1].dbtype & 0x0F]; + lba_to_msf(trackp[tracks+1].trackstart, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m); + + if (lverbose > 1) { + for (i = 0; i < ncue; i++) { + usal_prbytes("", (Uchar *)&cue[i], 8); + } + } + if (cuep) + *cuep = cue; + else + free(cue); + return (ncue); +} + +static void +fillcue(struct cw7501_cue *cp /* The target cue entry */, + int ca /* Control/adr for this entry */, + int tno /* Track number for this entry */, + int idx /* Index for this entry */, + int dataform /* Data format for this entry */, + int scms /* Serial copy management */, + msf_t *mp /* MSF value for this entry */) +{ + cp->cs_ctladr = ca; + if (tno <= 99) + cp->cs_tno = to_bcd(tno); + else + cp->cs_tno = tno; + cp->cs_index = to_bcd(idx); + if (scms != 0) + dataform |= 0x10; + cp->cs_dataform = dataform; + cp->cs_extension = 0; + cp->cs_min = to_bcd(mp->msf_min); + cp->cs_sec = to_bcd(mp->msf_sec); + cp->cs_frame = to_bcd(mp->msf_frame); +} + +static int +cw7501_send_cue(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + struct cw7501_cue *cp; + int ncue; + int ret; + Uint i; + struct timeval starttime; + struct timeval stoptime; + int disktype; + + disktype = toc2sess[track_base(trackp)->tracktype & TOC_MASK]; + + for (i = 1; i <= trackp->tracks; i++) { + if (trackp[i].tracksize < (tsize_t)0) { + errmsgno(EX_BAD, "Track %d has unknown length.\n", i); + return (-1); + } + } + ncue = (*dp->cdr_gen_cue)(trackp, &cp, FALSE); + + starttime.tv_sec = 0; + starttime.tv_usec = 0; + stoptime = starttime; + gettimeofday(&starttime, (struct timezone *)0); + + usalp->silent++; + ret = cw7501_write_dao(usalp, (Uchar *)cp, ncue*8, disktype); + usalp->silent--; + free(cp); + if (ret < 0) { + errmsgno(EX_BAD, "CUE sheet not accepted. Retrying with minimum pregapsize = 1.\n"); + ncue = (*dp->cdr_gen_cue)(trackp, &cp, TRUE); + ret = cw7501_write_dao(usalp, (Uchar *)cp, ncue*8, disktype); + free(cp); + } + if (ret >= 0 && lverbose) { + gettimeofday(&stoptime, (struct timezone *)0); + prtimediff("Write Lead-in time: ", &starttime, &stoptime); + } + return (ret); +} + +/*--------------------------------------------------------------------------*/ +static int +cw7501_rezero(SCSI *usalp, int reset, int dwreset) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_REZERO_UNIT; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[5] |= reset ? 0x80 : 0; + scmd->cdb.cmd_cdb[5] |= dwreset ? 0x40 : 0; + + usalp->cmdname = "cw7501 rezero"; + + return (usal_cmd(usalp)); +} + + +static int +cw7501_read_trackinfo(SCSI *usalp, Uchar *bp, int count, int track, int mode) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t) scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)bp; + scmd->size = count; + 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 = 0xE9; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[6] = track; + g1_cdblen(&scmd->cdb.g1_cdb, count); + scmd->cdb.cmd_cdb[9] = (mode & 3) << 6; + + usalp->cmdname = "cw7501 read_track_information"; + + if (usal_cmd(usalp) < 0) + return (-1); + + return (0); +} + +static int +cw7501_write_dao(SCSI *usalp, Uchar *bp, int len, int disktype) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)bp; + scmd->size = len; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE6; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[2] = disktype; + g1_cdblen(&scmd->cdb.g1_cdb, len); + + usalp->cmdname = "cw7501 write_dao"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +/* + * XXX CW-7501 also needs "control", so we need to make a different + * XXX driver interface. + */ +static int +cw7501_reserve_track(SCSI *usalp, unsigned long len) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE7; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); +/* scmd->cdb.cmd_cdb[2] = control & 0x0F;*/ + i_to_4_byte(&scmd->cdb.cmd_cdb[5], len); + + usalp->cmdname = "cw7501 reserve_track"; + + comerrno(EX_BAD, "Control (as in set mode) missing.\n"); + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +cw7501_set_mode(SCSI *usalp, int phys_form, int control, int subc, + int alt, int trackno, int tindex, int packet_size, + int write_mode) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE2; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[2] = phys_form & 0x0F; + scmd->cdb.cmd_cdb[3] = (control & 0x0F) << 4; + scmd->cdb.cmd_cdb[3] |= subc ? 2 : 0; + scmd->cdb.cmd_cdb[3] |= alt ? 1 : 0; + scmd->cdb.cmd_cdb[4] = trackno; + scmd->cdb.cmd_cdb[5] = tindex; + i_to_3_byte(&scmd->cdb.cmd_cdb[6], packet_size); + scmd->cdb.cmd_cdb[9] = (write_mode & 0x03) << 6; + + usalp->cmdname = "cw7501 set_mode"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +cw7501_finalize(SCSI *usalp, int pad, int fixed) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 8 * 60; /* Needs up to 4 minutes */ + scmd->cdb.g1_cdb.cmd = 0xE3; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[1] = pad ? 1 : 0; + scmd->cdb.cmd_cdb[8] = fixed & 0x03; + + usalp->cmdname = "cw7501 finalize"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} diff --git a/wodim/drv_jvc.c b/wodim/drv_jvc.c new file mode 100644 index 0000000..ee2bcc2 --- /dev/null +++ b/wodim/drv_jvc.c @@ -0,0 +1,1433 @@ +/* + * 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. + * + */ + +/** @(#)drv_jvc.c 1.82 05/05/16 Copyright 1997-2005 J. Schilling */ +/* + * CDR device implementation for + * JVC/TEAC + * + * Copyright (c) 1997-2005 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. + */ +/*#define XXDEBUG*/ +/*#define XXBUFFER*/ + +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <unixstd.h> +#ifdef XXDEBUG +#include <stdxlib.h> +#endif + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "wodim.h" + +/* just a hack */ +long lba_addr; +BOOL last_done; + +/* + * macros for building MSF values from LBA + */ +#define LBA_MIN(x) ((x)/(60*75)) +#define LBA_SEC(x) (((x)%(60*75))/75) +#define LBA_FRM(x) ((x)%75) +#define MSF_CONV(a) ((((a)%(unsigned)100)/10)*16 + ((a)%(unsigned)10)) + +extern int lverbose; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ +struct teac_mode_page_21 { /* teac dummy selection */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x01 = 1 Byte */ + Ucbit dummy : 2; + Ucbit res : 6; +}; +#else +struct teac_mode_page_21 { /* teac dummy selection */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x01 = 1 Byte */ + Ucbit res : 6; + Ucbit dummy : 2; +}; +#endif + +struct teac_mode_page_31 { /* teac speed selection */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Byte */ + Uchar speed; + Uchar res; +}; + +struct cdd_52x_mode_data { + struct scsi_mode_header header; + union cdd_pagex { + struct teac_mode_page_21 teac_page21; + struct teac_mode_page_31 teac_page31; + } pagex; +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct pgm_subcode { /* subcode for progam area */ + Uchar subcode; + Ucbit addr : 4; + Ucbit control : 4; + Uchar track; + Uchar index; +}; + +#else + +struct pgm_subcode { /* subcode for progam area */ + Uchar subcode; + Ucbit control : 4; + Ucbit addr : 4; + Uchar track; + Uchar index; +}; + +#endif + +#define set_pgm_subcode(sp, t, c, a, tr, idx) (\ + (sp)->subcode = (t), \ + (sp)->control = (c), \ + (sp)->addr = (a), \ + (sp)->track = MSF_CONV(tr), \ + (sp)->index = (idx)) + +#define SC_P 1 /* Subcode defines pre-gap (Pause) */ +#define SC_TR 0 /* Subcode defines track data */ + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +typedef struct lin_subcode { /* subcode for lead in area */ + Ucbit addr : 4; + Ucbit control : 4; + Uchar track; + Uchar msf[3]; +} lsc_t; + +#else + +typedef struct lin_subcode { /* subcode for lead in area */ + Ucbit control : 4; + Ucbit addr : 4; + Uchar track; + Uchar msf[3]; +} lsc_t; + +#endif + +#define set_toc_subcode(sp, c, a, tr, bno) (\ + ((lsc_t *)sp)->control = (c), \ + ((lsc_t *)sp)->addr = (a), \ + ((lsc_t *)sp)->track = MSF_CONV(tr), \ + ((lsc_t *)sp)->msf[0] = MSF_CONV(LBA_MIN(bno)), \ + ((lsc_t *)sp)->msf[1] = MSF_CONV(LBA_SEC(bno)), \ + ((lsc_t *)sp)->msf[2] = MSF_CONV(LBA_FRM(bno)), \ + &((lsc_t *)sp)->msf[3]) + +#define set_lin_subcode(sp, c, a, pt, min, sec, frm) (\ + ((lsc_t *)sp)->control = (c), \ + ((lsc_t *)sp)->addr = (a), \ + ((lsc_t *)sp)->track = (pt), \ + ((lsc_t *)sp)->msf[0] = (min), \ + ((lsc_t *)sp)->msf[1] = (sec), \ + ((lsc_t *)sp)->msf[2] = (frm), \ + &((lsc_t *)sp)->msf[3]) + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct upc_subcode { /* subcode for upc/bar code */ + Uchar res; + Ucbit addr : 4; + Ucbit control : 4; + Uchar upc[13]; +}; + +#else + +struct upc_subcode { /* subcode for upc/bar code */ + Uchar res; + Ucbit control : 4; + Ucbit addr : 4; + Uchar upc[13]; +}; + +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct isrc_subcode { /* subcode for ISRC code */ + Uchar res; + Ucbit addr : 4; + Ucbit control : 4; + Uchar isrc[12]; + Uchar res14; +}; + +#else + +struct isrc_subcode { /* subcode for ISRC code */ + Uchar res; + Ucbit control : 4; + Ucbit addr : 4; + Uchar isrc[12]; + Uchar res14; +}; + +#endif + + +static int teac_attach(SCSI *usalp, cdr_t *dp); +static int teac_init(SCSI *usalp, cdr_t *dp); +static int teac_getdisktype(SCSI *usalp, cdr_t *dp); +static int speed_select_teac(SCSI *usalp, cdr_t *dp, int *speedp); +static int select_secsize_teac(SCSI *usalp, track_t *trackp); +static int next_wr_addr_jvc(SCSI *usalp, track_t *, long *ap); +static int write_teac_xg1(SCSI *usalp, caddr_t, long, long, int, BOOL); +static int cdr_write_teac(SCSI *usalp, caddr_t bp, long sectaddr, long size, + int blocks, BOOL islast); +static int open_track_jvc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int teac_fixation(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int close_track_teac(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int teac_open_session(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int initsub_teac(SCSI *usalp, int toctype, int multi); +static int teac_doopc(SCSI *usalp); +static int teac_opc(SCSI *usalp, caddr_t, int cnt, int doopc); +static int opt_power_judge(SCSI *usalp, int judge); +static int clear_subcode(SCSI *usalp); +static int set_limits(SCSI *usalp, long lba, long length); +static int set_subcode(SCSI *usalp, Uchar *subcode_data, int length); +static int read_disk_info_teac(SCSI *usalp, Uchar *data, int length, + int type); +static int teac_freeze(SCSI *usalp, int bp_flag); +static int teac_wr_pma(SCSI *usalp); +static int teac_rd_pma(SCSI *usalp); +static int next_wr_addr_teac(SCSI *usalp, long start_lba, long last_lba); +static int blank_jvc(SCSI *usalp, cdr_t *dp, long addr, int blanktype); +static int buf_cap_teac(SCSI *usalp, long *sp, long *fp); +static long read_peak_buffer_cap_teac(SCSI *usalp); +static int buffer_inquiry_teac(SCSI *usalp, int fmt); +#ifdef XXBUFFER +static void check_buffer_teac(SCSI *usalp); +#endif +#ifdef XXDEBUG +static void xxtest_teac(SCSI *usalp); +#endif + + +cdr_t cdr_teac_cdr50 = { + 0, 0, +/* CDR_TAO|CDR_SAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT,*/ + CDR_TAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT, + CDR_CDRW_ALL, + 2, 4, + "teac_cdr50", + "driver for Teac CD-R50S, Teac CD-R55S, JVC XR-W2010, Pinnacle RCD-5020", + 0, + (dstat_t *)0, + drive_identify, + teac_attach, + teac_init, + teac_getdisktype, + scsi_load, + scsi_unload, + buf_cap_teac, + cmd_dummy, /* recovery_needed */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_teac, + select_secsize, + next_wr_addr_jvc, + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + cdr_write_teac, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_jvc, + close_track_teac, + teac_open_session, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + teac_fixation, + cmd_dummy, /* stats */ +/* blank_dummy,*/ + blank_jvc, + format_dummy, + teac_opc, + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +static int +teac_init(SCSI *usalp, cdr_t *dp) +{ + return (speed_select_teac(usalp, dp, NULL)); +} + +static int +teac_getdisktype(SCSI *usalp, cdr_t *dp) +{ + dstat_t *dsp = dp->cdr_dstat; + struct scsi_mode_data md; + int count = sizeof (struct scsi_mode_header) + + sizeof (struct scsi_mode_blockdesc); + int len; + int page = 0; + long l; + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + (void) test_unit_ready(usalp); + if (mode_sense(usalp, (Uchar *)&md, count, page, 0) < 0) { /* Page n current */ + return (-1); + } else { + len = ((struct scsi_mode_header *)&md)->sense_data_len + 1; + } + if (((struct scsi_mode_header *)&md)->blockdesc_len < 8) + return (-1); + + l = a_to_u_3_byte(md.blockdesc.nlblock); + dsp->ds_maxblocks = l; + return (drive_getdisktype(usalp, dp)); +} + +static int +speed_select_teac(SCSI *usalp, cdr_t *dp, int *speedp) +{ + struct cdd_52x_mode_data md; + int count; + int status; + int speed = 1; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) + speed = *speedp; + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct teac_mode_page_21); + + md.pagex.teac_page21.p_code = 0x21; + md.pagex.teac_page21.p_len = 0x01; + md.pagex.teac_page21.dummy = dummy?3:0; + + status = mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2); + if (status < 0) + return (status); + + if (speedp == 0) + return (0); + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct teac_mode_page_31); + + speed >>= 1; + md.pagex.teac_page31.p_code = 0x31; + md.pagex.teac_page31.p_len = 0x02; + md.pagex.teac_page31.speed = speed; + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +select_secsize_teac(SCSI *usalp, track_t *trackp) +{ + struct scsi_mode_data md; + int count = sizeof (struct scsi_mode_header) + + sizeof (struct scsi_mode_blockdesc); + int len; + int page = 0; + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + (void) test_unit_ready(usalp); + if (mode_sense(usalp, (Uchar *)&md, count, page, 0) < 0) { /* Page n current */ + return (-1); + } else { + len = ((struct scsi_mode_header *)&md)->sense_data_len + 1; + } + if (((struct scsi_mode_header *)&md)->blockdesc_len < 8) + return (-1); + + md.header.sense_data_len = 0; + md.header.blockdesc_len = 8; + + md.blockdesc.density = 1; + if (trackp->secsize == 2352) + md.blockdesc.density = 4; + i_to_3_byte(md.blockdesc.lblen, trackp->secsize); + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +next_wr_addr_jvc(SCSI *usalp, track_t *trackp, long *ap) +{ + if (trackp != 0 && trackp->track > 0) { + *ap = lba_addr; + } else { + long nwa; + + if (read_B0(usalp, TRUE, &nwa, NULL) < 0) + return (-1); + + *ap = nwa + 150; + } + return (0); +} + +static int +write_teac_xg1(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL extwr /* is an extended write */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; +/* 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 = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, sectaddr); + g1_cdblen(&scmd->cdb.g1_cdb, blocks); + scmd->cdb.g1_cdb.vu_97 = extwr; + + usalp->cmdname = "write_teac_g1"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (size - usal_getresid(usalp)); +} + +static int +cdr_write_teac(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + int ret; + + if (islast) + last_done = TRUE; + + ret = write_teac_xg1(usalp, bp, sectaddr, size, blocks, !islast); + if (ret < 0) + return (ret); + + lba_addr = sectaddr + blocks; +#ifdef XXBUFFER + check_buffer_teac(usalp); +#endif + return (ret); +} + +static int +open_track_jvc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int status; + long blocks; + long pregapsize; + struct pgm_subcode sc; + + last_done = FALSE; + + if (select_secsize_teac(usalp, trackp) < 0) + return (-1); + + status = clear_subcode(usalp); +/*next_wr_addr_teac(usalp);*/ + if (status < 0) + return (status); + +if (trackp->pregapsize != 0) { + if (lverbose > 1) { + printf("set_limits(%ld, %ld)-> %ld\n", + lba_addr, trackp->pregapsize, lba_addr + trackp->pregapsize); + } + + status = set_limits(usalp, lba_addr, trackp->pregapsize); + if (status < 0) + return (status); + + /* + * Set pre-gap (pause - index 0) + */ + set_pgm_subcode(&sc, SC_P, + st2mode[trackp->sectype&ST_MASK], ADR_POS, trackp->trackno, 0); + + if (lverbose > 1) + usal_prbytes("Subcode:", (Uchar *)&sc, sizeof (sc)); + + status = set_subcode(usalp, (Uchar *)&sc, sizeof (sc)); + if (status < 0) + return (status); + + pregapsize = trackp->pregapsize; + if (!is_audio(trackp)) { + lba_addr += 5; /* link & run in blocks */ + pregapsize -= 5; + } + if (lverbose > 1) { + printf("pad_track(%ld, %ld)-> %ld\n", + lba_addr, pregapsize, lba_addr + pregapsize); + } + /* + * XXX Do we need to check isecsize too? + */ + if (pad_track(usalp, dp, trackp, + lba_addr, (Llong)pregapsize*trackp->secsize, + FALSE, (Llong *)0) < 0) + return (-1); +} + + blocks = trackp->tracksize/trackp->secsize + + (trackp->tracksize%trackp->secsize?1:0); + blocks += trackp->padsecs; + if (blocks < 300) + blocks = 300; + if (!is_audio(trackp)) + blocks += 2; +if (!is_last(trackp) && trackp[1].pregapsize == 0) + blocks -= 150; + + /* + * set the limits for the new subcode - seems to apply to all + * of the data track. + * Unknown tracksize is handled in open_session. + * We definitely need to know the tracksize in this driver. + */ + if (lverbose > 1) { + printf("set_limits(%ld, %ld)-> %ld\n", + lba_addr, blocks, lba_addr + blocks); + } + status = set_limits(usalp, lba_addr, blocks); + if (status < 0) + return (status); + + /* + * Set track start (index 1) + */ + set_pgm_subcode(&sc, SC_TR, + st2mode[trackp->sectype&ST_MASK], ADR_POS, trackp->trackno, 1); + + if (lverbose > 1) + usal_prbytes("Subcode:", (Uchar *)&sc, sizeof (sc)); + + status = set_subcode(usalp, (Uchar *)&sc, sizeof (sc)); + if (status < 0) + return (status); + +if (!is_last(trackp) && trackp[1].pregapsize == 0) { + blocks += lba_addr; + pregapsize = 150; + + if (lverbose > 1) { + printf("set_limits(%ld, %ld)-> %ld\n", + blocks, pregapsize, blocks + pregapsize); + } + + status = set_limits(usalp, blocks, pregapsize); + if (status < 0) + return (status); + + /* + * Set pre-gap (pause - index 0) + */ + trackp++; + set_pgm_subcode(&sc, SC_P, + st2mode[trackp->sectype&ST_MASK], ADR_POS, trackp->trackno, 0); + + if (lverbose > 1) + usal_prbytes("Subcode:", (Uchar *)&sc, sizeof (sc)); + + status = set_subcode(usalp, (Uchar *)&sc, sizeof (sc)); + if (status < 0) + return (status); +} + return (status); +} + +static char sector[3000]; + +static int +close_track_teac(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int ret = 0; + + if (!last_done) { + printf("WARNING: adding dummy block to close track.\n"); + /* + * need read sector size + * XXX do we really need this ? + * XXX if we need this can we set blocks to 0 ? + */ + ret = write_teac_xg1(usalp, sector, lba_addr, 2352, 1, FALSE); + lba_addr++; + } + if (!is_audio(trackp)) + lba_addr += 2; + teac_wr_pma(usalp); + return (ret); +} + + + +static const char *sd_teac50_error_str[] = { + "\100\200diagnostic failure on component parts", /* 40 80 */ + "\100\201diagnostic failure on memories", /* 40 81 */ + "\100\202diagnostic failure on cd-rom ecc circuit", /* 40 82 */ + "\100\203diagnostic failure on gate array", /* 40 83 */ + "\100\204diagnostic failure on internal SCSI controller", /* 40 84 */ + "\100\205diagnostic failure on servo processor", /* 40 85 */ + "\100\206diagnostic failure on program rom", /* 40 86 */ + "\100\220thermal sensor failure", /* 40 90 */ + "\200\000controller prom error", /* 80 00 */ /* JVC */ + "\201\000no disk present - couldn't get focus", /* 81 00 */ /* JVC */ + "\202\000no cartridge present", /* 82 00 */ /* JVC */ + "\203\000unable to spin up", /* 83 00 */ /* JVC */ + "\204\000addr exceeded the last valid block addr", /* 84 00 */ /* JVC */ + "\205\000sync error", /* 85 00 */ /* JVC */ + "\206\000address can't find or not data track", /* 86 00 */ /* JVC */ + "\207\000missing track", /* 87 00 */ /* JVC */ + "\213\000cartridge could not be ejected", /* 8B 00 */ /* JVC */ + "\215\000audio not playing", /* 8D 00 */ /* JVC */ + "\216\000read toc error", /* 8E 00 */ /* JVC */ + "\217\000a blank disk is detected by read toc", /* 8F 00 */ + "\220\000pma less disk - not a recordable disk", /* 90 00 */ + "\223\000mount error", /* 93 00 */ /* JVC */ + "\224\000toc less disk", /* 94 00 */ + "\225\000disc information less disk", /* 95 00 */ /* JVC */ + "\226\000disc information read error", /* 96 00 */ /* JVC */ + "\227\000linear velocity measurement error", /* 97 00 */ /* JVC */ + "\230\000drive sequence stop", /* 98 00 */ /* JVC */ + "\231\000actuator velocity control error", /* 99 00 */ /* JVC */ + "\232\000slider velocity control error", /* 9A 00 */ /* JVC */ + "\233\000opc initialize error", /* 9B 00 */ + "\233\001power calibration not executed", /* 9B 01 */ + "\234\000opc execution eror", /* 9C 00 */ + "\234\001alpc error - opc execution", /* 9C 01 */ + "\234\002opc execution timeout", /* 9C 02 */ + "\245\000disk application code does not match host application code", /* A5 00 */ + "\255\000completed preview write", /* AD 00 */ + "\256\000invalid B0 value", /* AE 00 */ /* JVC */ + "\257\000pca area full", /* AF 00 */ + "\260\000efm isn't detected", /* B0 00 */ /* JVC */ + "\263\000no logical sector", /* B3 00 */ /* JVC */ + "\264\000full pma area", /* B4 00 */ + "\265\000read address is atip area - blank", /* B5 00 */ + "\266\000write address is efm area - aleady written", /* B6 00 */ + "\271\000abnormal spinning - servo irq", /* B9 00 */ /* JVC */ + "\272\000no write data - buffer empty", /* BA 00 */ + "\273\000write emergency occurred", /* BB 00 */ + "\274\000read timeout", /* BC 00 */ /* JVC */ + "\277\000abnormal spin - nmi", /* BF 00 */ /* JVC */ + "\301\0004th run-in block detected", /* C1 00 */ + "\302\0003rd run-in block detected", /* C2 00 */ + "\303\0002nd run-in block detected", /* C3 00 */ + "\304\0001st run-in block detected", /* C4 00 */ + "\305\000link block detected", /* C5 00 */ + "\306\0001st run-out block detected", /* C6 00 */ + "\307\0002nd run-out block detected", /* C7 00 */ + "\314\000write request means mixed data mode", /* CC 00 */ + "\315\000unable to ensure reliable writing with the inserted disk - unsupported disk", /* CD 00 */ + "\316\000unable to ensure reliable writing as the inserted disk does not support speed", /* CE 00 */ + "\317\000unable to ensure reliable writing as the inserted disk has no char id code", /* CF 00 */ + NULL +}; + +static int +teac_attach(SCSI *usalp, cdr_t *dp) +{ + usal_setnonstderrs(usalp, sd_teac50_error_str); +#ifdef XXDEBUG + xxtest_teac(usalp); + exit(0); +#endif + return (0); +} + +static int +teac_fixation(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + long lba; + int status; + Uchar *sp; + Uint i; +extern char *buf; + + if (trackp->tracks < 1) { + /* + * We come here if wodim isonly called with the -fix option. + * As long as we cannot read and interpret the PMA, we must + * abort here. + */ + teac_rd_pma(usalp); +/* errmsgno(EX_BAD, "Cannot fixate zero track disk.\n");*/ + errmsgno(EX_BAD, "Cannot fixate without track list (not yet implemented).\n"); + return (-1); + } + sp = (Uchar *)buf; + + sleep(1); + + status = clear_subcode(usalp); + sleep(1); + if (status < 0) + return (status); + + sp[0] = 0; /* reserved */ + sp[1] = 0; /* reserved */ + sp[2] = 0; /* Q TNO */ + + sp = &sp[3]; /* point past header */ + + /* + * Set up TOC entries for all tracks + */ + for (i = 1; i <= trackp->tracks; i++) { + lba = trackp[i].trackstart+150; /* MSF=00:02:00 is LBA=0 */ + + sp = set_toc_subcode(sp, + /* ctrl/adr for this track */ + st2mode[trackp[i].sectype&ST_MASK], ADR_POS, + trackp[i].trackno, lba); + } + + /* + * Set first track on disk + * + * XXX We set the track type for the lead-in to the track type + * XXX of the first track. The TEAC manual states that we should use + * XXX audio if the disk contains both, audio and data tracks. + */ + sp = set_lin_subcode(sp, + /* ctrl/adr for first track */ + st2mode[trackp[1].sectype&ST_MASK], ADR_POS, + 0xA0, /* Point A0 */ + trackp[1].trackno, /* first track # */ + toc2sess[track_base(trackp)->tracktype & TOC_MASK], /* disk type */ + 0); /* reserved */ + + /* + * Set last track on disk + */ + sp = set_lin_subcode(sp, + /* ctrl/adr for first track */ + st2mode[trackp[1].sectype&ST_MASK], ADR_POS, + 0xA1, /* Point A1 */ + MSF_CONV(trackp[trackp->tracks].trackno), /* last track # */ + 0, /* reserved */ + 0); /* reserved */ + + /* + * Set start of lead out area in MSF + * MSF=00:02:00 is LBA=0 + */ + lba = lba_addr + 150; + if (lverbose > 1) + printf("lba: %ld lba_addr: %ld\n", lba, lba_addr); + + if (lverbose > 1) + printf("Lead out start: (%02d:%02d/%02d)\n", + minutes(lba*2352), + seconds(lba*2352), + frames(lba*2352)); + + sp = set_lin_subcode(sp, + /* ctrl/adr for first track */ + st2mode[trackp[1].sectype&ST_MASK], ADR_POS, + 0xA2, /* Point A2 */ + MSF_CONV(LBA_MIN(lba)), + MSF_CONV(LBA_SEC(lba)), + MSF_CONV(LBA_FRM(lba))); + + status = sp - ((Uchar *)buf); + if (lverbose > 1) { + printf("Subcode len: %d\n", status); + usal_prbytes("Subcode:", (Uchar *)buf, status); + } + status = set_subcode(usalp, (Uchar *)buf, status); + sleep(1); + if (status < 0) + return (status); + + /* + * now write the toc + */ + status = teac_freeze(usalp, (track_base(trackp)->tracktype & TOCF_MULTI) == 0); + return (status); + +} + +static int +teac_open_session(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uint i; + + for (i = 1; i <= trackp->tracks; i++) { + if (trackp[i].tracksize < (tsize_t)0) { + /* + * XXX How about setting the subcode range to infinity. + * XXX and correct it in clode track before writing + * XXX the PMA? + */ + errmsgno(EX_BAD, "Track %d has unknown length.\n", i); + return (-1); + } + } + return (initsub_teac(usalp, track_base(trackp)->tracktype & TOC_MASK, + track_base(trackp)->tracktype & TOCF_MULTI)); +} + +static int +initsub_teac(SCSI *usalp, int toctype, int multi) +{ + int status; + + usalp->silent++; + if (read_B0(usalp, TRUE, &lba_addr, NULL) < 0) + lba_addr = -150; + usalp->silent--; + + status = clear_subcode(usalp); + if (status < 0) + return (status); + + return (0); +} + +static int +teac_doopc(SCSI *usalp) +{ + int status; + + if (lverbose) { + fprintf(stdout, "Judging disk..."); + flush(); + } + status = opt_power_judge(usalp, 1); + if (status < 0) { + printf("\n"); + return (status); + } + if (lverbose) { + fprintf(stdout, "done.\nCalibrating laser..."); + flush(); + } + + status = opt_power_judge(usalp, 0); + if (lverbose) { + fprintf(stdout, "done.\n"); + } + /* + * Check for error codes 0xCD ... 0xCF + */ + usalp->silent++; + if (next_wr_addr_teac(usalp, -1, -1) < 0) { + if (usalp->verbose == 0 && usal_sense_key(usalp) != SC_ILLEGAL_REQUEST) + usal_printerr(usalp); + } + usalp->silent--; + return (status); +} + +static int +teac_opc(SCSI *usalp, caddr_t bp, int cnt, int doopc) +{ + int status; + int count = 0; + + do { + status = teac_doopc(usalp); + } while (++count <= 1 && status < 0); + + return (status); +} + +/*--------------------------------------------------------------------------*/ +#define SC_SET_LIMITS 0xb3 /* teac 12 byte command */ +#define SC_SET_SUBCODE 0xc2 /* teac 10 byte command */ +#define SC_READ_PMA 0xc4 /* teac 10 byte command */ +#define SC_READ_DISK_INFO 0xc7 /* teac 10 byte command */ +#define SC_BUFFER_INQUIRY 0xe0 /* teac 12 byte command */ + +#define SC_WRITE_PMA 0xe1 /* teac 12 byte command */ +#define SC_FREEZE 0xe3 /* teac 12 byte command */ +#define SC_OPC_EXECUTE 0xec /* teac 12 byte command */ +#define SC_CLEAR_SUBCODE 0xe4 /* teac 12 byte command */ +#define SC_NEXT_WR_ADDRESS 0xe6 /* teac 12 byte command */ + +#define SC_READ_PEAK_BUF_CAP 0xef /* teac 12 byte command */ + +/* + * Optimum power calibration for Teac Drives. + */ +static int +opt_power_judge(SCSI *usalp, int judge) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 60; + + scmd->cdb.g5_cdb.cmd = SC_OPC_EXECUTE; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.reladr = judge; /* Judge the Disc */ + + usalp->cmdname = "opt_power_judge"; + + return (usal_cmd(usalp)); +} + +/* + * Clear subcodes for Teac Drives. + */ +static int +clear_subcode(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + + scmd->cdb.g5_cdb.cmd = SC_CLEAR_SUBCODE; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.addr[3] = 0x80; + + usalp->cmdname = "clear subcode"; + + return (usal_cmd(usalp)); +} + +/* + * Set limits for command linking for Teac Drives. + */ +static int +set_limits(SCSI *usalp, long lba, long length) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + + scmd->cdb.g5_cdb.cmd = SC_SET_LIMITS; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], lba); + i_to_4_byte(&scmd->cdb.g5_cdb.count[0], length); + + usalp->cmdname = "set limits"; + + return (usal_cmd(usalp)); +} + +/* + * Set subcode for Teac Drives. + */ +static int +set_subcode(SCSI *usalp, Uchar *subcode_data, int length) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)subcode_data; + scmd->size = length; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + + scmd->cdb.g1_cdb.cmd = SC_SET_SUBCODE; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, length); + + usalp->cmdname = "set subcode"; + + return (usal_cmd(usalp)); +} + +static int +read_disk_info_teac(SCSI *usalp, Uchar *data, int length, int type) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)data; + scmd->size = length; + 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 = SC_READ_DISK_INFO; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + scmd->cdb.g1_cdb.reladr = type & 1; + scmd->cdb.g1_cdb.res = (type & 2) >> 1; + + usalp->cmdname = "read disk info teac"; + + return (usal_cmd(usalp)); +} + +/* + * Perform the freeze command for Teac Drives. + */ +static int +teac_freeze(SCSI *usalp, int bp_flag) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 8 * 60; /* Needs up to 4 minutes */ + + scmd->cdb.g5_cdb.cmd = SC_FREEZE; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.addr[3] = bp_flag ? 0x80 : 0; + + usalp->cmdname = "teac_freeze"; + + return (usal_cmd(usalp)); +} + +static int +teac_wr_pma(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + + scmd->cdb.g5_cdb.cmd = SC_WRITE_PMA; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "teac_write_pma"; + + return (usal_cmd(usalp)); +} + +/* + * Read PMA for Teac Drives. + */ +static int +teac_rd_pma(SCSI *usalp) +{ + unsigned char xx[256]; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)xx, sizeof (xx), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)xx; + scmd->size = sizeof (xx); + 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 = SC_READ_PMA; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + g1_cdblen(&scmd->cdb.g1_cdb, sizeof (xx)); + + usalp->cmdname = "teac_read_pma"; + +/* return (usal_cmd(usalp));*/ + if (usal_cmd(usalp) < 0) + return (-1); + + if (usalp->verbose) { + usal_prbytes("PMA Data", xx, sizeof (xx) - usal_getresid(usalp)); + } + if (lverbose) { + unsigned i; + Uchar *p; + + usal_prbytes("PMA Header: ", xx, 4); + i = xx[2]; + p = &xx[4]; + for (; i <= xx[3]; i++) { + usal_prbytes("PMA: ", p, 10); + p += 10; + } + } + return (0); +} + +/* + * Next writable address for Teac Drives. + */ +static int +next_wr_addr_teac(SCSI *usalp, long start_lba, long last_lba) +{ + unsigned char xx[256]; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)xx, sizeof (xx), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)xx; + scmd->size = sizeof (xx); + 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 = SC_NEXT_WR_ADDRESS; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], start_lba); + i_to_4_byte(&scmd->cdb.g5_cdb.count[0], last_lba); + + if (usalp->verbose) + printf("start lba: %ld last lba: %ld\n", + start_lba, last_lba); + + usalp->cmdname = "next writable address"; + +/* return (usal_cmd(usalp));*/ + if (usal_cmd(usalp) < 0) + return (-1); + + if (usalp->verbose) { + usal_prbytes("WRa Data", xx, sizeof (xx) - usal_getresid(usalp)); + printf("NWA: %ld\n", a_to_4_byte(xx)); + } + return (0); +} + +static int +blank_jvc(SCSI *usalp, cdr_t *dp, long addr, int blanktype) +{ + extern char *blank_types[]; + + if (lverbose) { + printf("Blanking %s\n", blank_types[blanktype & 0x07]); + flush(); + } + + return (scsi_blank(usalp, addr, blanktype, FALSE)); +} + +static int +buf_cap_teac(SCSI *usalp, long *sp, long *fp) +{ + Ulong freespace; + Ulong bufsize; + long ret; + int per; + + ret = read_peak_buffer_cap_teac(usalp); + if (ret < 0) + return (-1); + bufsize = ret; + freespace = 0; + if (sp) + *sp = bufsize; + if (fp) + *fp = freespace; + + if (usalp->verbose || (sp == 0 && fp == 0)) + printf("BFree: %ld K BSize: %ld K\n", freespace >> 10, bufsize >> 10); + + if (bufsize == 0) + return (0); + per = (100 * (bufsize - freespace)) / bufsize; + if (per < 0) + return (0); + if (per > 100) + return (100); + return (per); +} + +static long +read_peak_buffer_cap_teac(SCSI *usalp) +{ + Uchar xx[4]; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)xx, sizeof (xx), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)xx; + scmd->size = sizeof (xx); + 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 = SC_READ_PEAK_BUF_CAP; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "read peak buffer capacity"; + +#define BDEBUG +#ifndef BDEBUG + return (usal_cmd(usalp)); +#else + if (usal_cmd(usalp) < 0) + return (-1); + + if (usalp->verbose) { + usal_prbytes("WRa Data", xx, sizeof (xx) - usal_getresid(usalp)); + printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1])); + } + return (a_to_u_3_byte(&xx[1])); +/* return (0);*/ +#endif +} + +#define BI_ONE_BYTE 0xC0 +#define BI_448_BYTE 0x40 +#define BI_APP_CODE 0x10 + +static int +buffer_inquiry_teac(SCSI *usalp, int fmt) +{ + Uchar xx[448]; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)xx, sizeof (xx), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)xx; + scmd->size = sizeof (xx); + scmd->size = 448; + 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 = SC_BUFFER_INQUIRY; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + if (fmt > 0) { + scmd->cdb.g5_cdb.addr[3] = fmt; + if (fmt == BI_ONE_BYTE) + scmd->size = 1; + } else { + scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE; +/* scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/ + } + + usalp->cmdname = "buffer inquiry"; + +#define BDEBUG +#ifndef BDEBUG + return (usal_cmd(usalp)); +#else + if (usal_cmd(usalp) < 0) + return (-1); + + if (usalp->verbose) { +/* usal_prbytes("WRa Data", xx, sizeof (xx) - usal_getresid(usalp));*/ +/* usal_prbytes("WRa Data", xx, 1);*/ + + if (fmt > 0) printf("fmt: %X ", fmt); + usal_prbytes("WRa Data", xx, 9); + printf("%d\n", xx[8] - xx[1]); +/* printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/ + } + return (0); +#endif +} + +#ifdef XXBUFFER +static void +check_buffer_teac(SCSI *usalp) +{ + printf("-------\n"); + buffer_inquiry_teac(usalp, 0); +#ifdef SL + usleep(40000); + buffer_inquiry_teac(usalp, 0); +#endif + read_peak_buffer_cap_teac(usalp); +} +#endif +/*--------------------------------------------------------------------------*/ +#ifdef XXDEBUG +#include "scsimmc.h" + +static int g7_teac(SCSI *usalp); +static int g6_teac(SCSI *usalp); + +static int +g7_teac(SCSI *usalp) +{ + Uchar xx[2048]; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)xx, sizeof (xx), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)xx; + scmd->size = sizeof (xx); + 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 = 0xDf; +/* scmd->cdb.g5_cdb.cmd = 0xE5;*/ + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + +/* scmd->cdb.g5_cdb.addr[3] = BI_ONE_BYTE;*/ +/* scmd->size = 1;*/ + +/* scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;*/ +/* scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/ + + usalp->cmdname = "g7 teac"; + +/* return (usal_cmd(usalp));*/ + if (usal_cmd(usalp) < 0) + return (-1); + +/* if (usalp->verbose) {*/ + usal_prbytes("WRa Data", xx, sizeof (xx) - usal_getresid(usalp)); +/* usal_prbytes("WRa Data", xx, 1);*/ +/* usal_prbytes("WRa Data", xx, 9);*/ +/*printf("%d\n", xx[8] - xx[1]);*/ +/* printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/ +/* }*/ + return (0); +} + +static int +g6_teac(SCSI *usalp) +{ + Uchar xx[2048]; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)xx, sizeof (xx), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)xx; + scmd->size = sizeof (xx); + 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 = 0xC1; + scmd->cdb.g1_cdb.cmd = 0xC3; + scmd->cdb.g1_cdb.cmd = 0xC6; + scmd->cdb.g1_cdb.cmd = 0xC7; /* Read TOC */ + scmd->cdb.g1_cdb.cmd = 0xCe; + scmd->cdb.g1_cdb.cmd = 0xCF; + scmd->cdb.g1_cdb.cmd = 0xC7; /* Read TOC */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "g6 teac"; + +/* return (usal_cmd(usalp));*/ + if (usal_cmd(usalp) < 0) + return (-1); + +/* if (usalp->verbose) {*/ + usal_prbytes("WRa Data", xx, sizeof (xx) - usal_getresid(usalp)); +/* usal_prbytes("WRa Data", xx, 1);*/ +/* usal_prbytes("WRa Data", xx, 9);*/ +/*printf("%d\n", xx[8] - xx[1]);*/ +/* printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/ +/* }*/ + return (0); +} + +static void +xxtest_teac(SCSI *usalp) +{ + read_peak_buffer_cap_teac(usalp); + +/*#define XDI*/ +#ifdef XDI + { + Uchar cbuf[512]; + +/* read_disk_info_teac(usalp, data, length, type)*/ +/* read_disk_info_teac(usalp, cbuf, 512, 2);*/ +/* read_disk_info_teac(usalp, cbuf, 512, 2);*/ + read_disk_info_teac(usalp, cbuf, 512, 3); + usal_prbytes("DI Data", cbuf, sizeof (cbuf) - usal_getresid(usalp)); + } +#endif /* XDI */ + + buffer_inquiry_teac(usalp, -1); + +/*#define XBU*/ +#ifdef XBU + { + int i; + + for (i = 0; i < 63; i++) { + usalp->silent++; + buffer_inquiry_teac(usalp, i<<2); + usalp->silent--; + } + } +#endif /* XBU */ + +/* printf("LLLL\n");*/ +/* g7_teac(usalp);*/ +/* g6_teac(usalp);*/ +} +#endif /* XXDEBUG */ diff --git a/wodim/drv_mmc.c b/wodim/drv_mmc.c new file mode 100644 index 0000000..b075889 --- /dev/null +++ b/wodim/drv_mmc.c @@ -0,0 +1,4362 @@ +/* + * 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. + * + */ + +/* @(#)drv_mmc.c 1.163 06/01/12 Copyright 1997-2006 J. Schilling */ +/* + * CDR device implementation for + * SCSI-3/mmc conforming drives + * e.g. Yamaha CDR-400, Ricoh MP6200 + * + * Copyright (c) 1997-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. + * + * 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. + */ + +/*#define DEBUG*/ +#define PRINT_ATIP +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "scsimmc.h" +#include "mmcvendor.h" +#include "wodim.h" +#include "scsi_scan.h" + +extern char *driveropts; + +extern int debug; +extern int lverbose; +extern int xdebug; + +static int curspeed = 1; + +static char clv_to_speed[16] = { +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + 0, 2, 4, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static char hs_clv_to_speed[16] = { +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + 0, 2, 4, 6, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static char us_clv_to_speed[16] = { +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + 0, 2, 4, 8, 0, 0, 16, 0, 24, 32, 40, 48, 0, 0, 0, 0 +}; + +#ifdef __needed__ +static int mmc_load(SCSI *usalp, cdr_t *dp); +static int mmc_unload(SCSI *usalp, cdr_t *dp); +#endif +void mmc_opthelp(cdr_t *dp, int excode); +char *hasdrvopt(char *optstr, char *optname); +static cdr_t *identify_mmc(SCSI *usalp, cdr_t *, struct scsi_inquiry *); +static int attach_mmc(SCSI *usalp, cdr_t *); +static int attach_mdvd(SCSI *usalp, cdr_t *); +int check_writemodes_mmc(SCSI *usalp, cdr_t *dp); +int check_writemodes_mdvd(SCSI *usalp, cdr_t *dp); +static int deflt_writemodes_mmc(SCSI *usalp, BOOL reset_dummy); +static int deflt_writemodes_mdvd(SCSI *usalp, BOOL reset_dummy); +static int get_diskinfo(SCSI *usalp, struct disk_info *dip); +static void di_to_dstat(struct disk_info *dip, dstat_t *dsp); +static int get_atip(SCSI *usalp, struct atipinfo *atp); +#ifdef PRINT_ATIP +static int get_pma(SCSI *usalp); +#endif +static int init_mmc(SCSI *usalp, cdr_t *dp); +static int getdisktype_mmc(SCSI *usalp, cdr_t *dp); +static int getdisktype_mdvd(SCSI *usalp, cdr_t *dp); +static int speed_select_mmc(SCSI *usalp, cdr_t *dp, int *speedp); +static int speed_select_mdvd(SCSI *usalp, cdr_t *dp, int *speedp); +static int mmc_set_speed(SCSI *usalp, int readspeed, int writespeed, + int rotctl); +static int next_wr_addr_mmc(SCSI *usalp, track_t *trackp, long *ap); +static int next_wr_addr_mdvd(SCSI *usalp, track_t *trackp, long *ap); +static int write_leadin_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int close_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int close_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_session_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_session_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int waitfix_mmc(SCSI *usalp, int secs); +static int fixate_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int fixate_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int blank_mmc(SCSI *usalp, cdr_t *dp, long addr, int blanktype); +static int format_mdvd(SCSI *usalp, cdr_t *dp, int formattype); +static int send_opc_mmc(SCSI *usalp, caddr_t, int cnt, int doopc); +static int opt1_mmc(SCSI *usalp, cdr_t *dp); +static int opt1_mdvd(SCSI *usalp, cdr_t *dp); +static int opt2_mmc(SCSI *usalp, cdr_t *dp); +static int scsi_sony_write(SCSI *usalp, caddr_t bp, long sectaddr, long size, + int blocks, BOOL islast); +static int gen_cue_mmc(track_t *trackp, void *vcuep, BOOL needgap); +static void fillcue(struct mmc_cue *cp, int ca, int tno, int idx, int dataform, + int scms, msf_t *mp); +static int send_cue_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int stats_mmc(SCSI *usalp, cdr_t *dp); +static BOOL mmc_isplextor(SCSI *usalp); +static BOOL mmc_isyamaha(SCSI *usalp); +static void do_varirec_plextor(SCSI *usalp); +static int do_gigarec_plextor(SCSI *usalp); +static int drivemode_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode, + void *modeval); +static int drivemode2_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode, + void *modeval); +static int check_varirec_plextor(SCSI *usalp); +static int check_gigarec_plextor(SCSI *usalp); +static int varirec_plextor(SCSI *usalp, BOOL on, int val); +static int gigarec_plextor(SCSI *usalp, int val); +static Int32_t gigarec_mult(int code, Int32_t val); +static int check_ss_hide_plextor(SCSI *usalp); +static int check_speed_rd_plextor(SCSI *usalp); +static int check_powerrec_plextor(SCSI *usalp); +static int ss_hide_plextor(SCSI *usalp, BOOL do_ss, BOOL do_hide); +static int speed_rd_plextor(SCSI *usalp, BOOL do_speedrd); +static int powerrec_plextor(SCSI *usalp, BOOL do_powerrec); +static int get_speeds_plextor(SCSI *usalp, int *selp, int *maxp, int *lastp); +static int bpc_plextor(SCSI *usalp, int mode, int *bpp); +static int set_audiomaster_yamaha(SCSI *usalp, cdr_t *dp, BOOL keep_mode); + +struct ricoh_mode_page_30 * get_justlink_ricoh(SCSI *usalp, Uchar *mode); +static int force_speed_yamaha(SCSI *usalp, int readspeed, int writespeed); +static BOOL get_tattoo_yamaha(SCSI *usalp, BOOL print, Int32_t *irp, + Int32_t *orp); +static int do_tattoo_yamaha(SCSI *usalp, FILE *f); +static int yamaha_write_buffer(SCSI *usalp, int mode, int bufferid, long offset, + long parlen, void *buffer, long buflen); +static int dvd_dual_layer_split(SCSI *usalp, cdr_t *dp, long tsize); + +extern int reserve_track(SCSI *usalp, Ulong size); /* FIXME */ +extern int scsi_format(SCSI *usalp, caddr_t addr, int size, BOOL background); /* FIXME */ + +#ifdef __needed__ +static int +mmc_load(SCSI *usalp, cdr_t *dp) +{ + return (scsi_load_unload(usalp, 1)); +} + +static int +mmc_unload(SCSI *usalp, cdr_t *dp) +{ + return (scsi_load_unload(usalp, 0)); +} +#endif + +/* + * MMC CD-writer + */ +cdr_t cdr_mmc = { + 0, 0, + CDR_SWABAUDIO, + CDR_CDRW_ALL, + 372, 372, + "mmc_cdr", + "generic SCSI-3/mmc CD-R/CD-RW driver", + 0, + (dstat_t *)0, + identify_mmc, + attach_mmc, + init_mmc, + getdisktype_mmc, + scsi_load, + scsi_unload, + read_buff_cap, + cmd_dummy, /* check_recovery */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_mmc, + select_secsize, + next_wr_addr_mmc, + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + scsi_cdr_write, + gen_cue_mmc, + send_cue_mmc, + write_leadin_mmc, + open_track_mmc, + close_track_mmc, + open_session_mmc, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + fixate_mmc, + stats_mmc, + blank_mmc, + format_dummy, + send_opc_mmc, + opt1_mmc, + opt2_mmc, +}; + +cdr_t cdr_mdvd = { + 0, 0, + CDR_SWABAUDIO, + CDR_CDRW_ALL, + 370,370, + "mmc_mdvd", + "generic SCSI-3/mmc DVD-R(W) driver", + 0, + (dstat_t *)0, + identify_mmc, + attach_mdvd, + init_mmc, + getdisktype_mdvd, + scsi_load, + scsi_unload, + read_buff_cap, + cmd_dummy, /* check_recovery */ + (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */ + speed_select_mdvd, + select_secsize, + next_wr_addr_mdvd, + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + scsi_cdr_write, + (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */ + (int(*)__PR((SCSI *usalp, cdr_t *, track_t *)))cmd_dummy, /* send_cue */ + write_leadin_mmc, + open_track_mdvd, + close_track_mdvd, + open_session_mdvd, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + fixate_mdvd, + stats_mmc, + blank_mmc, + format_mdvd, + send_opc_mmc, + opt1_mdvd, + opt2_mmc, + dvd_dual_layer_split, +}; + +/* + * Sony MMC CD-writer + */ +cdr_t cdr_mmc_sony = { + 0, 0, + CDR_SWABAUDIO, + CDR_CDRW_ALL, + 372, 372, + "mmc_cdr_sony", + "generic SCSI-3/mmc CD-R/CD-RW driver (Sony 928 variant)", + 0, + (dstat_t *)0, + identify_mmc, + attach_mmc, + init_mmc, + getdisktype_mmc, + scsi_load, + scsi_unload, + read_buff_cap, + cmd_dummy, /* check_recovery */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_mmc, + select_secsize, + next_wr_addr_mmc, + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + scsi_sony_write, + gen_cue_mmc, + send_cue_mmc, + write_leadin_mmc, + open_track_mmc, + close_track_mmc, + open_session_mmc, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + fixate_mmc, + cmd_dummy, /* stats */ + blank_mmc, + format_dummy, + send_opc_mmc, + opt1_mmc, + opt2_mmc, +}; + +/* + * SCSI-3/mmc conformant CD-ROM drive + */ +cdr_t cdr_cd = { + 0, 0, + CDR_ISREADER|CDR_SWABAUDIO, + CDR_CDRW_NONE, + 372, 372, + "mmc_cd", + "generic SCSI-3/mmc CD-ROM driver", + 0, + (dstat_t *)0, + identify_mmc, + attach_mmc, + cmd_dummy, + drive_getdisktype, + scsi_load, + scsi_unload, + read_buff_cap, + cmd_dummy, /* check_recovery */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_mmc, + select_secsize, + (int(*)(SCSI *usalp, track_t *, long *))cmd_ill, /* next_wr_addr */ + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + scsi_cdr_write, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_mmc, + close_track_mmc, + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* fixation */ + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +/* + * Old pre SCSI-3/mmc CD drive + */ +cdr_t cdr_oldcd = { + 0, 0, + CDR_ISREADER, + CDR_CDRW_NONE, + 372, 372, + "scsi2_cd", + "generic SCSI-2 CD-ROM driver", + 0, + (dstat_t *)0, + identify_mmc, + drive_attach, + cmd_dummy, + drive_getdisktype, + scsi_load, + scsi_unload, + buf_dummy, + cmd_dummy, /* check_recovery */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_mmc, + select_secsize, + (int(*)(SCSI *usal, track_t *, long *))cmd_ill, /* next_wr_addr */ + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + scsi_cdr_write, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_mmc, + close_track_mmc, + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* fixation */ + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +/* + * SCSI-3/mmc conformant CD or DVD writer + * Checks the current medium and then returns either cdr_mmc or cdr_dvd + */ +cdr_t cdr_cd_dvd = { + 0, 0, + CDR_SWABAUDIO, + CDR_CDRW_ALL, + 372, 372, + "mmc_cd_dvd", + "generic SCSI-3/mmc CD/DVD driver (checks media)", + 0, + (dstat_t *)0, + identify_mmc, + attach_mmc, + cmd_dummy, + drive_getdisktype, + scsi_load, + scsi_unload, + read_buff_cap, + cmd_dummy, /* check_recovery */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_mmc, + select_secsize, + (int(*)(SCSI *usalp, track_t *, long *))cmd_ill, /* next_wr_addr */ + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + scsi_cdr_write, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_mmc, + close_track_mmc, + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* fixation */ + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +void +mmc_opthelp(cdr_t *dp, int excode) +{ + BOOL haveopts = FALSE; + + fprintf(stderr, "Driver options:\n"); + if (dp->cdr_flags & CDR_BURNFREE) { + fprintf(stderr, "burnfree Prepare writer to use BURN-Free technology\n"); + fprintf(stderr, "noburnfree Disable using BURN-Free technology\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_VARIREC) { + fprintf(stderr, "varirec=val Set VariRec Laserpower to -2, -1, 0, 1, 2\n"); + fprintf(stderr, " Only works for audio and if speed is set to 4\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_GIGAREC) { + fprintf(stderr, "gigarec=val Set GigaRec capacity ratio to 0.6, 0.7, 0.8, 1.0, 1.2, 1.3, 1.4\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_AUDIOMASTER) { + fprintf(stderr, "audiomaster Turn Audio Master feature on (SAO CD-R Audio/Data only)\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_FORCESPEED) { + fprintf(stderr, "forcespeed Tell the drive to force speed even for low quality media\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_SPEEDREAD) { + fprintf(stderr, "speedread Tell the drive to read as fast as possible\n"); + fprintf(stderr, "nospeedread Disable to read as fast as possible\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_DISKTATTOO) { + fprintf(stderr, "tattooinfo Print image size info for DiskT@2 feature\n"); + fprintf(stderr, "tattoofile=name Use 'name' as DiskT@2 image file\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_SINGLESESS) { + fprintf(stderr, "singlesession Tell the drive to behave as single session only drive\n"); + fprintf(stderr, "nosinglesession Disable single session only mode\n"); + haveopts = TRUE; + } + if (dp->cdr_flags & CDR_HIDE_CDR) { + fprintf(stderr, "hidecdr Tell the drive to hide CD-R media\n"); + fprintf(stderr, "nohidecdr Disable hiding CD-R media\n"); + haveopts = TRUE; + } + if (!haveopts) { + fprintf(stderr, "None supported for this drive.\n"); + } + exit(excode); +} + +char * +hasdrvopt(char *optstr, char *optname) +{ + char *ep; + char *np; + char *ret = NULL; + int optnamelen; + int optlen; + BOOL not = FALSE; + + if (optstr == NULL) + return (ret); + + optnamelen = strlen(optname); + + while (*optstr) { + not = FALSE; /* Reset before every token */ + if ((ep = strchr(optstr, ',')) != NULL) { + optlen = ep - optstr; + np = &ep[1]; + } else { + optlen = strlen(optstr); + np = &optstr[optlen]; + } + if ((ep = strchr(optstr, '=')) != NULL) { + if (ep < np) + optlen = ep - optstr; + } + if (optstr[0] == '!') { + optstr++; + optlen--; + not = TRUE; + } + if (strncmp(optstr, "no", 2) == 0) { + optstr += 2; + optlen -= 2; + not = TRUE; + } + if (strncmp(optstr, optname, optlen) == 0) { + ret = &optstr[optlen]; + break; + } + optstr = np; + } + if (ret != NULL) { + if (*ret == ',' || *ret == '\0') { + if (not) + return ("0"); + return ("1"); + } + if (*ret == '=') { + if (not) + return (NULL); + return (++ret); + } + } + return (ret); +} + +static cdr_t * +identify_mmc(SCSI *usalp, cdr_t *dp, struct scsi_inquiry *ip) +{ + BOOL cdrr = FALSE; /* Read CD-R */ + BOOL cdwr = FALSE; /* Write CD-R */ + BOOL cdrrw = FALSE; /* Read CD-RW */ + BOOL cdwrw = FALSE; /* Write CD-RW */ + BOOL dvdwr = FALSE; /* DVD writer */ + BOOL is_dvd = FALSE; /* use DVD driver*/ + Uchar mode[0x100]; + struct cd_mode_page_2A *mp; + int profile; + + if (ip->type != INQ_WORM && ip->type != INQ_ROMD) + return ((cdr_t *)0); + + allow_atapi(usalp, TRUE); /* Try to switch to 10 byte mode cmds */ + + usalp->silent++; + mp = mmc_cap(usalp, mode); /* Get MMC capabilities */ + usalp->silent--; + if (mp == NULL) + return (&cdr_oldcd); /* Pre SCSI-3/mmc drive */ + + /* + * 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. + * + * XXX xxx_identify() should not have any side_effects ?? + */ + if (ip->data_format < 2) + ip->data_format = 2; + + /* + * First handle exceptions.... + */ + if (strncmp(ip->vendor_info, "SONY", 4) == 0 && + strncmp(ip->prod_ident, "CD-R CDU928E", 14) == 0) { + return (&cdr_mmc_sony); + } + + /* + * Now try to do it the MMC-3 way.... + */ + profile = get_curprofile(usalp); + if (xdebug) + printf("Current profile: 0x%04X\n", profile); + if (profile == 0) { + if (xdebug) + print_profiles(usalp); + /* + * If the current profile is 0x0000, then the + * drive does not know about the media. First + * close the tray and then try to issue the + * get_curprofile() command again. + */ + usalp->silent++; + load_media(usalp, dp, FALSE); + usalp->silent--; + profile = get_curprofile(usalp); + scsi_prevent_removal(usalp, 0); + if (xdebug) + printf("Current profile: 0x%04X\n", profile); + } + if (profile >= 0) { + if (lverbose) + print_profiles(usalp); + if (profile == 0 || (profile >= 0x10 && profile <= 0x15) || profile > 0x19) { + /* + * 10h DVD-ROM + * 11h DVD-R + * 12h DVD-RAM + * 13h DVD-RW (Restricted overwrite) + * 14h DVD-RW (Sequential recording) + * 1Ah DVD+RW + * 1Bh DVD+R + * 2Bh DVD+R DL + * + */ + if (profile == 0x11 || profile == 0x13 || profile == 0x14 || profile == 0x1A || profile == 0x1B || profile == 0x2B) { + is_dvd = TRUE; + dp = &cdr_mdvd; + } else { + is_dvd = FALSE; + dp = &cdr_cd; + + if (profile == 0) { /* No Medium */ + BOOL is_cdr = FALSE; + + /* + * Check for CD-writer + */ + get_wproflist(usalp, &is_cdr, NULL, + NULL, NULL); + if (is_cdr) + return (&cdr_mmc); + /* + * Other MMC-3 drive without media + */ + return (dp); + } if (profile == 0x12) { /* DVD-RAM */ + errmsgno(EX_BAD, + "Found unsupported DVD-RAM media.\n"); + return (dp); + } + } + } + } else { + if (xdebug) + printf("Drive is pre MMC-3\n"); + } + + mmc_getval(mp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, &dvdwr); + + if (!cdwr && !cdwrw) { /* SCSI-3/mmc CD drive */ + /* + * If the drive does not support to write CD's, we select the + * CD-ROM driver here. If we have DVD-R/DVD-RW support compiled + * in, we may later decide to switch to the DVD driver. + */ + dp = &cdr_cd; + } else { + /* + * We need to set the driver to cdr_mmc because we may come + * here with driver set to cdr_cd_dvd which is not a driver + * that may be used for actual CD/DVD writing. + */ + dp = &cdr_mmc; + } + +/*#define DVD_DEBUG*/ +#ifdef DVD_DEBUG + if (1) { /* Always check for DVD media in debug mode */ +#else + if ((cdwr || cdwrw) && dvdwr) { +#endif + char xb[32]; + +#ifndef DVD_DEBUG + usalp->silent++; +#else + fprintf(stderr, "identify_dvd: checking for DVD media\n"); +#endif + if (read_dvd_structure(usalp, (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 { + if (usal_sense_key(usalp) == SC_NOT_READY) { + /* + * If the SCSI sense key is NOT READY, then the + * drive does not know about the media. First + * close the tray and then try to issue the + * read_dvd_structure() command again. + */ + load_media(usalp, dp, FALSE); + if (read_dvd_structure(usalp, (caddr_t)xb, 32, 0, 0, 0) >= 0) { + is_dvd = TRUE; + } + scsi_prevent_removal(usalp, 0); + } + } +#ifndef DVD_DEBUG + usalp->silent--; +#else + fprintf(stderr, "identify_dvd: is_dvd: %d\n", is_dvd); +#endif + } + if (is_dvd) { + if(lverbose>2) + fprintf(stderr, "Found DVD media: using cdr_mdvd.\n"); + dp = &cdr_mdvd; + } + dp->profile = profile; + dp->is_dvd = is_dvd; + return (dp); +} + +static int +attach_mmc(SCSI *usalp, cdr_t *dp) +{ + int ret; + Uchar mode[0x100]; + struct cd_mode_page_2A *mp; + struct ricoh_mode_page_30 *rp = NULL; + + allow_atapi(usalp, TRUE); /* Try to switch to 10 byte mode cmds */ + + usalp->silent++; + mp = mmc_cap(usalp, NULL); /* Get MMC capabilities in allocated mp */ + usalp->silent--; + if (mp == NULL) + return (-1); /* Pre SCSI-3/mmc drive */ + + dp->cdr_cdcap = mp; /* Store MMC cap pointer */ + + dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/176; + if (dp->cdr_dstat->ds_dr_max_rspeed == 0) + dp->cdr_dstat->ds_dr_max_rspeed = 372; + dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/176; + if (dp->cdr_dstat->ds_dr_cur_rspeed == 0) + dp->cdr_dstat->ds_dr_cur_rspeed = 372; + + dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/176; + if (mp->p_len >= 28) + dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/176; + else + dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/176; + + if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed) + dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed; + + if (dp->cdr_speeddef > dp->cdr_speedmax) + dp->cdr_speeddef = dp->cdr_speedmax; + + rp = get_justlink_ricoh(usalp, mode); + + if (mp->p_len >= 28) + dp->cdr_flags |= CDR_MMC3; + if (mp->p_len >= 24) + dp->cdr_flags |= CDR_MMC2; + dp->cdr_flags |= CDR_MMC; + + if (mp->loading_type == LT_TRAY) + dp->cdr_flags |= CDR_TRAYLOAD; + else if (mp->loading_type == LT_CADDY) + dp->cdr_flags |= CDR_CADDYLOAD; + + if (mp->BUF != 0) { + dp->cdr_flags |= CDR_BURNFREE; + } else if (rp) { + if ((dp->cdr_cmdflags & F_DUMMY) && rp->TWBFS && rp->BUEFS) + dp->cdr_flags |= CDR_BURNFREE; + + if (rp->BUEFS) + dp->cdr_flags |= CDR_BURNFREE; + } + + if (mmc_isplextor(usalp)) { + if (check_varirec_plextor(usalp) >= 0) + dp->cdr_flags |= CDR_VARIREC; + + if (check_gigarec_plextor(usalp) >= 0) + dp->cdr_flags |= CDR_GIGAREC; + + if (check_ss_hide_plextor(usalp) >= 0) + dp->cdr_flags |= CDR_SINGLESESS|CDR_HIDE_CDR; + + if (check_powerrec_plextor(usalp) >= 0) + dp->cdr_flags |= CDR_FORCESPEED; + + if (check_speed_rd_plextor(usalp) >= 0) + dp->cdr_flags |= CDR_SPEEDREAD; + } + if (mmc_isyamaha(usalp)) { + if (set_audiomaster_yamaha(usalp, dp, FALSE) >= 0) + dp->cdr_flags |= CDR_AUDIOMASTER; + + /* + * Starting with CRW 2200 / CRW 3200 + */ + if ((mp->p_len+2) >= (unsigned)28) + dp->cdr_flags |= CDR_FORCESPEED; + + if (get_tattoo_yamaha(usalp, FALSE, 0, 0)) + dp->cdr_flags |= CDR_DISKTATTOO; + } + + if (rp && rp->AWSCS) + dp->cdr_flags |= CDR_FORCESPEED; + +#ifdef FUTURE_ROTCTL + if (mp->p_len >= 28) { + int val; + + val = dp->cdr_dstat->ds_dr_cur_wspeed; + if (val == 0) + val = 372; + + usalp->verbose++; + if (scsi_set_speed(usalp, -1, val, ROTCTL_CAV) < 0) { + fprintf(stderr, "XXX\n"); + } + usalp->verbose--; + } +#endif + + check_writemodes_mmc(usalp, dp); + + /* Enable Burnfree by default, it can be disabled later */ + if ((dp->cdr_flags & CDR_BURNFREE) != 0) + dp->cdr_dstat->ds_cdrflags |= RF_BURNFREE; + + if (driveropts != NULL) { + char *p; + + if (strcmp(driveropts, "help") == 0) { + mmc_opthelp(dp, 0); + } + + p = hasdrvopt(driveropts, "varirec"); + if (p != NULL && (dp->cdr_flags & CDR_VARIREC) != 0) { + dp->cdr_dstat->ds_cdrflags |= RF_VARIREC; + } + + p = hasdrvopt(driveropts, "gigarec"); + if (p != NULL && (dp->cdr_flags & CDR_GIGAREC) != 0) { + dp->cdr_dstat->ds_cdrflags |= RF_GIGAREC; + } + + p = hasdrvopt(driveropts, "audiomaster"); + if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_AUDIOMASTER) != 0) { + dp->cdr_dstat->ds_cdrflags |= RF_AUDIOMASTER; + dp->cdr_dstat->ds_cdrflags &= ~RF_BURNFREE; + } + p = hasdrvopt(driveropts, "forcespeed"); + if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_FORCESPEED) != 0) { + dp->cdr_dstat->ds_cdrflags |= RF_FORCESPEED; + } + p = hasdrvopt(driveropts, "tattooinfo"); + if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_DISKTATTOO) != 0) { + get_tattoo_yamaha(usalp, TRUE, 0, 0); + } + p = hasdrvopt(driveropts, "tattoofile"); + if (p != NULL && (dp->cdr_flags & CDR_DISKTATTOO) != 0) { + FILE *f; + + if ((f = fileopen(p, "rb")) == NULL) + comerr("Cannot open '%s'.\n", p); + + if (do_tattoo_yamaha(usalp, f) < 0) + errmsgno(EX_BAD, "Cannot do DiskT@2.\n"); + fclose(f); + } + p = hasdrvopt(driveropts, "singlesession"); + if (p != NULL && (dp->cdr_flags & CDR_SINGLESESS) != 0) { + if (*p == '1') { + dp->cdr_dstat->ds_cdrflags |= RF_SINGLESESS; + } else if (*p == '0') { + dp->cdr_dstat->ds_cdrflags &= ~RF_SINGLESESS; + } + } + p = hasdrvopt(driveropts, "hidecdr"); + if (p != NULL && (dp->cdr_flags & CDR_HIDE_CDR) != 0) { + if (*p == '1') { + dp->cdr_dstat->ds_cdrflags |= RF_HIDE_CDR; + } else if (*p == '0') { + dp->cdr_dstat->ds_cdrflags &= ~RF_HIDE_CDR; + } + } + p = hasdrvopt(driveropts, "speedread"); + if (p != NULL && (dp->cdr_flags & CDR_SPEEDREAD) != 0) { + if (*p == '1') { + dp->cdr_dstat->ds_cdrflags |= RF_SPEEDREAD; + } else if (*p == '0') { + dp->cdr_dstat->ds_cdrflags &= ~RF_SPEEDREAD; + } + } + } + + if ((ret = get_supported_cdrw_media_types(usalp)) < 0) { + dp->cdr_cdrw_support = CDR_CDRW_ALL; + return (0); + } + dp->cdr_cdrw_support = ret; + if (lverbose > 1) + printf("Supported CD-RW media types: %02X\n", dp->cdr_cdrw_support); + + return (0); +} + +static int +attach_mdvd(SCSI *usalp, cdr_t *dp) +{ + struct cd_mode_page_2A *mp; + + + allow_atapi(usalp, TRUE);/* Try to switch to 10 byte mode cmds */ + + usalp->silent++; + mp = mmc_cap(usalp, NULL);/* Get MMC capabilities in allocated mp */ + usalp->silent--; + if (mp == NULL) + return (-1); /* Pre SCSI-3/mmc drive */ + + dp->cdr_cdcap = mp; /* Store MMC cap pointer */ + + dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/1385; + if (dp->cdr_dstat->ds_dr_max_rspeed == 0) + dp->cdr_dstat->ds_dr_max_rspeed = 1385; + dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/1385; + if (dp->cdr_dstat->ds_dr_cur_rspeed == 0) + dp->cdr_dstat->ds_dr_cur_rspeed = 1385; + + dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/1385; + if (mp->p_len >= 28) + dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/1385; + else + dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/1385; + + if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed) + dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed; + + if (dp->cdr_speeddef > dp->cdr_speedmax) + dp->cdr_speeddef = dp->cdr_speedmax; + + + if (mp->loading_type == LT_TRAY) + dp->cdr_flags |= CDR_TRAYLOAD; + else if (mp->loading_type == LT_CADDY) + dp->cdr_flags |= CDR_CADDYLOAD; + + if (mp->BUF != 0) + dp->cdr_flags |= CDR_BURNFREE; + + check_writemodes_mdvd(usalp, dp); + + if (driveropts != NULL) { + if (strcmp(driveropts, "help") == 0) { + mmc_opthelp(dp, 0); + } + } + + return (0); +} + +int +check_writemodes_mmc(SCSI *usalp, cdr_t *dp) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + if (xdebug) + printf("Checking possible write modes: "); + + /* + * Reset mp->test_write (-dummy) here. + */ + deflt_writemodes_mmc(usalp, TRUE); + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + usalp->silent++; + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + usalp->silent--; + return (-1); + } + if (len == 0) { + usalp->silent--; + return (-1); + } + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + + /* + * mp->test_write has already been reset in deflt_writemodes_mmc() + * Do not reset mp->test_write (-dummy) here. It should be set + * only at one place and only one time. + */ + + mp->write_type = WT_TAO; + mp->track_mode = TM_DATA; + mp->dbtype = DB_ROM_MODE1; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_TAO; + if (xdebug) + printf("TAO "); + } else + dp->cdr_flags &= ~CDR_TAO; + + mp->write_type = WT_PACKET; + mp->track_mode |= TM_INCREMENTAL; +/* mp->fp = (trackp->pktsize > 0) ? 1 : 0;*/ +/* i_to_4_byte(mp->packet_size, trackp->pktsize);*/ + mp->fp = 0; + i_to_4_byte(mp->packet_size, 0); + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_PACKET; + if (xdebug) + printf("PACKET "); + } else + dp->cdr_flags &= ~CDR_PACKET; + mp->fp = 0; + i_to_4_byte(mp->packet_size, 0); + mp->track_mode = TM_DATA; + mp->write_type = WT_SAO; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_SAO; + if (xdebug) + printf("SAO "); + } else + dp->cdr_flags &= ~CDR_SAO; + + if (dp->cdr_flags & CDR_SAO) { + mp->dbtype = DB_RAW_PQ; + +#ifdef __needed__ + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_SRAW16; + if (xdebug) + printf("SAO/R16 "); + } +#endif + + mp->dbtype = DB_RAW_PW; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_SRAW96P; + if (xdebug) + printf("SAO/R96P "); + } + + mp->dbtype = DB_RAW_PW_R; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_SRAW96R; + if (xdebug) + printf("SAO/R96R "); + } + } + + mp->write_type = WT_RAW; + mp->dbtype = DB_RAW_PQ; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_RAW; + dp->cdr_flags |= CDR_RAW16; + if (xdebug) + printf("RAW/R16 "); + } + + mp->dbtype = DB_RAW_PW; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_RAW; + dp->cdr_flags |= CDR_RAW96P; + if (xdebug) + printf("RAW/R96P "); + } + + mp->dbtype = DB_RAW_PW_R; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_RAW; + dp->cdr_flags |= CDR_RAW96R; + if (xdebug) + printf("RAW/R96R "); + } + + if (xdebug) + printf("\n"); + + /* + * Reset mp->test_write (-dummy) here. + */ + deflt_writemodes_mmc(usalp, TRUE); + usalp->silent--; + + return (0); +} + +int +check_writemodes_mdvd(SCSI *usalp, cdr_t *dp) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + if (xdebug) + printf("Checking possible write modes: "); + + deflt_writemodes_mdvd(usalp, FALSE); + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + + usalp->silent++; + if (!get_mode_params(usalp, 0x05, "DVD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + usalp->silent--; + return (-1); + } + if (len == 0) { + usalp->silent--; + return (-1); + } + + mp = (struct cd_mode_page_05 *) + (mode + sizeof(struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + mp->test_write = 0; + + /*We only check for PACKET and SAO since these are the only supported modes for DVD */ + /*XXX these checks are irrelevant because they are not medium sensitive. ie the device returns + error only when it does not support a given mode for ALL mediums. It should check using + GET CONFIGURATION command.*/ + + mp->write_type = WT_PACKET; + mp->fp = 0; + i_to_4_byte(mp->packet_size, 0); + + if (set_mode_params(usalp, "DVD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_PACKET; + if (xdebug) + printf("PACKET "); + } else + dp->cdr_flags &= ~CDR_PACKET; + mp->fp = 0; + i_to_4_byte(mp->packet_size, 0); + mp->track_mode = TM_DATA; + + + mp->write_type = WT_SAO; + + if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + dp->cdr_flags |= CDR_SAO; + if (xdebug) + printf("SAO "); + } else + dp->cdr_flags &= ~CDR_SAO; + + + if (xdebug) + printf("\n"); + + deflt_writemodes_mdvd(usalp, TRUE); + usalp->silent--; + return (0); +} + +static int +deflt_writemodes_mmc(SCSI *usalp, BOOL reset_dummy) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + usalp->silent++; + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + usalp->silent--; + return (-1); + } + if (len == 0) { + usalp->silent--; + return (-1); + } + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); + fprintf(stderr, "Audio pause len: %d\n", a_to_2_byte(mp->audio_pause_len)); +#endif + + /* + * This is the only place where we reset mp->test_write (-dummy) + */ + if (reset_dummy) + mp->test_write = 0; + + /* + * Set default values: + * Write type = 01 (track at once) + * Track mode = 04 (CD-ROM) + * Data block type = 08 (CD-ROM) + * Session format = 00 (CD-ROM) + * + * XXX Note: the same code appears in check_writemodes_mmc() and + * XXX in speed_select_mmc(). + */ + mp->write_type = WT_TAO; + mp->track_mode = TM_DATA; + mp->dbtype = DB_ROM_MODE1; + mp->session_format = SES_DA_ROM; /* Matsushita has illegal def. value */ + + i_to_2_byte(mp->audio_pause_len, 150); /* LG has illegal def. value */ + +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + + mp->write_type = WT_SAO; + mp->LS_V = 0; + mp->copy = 0; + mp->fp = 0; + mp->multi_session = MS_NONE; + mp->host_appl_code = 0; + + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) { + usalp->silent--; + return (-1); + } + } + usalp->silent--; + return (0); +} + +static int +deflt_writemodes_mdvd(SCSI *usalp, BOOL reset_dummy) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + + usalp->silent++; + if (!get_mode_params(usalp, 0x05, "DVD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + usalp->silent--; + return (-1); + } + if (len == 0) { + usalp->silent--; + return (-1); + } + + mp = (struct cd_mode_page_05 *) + (mode + sizeof(struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + mp->test_write = 0; + /* + * This is the only place where we reset mp->test_write (-dummy) for DVD + */ + if (reset_dummy) + mp->test_write = 0; + + /* + * Set default values: + * Write type = 02 (session at once) + * + * XXX Note: the same code appears in check_writemodes_mmc() and + * XXX in speed_select_mmc(). + */ + mp->write_type = WT_SAO; + mp->track_mode = TM_DATA; + mp->dbtype = DB_ROM_MODE1; + mp->session_format = SES_DA_ROM; + + + if (set_mode_params(usalp, "DVD write parameter", mode, len, 0, -1) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + return (0); +} + +#ifdef PRINT_ATIP +static void print_di(struct disk_info *dip); +static void atip_printspeed(char *fmt, int speedindex, char speedtab[]); +static void print_atip(SCSI *usalp, struct atipinfo *atp); +#endif /* PRINT_ATIP */ + +static int +get_diskinfo(SCSI *usalp, struct disk_info *dip) +{ + int len; + int ret; + + fillbytes((caddr_t)dip, sizeof (*dip), '\0'); + + /* + * Used to be 2 instead of 4 (now). But some Y2k ATAPI drives as used + * by IOMEGA create a DMA overrun if we try to transfer only 2 bytes. + */ +/* if (read_disk_info(usalp, (caddr_t)dip, 2) < 0)*/ + if (read_disk_info(usalp, (caddr_t)dip, 4) < 0) + return (-1); + len = a_to_u_2_byte(dip->data_len); + len += 2; + ret = read_disk_info(usalp, (caddr_t)dip, len); + +#ifdef DEBUG + usal_prbytes("Disk info:", (Uchar *)dip, + len-usal_getresid(usalp)); +#endif + return (ret); +} + +static void +di_to_dstat(struct disk_info *dip, dstat_t *dsp) +{ + dsp->ds_diskid = a_to_u_4_byte(dip->disk_id); + if (dip->did_v) + dsp->ds_flags |= DSF_DID_V; + dsp->ds_disktype = dip->disk_type; + dsp->ds_diskstat = dip->disk_status; + dsp->ds_sessstat = dip->sess_status; + if (dip->erasable) + dsp->ds_flags |= DSF_ERA; + + dsp->ds_trfirst = dip->first_track; + dsp->ds_trlast = dip->last_track_ls; + dsp->ds_trfirst_ls = dip->first_track_ls; + + dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1], + dip->last_lead_out[2], + dip->last_lead_out[3], TRUE); + /* + * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk + */ + if (dsp->ds_maxblocks == 1166730) + dsp->ds_maxblocks = -1L; + + dsp->ds_first_leadin = msf_to_lba(dip->last_lead_in[1], + dip->last_lead_in[2], + dip->last_lead_in[3], FALSE); + if (dsp->ds_first_leadin > 0) + dsp->ds_first_leadin = 0; + + if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0) + dsp->ds_last_leadout = dsp->ds_maxblocks; + dsp->ds_trfirst=dip->first_track; + dsp->ds_trlast=dip->last_track_ls; + dsp->ds_trfirst_ls=dip->first_track_ls; +} + +static int +get_atip(SCSI *usalp, struct atipinfo *atp) +{ + int len; + int ret; + + fillbytes((caddr_t)atp, sizeof (*atp), '\0'); + + /* + * Used to be 2 instead of sizeof (struct tocheader), but all + * other places in the code use sizeof (struct tocheader) too and + * some Y2k ATAPI drives as used by IOMEGA create a DMA overrun if we + * try to transfer only 2 bytes. + */ + if (read_toc(usalp, (caddr_t)atp, 0, sizeof (struct tocheader), 0, FMT_ATIP) < 0) + return (-1); + len = a_to_u_2_byte(atp->hd.len); + len += 2; + ret = read_toc(usalp, (caddr_t)atp, 0, len, 0, FMT_ATIP); + +#ifdef DEBUG + usal_prbytes("ATIP info:", (Uchar *)atp, + len-usal_getresid(usalp)); +#endif + /* + * Yamaha sometimes returns zeroed ATIP info for disks without ATIP + */ + if (atp->desc.lead_in[1] == 0 && + atp->desc.lead_in[2] == 0 && + atp->desc.lead_in[3] == 0 && + atp->desc.lead_out[1] == 0 && + atp->desc.lead_out[2] == 0 && + atp->desc.lead_out[3] == 0) + return (-1); + + if (atp->desc.lead_in[1] >= 0x90 && debug) { + /* + * Only makes sense with buggy Ricoh firmware. + */ + errmsgno(EX_BAD, "Converting ATIP from BCD\n"); + atp->desc.lead_in[1] = from_bcd(atp->desc.lead_in[1]); + atp->desc.lead_in[2] = from_bcd(atp->desc.lead_in[2]); + atp->desc.lead_in[3] = from_bcd(atp->desc.lead_in[3]); + + atp->desc.lead_out[1] = from_bcd(atp->desc.lead_out[1]); + atp->desc.lead_out[2] = from_bcd(atp->desc.lead_out[2]); + atp->desc.lead_out[3] = from_bcd(atp->desc.lead_out[3]); + } + + return (ret); +} + +#ifdef PRINT_ATIP + +static int +get_pma(SCSI *usalp) +{ + int len; + int ret; + char atp[1024]; + + fillbytes((caddr_t)atp, sizeof (*atp), '\0'); + + /* + * Used to be 2 instead of sizeof (struct tocheader), but all + * other places in the code use sizeof (struct tocheader) too and + * some Y2k ATAPI drives as used by IOMEGA create a DMA overrun if we + * try to transfer only 2 bytes. + */ +/* if (read_toc(usalp, (caddr_t)atp, 0, 2, 1, FMT_PMA) < 0)*/ +/* if (read_toc(usalp, (caddr_t)atp, 0, 2, 0, FMT_PMA) < 0)*/ + if (read_toc(usalp, (caddr_t)atp, 0, sizeof (struct tocheader), 0, FMT_PMA) < 0) + return (-1); +/* len = a_to_u_2_byte(atp->hd.len);*/ + len = a_to_u_2_byte(atp); + len += 2; +/* ret = read_toc(usalp, (caddr_t)atp, 0, len, 1, FMT_PMA);*/ + ret = read_toc(usalp, (caddr_t)atp, 0, len, 0, FMT_PMA); + +#ifdef DEBUG + usal_prbytes("PMA:", (Uchar *)atp, + len-usal_getresid(usalp)); +#endif + ret = read_toc(usalp, (caddr_t)atp, 0, len, 1, FMT_PMA); + +#ifdef DEBUG + usal_prbytes("PMA:", (Uchar *)atp, + len-usal_getresid(usalp)); +#endif + return (ret); +} + +#endif /* PRINT_ATIP */ + +static int +init_mmc(SCSI *usalp, cdr_t *dp) +{ + return (speed_select_mmc(usalp, dp, NULL)); +} + +static int +getdisktype_mdvd(SCSI *usalp, cdr_t *dp) +{ + int ret = 0; + dstat_t *dsp = dp->cdr_dstat; + + struct track_info track_info; + if(lverbose) + printf("HINT: use dvd+rw-mediainfo from dvd+rw-tools for information extraction.\n"); + /* if(getdisktype_mmc(usalp, dp)<0) + return -1; + */ + + /* read rzone info to get the space left on disk */ + /*ds_trlast is the last rzone on disk, can be invisible */ + if(read_rzone_info(usalp, (caddr_t)&track_info, sizeof(track_info))>=0) + dsp->ds_maxblocks=a_to_u_4_byte(track_info.free_blocks)+a_to_4_byte(track_info.next_writable_addr); + + dsp->ds_disktype&= ~DT_CD; + dsp->ds_disktype|= DT_DVD; + + return (ret); + +} + +static int +getdisktype_mmc(SCSI *usalp, cdr_t *dp) +{ +extern char *buf; + dstat_t *dsp = dp->cdr_dstat; + struct disk_info *dip; + Uchar mode[0x100]; + msf_t msf; + BOOL did_atip = FALSE; + BOOL did_dummy = FALSE; + int rplus; + + msf.msf_min = msf.msf_sec = msf.msf_frame = 0; + + /* + * It seems that there are drives that do not support to + * read ATIP (e.g. HP 7100) + * Also if a NON CD-R media is inserted, this will never work. + * For this reason, make a failure non-fatal. + */ + usalp->silent++; + if (get_atip(usalp, (struct atipinfo *)mode) >= 0) { + struct atipinfo *atp = (struct atipinfo *)mode; + + msf.msf_min = mode[8]; + msf.msf_sec = mode[9]; + msf.msf_frame = mode[10]; + if (atp->desc.erasable) { + dsp->ds_flags |= DSF_ERA; + if (atp->desc.sub_type == 1) + dsp->ds_flags |= DSF_HIGHSP_ERA; + else if (atp->desc.sub_type == 2) + dsp->ds_flags |= DSF_ULTRASP_ERA; + else if (atp->desc.sub_type == 3) + dsp->ds_flags |= DSF_ULTRASP_ERA | DSF_ULTRASPP_ERA; + } + if (atp->desc.a1_v) { + if (atp->desc.clv_low != 0) + dsp->ds_at_min_speed = clv_to_speed[atp->desc.clv_low]; + if (atp->desc.clv_high != 0) + dsp->ds_at_max_speed = clv_to_speed[atp->desc.clv_high]; + + if (atp->desc.erasable && atp->desc.sub_type == 1) { + if (atp->desc.clv_high != 0) + dsp->ds_at_max_speed = hs_clv_to_speed[atp->desc.clv_high]; + } + } + if (atp->desc.a2_v && atp->desc.erasable && (atp->desc.sub_type == 2 || atp->desc.sub_type == 3)) { + Uint vlow; + Uint vhigh; + + vlow = (atp->desc.a2[0] >> 4) & 0x07; + vhigh = atp->desc.a2[0] & 0x0F; + if (vlow != 0) + dsp->ds_at_min_speed = us_clv_to_speed[vlow]; + if (vhigh != 0) + dsp->ds_at_max_speed = us_clv_to_speed[vhigh]; + } + did_atip = TRUE; + } + usalp->silent--; + +#ifdef PRINT_ATIP + if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && did_atip) { + print_atip(usalp, (struct atipinfo *)mode); + pr_manufacturer(&msf, + ((struct atipinfo *)mode)->desc.erasable, + ((struct atipinfo *)mode)->desc.uru); + } +#endif +again: + dip = (struct disk_info *)buf; + if (get_diskinfo(usalp, dip) < 0) + return (-1); + + /* + * Check for non writable disk first. + */ + + /* DVD+RW does not need to be blanked */ + rplus = dsp->ds_cdrflags; + if (dp->profile == 0x1A) rplus = RF_BLANK; + + if (dip->disk_status == DS_COMPLETE && + (rplus & dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) { + if (!did_dummy) { + int xspeed = 0xFFFF; + int oflags = dp->cdr_cmdflags; + + /* + * Try to clear the dummy bit to reset the virtual + * drive status. Not all drives support it even though + * it is mentioned in the MMC standard. + */ + if (lverbose) + printf("Trying to clear drive status.\n"); + + dp->cdr_cmdflags &= ~F_DUMMY; + speed_select_mmc(usalp, dp, &xspeed); + dp->cdr_cmdflags = oflags; + did_dummy = TRUE; + goto again; + } + /* + * Trying to clear drive status did not work... + */ + reload_media(usalp, dp); + } + if (get_diskinfo(usalp, dip) < 0) + return (-1); + di_to_dstat(dip, dsp); + if (!did_atip && dsp->ds_first_leadin < 0) + lba_to_msf(dsp->ds_first_leadin, &msf); + + if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && !did_atip) { + print_min_atip(dsp->ds_first_leadin, dsp->ds_last_leadout); + if (dsp->ds_first_leadin < 0) + pr_manufacturer(&msf, + dip->erasable, + dip->uru); + } + dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks, + dip->erasable, + dip->uru); + + +#ifdef PRINT_ATIP +#ifdef DEBUG + if (get_atip(usalp, (struct atipinfo *)mode) < 0) + return (-1); + /* + * Get pma gibt Ärger mit CW-7502 + * Wenn Die Disk leer ist, dann stuerzt alles ab. + * Firmware 4.02 kann nicht get_pma + */ + if (dip->disk_status != DS_EMPTY) { +/* get_pma();*/ + } + printf("ATIP lead in: %ld (%02d:%02d/%02d)\n", + msf_to_lba(mode[8], mode[9], mode[10], FALSE), + mode[8], mode[9], mode[10]); + printf("ATIP lead out: %ld (%02d:%02d/%02d)\n", + msf_to_lba(mode[12], mode[13], mode[14], TRUE), + mode[12], mode[13], mode[14]); + print_di(dip); + print_atip(usalp, (struct atipinfo *)mode); +#endif +#endif /* PRINT_ATIP */ + return (drive_getdisktype(usalp, dp)); +} + +#ifdef PRINT_ATIP + +#define DOES(what, flag) printf(" Does %s%s\n", flag?"":"not ", what); +#define IS(what, flag) printf(" Is %s%s\n", flag?"":"not ", what); +#define VAL(what, val) printf(" %s: %d\n", what, val[0]*256 + val[1]); +#define SVAL(what, val) printf(" %s: %s\n", what, val); + +static void +print_di(struct disk_info *dip) +{ + static char *ds_name[] = { "empty", "incomplete/appendable", "complete", "illegal" }; + static char *ss_name[] = { "empty", "incomplete/appendable", "illegal", "complete", }; + + IS("erasable", dip->erasable); + printf("disk status: %s\n", ds_name[dip->disk_status]); + printf("session status: %s\n", ss_name[dip->sess_status]); + printf("first track: %d number of sessions: %d first track in last sess: %d last track in last sess: %d\n", + dip->first_track, + dip->numsess, + dip->first_track_ls, + dip->last_track_ls); + IS("unrestricted", dip->uru); + printf("Disk type: "); + switch (dip->disk_type) { + + case SES_DA_ROM: printf("CD-DA or CD-ROM"); break; + case SES_CDI: printf("CDI"); break; + case SES_XA: printf("CD-ROM XA"); break; + case SES_UNDEF: printf("undefined"); break; + default: printf("reserved"); break; + } + printf("\n"); + if (dip->did_v) + printf("Disk id: 0x%lX\n", a_to_u_4_byte(dip->disk_id)); + + printf("last start of lead in: %ld\n", + msf_to_lba(dip->last_lead_in[1], + dip->last_lead_in[2], + dip->last_lead_in[3], FALSE)); + printf("last start of lead out: %ld\n", + msf_to_lba(dip->last_lead_out[1], + dip->last_lead_out[2], + dip->last_lead_out[3], TRUE)); + + if (dip->dbc_v) + printf("Disk bar code: 0x%lX%lX\n", + a_to_u_4_byte(dip->disk_barcode), + a_to_u_4_byte(&dip->disk_barcode[4])); + + if (dip->num_opc_entries > 0) { + printf("OPC table:\n"); + } +} + +char *cdr_subtypes[] = { + "Normal Rewritable (CLV) media", + "High speed Rewritable (CAV) media", + "Medium Type A, low Beta category (A-)", + "Medium Type A, high Beta category (A+)", + "Medium Type B, low Beta category (B-)", + "Medium Type B, high Beta category (B+)", + "Medium Type C, low Beta category (C-)", + "Medium Type C, high Beta category (C+)", +}; + +char *cdrw_subtypes[] = { + "Normal Rewritable (CLV) media", + "High speed Rewritable (CAV) media", + "Ultra High speed Rewritable media", + "Ultra High speed+ Rewritable media", + "Medium Type B, low Beta category (B-)", + "Medium Type B, high Beta category (B+)", + "Medium Type C, low Beta category (C-)", + "Medium Type C, high Beta category (C+)", +}; + +static void +atip_printspeed(char *fmt, int speedindex, char speedtab[]) +{ + printf("%s:", fmt); + if (speedtab[speedindex] == 0) { + printf(" %2d (reserved val %2d)", + speedtab[speedindex], speedindex); + } else { + printf(" %2d", speedtab[speedindex]); + } +} + +static void +print_atip(SCSI *usalp, struct atipinfo *atp) +{ + char *sub_type; + char *speedvtab = clv_to_speed; + + if (usalp->verbose) + usal_prbytes("ATIP info: ", (Uchar *)atp, sizeof (*atp)); + + printf("ATIP info from disk:\n"); + printf(" Indicated writing power: %d\n", atp->desc.ind_wr_power); + if (atp->desc.erasable || atp->desc.ref_speed) + printf(" Reference speed: %d\n", clv_to_speed[atp->desc.ref_speed]); + IS("unrestricted", atp->desc.uru); +/* printf(" Disk application code: %d\n", atp->desc.res5_05);*/ + IS("erasable", atp->desc.erasable); + if (atp->desc.erasable) + sub_type = cdrw_subtypes[atp->desc.sub_type]; + else + sub_type = cdr_subtypes[atp->desc.sub_type]; + if (atp->desc.sub_type) + printf(" Disk sub type: %s (%d)\n", sub_type, atp->desc.sub_type); + printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n", + msf_to_lba(atp->desc.lead_in[1], + atp->desc.lead_in[2], + atp->desc.lead_in[3], FALSE), + atp->desc.lead_in[1], + atp->desc.lead_in[2], + atp->desc.lead_in[3]); + printf(" ATIP start of lead out: %ld (%02d:%02d/%02d)\n", + msf_to_lba(atp->desc.lead_out[1], + atp->desc.lead_out[2], + atp->desc.lead_out[3], TRUE), + atp->desc.lead_out[1], + atp->desc.lead_out[2], + atp->desc.lead_out[3]); + if (atp->desc.a1_v) { + if (atp->desc.erasable && atp->desc.sub_type == 1) { + speedvtab = hs_clv_to_speed; + } + if (atp->desc.a2_v && (atp->desc.sub_type == 2 || atp->desc.sub_type == 3)) { + speedvtab = us_clv_to_speed; + } + if (atp->desc.clv_low != 0 || atp->desc.clv_high != 0) { + atip_printspeed(" 1T speed low", + atp->desc.clv_low, speedvtab); + atip_printspeed(" 1T speed high", + atp->desc.clv_high, speedvtab); + printf("\n"); + } + } + if (atp->desc.a2_v) { + Uint vlow; + Uint vhigh; + + vlow = (atp->desc.a2[0] >> 4) & 0x07; + vhigh = atp->desc.a2[0] & 0x0F; + + if (vlow != 0 || vhigh != 0) { + atip_printspeed(" 2T speed low", + vlow, speedvtab); + atip_printspeed(" 2T speed high", + vhigh, speedvtab); + printf("\n"); + } + } + if (atp->desc.a1_v) { + printf(" power mult factor: %d %d\n", atp->desc.power_mult, atp->desc.tgt_y_pow); + if (atp->desc.erasable) + printf(" recommended erase/write power: %d\n", atp->desc.rerase_pwr_ratio); + } + if (atp->desc.a1_v) { + printf(" A1 values: %02X %02X %02X\n", + (&atp->desc.res15)[1], + (&atp->desc.res15)[2], + (&atp->desc.res15)[3]); + } + if (atp->desc.a2_v) { + printf(" A2 values: %02X %02X %02X\n", + atp->desc.a2[0], + atp->desc.a2[1], + atp->desc.a2[2]); + } + if (atp->desc.a3_v) { + printf(" A3 values: %02X %02X %02X\n", + atp->desc.a3[0], + atp->desc.a3[1], + atp->desc.a3[2]); + } +} +#endif /* PRINT_ATIP */ + +static int +speed_select_mmc(SCSI *usalp, cdr_t *dp, int *speedp) +{ + Uchar mode[0x100]; + Uchar moder[0x100]; + int len; + struct cd_mode_page_05 *mp; + struct ricoh_mode_page_30 *rp = NULL; + int val; + BOOL forcespeed = FALSE; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) + curspeed = *speedp; + + /* + * Do not reset mp->test_write (-dummy) here. + */ + deflt_writemodes_mmc(usalp, FALSE); + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) + return (-1); + if (len == 0) + return (-1); + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + + if(dummy) { + mp->test_write = 1; + /* but it does not work on DVD+RW and -RAM, also bail out on other + * types that have not been tested yet */ + int profile=get_curprofile(usalp); + switch(profile) { + case(0x12): + case(0x1a): + case(0x2a): + case(0x43): + case(0x52): + { + fprintf(stderr, + "Dummy mode not possible with %s.\n", + mmc_obtain_profile_name(profile) ); + exit(EXIT_FAILURE); + } + } + } + else + mp->test_write = 0; + +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) + return (-1); + + /* + * Neither set nor get speed. + */ + if (speedp == 0) + return (0); + + + rp = get_justlink_ricoh(usalp, moder); + if (mmc_isyamaha(usalp)) { + forcespeed = FALSE; + } else if (mmc_isplextor(usalp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) { + int pwr; + + pwr = check_powerrec_plextor(usalp); + if (pwr >= 0) + forcespeed = (pwr == 0); + } else if ((dp->cdr_flags & CDR_FORCESPEED) != 0) { + forcespeed = rp && rp->AWSCD != 0; + } + + if (lverbose && (dp->cdr_flags & CDR_FORCESPEED) != 0) + printf("Forcespeed is %s.\n", forcespeed?"ON":"OFF"); + + if (!forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) != 0) { + printf("Turning forcespeed on\n"); + forcespeed = TRUE; + } + if (forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) == 0) { + printf("Turning forcespeed off\n"); + forcespeed = FALSE; + } + if (mmc_isplextor(usalp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) { + powerrec_plextor(usalp, !forcespeed); + } + if (!mmc_isyamaha(usalp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) { + + if (rp) { + rp->AWSCD = forcespeed?1:0; + set_mode_params(usalp, "Ricoh Vendor Page", moder, moder[0]+1, 0, -1); + rp = get_justlink_ricoh(usalp, moder); + } + } + + /* + * 44100 * 2 * 2 = 176400 bytes/s + * + * The right formula would be: + * tmp = (((long)curspeed) * 1764) / 10; + * + * But the standard is rounding the wrong way. + * Furtunately rounding down is guaranteed. + */ + val = curspeed*177; + if (val > 0xFFFF) + val = 0xFFFF; + if (mmc_isyamaha(usalp) && forcespeed) { + if (force_speed_yamaha(usalp, -1, val) < 0) + return (-1); + } else if (mmc_set_speed(usalp, -1, val, ROTCTL_CLV) < 0) { + return (-1); + } + + if (scsi_get_speed(usalp, 0, &val) >= 0) { + if (val > 0) { + fprintf(stderr, "Speed set to %d KB/s\n", val); + curspeed = val / 176; + *speedp = curspeed; + } + } + return (0); +} + +/* + * Some drives do not round up when writespeed is e.g. 1 and + * the minimum write speed of the drive is higher. Try to increment + * the write speed unti it gets accepted by the drive. + */ +static int +mmc_set_speed(SCSI *usalp, int readspeed, int writespeed, int rotctl) +{ + int rs; + int ws; + int ret = -1; + int c; + int k; + + if (scsi_get_speed(usalp, &rs, &ws) >= 0) { + if (readspeed < 0) + readspeed = rs; + if (writespeed < 0) + writespeed = ws; + } + if (writespeed < 0 || writespeed > 0xFFFF) + return (ret); + + usalp->silent++; + while (writespeed <= 0xFFFF) { + ret = scsi_set_speed(usalp, readspeed, writespeed, rotctl); + if (ret >= 0) + break; + c = usal_sense_code(usalp); + k = usal_sense_key(usalp); + /* + * Abort quickly if it does not make sense to repeat. + * 0x24 == Invalid field in cdb + * 0x24 means illegal speed. + */ + if ((k != SC_ILLEGAL_REQUEST) || (c != 0x24)) { + if (usalp->silent <= 1) + usal_printerr(usalp); + usalp->silent--; + return (-1); + } + writespeed += 177; + } + if (ret < 0 && usalp->silent <= 1) + usal_printerr(usalp); + usalp->silent--; + + return (ret); +} + +static int +speed_select_mdvd(SCSI *usalp, cdr_t *dp, int *speedp) +{ + int retcode; + char perf_desc[28]; + int write_speed = *speedp * 1385; + + /* For the moment we just divide the CD speed by 7*/ + + if(speedp!=NULL) + (*speedp)=(*speedp)*8; + + memset(perf_desc, 0, sizeof(perf_desc)); + + /* Write Rotation Control = ROTCTL_CLV + * | Restore Logical Unit Defaults = 0 + * | Exact = 0 + * | Random Access = 0) + */ + perf_desc[0]= ROTCTL_CLV << 3 | 0 << 2 | 0 << 1 | 0; + /* Start LBA to 0 */ + perf_desc[4] = 0; + perf_desc[5] = 0; + perf_desc[6] = 0; + perf_desc[7] = 0; + /* End LBA set to 0 (setting to 0xffffffff failed on my LG burner + */ + perf_desc[8] = 0; + perf_desc[9] = 0; + perf_desc[10] = 0; + perf_desc[11] = 0; + /* Read Speed = 0xFFFF */ + perf_desc[12] = 0; + perf_desc[13] = 0; + perf_desc[14] = 0xFF; + perf_desc[15] = 0xFF; + /* Read Time = 1s */ + perf_desc[18] = 1000 >> 8; + perf_desc[19] = 1000 & 0xFF; + /* Write Speed */ + perf_desc[20] = write_speed >> 24; + perf_desc[21] = write_speed >> 16 & 0xFF; + perf_desc[22] = write_speed >> 8 & 0xFF; + perf_desc[23] = write_speed & 0xFF; + /* Write Time = 1s */ + perf_desc[26] = 1000 >> 8; + perf_desc[27] = 1000 & 0xFF; + + /* retcode = scsi_set_streaming(usalp, NULL, 0); */ + retcode = scsi_set_streaming(usalp, perf_desc, sizeof(perf_desc)); + if (retcode == -1) return retcode; + retcode = speed_select_mmc(usalp, dp, speedp); + if(speedp!=NULL) + (*speedp)=(*speedp)/7; + return retcode; +} + +static int +next_wr_addr_mmc(SCSI *usalp, track_t *trackp, long *ap) +{ + struct track_info track_info; + long next_addr; + int result = -1; + + + /* + * Reading info for current track may require doing the read_track_info + * with either the track number (if the track is currently being written) + * or with 0xFF (if the track hasn't been started yet and is invisible + */ + + if (trackp != 0 && trackp->track > 0 && is_packet(trackp)) { + usalp->silent++; + result = read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_TRACK, + trackp->trackno, + sizeof (track_info)); + usalp->silent--; + } + + if (result < 0) { + if (read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_TRACK, 0xFF, + sizeof (track_info)) < 0) { + errmsgno(EX_BAD, "Cannot get next writable address for 'invisible' track.\n"); + errmsgno(EX_BAD, "This means that we are checking recorded media.\n"); + errmsgno(EX_BAD, "This media cannot be written in streaming mode anymore.\n"); + errmsgno(EX_BAD, "If you like to write to 'preformatted' RW media, try to blank the media first.\n"); + return (-1); + } + } + if (usalp->verbose) + usal_prbytes("track info:", (Uchar *)&track_info, + sizeof (track_info)-usal_getresid(usalp)); + next_addr = a_to_4_byte(track_info.next_writable_addr); + if (ap) + *ap = next_addr; + return (0); +} + +static int +write_leadin_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uint i; + long startsec = 0L; + +/* if (flags & F_SAO) {*/ + if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) { + if (debug || lverbose) { + printf("Sending CUE sheet...\n"); + flush(); + } + if ((*dp->cdr_send_cue)(usalp, dp, trackp) < 0) { + errmsgno(EX_BAD, "Cannot send CUE sheet.\n"); + return (-1); + } + + (*dp->cdr_next_wr_address)(usalp, &trackp[0], &startsec); + if (trackp[0].flags & TI_TEXT) { + startsec = dp->cdr_dstat->ds_first_leadin; + printf("SAO startsec: %ld\n", startsec); + } else if (startsec <= 0 && startsec != -150) { + if(lverbose>2) + fprintf(stderr, "WARNING: Drive returns wrong startsec (%ld) using -150\n", + startsec); + startsec = -150; + } + if (debug) + printf("SAO startsec: %ld\n", startsec); + + if (trackp[0].flags & TI_TEXT) { + if (startsec > 0) { + errmsgno(EX_BAD, "CD-Text must be in first session.\n"); + return (-1); + } + if (debug || lverbose) + printf("Writing lead-in...\n"); + if (write_cdtext(usalp, dp, startsec) < 0) + return (-1); + + dp->cdr_dstat->ds_cdrflags |= RF_LEADIN; + } else for (i = 1; i <= trackp->tracks; i++) { + trackp[i].trackstart += startsec +150; + } +#ifdef XXX + if (debug || lverbose) + printf("Writing lead-in...\n"); + + pad_track(usalp, dp, &trackp[1], -150, (Llong)0, + FALSE, 0); +#endif + } +/* if (flags & F_RAW) {*/ + if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_RAW) { + /* + * In RAW write mode, we now write the lead in (TOC). + */ + (*dp->cdr_next_wr_address)(usalp, &trackp[0], &startsec); + if (startsec > -4500) { + /* + * There must be at least 1 minute lead-in. + */ + errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%ld) using %ld from ATIP\n", + startsec, (long)dp->cdr_dstat->ds_first_leadin); + startsec = dp->cdr_dstat->ds_first_leadin; + } + if (startsec > -4500) { + errmsgno(EX_BAD, "Illegal startsec (%ld)\n", startsec); + return (-1); + } + if (debug || lverbose) + printf("Writing lead-in at sector %ld\n", startsec); + if (write_leadin(usalp, dp, trackp, startsec) < 0) + return (-1); + dp->cdr_dstat->ds_cdrflags |= RF_LEADIN; + } + return (0); +} + +int st2mode[] = { + 0, /* 0 */ + TM_DATA, /* 1 ST_ROM_MODE1 */ + TM_DATA, /* 2 ST_ROM_MODE2 */ + 0, /* 3 */ + 0, /* 4 ST_AUDIO_NOPRE */ + TM_PREEM, /* 5 ST_AUDIO_PRE */ + 0, /* 6 */ + 0, /* 7 */ +}; + +static int +next_wr_addr_mdvd(SCSI *usalp, track_t *trackp, long *ap) +{ + int track=0; + struct track_info track_info; + long next_addr; + int result = -1; + struct disk_info disk_info; + if (trackp){ + track = trackp->trackno; + } + + if (trackp != 0 && track > 0 && is_packet(trackp)) { + usalp->silent++; + result = read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_SESS, track, sizeof(track_info)); + usalp->silent--; + if (scsi_in_progress(usalp)){ + return -1; + } + + } + + if (result < 0) { + /* Get the last rzone*/ + if(read_disk_info(usalp,(caddr_t)&disk_info,8)<0) + return (-1); + + /* if (read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_SESS, 0xFF, sizeof(track_info)) < 0) */ + if (read_rzone_info(usalp, (caddr_t)&track_info, sizeof(track_info)) < 0) + return (-1); + } + if (usalp->verbose) + usal_prbytes("track info:", (Uchar *)&track_info, + sizeof(track_info)-usal_getresid(usalp)); + next_addr = a_to_4_byte(track_info.next_writable_addr); + if (ap) + *ap = next_addr; + return (0); +} + +static int +open_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + if (!is_tao(trackp) && !is_packet(trackp)) { + if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) { + if (lverbose) { + printf("Writing pregap for track %d at %ld\n", + (int)trackp->trackno, + trackp->trackstart-trackp->pregapsize); + } + /* + * XXX Do we need to check isecsize too? + */ + pad_track(usalp, dp, trackp, + trackp->trackstart-trackp->pregapsize, + (Llong)trackp->pregapsize*trackp->secsize, + FALSE, 0); + } + return (0); + } + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) + return (-1); + if (len == 0) + return (-1); + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + +/* mp->track_mode = ???;*/ + mp->track_mode = st2mode[trackp->sectype & ST_MASK]; +/* mp->copy = ???;*/ + mp->dbtype = trackp->dbtype; + +/*i_to_short(mp->audio_pause_len, 300);*/ +/*i_to_short(mp->audio_pause_len, 150);*/ +/*i_to_short(mp->audio_pause_len, 0);*/ + + if (is_packet(trackp)) { + mp->write_type = WT_PACKET; + mp->track_mode |= TM_INCREMENTAL; + mp->fp = (trackp->pktsize > 0) ? 1 : 0; + i_to_4_byte(mp->packet_size, trackp->pktsize); + } else if (is_tao(trackp)) { + mp->write_type = WT_TAO; + mp->fp = 0; + i_to_4_byte(mp->packet_size, 0); + } else { + errmsgno(EX_BAD, "Unknown write mode.\n"); + return (-1); + } + if (trackp->isrc) { + mp->ISRC[0] = 0x80; /* Set ISRC valid */ + strncpy((char *)&mp->ISRC[1], trackp->isrc, 12); + + } else { + fillbytes(&mp->ISRC[0], sizeof (mp->ISRC), '\0'); + } + +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, trackp->secsize)) + return (-1); + + return (0); +} + +static int +open_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + if (is_packet(trackp)) { + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + + if (!get_mode_params(usalp, 0x05, "DVD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) + return (-1); + if (len == 0) + return (-1); + + mp = (struct cd_mode_page_05 *) + (mode + sizeof(struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + mp->write_type = WT_PACKET; + mp->LS_V = 1; + /*For now we set the link size to 0x10(32k) because Pioneer-A03 only support this */ + mp->link_size=0x10; + mp->fp = 1; + i_to_4_byte(mp->packet_size, trackp->pktsize); + } else { + return 0; + } + + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, trackp->secsize)) + return (-1); + + return (0); +} + +static int +close_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int ret; + + if (!is_tao(trackp) && !is_packet(trackp)) + return (0); + + if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) { + printf("Trouble flushing the cache\n"); + return (-1); + } + wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */ + if (is_packet(trackp) && !is_noclose(trackp)) { + /* close the incomplete track */ + ret = scsi_close_tr_session(usalp, CL_TYPE_TRACK, 0xFF, + (dp->cdr_cmdflags&F_IMMED) != 0); + wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */ + return (ret); + } + return (0); +} + +static int +close_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int ret; + if (!is_packet(trackp)) + return (0); + + if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) { + printf("Trouble flushing the cache\n"); + return -1; + } + wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */ + if (is_packet(trackp) && !is_noclose(trackp)) { + /* close the incomplete track */ + ret = scsi_close_tr_session(usalp, 1, 0xFF, (dp->cdr_cmdflags&F_IMMED) != 0); + wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */ + return (ret); + } + return (0); +} + +int toc2sess[] = { + SES_DA_ROM, /* CD-DA */ + SES_DA_ROM, /* CD-ROM */ + SES_XA, /* CD-ROM XA mode 1 */ + SES_XA, /* CD-ROM XA MODE 2 */ + SES_CDI, /* CDI */ + SES_DA_ROM, /* Invalid - use default */ + SES_DA_ROM, /* Invalid - use default */ +}; + +static int +open_session_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uchar mode[0x100]; + int len; + struct cd_mode_page_05 *mp; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) + return (-1); + if (len == 0) + return (-1); + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + mp->write_type = WT_TAO; /* fix to allow DAO later */ + /* + * We need to set the right dbtype here because Sony drives + * don't like multi session in to be set with DB_ROM_MODE1 + * which is set by us at the beginning as default as some drives + * have illegal default values. + */ + mp->track_mode = st2mode[trackp[0].sectype & ST_MASK]; + mp->dbtype = trackp[0].dbtype; + + if (!is_tao(trackp) && !is_packet(trackp)) { + mp->write_type = WT_SAO; + if (dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) + mp->write_type = 8; + mp->track_mode = 0; + mp->dbtype = DB_RAW; + } + if (is_raw(trackp)) { + mp->write_type = WT_RAW; + mp->track_mode = 0; + + if (is_raw16(trackp)) { + mp->dbtype = DB_RAW_PQ; + } else if (is_raw96r(trackp)) { + mp->dbtype = DB_RAW_PW_R; + } else { + mp->dbtype = DB_RAW_PW; + } + } + + mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ? + MS_MULTI : MS_NONE; + mp->session_format = toc2sess[track_base(trackp)->tracktype & TOC_MASK]; + + if (trackp->isrc) { + mp->media_cat_number[0] = 0x80; /* Set MCN valid */ + strncpy((char *)&mp->media_cat_number[1], trackp->isrc, 13); + + } else { + fillbytes(&mp->media_cat_number[0], sizeof (mp->media_cat_number), '\0'); + } +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) + return (-1); + + return (0); +} + +static int +open_session_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uchar mode[0x100]; + int tracks = trackp->tracks; + + int len; + struct cd_mode_page_05 *mp; + Ulong totalsize; + int i; + int profile; + + fillbytes((caddr_t)mode, sizeof(mode), '\0'); + + if (!get_mode_params(usalp, 0x05, "DVD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) + return (-1); + if (len == 0) + return (-1); + + mp = (struct cd_mode_page_05 *) + (mode + sizeof(struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + if(is_packet(trackp)){ + mp->write_type=WT_PACKET; + mp->fp=0; + mp->BUFE=1; + mp->track_mode=1; + }else{ + mp->write_type = WT_SAO; + } + + mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ? + MS_MULTI : MS_NONE; + mp->session_format = toc2sess[track_base(trackp)->tracktype & TOC_MASK]; + + /* Enable Burnfree by default, allow to disable. XXX Sucks, duplicated functionality. */ + if (dp->cdr_cdcap->BUF != 0) { + if (lverbose > 2) + fprintf(stderr, + "BURN-Free is %s.\n" + "Turning BURN-Free on\n", + mp->BUFE?"ON":"OFF"); + mp->BUFE = 1; + } + if (driveropts != NULL) { + if ((strcmp(driveropts, "noburnproof") == 0 || + strcmp(driveropts, "noburnfree") == 0)) { + if(lverbose>1) + fprintf(stderr, "Turning BURN-Free off\n"); + mp->BUFE = 0; + } + else if ((strcmp(driveropts, "burnproof") == 0 || + strcmp(driveropts, "burnfree") == 0)) { + /* a NOP, we enable burnfree by default */ + if(lverbose>2) + fprintf(stderr, "Found burnproof/burnfree in driveropts, those options are enabled by default now."); + } + else if (strcmp(driveropts, "help") == 0) { + mmc_opthelp(dp, 0); + } + else { + errmsgno(EX_BAD, "Bad driver opts '%s'.\n", driveropts); + mmc_opthelp(dp, EX_BAD); + } + } + + + if (!set_mode_params(usalp, "DVD write parameter", mode, len, 0, -1)) + return (-1); + + + totalsize=0; + for(i=1;i<=tracks;i++) { + totalsize+=trackp[i].tracksecs; + } + + profile = get_curprofile(usalp); + if(!is_packet(trackp) && profile != 0x1A){ + /* in DAO mode we need to reserve space for the track*/ + if(reserve_track(usalp, totalsize)<0) + return (-1); + } + return (0); +} + +static int +waitfix_mmc(SCSI *usalp, int secs) +{ + char dibuf[16]; + int i; + int key; +#define W_SLEEP 2 + + usalp->silent++; + for (i = 0; i < secs/W_SLEEP; i++) { + if (read_disk_info(usalp, dibuf, sizeof (dibuf)) >= 0) { + usalp->silent--; + return (0); + } + key = usal_sense_key(usalp); + if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY) + break; + sleep(W_SLEEP); + } + usalp->silent--; + return (-1); +#undef W_SLEEP +} + +static int +fixate_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int ret = 0; + int key = 0; + int code = 0; + struct timeval starttime; + struct timeval stoptime; + int dummy = (track_base(trackp)->tracktype & TOCF_DUMMY) != 0; + + if(debug) + printf("fixate_mmc\n"); + starttime.tv_sec = 0; + starttime.tv_usec = 0; + stoptime = starttime; + gettimeofday(&starttime, (struct timezone *)0); + + if (dummy && lverbose) + printf("WARNING: Some drives don't like fixation in dummy mode.\n"); + + usalp->silent++; + if(debug) + printf("is_tao: %d,is_packet: %d\n", is_tao(trackp), is_packet(trackp)); + if (is_tao(trackp) || is_packet(trackp)) { + ret = scsi_close_tr_session(usalp, CL_TYPE_SESSION, 0, + (dp->cdr_cmdflags&F_IMMED) != 0); + } else { + if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) { + if (!scsi_in_progress(usalp)) + printf("Trouble flushing the cache\n"); + } + } + usalp->silent--; + key = usal_sense_key(usalp); + code = usal_sense_code(usalp); + + usalp->silent++; + if (debug && !unit_ready(usalp)) { + fprintf(stderr, "Early return from fixating. Ret: %d Key: %d, Code: %d\n", ret, key, code); + } + usalp->silent--; + + if (ret >= 0) { + wait_unit_ready(usalp, 420/curspeed); /* XXX Wait for ATAPI */ + waitfix_mmc(usalp, 420/curspeed); /* XXX Wait for ATAPI */ + return (ret); + } + + if ((dummy != 0 && (key != SC_ILLEGAL_REQUEST)) || + /* + * Try to suppress messages from drives that don't like fixation + * in -dummy mode. + */ + ((dummy == 0) && + (((key != SC_UNIT_ATTENTION) && (key != SC_NOT_READY)) || + ((code != 0x2E) && (code != 0x04))))) { + /* + * UNIT ATTENTION/2E seems to be a magic for old Mitsumi ATAPI drives + * NOT READY/ code 4 qual 7 (logical unit not ready, operation in progress) + * seems to be a magic for newer Mitsumi ATAPI drives + * NOT READY/ code 4 qual 8 (logical unit not ready, long write in progress) + * seems to be a magic for SONY drives + * when returning early from fixating. + * Try to supress the error message in this case to make + * simple minded users less confused. + */ + usal_printerr(usalp); + usal_printresult(usalp); /* XXX restore key/code in future */ + } + + if (debug && !unit_ready(usalp)) { + fprintf(stderr, "Early return from fixating. Ret: %d Key: %d, Code: %d\n", ret, key, code); + } + + wait_unit_ready(usalp, 420); /* XXX Wait for ATAPI */ + waitfix_mmc(usalp, 420/curspeed); /* XXX Wait for ATAPI */ + + if (!dummy && + (ret >= 0 || (key == SC_UNIT_ATTENTION && code == 0x2E))) { + /* + * Some ATAPI drives (e.g. Mitsumi) imply the + * IMMED bit in the SCSI cdb. As there seems to be no + * way to properly check for the real end of the + * fixating process we wait for the expected time. + */ + gettimeofday(&stoptime, (struct timezone *)0); + timevaldiff(&starttime, &stoptime); + if (stoptime.tv_sec < (220 / curspeed)) { + unsigned secs; + + if (lverbose) { + printf("Actual fixating time: %ld seconds\n", + (long)stoptime.tv_sec); + } + secs = (280 / curspeed) - stoptime.tv_sec; + if (lverbose) { + printf("ATAPI early return: sleeping %d seconds.\n", + secs); + } + sleep(secs); + } + } + return (ret); +} + +static int +fixate_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int ret; + if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) { + printf("Trouble flushing the cache\n"); + return -1; + } + wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */ + /*set a really BIG timeout and call fixate_mmc + The BIG timeout is needed in case there was a very short rzone to write at the + beginning of the disk, because lead-out needs to be at some distance. + */ + if(debug) + printf("fixate_mdvd\n"); + usal_settimeout(usalp, 1000); + if(is_packet(trackp) || dp->profile == 0x1B){ + scsi_close_tr_session(usalp, CL_TYPE_SESSION, 0, FALSE); + } + ret = fixate_mmc(usalp, dp, trackp); + if (dp->profile == 0x2B) { + scsi_close_tr_session(usalp, CL_TYPE_OPEN_SESSION, 0, FALSE); + scsi_close_tr_session(usalp, CL_TYPE_FINALISE_MINRAD, 0, FALSE); + } + usal_settimeout(usalp, 200); + + return ret; +} + +char *blank_types[] = { + "entire disk", + "PMA, TOC, pregap", + "incomplete track", + "reserved track", + "tail of track", + "closing of last session", + "last session", + "reserved blanking type", +}; + +char *format_types[] = { + "full format", + "background format", + "forced format", +}; + +static int +blank_mmc(SCSI *usalp, cdr_t *dp, long addr, int blanktype) +{ + BOOL cdrr = FALSE; /* Read CD-R */ + BOOL cdwr = FALSE; /* Write CD-R */ + BOOL cdrrw = FALSE; /* Read CD-RW */ + BOOL cdwrw = FALSE; /* Write CD-RW */ + int ret; + + mmc_check(usalp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, NULL); + if (!cdwrw) + return (blank_dummy(usalp, dp, addr, blanktype)); + + if (dp->profile == 0x1A) { + printf("Error: this media does not support blanking, ignoring.\n"); + return (blank_dummy(usalp, dp, addr, blanktype)); + } + if (lverbose) { + printf("Blanking %s\n", blank_types[blanktype & 0x07]); + flush(); + } + + ret = scsi_blank(usalp, addr, blanktype, (dp->cdr_cmdflags&F_IMMED) != 0); + if (ret < 0) + return (ret); + + wait_unit_ready(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */ + waitfix_mmc(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */ + return (ret); +} + +static int format_mdvd(SCSI *usalp, cdr_t *dp, int formattype) +{ +extern char *buf; + BOOL dvdwr = FALSE; /* Write DVD */ + int ret; + int profile; + char addr[12]; + struct disk_info *dip; + + if (debug || lverbose > 2) + printf("format_mdvd\n"); + mmc_check(usalp, NULL, NULL, NULL, NULL, NULL, &dvdwr); + if (!dvdwr) + return (format_dummy(usalp, dp, formattype)); + + if (debug || lverbose > 2) + printf("format_mdvd: drive is a dvd burner.\n"); + profile = get_curprofile(usalp); + if (profile != 0x1A) { + printf("Error: only support DVD+RW formating, ignoring.\n"); + return (format_dummy(usalp, dp, formattype)); + } + dip = (struct disk_info *)buf; + if (get_diskinfo(usalp, dip) < 0) + return -1; + + if (dip->disk_status & 3 && formattype != FORCE_FORMAT) { + printf("Error: disk already formated, ignoring.\n"); + return -1; + } + addr[0] = 0; /* "Reserved" */ + addr[1] = 2; /* "IMMED" flag */ + addr[2] = 0; /* "Descriptor Length" (MSB) */ + addr[3] = 8; /* "Descriptor Length" (LSB) */ + addr[4+0] = 0xff; + addr[4+1] = 0xff; + addr[4+2] = 0xff; + addr[4+3] = 0xff; + addr[4+4] = 0x26<<2; + addr[4+5] = 0; + addr[4+6] = 0; + addr[4+7] = 0; + if (formattype == FORCE_FORMAT) { + printf("format_mdvd: forcing reformat.\n"); + formattype = FULL_FORMAT; + addr[4+0] = 0; + addr[4+1] = 0; + addr[4+2] = 0; + addr[4+3] = 0; + addr[4+7] = 1; + } else { + printf("format_mdvd: media is unformated.\n"); + } + + if (lverbose) { + printf("Formating %s\n", format_types[formattype & 0x07]); + flush(); + } + if (formattype == FULL_FORMAT) { + ret = scsi_format(usalp, (caddr_t)&addr, sizeof(addr), FALSE); + } else { + ret = scsi_format(usalp, (caddr_t)&addr, sizeof(addr), TRUE); + } + if (ret < 0) + return (ret); + + wait_unit_ready(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */ + waitfix_mmc(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */ + return (ret); +} + +static int +send_opc_mmc(SCSI *usalp, caddr_t bp, int cnt, int doopc) +{ + int ret; + + usalp->silent++; + ret = send_opc(usalp, bp, cnt, doopc); + usalp->silent--; + + if (ret >= 0) + return (ret); + + /* BEGIN CSTYLED */ + /* + * Hack for a mysterioys drive .... + * Device type : Removable CD-ROM + * Version : 0 + * Response Format: 1 + * Vendor_info : 'RWD ' + * Identifikation : 'RW2224 ' + * Revision : '2.53' + * Device seems to be: Generic mmc CD-RW. + * + * Performing OPC... + * CDB: 54 01 00 00 00 00 00 00 00 00 + * Sense Bytes: 70 00 06 00 00 00 00 0A 00 00 00 00 5A 03 00 00 + * Sense Key: 0x6 Unit Attention, Segment 0 + * Sense Code: 0x5A Qual 0x03 (operator selected write permit) Fru 0x0 + * Sense flags: Blk 0 (not valid) + */ + /* END CSTYLED */ + if (usal_sense_key(usalp) == SC_UNIT_ATTENTION && + usal_sense_code(usalp) == 0x5A && + usal_sense_qual(usalp) == 0x03) + return (0); + + /* + * Do not make the condition: + * "Power calibration area almost full" a fatal error. + * It just flags that we have a single and last chance to write now. + */ + if ((usal_sense_key(usalp) == SC_RECOVERABLE_ERROR || + usal_sense_key(usalp) == SC_MEDIUM_ERROR) && + usal_sense_code(usalp) == 0x73 && + usal_sense_qual(usalp) == 0x01) + return (0); + + /* + * Send OPC is optional. + */ + if (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST) { + if (usalp->silent <= 0) + usal_printerr(usalp); + return (ret); + } + return (0); +} + +static int +opt1_mmc(SCSI *usalp, cdr_t *dp) +{ + int oflags = dp->cdr_dstat->ds_cdrflags; + + if ((dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) != 0) { + printf("Turning Audio Master Q. R. on\n"); + if (set_audiomaster_yamaha(usalp, dp, TRUE) < 0) + return (-1); + if (!debug && lverbose <= 1) + dp->cdr_dstat->ds_cdrflags &= ~RF_PRATIP; + if (getdisktype_mmc(usalp, dp) < 0) { + dp->cdr_dstat->ds_cdrflags = oflags; + return (-1); + } + dp->cdr_dstat->ds_cdrflags = oflags; + if (oflags & RF_PRATIP) { + msf_t msf; + lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf); + printf("New start of lead in: %ld (%02d:%02d/%02d)\n", + (long)dp->cdr_dstat->ds_first_leadin, + msf.msf_min, + msf.msf_sec, + msf.msf_frame); + lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf); + printf("New start of lead out: %ld (%02d:%02d/%02d)\n", + (long)dp->cdr_dstat->ds_maxblocks, + msf.msf_min, + msf.msf_sec, + msf.msf_frame); + } + } + if (mmc_isplextor(usalp)) { + int gcode; + + if ((dp->cdr_flags & (CDR_SINGLESESS|CDR_HIDE_CDR)) != 0) { + if (ss_hide_plextor(usalp, + (dp->cdr_dstat->ds_cdrflags & RF_SINGLESESS) != 0, + (dp->cdr_dstat->ds_cdrflags & RF_HIDE_CDR) != 0) < 0) + return (-1); + } + + if ((dp->cdr_flags & CDR_SPEEDREAD) != 0) { + if (speed_rd_plextor(usalp, + (dp->cdr_dstat->ds_cdrflags & RF_SPEEDREAD) != 0) < 0) + return (-1); + } + + if ((dp->cdr_cmdflags & F_SETDROPTS) || + (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) || + (wm_base(dp->cdr_dstat->ds_wrmode) == WM_RAW)) + gcode = do_gigarec_plextor(usalp); + else + gcode = gigarec_plextor(usalp, 0); + if (gcode != 0) { + msf_t msf; + + dp->cdr_dstat->ds_first_leadin = + gigarec_mult(gcode, dp->cdr_dstat->ds_first_leadin); + dp->cdr_dstat->ds_maxblocks = + gigarec_mult(gcode, dp->cdr_dstat->ds_maxblocks); + + if (oflags & RF_PRATIP) { + lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf); + printf("New start of lead in: %ld (%02d:%02d/%02d)\n", + (long)dp->cdr_dstat->ds_first_leadin, + msf.msf_min, + msf.msf_sec, + msf.msf_frame); + lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf); + printf("New start of lead out: %ld (%02d:%02d/%02d)\n", + (long)dp->cdr_dstat->ds_maxblocks, + msf.msf_min, + msf.msf_sec, + msf.msf_frame); + } + } + } + return (0); +} + +static int +opt2_mmc(SCSI *usalp, cdr_t *dp) +{ + Uchar mode[0x100]; + Uchar moder[0x100]; + int len; + struct cd_mode_page_05 *mp; + struct ricoh_mode_page_30 *rp = NULL; + BOOL burnfree = FALSE; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) + return (-1); + if (len == 0) + return (-1); + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + + rp = get_justlink_ricoh(usalp, moder); + + if (dp->cdr_cdcap->BUF != 0) { + burnfree = (mp->BUFE != 0); + } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) { + burnfree = (rp && (rp->BUEFE != 0)); + } + + if (lverbose>2 && (dp->cdr_flags & CDR_BURNFREE) != 0) + printf("BURN-Free is %s.\n", burnfree?"ON":"OFF"); + + if (!burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) != 0) { + if(lverbose>2) + printf("Turning BURN-Free on\n"); + burnfree = TRUE; + } + if (burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) { + if(lverbose>2) + printf("Turning BURN-Free off\n"); + burnfree = FALSE; + } + if (dp->cdr_cdcap->BUF != 0) { + mp->BUFE = burnfree?1:0; + } + else if ((dp->cdr_flags & CDR_BURNFREE) != 0) { + + if (rp) + rp->BUEFE = burnfree?1:0; + } + if (rp) { + /* + * Clear Just-Link counter + */ + i_to_2_byte(rp->link_counter, 0); + if (xdebug) + usal_prbytes("Mode Select Data ", moder, moder[0]+1); + + if (!set_mode_params(usalp, "Ricoh Vendor Page", moder, moder[0]+1, 0, -1)) + return (-1); + rp = get_justlink_ricoh(usalp, moder); + } + +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) + return (-1); + + if (mmc_isplextor(usalp)) { + /* + * Clear Burn-Proof counter + */ + usalp->silent++; + bpc_plextor(usalp, 1, NULL); + usalp->silent--; + + do_varirec_plextor(usalp); + } + + return (0); +} + +static int +opt1_mdvd(SCSI *usalp, cdr_t *dp) +{ + int oflags = dp->cdr_dstat->ds_cdrflags; + + if ((dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) != 0) { + printf("Turning Audio Master Q. R. on\n"); + if (set_audiomaster_yamaha(usalp, dp, TRUE) < 0) + return (-1); + if (!debug && lverbose <= 1) + dp->cdr_dstat->ds_cdrflags &= ~RF_PRATIP; + if (getdisktype_mdvd(usalp, dp) < 0) { + dp->cdr_dstat->ds_cdrflags = oflags; + return (-1); + } + dp->cdr_dstat->ds_cdrflags = oflags; + if (oflags & RF_PRATIP) { + msf_t msf; + lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf); + printf("New start of lead in: %ld (%02d:%02d/%02d)\n", + (long)dp->cdr_dstat->ds_first_leadin, + msf.msf_min, + msf.msf_sec, + msf.msf_frame); + lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf); + printf("New start of lead out: %ld (%02d:%02d/%02d)\n", + (long)dp->cdr_dstat->ds_maxblocks, + msf.msf_min, + msf.msf_sec, + msf.msf_frame); + } + } + return (0); +} + +static int +scsi_sony_write(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + return (write_xg5(usalp, bp, sectaddr, size, blocks)); +} + +Uchar db2df[] = { + 0x00, /* 0 2352 bytes of raw data */ + 0xFF, /* 1 2368 bytes (raw data + P/Q Subchannel) */ + 0xFF, /* 2 2448 bytes (raw data + P-W Subchannel) */ + 0xFF, /* 3 2448 bytes (raw data + P-W raw Subchannel)*/ + 0xFF, /* 4 - Reserved */ + 0xFF, /* 5 - Reserved */ + 0xFF, /* 6 - Reserved */ + 0xFF, /* 7 - Vendor specific */ + 0x10, /* 8 2048 bytes Mode 1 (ISO/IEC 10149) */ + 0x30, /* 9 2336 bytes Mode 2 (ISO/IEC 10149) */ + 0xFF, /* 10 2048 bytes Mode 2! (CD-ROM XA form 1) */ + 0xFF, /* 11 2056 bytes Mode 2 (CD-ROM XA form 1) */ + 0xFF, /* 12 2324 bytes Mode 2 (CD-ROM XA form 2) */ + 0xFF, /* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */ + 0xFF, /* 14 - Reserved */ + 0xFF, /* 15 - Vendor specific */ +}; + +static int +gen_cue_mmc(track_t *trackp, void *vcuep, BOOL needgap) +{ + int tracks = trackp->tracks; + int i; + struct mmc_cue **cuep = vcuep; + struct mmc_cue *cue; + struct mmc_cue *cp; + int ncue = 0; + int icue = 0; + int pgsize; + msf_t m; + int ctl; + int df; + int scms; + + cue = malloc(1); + + for (i = 0; i <= tracks; i++) { + ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[i])) + ctl |= TM_ALLOW_COPY << 4; + if (is_quadro(&trackp[i])) + ctl |= TM_QUADRO << 4; + df = db2df[trackp[i].dbtype & 0x0F]; + if (trackp[i].tracktype == TOC_XA2 && + trackp[i].sectype == (SECT_MODE_2_MIX|ST_MODE_RAW)) { + /* + * Hack for CUE with MODE2/CDI and + * trackp[i].dbtype == DB_RAW + */ + df = 0x21; + } + + if (trackp[i].isrc) { /* MCN or ISRC */ + ncue += 2; + cue = realloc(cue, ncue * sizeof (*cue)); + cp = &cue[icue++]; + if (i == 0) { + cp->cs_ctladr = 0x02; + movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7); + cp = &cue[icue++]; + cp->cs_ctladr = 0x02; + movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7); + } else { + cp->cs_ctladr = 0x03; + cp->cs_tno = i; + movebytes(&trackp[i].isrc[0], &cp->cs_index, 6); + cp = &cue[icue++]; + cp->cs_ctladr = 0x03; + cp->cs_tno = i; + movebytes(&trackp[i].isrc[6], &cp->cs_index, 6); + } + } + if (i == 0) { /* Lead in */ + df &= ~7; /* Mask off data size & nonRAW subch */ + if (df < 0x10) + df |= 1; + else + df |= 4; + if (trackp[0].flags & TI_TEXT) /* CD-Text in Lead-in*/ + df |= 0x40; + lba_to_msf(-150, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 0, df, 0, &m); + } else { + scms = 0; + + if (is_scms(&trackp[i])) + scms = 0x80; + pgsize = trackp[i].pregapsize; + if (pgsize == 0 && needgap) + pgsize++; + lba_to_msf(trackp[i].trackstart-pgsize, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 0, df, scms, &m); + + if (trackp[i].nindex == 1) { + lba_to_msf(trackp[i].trackstart, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 1, df, scms, &m); + } else { + int idx; + long *idxlist; + + ncue += trackp[i].nindex; + idxlist = trackp[i].tindex; + cue = realloc(cue, ncue * sizeof (*cue)); + + for (idx = 1; idx <= trackp[i].nindex; idx++) { + lba_to_msf(trackp[i].trackstart + idxlist[idx], &m); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, idx, df, scms, &m); + } + } + } + } + /* Lead out */ + ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[i])) + ctl |= TM_ALLOW_COPY << 4; + if (is_quadro(&trackp[i])) + ctl |= TM_QUADRO << 4; + df = db2df[trackp[tracks+1].dbtype & 0x0F]; + if (trackp[i].tracktype == TOC_XA2 && + trackp[i].sectype == (SECT_MODE_2_MIX|ST_MODE_RAW)) { + /* + * Hack for CUE with MODE2/CDI and + * trackp[i].dbtype == DB_RAW + */ + df = 0x21; + } + df &= ~7; /* Mask off data size & nonRAW subch */ + if (df < 0x10) + df |= 1; + else + df |= 4; + lba_to_msf(trackp[tracks+1].trackstart, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m); + + if (lverbose > 1) { + for (i = 0; i < ncue; i++) { + usal_prbytes("", (Uchar *)&cue[i], 8); + } + } + if (cuep) + *cuep = cue; + else + free(cue); + return (ncue); +} + +static void +fillcue(struct mmc_cue *cp /* The target cue entry */, + int ca /* Control/adr for this entry */, + int tno /* Track number for this entry */, + int idx /* Index for this entry */, + int dataform /* Data format for this entry */, + int scms /* Serial copy management */, + msf_t *mp /* MSF value for this entry */) +{ + cp->cs_ctladr = ca; /* XXX wie lead in */ + cp->cs_tno = tno; + cp->cs_index = idx; + cp->cs_dataform = dataform; /* XXX wie lead in */ + cp->cs_scms = scms; + cp->cs_min = mp->msf_min; + cp->cs_sec = mp->msf_sec; + cp->cs_frame = mp->msf_frame; +} + +static int +send_cue_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + struct mmc_cue *cp; + int ncue; + int ret; + Uint i; + + for (i = 1; i <= trackp->tracks; i++) { + if (trackp[i].tracksize < (tsize_t)0) { + errmsgno(EX_BAD, "Track %d has unknown length.\n", i); + return (-1); + } + } + ncue = (*dp->cdr_gen_cue)(trackp, &cp, FALSE); + + usalp->silent++; + ret = send_cue_sheet(usalp, (caddr_t)cp, ncue*8); + usalp->silent--; + free(cp); + if (ret < 0) { + errmsgno(EX_BAD, "CUE sheet not accepted. Retrying with minimum pregapsize = 1.\n"); + ncue = (*dp->cdr_gen_cue)(trackp, &cp, TRUE); + ret = send_cue_sheet(usalp, (caddr_t)cp, ncue*8); + if (ret < 0) { + errmsgno(EX_BAD, + "CUE sheet still not accepted. Please try to write in RAW (-raw96r) mode.\n"); + } + free(cp); + } + return (ret); +} + +static int +stats_mmc(SCSI *usalp, cdr_t *dp) +{ + Uchar mode[256]; + struct ricoh_mode_page_30 *rp; + UInt32_t count; + + if (mmc_isplextor(usalp) && lverbose) { + int sels; + int maxs; + int lasts; + + /* + * Run it in silent mode as old drives do not support it. + * As this function looks to be a part of the PowerRec + * features, we may want to check + * dp->cdr_flags & CDR_FORCESPEED + */ + usalp->silent++; + if (get_speeds_plextor(usalp, &sels, &maxs, &lasts) >= 0) { + printf("Last selected write speed: %dx\n", + sels / 176); + printf("Max media write speed: %dx\n", + maxs / 176); + printf("Last actual write speed: %dx\n", + lasts / 176); + } + usalp->silent--; + } + + if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) + return (0); + + if (mmc_isplextor(usalp)) { + int i = 0; + int ret; + + /* + * Read Burn-Proof counter + */ + usalp->silent++; + ret = bpc_plextor(usalp, 2, &i); + usalp->silent--; + if (ret < 0) + return (-1); + count = i; + /* + * Clear Burn-Proof counter + */ + bpc_plextor(usalp, 1, NULL); + } else { + rp = get_justlink_ricoh(usalp, mode); + if (rp) + count = a_to_u_2_byte(rp->link_counter); + else + return (-1); + } + if (lverbose) { + if (count == 0) + printf("BURN-Free was never needed.\n"); + else + printf("BURN-Free was %d times used.\n", + (int)count); + } + return (0); +} +/*--------------------------------------------------------------------------*/ +static BOOL +mmc_isplextor(SCSI *usalp) +{ + if (usalp->inq != NULL && + strncmp(usalp->inq->vendor_info, "PLEXTOR", 7) == 0) { + return (TRUE); + } + return (FALSE); +} + +static BOOL +mmc_isyamaha(SCSI *usalp) +{ + if (usalp->inq != NULL && + strncmp(usalp->inq->vendor_info, "YAMAHA", 6) == 0) { + return (TRUE); + } + return (FALSE); +} + +static void +do_varirec_plextor(SCSI *usalp) +{ + char *p; + int voff; + + p = hasdrvopt(driveropts, "varirec="); + if (p == NULL || curspeed != 4) { + if (check_varirec_plextor(usalp) >= 0) + varirec_plextor(usalp, FALSE, 0); + } else { + if (*astoi(p, &voff) != '\0') + comerrno(EX_BAD, + "Bad varirec value '%s'.\n", p); + if (check_varirec_plextor(usalp) < 0) + comerrno(EX_BAD, "Drive does not support VariRec.\n"); + varirec_plextor(usalp, TRUE, voff); + } +} + +/* + * GigaRec value table + */ +struct gr { + Uchar val; + char vadd; + char *name; +} gr[] = { + { 0x00, 0, "off", }, + { 0x00, 0, "1.0", }, + { 0x01, 2, "1.2", }, + { 0x02, 3, "1.3", }, + { 0x03, 4, "1.4", }, + { 0x81, -2, "0.8", }, + { 0x82, -3, "0.7", }, + { 0x83, -4, "0.6", }, + { 0x00, 0, NULL, }, +}; + +static int +do_gigarec_plextor(SCSI *usalp) +{ + char *p; + int val = 0; /* Make silly GCC happy */ + + p = hasdrvopt(driveropts, "gigarec="); + if (p == NULL) { + if (check_gigarec_plextor(usalp) >= 0) + gigarec_plextor(usalp, 0); + } else { + struct gr *gp = gr; + + for (; gp->name != NULL; gp++) { + if (streql(p, gp->name)) { + val = gp->val; + break; + } + } + if (gp->name == NULL) + comerrno(EX_BAD, + "Bad gigarec value '%s'.\n", p); + if (check_gigarec_plextor(usalp) < 0) + comerrno(EX_BAD, "Drive does not support GigaRec.\n"); + return (gigarec_plextor(usalp, val)); + } + return (0); +} + +static int +drivemode_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode, void *modeval) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + if (modeval == NULL) { + scmd->flags |= SCG_RECV_DATA; + scmd->addr = bp; + scmd->size = cnt; + } else { + scmd->cdb.g5_cdb.res = 0x08; + } + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xE9; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = modecode; + if (modeval) + movebytes(modeval, &scmd->cdb.g1_cdb.addr[1], 6); + else + i_to_2_byte(&scmd->cdb.g1_cdb.count[2], cnt); + + usalp->cmdname = "plextor drive mode"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +/* + * #defines for drivemode_plextor()... + */ +#define MODE_CODE_SH 0x01 /* Mode code for Single Session & Hide-CDR */ +#define MB1_SS 0x01 /* Single Session Mode */ +#define MB1_HIDE_CDR 0x02 /* Hide CDR Media */ + +#define MODE_CODE_VREC 0x02 /* Mode code for Vari Rec */ + +#define MODE_CODE_GREC 0x04 /* Mode code for Giga Rec */ + +#define MODE_CODE_SPEED 0xbb /* Mode code for Speed Read */ +#define MBbb_SPEAD_READ 0x01 /* Spead Read */ + /* Danach Speed auf 0xFFFF 0xFFFF setzen */ + +static int +drivemode2_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode, void *modeval) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + if (modeval == NULL) { + scmd->flags |= SCG_RECV_DATA; + scmd->addr = bp; + scmd->size = cnt; + } else { + scmd->cdb.g5_cdb.res = 0x08; + } + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xED; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = modecode; + if (modeval) + scmd->cdb.g5_cdb.reladr = *(char *)modeval != 0 ? 1 : 0; + else + i_to_2_byte(&scmd->cdb.g1_cdb.count[1], cnt); + + usalp->cmdname = "plextor drive mode2"; + + if (usal_cmd(usalp) < 0) + return (-1); + + return (0); +} + +static int +check_varirec_plextor(SCSI *usalp) +{ + int modecode = 2; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + return (0); +} + +static int +check_gigarec_plextor(SCSI *usalp) +{ + int modecode = 4; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + return (0); +} + +static int +varirec_plextor(SCSI *usalp, BOOL on, int val) +{ + int modecode = 2; + Uchar setmode[8]; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + + fillbytes(setmode, sizeof (setmode), '\0'); + setmode[0] = on?1:0; + if (on) { + if (val < -2 || val > 2) + comerrno(EX_BAD, "Bad VariRec offset %d\n", val); + printf("Turning Varirec on.\n"); + printf("Varirec offset is %d.\n", val); + + if (val > 0) { + setmode[1] = val & 0x7F; + } else { + setmode[1] = (-val) & 0x7F; + setmode[1] |= 0x80; + } + } + + if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0) + return (-1); + + fillbytes(getmode, sizeof (getmode), '\0'); + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) + return (-1); + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + return (0); +} + +static int +gigarec_plextor(SCSI *usalp, int val) +{ + int modecode = 4; + Uchar setmode[8]; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + + fillbytes(setmode, sizeof (setmode), '\0'); + setmode[1] = val; + + if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0) + return (-1); + + fillbytes(getmode, sizeof (getmode), '\0'); + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) + return (-1); + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + { + struct gr *gp = gr; + + for (; gp->name != NULL; gp++) { + if (getmode[3] == gp->val) + break; + } + if (gp->name == NULL) + printf("Unknown GigaRec value 0x%X.\n", getmode[3]); + else + printf("GigaRec %sis %s.\n", gp->val?"value ":"", gp->name); + } + return (getmode[3]); +} + +static Int32_t +gigarec_mult(int code, Int32_t val) +{ + Int32_t add; + struct gr *gp = gr; + + for (; gp->name != NULL; gp++) { + if (code == gp->val) + break; + } + if (gp->vadd == 0) + return (val); + + add = val * gp->vadd / 10; + return (val + add); +} + +static int +check_ss_hide_plextor(SCSI *usalp) +{ + int modecode = 1; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + return (getmode[2] & 0x03); +} + +static int +check_speed_rd_plextor(SCSI *usalp) +{ + int modecode = 0xBB; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + return (getmode[2] & 0x01); +} + +static int +check_powerrec_plextor(SCSI *usalp) +{ + int modecode = 0; + Uchar getmode[8]; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode2_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + if (getmode[2] & 1) + return (1); + + return (0); +} + +static int +ss_hide_plextor(SCSI *usalp, BOOL do_ss, BOOL do_hide) +{ + int modecode = 1; + Uchar setmode[8]; + Uchar getmode[8]; + BOOL is_ss; + BOOL is_hide; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + + is_ss = (getmode[2] & MB1_SS) != 0; + is_hide = (getmode[2] & MB1_HIDE_CDR) != 0; + + if (lverbose > 0) { + printf("Single session is %s.\n", is_ss ? "ON":"OFF"); + printf("Hide CDR is %s.\n", is_hide ? "ON":"OFF"); + } + + fillbytes(setmode, sizeof (setmode), '\0'); + setmode[0] = getmode[2]; /* Copy over old values */ + if (do_ss >= 0) { + if (do_ss) + setmode[0] |= MB1_SS; + else + setmode[0] &= ~MB1_SS; + } + if (do_hide >= 0) { + if (do_hide) + setmode[0] |= MB1_HIDE_CDR; + else + setmode[0] &= ~MB1_HIDE_CDR; + } + + if (do_ss >= 0 && do_ss != is_ss) + printf("Turning single session %s.\n", do_ss?"on":"off"); + if (do_hide >= 0 && do_hide != is_hide) + printf("Turning hide CDR %s.\n", do_hide?"on":"off"); + + if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0) + return (-1); + + fillbytes(getmode, sizeof (getmode), '\0'); + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) + return (-1); + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + return (0); +} + +static int +speed_rd_plextor(SCSI *usalp, BOOL do_speedrd) +{ + int modecode = 0xBB; + Uchar setmode[8]; + Uchar getmode[8]; + BOOL is_speedrd; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + + is_speedrd = (getmode[2] & MBbb_SPEAD_READ) != 0; + + if (lverbose > 0) + printf("Speed-Read is %s.\n", is_speedrd ? "ON":"OFF"); + + fillbytes(setmode, sizeof (setmode), '\0'); + setmode[0] = getmode[2]; /* Copy over old values */ + if (do_speedrd >= 0) { + if (do_speedrd) + setmode[0] |= MBbb_SPEAD_READ; + else + setmode[0] &= ~MBbb_SPEAD_READ; + } + + if (do_speedrd >= 0 && do_speedrd != is_speedrd) + printf("Turning Speed-Read %s.\n", do_speedrd?"on":"off"); + + if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0) + return (-1); + + fillbytes(getmode, sizeof (getmode), '\0'); + if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) + return (-1); + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + /* + * Set current read speed to new max value. + */ + if (do_speedrd >= 0 && do_speedrd != is_speedrd) + scsi_set_speed(usalp, 0xFFFF, -1, ROTCTL_CAV); + + return (0); +} + +static int +powerrec_plextor(SCSI *usalp, BOOL do_powerrec) +{ + int modecode = 0; + Uchar setmode[8]; + Uchar getmode[8]; + BOOL is_powerrec; + int speed; + + fillbytes(getmode, sizeof (getmode), '\0'); + usalp->silent++; + if (drivemode2_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) { + usalp->silent--; + return (-1); + } + usalp->silent--; + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + + is_powerrec = (getmode[2] & 1) != 0; + + speed = a_to_u_2_byte(&getmode[4]); + + if (lverbose > 0) { + printf("Power-Rec is %s.\n", is_powerrec ? "ON":"OFF"); + printf("Power-Rec write speed: %dx (recommended)\n", speed / 176); + } + + fillbytes(setmode, sizeof (setmode), '\0'); + setmode[0] = getmode[2]; /* Copy over old values */ + if (do_powerrec >= 0) { + if (do_powerrec) + setmode[0] |= 1; + else + setmode[0] &= ~1; + } + + if (do_powerrec >= 0 && do_powerrec != is_powerrec) + printf("Turning Power-Rec %s.\n", do_powerrec?"on":"off"); + + if (drivemode2_plextor(usalp, NULL, 0, modecode, setmode) < 0) + return (-1); + + fillbytes(getmode, sizeof (getmode), '\0'); + if (drivemode2_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) + return (-1); + + if (lverbose > 1) + usal_prbytes("Modes", getmode, sizeof (getmode)); + + return (0); +} + +static int +get_speeds_plextor(SCSI *usalp, int *selp, int *maxp, int *lastp) +{ + register struct usal_cmd *scmd = usalp->scmd; + char buf[10]; + int i; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->flags |= SCG_RECV_DATA; + scmd->addr = buf; + scmd->size = sizeof (buf); + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xEB; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + i_to_2_byte(&scmd->cdb.g1_cdb.count[1], sizeof (buf)); + + usalp->cmdname = "plextor get speedlist"; + + if (usal_cmd(usalp) < 0) + return (-1); + + i = a_to_u_2_byte(&buf[4]); + if (selp) + *selp = i; + + i = a_to_u_2_byte(&buf[6]); + if (maxp) + *maxp = i; + + i = a_to_u_2_byte(&buf[8]); + if (lastp) + *lastp = i; + + return (0); +} + +static int +bpc_plextor(SCSI *usalp, int mode, int *bpp) +{ + register struct usal_cmd *scmd = usalp->scmd; + char buf[4]; + int i; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + fillbytes((caddr_t)buf, sizeof (buf), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->flags |= SCG_RECV_DATA; + scmd->addr = buf; + scmd->size = sizeof (buf); + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xF5; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + scmd->cdb.g5_cdb.addr[1] = 0x08; + scmd->cdb.g5_cdb.addr[2] = mode; + + i_to_2_byte(&scmd->cdb.g1_cdb.count[1], sizeof (buf)); + + usalp->cmdname = "plextor read bpc"; + + if (usal_cmd(usalp) < 0) + return (-1); + + if (usal_getresid(usalp) > 2) + return (0); + + i = a_to_u_2_byte(buf); + if (bpp) + *bpp = i; + + return (0); +} + +static int +set_audiomaster_yamaha(SCSI *usalp, cdr_t *dp, BOOL keep_mode) +{ + Uchar mode[0x100]; + int len; + int ret = 0; + struct cd_mode_page_05 *mp; + + if (xdebug && !keep_mode) + printf("Checking for Yamaha Audio Master feature: "); + + /* + * Do not reset mp->test_write (-dummy) here. + */ + deflt_writemodes_mmc(usalp, FALSE); + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + usalp->silent++; + if (!get_mode_params(usalp, 0x05, "CD write parameter", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + usalp->silent--; + return (-1); + } + if (len == 0) { + usalp->silent--; + return (-1); + } + + mp = (struct cd_mode_page_05 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); +#ifdef DEBUG + usal_prbytes("CD write parameter:", (Uchar *)mode, len); +#endif + + /* + * Do not set mp->test_write (-dummy) here. It should be set + * only at one place and only one time. + */ + mp->BUFE = 0; + + mp->write_type = 8; + mp->track_mode = 0; + mp->dbtype = DB_RAW; + + if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) + ret = -1; + + /* + * Do not reset mp->test_write (-dummy) here. + */ + if (!keep_mode || ret < 0) + deflt_writemodes_mmc(usalp, FALSE); + usalp->silent--; + + return (ret); +} + +struct +ricoh_mode_page_30 *get_justlink_ricoh(SCSI *usalp, Uchar *mode) +{ + Uchar modec[0x100]; + int len; + struct ricoh_mode_page_30 *mp; + + usalp->silent++; + if (!get_mode_params(usalp, 0x30, "Ricoh Vendor Page", mode, modec, NULL, NULL, &len)) { + usalp->silent--; + return ((struct ricoh_mode_page_30 *)0); + } + usalp->silent--; + + /* + * SCSI mode header + 6 bytes mode page 30. + * This is including the Burn-Free counter. + */ + if (len < 10) + return ((struct ricoh_mode_page_30 *)0); + + if (xdebug) { + fprintf(stderr, "Mode len: %d\n", len); + usal_prbytes("Mode Sense Data ", mode, len); + usal_prbytes("Mode Sence CData", modec, len); + } + + mp = (struct ricoh_mode_page_30 *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + /* + * 6 bytes mode page 30. + * This is including the Burn-Free counter. + */ + if ((len - ((Uchar *)mp - mode) -1) < 5) + return ((struct ricoh_mode_page_30 *)0); + + if (xdebug) { + fprintf(stderr, "Burnfree counter: %d\n", a_to_u_2_byte(mp->link_counter)); + } + return (mp); +} + +static int +force_speed_yamaha(SCSI *usalp, int readspeed, int writespeed) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xBB; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + if (readspeed < 0) + i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], 0xFFFF); + else + i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], readspeed); + if (writespeed < 0) + i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], 0xFFFF); + else + i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], writespeed); + + scmd->cdb.cmd_cdb[11] = 0x80; + + usalp->cmdname = "yamaha force cd speed"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static BOOL +get_tattoo_yamaha(SCSI *usalp, BOOL print, Int32_t *irp, Int32_t *orp) +{ + Uchar mode[0x100]; + int len; + UInt32_t ival; + UInt32_t oval; + Uchar *mp; + + usalp->silent++; + if (!get_mode_params(usalp, 0x31, "Yamaha Tattoo Page", mode, NULL, NULL, NULL, &len)) { + usalp->silent--; + return (FALSE); + } + usalp->silent--; + + /* + * SCSI mode header + 16 bytes mode page 31. + * This is including the Burn-Free counter. + */ + if (len < 20) + return (FALSE); + + mp = (Uchar *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + /* + * 10 bytes mode page 31. + * This is including the Burn-Free counter. + */ + if ((len - ((Uchar *)mp - mode) -1) < 10) + return (FALSE); + + ival = a_to_u_3_byte(&mp[4]); + oval = a_to_u_3_byte(&mp[7]); + + if (irp) + *irp = ival; + if (orp) + *orp = oval; + + if (print && ival > 0 && oval > 0) { + printf("DiskT@2 inner r: %d\n", (int)ival); + printf("DiskT@2 outer r: %d\n", (int)oval); + printf("DiskT@2 image size: 3744 x %d pixel.\n", + (int)(oval-ival)+1); + } + + return (TRUE); +} + +static int +do_tattoo_yamaha(SCSI *usalp, FILE *f) +{ + Int32_t ival = 0; + Int32_t oval = 0; + Int32_t lines; + off_t fsize; + char *buf = usalp->bufptr; + long bufsize = usalp->maxbuf; + long nsecs; + long amt; + + nsecs = bufsize / 2048; + bufsize = nsecs * 2048; + + if (!get_tattoo_yamaha(usalp, FALSE, &ival, &oval)) { + errmsgno(EX_BAD, "Cannot get DiskT@2 info.\n"); + return (-1); + } + + if (ival == 0 || oval == 0) { + errmsgno(EX_BAD, "DiskT@2 info not valid.\n"); + return (-1); + } + + lines = oval - ival + 1; + fsize = filesize(f); + if ((fsize % 3744) != 0 || fsize < (lines*3744)) { + errmsgno(EX_BAD, "Illegal DiskT@2 file size.\n"); + return (-1); + } + if (fsize > (lines*3744)) + fsize = lines*3744; + + if (lverbose) + printf("Starting to write DiskT@2 data.\n"); + fillbytes(buf, bufsize, '\0'); + if ((amt = fileread(f, buf, bufsize)) <= 0) { + errmsg("DiskT@2 file read error.\n"); + return (-1); + } + + if (yamaha_write_buffer(usalp, 1, 0, ival, amt/2048, buf, amt) < 0) { + errmsgno(EX_BAD, "DiskT@2 1st write error.\n"); + return (-1); + } + amt = (amt+2047) / 2048 * 2048; + fsize -= amt; + + while (fsize > 0) { + fillbytes(buf, bufsize, '\0'); + if ((amt = fileread(f, buf, bufsize)) <= 0) { + errmsg("DiskT@2 file read error.\n"); + return (-1); + } + amt = (amt+2047) / 2048 * 2048; + fsize -= amt; + if (yamaha_write_buffer(usalp, 1, 0, 0, amt/2048, buf, amt) < 0) { + errmsgno(EX_BAD, "DiskT@2 write error.\n"); + return (-1); + } + } + + if (yamaha_write_buffer(usalp, 1, 0, oval, 0, buf, 0) < 0) { + errmsgno(EX_BAD, "DiskT@2 final error.\n"); + return (-1); + } + + wait_unit_ready(usalp, 1000); /* Wait for DiskT@2 */ + waitfix_mmc(usalp, 1000); /* Wait for DiskT@2 */ + + return (0); +} + +/* + * Yamaha specific version of 'write buffer' that offers an additional + * Parameter Length 'parlen' parameter. + */ +static int +yamaha_write_buffer(SCSI *usalp, int mode, int bufferid, long offset, + long parlen, void *buffer, long buflen) +{ + register struct usal_cmd *scmd = usalp->scmd; + Uchar *CDB; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = buffer; + scmd->size = buflen; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x3B; + + CDB = (Uchar *)scmd->cdb.cmd_cdb; + CDB[1] = mode & 7; + CDB[2] = bufferid; + i_to_3_byte(&CDB[3], offset); + i_to_3_byte(&CDB[6], parlen); + + usalp->cmdname = "write_buffer"; + + if (usal_cmd(usalp) >= 0) + return (1); + return (0); +} + +static int +dvd_dual_layer_split(SCSI *usalp, cdr_t *dp, long tsize) +{ + unsigned char xb[12]; + long l0_size; + + /* Get the Layer 0 defined data zone*/ + if (read_dvd_structure(usalp, (caddr_t)xb, 12, 0, 0, 0x20) >= 0) { + if ((xb[1] | xb[0] << 8) < 13) { + fprintf(stderr, "dvd_dual_layer_split: read_dvd_structure returns invalid data\n"); + return 1; + } + if (xb[4] & 0x80) { + printf("L0 zone size already set\n"); + return 1; + } + l0_size = xb[11] | xb[10] << 8 | xb[9] << 16 | xb[8] << 24; + if (tsize < l0_size) { + fprintf(stderr, "track size smaller than one layer, use --force to force burning."); + return 0; + } + printf("L0 size: %ld (track size %ld)\n", l0_size, tsize); + l0_size = tsize / 2; + l0_size = l0_size - 1 + 16 - (l0_size - 1) % 16; + printf("New L0 size: %ld\n", l0_size); + + memset (xb, 0, sizeof(xb)); + xb[1] = sizeof(xb) - 2; + xb[8] = l0_size >> 24; + xb[9] = l0_size >> 16; + xb[10] = l0_size >> 8; + xb[11] = l0_size; + if (send_dvd_structure(usalp, (caddr_t)xb, 12, 0, 0x20)) { + fprintf(stderr, "dvd_dual_layer_split: send_dvd_structure failed, could not set middle zone location.\n"); + return 0; + } + } + return 1; +} diff --git a/wodim/drv_philips.c b/wodim/drv_philips.c new file mode 100644 index 0000000..13cf8ed --- /dev/null +++ b/wodim/drv_philips.c @@ -0,0 +1,1346 @@ +/* + * 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. + * + */ + +/* @(#)drv_philips.c 1.69 05/05/16 Copyright 1997-2005 J. Schilling */ +/* + * CDR device implementation for + * Philips/Yamaha/Ricoh/Plasmon + * + * Copyright (c) 1997-2005 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 <unixstd.h> /* Include sys/types.h to make off_t available */ +#include <standard.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/scsireg.h> +#include <usal/scsitransp.h> +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> /* XXX Only for DEV_RICOH_RO_1060C */ + +#include "wodim.h" + +extern int debug; +extern int lverbose; + +static int load_unload_philips(SCSI *usalp, int); +static int philips_load(SCSI *usalp, cdr_t *dp); +static int philips_unload(SCSI *usalp, cdr_t *dp); +static int philips_dumbload(SCSI *usalp, cdr_t *dp); +static int philips_dumbunload(SCSI *usalp, cdr_t *dp); +static int plasmon_buf(SCSI *, long *, long *); +static int recover_philips(SCSI *usalp, cdr_t *dp, int); +static int speed_select_yamaha(SCSI *usalp, cdr_t *dp, int *speedp); +static int speed_select_philips(SCSI *usalp, cdr_t *dp, int *speedp); +static int speed_select_oldphilips(SCSI *usalp, cdr_t *dp, int *speedp); +static int speed_select_dumbphilips(SCSI *usalp, cdr_t *dp, int *speedp); +static int speed_select_pioneer(SCSI *usalp, cdr_t *dp, int *speedp); +static int philips_init(SCSI *usalp, cdr_t *dp); +static int philips_getdisktype(SCSI *usalp, cdr_t *dp); +static BOOL capacity_philips(SCSI *usalp, long *lp); +static int first_writable_addr_philips(SCSI *usalp, long *, int, int, int, + int); +static int next_wr_addr_philips(SCSI *usalp, track_t *trackp, long *ap); +static int reserve_track_philips(SCSI *usalp, unsigned long); +static int scsi_cdr_write_philips(SCSI *usalp, caddr_t bp, long sectaddr, + long size, int blocks, BOOL islast); +static int write_track_info_philips(SCSI *usalp, int); +static int write_track_philips(SCSI *usalp, long, int); +static int open_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_track_plasmon(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_track_oldphilips(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_track_yamaha(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int close_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int fixation_philips(SCSI *usalp, cdr_t *dp, track_t *trackp); + +static int philips_attach(SCSI *usalp, cdr_t *); +static int plasmon_attach(SCSI *usalp, cdr_t *); +static int ricoh_attach(SCSI *usalp, cdr_t *); +static int philips_getlilo(SCSI *usalp, long *lilenp, long *lolenp); + + +struct cdd_52x_mode_page_21 { /* write track information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x0E = 14 Bytes */ + Uchar res_2; + Uchar sectype; + Uchar track; + Uchar ISRC[9]; + Uchar res[2]; +}; + +struct cdd_52x_mode_page_23 { /* speed selection */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 6 Bytes */ + Uchar speed; + Uchar dummy; + Uchar res[4]; + +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct yamaha_mode_page_31 { /* drive configuration */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar res; + Ucbit dummy : 4; + Ucbit speed : 4; +}; + +#else /* Motorola byteorder */ + +struct yamaha_mode_page_31 { /* drive configuration */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar res; + Ucbit speed : 4; + Ucbit dummy : 4; +}; +#endif + +struct cdd_52x_mode_data { + struct scsi_mode_header header; + union cdd_pagex { + struct cdd_52x_mode_page_21 page21; + struct cdd_52x_mode_page_23 page23; + struct yamaha_mode_page_31 page31; + } pagex; +}; + + +cdr_t cdr_philips_cdd521O = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 2, 2, + "philips_cdd521_old", + "driver for Philips old CDD-521", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + philips_load, + philips_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_oldphilips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_oldphilips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_philips_dumb = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 2, 2, + "philips_dumb", + "driver for Philips CDD-521 with pessimistic assumptions", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + philips_dumbload, + philips_dumbunload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_dumbphilips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_oldphilips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_philips_cdd521 = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 2, 2, + "philips_cdd521", + "driver for Philips CDD-521", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + philips_load, + philips_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_philips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_philips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_philips_cdd522 = { + 0, 0, +/* CDR_TAO|CDR_SAO|CDR_TRAYLOAD,*/ + CDR_TAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 2, 2, + "philips_cdd522", + "driver for Philips CDD-522", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + philips_load, + philips_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_philips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_philips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_tyuden_ew50 = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD|CDR_SWABAUDIO, + CDR_CDRW_NONE, + 2, 2, + "tyuden_ew50", + "driver for Taiyo Yuden EW-50", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + philips_load, + philips_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_philips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_philips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_kodak_pcd600 = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 6, 6, + "kodak_pcd_600", + "driver for Kodak PCD-600", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + philips_load, + philips_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_philips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_oldphilips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_plasmon_rf4100 = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD, + CDR_CDRW_NONE, + 2, 4, + "plasmon_rf4100", + "driver for Plasmon RF 4100", + 0, + (dstat_t *)0, + drive_identify, + plasmon_attach, + philips_init, + philips_getdisktype, + philips_load, + philips_unload, + plasmon_buf, + recovery_needed, + recover_philips, + speed_select_philips, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_plasmon, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_pioneer_dw_s114x = { + 0, 0, + CDR_TAO|CDR_TRAYLOAD|CDR_SWABAUDIO, + CDR_CDRW_NONE, + 2, 4, + "pioneer_dws114x", + "driver for Pioneer DW-S114X", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + philips_getdisktype, + scsi_load, + scsi_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_pioneer, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ +/* open_track_yamaha,*/ +/*???*/ open_track_oldphilips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_yamaha_cdr100 = { + 0, 0, +/* CDR_TAO|CDR_SAO|CDR_CADDYLOAD|CDR_SWABAUDIO,*/ + CDR_TAO|CDR_CADDYLOAD|CDR_SWABAUDIO, + CDR_CDRW_NONE, + 2, 4, + "yamaha_cdr100", + "driver for Yamaha CDR-100 / CDR-102", + 0, + (dstat_t *)0, + drive_identify, + philips_attach, + philips_init, + drive_getdisktype, + scsi_load, + philips_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_yamaha, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_yamaha, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_ricoh_ro1060 = { + 0, 0, +/* CDR_TAO|CDR_SAO|CDR_CADDYLOAD,*/ + CDR_TAO|CDR_CADDYLOAD, + CDR_CDRW_NONE, + 2, 2, + "ricoh_ro1060c", + "driver for Ricoh RO-1060C", + 0, + (dstat_t *)0, + drive_identify, + ricoh_attach, + philips_init, + philips_getdisktype, + scsi_load, + scsi_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_yamaha, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_philips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_ricoh_ro1420 = { + 0, 0, +/* CDR_TAO|CDR_SAO|CDR_CADDYLOAD,*/ + CDR_TAO|CDR_CADDYLOAD, + CDR_CDRW_NONE, + 2, 2, + "ricoh_ro1420c", + "driver for Ricoh RO-1420C", + 0, + (dstat_t *)0, + drive_identify, + ricoh_attach, + philips_init, + philips_getdisktype, + scsi_load, + scsi_unload, + buf_dummy, + recovery_needed, + recover_philips, + speed_select_yamaha, + select_secsize, + next_wr_addr_philips, + reserve_track_philips, + scsi_cdr_write_philips, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + no_sendcue, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_philips, + close_track_philips, + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset_philips, + fixation_philips, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + + +static int load_unload_philips(SCSI *usalp, int load) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE7; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.count[1] = !load; + + usalp->cmdname = "philips medium load/unload"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +philips_load(SCSI *usalp, cdr_t *dp) +{ + return (load_unload_philips(usalp, 1)); +} + +static int +philips_unload(SCSI *usalp, cdr_t *dp) +{ + return (load_unload_philips(usalp, 0)); +} + +static int +philips_dumbload(SCSI *usalp, cdr_t *dp) +{ + int ret; + + usalp->silent++; + ret = load_unload_philips(usalp, 1); + usalp->silent--; + if (ret < 0) + return (scsi_load(usalp, dp)); + return (0); +} + +static int +philips_dumbunload(SCSI *usalp, cdr_t *dp) +{ + int ret; + + usalp->silent++; + ret = load_unload_philips(usalp, 0); + usalp->silent--; + if (ret < 0) + return (scsi_unload(usalp, dp)); + return (0); +} + +static int +plasmon_buf(SCSI *usalp, + long *sp /* Size pointer */, + long *fp /* Free space pointer */) +{ + /* + * There's no way to obtain these values from the + * Plasmon RF41xx devices. This function stub is only + * present to prevent cdrecord.c from calling the READ BUFFER + * SCSI cmd which is implemented non standard compliant in + * the Plasmon drive. Calling READ BUFFER would only jam the Plasmon + * as the non standard implementation in the Plasmon firmware + * expects different parameters. + */ + + if (sp) + *sp = 0L; + if (fp) + *fp = 0L; + + return (100); /* 100 % */ +} + +static int +recover_philips(SCSI *usalp, cdr_t *dp, int track) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xEC; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "philips recover"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +speed_select_yamaha(SCSI *usalp, cdr_t *dp, int *speedp) +{ + struct scsi_mode_page_header *mp; + char mode[256]; + int len = 16; + int page = 0x31; + struct yamaha_mode_page_31 *xp; + struct cdd_52x_mode_data md; + int count; + int speed = 1; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) { + speed = *speedp; + } else { + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, page, "Speed/Dummy information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + return (-1); + } + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp = (struct yamaha_mode_page_31 *)mp; + speed = xp->speed; + } + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct yamaha_mode_page_31); + + speed >>= 1; + md.pagex.page31.p_code = 0x31; + md.pagex.page31.p_len = 0x02; + md.pagex.page31.speed = speed; + md.pagex.page31.dummy = dummy?1:0; + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +speed_select_philips(SCSI *usalp, cdr_t *dp, int *speedp) +{ + struct scsi_mode_page_header *mp; + char mode[256]; + int len = 20; + int page = 0x23; + struct cdd_52x_mode_page_23 *xp; + struct cdd_52x_mode_data md; + int count; + int speed = 1; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) { + speed = *speedp; + } else { + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, page, "Speed/Dummy information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + return (-1); + } + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp = (struct cdd_52x_mode_page_23 *)mp; + speed = xp->speed; + } + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct cdd_52x_mode_page_23); + + md.pagex.page23.p_code = 0x23; + md.pagex.page23.p_len = 0x06; + md.pagex.page23.speed = speed; + md.pagex.page23.dummy = dummy?1:0; + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +speed_select_pioneer(SCSI *usalp, cdr_t *dp, int *speedp) +{ + if (speedp != 0 && *speedp < 2) { + *speedp = 2; + if (lverbose) + printf("WARNING: setting to minimum speed (2).\n"); + } + return (speed_select_philips(usalp, dp, speedp)); +} + +static int +speed_select_oldphilips(SCSI *usalp, cdr_t *dp, int *speedp) +{ + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (lverbose) + printf("WARNING: ignoring selected speed.\n"); + if (dummy) { + errmsgno(EX_BAD, "Cannot set dummy writing for this device.\n"); + return (-1); + } + return (0); +} + +static int +speed_select_dumbphilips(SCSI *usalp, cdr_t *dp, int *speedp) +{ + if (speed_select_philips(usalp, dp, speedp) < 0) + return (speed_select_oldphilips(usalp, dp, speedp)); + return (0); +} + +static int +philips_init(SCSI *usalp, cdr_t *dp) +{ + return ((*dp->cdr_set_speed_dummy)(usalp, dp, NULL)); +} + + +#define IS(what, flag) printf(" Is %s%s\n", flag?"":"not ", what); + +static int +philips_getdisktype(SCSI *usalp, cdr_t *dp) +{ + dstat_t *dsp = dp->cdr_dstat; + char sbuf[16]; + long dummy; + long lilen; + long lolen; + msf_t msf; + int audio = -1; + + usalp->silent++; + dummy = (*dp->cdr_next_wr_address)(usalp, (track_t *)0, &lilen); + usalp->silent--; + + /* + * Check for "Command sequence error" first. + */ + if ((dsp->ds_cdrflags & RF_WRITE) != 0 && + dummy < 0 && + (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST || + usal_sense_code(usalp) != 0x2C)) { + reload_media(usalp, dp); + } + + usalp->silent++; + if (read_subchannel(usalp, sbuf, 0, 12, 0, 1, 0xf0) >= 0) { + if (sbuf[2] == 0 && sbuf[3] == 8) + audio = (sbuf[7] & 0x40) != 0; + } + usalp->silent--; + + if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && + dummy >= 0 && lilen == 0) { + usalp->silent++; + dummy = philips_getlilo(usalp, &lilen, &lolen); + usalp->silent--; + + if (dummy >= 0) { +/* printf("lead-in len: %d lead-out len: %d\n", lilen, lolen);*/ + lba_to_msf(-150 - lilen, &msf); + + printf("ATIP info from disk:\n"); + if (audio >= 0) + IS("unrestricted", audio); + if (audio == 1 || (audio == 0 && (sbuf[7] & 0x3F) != 0x3F)) + printf(" Disk application code: %d\n", sbuf[7] & 0x3F); + printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n", + -150 - lilen, msf.msf_min, msf.msf_sec, msf.msf_frame); + + if (capacity_philips(usalp, &lolen)) { + lba_to_msf(lolen, &msf); + printf( + " ATIP start of lead out: %ld (%02d:%02d/%02d)\n", + lolen, msf.msf_min, msf.msf_sec, msf.msf_frame); + } + lba_to_msf(-150 - lilen, &msf); + pr_manufacturer(&msf, + FALSE, /* Always not erasable */ + audio > 0); /* Audio from read subcode */ + } + } + + if (capacity_philips(usalp, &lolen)) { + dsp->ds_maxblocks = lolen; + dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks, + FALSE, /* Always not erasable */ + audio > 0); /* Audio from read subcode */ + } + usalp->silent++; + /*read_subchannel(usalp, bp, track, cnt, msf, subq, fmt); */ + + if (read_subchannel(usalp, sbuf, 0, 14, 0, 0, 0xf1) >= 0) + usal_prbytes("Disk bar code:", (Uchar *)sbuf, 14 - usal_getresid(usalp)); + usalp->silent--; + + return (drive_getdisktype(usalp, dp)); +} + +static BOOL +capacity_philips(SCSI *usalp, long *lp) +{ + long l = 0L; + BOOL succeed = TRUE; + + usalp->silent++; + if (read_B0(usalp, FALSE, NULL, &l) >= 0) { + if (debug) + printf("lead out B0: %ld\n", l); + *lp = l; + } else if (read_trackinfo(usalp, 0xAA, &l, NULL, NULL, NULL, NULL) >= 0) { + if (debug) + printf("lead out AA: %ld\n", l); + *lp = l; + } if (read_capacity(usalp) >= 0) { + l = usalp->cap->c_baddr + 1; + if (debug) + printf("lead out capacity: %ld\n", l); + } else { + succeed = FALSE; + } + *lp = l; + usalp->silent--; + return (succeed); +} + +struct fwa { + char len; + char addr[4]; + char res; +}; + +static int +first_writable_addr_philips(SCSI *usalp, long *ap, int track, int isaudio, + int preemp, int npa) +{ + struct fwa fwa; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)&fwa, sizeof (fwa), '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)&fwa; + scmd->size = sizeof (fwa); + 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 = 0xE2; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = track; + scmd->cdb.g1_cdb.addr[1] = isaudio ? (preemp ? 5 : 4) : 1; + + scmd->cdb.g1_cdb.count[0] = npa?1:0; + scmd->cdb.g1_cdb.count[1] = sizeof (fwa); + + usalp->cmdname = "first writeable address philips"; + + if (usal_cmd(usalp) < 0) + return (-1); + + if (ap) + *ap = a_to_4_byte(fwa.addr); + return (0); +} + +static int +next_wr_addr_philips(SCSI *usalp, track_t *trackp, long *ap) +{ + +/* if (first_writable_addr_philips(usalp, ap, 0, 0, 0, 1) < 0)*/ + if (first_writable_addr_philips(usalp, ap, 0, 0, 0, 0) < 0) + return (-1); + return (0); +} + +static int +reserve_track_philips(SCSI *usalp, unsigned long len) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE4; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], len); + + usalp->cmdname = "philips reserve_track"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +scsi_cdr_write_philips(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + return (write_xg0(usalp, bp, 0, size, blocks)); +} + +static int +write_track_info_philips(SCSI *usalp, int sectype) +{ + struct cdd_52x_mode_data md; + int count = sizeof (struct scsi_mode_header) + + sizeof (struct cdd_52x_mode_page_21); + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + md.pagex.page21.p_code = 0x21; + md.pagex.page21.p_len = 0x0E; + /* is sectype ok ??? */ + md.pagex.page21.sectype = sectype & ST_MASK; + md.pagex.page21.track = 0; /* 0 : create new track */ + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +static int +write_track_philips(SCSI *usalp, + long track /* track number 0 == new track */, + int sectype) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; +/* scmd->flags = SCG_DISRE_ENA;*/ + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE6; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, track); + scmd->cdb.g1_cdb.res6 = sectype & ST_MASK; + + usalp->cmdname = "philips write_track"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +open_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (select_secsize(usalp, trackp->secsize) < 0) + return (-1); + + if (write_track_info_philips(usalp, trackp->sectype) < 0) + return (-1); + + if (write_track_philips(usalp, 0, trackp->sectype) < 0) + return (-1); + + return (0); +} + +static int +open_track_plasmon(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (select_secsize(usalp, trackp->secsize) < 0) + return (-1); + + if (write_track_info_philips(usalp, trackp->sectype) < 0) + return (-1); + + return (0); +} + +static int +open_track_oldphilips(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (write_track_philips(usalp, 0, trackp->sectype) < 0) + return (-1); + + return (0); +} + +static int +open_track_yamaha(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (select_secsize(usalp, trackp->secsize) < 0) + return (-1); + + if (write_track_philips(usalp, 0, trackp->sectype) < 0) + return (-1); + + return (0); +} + +static int +close_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + return (scsi_flush_cache(usalp, FALSE)); +} + +static int fixation_philips(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 8 * 60; /* Needs up to 4 minutes */ + scmd->cdb.g1_cdb.cmd = 0xE9; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.count[1] = + ((track_base(trackp)->tracktype & TOCF_MULTI) ? 8 : 0) | + (track_base(trackp)->tracktype & TOC_MASK); + + usalp->cmdname = "philips fixation"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static const char *sd_cdd_521_error_str[] = { + "\003\000tray out", /* 0x03 */ + "\062\000write data error with CU", /* 0x32 */ /* Yamaha */ + "\063\000monitor atip error", /* 0x33 */ + "\064\000absorbtion control error", /* 0x34 */ +#ifdef YAMAHA_CDR_100 + /* Is this the same ??? */ + "\120\000write operation in progress", /* 0x50 */ +#endif + "\127\000unable to read TOC/PMA/Subcode/ATIP", /* 0x57 */ + "\132\000operator medium removal request", /* 0x5a */ + "\145\000verify failed", /* 0x65 */ + "\201\000illegal track number", /* 0x81 */ + "\202\000command now not valid", /* 0x82 */ + "\203\000medium removal is prevented", /* 0x83 */ + "\204\000tray out", /* 0x84 */ + "\205\000track at one not in PMA", /* 0x85 */ + "\240\000stopped on non data block", /* 0xa0 */ + "\241\000invalid start adress", /* 0xa1 */ + "\242\000attampt to cross track-boundary", /* 0xa2 */ + "\243\000illegal medium", /* 0xa3 */ + "\244\000disk write protected", /* 0xa4 */ + "\245\000application code conflict", /* 0xa5 */ + "\246\000illegal blocksize for command", /* 0xa6 */ + "\247\000blocksize conflict", /* 0xa7 */ + "\250\000illegal transfer length", /* 0xa8 */ + "\251\000request for fixation failed", /* 0xa9 */ + "\252\000end of medium reached", /* 0xaa */ +#ifdef REAL_CDD_521 + "\253\000non reserved reserved track", /* 0xab */ +#else + "\253\000illegal track number", /* 0xab */ +#endif + "\254\000data track length error", /* 0xac */ + "\255\000buffer under run", /* 0xad */ + "\256\000illegal track mode", /* 0xae */ + "\257\000optical power calibration error", /* 0xaf */ + "\260\000calibration area almost full", /* 0xb0 */ + "\261\000current program area empty", /* 0xb1 */ + "\262\000no efm at search address", /* 0xb2 */ + "\263\000link area encountered", /* 0xb3 */ + "\264\000calibration area full", /* 0xb4 */ + "\265\000dummy data blocks added", /* 0xb5 */ + "\266\000block size format conflict", /* 0xb6 */ + "\267\000current command aborted", /* 0xb7 */ + "\270\000program area not empty", /* 0xb8 */ +#ifdef YAMAHA_CDR_100 + /* Used while writing lead in in DAO */ + "\270\000write leadin in progress", /* 0xb8 */ +#endif + "\271\000parameter list too large", /* 0xb9 */ + "\277\000buffer overflow", /* 0xbf */ /* Yamaha */ + "\300\000no barcode available", /* 0xc0 */ + "\301\000barcode reading error", /* 0xc1 */ + "\320\000recovery needed", /* 0xd0 */ + "\321\000cannot recover track", /* 0xd1 */ + "\322\000cannot recover pma", /* 0xd2 */ + "\323\000cannot recover leadin", /* 0xd3 */ + "\324\000cannot recover leadout", /* 0xd4 */ + "\325\000cannot recover opc", /* 0xd5 */ + "\326\000eeprom failure", /* 0xd6 */ + "\340\000laser current over", /* 0xe0 */ /* Yamaha */ + "\341\000servo adjustment over", /* 0xe0 */ /* Yamaha */ + NULL +}; + +static const char *sd_ro1420_error_str[] = { + "\004\000logical unit is in process of becoming ready", /* 04 00 */ + "\011\200radial skating error", /* 09 80 */ + "\011\201sledge servo failure", /* 09 81 */ + "\011\202pll no lock", /* 09 82 */ + "\011\203servo off track", /* 09 83 */ + "\011\204atip sync error", /* 09 84 */ + "\011\205atip/subcode jumped error", /* 09 85 */ + "\127\300subcode not found", /* 57 C0 */ + "\127\301atip not found", /* 57 C1 */ + "\127\302no atip or subcode", /* 57 C2 */ + "\127\303pma error", /* 57 C3 */ + "\127\304toc read error", /* 57 C4 */ + "\127\305disk informatoion error", /* 57 C5 */ + "\144\200read in leadin", /* 64 80 */ + "\144\201read in leadout", /* 64 81 */ + "\201\000illegal track", /* 81 00 */ + "\202\000command not now valid", /* 82 00 */ + "\220\000reserve track check error", /* 90 00 */ + "\220\001verify blank error", /* 90 01 */ + "\221\001mode of last track error", /* 91 01 */ + "\222\000header search error", /* 92 00 */ + "\230\001header monitor error", /* 98 01 */ + "\230\002edc error", /* 98 02 */ + "\230\003read link, run-in run-out", /* 98 03 */ + "\230\004last one block error", /* 98 04 */ + "\230\005illegal blocksize", /* 98 05 */ + "\230\006not all data transferred", /* 98 06 */ + "\230\007cdbd over run error", /* 98 07 */ + "\240\000stopped on non_data block", /* A0 00 */ + "\241\000invalid start address", /* A1 00 */ + "\243\000illegal medium", /* A3 00 */ + "\246\000illegal blocksize for command", /* A6 00 */ + "\251\000request for fixation failed", /* A9 00 */ + "\252\000end of medium reached", /* AA 00 */ + "\253\000illegal track number", /* AB 00 */ + "\255\000buffer underrun", /* AD 00 */ + "\256\000illegal track mode", /* AE 00 */ + "\257\200power range error", /* AF 80 */ + "\257\201moderation error", /* AF 81 */ + "\257\202beta upper range error", /* AF 82 */ + "\257\203beta lower range error", /* AF 83 */ + "\257\204alpha upper range error", /* AF 84 */ + "\257\205alpha lower range error", /* AF 85 */ + "\257\206alpha and power range error", /* AF 86 */ + "\260\000calibration area almost full", /* B0 00 */ + "\261\000current program area empty", /* B1 00 */ + "\262\000no efm at search address", /* B2 00 */ + "\264\000calibration area full", /* B4 00 */ + "\265\000dummy blocks added", /* B5 00 */ + "\272\000write audio on reserved track", /* BA 00 */ + "\302\200syscon rom error", /* C2 80 */ + "\302\201syscon ram error", /* C2 81 */ + "\302\220efm encoder error", /* C2 90 */ + "\302\221efm decoder error", /* C2 91 */ + "\302\222servo ic error", /* C2 92 */ + "\302\223motor controller error", /* C2 93 */ + "\302\224dac error", /* C2 94 */ + "\302\225syscon eeprom error", /* C2 95 */ + "\302\240block decoder communication error", /* C2 A0 */ + "\302\241block encoder communication error", /* C2 A1 */ + "\302\242block encoder/decoder path error", /* C2 A2 */ + "\303\000CD-R engine selftest error", /* C3 xx */ + "\304\000buffer parity error", /* C4 00 */ + "\305\000data transfer error", /* C5 00 */ + "\340\00012V failure", /* E0 00 */ + "\341\000undefined syscon error", /* E1 00 */ + "\341\001syscon communication error", /* E1 01 */ + "\341\002unknown syscon error", /* E1 02 */ + "\342\000syscon not ready", /* E2 00 */ + "\343\000command rejected", /* E3 00 */ + "\344\000command not accepted", /* E4 00 */ + "\345\000verify error at beginning of track", /* E5 00 */ + "\345\001verify error at ending of track", /* E5 01 */ + "\345\002verify error at beginning of lead-in", /* E5 02 */ + "\345\003verify error at ending of lead-in", /* E5 03 */ + "\345\004verify error at beginning of lead-out", /* E5 04 */ + "\345\005verify error at ending of lead-out", /* E5 05 */ + "\377\000command phase timeout error", /* FF 00 */ + "\377\001data in phase timeout error", /* FF 01 */ + "\377\002data out phase timeout error", /* FF 02 */ + "\377\003status phase timeout error", /* FF 03 */ + "\377\004message in phase timeout error", /* FF 04 */ + "\377\005message out phase timeout error", /* FF 05 */ + NULL +}; + +static int +philips_attach(SCSI *usalp, cdr_t *dp) +{ + usal_setnonstderrs(usalp, sd_cdd_521_error_str); + return (0); +} + +static int +plasmon_attach(SCSI *usalp, cdr_t *dp) +{ + usalp->inq->data_format = 1; /* Correct the ly */ + + usal_setnonstderrs(usalp, sd_cdd_521_error_str); + return (0); +} + +static int +ricoh_attach(SCSI *usalp, cdr_t *dp) +{ + if (dp == &cdr_ricoh_ro1060) { + errmsgno(EX_BAD, "No support for Ricoh RO-1060C\n"); + return (-1); + } + usal_setnonstderrs(usalp, sd_ro1420_error_str); + return (0); +} + +static int +philips_getlilo(SCSI *usalp, long *lilenp, long *lolenp) +{ + char buf[4]; + long li, lo; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = buf; + scmd->size = sizeof (buf); + 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 = 0xEE; /* Read session info */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, sizeof (buf)); + + usalp->cmdname = "philips read session info"; + + if (usal_cmd(usalp) < 0) + return (-1); + + if (usalp->verbose) + usal_prbytes("Session info data: ", (Uchar *)buf, sizeof (buf) - usal_getresid(usalp)); + + li = a_to_u_2_byte(buf); + lo = a_to_u_2_byte(&buf[2]); + + if (lilenp) + *lilenp = li; + if (lolenp) + *lolenp = lo; + + return (0); +} diff --git a/wodim/drv_simul.c b/wodim/drv_simul.c new file mode 100644 index 0000000..f7f7e06 --- /dev/null +++ b/wodim/drv_simul.c @@ -0,0 +1,393 @@ +/* + * 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. + * + */ + +/* @(#)drv_simul.c 1.48 05/05/16 Copyright 1998-2005 J. Schilling */ +/* + * Simulation device driver + * + * Copyright (c) 1998-2005 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. + */ + +#ifndef DEBUG +#define DEBUG +#endif +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> +#include <utypes.h> +#include <btorder.h> +#include <schily.h> + +/*#include <usalio.h>*/ +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include <libport.h> + +#include "wodim.h" + +extern int silent; +extern int verbose; +extern int lverbose; + +static int simul_load(SCSI *usalp, cdr_t *); +static int simul_unload(SCSI *usalp, cdr_t *); +static cdr_t *identify_simul(SCSI *usalp, cdr_t *, struct scsi_inquiry *); +static int init_simul(SCSI *usalp, cdr_t *dp); +static int getdisktype_simul(SCSI *usalp, cdr_t *dp); +static int speed_select_simul(SCSI *usalp, cdr_t *dp, int *speedp); +static int next_wr_addr_simul(SCSI *usalp, track_t *trackp, long *ap); +static int cdr_write_simul(SCSI *usalp, caddr_t bp, long sectaddr, long size, + int blocks, BOOL islast); +static int open_track_simul(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int close_track_simul(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_session_simul(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int fixate_simul(SCSI *usalp, cdr_t *dp, track_t *trackp); +static void tv_sub(struct timeval *tvp1, struct timeval *tvp2); + +static int simul_load(SCSI *usalp, cdr_t *dp) +{ + return (0); +} + +static int simul_unload(SCSI *usalp, cdr_t *dp) +{ + return (0); +} + +cdr_t cdr_cdr_simul = { + 0, 0, + CDR_TAO|CDR_SAO|CDR_PACKET|CDR_RAW|CDR_RAW16|CDR_RAW96P|CDR_RAW96R|CDR_SRAW96P|CDR_SRAW96R|CDR_TRAYLOAD|CDR_SIMUL, + CDR_CDRW_ALL, + 40, 372, + "cdr_simul", + "simulation CD-R driver for timing/speed tests", + 0, + (dstat_t *)0, + identify_simul, + drive_attach, + init_simul, + getdisktype_simul, + simul_load, + simul_unload, + buf_dummy, + cmd_dummy, /* recovery_needed */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_simul, + select_secsize, + next_wr_addr_simul, + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + cdr_write_simul, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* send_cue */ + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_simul, + close_track_simul, + open_session_simul, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + fixate_simul, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +cdr_t cdr_dvd_simul = { + 0, 0, + CDR_TAO|CDR_SAO|CDR_PACKET|CDR_RAW|CDR_RAW16|CDR_RAW96P|CDR_RAW96R|CDR_SRAW96P|CDR_SRAW96R|CDR_DVD|CDR_TRAYLOAD|CDR_SIMUL, + CDR_CDRW_ALL, + 2, 1000, + "dvd_simul", + "simulation DVD-R driver for timing/speed tests", + 0, + (dstat_t *)0, + identify_simul, + drive_attach, + init_simul, + getdisktype_simul, + simul_load, + simul_unload, + buf_dummy, + cmd_dummy, /* recovery_needed */ + (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */ + speed_select_simul, + select_secsize, + next_wr_addr_simul, + (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */ + cdr_write_simul, + (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */ + (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* send_cue */ + (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */ + open_track_simul, + close_track_simul, + open_session_simul, + cmd_dummy, + cmd_dummy, /* abort */ + read_session_offset, + fixate_simul, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +static cdr_t * +identify_simul(SCSI *usalp, cdr_t *dp, struct scsi_inquiry *ip) +{ + return (dp); +} + +static long simul_nwa; +static int simul_speed = 1; +static int simul_dummy; +static int simul_isdvd; +static int simul_bufsize = 1024; +static Uint sleep_rest; +static Uint sleep_max; +static Uint sleep_min; + +static int +init_simul(SCSI *usalp, cdr_t *dp) +{ + return (speed_select_simul(usalp, dp, NULL)); +} + +static int +getdisktype_simul(SCSI *usalp, cdr_t *dp) +{ + dstat_t *dsp = dp->cdr_dstat; + + if (strcmp(dp->cdr_drname, cdr_cdr_simul.cdr_drname) == 0) { + dsp->ds_maxblocks = 333000; + simul_isdvd = FALSE; + } else { + dsp->ds_maxblocks = 2464153; /* 4.7 GB */ +/* dsp->ds_maxblocks = 1927896;*/ /* 3.95 GB */ + dsp->ds_flags |= DSF_DVD; + simul_isdvd = TRUE; + } + return (drive_getdisktype(usalp, dp)); +} + + +static int +speed_select_simul(SCSI *usalp, cdr_t *dp, int *speedp) +{ + long val; + char *p; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) + simul_speed = *speedp; + simul_dummy = dummy; + + if ((p = getenv("CDR_SIMUL_BUFSIZE")) != NULL) { + if (getnum(p, &val) == 1) + simul_bufsize = val / 1024; + } + + /* + * sleep_max is the time to empty the drive's buffer in µs. + * sector size is from 2048 bytes to 2352 bytes. + * If sector size is 2048 bytes, 1k takes 6.666 ms. + * If sector size is 2352 bytes, 1k takes 5.805 ms. + * We take the 6 ms as an average between both values. + * simul_bufsize is the number of kilobytes in drive buffer. + */ + sleep_max = 6 * 1000 * simul_bufsize / simul_speed; + + /* + * DVD single speed is 1385 * 1000 Bytes/s (676.27 sectors/s) + */ + if ((dp->cdr_flags & CDR_DVD) != 0) + sleep_max = 739 * simul_bufsize / simul_speed; + + if (lverbose) { + printf("Simulation drive buffer size: %d KB\n", simul_bufsize); + printf("Maximum reserve time in drive buffer: %d.%3.3d ms for speed %dx\n", + sleep_max / 1000, + sleep_max % 1000, + simul_speed); + } + return (0); +} + +static int +next_wr_addr_simul(SCSI *usalp, track_t *trackp, long *ap) +{ + /* + * This will most likely not 100% correct for TAO CDs + * but it is better than returning 0 in all cases. + */ + if (ap) + *ap = simul_nwa; + return (0); +} + + +static int +cdr_write_simul(SCSI *usalp, caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + Uint sleep_time; + Uint sleep_diff; + + struct timeval tv1; + static struct timeval tv2; + + if (lverbose > 1 && islast) + printf("\nWriting last record for this track.\n"); + + simul_nwa += blocks; + + gettimeofday(&tv1, (struct timezone *)0); + if (tv2.tv_sec != 0) { /* Already did gettimeofday(&tv2) */ + tv_sub(&tv1, &tv2); + if (sleep_rest != 0) { + sleep_diff = tv1.tv_sec * 1000000 + tv1.tv_usec; + + if (sleep_min > (sleep_rest - sleep_diff)) + sleep_min = (sleep_rest - sleep_diff); + + if (sleep_diff > sleep_rest) { + printf("Buffer underrun: actual delay was %d.%3.3d ms, max delay was %d.%3.3d ms.\n", + sleep_diff / 1000, + sleep_diff % 1000, + sleep_rest / 1000, + sleep_rest % 1000); + if (!simul_dummy) + return (-1); + } + /* + * If we spent time outside the write function + * subtract this time. + */ + sleep_diff = tv1.tv_sec * 1000000 + tv1.tv_usec; + if (sleep_rest >= sleep_diff) + sleep_rest -= sleep_diff; + else + sleep_rest = 0; + } + } + /* + * Speed 1 ist 150 Sektoren/s + * Bei DVD 767.27 Sektoren/s + */ + sleep_time = 1000000 * blocks / 75 / simul_speed; + if (simul_isdvd) + sleep_time = 1000000 * blocks / 676 / simul_speed; + + sleep_time += sleep_rest; + + if (sleep_time > sleep_max) { + int mod; + long rsleep; + + sleep_rest = sleep_max; + sleep_time -= sleep_rest; + mod = sleep_time % 20000; + sleep_rest += mod; + sleep_time -= mod; + if (sleep_time > 0) { + gettimeofday(&tv1, (struct timezone *)0); + usleep(sleep_time); + gettimeofday(&tv2, (struct timezone *)0); + tv2.tv_sec -= tv1.tv_sec; + tv2.tv_usec -= tv1.tv_usec; + rsleep = tv2.tv_sec * 1000000 + tv2.tv_usec; + sleep_rest -= rsleep - sleep_time; + } + } else { + sleep_rest = sleep_time; + } + + gettimeofday(&tv2, (struct timezone *)0); + return (size); +} + +static int +open_track_simul(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + sleep_min = 999 * 1000000; + return (0); +} + +static int +close_track_simul(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (lverbose) { + printf("Remaining reserve time in drive buffer: %d.%3.3d ms\n", + sleep_rest / 1000, + sleep_rest % 1000); + printf("Minimum reserve time in drive buffer: %d.%3.3d ms\n", + sleep_min / 1000, + sleep_min % 1000); + } + usleep(sleep_rest); + sleep_rest = 0; + return (0); +} + +static int +open_session_simul(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + simul_nwa = 0L; + return (0); +} + +static int +fixate_simul(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + return (0); +} + +static void +tv_sub(struct timeval *tvp1, struct timeval *tvp2) +{ + tvp1->tv_sec -= tvp2->tv_sec; + tvp1->tv_usec -= tvp2->tv_usec; + + while (tvp1->tv_usec < 0) { + tvp1->tv_usec += 1000000; + tvp1->tv_sec -= 1; + } +} diff --git a/wodim/drv_sony.c b/wodim/drv_sony.c new file mode 100644 index 0000000..af8af68 --- /dev/null +++ b/wodim/drv_sony.c @@ -0,0 +1,1364 @@ +/* + * 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. + * + */ + +/* @(#)drv_sony.c 1.72 05/05/16 Copyright 1997-2005 J. Schilling */ +/* + * CDR device implementation for + * Sony + * + * Copyright (c) 1997-2005 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. + */ + +/*#define SONY_DEBUG*/ + +#include <mconfig.h> + +#include <stdio.h> +#include <stdxlib.h> +#include <unixstd.h> /* Include sys/types.h to make off_t available */ +#include <standard.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "wodim.h" + +#ifdef SONY_DEBUG +# define inc_verbose() usalp->verbose++ +# define dec_verbose() usalp->verbose-- +#else +# define inc_verbose() +# define dec_verbose() +#endif + +extern int debug; +extern int lverbose; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + +struct sony_924_mode_page_20 { /* mastering information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 6 Bytes */ + Uchar subcode_header_off; + Ucbit res3_0 : 1; + Ucbit speudo : 1; + Ucbit res3_2 : 1; + Ucbit c2po : 1; + Ucbit subcode_ecc : 1; + Ucbit res3_567 : 3; + Uchar res_4; + Uchar cue_sheet_opt; + Uchar res[2]; +}; + +#else /* Motorola byteorder */ + +struct sony_924_mode_page_20 { /* mastering information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x06 = 6 Bytes */ + Uchar subcode_header_off; + Ucbit res3_567 : 3; + Ucbit subcode_ecc : 1; + Ucbit c2po : 1; + Ucbit res3_2 : 1; + Ucbit speudo : 1; + Ucbit res3_0 : 1; + Uchar res_4; + Uchar cue_sheet_opt; + Uchar res[2]; +}; +#endif + +struct sony_924_mode_page_22 { /* disk information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x1E = 30 Bytes */ + Uchar disk_style; + Uchar disk_type; + Uchar first_track; + Uchar last_track; + Uchar numsess; + Uchar res_7; + Uchar disk_appl_code[4]; + Uchar last_start_time[4]; + Uchar disk_status; + Uchar num_valid_nra; + Uchar track_info_track; + Uchar post_gap; + Uchar disk_id_code[4]; + Uchar lead_in_start[4]; + Uchar res[4]; +}; + +struct sony_924_mode_page_23 { /* track information */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x22 = 34 Bytes */ + Uchar res_2; + Uchar track_num; + Uchar data_form; + Uchar write_method; + Uchar session; + Uchar track_status; + Uchar start_lba[4]; + Uchar next_recordable_addr[4]; + Uchar blank_area_cap[4]; + Uchar fixed_packet_size[4]; + Uchar res_24; + Uchar starting_msf[3]; + Uchar res_28; + Uchar ending_msf[3]; + Uchar res_32; + Uchar next_rec_time[3]; +}; + +struct sony_924_mode_page_31 { /* drive speed */ + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0x02 = 2 Bytes */ + Uchar speed; + Uchar res; +}; + +struct cdd_52x_mode_data { + struct scsi_mode_header header; + union cdd_pagex { + struct sony_924_mode_page_20 page_s20; + struct sony_924_mode_page_22 page_s22; + struct sony_924_mode_page_23 page_s23; + struct sony_924_mode_page_31 page_s31; + } pagex; +}; + +struct sony_write_parameter { + Uchar res0; /* Reserved (must be zero) */ + Uchar len; /* Parameter length 0x32 == 52 */ + Uchar res2; /* Reserved (must be zero) */ +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + Ucbit res3_05 : 6; /* Reserved */ + Ucbit ms : 2; /* Multi session mode */ +#else /* Motorola byteorder */ + Ucbit ms : 2; /* Multi session mode */ + Ucbit res3_05 : 6; /* Reserved */ +#endif + Uchar resx[12]; +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + Ucbit res16_06 : 7; /* Reserved */ + Ucbit mcval : 1; /* MCN valid */ +#else /* Motorola byteorder */ + Ucbit mcval : 1; /* MCN valid */ + Ucbit res16_06 : 7; /* Reserved */ +#endif + Uchar mcn[15]; +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + Ucbit res32_06 : 7; /* Reserved */ + Ucbit icval : 1; /* ISRC valid */ +#else /* Motorola byteorder */ + Ucbit icval : 1; /* ISRC valid */ + Ucbit res32_06 : 7; /* Reserved */ +#endif + Uchar isrc[15]; + Uchar subheader[4]; +}; + +struct sony_cue { + Uchar cs_ctladr; /* CTL/ADR for this track */ + Uchar cs_tno; /* This track number */ + Uchar cs_index; /* Index within this track */ + Uchar cs_dataform; /* Data form */ + /* Bit 0..5 Main channel Format */ + /* Bit 6..7 SubChannel format */ + Uchar cs_zero; /* Reserved or MCN/ISRC */ + Uchar cs_min; /* Absolute time minutes */ + Uchar cs_sec; /* Absolute time seconds */ + Uchar cs_frame; /* Absolute time frames */ +}; + + +#define strbeg(s1, s2) (strstr((s2), (s1)) == (s2)) + +static int write_start_sony(SCSI *usalp, caddr_t bp, int size); +static int write_continue_sony(SCSI *usalp, caddr_t bp, long sectaddr, + long size, int blocks, BOOL islast); +static int discontinue_sony(SCSI *usalp); +static int write_track_sony(SCSI *usalp, long track, int sectype); +static int close_track_sony(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int flush_sony(SCSI *usalp, int track); +static int finalize_sony(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int recover_sony(SCSI *usalp, cdr_t *dp, int track); +static int set_wr_parameter_sony(SCSI *usalp, caddr_t bp, int size); +static int next_wr_addr_sony(SCSI *usalp, track_t *trackp, long *ap); +static int reserve_track_sony(SCSI *usalp, unsigned long len); +static int init_sony(SCSI *usalp, cdr_t *dp); +static int getdisktype_sony(SCSI *usalp, cdr_t *dp); +static void di_to_dstat_sony(struct sony_924_mode_page_22 *dip, + dstat_t *dsp); +static int speed_select_sony(SCSI *usalp, cdr_t *dp, int *speedp); +static int next_writable_address_sony(SCSI *usalp, long *ap, int track, + int sectype, int tracktype); +static int new_track_sony(SCSI *usalp, int track, int sectype, + int tracktype); +static int open_track_sony(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int open_session_sony(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int abort_session_sony(SCSI *usalp, cdr_t *dp); +static int get_page22_sony(SCSI *usalp, char *mode); +static int gen_cue_sony(track_t *trackp, void *vcuep, BOOL needgap); +static void fillcue(struct sony_cue *cp, int ca, int tno, int idx, int dataform, int scms, msf_t *mp); +static int send_cue_sony(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int write_leadin_sony(SCSI *usalp, cdr_t *dp, track_t *trackp); +static int sony_attach(SCSI *usalp, cdr_t *dp); +#ifdef SONY_DEBUG +static void print_sony_mp22(struct sony_924_mode_page_22 *xp, int len); +static void print_sony_mp23(struct sony_924_mode_page_23 *xp, int len); +#endif +static int buf_cap_sony(SCSI *usalp, long *, long *); + +cdr_t cdr_sony_cdu924 = { + 0, 0, + CDR_TAO|CDR_SAO|CDR_CADDYLOAD|CDR_SWABAUDIO, + CDR_CDRW_NONE, + 2, 4, + "sony_cdu924", + "driver for Sony CDU-924 / CDU-948", + 0, + (dstat_t *)0, + drive_identify, + sony_attach, + init_sony, + getdisktype_sony, + scsi_load, + scsi_unload, + buf_cap_sony, + cmd_dummy, /* recovery_needed */ + recover_sony, + speed_select_sony, + select_secsize, + next_wr_addr_sony, + reserve_track_sony, + write_continue_sony, + gen_cue_sony, + send_cue_sony, + write_leadin_sony, + open_track_sony, + close_track_sony, + open_session_sony, + cmd_dummy, + abort_session_sony, + read_session_offset_philips, + finalize_sony, + cmd_dummy, /* stats */ + blank_dummy, + format_dummy, + (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */ + cmd_dummy, /* opt1 */ + cmd_dummy, /* opt2 */ +}; + +static int +write_start_sony(SCSI *usalp, caddr_t bp, int size) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->sense_len = 26; + scmd->cdb.g1_cdb.cmd = 0xE0; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g0_cdbaddr(&scmd->cdb.g0_cdb, size); /* Hack, but Sony is silly */ + + usalp->cmdname = "write_start"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +write_continue_sony(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE1; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g0_cdbaddr(&scmd->cdb.g0_cdb, size); /* Hack, but Sony is silly */ + + usalp->cmdname = "write_continue"; + + if (usal_cmd(usalp) < 0) { + /* + * XXX This seems to happen only sometimes. + */ + if (usal_sense_code(usalp) != 0x80) + return (-1); + } + return (size - usal_getresid(usalp)); +} + +static int +discontinue_sony(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xE2; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "discontinue"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +write_track_sony(SCSI *usalp, + long track /* track number 0 == new track */, + int sectype /* no sectype for Sony write track */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xF5; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, track); + + usalp->cmdname = "write_track"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +/* XXX NOCH NICHT FERTIG */ +static int +close_track_sony(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + register struct usal_cmd *scmd = usalp->scmd; + int track = 0; + + if (!is_tao(trackp) && !is_packet(trackp)) + return (0); + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xF0; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, track); +/* XXX Padding ??? (bit 0 in addr[0] / CDB[2]) */ + + usalp->cmdname = "close_track"; + + if (usal_cmd(usalp) < 0) + return (-1); + + /* + * Clear the silly "error situation" from Sony´ dummy write end + * but notify if real errors occurred. + */ + usalp->silent++; + if (test_unit_ready(usalp) < 0 && usal_sense_code(usalp) != 0xD4) { + usalp->cmdname = "close_track/test_unit_ready"; + usal_printerr(usalp); + } + usalp->silent--; + + return (0); +} + +static int +finalize_sony(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + register struct usal_cmd *scmd = usalp->scmd; + int dummy = track_base(trackp)->tracktype & TOCF_DUMMY; + + if (!is_tao(trackp) && !is_packet(trackp)) { + wait_unit_ready(usalp, 240); + return (0); + } + if (dummy) { + printf("Fixating is not possible in dummy write mode.\n"); + return (0); + } + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 8 * 60; /* Needs up to 4 minutes */ + scmd->cdb.g1_cdb.cmd = 0xF1; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.count[1] = ((track_base(trackp)->tracktype & TOCF_MULTI) ? 1 : 0); +/* XXX Padding ??? (bit 0 in addr[0] / CDB[2]) */ + + usalp->cmdname = "finalize"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +flush_sony(SCSI *usalp, int track) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 8 * 60; /* Needs up to 4 minutes */ + scmd->cdb.g1_cdb.cmd = 0xF2; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[5] = track; +/* XXX POE ??? (bit 1 in addr[0] / CDB[2]) */ +/* XXX Padding ??? (bit 0 in addr[0] / CDB[2]) */ +/* XXX Partial flush ??? (CDB[3]) */ + + usalp->cmdname = "flush"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +recover_sony(SCSI *usalp, cdr_t *dp, int track) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xF6; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[3] = track; + + usalp->cmdname = "recover"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +set_wr_parameter_sony(SCSI *usalp, caddr_t bp, int size) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xF8; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, size); + + usalp->cmdname = "set_write_parameter"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +next_wr_addr_sony(SCSI *usalp, track_t *trackp, long *ap) +{ + if (next_writable_address_sony(usalp, ap, 0, 0, 0) < 0) + return (-1); + return (0); +} + +static int +reserve_track_sony(SCSI *usalp, unsigned long len) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0xF3; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], len); + + usalp->cmdname = "reserve_track"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +static int +init_sony(SCSI *usalp, cdr_t *dp) +{ + return (speed_select_sony(usalp, dp, NULL)); +} + + +#define IS(what, flag) printf(" Is %s%s\n", flag?"":"not ", what); + +static int +getdisktype_sony(SCSI *usalp, cdr_t *dp) +{ + dstat_t *dsp = dp->cdr_dstat; + long dummy; + long lst; + msf_t msf; + + char mode[256]; + struct scsi_mode_page_header *mp; + struct sony_924_mode_page_22 *xp; + + dummy = get_page22_sony(usalp, mode); + if (dummy >= 0) { + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp = (struct sony_924_mode_page_22 *)mp; + + if (xp->disk_appl_code[0] == 0xFF) + dummy = -1; + } else { + return (drive_getdisktype(usalp, dp)); + } + + if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && dummy >= 0) { + + printf("ATIP info from disk:\n"); + printf(" Indicated writing power: %d\n", + (unsigned)(xp->disk_appl_code[1] & 0x70) >> 4); + IS("unrestricted", xp->disk_appl_code[2] & 0x40); + printf(" Disk application code: %d\n", xp->disk_appl_code[2] & 0x3F); + msf.msf_min = xp->lead_in_start[1]; + msf.msf_sec = xp->lead_in_start[2]; + msf.msf_frame = xp->lead_in_start[3]; + lst = msf_to_lba(msf.msf_min, msf.msf_sec, msf.msf_frame, FALSE); + if (lst < -150) { + /* + * The Sony CDU 920 seems to deliver 00:00/00 for + * lead-in start time, dont use it. + */ + printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n", + msf_to_lba(msf.msf_min, msf.msf_sec, msf.msf_frame, FALSE), + msf.msf_min, msf.msf_sec, msf.msf_frame); + } + msf.msf_min = xp->last_start_time[1]; + msf.msf_sec = xp->last_start_time[2]; + msf.msf_frame = xp->last_start_time[3]; + printf(" ATIP start of lead out: %ld (%02d:%02d/%02d)\n", + msf_to_lba(msf.msf_min, msf.msf_sec, msf.msf_frame, TRUE), + msf.msf_min, msf.msf_sec, msf.msf_frame); + if (lst < -150) { + /* + * The Sony CDU 920 seems to deliver 00:00/00 for + * lead-in start time, dont use it. + */ + msf.msf_min = xp->lead_in_start[1]; + msf.msf_sec = xp->lead_in_start[2]; + msf.msf_frame = xp->lead_in_start[3]; + pr_manufacturer(&msf, + FALSE, /* Always not erasable */ + (xp->disk_appl_code[2] & 0x40) != 0); + } + } + if (dummy >= 0) + di_to_dstat_sony(xp, dsp); + return (drive_getdisktype(usalp, dp)); +} + +static void +di_to_dstat_sony(struct sony_924_mode_page_22 *dip, dstat_t *dsp) +{ + msf_t msf; + + dsp->ds_diskid = a_to_u_4_byte(dip->disk_id_code); +#ifdef PROTOTYPES + if (dsp->ds_diskid != 0xFFFFFFFFUL) +#else + if (dsp->ds_diskid != (Ulong)0xFFFFFFFF) +#endif + dsp->ds_flags |= DSF_DID_V; + dsp->ds_diskstat = (dip->disk_status >> 6) & 0x03; +#ifdef XXX + /* + * There seems to be no MMC equivalent... + */ + dsp->ds_sessstat = dip->sess_status; +#endif + + dsp->ds_maxblocks = msf_to_lba(dip->last_start_time[1], + dip->last_start_time[2], + dip->last_start_time[3], TRUE); + /* + * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk + */ + if (dsp->ds_maxblocks == 716730) + dsp->ds_maxblocks = -1L; + + if (dsp->ds_first_leadin == 0) { + dsp->ds_first_leadin = msf_to_lba(dip->lead_in_start[1], + dip->lead_in_start[2], + dip->lead_in_start[3], FALSE); + /* + * Check for illegal values (> 0) + * or for empty field (-150) with CDU-920. + */ + if (dsp->ds_first_leadin > 0 || dsp->ds_first_leadin == -150) + dsp->ds_first_leadin = 0; + } + + if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0) + dsp->ds_last_leadout = dsp->ds_maxblocks; + + msf.msf_min = dip->lead_in_start[1]; + msf.msf_sec = dip->lead_in_start[2]; + msf.msf_frame = dip->lead_in_start[3]; + dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks, + FALSE, /* Always not erasable */ + (dip->disk_appl_code[2] & 0x40) != 0); +} + + +int sony_speeds[] = { + -1, /* Speed null is not allowed */ + 0, /* Single speed */ + 1, /* Double speed */ + -1, /* Three times */ + 3, /* Quad speed */ +}; + +static int +speed_select_sony(SCSI *usalp, cdr_t *dp, int *speedp) +{ + struct cdd_52x_mode_data md; + int count; + int err; + int speed = 1; + BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0; + + if (speedp) { + speed = *speedp; + if (speed < 1 || speed > 4 || sony_speeds[speed] < 0) + return (-1); + } + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct sony_924_mode_page_20); + + md.pagex.page_s20.p_code = 0x20; + md.pagex.page_s20.p_len = 0x06; + md.pagex.page_s20.speudo = dummy?1:0; + + /* + * Set Cue sheet option. This is documented for the 924 and + * seems to be supported for the 948 too. + */ + md.pagex.page_s20.cue_sheet_opt = 0x03; + + err = mode_select(usalp, (Uchar *)&md, count, 0, 1); + if (err < 0) + return (err); + + if (speedp == 0) + return (0); + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + + count = sizeof (struct scsi_mode_header) + + sizeof (struct sony_924_mode_page_31); + + md.pagex.page_s31.p_code = 0x31; + md.pagex.page_s31.p_len = 0x02; + md.pagex.page_s31.speed = sony_speeds[speed]; + + return (mode_select(usalp, (Uchar *)&md, count, 0, 1)); +} + +static int +next_writable_address_sony(SCSI *usalp, long *ap, int track, int sectype, + int tracktype) +{ + struct scsi_mode_page_header *mp; + char mode[256]; + int len = 0x30; + int page = 0x23; + struct sony_924_mode_page_23 *xp; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + inc_verbose(); + if (!get_mode_params(usalp, page, "CD track information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + dec_verbose(); + return (-1); + } + dec_verbose(); + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + + xp = (struct sony_924_mode_page_23 *)mp; + +#ifdef SONY_DEBUG + print_sony_mp23(xp, len); +#endif + if (ap) + *ap = a_to_4_byte(xp->next_recordable_addr); + return (0); +} + + +static int +new_track_sony(SCSI *usalp, int track, int sectype, int tracktype) +{ + struct scsi_mode_page_header *mp; + char mode[256]; + int len = 0x30; + int page = 0x23; + struct sony_924_mode_page_23 *xp; + int i; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + get_page22_sony(usalp, mode); + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + inc_verbose(); + if (!get_mode_params(usalp, page, "CD track information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + dec_verbose(); + return (-1); + } + dec_verbose(); + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + + xp = (struct sony_924_mode_page_23 *)mp; + +#ifdef SONY_DEBUG + print_sony_mp23(xp, len); +#endif + + xp->write_method = 0; /* Track at one recording */ + + if (sectype & ST_AUDIOMASK) { + xp->data_form = (sectype & ST_MASK) == ST_AUDIO_PRE ? 0x02 : 0x00; + } else { + if (tracktype == TOC_ROM) { + xp->data_form = (sectype & ST_MASK) == ST_ROM_MODE1 ? 0x10 : 0x11; + } else if (tracktype == TOC_XA1) { + xp->data_form = 0x12; + } else if (tracktype == TOC_XA2) { + xp->data_form = 0x12; + } else if (tracktype == TOC_CDI) { + xp->data_form = 0x12; + } + } + + ((struct scsi_modesel_header *)mode)->sense_data_len = 0; + ((struct scsi_modesel_header *)mode)->res2 = 0; + + i = ((struct scsi_mode_header *)mode)->blockdesc_len; + if (i > 0) { + i_to_3_byte( + ((struct scsi_mode_data *)mode)->blockdesc.nlblock, + 0); + } + + if (mode_select(usalp, (Uchar *)mode, len, 0, usalp->inq->data_format >= 2) < 0) { + return (-1); + } + + return (0); +} + +static int +open_track_sony(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + if (!is_tao(trackp) && !is_packet(trackp)) { + if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) { + if (lverbose) { + printf("Writing pregap for track %d at %ld\n", + (int)trackp->trackno, + trackp->trackstart-trackp->pregapsize); + } + /* + * XXX Do we need to check isecsize too? + */ + pad_track(usalp, dp, trackp, + trackp->trackstart-trackp->pregapsize, + (Llong)trackp->pregapsize*trackp->secsize, + FALSE, 0); + } + return (0); + } + + if (select_secsize(usalp, trackp->secsize) < 0) + return (-1); + + if (new_track_sony(usalp, trackp->trackno, trackp->sectype, trackp->tracktype & TOC_MASK) < 0) + return (-1); + + if (write_track_sony(usalp, 0L, trackp->sectype) < 0) + return (-1); + + return (0); +} + +static int +open_session_sony(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + struct scsi_mode_page_header *mp; + char mode[256]; + int i; + int len = 0x30; + struct sony_924_mode_page_22 *xp; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if ((len = get_page22_sony(usalp, mode)) < 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp = (struct sony_924_mode_page_22 *)mp; + + xp->disk_type = toc2sess[track_base(trackp)->tracktype & TOC_MASK]; + + if (is_tao(track_base(trackp))) { +#ifdef __needed__ + if ((track_base(trackp)->tracktype & TOC_MASK) == TOC_DA) + xp->disk_style = 0x80; + else + xp->disk_style = 0xC0; +#endif + } else if (is_sao(track_base(trackp))) { + /* + * We may only change this value if the disk is empty. + * i.e. when disk_status & 0xC0 == 0x00 + */ + if ((xp->disk_status & 0xC0) != 0) { + if (xp->disk_style != 0x00) + errmsgno(EX_BAD, "Cannot change disk stile for recorded disk.\n"); + } + xp->disk_style = 0x00; + } + + ((struct scsi_modesel_header *)mode)->sense_data_len = 0; + ((struct scsi_modesel_header *)mode)->res2 = 0; + + i = ((struct scsi_mode_header *)mode)->blockdesc_len; + if (i > 0) { + i_to_3_byte( + ((struct scsi_mode_data *)mode)->blockdesc.nlblock, + 0); + } + + if (mode_select(usalp, (Uchar *)mode, len, 0, usalp->inq->data_format >= 2) < 0) { + return (-1); + } +/* + * XXX set write parameter für SAO mit Multi Session (948 only?) + * XXX set_wr_parameter_sony(usalp, bp, size); + */ + return (0); +} + +static int +abort_session_sony(SCSI *usalp, cdr_t *dp) +{ + return (discontinue_sony(usalp)); +} + +static int +get_page22_sony(SCSI *usalp, char *mode) +{ + struct scsi_mode_page_header *mp; + int len = 0x30; + int page = 0x22; + struct sony_924_mode_page_22 *xp; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + inc_verbose(); + if (!get_mode_params(usalp, page, "CD disk information", + (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + dec_verbose(); + return (-1); + } + dec_verbose(); + if (len == 0) + return (-1); + + mp = (struct scsi_mode_page_header *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + xp = (struct sony_924_mode_page_22 *)mp; + +#ifdef SONY_DEBUG + print_sony_mp22(xp, len); +#endif + return (len); +} + +/*--------------------------------------------------------------------------*/ + +static Uchar db2df[] = { + 0x01, /* 0 2352 bytes of raw data */ + 0xFF, /* 1 2368 bytes (raw data + P/Q Subchannel) */ + 0xFF, /* 2 2448 bytes (raw data + P-W Subchannel) */ + 0xFF, /* 3 2448 bytes (raw data + P-W raw Subchannel)*/ + 0xFF, /* 4 - Reserved */ + 0xFF, /* 5 - Reserved */ + 0xFF, /* 6 - Reserved */ + 0xFF, /* 7 - Vendor specific */ + 0x11, /* 8 2048 bytes Mode 1 (ISO/IEC 10149) */ + 0xFF, /* 9 2336 bytes Mode 2 (ISO/IEC 10149) */ + 0xFF, /* 10 2048 bytes Mode 2! (CD-ROM XA form 1) */ + 0xFF, /* 11 2056 bytes Mode 2 (CD-ROM XA form 1) */ + 0xFF, /* 12 2324 bytes Mode 2 (CD-ROM XA form 2) */ + 0xFF, /* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */ + 0xFF, /* 14 - Reserved */ + 0xFF, /* 15 - Vendor specific */ +}; + +static int +gen_cue_sony(track_t *trackp, void *vcuep, BOOL needgap) +{ + int tracks = trackp->tracks; + int i; + struct sony_cue **cuep = vcuep; + struct sony_cue *cue; + struct sony_cue *cp; + int ncue = 0; + int icue = 0; + int pgsize; + msf_t m; + int ctl; + int df; + int scms; + + cue = malloc(1); + + for (i = 0; i <= tracks; i++) { + ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[i])) + ctl |= TM_ALLOW_COPY << 4; + df = db2df[trackp[i].dbtype & 0x0F]; + +#ifdef __supported__ + if (trackp[i].isrc) { /* MCN or ISRC */ + ncue += 2; + cue = realloc(cue, ncue * sizeof (*cue)); + cp = &cue[icue++]; + if (i == 0) { + cp->cs_ctladr = 0x02; + movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7); + cp = &cue[icue++]; + cp->cs_ctladr = 0x02; + movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7); + } else { + cp->cs_ctladr = 0x03; + cp->cs_tno = i; + movebytes(&trackp[i].isrc[0], &cp->cs_index, 6); + cp = &cue[icue++]; + cp->cs_ctladr = 0x03; + cp->cs_tno = i; + movebytes(&trackp[i].isrc[6], &cp->cs_index, 6); + } + } +#endif + if (i == 0) { /* Lead in */ + df &= ~7; + if (trackp[0].flags & TI_TEXT) /* CD-Text in Lead-in*/ + df |= 0xC0; + lba_to_msf(-150, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 0, df, 0, &m); + } else { + scms = 0; + + if (is_scms(&trackp[i])) + scms = 0x80; + pgsize = trackp[i].pregapsize; + if (pgsize == 0 && needgap) + pgsize++; + lba_to_msf(trackp[i].trackstart-pgsize, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 0, df, scms, &m); + + if (trackp[i].nindex == 1) { + lba_to_msf(trackp[i].trackstart, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, 1, df, scms, &m); + } else { + int idx; + long *idxlist; + + ncue += trackp[i].nindex; + idxlist = trackp[i].tindex; + cue = realloc(cue, ncue * sizeof (*cue)); + + for (idx = 1; idx <= trackp[i].nindex; idx++) { + lba_to_msf(trackp[i].trackstart + idxlist[idx], &m); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, i, idx, df, scms, &m); + } + } + } + } + /* Lead out */ + ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4; + df = db2df[trackp[tracks+1].dbtype & 0x0F]; + df &= ~7; + lba_to_msf(trackp[tracks+1].trackstart, &m); + cue = realloc(cue, ++ncue * sizeof (*cue)); + cp = &cue[icue++]; + fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m); + + if (lverbose > 1) { + for (i = 0; i < ncue; i++) { + usal_prbytes("", (Uchar *)&cue[i], 8); + } + } + if (cuep) + *cuep = cue; + else + free(cue); + return (ncue); +} + + +static void +fillcue(struct sony_cue *cp /* The target cue entry */, + int ca /* Control/adr for this entry */, + int tno /* Track number for this entry */, + int idx /* Index for this entry */, + int dataform /* Data format for this entry */, + int scms /* Serial copy management */, + msf_t *mp /* MSF value for this entry */) +{ + cp->cs_ctladr = ca; + if (tno <= 99) + cp->cs_tno = to_bcd(tno); + else + cp->cs_tno = tno; + cp->cs_index = to_bcd(idx); + cp->cs_dataform = dataform; + cp->cs_zero = scms; + cp->cs_min = to_bcd(mp->msf_min); + cp->cs_sec = to_bcd(mp->msf_sec); + cp->cs_frame = to_bcd(mp->msf_frame); +} + +static int +send_cue_sony(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + struct sony_cue *cp; + int ncue; + int ret; + Uint i; + struct timeval starttime; + struct timeval stoptime; + int disktype; + + disktype = toc2sess[track_base(trackp)->tracktype & TOC_MASK]; + + for (i = 1; i <= trackp->tracks; i++) { + if (trackp[i].tracksize < (tsize_t)0) { + errmsgno(EX_BAD, "Track %d has unknown length.\n", i); + return (-1); + } + } + ncue = (*dp->cdr_gen_cue)(trackp, &cp, FALSE); + + starttime.tv_sec = 0; + starttime.tv_usec = 0; + stoptime = starttime; + gettimeofday(&starttime, (struct timezone *)0); + + usalp->silent++; + ret = write_start_sony(usalp, (caddr_t)cp, ncue*8); + usalp->silent--; + free(cp); + if (ret < 0) { + errmsgno(EX_BAD, "CUE sheet not accepted. Retrying with minimum pregapsize = 1.\n"); + ncue = (*dp->cdr_gen_cue)(trackp, &cp, TRUE); + ret = write_start_sony(usalp, (caddr_t)cp, ncue*8); + free(cp); + } + if (ret >= 0 && lverbose) { + gettimeofday(&stoptime, (struct timezone *)0); + prtimediff("Write Lead-in time: ", &starttime, &stoptime); + } + return (ret); +} + +static int +write_leadin_sony(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + Uint i; + long startsec = 0L; + +/* if (flags & F_SAO) {*/ + if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) { + if (debug || lverbose) { + printf("Sending CUE sheet...\n"); + flush(); + } + if (trackp[0].flags & TI_TEXT) { + if (dp->cdr_speeddef != 4) { + errmsgno(EX_BAD, + "The CDU-924 does not support CD-Text, disabling.\n"); + + trackp[0].flags &= ~TI_TEXT; + } + } + if ((*dp->cdr_send_cue)(usalp, dp, trackp) < 0) { + errmsgno(EX_BAD, "Cannot send CUE sheet.\n"); + return (-1); + } + + if (trackp[0].flags & TI_TEXT) { + startsec = dp->cdr_dstat->ds_first_leadin; + printf("SAO startsec: %ld\n", startsec); + } else { + startsec = -150; + } + if (debug) + printf("SAO startsec: %ld\n", startsec); + + if (trackp[0].flags & TI_TEXT) { + if (startsec > 0) { + errmsgno(EX_BAD, "CD-Text must be in first session.\n"); + return (-1); + } + if (debug || lverbose) + printf("Writing lead-in...\n"); + if (write_cdtext(usalp, dp, startsec) < 0) + return (-1); + + dp->cdr_dstat->ds_cdrflags |= RF_LEADIN; + } else for (i = 1; i <= trackp->tracks; i++) { + trackp[i].trackstart += startsec +150; + } + } + return (0); +} + +/*--------------------------------------------------------------------------*/ + +static const char *sd_cdu_924_error_str[] = { + + "\200\000write complete", /* 80 00 */ + "\201\000logical unit is reserved", /* 81 00 */ + "\205\000audio address not valid", /* 85 00 */ + "\210\000illegal cue sheet", /* 88 00 */ + "\211\000inappropriate command", /* 89 00 */ + + "\266\000media load mechanism failed", /* B6 00 */ + "\271\000audio play operation aborted", /* B9 00 */ + "\277\000buffer overflow for read all subcodes command", /* BF 00 */ + "\300\000unrecordable disk", /* C0 00 */ + "\301\000illegal track status", /* C1 00 */ + "\302\000reserved track present", /* C2 00 */ + "\303\000buffer data size error", /* C3 00 */ + "\304\001illegal data form for reserve track command", /* C4 01 */ + "\304\002unable to reserve track, because track mode has been changed", /* C4 02 */ + "\305\000buffer error during at once recording", /* C5 00 */ + "\306\001unwritten area encountered", /* C6 01 */ + "\306\002link blocks encountered", /* C6 02 */ + "\306\003nonexistent block encountered", /* C6 03 */ + "\307\000disk style mismatch", /* C7 00 */ + "\310\000no table of contents", /* C8 00 */ + "\311\000illegal block length for write command", /* C9 00 */ + "\312\000power calibration error", /* CA 00 */ + "\313\000write error", /* CB 00 */ + "\313\001write error track recovered", /* CB 01 */ + "\314\000not enough space", /* CC 00 */ + "\315\000no track present to finalize", /* CD 00 */ + "\316\000unrecoverable track descriptor encountered", /* CE 00 */ + "\317\000damaged track present", /* CF 00 */ + "\320\000pma area full", /* D0 00 */ + "\321\000pca area full", /* D1 00 */ + "\322\000unrecoverable damaged track cause too small writing area", /* D2 00 */ + "\323\000no bar code", /* D3 00 */ + "\323\001not enough bar code margin", /* D3 01 */ + "\323\002no bar code start pattern", /* D3 02 */ + "\323\003illegal bar code length", /* D3 03 */ + "\323\004illegal bar code format", /* D3 04 */ + "\324\000exit from pseudo track at once recording", /* D4 00 */ + NULL +}; + +static int +sony_attach(SCSI *usalp, cdr_t *dp) +{ + if (usalp->inq != NULL) { + if (strbeg("CD-R CDU94", usalp->inq->prod_ident)) { + dp->cdr_speeddef = 4; + } + } + usal_setnonstderrs(usalp, sd_cdu_924_error_str); + return (0); +} + +#ifdef SONY_DEBUG +static void +print_sony_mp22(struct sony_924_mode_page_22 *xp, int len) +{ + printf("disk style: %X\n", xp->disk_style); + printf("disk type: %X\n", xp->disk_type); + printf("first track: %X\n", xp->first_track); + printf("last track: %X\n", xp->last_track); + printf("numsess: %X\n", xp->numsess); + printf("disk appl code: %lX\n", a_to_u_4_byte(xp->disk_appl_code)); + printf("last start time: %lX\n", a_to_u_4_byte(xp->last_start_time)); + printf("disk status: %X\n", xp->disk_status); + printf("num valid nra: %X\n", xp->num_valid_nra); + printf("track info track: %X\n", xp->track_info_track); + printf("post gap: %X\n", xp->post_gap); + printf("disk id code: %lX\n", a_to_u_4_byte(xp->disk_id_code)); + printf("lead in start: %lX\n", a_to_u_4_byte(xp->lead_in_start)); +} + +static void +print_sony_mp23(struct sony_924_mode_page_23 *xp, int len) +{ + printf("len: %d\n", len); + + printf("track num: %X\n", xp->track_num); + printf("data form: %X\n", xp->data_form); + printf("write method: %X\n", xp->write_method); + printf("session: %X\n", xp->session); + printf("track status: %X\n", xp->track_status); + +/* + * XXX Check for signed/unsigned a_to_*() conversion. + */ + printf("start lba: %lX\n", a_to_4_byte(xp->start_lba)); + printf("next recordable addr: %lX\n", a_to_4_byte(xp->next_recordable_addr)); + printf("blank area cap: %lX\n", a_to_u_4_byte(xp->blank_area_cap)); + printf("fixed packet size: %lX\n", a_to_u_4_byte(xp->fixed_packet_size)); + printf("starting msf: %lX\n", a_to_u_4_byte(xp->starting_msf)); + printf("ending msf: %lX\n", a_to_u_4_byte(xp->ending_msf)); + printf("next rec time: %lX\n", a_to_u_4_byte(xp->next_rec_time)); +} +#endif + +static int +buf_cap_sony(SCSI *usalp, long *sp, long *fp) +{ + char resp[8]; + Ulong freespace; + Ulong bufsize; + int per; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)resp; + scmd->size = sizeof (resp); + 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 = 0xEC; /* Read buffer cap */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "read buffer cap sony"; + + if (usal_cmd(usalp) < 0) + return (-1); + + bufsize = a_to_u_3_byte(&resp[1]); + freespace = a_to_u_3_byte(&resp[5]); + if (sp) + *sp = bufsize; + if (fp) + *fp = freespace; + + if (usalp->verbose || (sp == 0 && fp == 0)) + printf("BFree: %ld K BSize: %ld K\n", freespace >> 10, bufsize >> 10); + + if (bufsize == 0) + return (0); + per = (100 * (bufsize - freespace)) / bufsize; + if (per < 0) + return (0); + if (per > 100) + return (100); + return (per); +} diff --git a/wodim/fifo.c b/wodim/fifo.c new file mode 100644 index 0000000..2f70f5b --- /dev/null +++ b/wodim/fifo.c @@ -0,0 +1,878 @@ +/* + * 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. + * + */ + +/* @(#)fifo.c 1.49 06/02/08 Copyright 1989,1997-2006 J. Schilling */ +/* + * A "fifo" that uses shared memory between two processes + * + * The actual code is a mixture of borrowed code from star's fifo.c + * and a proposal from Finn Arne Gangstad <finnag@guardian.no> + * who had the idea to use a ring buffer to handle average size chunks. + * + * Copyright (c) 1989,1997-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. + * + * 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. + */ + +#ifndef DEBUG +#define DEBUG +#endif +/*#define XDEBUG*/ +#include <mconfig.h> + + /* We always wish FIFO unless it is disabled below */ +#ifndef FIFO +#define FIFO +#endif + +#if defined(HAVE_OS_H) && \ + defined(HAVE_CLONE_AREA) && defined(HAVE_CREATE_AREA) && \ + defined(HAVE_DELETE_AREA) +#include <OS.h> +# define HAVE_BEOS_AREAS /* BeOS/Zeta */ +#endif +#if !defined(HAVE_SMMAP) && !defined(HAVE_USGSHM) && \ + !defined(HAVE_DOSALLOCSHAREDMEM) && !defined(HAVE_BEOS_AREAS) +#undef FIFO /* We cannot have a FIFO on this platform */ +#endif +#if !defined(HAVE_FORK) +#undef FIFO /* We cannot have a FIFO on this platform */ +#endif +#ifdef FIFO +#if !defined(USE_MMAP) && !defined(USE_USGSHM) +#define USE_MMAP +#endif +#ifndef HAVE_SMMAP +# undef USE_MMAP +# define USE_USGSHM /* now SYSV shared memory is the default*/ +#endif +#ifdef USE_MMAP /* Only want to have one implementation */ +# undef USE_USGSHM /* mmap() is preferred */ +#endif + +#ifdef HAVE_DOSALLOCSHAREDMEM /* This is for OS/2 */ +# undef USE_MMAP +# undef USE_USGSHM +# define USE_OS2SHM +#endif + +#ifdef HAVE_BEOS_AREAS /* This is for BeOS/Zeta */ +# undef USE_MMAP +# undef USE_USGSHM +# undef USE_OS2SHM +# define USE_BEOS_AREAS +#endif + +#include <stdio.h> +#include <stdxlib.h> +#include <unixstd.h> /* includes <sys/types.h> */ +#include <utypes.h> +#include <fctldefs.h> +#if defined(HAVE_SMMAP) && defined(USE_MMAP) +#include <mmapdefs.h> +#endif +#include <waitdefs.h> +#include <standard.h> +#include <errno.h> +#include <signal.h> +#include <libport.h> +#include <schily.h> + +#include "wodim.h" +#include "xio.h" + +#ifdef DEBUG +#ifdef XDEBUG +FILE *ef; +#define USDEBUG1 if (debug) {if (s == owner_reader) fprintf(ef, "r"); else fprintf(ef, "w"); fflush(ef); } +#define USDEBUG2 if (debug) {if (s == owner_reader) fprintf(ef, "R"); else fprintf(ef, "W"); fflush(ef); } +#else +#define USDEBUG1 +#define USDEBUG2 +#endif +#define EDEBUG(a) if (debug) schily_error a +#else +#define EDEBUG(a) +#define USDEBUG1 +#define USDEBUG2 +#endif + +#define palign(x, a) (((char *)(x)) + ((a) - 1 - (((UIntptr_t)((x)-1))%(a)))) + +typedef enum faio_owner { + owner_none, /* Unused in real life */ + owner_writer, /* owned by process that writes into FIFO */ + owner_faio, /* Intermediate state when buf still in use */ + owner_reader /* owned by process that reads from FIFO */ +} fowner_t; + +char *onames[] = { + "none", + "writer", + "faio", + "reader", +}; + +typedef struct faio { + int len; + volatile fowner_t owner; + volatile int users; + short fd; + short saved_errno; + char *bufp; +} faio_t; + +struct faio_stats { + long puts; + long gets; + long empty; + long full; + long done; + long cont_low; + int users; +} *sp; + +#define MIN_BUFFERS 3 + +#define MSECS 1000 +#define SECS (1000*MSECS) + +/* + * Note: WRITER_MAXWAIT & READER_MAXWAIT need to be greater than the SCSI + * timeout for commands that write to the media. This is currently 200s + * if we are in SAO mode. + */ +/* microsecond delay between each buffer-ready probe by writing process */ +#define WRITER_DELAY (20*MSECS) +#define WRITER_MAXWAIT (240*SECS) /* 240 seconds max wait for data */ + +/* microsecond delay between each buffer-ready probe by reading process */ +#define READER_DELAY (80*MSECS) +#define READER_MAXWAIT (240*SECS) /* 240 seconds max wait for reader */ + +static char *buf; +static char *bufbase; +static char *bufend; +static long buflen; /* The size of the FIFO buffer */ + +extern int debug; +extern int lverbose; + +void init_fifo(long); +#ifdef USE_MMAP +static char *mkshare(int size); +#endif +#ifdef USE_USGSHM +static char *mkshm(int size); +#endif +#ifdef USE_OS2SHM +static char *mkos2shm(int size); +#endif +#ifdef USE_BEOS_AREAS +static char *mkbeosshm(int size); +static void beosshm_child(void); +#endif + +BOOL init_faio(track_t *trackp, int); +BOOL await_faio(void); +void kill_faio(void); +int wait_faio(void); +static void faio_reader(track_t *trackp); +static void faio_read_track(track_t *trackp); +static void faio_wait_on_buffer(faio_t *f, fowner_t s, unsigned long delay, + unsigned long max_wait); +static int faio_read_segment(int fd, faio_t *f, track_t *track, long secno, + int len); +static faio_t *faio_ref(int n); +int faio_read_buf(int f, char *bp, int size); +int faio_get_buf(int f, char **bpp, int size); +void fifo_stats(void); +int fifo_percent(BOOL addone); + + +void +init_fifo(long fs) +{ + int pagesize; + + if (fs == 0L) + return; + + pagesize = getpagesize(); + buflen = roundup(fs, pagesize) + pagesize; + EDEBUG(("fs: %ld buflen: %ld\n", fs, buflen)); + +#if defined(USE_MMAP) + buf = mkshare(buflen); +#endif +#if defined(USE_USGSHM) + buf = mkshm(buflen); +#endif +#if defined(USE_OS2SHM) + buf = mkos2shm(buflen); +#endif +#if defined(USE_BEOS_AREAS) + buf = mkbeosshm(buflen); +#endif + + bufbase = buf; + bufend = buf + buflen; + EDEBUG(("buf: %p bufend: %p, buflen: %ld\n", buf, bufend, buflen)); + buf = palign(buf, pagesize); + buflen -= buf - bufbase; + EDEBUG(("buf: %p bufend: %p, buflen: %ld (align %ld)\n", buf, bufend, buflen, (long)(buf - bufbase))); + + /* + * Dirty the whole buffer. This can die with various signals if + * we're trying to lock too much memory + */ + fillbytes(buf, buflen, '\0'); + +#ifdef XDEBUG + if (debug) + ef = fopen("/tmp/ef", "w"); +#endif +} + +#ifdef USE_MMAP +static char * +mkshare(int size) +{ + int f; + char *addr; + +#ifdef MAP_ANONYMOUS /* HP/UX */ + f = -1; + addr = mmap(0, mmap_sizeparm(size), + PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, f, 0); +#else + if ((f = open("/dev/zero", O_RDWR)) < 0) + comerr("Cannot open '/dev/zero'.\n"); + addr = mmap(0, mmap_sizeparm(size), + PROT_READ|PROT_WRITE, MAP_SHARED, f, 0); +#endif + if (addr == (char *)-1) + comerr("Cannot get mmap for %d Bytes on /dev/zero.\n", size); + if (f >= 0) + close(f); + + if (debug) errmsgno(EX_BAD, "shared memory segment attached at: %p size %d\n", + (void *)addr, size); + + return (addr); +} +#endif + +#ifdef USE_USGSHM +#include <sys/ipc.h> +#include <sys/shm.h> +static char * +mkshm(int size) +{ + int id; + char *addr; + /* + * Unfortunately, a declaration of shmat() is missing in old + * implementations such as AT&T SVr0 and SunOS. + * We cannot add this definition here because the return-type + * changed on newer systems. + * + * We will get a warning like this: + * + * warning: assignment of pointer from integer lacks a cast + * or + * warning: illegal combination of pointer and integer, op = + */ +/* extern char *shmat();*/ + + if ((id = shmget(IPC_PRIVATE, size, IPC_CREAT|0600)) == -1) + comerr("shmget failed\n"); + + if (debug) errmsgno(EX_BAD, "shared memory segment allocated: %d\n", id); + + if ((addr = shmat(id, (char *)0, 0600)) == (char *)-1) + comerr("shmat failed\n"); + + if (debug) errmsgno(EX_BAD, "shared memory segment attached at: %p size %d\n", + (void *)addr, size); + + if (shmctl(id, IPC_RMID, 0) < 0) + comerr("shmctl failed to detach shared memory segment\n"); + +#ifdef SHM_LOCK + /* + * Although SHM_LOCK is standard, it seems that all versions of AIX + * ommit this definition. + */ + if (shmctl(id, SHM_LOCK, 0) < 0) + comerr("shmctl failed to lock shared memory segment\n"); +#endif + + return (addr); +} +#endif + +#ifdef USE_OS2SHM +static char * +mkos2shm(int size) +{ + char *addr; + + /* + * The OS/2 implementation of shm (using shm.dll) limits the size of one shared + * memory segment to 0x3fa000 (aprox. 4MBytes). Using OS/2 native API we have + * no such restriction so I decided to use it allowing fifos of arbitrary size. + */ + if (DosAllocSharedMem(&addr, NULL, size, 0X100L | 0x1L | 0x2L | 0x10L)) + comerr("DosAllocSharedMem() failed\n"); + + if (debug) errmsgno(EX_BAD, "shared memory allocated attached at: %p size %d\n", + (void *)addr, size); + + return (addr); +} +#endif + +#ifdef USE_BEOS_AREAS +static area_id faio_aid; +static void *faio_addr; +static char faio_name[32]; + +static char * +mkbeosshm(int size) +{ + snprintf(faio_name, sizeof (faio_name), "cdrecord FIFO %lld", + (Llong)getpid()); + + faio_aid = create_area(faio_name, &faio_addr, + B_ANY_ADDRESS, + size, + B_NO_LOCK, B_READ_AREA|B_WRITE_AREA); + if (faio_addr == NULL) { + comerrno(faio_aid, + "Cannot get create_area for %d Bytes FIFO.\n", size); + } + if (debug) errmsgno(EX_BAD, "shared memory allocated attached at: %p size %d\n", + (void *)faio_addr, size); + return (faio_addr); +} + +static void +beosshm_child() +{ + /* + * Delete the area created by fork that is copy-on-write. + */ + delete_area(area_for(faio_addr)); + /* + * Clone (share) the original one. + */ + faio_aid = clone_area(faio_name, &faio_addr, + B_ANY_ADDRESS, B_READ_AREA|B_WRITE_AREA, + faio_aid); + if (bufbase != faio_addr) { + errmsgno(EX_BAD, "Panic FIFO addr.\n"); + return (FALSE); + } +} +#endif + +static int faio_buffers; +static int faio_buf_size; +static int buf_idx = 0; /* Initialize to fix an Amiga bug */ +static int buf_idx_reader = 0; /* Separate var to allow vfork() */ + /* buf_idx_reader is for the process */ + /* that fills the FIFO */ +static pid_t faio_pid = -1; +static BOOL faio_didwait; + +#ifdef AMIGA +/* + * On Amiga fork will be replaced by the speciall vfork() like call ix_vfork, + * which lets the parent asleep. The child process later wakes up the parent + * process by calling ix_fork_resume(). + */ +#define fork() ix_vfork() +#define __vfork_resume() ix_vfork_resume() + +#else /* !AMIGA */ +#define __vfork_resume() +#endif + + +/*#define faio_ref(n) (&((faio_t *)buf)[n])*/ + + +BOOL +init_faio(track_t *trackp, int bufsize) +{ + int n; + faio_t *f; + int pagesize; + char *base; + + if (buflen == 0L) + return (FALSE); + + pagesize = getpagesize(); + faio_buf_size = bufsize; + f = (faio_t *)buf; + + /* + * Compute space for buffer headers. + * Round bufsize up to pagesize to make each FIFO segment + * properly page aligned. + */ + bufsize = roundup(bufsize, pagesize); + faio_buffers = (buflen - sizeof (*sp)) / bufsize; + EDEBUG(("bufsize: %d buffers: %d hdrsize %ld\n", bufsize, faio_buffers, (long)faio_buffers * sizeof (struct faio))); + + /* + * Reduce buffer space by header space. + */ + n = sizeof (*sp) + faio_buffers * sizeof (struct faio); + n = roundup(n, pagesize); + faio_buffers = (buflen-n) / bufsize; + EDEBUG(("bufsize: %d buffers: %d hdrsize %ld\n", bufsize, faio_buffers, (long)faio_buffers * sizeof (struct faio))); + + if (faio_buffers < MIN_BUFFERS) { + errmsgno(EX_BAD, + "write-buffer too small, minimum is %dk. Disabling.\n", + MIN_BUFFERS*bufsize/1024); + return (FALSE); + } + + if (debug) + printf("Using %d buffers of %d bytes.\n", faio_buffers, faio_buf_size); + + f = (faio_t *)buf; + base = buf + roundup(sizeof (*sp) + faio_buffers * sizeof (struct faio), + pagesize); + + for (n = 0; n < faio_buffers; n++, f++, base += bufsize) { + /* Give all the buffers to the file reader process */ + f->owner = owner_writer; + f->users = 0; + f->bufp = base; + f->fd = -1; + } + sp = (struct faio_stats *)f; /* point past headers */ + sp->gets = sp->puts = sp->done = 0L; + sp->users = 1; + + faio_pid = fork(); + if (faio_pid < 0) + comerr("fork(2) failed"); + + if (faio_pid == 0) { + /* + * child (background) process that fills the FIFO. + */ + raisepri(1); /* almost max priority */ + +#ifdef USE_OS2SHM + DosGetSharedMem(buf, 3); /* PAG_READ|PAG_WRITE */ +#endif +#ifdef USE_BEOS_AREAS + beosshm_child(); +#endif + /* Ignoring SIGALRM cures the SCO usleep() bug */ +/* signal(SIGALRM, SIG_IGN);*/ + __vfork_resume(); /* Needed on some platforms */ + faio_reader(trackp); + /* NOTREACHED */ + } else { +#ifdef __needed__ + Uint t; +#endif + + faio_didwait = FALSE; + + /* + * XXX We used to close all track files in the foreground + * XXX process. This was not correct before we used "xio" + * XXX and with "xio" it will start to fail because we need + * XXX the fd handles for the faio_get_buf() function. + */ +#ifdef __needed__ + /* close all file-descriptors that only the child will use */ + for (t = 1; t <= trackp->tracks; t++) { + if (trackp[t].xfp != NULL) + xclose(trackp[t].xfp); + } +#endif + } + + return (TRUE); +} + +BOOL +await_faio() +{ + int n; + int lastfd = -1; + faio_t *f; + + /* + * Wait until the reader is active and has filled the buffer. + */ + if (lverbose || debug) { + printf("Waiting for reader process to fill input buffer ... "); + flush(); + } + + faio_wait_on_buffer(faio_ref(faio_buffers - 1), owner_reader, + 500*MSECS, 0); + + if (lverbose || debug) + printf("input buffer ready.\n"); + + sp->empty = sp->full = 0L; /* set correct stat state */ + sp->cont_low = faio_buffers; /* set cont to max value */ + + f = faio_ref(0); + for (n = 0; n < faio_buffers; n++, f++) { + if (f->fd != lastfd && + f->fd == STDIN_FILENO && f->len == 0) { + errmsgno(EX_BAD, "Premature EOF on stdin.\n"); + kill(faio_pid, SIGKILL); + return (FALSE); + } + lastfd = f->fd; + } + return (TRUE); +} + +void +kill_faio() +{ + if (faio_pid > 0) + kill(faio_pid, SIGKILL); + faio_pid=-1; +} + +int +wait_faio() +{ + if (faio_pid > 0 && !faio_didwait) + return (wait(0)); + faio_didwait = TRUE; + return (0); +} + +static void +faio_reader(track_t *trackp) +{ + /* This function should not return, but _exit. */ + Uint trackno; + + if (debug) + printf("\nfaio_reader starting\n"); + + for (trackno = 1; trackno <= trackp->tracks; trackno++) { + if (debug) + printf("\nfaio_reader reading track %u\n", trackno); + faio_read_track(&trackp[trackno]); + } + sp->done++; + if (debug) + printf("\nfaio_reader all tracks read, exiting\n"); + + /* Prevent hang if buffer is larger than all the tracks combined */ + if (sp->gets == 0) + faio_ref(faio_buffers - 1)->owner = owner_reader; + +#ifdef USE_OS2SHM + DosFreeMem(buf); + sleep(30000); /* XXX If calling _exit() here the parent process seems to be blocked */ + /* XXX This should be fixed soon */ +#endif + if (debug) + fprintf(stderr, "\nfaio_reader _exit(0)\n"); + _exit(0); +} + +#ifndef faio_ref +static faio_t * +faio_ref(int n) +{ + return (&((faio_t *)buf)[n]); +} +#endif + + +static void +faio_read_track(track_t *trackp) +{ + int fd = -1; + int bytespt = trackp->secsize * trackp->secspt; + int secspt = trackp->secspt; + int l; + long secno = trackp->trackstart; + tsize_t tracksize = trackp->tracksize; + tsize_t bytes_read = (tsize_t)0; + long bytes_to_read; + + if (trackp->xfp != NULL) + fd = xfileno(trackp->xfp); + + if (bytespt > faio_buf_size) { + comerrno(EX_BAD, + "faio_read_track fatal: secsize %d secspt %d, bytespt(%d) > %d !!\n", + trackp->secsize, trackp->secspt, bytespt, + faio_buf_size); + } + + do { + bytes_to_read = bytespt; + if (tracksize > 0) { + if ((tracksize - bytes_read) > bytespt) { + bytes_to_read = bytespt; + } else { + bytes_to_read = tracksize - bytes_read; + } + } + l = faio_read_segment(fd, faio_ref(buf_idx_reader), trackp, secno, bytes_to_read); + if (++buf_idx_reader >= faio_buffers) + buf_idx_reader = 0; + if (l <= 0) + break; + bytes_read += l; + secno += secspt; + } while (tracksize < 0 || bytes_read < tracksize); + + xclose(trackp->xfp); /* Don't keep files open longer than neccesary */ +} + +static void +#ifdef PROTOTYPES +faio_wait_on_buffer(faio_t *f, fowner_t s, + unsigned long delay, + unsigned long max_wait) +#else +faio_wait_on_buffer(faio_t *f, fowner_t *s, unsigned long delay, unsigned long max_wait) +#endif +{ + unsigned long max_loops; + + if (f->owner == s) + return; /* return immediately if the buffer is ours */ + + if (s == owner_reader) + sp->empty++; + else + sp->full++; + + max_loops = max_wait / delay + 1; + + while (max_wait == 0 || max_loops--) { + USDEBUG1; + usleep(delay); + USDEBUG2; + + if (f->owner == s) + return; + } + if (debug) { + errmsgno(EX_BAD, + "%lu microseconds passed waiting for %d current: %d idx: %ld\n", + max_wait, s, f->owner, (long)(f - faio_ref(0))/sizeof (*f)); + } + comerrno(EX_BAD, "faio_wait_on_buffer for %s timed out.\n", + (s > owner_reader || s < owner_none) ? "bad_owner" : onames[s-owner_none]); +} + +static int +faio_read_segment(int fd, faio_t *f, track_t *trackp, long secno, int len) +{ + int l; + + faio_wait_on_buffer(f, owner_writer, WRITER_DELAY, WRITER_MAXWAIT); + + f->fd = fd; + l = fill_buf(fd, trackp, secno, f->bufp, len); + f->len = l; + f->saved_errno = geterrno(); + f->owner = owner_reader; + f->users = sp->users; + + sp->puts++; + + return (l); +} + +int +faio_read_buf(int fd, char *bp, int size) +{ + char *bufp; + + int len = faio_get_buf(fd, &bufp, size); + if (len > 0) { + movebytes(bufp, bp, len); + } + return (len); +} + +int +faio_get_buf(int fd, char **bpp, int size) +{ + faio_t *f; + int len; + +again: + f = faio_ref(buf_idx); + if (f->owner == owner_faio) { + f->owner = owner_writer; + if (++buf_idx >= faio_buffers) + buf_idx = 0; + f = faio_ref(buf_idx); + } + + if ((sp->puts - sp->gets) < sp->cont_low && sp->done == 0) { + EDEBUG(("gets: %ld puts: %ld cont: %ld low: %ld\n", sp->gets, sp->puts, sp->puts - sp->gets, sp->cont_low)); + sp->cont_low = sp->puts - sp->gets; + } + faio_wait_on_buffer(f, owner_reader, READER_DELAY, READER_MAXWAIT); + len = f->len; + + if (f->fd != fd) { + if (f->len == 0) { + /* + * If the tracksize for this track was known, and + * the tracksize is 0 mod bytespt, this happens. + */ + goto again; + } + comerrno(EX_BAD, + "faio_get_buf fatal: fd=%d, f->fd=%d, f->len=%d f->errno=%d\n", + fd, f->fd, f->len, f->saved_errno); + } + if (size < len) { + comerrno(EX_BAD, + "unexpected short read-attempt in faio_get_buf. size = %d, len = %d\n", + size, len); + } + + if (len < 0) + seterrno(f->saved_errno); + + sp->gets++; + + *bpp = f->bufp; + if (--f->users <= 0) + f->owner = owner_faio; + return (len); +} + +void +fifo_stats() +{ + if (sp == NULL) /* We might not use a FIFO */ + return; + + errmsgno(EX_BAD, "fifo had %ld puts and %ld gets.\n", + sp->puts, sp->gets); + errmsgno(EX_BAD, "fifo was %ld times empty and %ld times full, min fill was %ld%%.\n", + sp->empty, sp->full, (100L*sp->cont_low)/faio_buffers); +} + +int +fifo_percent(BOOL addone) +{ + int percent; + + if (sp == NULL) /* We might not use a FIFO */ + return (-1); + + if (sp->done) + return (100); + percent = (100*(sp->puts + 1 - sp->gets)/faio_buffers); + if (percent > 100) + return (100); + return (percent); +} +#else /* FIFO */ + +#include <standard.h> +#include <utypes.h> /* includes sys/types.h */ +#include <schily.h> + +#include "wodim.h" + +void init_fifo(long); +BOOL init_faio(track_t *track, int); +BOOL await_faio(void); +void kill_faio(void); +int wait_faio(void); +int faio_read_buf(int f, char *bp, int size); +int faio_get_buf(int f, char **bpp, int size); +void fifo_stats(void); +int fifo_percent(BOOL addone); + + +void init_fifo(long fs) +{ + errmsgno(EX_BAD, "Fifo not supported.\n"); +} + +BOOL init_faio(track_t *track, + int bufsize /* The size of a single transfer buffer */) +{ + return (FALSE); +} + +BOOL await_faio() +{ + return (TRUE); +} + +void kill_faio() +{ +} + +int wait_faio() +{ + return (0); +} + +int faio_read_buf(int fd, char *bp, int size) +{ + return (0); +} + +int faio_get_buf(int fd, char **bpp, int size) +{ + return (0); +} + +void fifo_stats() +{ +} + +int fifo_percent(BOOL addone) +{ + return (-1); +} + +#endif /* FIFO */ diff --git a/wodim/getnum.c b/wodim/getnum.c new file mode 100644 index 0000000..ed13df9 --- /dev/null +++ b/wodim/getnum.c @@ -0,0 +1,123 @@ +/* + * 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. + * + */ + +/* @(#)getnum.c 1.2 04/03/02 Copyright 1984-2002, 2004 J. Schilling */ +/* + * Number conversion routines to implement 'dd' like options. + * + * Copyright (c) 1984-2002, 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 <standard.h> +#include <utypes.h> +#include <schily.h> + +static Llong number(char *arg, int *retp); +int getnum(char *arg, long *valp); +int getllnum(char *arg, Llong *lvalp); + +static Llong +number(register char *arg, int *retp) +{ + Llong val = 0; + + if (*retp != 1) + return (val); + if (*arg == '\0') { + *retp = -1; + } else if (*(arg = astoll(arg, &val))) { + if (*arg == 'p' || *arg == 'P') { + val *= (1024*1024); + val *= (1024*1024*1024); + arg++; + + } else if (*arg == 't' || *arg == 'T') { + val *= (1024*1024); + val *= (1024*1024); + arg++; + + } else if (*arg == 'g' || *arg == 'G') { + val *= (1024*1024*1024); + arg++; + + } else if (*arg == 'm' || *arg == 'M') { + val *= (1024*1024); + arg++; + + } else if (*arg == 'f' || *arg == 'F') { + val *= 2352; + arg++; + + } else if (*arg == 's' || *arg == 'S') { + val *= 2048; + arg++; + + } else if (*arg == 'k' || *arg == 'K') { + val *= 1024; + arg++; + + } else if (*arg == 'b' || *arg == 'B') { + val *= 512; + arg++; + + } else if (*arg == 'w' || *arg == 'W') { + val *= 2; + arg++; + } + if (*arg == '*' || *arg == 'x') + val *= number(++arg, retp); + else if (*arg != '\0') + *retp = -1; + } + return (val); +} + +int +getnum(char *arg, long *valp) +{ + Llong llval; + int ret = 1; + + llval = number(arg, &ret); + *valp = llval; + if (*valp != llval) { + errmsgno(EX_BAD, + "Value %lld is too large for data type 'long'.\n", + llval); + ret = -1; + } + return (ret); +} + +int +getllnum(char *arg, Llong *lvalp) +{ + int ret = 1; + + *lvalp = number(arg, &ret); + return (ret); +} diff --git a/wodim/iso9660.h b/wodim/iso9660.h new file mode 100644 index 0000000..efcb212 --- /dev/null +++ b/wodim/iso9660.h @@ -0,0 +1,180 @@ +/* + * 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. + * + */ + +/* @(#)iso9660.h 1.5 04/03/02 Copyright 1996, 2004 J. Schilling */ +/* + * Copyright (c) 1996, 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. + */ + +#define _delta(from, to) ((to) - (from) + 1) + +#define VD_BOOT 0 +#define VD_PRIMARY 1 +#define VD_SUPPLEMENT 2 +#define VD_PARTITION 3 +#define VD_TERM 255 + +#define VD_ID "CD001" + +struct iso9660_voldesc { + char vd_type [_delta(1, 1)]; + char vd_id [_delta(2, 6)]; + char vd_version [_delta(7, 7)]; + char vd_fill [_delta(8, 2048)]; +}; + +struct iso9660_boot_voldesc { + char vd_type [_delta(1, 1)]; + char vd_id [_delta(2, 6)]; + char vd_version [_delta(7, 7)]; + char vd_bootsys [_delta(8, 39)]; + char vd_bootid [_delta(40, 71)]; + char vd_bootcode [_delta(72, 2048)]; +}; + +struct iso9660_pr_voldesc { + char vd_type [_delta(1, 1)]; + char vd_id [_delta(2, 6)]; + char vd_version [_delta(7, 7)]; + char vd_unused1 [_delta(8, 8)]; + char vd_system_id [_delta(9, 40)]; + char vd_volume_id [_delta(41, 72)]; + char vd_unused2 [_delta(73, 80)]; + char vd_volume_space_size [_delta(81, 88)]; + char vd_unused3 [_delta(89, 120)]; + char vd_volume_set_size [_delta(121, 124)]; + char vd_volume_seq_number [_delta(125, 128)]; + char vd_lbsize [_delta(129, 132)]; + char vd_path_table_size [_delta(133, 140)]; + char vd_pos_path_table_l [_delta(141, 144)]; + char vd_opt_pos_path_table_l [_delta(145, 148)]; + char vd_pos_path_table_m [_delta(149, 152)]; + char vd_opt_pos_path_table_m [_delta(153, 156)]; + char vd_root_dir [_delta(157, 190)]; + char vd_volume_set_id [_delta(191, 318)]; + char vd_publisher_id [_delta(319, 446)]; + char vd_data_preparer_id [_delta(447, 574)]; + char vd_application_id [_delta(575, 702)]; + char vd_copyr_file_id [_delta(703, 739)]; + char vd_abstr_file_id [_delta(740, 776)]; + char vd_bibl_file_id [_delta(777, 813)]; + char vd_create_time [_delta(814, 830)]; + char vd_mod_time [_delta(831, 847)]; + char vd_expiry_time [_delta(848, 864)]; + char vd_effective_time [_delta(865, 881)]; + char vd_file_struct_vers [_delta(882, 882)]; + char vd_reserved1 [_delta(883, 883)]; + char vd_application_use [_delta(884, 1395)]; + char vd_fill [_delta(1396, 2048)]; +}; + +struct iso9660_dir { + char dr_len [_delta(1, 1)]; + char dr_eattr_len [_delta(2, 2)]; + char dr_eattr_pos [_delta(3, 10)]; + char dr_data_len [_delta(11, 18)]; + char dr_recording_time [_delta(19, 25)]; + char dr_file_flags [_delta(26, 26)]; + char dr_file_unit_size [_delta(27, 27)]; + char dr_interleave_gap [_delta(28, 28)]; + char dr_volume_seq_number [_delta(29, 32)]; + char dr_file_name_len [_delta(33, 33)]; + char dr_file_name [_delta(34, 34)]; +}; + +struct iso9660_dtime { + unsigned char dt_year; + unsigned char dt_month; + unsigned char dt_day; + unsigned char dt_hour; + unsigned char dt_minute; + unsigned char dt_second; + char dt_gmtoff; +}; + +struct iso9660_ltime { + char lt_year [_delta(1, 4)]; + char lt_month [_delta(5, 6)]; + char lt_day [_delta(7, 8)]; + char lt_hour [_delta(9, 10)]; + char lt_minute [_delta(11, 12)]; + char lt_second [_delta(13, 14)]; + char lt_hsecond [_delta(15, 16)]; + char lt_gmtoff [_delta(17, 17)]; +}; + +struct iso9660_path_table { + char pt_di_len [_delta(1, 1)]; + char pt_eattr_len [_delta(2, 2)]; + char pt_eattr_pos [_delta(3, 6)]; + char pt_di_parent [_delta(7, 8)]; + char pt_name [_delta(9, 9)]; +}; + +struct iso9660_eattr { + char ea_owner [_delta(1, 4)]; + char ea_group [_delta(5, 8)]; + char ea_perm [_delta(9, 10)]; + char ea_ctime [_delta(11, 27)]; + char ea_mtime [_delta(28, 44)]; + char ea_extime [_delta(45, 61)]; + char ea_eftime [_delta(62, 78)]; + char ea_record_format [_delta(79, 79)]; + char ea_record_attr [_delta(80, 80)]; + char ea_record_len [_delta(81, 84)]; + char ea_system_id [_delta(85, 116)]; + char ea_system_use [_delta(117, 180)]; + char ea_version [_delta(181, 181)]; + char ea_esc_seq_len [_delta(182, 182)]; + char ea_reserved1 [_delta(183, 246)]; + char ea_appl_use_len [_delta(247, 250)]; + char ea_appl_use [_delta(251, 251)]; /* actually more */ +/* char ea_esc_seq [_delta(xxx, xxx)]; */ + +}; + +#define PERM_MB_ONE 0xAAAA + +#define PERM_RSYS 0x0001 +#define PERM_XSYS 0x0004 + +#define PERM_RUSR 0x0010 +#define PERM_XUSR 0x0040 + +#define PERM_RGRP 0x0100 +#define PERM_XGRP 0x0400 + +#define PERM_ROTH 0x1000 +#define PERM_XOTH 0x4000 + + +#define GET_UBYTE(a) a_to_u_byte(a) +#define GET_SBYTE(a) a_to_byte(a) +#define GET_SHORT(a) a_to_u_2_byte(&((unsigned char *) (a))[0]) +#define GET_BSHORT(a) a_to_u_2_byte(&((unsigned char *) (a))[2]) +#define GET_INT(a) a_to_4_byte(&((unsigned char *) (a))[0]) +#define GET_LINT(a) la_to_4_byte(&((unsigned char *) (a))[0]) +#define GET_BINT(a) a_to_4_byte(&((unsigned char *) (a))[4]) diff --git a/wodim/isosize.c b/wodim/isosize.c new file mode 100644 index 0000000..b3f6624 --- /dev/null +++ b/wodim/isosize.c @@ -0,0 +1,86 @@ +/* + * 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. + * + */ + +/* @(#)isosize.c 1.9 04/03/02 Copyright 1996, 2001-2004 J. Schilling */ +/* + * Copyright (c) 1996, 2001-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 <statdefs.h> +#include <unixstd.h> +#include <standard.h> +#include <utypes.h> +#include <intcvt.h> + +#include "iso9660.h" +#include "wodim.h" /* to verify isosize() prototype */ + +Llong isosize(int f); + +Llong +isosize(int f) +{ + struct iso9660_voldesc vd; + struct iso9660_pr_voldesc *vp; + Llong isize; + struct stat sb; + mode_t mode; + + /* + * First check if a bad guy tries to call isosize() + * with an unappropriate file descriptor. + * return -1 in this case. + */ + if (isatty(f)) + return ((Llong)-1); + if (fstat(f, &sb) < 0) + return ((Llong)-1); + mode = sb.st_mode & S_IFMT; + if (!S_ISREG(mode) && !S_ISBLK(mode) && !S_ISCHR(mode)) + return ((Llong)-1); + + if (lseek(f, (off_t)(16L * 2048L), SEEK_SET) == -1) + return ((Llong)-1); + + vp = (struct iso9660_pr_voldesc *) &vd; + + do { + read(f, &vd, sizeof (vd)); /* FIXME: check return value */ + if (GET_UBYTE(vd.vd_type) == VD_PRIMARY) + break; + + } while (GET_UBYTE(vd.vd_type) != VD_TERM); + + lseek(f, (off_t)0L, SEEK_SET); + + if (GET_UBYTE(vd.vd_type) != VD_PRIMARY) + return (-1L); + + isize = (Llong)GET_BINT(vp->vd_volume_space_size); + isize *= GET_BSHORT(vp->vd_lbsize); + return (isize); +} diff --git a/wodim/misc.c b/wodim/misc.c new file mode 100644 index 0000000..ada60a4 --- /dev/null +++ b/wodim/misc.c @@ -0,0 +1,82 @@ +/* + * 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. + * + */ + +/* @(#)misc.c 1.4 04/03/02 Copyright 1998, 2001-2004 J. Schilling */ +/* + * Misc support functions + * + * Copyright (c) 1998, 2001-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 <timedefs.h> +#include <stdio.h> +#include <standard.h> +#include <schily.h> + +void timevaldiff(struct timeval *start, struct timeval *stop); +void prtimediff(const char *fmt, struct timeval *start, struct timeval *stop); + +void +timevaldiff(struct timeval *start, struct timeval *stop) +{ + struct timeval tv; + + tv.tv_sec = stop->tv_sec - start->tv_sec; + tv.tv_usec = stop->tv_usec - start->tv_usec; + while (tv.tv_usec > 1000000) { + tv.tv_usec -= 1000000; + tv.tv_sec += 1; + } + while (tv.tv_usec < 0) { + tv.tv_usec += 1000000; + tv.tv_sec -= 1; + } + *stop = tv; +} + +void +prtimediff(const char *fmt, struct timeval *start, struct timeval *stop) +{ + struct timeval tv; + + tv.tv_sec = stop->tv_sec - start->tv_sec; + tv.tv_usec = stop->tv_usec - start->tv_usec; + while (tv.tv_usec > 1000000) { + tv.tv_usec -= 1000000; + tv.tv_sec += 1; + } + while (tv.tv_usec < 0) { + tv.tv_usec += 1000000; + tv.tv_sec -= 1; + } + /* + * We need to cast timeval->* to long because + * of the broken sys/time.h in Linux. + */ + printf("%s%4ld.%03lds\n", fmt, (long)tv.tv_sec, (long)tv.tv_usec/1000); + flush(); +} diff --git a/wodim/mmcvendor.h b/wodim/mmcvendor.h new file mode 100644 index 0000000..3c71afc --- /dev/null +++ b/wodim/mmcvendor.h @@ -0,0 +1,87 @@ +/* + * 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. + * + */ + +/* @(#)mmcvendor.h 1.3 04/03/01 Copyright 2002-2004 J. Schilling */ +/* + * Copyright (c) 2002-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. + */ + +#ifndef _MMCVENDOR_H +#define _MMCVENDOR_H + +#include <utypes.h> +#include <btorder.h> + +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct ricoh_mode_page_30 { + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0xE = 14 Bytes */ + Ucbit BUEFS :1; /* Burn-Free supported */ + Ucbit TWBFS :1; /* Test Burn-Free sup. */ + Ucbit res_2_23 :2; + Ucbit ARSCS :1; /* Auto read speed control supp. */ + Ucbit AWSCS :1; /* Auto write speed control supp. */ + Ucbit res_2_67 :2; + Ucbit BUEFE :1; /* Burn-Free enabled */ + Ucbit res_2_13 :3; + Ucbit ARSCE :1; /* Auto read speed control enabled */ + Ucbit AWSCD :1; /* Auto write speed control disabled */ + Ucbit res_3_67 :2; + Uchar link_counter[2]; /* Burn-Free link counter */ + Uchar res[10]; /* Padding up to 16 bytes */ +}; + +#else /* Motorola bitorder */ + +struct ricoh_mode_page_30 { + MP_P_CODE; /* parsave & pagecode */ + Uchar p_len; /* 0xE = 14 Bytes */ + Ucbit res_2_67 :2; + Ucbit AWSCS :1; /* Auto write speed control supp. */ + Ucbit ARSCS :1; /* Auto read speed control supp. */ + Ucbit res_2_23 :2; + Ucbit TWBFS :1; /* Test Burn-Free sup. */ + Ucbit BUEFS :1; /* Burn-Free supported */ + Ucbit res_3_67 :2; + Ucbit AWSCD :1; /* Auto write speed control disabled */ + Ucbit ARSCE :1; /* Auto read speed control enabled */ + Ucbit res_2_13 :3; + Ucbit BUEFE :1; /* Burn-Free enabled */ + Uchar link_counter[2]; /* Burn-Free link counter */ + Uchar res[10]; /* Padding up to 16 bytes */ +}; +#endif + +struct cd_mode_vendor { + struct scsi_mode_header header; + union cd_v_pagex { + struct ricoh_mode_page_30 page30; + } pagex; +}; + + +#endif /* _MMCVENDOR_H */ diff --git a/wodim/modes.c b/wodim/modes.c new file mode 100644 index 0000000..6718352 --- /dev/null +++ b/wodim/modes.c @@ -0,0 +1,289 @@ +/* + * 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. + * + */ + +/* @(#)modes.c 1.25 04/03/02 Copyright 1988, 1997-2001, 2004 J. Schilling */ +/* + * SCSI mode page handling + * + * Copyright (c) 1988, 1997-2001, 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 <utypes.h> +#include <standard.h> +#include <schily.h> +#include <usal/usalcmd.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "wodim.h" + +int scsi_compliant; + +static BOOL has_mode_page(SCSI *usalp, int page, char *pagename, int *lenp); +BOOL get_mode_params(SCSI *usalp, int page, char *pagename, Uchar *modep, + Uchar *cmodep, Uchar *dmodep, Uchar *smodep, int *lenp); +BOOL set_mode_params(SCSI *usalp, char *pagename, Uchar *modep, int len, + int save, int secsize); + +#define XXX + +#ifdef XXX +static BOOL +has_mode_page(SCSI *usalp, int page, char *pagename, int *lenp) +{ + Uchar mode[0x100]; + int hdlen; + int len = 1; /* Nach SCSI Norm */ + int try = 0; + struct scsi_mode_page_header *mp; + + /* + * ATAPI drives (used e.g. by IOMEGA) from y2k have the worst firmware + * I've seen. They create DMA buffer overruns if we request less than + * 3 bytes with 6 byte mode sense which equals 4 byte with 10 byte mode + * sense. In order to prevent repeated bus resets, we remember this + * bug. + * + * IOMEGA claims that they are using Philips clone drives but a Philips + * drive I own does not have the problem. + */ + if ((usalp->dflags & DRF_MODE_DMA_OVR) != 0) + len = sizeof (struct scsi_mode_header); +again: + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + if (lenp) + *lenp = 0; + + usalp->silent++; + (void) unit_ready(usalp); +/* Maxoptix bringt Aborted cmd 0x0B mit code 0x4E (overlapping cmds)*/ + + /* + * The Matsushita CW-7502 will sometimes deliver a zeroed + * mode page 2A if "Page n default" is used instead of "current". + */ + if (mode_sense(usalp, mode, len, page, 0) < 0) { /* Page n current */ + usalp->silent--; + if (len < (int)sizeof (struct scsi_mode_header) && try == 0) { + len = sizeof (struct scsi_mode_header); + goto again; + } + return (FALSE); + } else { + if (len > 1 && try == 0) { + /* + * If we come here, we got a hard failure with the + * fist try. Remember this (IOMEGA USB) firmware bug. + */ + if ((usalp->dflags & DRF_MODE_DMA_OVR) == 0) { + /* XXX if (!nowarn) */ + errmsgno(EX_BAD, + "Warning: controller creates hard SCSI failure when retrieving %s page.\n", + pagename); + usalp->dflags |= DRF_MODE_DMA_OVR; + } + } + len = ((struct scsi_mode_header *)mode)->sense_data_len + 1; + } + /* + * ATAPI drives as used by IOMEGA may receive a SCSI bus device reset + * in between these two mode sense commands. + */ + (void) unit_ready(usalp); + if (mode_sense(usalp, mode, len, page, 0) < 0) { /* Page n current */ + usalp->silent--; + return (FALSE); + } + usalp->silent--; + + if (usalp->verbose) + usal_prbytes("Mode Sense Data", mode, len - usal_getresid(usalp)); + hdlen = sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len; + mp = (struct scsi_mode_page_header *)(mode + hdlen); + if (usalp->verbose) + usal_prbytes("Mode Page Data", (Uchar *)mp, mp->p_len+2); + + if (mp->p_len == 0) { + if (!scsi_compliant && try == 0) { + len = hdlen; + /* + * add sizeof page header (page # + len byte) + * (should normaly result in len == 14) + * this allowes to work with: + * Quantum Q210S (wants at least 13) + * MD2x (wants at least 4) + */ + len += 2; + try++; + goto again; + } + /* XXX if (!nowarn) */ + errmsgno(EX_BAD, + "Warning: controller returns zero sized %s page.\n", + pagename); + } + if (!scsi_compliant && + (len < (int)(mp->p_len + hdlen + 2))) { + len = mp->p_len + hdlen + 2; + + /* XXX if (!nowarn) */ + errmsgno(EX_BAD, + "Warning: controller returns wrong size for %s page.\n", + pagename); + } + if (mp->p_code != page) { + /* XXX if (!nowarn) */ + errmsgno(EX_BAD, + "Warning: controller returns wrong page %X for %s page (%X).\n", + mp->p_code, pagename, page); + return (FALSE); + } + + if (lenp) + *lenp = len; + return (mp->p_len > 0); +} +#endif + +BOOL +get_mode_params(SCSI *usalp, int page, char *pagename, Uchar *modep, + Uchar *cmodep, Uchar *dmodep, Uchar *smodep, int *lenp) +{ + int len; + BOOL ret = TRUE; + +#ifdef XXX + if (lenp) + *lenp = 0; + if (!has_mode_page(usalp, page, pagename, &len)) { + if (!usalp->silent) errmsgno(EX_BAD, + "Warning: controller does not support %s page.\n", + pagename); + return (FALSE); + } + if (lenp) + *lenp = len; +#else + if (lenp == 0) + len = 0xFF; +#endif + + if (modep) { + fillbytes(modep, 0x100, '\0'); + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + if (mode_sense(usalp, modep, len, page, 0) < 0) { /* Page x current */ + errmsgno(EX_BAD, "Cannot get %s data.\n", pagename); + ret = FALSE; + } else if (usalp->verbose) { + usal_prbytes("Mode Sense Data", modep, len - usal_getresid(usalp)); + } + } + + if (cmodep) { + fillbytes(cmodep, 0x100, '\0'); + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + if (mode_sense(usalp, cmodep, len, page, 1) < 0) { /* Page x change */ + errmsgno(EX_BAD, "Cannot get %s mask.\n", pagename); + ret = FALSE; + } else if (usalp->verbose) { + usal_prbytes("Mode Sense Data", cmodep, len - usal_getresid(usalp)); + } + } + + if (dmodep) { + fillbytes(dmodep, 0x100, '\0'); + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + if (mode_sense(usalp, dmodep, len, page, 2) < 0) { /* Page x default */ + errmsgno(EX_BAD, "Cannot get default %s data.\n", + pagename); + ret = FALSE; + } else if (usalp->verbose) { + usal_prbytes("Mode Sense Data", dmodep, len - usal_getresid(usalp)); + } + } + + if (smodep) { + fillbytes(smodep, 0x100, '\0'); + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + if (mode_sense(usalp, smodep, len, page, 3) < 0) { /* Page x saved */ + errmsgno(EX_BAD, "Cannot get saved %s data.\n", pagename); + ret = FALSE; + } else if (usalp->verbose) { + usal_prbytes("Mode Sense Data", smodep, len - usal_getresid(usalp)); + } + } + + return (ret); +} + +BOOL +set_mode_params(SCSI *usalp, char *pagename, Uchar *modep, int len, int save, + int secsize) +{ + int i; + + ((struct scsi_modesel_header *)modep)->sense_data_len = 0; + ((struct scsi_modesel_header *)modep)->res2 = 0; + + i = ((struct scsi_mode_header *)modep)->blockdesc_len; + if (i > 0) { + i_to_3_byte( + ((struct scsi_mode_data *)modep)->blockdesc.nlblock, + 0); + if (secsize >= 0) + i_to_3_byte(((struct scsi_mode_data *)modep)->blockdesc.lblen, + secsize); + } + + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + if (save == 0 || mode_select(usalp, modep, len, save, usalp->inq->data_format >= 2) < 0) { + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + if (mode_select(usalp, modep, len, 0, usalp->inq->data_format >= 2) < 0) { + if (usalp->silent == 0) { + errmsgno(EX_BAD, + "Warning: using default %s data.\n", + pagename); + usal_prbytes("Mode Select Data", modep, len); + } + return (FALSE); + } + } + return (TRUE); +} diff --git a/wodim/movesect.c b/wodim/movesect.c new file mode 100644 index 0000000..ef4bc70 --- /dev/null +++ b/wodim/movesect.c @@ -0,0 +1,104 @@ +/* + * 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. + * + */ + +/* @(#)movesect.c 1.3 04/03/02 Copyright 2001, 2004 J. Schilling */ +/* + * Copyright (c) 2001, 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 <standard.h> +#include <utypes.h> +#include <schily.h> + +#include "wodim.h" +#include "movesect.h" + +void scatter_secs(track_t *trackp, char *bp, int nsecs); + +/* + * Scatter input sector size records over buffer to make them + * output sector size. + * + * If input sector size is less than output sector size, + * + * | sector_0 || sector_1 || ... || sector_n || + * + * will be convterted into: + * + * | sector_0 |grass|| sector_1 |grass|| ... || sector_n |grass|| + * + * Sector_n must me moved n * grass_size forward, + * Sector_1 must me moved 1 * grass_size forward + * + * + * If output sector size is less than input sector size, + * + * | sector_0 |grass|| sector_1 |grass|| ... || sector_n |grass|| + * + * will be convterted into: + * + * | sector_0 || sector_1 || ... || sector_n || + * + * Sector_1 must me moved 1 * grass_size backward, + * Sector_n must me moved n * grass_size backward, + * + * Sector_0 must never be moved. + */ +void +scatter_secs(track_t *trackp, char *bp, int nsecs) +{ + char *from; + char *to; + int isecsize = trackp->isecsize; + int secsize = trackp->secsize; + int i; + + if (secsize == isecsize) + return; + + nsecs -= 1; /* we do not move sector # 0 */ + + if (secsize < isecsize) { + from = bp + isecsize; + to = bp + secsize; + + for (i = nsecs; i > 0; i--) { + movebytes(from, to, secsize); + from += isecsize; + to += secsize; + } + } else { + from = bp + (nsecs * isecsize); + to = bp + (nsecs * secsize); + + for (i = nsecs; i > 0; i--) { + movebytes(from, to, isecsize); + from -= isecsize; + to -= secsize; + } + } +} diff --git a/wodim/movesect.h b/wodim/movesect.h new file mode 100644 index 0000000..64f09b7 --- /dev/null +++ b/wodim/movesect.h @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +/* @(#)movesect.h 1.1 01/06/02 Copyright 2001 J. Schilling */ +/* + * Copyright (c) 2001 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. + */ + +#ifndef _MOVESECT_H +#define _MOVESECT_H + +#define move2352(from, to) movebytes(from, to, 2352) +#define move2336(from, to) movebytes(from, to, 2336) +#define move2048(from, to) movebytes(from, to, 2048) + +#define fill2352(p, val) fillbytes(p, 2352, val) +#define fill2048(p, val) fillbytes(p, 2048, val) +#define fill96(p, val) fillbytes(p, 96, val) + +extern void scatter_secs(track_t *trackp, char *bp, int nsecs); + +#endif diff --git a/wodim/scsi_cdr.c b/wodim/scsi_cdr.c new file mode 100644 index 0000000..fbb8270 --- /dev/null +++ b/wodim/scsi_cdr.c @@ -0,0 +1,2918 @@ +/* + * 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. + * + */ + +/* @(#)scsi_cdr.c 1.137 04/05/25 Copyright 1995-2004 J. Schilling */ +/* + * SCSI command functions for cdrecord + * covering pre-MMC standard functions up to MMC-2 + * + * Copyright (c) 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. + */ + +/* + * NOTICE: The Philips CDD 521 has several firmware bugs. + * One of them is not to respond to a SCSI selection + * within 200ms if the general load on the + * SCSI bus is high. To deal with this problem + * most of the SCSI commands are send with the + * SCG_CMD_RETRY flag enabled. + */ +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "scsimmc.h" +#include "wodim.h" +#include "scsi_scan.h" + +#define strbeg(s1, s2) (strstr((s2), (s1)) == (s2)) + +BOOL unit_ready(SCSI *usalp); +BOOL wait_unit_ready(SCSI *usalp, int secs); +BOOL scsi_in_progress(SCSI *usalp); +BOOL cdr_underrun(SCSI *usalp); +int test_unit_ready(SCSI *usalp); +int rezero_unit(SCSI *usalp); +int request_sense(SCSI *usalp); +int request_sense_b(SCSI *usalp, caddr_t bp, int cnt); +int inquiry(SCSI *usalp, caddr_t, int); +int read_capacity(SCSI *usalp); +void print_capacity(SCSI *usalp, FILE *f); +int scsi_load_unload(SCSI *usalp, int); +int scsi_prevent_removal(SCSI *usalp, int); +int scsi_start_stop_unit(SCSI *usalp, int, int, BOOL immed); +int scsi_set_speed(SCSI *usalp, int readspeed, int writespeed, int rotctl); +int scsi_get_speed(SCSI *usalp, int *readspeedp, int *writespeedp); +int qic02(SCSI *usalp, int); +int write_xscsi(SCSI *usalp, caddr_t, long, long, int); +int write_xg0(SCSI *usalp, caddr_t, long, long, int); +int write_xg1(SCSI *usalp, caddr_t, long, long, int); +int write_xg5(SCSI *usalp, caddr_t, long, long, int); +int seek_scsi(SCSI *usalp, long addr); +int seek_g0(SCSI *usalp, long addr); +int seek_g1(SCSI *usalp, long addr); +int scsi_flush_cache(SCSI *usalp, BOOL immed); +int read_buffer(SCSI *usalp, caddr_t bp, int cnt, int mode); +int write_buffer(SCSI *usalp, char *buffer, long length, int mode, + int bufferid, long offset); +int read_subchannel(SCSI *usalp, caddr_t bp, int track, int cnt, int msf, + int subq, int fmt); +int read_toc(SCSI *usalp, caddr_t, int, int, int, int); +int read_toc_philips(SCSI *usalp, caddr_t, int, int, int, int); +int read_header(SCSI *usalp, caddr_t, long, int, int); +int read_disk_info(SCSI *usalp, caddr_t, int); +int read_track_info(SCSI *usalp, caddr_t, int type, int addr, int cnt); +int read_rzone_info(SCSI *usalp, caddr_t bp, int cnt); +int reserve_tr_rzone(SCSI *usalp, long size); +int read_dvd_structure(SCSI *usalp, caddr_t bp, int cnt, int addr, int layer, + int fmt); +int send_dvd_structure(SCSI *usalp, caddr_t bp, int cnt, int layer, int fmt); +int send_opc(SCSI *usalp, caddr_t, int cnt, int doopc); +int read_track_info_philips(SCSI *usalp, caddr_t, int, int); +int scsi_close_tr_session(SCSI *usalp, int type, int track, BOOL immed); +int read_master_cue(SCSI *usalp, caddr_t bp, int sheet, int cnt); +int send_cue_sheet(SCSI *usalp, caddr_t bp, long size); +int read_buff_cap(SCSI *usalp, long *, long *); +int scsi_blank(SCSI *usalp, long addr, int blanktype, BOOL immed); +int scsi_format(SCSI *usalp, caddr_t addr, int size, BOOL background); +int scsi_set_streaming(SCSI *usalp, caddr_t addr, int size); +BOOL allow_atapi(SCSI *usalp, BOOL new); +int mode_select(SCSI *usalp, Uchar *, int, int, int); +int mode_sense(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +int mode_select_sg0(SCSI *usalp, Uchar *, int, int, int); +int mode_sense_sg0(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +int mode_select_g0(SCSI *usalp, Uchar *, int, int, int); +int mode_select_g1(SCSI *usalp, Uchar *, int, int, int); +int mode_sense_g0(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +int mode_sense_g1(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +int read_tochdr(SCSI *usalp, cdr_t *, int *, int *); +int read_cdtext(SCSI *usalp); +int read_trackinfo(SCSI *usalp, int, long *, struct msf *, int *, int *, + int *); +int read_B0(SCSI *usalp, BOOL isbcd, long *b0p, long *lop); +int read_session_offset(SCSI *usalp, long *); +int read_session_offset_philips(SCSI *usalp, long *); +int sense_secsize(SCSI *usalp, int current); +int select_secsize(SCSI *usalp, int); +BOOL is_cddrive(SCSI *usalp); +BOOL is_unknown_dev(SCSI *usalp); +int read_scsi(SCSI *usalp, caddr_t, long, int); +int read_g0(SCSI *usalp, caddr_t, long, int); +int read_g1(SCSI *usalp, caddr_t, long, int); +BOOL getdev(SCSI *usalp, BOOL); +void printinq(SCSI *usalp, FILE *f); +void printdev(SCSI *usalp); +BOOL do_inquiry(SCSI *usalp, BOOL); +BOOL recovery_needed(SCSI *usalp, cdr_t *); +int scsi_load(SCSI *usalp, cdr_t *); +int scsi_unload(SCSI *usalp, cdr_t *); +int scsi_cdr_write(SCSI *usalp, caddr_t bp, long sectaddr, long size, + int blocks, BOOL islast); +struct cd_mode_page_2A * mmc_cap(SCSI *usalp, Uchar *modep); +void mmc_getval(struct cd_mode_page_2A *mp, BOOL *cdrrp, BOOL *cdwrp, + BOOL *cdrrwp, BOOL *cdwrwp, BOOL *dvdp, BOOL *dvdwp); +BOOL is_mmc(SCSI *usalp, BOOL *cdwp, BOOL *dvdwp); +BOOL mmc_check(SCSI *usalp, BOOL *cdrrp, BOOL *cdwrp, BOOL *cdrrwp, + BOOL *cdwrwp, BOOL *dvdp, BOOL *dvdwp); +static void print_speed(char *fmt, int val); +void print_capabilities(SCSI *usalp); + +BOOL +unit_ready(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (test_unit_ready(usalp) >= 0) /* alles OK */ + return (TRUE); + else if (scmd->error >= SCG_FATAL) /* nicht selektierbar */ + return (FALSE); + + if (usal_sense_key(usalp) == SC_UNIT_ATTENTION) { + if (test_unit_ready(usalp) >= 0) /* alles OK */ + return (TRUE); + } + if ((usal_cmd_status(usalp) & ST_BUSY) != 0) { + /* + * Busy/reservation_conflict + */ + usleep(500000); + if (test_unit_ready(usalp) >= 0) /* alles OK */ + return (TRUE); + } + if (usal_sense_key(usalp) == -1) { /* non extended Sense */ + if (usal_sense_code(usalp) == 4) /* NOT_READY */ + return (FALSE); + return (TRUE); + } + /* FALSE wenn NOT_READY */ + return (usal_sense_key(usalp) != SC_NOT_READY); +} + +BOOL +wait_unit_ready(SCSI *usalp, int secs) +{ + int i; + int c; + int k; + int ret; + + usalp->silent++; + ret = test_unit_ready(usalp); /* eat up unit attention */ + if (ret < 0) + ret = test_unit_ready(usalp); /* got power on condition? */ + usalp->silent--; + + if (ret >= 0) /* success that's enough */ + return (TRUE); + + usalp->silent++; + for (i = 0; i < secs && (ret = test_unit_ready(usalp)) < 0; i++) { + if (usalp->scmd->scb.busy != 0) { + sleep(1); + continue; + } + c = usal_sense_code(usalp); + k = usal_sense_key(usalp); + /* + * Abort quickly if it does not make sense to wait. + * 0x30 == Cannot read medium + * 0x3A == Medium not present + */ + if ((k == SC_NOT_READY && (c == 0x3A || c == 0x30)) || + (k == SC_MEDIUM_ERROR)) { + if (usalp->silent <= 1) + usal_printerr(usalp); + usalp->silent--; + return (FALSE); + } + sleep(1); + } + usalp->silent--; + if (ret < 0) + return (FALSE); + return (TRUE); +} + +BOOL +scsi_in_progress(SCSI *usalp) +{ + if (usal_sense_key(usalp) == SC_NOT_READY && + /* + * Logigal unit not ready operation/long_write in progress + */ + usal_sense_code(usalp) == 0x04 && + (usal_sense_qual(usalp) == 0x04 || /* CyberDr. "format in progress"*/ + usal_sense_qual(usalp) == 0x07 || /* "operation in progress" */ + usal_sense_qual(usalp) == 0x08)) { /* "long write in progress" */ + return (TRUE); + } else { + if (usalp->silent <= 1) + usal_printerr(usalp); + } + return (FALSE); +} + +BOOL +cdr_underrun(SCSI *usalp) +{ + if ((usal_sense_key(usalp) != SC_ILLEGAL_REQUEST && + usal_sense_key(usalp) != SC_MEDIUM_ERROR)) + return (FALSE); + + if ((usal_sense_code(usalp) == 0x21 && + (usal_sense_qual(usalp) == 0x00 || /* logical block address out of range */ + usal_sense_qual(usalp) == 0x02)) || /* invalid address for write */ + + (usal_sense_code(usalp) == 0x0C && + usal_sense_qual(usalp) == 0x09)) { /* write error - loss of streaming */ + return (TRUE); + } + /* + * XXX Bei manchen Brennern kommt mach dem der Brennvorgang bereits + * XXX eine Weile gelaufen ist ein 5/24/0 Invalid field in CDB. + * XXX Daher sollte man testen ob schon geschrieben wurde... + */ + return (FALSE); +} + +int +test_unit_ready(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA | (usalp->silent ? SCG_SILENT:0); + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_TEST_UNIT_READY; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "test unit ready"; + + return (usal_cmd(usalp)); +} + +int +rezero_unit(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_REZERO_UNIT; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + + usalp->cmdname = "rezero unit"; + + return (usal_cmd(usalp)); +} + +int +request_sense(SCSI *usalp) +{ + char sensebuf[CCS_SENSE_LEN]; + register struct usal_cmd *scmd = usalp->scmd; + + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = sensebuf; + scmd->size = sizeof (sensebuf); + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_REQUEST_SENSE; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.count = CCS_SENSE_LEN; + + usalp->cmdname = "request_sense"; + + if (usal_cmd(usalp) < 0) + return (-1); + usal_prsense((Uchar *)sensebuf, CCS_SENSE_LEN - usal_getresid(usalp)); + return (0); +} + +int +request_sense_b(SCSI *usalp, caddr_t bp, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_REQUEST_SENSE; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.count = cnt; + + usalp->cmdname = "request_sense"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +inquiry(SCSI *usalp, caddr_t bp, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes(bp, cnt, '\0'); + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_INQUIRY; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.count = cnt; + + usalp->cmdname = "inquiry"; + + if (usal_cmd(usalp) < 0) + return (-1); + if (usalp->verbose) + usal_prbytes("Inquiry Data :", (Uchar *)bp, cnt - usal_getresid(usalp)); + return (0); +} + +int +read_capacity(SCSI *usalp) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)usalp->cap; + scmd->size = sizeof (struct scsi_capacity); + 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 = 0x25; /* Read Capacity */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, 0); /* Full Media */ + + usalp->cmdname = "read capacity"; + + if (usal_cmd(usalp) < 0) { + return (-1); + } else { + long cbsize; + long cbaddr; + + /* + * c_bsize & c_baddr are signed Int32_t + * so we use signed int conversion here. + */ + cbsize = a_to_4_byte(&usalp->cap->c_bsize); + cbaddr = a_to_4_byte(&usalp->cap->c_baddr); + usalp->cap->c_bsize = cbsize; + usalp->cap->c_baddr = cbaddr; + } + return (0); +} + +void +print_capacity(SCSI *usalp, FILE *f) +{ + long kb; + long mb; + long prmb; + double dkb; + + dkb = (usalp->cap->c_baddr+1.0) * (usalp->cap->c_bsize/1024.0); + kb = dkb; + mb = dkb / 1024.0; + prmb = dkb / 1000.0 * 1.024; + fprintf(f, "Capacity: %ld Blocks = %ld kBytes = %ld MBytes = %ld prMB\n", + (long)usalp->cap->c_baddr+1, kb, mb, prmb); + fprintf(f, "Sectorsize: %ld Bytes\n", (long)usalp->cap->c_bsize); +} + +int +scsi_load_unload(SCSI *usalp, int load) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xA6; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + scmd->cdb.g5_cdb.addr[1] = load?3:2; + scmd->cdb.g5_cdb.count[2] = 0; /* slot # */ + + usalp->cmdname = "medium load/unload"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +scsi_prevent_removal(SCSI *usalp, int prevent) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = 0x1E; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.count = prevent & 1; + + usalp->cmdname = "prevent/allow medium removal"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + + +int +scsi_start_stop_unit(SCSI *usalp, int flg, int loej, BOOL immed) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = 0x1B; /* Start Stop Unit */ + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.count = (flg ? 1:0) | (loej ? 2:0); + + if (immed) + scmd->cdb.cmd_cdb[1] |= 0x01; + + usalp->cmdname = "start/stop unit"; + + return (usal_cmd(usalp)); +} + +int +scsi_set_streaming(SCSI *usalp, caddr_t perf_desc, int size) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = perf_desc; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xB6; + scmd->cdb.cmd_cdb[11] = 0; + scmd->cdb.cmd_cdb[10] = size; + + usalp->cmdname = "set streaming"; + + if(usalp->verbose) + fprintf(stderr, "scsi_set_streaming\n"); + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +scsi_set_speed(SCSI *usalp, int readspeed, int writespeed, int rotctl) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xBB; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + + if (readspeed < 0) + i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], 0xFFFF); + else + i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], readspeed); + if (writespeed < 0) + i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], 0xFFFF); + else + i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], writespeed); + + scmd->cdb.cmd_cdb[1] |= rotctl & 0x03; + + usalp->cmdname = "set cd speed"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +scsi_get_speed(SCSI *usalp, int *readspeedp, int *writespeedp) +{ + struct cd_mode_page_2A *mp; + Uchar m[256]; + int val; + + usalp->silent++; + mp = mmc_cap(usalp, m); /* Get MMC capabilities in allocated mp */ + usalp->silent--; + if (mp == NULL) + return (-1); /* Pre SCSI-3/mmc drive */ + + val = a_to_u_2_byte(mp->cur_read_speed); + if (readspeedp) + *readspeedp = val; + + if (mp->p_len >= 28) + val = a_to_u_2_byte(mp->v3_cur_write_speed); + else + val = a_to_u_2_byte(mp->cur_write_speed); + if (writespeedp) + *writespeedp = val; + + return (0); +} + + +int +qic02(SCSI *usalp, int cmd) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = DEF_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = 0x0D; /* qic02 Sysgen SC4000 */ + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.mid_addr = cmd; + + usalp->cmdname = "qic 02"; + return (usal_cmd(usalp)); +} + +#define G0_MAXADDR 0x1FFFFFL + +int +write_xscsi(SCSI *usalp, caddr_t bp, long addr, long size, int cnt) +{ + if (addr <= G0_MAXADDR) + return (write_xg0(usalp, bp, addr, size, cnt)); + else + return (write_xg1(usalp, bp, addr, size, cnt)); +} + +int +write_xg0(SCSI *usalp, + caddr_t bp /* address of buffer */, + long addr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int cnt /* sectorcount */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; +/* 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 = usal_lun(usalp); + g0_cdbaddr(&scmd->cdb.g0_cdb, addr); + scmd->cdb.g0_cdb.count = cnt; + + usalp->cmdname = "write_g0"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (size - usal_getresid(usalp)); +} + +int +write_xg1(SCSI *usalp, + caddr_t bp /* address of buffer */, + long addr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int cnt /* sectorcount */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; +/* 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 = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "write_g1"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (size - usal_getresid(usalp)); +} + +int +write_xg5(SCSI *usalp, + caddr_t bp /* address of buffer */, + long addr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int cnt /* sectorcount */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; +/* scmd->flags = SCG_DISRE_ENA;*/ + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g5_cdb.cmd = 0xAA; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + g5_cdbaddr(&scmd->cdb.g5_cdb, addr); + g5_cdblen(&scmd->cdb.g5_cdb, cnt); + + usalp->cmdname = "write_g5"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (size - usal_getresid(usalp)); +} + +int +seek_scsi(SCSI *usalp, long addr) +{ + if (addr <= G0_MAXADDR) + return (seek_g0(usalp, addr)); + else + return (seek_g1(usalp, addr)); +} + +int +seek_g0(SCSI *usalp, long addr) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = 0x0B; /* Seek */ + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + g0_cdbaddr(&scmd->cdb.g0_cdb, addr); + + usalp->cmdname = "seek_g0"; + + return (usal_cmd(usalp)); +} + +int +seek_g1(SCSI *usalp, long addr) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x2B; /* Seek G1 */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); + + usalp->cmdname = "seek_g1"; + + return (usal_cmd(usalp)); +} + +int +scsi_flush_cache(SCSI *usalp, BOOL immed) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 2 * 60; /* Max: sizeof (CDR-cache)/150KB/s */ + scmd->cdb.g1_cdb.cmd = 0x35; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + if (immed) + scmd->cdb.cmd_cdb[1] |= 0x02; + + usalp->cmdname = "flush cache"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_buffer(SCSI *usalp, caddr_t bp, int cnt, int mode) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->dma_read = 1; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x3C; /* Read Buffer */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.cmd_cdb[1] |= (mode & 7); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read buffer"; + + return (usal_cmd(usalp)); +} + +int +write_buffer(SCSI *usalp, char *buffer, long length, int mode, int bufferid, + long offset) +{ + register struct usal_cmd *scmd = usalp->scmd; + char *cdb; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = buffer; + scmd->size = length; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + + cdb = (char *)scmd->cdb.cmd_cdb; + + cdb[0] = 0x3B; + cdb[1] = mode & 7; + cdb[2] = bufferid; + cdb[3] = offset >> 16; + cdb[4] = (offset >> 8) & 0xff; + cdb[5] = offset & 0xff; + cdb[6] = length >> 16; + cdb[7] = (length >> 8) & 0xff; + cdb[8] = length & 0xff; + + usalp->cmdname = "write_buffer"; + + if (usal_cmd(usalp) >= 0) + return (1); + return (0); +} + +int +read_subchannel(SCSI *usalp, caddr_t bp, int track, int cnt, int msf, int subq, + int fmt) + +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + 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 = 0x42; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + if (msf) + scmd->cdb.g1_cdb.res = 1; + if (subq) + scmd->cdb.g1_cdb.addr[0] = 0x40; + scmd->cdb.g1_cdb.addr[1] = fmt; + scmd->cdb.g1_cdb.res6 = track; + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read subchannel"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_toc(SCSI *usalp, caddr_t bp, int track, int cnt, int msf, int fmt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + 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 = 0x43; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + if (msf) + scmd->cdb.g1_cdb.res = 1; + scmd->cdb.g1_cdb.addr[0] = fmt & 0x0F; + scmd->cdb.g1_cdb.res6 = track; + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read toc"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_toc_philips(SCSI *usalp, caddr_t bp, int track, int cnt, int msf, int fmt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 4 * 60; /* May last 174s on a TEAC CD-R55S */ + scmd->cdb.g1_cdb.cmd = 0x43; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + if (msf) + scmd->cdb.g1_cdb.res = 1; + scmd->cdb.g1_cdb.res6 = track; + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + if (fmt & 1) + scmd->cdb.g1_cdb.vu_96 = 1; + if (fmt & 2) + scmd->cdb.g1_cdb.vu_97 = 1; + + usalp->cmdname = "read toc"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_header(SCSI *usalp, caddr_t bp, long addr, int cnt, int msf) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + 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 = 0x44; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + if (msf) + scmd->cdb.g1_cdb.res = 1; + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read header"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_disk_info(SCSI *usalp, caddr_t bp, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 4 * 60; /* Needs up to 2 minutes */ + scmd->cdb.g1_cdb.cmd = 0x51; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read disk info"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_track_info(SCSI *usalp, caddr_t bp, int type, int addr, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 4 * 60; /* Needs up to 2 minutes */ + scmd->cdb.g1_cdb.cmd = 0x52; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); +/* scmd->cdb.cmd_cdb[1] = type & 0x03;*/ + scmd->cdb.cmd_cdb[1] = type; + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); /* LBA/Track/Session */ + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read track info"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +reserve_track(SCSI *usalp, Ulong size) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x53; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], size); + + usalp->cmdname = "reserve track"; + + if (usal_cmd(usalp) < 0) + return (-1); + + return (0); + +} + +int +read_rzone_info(SCSI *usalp, caddr_t bp, int cnt) +{ + return (read_track_info(usalp, bp, TI_TYPE_LBA, 0, cnt)); +} + +int +reserve_tr_rzone(SCSI *usalp, long size /* number of blocks */) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)0; + scmd->size = 0; + scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x53; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + + i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], size); + + usalp->cmdname = "reserve_track_rzone"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_dvd_structure(SCSI *usalp, caddr_t bp, int cnt, int addr, int layer, + int fmt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 4 * 60; /* Needs up to 2 minutes ??? */ + scmd->cdb.g5_cdb.cmd = 0xAD; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + g5_cdbaddr(&scmd->cdb.g5_cdb, addr); + g5_cdblen(&scmd->cdb.g5_cdb, cnt); + scmd->cdb.g5_cdb.count[0] = layer; + scmd->cdb.g5_cdb.count[1] = fmt; + + usalp->cmdname = "read dvd structure"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +send_dvd_structure(SCSI *usalp, caddr_t bp, int cnt, int layer, int fmt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 4 * 60; /* Needs up to 2 minutes ??? */ + scmd->cdb.g5_cdb.cmd = 0xBF; + scmd->cdb.g5_cdb.lun = usal_lun(usalp); + g5_cdblen(&scmd->cdb.g5_cdb, cnt); + + scmd->cdb.cmd_cdb[7] = fmt; + + usalp->cmdname = "send dvd structure"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +send_opc(SCSI *usalp, caddr_t bp, int cnt, int doopc) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 60; + scmd->cdb.g1_cdb.cmd = 0x54; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.reladr = doopc?1:0; + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "send opc"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_track_info_philips(SCSI *usalp, caddr_t bp, int track, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + 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 = 0xE5; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, track); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read track info"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +scsi_close_tr_session(SCSI *usalp, int type, int track, BOOL immed) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 8 * 60; /* Needs up to 4 minutes */ + scmd->cdb.g1_cdb.cmd = 0x5B; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[0] = type; + scmd->cdb.g1_cdb.addr[3] = track; + + if (immed) + scmd->cdb.g1_cdb.reladr = 1; +/* scmd->cdb.cmd_cdb[1] |= 0x01;*/ +#ifdef nono + scmd->cdb.g1_cdb.reladr = 1; /* IMM hack to test Mitsumi behaviour*/ +#endif + + usalp->cmdname = "close track/session"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +read_master_cue(SCSI *usalp, caddr_t bp, int sheet, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + 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 = 0x59; /* Read master cue */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g1_cdb.addr[2] = sheet; + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read master cue"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (0); +} + +int +send_cue_sheet(SCSI *usalp, caddr_t bp, long size) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x5D; /* Send CUE sheet */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, size); + + usalp->cmdname = "send_cue_sheet"; + + if (usal_cmd(usalp) < 0) + return (-1); + return (size - scmd->resid); +} + +int +read_buff_cap(SCSI *usalp, long *sp, long *fp) +{ + char resp[12]; + Ulong freespace; + Ulong bufsize; + int per; + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)resp; + scmd->size = sizeof (resp); + 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 = 0x5C; /* Read buffer cap */ + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdblen(&scmd->cdb.g1_cdb, sizeof (resp)); + + usalp->cmdname = "read buffer cap"; + + if (usal_cmd(usalp) < 0) + return (-1); + + bufsize = a_to_u_4_byte(&resp[4]); + freespace = a_to_u_4_byte(&resp[8]); + if (sp) + *sp = bufsize; + if (fp) + *fp = freespace; + + if (usalp->verbose || (sp == 0 && fp == 0)) + printf("BFree: %ld K BSize: %ld K\n", freespace >> 10, bufsize >> 10); + + if (bufsize == 0) + return (0); + per = (100 * (bufsize - freespace)) / bufsize; + if (per < 0) + return (0); + if (per > 100) + return (100); + return (per); +} + +int +scsi_blank(SCSI *usalp, long addr, int blanktype, BOOL immed) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 160 * 60; /* full blank at 1x could take 80 minutes */ + scmd->cdb.g5_cdb.cmd = 0xA1; /* Blank */ + scmd->cdb.g0_cdb.high_addr = blanktype; + g1_cdbaddr(&scmd->cdb.g5_cdb, addr); + + if (immed) + scmd->cdb.g5_cdb.res |= 8; +/* scmd->cdb.cmd_cdb[1] |= 0x10;*/ + + usalp->cmdname = "blank unit"; + + return (usal_cmd(usalp)); +} + +int +scsi_format(SCSI *usalp, caddr_t addr, int size, BOOL background) +{ + register struct usal_cmd *scmd = usalp->scmd; + int progress=0, ret=-1, pid=-1; + unsigned char sense_table[18]; + int i; + + printf("scsi_format: preparing\n"); + + fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + scmd->addr = addr; + scmd->size = size; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G5_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->timeout = 160 * 60; /* Do not know what to set */ + scmd->cdb.g5_cdb.cmd = 0x04; /* Format Unit */ + scmd->cdb.cmd_cdb[1] = 0x11; /* "FmtData" and "Format Code" */ + scmd->cdb.cmd_cdb[5] = 0; + + usalp->cmdname = "format unit"; + + printf("scsi_format: running\n"); + ret = (usal_cmd(usalp)); + printf("scsi_format: post processing %d\n", ret); + if (ret == -1) return ret; + if (background) { + if ((pid=fork()) == (pid_t)-1) + perror ("- [unable to fork()]"); + else { + if (!pid) { + while (1) { + if (test_unit_ready(usalp) >= 0) + break; + sleep(1); + } + return ret; + } + } + } + printf("Formating in progress: 0.00 %% done."); + sleep(20); + i = 0; + while (progress < 0xfff0 && !(progress == 0 && i > 50)) { + test_unit_ready(usalp); + request_sense_b(usalp, (caddr_t)sense_table, 18); + progress = sense_table[16]<<8|sense_table[17]; + printf("\rFormating in progress: %.2f %% done [%d]. ", (float)(progress*100)/0x10000,progress); + usleep(100000); + i++; + /*for (i=0; i < 18; i++) { + printf("%d ", sense_table[i]); + }*/ + } + sleep(10); + printf("\rFormating in progress: 100.00 %% done. \n"); + if (pid) exit (0); + return ret; +} + +/* + * XXX First try to handle ATAPI: + * XXX ATAPI cannot handle SCSI 6 byte commands. + * XXX We try to simulate 6 byte mode sense/select. + */ +static BOOL is_atapi; + +BOOL +allow_atapi(SCSI *usalp, BOOL new) +{ + BOOL old = is_atapi; + Uchar mode[256]; + + if (new == old) + return (old); + + usalp->silent++; + /* + * If a bad drive has been reset before, we may need to fire up two + * test unit ready commands to clear status. + */ + (void) unit_ready(usalp); + if (new && + mode_sense_g1(usalp, mode, 8, 0x3F, 0) < 0) { /* All pages current */ + new = FALSE; + } + usalp->silent--; + + is_atapi = new; + return (old); +} + +int +mode_select(SCSI *usalp, Uchar *dp, int cnt, int smp, int pf) +{ + if (is_atapi) + return (mode_select_sg0(usalp, dp, cnt, smp, pf)); + return (mode_select_g0(usalp, dp, cnt, smp, pf)); +} + +int +mode_sense(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf) +{ + if (is_atapi) + return (mode_sense_sg0(usalp, dp, cnt, page, pcf)); + return (mode_sense_g0(usalp, dp, cnt, page, pcf)); +} + +/* + * Simulate mode select g0 with mode select g1. + */ +int +mode_select_sg0(SCSI *usalp, Uchar *dp, int cnt, int smp, int pf) +{ + Uchar xmode[256+4]; + int amt = cnt; + + if (amt < 1 || amt > 255) { + /* XXX clear SCSI error codes ??? */ + return (-1); + } + + if (amt < 4) { /* Data length. medium type & VU */ + amt += 1; + } else { + amt += 4; + movebytes(&dp[4], &xmode[8], cnt-4); + } + xmode[0] = 0; + xmode[1] = 0; + xmode[2] = dp[1]; + xmode[3] = dp[2]; + xmode[4] = 0; + xmode[5] = 0; + i_to_2_byte(&xmode[6], (unsigned int)dp[3]); + + if (usalp->verbose) usal_prbytes("Mode Parameters (un-converted)", dp, cnt); + + return (mode_select_g1(usalp, xmode, amt, smp, pf)); +} + +/* + * Simulate mode sense g0 with mode sense g1. + */ +int +mode_sense_sg0(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf) +{ + Uchar xmode[256+4]; + int amt = cnt; + int len; + + if (amt < 1 || amt > 255) { + /* XXX clear SCSI error codes ??? */ + return (-1); + } + + fillbytes((caddr_t)xmode, sizeof (xmode), '\0'); + if (amt < 4) { /* Data length. medium type & VU */ + amt += 1; + } else { + amt += 4; + } + if (mode_sense_g1(usalp, xmode, amt, page, pcf) < 0) + return (-1); + + amt = cnt - usal_getresid(usalp); +/* + * For tests: Solaris 8 & LG CD-ROM always returns resid == amt + */ +/* amt = cnt;*/ + if (amt > 4) + movebytes(&xmode[8], &dp[4], amt-4); + len = a_to_u_2_byte(xmode); + if (len == 0) { + dp[0] = 0; + } else if (len < 6) { + if (len > 2) + len = 2; + dp[0] = len; + } else { + dp[0] = len - 3; + } + dp[1] = xmode[2]; + dp[2] = xmode[3]; + len = a_to_u_2_byte(&xmode[6]); + dp[3] = len; + + if (usalp->verbose) usal_prbytes("Mode Sense Data (converted)", dp, amt); + return (0); +} + +int +mode_select_g0(SCSI *usalp, Uchar *dp, int cnt, int smp, int pf) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)dp; + scmd->size = cnt; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_MODE_SELECT; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.high_addr = smp ? 1 : 0 | pf ? 0x10 : 0; + scmd->cdb.g0_cdb.count = cnt; + + if (usalp->verbose) { + fprintf(stderr, "%s ", smp?"Save":"Set "); + usal_prbytes("Mode Parameters", dp, cnt); + } + + usalp->cmdname = "mode select g0"; + + return (usal_cmd(usalp)); +} + +int +mode_select_g1(SCSI *usalp, Uchar *dp, int cnt, int smp, int pf) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)dp; + scmd->size = cnt; + scmd->flags = SCG_DISRE_ENA; + scmd->cdb_len = SC_G1_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g1_cdb.cmd = 0x55; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + scmd->cdb.g0_cdb.high_addr = smp ? 1 : 0 | pf ? 0x10 : 0; + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + if (usalp->verbose) { + printf("%s ", smp?"Save":"Set "); + usal_prbytes("Mode Parameters", dp, cnt); + } + + usalp->cmdname = "mode select g1"; + + return (usal_cmd(usalp)); +} + +int +mode_sense_g0(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)dp; + scmd->size = 0xFF; + scmd->size = cnt; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_MODE_SENSE; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); +#ifdef nonono + scmd->cdb.g0_cdb.high_addr = 1<<4; /* DBD Disable Block desc. */ +#endif + scmd->cdb.g0_cdb.mid_addr = (page&0x3F) | ((pcf<<6)&0xC0); + scmd->cdb.g0_cdb.count = page ? 0xFF : 24; + scmd->cdb.g0_cdb.count = cnt; + + usalp->cmdname = "mode sense g0"; + + if (usal_cmd(usalp) < 0) + return (-1); + if (usalp->verbose) usal_prbytes("Mode Sense Data", dp, cnt - usal_getresid(usalp)); + return (0); +} + +int +mode_sense_g1(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = (caddr_t)dp; + scmd->size = cnt; + 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 = 0x5A; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); +#ifdef nonono + scmd->cdb.g0_cdb.high_addr = 1<<4; /* DBD Disable Block desc. */ +#endif + scmd->cdb.g1_cdb.addr[0] = (page&0x3F) | ((pcf<<6)&0xC0); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "mode sense g1"; + + if (usal_cmd(usalp) < 0) + return (-1); + if (usalp->verbose) usal_prbytes("Mode Sense Data", dp, cnt - usal_getresid(usalp)); + return (0); +} + +struct trackdesc { + Uchar res0; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + Ucbit control : 4; + Ucbit adr : 4; +#else /* Motorola byteorder */ + Ucbit adr : 4; + Ucbit control : 4; +#endif + + Uchar track; + Uchar res3; + Uchar addr[4]; +}; + +struct diskinfo { + struct tocheader hd; + struct trackdesc desc[1]; +}; + +struct siheader { + Uchar len[2]; + Uchar finished; + Uchar unfinished; +}; + +struct sidesc { + Uchar sess_number; + Uchar res1; + Uchar track; + Uchar res3; + Uchar addr[4]; +}; + +struct sinfo { + struct siheader hd; + struct sidesc desc[1]; +}; + +struct trackheader { + Uchar mode; + Uchar res[3]; + Uchar addr[4]; +}; +#define TRM_ZERO 0 +#define TRM_USER_ECC 1 /* 2048 bytes user data + 288 Bytes ECC/EDC */ +#define TRM_USER 2 /* All user data (2336 bytes) */ + + +int +read_tochdr(SCSI *usalp, cdr_t *dp, int *fp, int *lp) +{ + struct tocheader *tp; + char xb[256]; + int len; + + tp = (struct tocheader *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc(usalp, xb, 0, sizeof (struct tocheader), 0, FMT_TOC) < 0) { + if (usalp->silent == 0) + errmsgno(EX_BAD, "Cannot read TOC header\n"); + return (-1); + } + len = a_to_u_2_byte(tp->len) + sizeof (struct tocheader)-2; + if (len >= 4) { + if (fp) + *fp = tp->first; + if (lp) + *lp = tp->last; + return (0); + } + return (-1); +} + +int +read_cdtext(SCSI *usalp) +{ + struct tocheader *tp; + char xb[256]; + int len; + char xxb[10000]; + + tp = (struct tocheader *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc(usalp, xb, 0, sizeof (struct tocheader), 0, FMT_CDTEXT) < 0) { + if (usalp->silent == 0 || usalp->verbose > 0) + errmsgno(EX_BAD, "Cannot read CD-Text header\n"); + return (-1); + } + len = a_to_u_2_byte(tp->len) + sizeof (struct tocheader)-2; + printf("CD-Text len: %d\n", len); + + if (read_toc(usalp, xxb, 0, len, 0, FMT_CDTEXT) < 0) { + if (usalp->silent == 0) + errmsgno(EX_BAD, "Cannot read CD-Text\n"); + return (-1); + } + { + FILE *f = fileopen("cdtext.dat", "wctb"); + filewrite(f, xxb, len); + } + return (0); +} + +int +read_trackinfo(SCSI *usalp, int track, long *offp, struct msf *msfp, int *adrp, + int *controlp, int *modep) +{ + struct diskinfo *dp; + char xb[256]; + int len; + + dp = (struct diskinfo *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc(usalp, xb, track, sizeof (struct diskinfo), 0, FMT_TOC) < 0) { + if (usalp->silent <= 0) + errmsgno(EX_BAD, "Cannot read TOC\n"); + return (-1); + } + len = a_to_u_2_byte(dp->hd.len) + sizeof (struct tocheader)-2; + if (len < (int)sizeof (struct diskinfo)) + return (-1); + + if (offp) + *offp = a_to_4_byte(dp->desc[0].addr); + if (adrp) + *adrp = dp->desc[0].adr; + if (controlp) + *controlp = dp->desc[0].control; + + if (msfp) { + usalp->silent++; + if (read_toc(usalp, xb, track, sizeof (struct diskinfo), 1, FMT_TOC) + >= 0) { + msfp->msf_min = dp->desc[0].addr[1]; + msfp->msf_sec = dp->desc[0].addr[2]; + msfp->msf_frame = dp->desc[0].addr[3]; + } else if (read_toc(usalp, xb, track, sizeof (struct diskinfo), 0, FMT_TOC) + >= 0) { + /* + * Some drives (e.g. the Philips CDD-522) don't support + * to read the TOC in MSF mode. + */ + long off = a_to_4_byte(dp->desc[0].addr); + + lba_to_msf(off, msfp); + } else { + msfp->msf_min = 0; + msfp->msf_sec = 0; + msfp->msf_frame = 0; + } + usalp->silent--; + } + + if (modep == NULL) + return (0); + + if (track == 0xAA) { + *modep = -1; + return (0); + } + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + + usalp->silent++; + if (read_header(usalp, xb, *offp, 8, 0) >= 0) { + *modep = xb[0]; + } else if (read_track_info_philips(usalp, xb, track, 14) >= 0) { + *modep = xb[0xb] & 0xF; + } else { + *modep = -1; + } + usalp->silent--; + return (0); +} + +int +read_B0(SCSI *usalp, BOOL isbcd, long *b0p, long *lop) +{ + struct fdiskinfo *dp; + struct ftrackdesc *tp; + char xb[8192]; + char *pe; + int len; + long l; + + dp = (struct fdiskinfo *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc_philips(usalp, xb, 1, sizeof (struct tocheader), 0, FMT_FULLTOC) < 0) { + return (-1); + } + len = a_to_u_2_byte(dp->hd.len) + sizeof (struct tocheader)-2; + if (len < (int)sizeof (struct fdiskinfo)) + return (-1); + if (read_toc_philips(usalp, xb, 1, len, 0, FMT_FULLTOC) < 0) { + return (-1); + } + if (usalp->verbose) { + usal_prbytes("TOC data: ", (Uchar *)xb, + len > (int)sizeof (xb) - usal_getresid(usalp) ? + sizeof (xb) - usal_getresid(usalp) : len); + + tp = &dp->desc[0]; + pe = &xb[len]; + + while ((char *)tp < pe) { + usal_prbytes("ENT: ", (Uchar *)tp, 11); + tp++; + } + } + tp = &dp->desc[0]; + pe = &xb[len]; + + for (; (char *)tp < pe; tp++) { + if (tp->sess_number != dp->hd.last) + continue; + if (tp->point != 0xB0) + continue; + if (usalp->verbose) + usal_prbytes("B0: ", (Uchar *)tp, 11); + if (isbcd) { + l = msf_to_lba(from_bcd(tp->amin), + from_bcd(tp->asec), + from_bcd(tp->aframe), TRUE); + } else { + l = msf_to_lba(tp->amin, + tp->asec, + tp->aframe, TRUE); + } + if (b0p) + *b0p = l; + + if (usalp->verbose) + printf("B0 start: %ld\n", l); + + if (isbcd) { + l = msf_to_lba(from_bcd(tp->pmin), + from_bcd(tp->psec), + from_bcd(tp->pframe), TRUE); + } else { + l = msf_to_lba(tp->pmin, + tp->psec, + tp->pframe, TRUE); + } + + if (usalp->verbose) + printf("B0 lout: %ld\n", l); + if (lop) + *lop = l; + return (0); + } + return (-1); +} + + +/* + * Return address of first track in last session (SCSI-3/mmc version). + */ +int +read_session_offset(SCSI *usalp, long *offp) +{ + struct diskinfo *dp; + char xb[256]; + int len; + + dp = (struct diskinfo *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc(usalp, (caddr_t)xb, 0, sizeof (struct tocheader), 0, FMT_SINFO) < 0) + return (-1); + + if (usalp->verbose) + usal_prbytes("tocheader: ", + (Uchar *)xb, sizeof (struct tocheader) - usal_getresid(usalp)); + + len = a_to_u_2_byte(dp->hd.len) + sizeof (struct tocheader)-2; + if (len > (int)sizeof (xb)) { + errmsgno(EX_BAD, "Session info too big.\n"); + return (-1); + } + if (read_toc(usalp, (caddr_t)xb, 0, len, 0, FMT_SINFO) < 0) + return (-1); + + if (usalp->verbose) + usal_prbytes("tocheader: ", + (Uchar *)xb, len - usal_getresid(usalp)); + + dp = (struct diskinfo *)xb; + if (offp) + *offp = a_to_u_4_byte(dp->desc[0].addr); + return (0); +} + +/* + * Return address of first track in last session (pre SCSI-3 version). + */ +int +read_session_offset_philips(SCSI *usalp, long *offp) +{ + struct sinfo *sp; + char xb[256]; + int len; + + sp = (struct sinfo *)xb; + + fillbytes((caddr_t)xb, sizeof (xb), '\0'); + if (read_toc_philips(usalp, (caddr_t)xb, 0, sizeof (struct siheader), 0, FMT_SINFO) < 0) + return (-1); + len = a_to_u_2_byte(sp->hd.len) + sizeof (struct siheader)-2; + if (len > (int)sizeof (xb)) { + errmsgno(EX_BAD, "Session info too big.\n"); + return (-1); + } + if (read_toc_philips(usalp, (caddr_t)xb, 0, len, 0, FMT_SINFO) < 0) + return (-1); + /* + * Old drives return the number of finished sessions in first/finished + * a descriptor is returned for each session. + * New drives return the number of the first and last session + * one descriptor for the last finished session is returned + * as in SCSI-3 + * In all cases the lowest session number is set to 1. + */ + sp = (struct sinfo *)xb; + if (offp) + *offp = a_to_u_4_byte(sp->desc[sp->hd.finished-1].addr); + return (0); +} + +int +sense_secsize(SCSI *usalp, int current) +{ + Uchar mode[0x100]; + Uchar *p; + Uchar *ep; + int len; + int secsize = -1; + + usalp->silent++; + (void) unit_ready(usalp); + usalp->silent--; + + /* XXX Quick and dirty, musz verallgemeinert werden !!! */ + + fillbytes(mode, sizeof (mode), '\0'); + usalp->silent++; + + len = sizeof (struct scsi_mode_header) + + sizeof (struct scsi_mode_blockdesc); + /* + * Wenn wir hier get_mode_params() nehmen bekommen wir die Warnung: + * Warning: controller returns wrong page 1 for All pages page (3F). + */ + if (mode_sense(usalp, mode, len, 0x3F, current?0:2) < 0) { + fillbytes(mode, sizeof (mode), '\0'); + if (mode_sense(usalp, mode, len, 0, current?0:2) < 0) { /* VU (block desc) */ + usalp->silent--; + return (-1); + } + } + if (mode[3] == 8) { + if (usalp->debug) { + printf("Density: 0x%X\n", mode[4]); + printf("Blocks: %ld\n", a_to_u_3_byte(&mode[5])); + printf("Blocklen:%ld\n", a_to_u_3_byte(&mode[9])); + } + secsize = a_to_u_3_byte(&mode[9]); + } + fillbytes(mode, sizeof (mode), '\0'); + /* + * The ACARD TECH AEC-7720 ATAPI<->SCSI adaptor + * chokes if we try to transfer more than 0x40 bytes with + * mode_sense of all pages. So try to avoid to run this + * command if possible. + */ + if (usalp->debug && + mode_sense(usalp, mode, 0xFE, 0x3F, current?0:2) >= 0) { /* All Pages */ + + ep = mode+mode[0]; /* Points to last byte of data */ + p = &mode[4]; + p += mode[3]; + printf("Pages: "); + while (p < ep) { + printf("0x%X ", *p&0x3F); + p += p[1]+2; + } + printf("\n"); + } + usalp->silent--; + + return (secsize); +} + +int +select_secsize(SCSI *usalp, int secsize) +{ + struct scsi_mode_data md; + int count = sizeof (struct scsi_mode_header) + + sizeof (struct scsi_mode_blockdesc); + + (void) test_unit_ready(usalp); /* clear any error situation */ + + fillbytes((caddr_t)&md, sizeof (md), '\0'); + md.header.blockdesc_len = 8; + i_to_3_byte(md.blockdesc.lblen, secsize); + + return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2)); +} + +BOOL +is_cddrive(SCSI *usalp) +{ + return (usalp->inq->type == INQ_ROMD || usalp->inq->type == INQ_WORM); +} + +BOOL +is_unknown_dev(SCSI *usalp) +{ + return (usalp->dev == DEV_UNKNOWN); +} + +#ifndef DEBUG +#define DEBUG +#endif +#ifdef DEBUG + +int +read_scsi(SCSI *usalp, caddr_t bp, long addr, int cnt) +{ + if (addr <= G0_MAXADDR && cnt < 256 && !is_atapi) + return (read_g0(usalp, bp, addr, cnt)); + else + return (read_g1(usalp, bp, addr, cnt)); +} + +int +read_g0(SCSI *usalp, caddr_t bp, long addr, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (usalp->cap->c_bsize <= 0) + raisecond("capacity_not_set", 0L); + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt*usalp->cap->c_bsize; + scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; + scmd->cdb_len = SC_G0_CDBLEN; + scmd->sense_len = CCS_SENSE_LEN; + scmd->cdb.g0_cdb.cmd = SC_READ; + scmd->cdb.g0_cdb.lun = usal_lun(usalp); + g0_cdbaddr(&scmd->cdb.g0_cdb, addr); + scmd->cdb.g0_cdb.count = cnt; +/* scmd->cdb.g0_cdb.vu_56 = 1;*/ + + usalp->cmdname = "read_g0"; + + return (usal_cmd(usalp)); +} + +int +read_g1(SCSI *usalp, caddr_t bp, long addr, int cnt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + if (usalp->cap->c_bsize <= 0) + raisecond("capacity_not_set", 0L); + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt*usalp->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 = SC_EREAD; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + g1_cdbaddr(&scmd->cdb.g1_cdb, addr); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "read_g1"; + + return (usal_cmd(usalp)); +} +#endif /* DEBUG */ + +BOOL +getdev(SCSI *usalp, BOOL print) +{ + BOOL got_inquiry = TRUE; + char vendor_info[8+1]; + char prod_ident[16+1]; + char prod_revision[4+1]; + int inq_len = 0; + register struct usal_cmd *scmd = usalp->scmd; + register struct scsi_inquiry *inq = usalp->inq; + + + fillbytes((caddr_t)inq, sizeof (*inq), '\0'); + usalp->dev = DEV_UNKNOWN; + usalp->silent++; + (void) unit_ready(usalp); + if (scmd->error >= SCG_FATAL && + !(scmd->scb.chk && scmd->sense_count > 0)) { + usalp->silent--; + return (FALSE); + } + + +/* if (scmd->error < SCG_FATAL || scmd->scb.chk && scmd->sense_count > 0){*/ + + if (inquiry(usalp, (caddr_t)inq, sizeof (*inq)) < 0) { + got_inquiry = FALSE; + } else { + inq_len = sizeof (*inq) - usal_getresid(usalp); + } + if (!got_inquiry) { + if (usalp->verbose) { + printf( + "error: %d scb.chk: %d sense_count: %d sense.code: 0x%x\n", + scmd->error, scmd->scb.chk, + scmd->sense_count, scmd->sense.code); + } + /* + * Folgende Kontroller kennen das Kommando + * INQUIRY nicht: + * + * ADAPTEC ACB-4000, ACB-4010, ACB 4070 + * SYSGEN SC4000 + * + * Leider reagieren ACB40X0 und ACB5500 identisch + * wenn drive not ready (code == not ready), + * sie sind dann nicht zu unterscheiden. + */ + + if (scmd->scb.chk && scmd->sense_count == 4) { + /* Test auf SYSGEN */ + (void) qic02(usalp, 0x12); /* soft lock on */ + if (qic02(usalp, 1) < 0) { /* soft lock off */ + usalp->dev = DEV_ACB40X0; +/* usalp->dev = acbdev();*/ + } else { + usalp->dev = DEV_SC4000; + inq->type = INQ_SEQD; + inq->removable = 1; + } + } + } else if (usalp->verbose) { + int i; + int len = inq->add_len + 5; + Uchar ibuf[256+5]; + Uchar *ip = (Uchar *)inq; + Uchar c; + + if (len > (int)sizeof (*inq) && + inquiry(usalp, (caddr_t)ibuf, inq->add_len+5) >= 0) { + len = inq->add_len+5 - usal_getresid(usalp); + ip = ibuf; + } else { + len = sizeof (*inq); + } + printf("Inquiry Data : "); + for (i = 0; i < len; i++) { + c = ip[i]; + if (c >= ' ' && c < 0177) + printf("%c", c); + else + printf("."); + } + printf("\n"); + } + + strncpy(vendor_info, inq->vendor_info, sizeof (inq->vendor_info)); + strncpy(prod_ident, inq->prod_ident, sizeof (inq->prod_ident)); + strncpy(prod_revision, inq->prod_revision, sizeof (inq->prod_revision)); + + vendor_info[sizeof (inq->vendor_info)] = '\0'; + prod_ident[sizeof (inq->prod_ident)] = '\0'; + prod_revision[sizeof (inq->prod_revision)] = '\0'; + + switch (inq->type) { + + case INQ_DASD: + if (inq->add_len == 0 && inq->vendor_info[0] != '\0') { + Uchar *p; + /* + * NT-4.0 creates fake inquiry data for IDE disks. + * Unfortunately, it does not set add_len wo we + * check if vendor_info, prod_ident and prod_revision + * contains valid chars for a CCS inquiry. + */ + if (inq_len >= 36) + inq->add_len = 31; + + for (p = (Uchar *)&inq->vendor_info[0]; + p < (Uchar *)&inq->prod_revision[4]; + p++) { + if (*p < 0x20 || *p > 0x7E) { + inq->add_len = 0; + break; + } + } + } + if (inq->add_len == 0) { + if (usalp->dev == DEV_UNKNOWN && got_inquiry) { + usalp->dev = DEV_ACB5500; + strcpy(inq->vendor_info, + "ADAPTEC ACB-5500 FAKE"); + + } else switch (usalp->dev) { + + case DEV_ACB40X0: + strcpy(inq->vendor_info, + "ADAPTEC ACB-40X0 FAKE"); + break; + case DEV_ACB4000: + strcpy(inq->vendor_info, + "ADAPTEC ACB-4000 FAKE"); + break; + case DEV_ACB4010: + strcpy(inq->vendor_info, + "ADAPTEC ACB-4010 FAKE"); + break; + case DEV_ACB4070: + strcpy(inq->vendor_info, + "ADAPTEC ACB-4070 FAKE"); + break; + } + } else if (inq->add_len < 31) { + usalp->dev = DEV_NON_CCS_DSK; + + } else if (strbeg("EMULEX", vendor_info)) { + if (strbeg("MD21", prod_ident)) + usalp->dev = DEV_MD21; + if (strbeg("MD23", prod_ident)) + usalp->dev = DEV_MD23; + else + usalp->dev = DEV_CCS_GENDISK; + } else if (strbeg("ADAPTEC", vendor_info)) { + if (strbeg("ACB-4520", prod_ident)) + usalp->dev = DEV_ACB4520A; + if (strbeg("ACB-4525", prod_ident)) + usalp->dev = DEV_ACB4525; + else + usalp->dev = DEV_CCS_GENDISK; + } else if (strbeg("SONY", vendor_info) && + strbeg("SMO-C501", prod_ident)) { + usalp->dev = DEV_SONY_SMO; + } else { + usalp->dev = DEV_CCS_GENDISK; + } + break; + + case INQ_SEQD: + if (usalp->dev == DEV_SC4000) { + strcpy(inq->vendor_info, + "SYSGEN SC4000 FAKE"); + } else if (inq->add_len == 0 && + inq->removable && + inq->ansi_version == 1) { + usalp->dev = DEV_MT02; + strcpy(inq->vendor_info, + "EMULEX MT02 FAKE"); + } + break; + +/* case INQ_OPTD:*/ + case INQ_ROMD: + case INQ_WORM: + if (strbeg("RXT-800S", prod_ident)) + usalp->dev = DEV_RXT800S; + + /* + * Start of CD-Recorders: + */ + if (strbeg("ACER", vendor_info)) { + if (strbeg("CR-4020C", prod_ident)) + usalp->dev = DEV_RICOH_RO_1420C; + + } else if (strbeg("CREATIVE", vendor_info)) { + if (strbeg("CDR2000", prod_ident)) + usalp->dev = DEV_RICOH_RO_1060C; + + } else if (strbeg("GRUNDIG", vendor_info)) { + if (strbeg("CDR100IPW", prod_ident)) + usalp->dev = DEV_CDD_2000; + + } else if (strbeg("JVC", vendor_info)) { + if (strbeg("XR-W2001", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + else if (strbeg("XR-W2010", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + else if (strbeg("R2626", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + + } else if (strbeg("MITSBISH", vendor_info)) { + +#ifdef XXXX_REALLY + /* It's MMC compliant */ + if (strbeg("CDRW226", prod_ident)) + usalp->dev = DEV_MMC_CDRW; +#else + /* EMPTY */ +#endif + + } else if (strbeg("MITSUMI", vendor_info)) { + /* Don't know any product string */ + usalp->dev = DEV_CDD_522; + + } else if (strbeg("OPTIMA", vendor_info)) { + if (strbeg("CD-R 650", prod_ident)) + usalp->dev = DEV_SONY_CDU_924; + + } else if (strbeg("PHILIPS", vendor_info) || + strbeg("IMS", vendor_info) || + strbeg("KODAK", vendor_info) || + strbeg("HP", vendor_info)) { + + if (strbeg("CDD521/00", prod_ident)) + usalp->dev = DEV_CDD_521_OLD; + else if (strbeg("CDD521/02", prod_ident)) + usalp->dev = DEV_CDD_521_OLD; /* PCD 200R? */ + else if (strbeg("CDD521", prod_ident)) + usalp->dev = DEV_CDD_521; + + if (strbeg("CDD522", prod_ident)) + usalp->dev = DEV_CDD_522; + if (strbeg("PCD225", prod_ident)) + usalp->dev = DEV_CDD_522; + if (strbeg("KHSW/OB", prod_ident)) /* PCD600 */ + usalp->dev = DEV_PCD_600; + if (strbeg("CDR-240", prod_ident)) + usalp->dev = DEV_CDD_2000; + + if (strbeg("CDD20", prod_ident)) + usalp->dev = DEV_CDD_2000; + if (strbeg("CDD26", prod_ident)) + usalp->dev = DEV_CDD_2600; + + if (strbeg("C4324/C4325", prod_ident)) + usalp->dev = DEV_CDD_2000; + if (strbeg("CD-Writer 6020", prod_ident)) + usalp->dev = DEV_CDD_2600; + + } else if (strbeg("PINNACLE", vendor_info)) { + if (strbeg("RCD-1000", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + if (strbeg("RCD5020", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + if (strbeg("RCD5040", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + if (strbeg("RCD 4X4", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + + } else if (strbeg("PIONEER", vendor_info)) { + if (strbeg("CD-WO DW-S114X", prod_ident)) + usalp->dev = DEV_PIONEER_DW_S114X; + else if (strbeg("CD-WO DR-R504X", prod_ident)) /* Reoprt from philip@merge.com */ + usalp->dev = DEV_PIONEER_DW_S114X; + else if (strbeg("DVD-R DVR-S101", prod_ident)) + usalp->dev = DEV_PIONEER_DVDR_S101; + + } else if (strbeg("PLASMON", vendor_info)) { + if (strbeg("RF4100", prod_ident)) + usalp->dev = DEV_PLASMON_RF_4100; + else if (strbeg("CDR4220", prod_ident)) + usalp->dev = DEV_CDD_2000; + + } else if (strbeg("PLEXTOR", vendor_info)) { + if (strbeg("CD-R PX-R24CS", prod_ident)) + usalp->dev = DEV_RICOH_RO_1420C; + + } else if (strbeg("RICOH", vendor_info)) { + if (strbeg("RO-1420C", prod_ident)) + usalp->dev = DEV_RICOH_RO_1420C; + if (strbeg("RO1060C", prod_ident)) + usalp->dev = DEV_RICOH_RO_1060C; + + } else if (strbeg("SAF", vendor_info)) { /* Smart & Friendly */ + if (strbeg("CD-R2004", prod_ident) || + strbeg("CD-R2006 ", prod_ident)) + usalp->dev = DEV_SONY_CDU_924; + else if (strbeg("CD-R2006PLUS", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + else if (strbeg("CD-RW226", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + else if (strbeg("CD-R4012", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + + } else if (strbeg("SANYO", vendor_info)) { + if (strbeg("CD-WO CRD-R24S", prod_ident)) + usalp->dev = DEV_CDD_521; + + } else if (strbeg("SONY", vendor_info)) { + if (strbeg("CD-R CDU92", prod_ident) || + strbeg("CD-R CDU94", prod_ident)) + usalp->dev = DEV_SONY_CDU_924; + + } else if (strbeg("TEAC", vendor_info)) { + if (strbeg("CD-R50S", prod_ident) || + strbeg("CD-R55S", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + + } else if (strbeg("TRAXDATA", vendor_info) || + strbeg("Traxdata", vendor_info)) { + if (strbeg("CDR4120", prod_ident)) + usalp->dev = DEV_TEAC_CD_R50S; + + } else if (strbeg("T.YUDEN", vendor_info)) { + if (strbeg("CD-WO EW-50", prod_ident)) + usalp->dev = DEV_TYUDEN_EW50; + + } else if (strbeg("WPI", vendor_info)) { /* Wearnes */ + if (strbeg("CDR-632P", prod_ident)) + usalp->dev = DEV_CDD_2600; + + } else if (strbeg("YAMAHA", vendor_info)) { + if (strbeg("CDR10", prod_ident)) + usalp->dev = DEV_YAMAHA_CDR_100; + if (strbeg("CDR200", prod_ident)) + usalp->dev = DEV_YAMAHA_CDR_400; + if (strbeg("CDR400", prod_ident)) + usalp->dev = DEV_YAMAHA_CDR_400; + + } else if (strbeg("MATSHITA", vendor_info)) { + if (strbeg("CD-R CW-7501", prod_ident)) + usalp->dev = DEV_MATSUSHITA_7501; + if (strbeg("CD-R CW-7502", prod_ident)) + usalp->dev = DEV_MATSUSHITA_7502; + } + if (usalp->dev == DEV_UNKNOWN) { + /* + * We do not have Manufacturer strings for + * the following drives. + */ + if (strbeg("CDS615E", prod_ident)) /* Olympus */ + usalp->dev = DEV_SONY_CDU_924; + } + if (usalp->dev == DEV_UNKNOWN && inq->type == INQ_ROMD) { + BOOL cdrr = FALSE; + BOOL cdwr = FALSE; + BOOL cdrrw = FALSE; + BOOL cdwrw = FALSE; + BOOL dvd = FALSE; + BOOL dvdwr = FALSE; + + usalp->dev = DEV_CDROM; + + if (mmc_check(usalp, &cdrr, &cdwr, &cdrrw, &cdwrw, + &dvd, &dvdwr)) + usalp->dev = DEV_MMC_CDROM; + if (cdwr) + usalp->dev = DEV_MMC_CDR; + if (cdwrw) + usalp->dev = DEV_MMC_CDRW; + if (dvd) + usalp->dev = DEV_MMC_DVD; + if (dvdwr) + usalp->dev = DEV_MMC_DVD_WR; + } + break; + + case INQ_PROCD: + if (strbeg("BERTHOLD", vendor_info)) { + if (strbeg("", prod_ident)) + usalp->dev = DEV_HRSCAN; + } + break; + + case INQ_SCAN: + usalp->dev = DEV_MS300A; + break; + } + usalp->silent--; + if (!print) + return (TRUE); + + if (usalp->dev == DEV_UNKNOWN && !got_inquiry) { +#ifdef PRINT_INQ_ERR + usal_printerr(usalp); +#endif + return (FALSE); + } + + printinq(usalp, stdout); + return (TRUE); +} + +void +printinq(SCSI *usalp, FILE *f) +{ + register struct scsi_inquiry *inq = usalp->inq; + + fprintf(f, "Device type : "); + usal_fprintdev(f, inq); + fprintf(f, "Version : %d\n", inq->ansi_version); + fprintf(f, "Response Format: %d\n", inq->data_format); + if (inq->data_format >= 2) { + fprintf(f, "Capabilities : "); + if (inq->aenc) fprintf(f, "AENC "); + if (inq->termiop) fprintf(f, "TERMIOP "); + if (inq->reladr) fprintf(f, "RELADR "); + if (inq->wbus32) fprintf(f, "WBUS32 "); + if (inq->wbus16) fprintf(f, "WBUS16 "); + if (inq->sync) fprintf(f, "SYNC "); + if (inq->linked) fprintf(f, "LINKED "); + if (inq->cmdque) fprintf(f, "CMDQUE "); + if (inq->softreset) fprintf(f, "SOFTRESET "); + fprintf(f, "\n"); + } + if (inq->add_len >= 31 || + inq->vendor_info[0] || + inq->prod_ident[0] || + inq->prod_revision[0]) { + fprintf(f, "Vendor_info : '%.8s'\n", inq->vendor_info); + fprintf(f, "Identification : '%.16s'\n", inq->prod_ident); + fprintf(f, "Revision : '%.4s'\n", inq->prod_revision); + } +} + +void +printdev(SCSI *usalp) +{ + printf("Device seems to be: "); + + switch (usalp->dev) { + + case DEV_UNKNOWN: printf("unknown"); break; + case DEV_ACB40X0: printf("Adaptec 4000/4010/4070"); break; + case DEV_ACB4000: printf("Adaptec 4000"); break; + case DEV_ACB4010: printf("Adaptec 4010"); break; + case DEV_ACB4070: printf("Adaptec 4070"); break; + case DEV_ACB5500: printf("Adaptec 5500"); break; + case DEV_ACB4520A: printf("Adaptec 4520A"); break; + case DEV_ACB4525: printf("Adaptec 4525"); break; + case DEV_MD21: printf("Emulex MD21"); break; + case DEV_MD23: printf("Emulex MD23"); break; + case DEV_NON_CCS_DSK: printf("Generic NON CCS Disk"); break; + case DEV_CCS_GENDISK: printf("Generic CCS Disk"); break; + case DEV_SONY_SMO: printf("Sony SMO-C501"); break; + case DEV_MT02: printf("Emulex MT02"); break; + case DEV_SC4000: printf("Sysgen SC4000"); break; + case DEV_RXT800S: printf("Maxtor RXT800S"); break; + case DEV_HRSCAN: printf("Berthold HR-Scanner"); break; + case DEV_MS300A: printf("Microtek MS300A"); break; + + case DEV_CDROM: printf("Generic CD-ROM"); break; + case DEV_MMC_CDROM: printf("Generic mmc CD-ROM"); break; + case DEV_MMC_CDR: printf("Generic mmc CD-R"); break; + case DEV_MMC_CDRW: printf("Generic mmc CD-RW"); break; + case DEV_MMC_DVD: printf("Generic mmc2 DVD-ROM"); break; + case DEV_MMC_DVD_WR: printf("Generic mmc2 DVD-R/DVD-RW"); break; + case DEV_CDD_521_OLD: printf("Philips old CDD-521"); break; + case DEV_CDD_521: printf("Philips CDD-521"); break; + case DEV_CDD_522: printf("Philips CDD-522"); break; + case DEV_PCD_600: printf("Kodak PCD-600"); break; + case DEV_CDD_2000: printf("Philips CDD-2000"); break; + case DEV_CDD_2600: printf("Philips CDD-2600"); break; + case DEV_YAMAHA_CDR_100:printf("Yamaha CDR-100"); break; + case DEV_YAMAHA_CDR_400:printf("Yamaha CDR-400"); break; + case DEV_PLASMON_RF_4100:printf("Plasmon RF-4100"); break; + case DEV_SONY_CDU_924: printf("Sony CDU-924S"); break; + case DEV_RICOH_RO_1060C:printf("Ricoh RO-1060C"); break; + case DEV_RICOH_RO_1420C:printf("Ricoh RO-1420C"); break; + case DEV_TEAC_CD_R50S: printf("Teac CD-R50S"); break; + case DEV_MATSUSHITA_7501:printf("Matsushita CW-7501"); break; + case DEV_MATSUSHITA_7502:printf("Matsushita CW-7502"); break; + + case DEV_PIONEER_DW_S114X: printf("Pioneer DW-S114X"); break; + case DEV_PIONEER_DVDR_S101:printf("Pioneer DVD-R S101"); break; + + default: printf("Missing Entry for dev %d", + usalp->dev); break; + + } + printf(".\n"); + +} + +BOOL +do_inquiry(SCSI *usalp, int print) +{ + if (getdev(usalp, print)) { + if (print) + printdev(usalp); + return (TRUE); + } else { + return (FALSE); + } +} + +BOOL +recovery_needed(SCSI *usalp, cdr_t *dp) +{ + int err; + register struct usal_cmd *scmd = usalp->scmd; + + usalp->silent++; + err = test_unit_ready(usalp); + usalp->silent--; + + if (err >= 0) + return (FALSE); + else if (scmd->error >= SCG_FATAL) /* nicht selektierbar */ + return (FALSE); + + if (scmd->sense.code < 0x70) /* non extended Sense */ + return (FALSE); + + /* XXX Old Philips code */ + return (((struct scsi_ext_sense *)&scmd->sense)->sense_code == 0xD0); +} + +int +scsi_load(SCSI *usalp, cdr_t *dp) +{ + int key; + int code; + + if ((dp->cdr_flags & CDR_CADDYLOAD) == 0) { + if (scsi_start_stop_unit(usalp, 1, 1, dp && (dp->cdr_cmdflags&F_IMMED)) >= 0) + return (0); + } + + if (wait_unit_ready(usalp, 60)) + return (0); + + key = usal_sense_key(usalp); + code = usal_sense_code(usalp); + + if (key == SC_NOT_READY && (code == 0x3A || code == 0x30)) { + errmsgno(EX_BAD, "Cannot load media with %s drive!\n", + (dp->cdr_flags & CDR_CADDYLOAD) ? "caddy" : "this"); + errmsgno(EX_BAD, "Try to load media by hand.\n"); + } + return (-1); +} + +int +scsi_unload(SCSI *usalp, cdr_t *dp) +{ + return (scsi_start_stop_unit(usalp, 0, 1, dp && (dp->cdr_cmdflags&F_IMMED))); +} + +int +scsi_cdr_write(SCSI *usalp, + caddr_t bp /* address of buffer */, + long sectaddr /* disk address (sector) to put */, + long size /* number of bytes to transfer */, + int blocks /* sector count */, + BOOL islast /* last write for track */) +{ + return (write_xg1(usalp, bp, sectaddr, size, blocks)); +} + +struct cd_mode_page_2A * +mmc_cap(SCSI *usalp, Uchar *modep) +{ + int len; + int val; + Uchar mode[0x100]; + struct cd_mode_page_2A *mp; + struct cd_mode_page_2A *mp2; + + +retry: + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + if (!get_mode_params(usalp, 0x2A, "CD capabilities", + mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) { + + if (usal_sense_key(usalp) == SC_NOT_READY) { + if (wait_unit_ready(usalp, 60)) + goto retry; + } + return (NULL); /* Pre SCSI-3/mmc drive */ + } + + if (len == 0) /* Pre SCSI-3/mmc drive */ + return (NULL); + + mp = (struct cd_mode_page_2A *) + (mode + sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len); + + /* + * Do some heuristics against pre SCSI-3/mmc VU page 2A + * We should test for a minimum p_len of 0x14, but some + * buggy CD-ROM readers ommit the write speed values. + */ + if (mp->p_len < 0x10) + return (NULL); + + val = a_to_u_2_byte(mp->max_read_speed); + if (val != 0 && val < 176) + return (NULL); + + val = a_to_u_2_byte(mp->cur_read_speed); + if (val != 0 && val < 176) + return (NULL); + + len -= sizeof (struct scsi_mode_header) + + ((struct scsi_mode_header *)mode)->blockdesc_len; + if (modep) + mp2 = (struct cd_mode_page_2A *)modep; + else + mp2 = malloc(len); + if (mp2) + movebytes(mp, mp2, len); + + return (mp2); +} + +void +mmc_getval(struct cd_mode_page_2A *mp, + BOOL *cdrrp /* CD ROM */, + BOOL *cdwrp /* CD-R writer */, + BOOL *cdrrwp /* CD-RW reader */, + BOOL *cdwrwp /* CD-RW writer */, + BOOL *dvdp /* DVD reader */, + BOOL *dvdwp /* DVD writer */) +{ + BOOL isdvd; /* Any DVD reader */ + BOOL isdvd_wr; /* DVD writer (R / RAM) */ + BOOL iscd_wr; /* CD writer */ + + iscd_wr = (mp->cd_r_write != 0) || /* SCSI-3/mmc CD-R */ + (mp->cd_rw_write != 0); /* SCSI-3/mmc CD-RW */ + + if (cdrrp) + *cdrrp = (mp->cd_r_read != 0); /* SCSI-3/mmc CD */ + if (cdwrp) + *cdwrp = (mp->cd_r_write != 0); /* SCSI-3/mmc CD-R */ + + if (cdrrwp) + *cdrrwp = (mp->cd_rw_read != 0); /* SCSI-3/mmc CD */ + if (cdwrwp) + *cdwrwp = (mp->cd_rw_write != 0); /* SCSI-3/mmc CD-RW */ + + isdvd = /* SCSI-3/mmc2 DVD */ + (mp->dvd_ram_read + mp->dvd_r_read + + mp->dvd_rom_read) != 0; + + isdvd_wr = /* SCSI-3/mmc2 DVD writer*/ + (mp->dvd_ram_write + mp->dvd_r_write) != 0; + + if (dvdp) + *dvdp = isdvd; + if (dvdwp) + *dvdwp = isdvd_wr; +} + +BOOL +is_mmc(SCSI *usalp, BOOL *cdwp, BOOL *dvdwp) +{ + BOOL cdwr = FALSE; + BOOL cdwrw = FALSE; + + if (cdwp) + *cdwp = FALSE; + if (dvdwp) + *dvdwp = FALSE; + + if (!mmc_check(usalp, NULL, &cdwr, NULL, &cdwrw, NULL, dvdwp)) + return (FALSE); + + if (cdwp) + *cdwp = cdwr | cdwrw; + + return (TRUE); +} + +BOOL +mmc_check(SCSI *usalp, + BOOL *cdrrp /* CD ROM */, + BOOL *cdwrp /* CD-R writer */, + BOOL *cdrrwp /* CD-RW reader */, + BOOL *cdwrwp /* CD-RW writer */, + BOOL *dvdp /* DVD reader */, + BOOL *dvdwp /* DVD writer */) +{ + Uchar mode[0x100]; + BOOL was_atapi; + struct cd_mode_page_2A *mp; + + if (usalp->inq->type != INQ_ROMD) + return (FALSE); + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + was_atapi = allow_atapi(usalp, TRUE); + usalp->silent++; + mp = mmc_cap(usalp, mode); + usalp->silent--; + allow_atapi(usalp, was_atapi); + if (mp == NULL) + return (FALSE); + + mmc_getval(mp, cdrrp, cdwrp, cdrrwp, cdwrwp, dvdp, dvdwp); + + return (TRUE); /* Generic SCSI-3/mmc CD */ +} + +static void +print_speed(char *fmt, int val) +{ + printf(" %s: %5d kB/s", fmt, val); + printf(" (CD %3ux,", val/176); + printf(" DVD %2ux)\n", val/1385); +} + +#define DOES(what, flag) printf(" Does %s%s\n", flag?"":"not ", what) +#define IS(what, flag) printf(" Is %s%s\n", flag?"":"not ", what) +#define VAL(what, val) printf(" %s: %d\n", what, val[0]*256 + val[1]) +#define SVAL(what, val) printf(" %s: %s\n", what, val) + +void +print_capabilities(SCSI *usalp) +{ + BOOL was_atapi; + Uchar mode[0x100]; + struct cd_mode_page_2A *mp; +static const char *bclk[4] = {"32", "16", "24", "24 (I2S)"}; +static const char *load[8] = {"caddy", "tray", "pop-up", "reserved(3)", + "disc changer", "cartridge changer", + "reserved(6)", "reserved(7)" }; +static const char *rotctl[4] = {"CLV/PCAV", "CAV", "reserved(2)", "reserved(3)"}; + + + if (usalp->inq->type != INQ_ROMD) + return; + + fillbytes((caddr_t)mode, sizeof (mode), '\0'); + + was_atapi = allow_atapi(usalp, TRUE); /* Try to switch to 10 byte mode cmds */ + usalp->silent++; + mp = mmc_cap(usalp, mode); + usalp->silent--; + allow_atapi(usalp, was_atapi); + if (mp == NULL) + return; + + printf("\nDrive capabilities, per"); + if (mp->p_len >= 28) + printf(" MMC-3"); + else if (mp->p_len >= 24) + printf(" MMC-2"); + else + printf(" MMC"); + printf(" page 2A:\n\n"); + + DOES("read CD-R media", mp->cd_r_read); + DOES("write CD-R media", mp->cd_r_write); + DOES("read CD-RW media", mp->cd_rw_read); + DOES("write CD-RW media", mp->cd_rw_write); + DOES("read DVD-ROM media", mp->dvd_rom_read); + DOES("read DVD-R media", mp->dvd_r_read); + DOES("write DVD-R media", mp->dvd_r_write); + DOES("read DVD-RAM media", mp->dvd_ram_read); + DOES("write DVD-RAM media", mp->dvd_ram_write); + DOES("support test writing", mp->test_write); + printf("\n"); + DOES("read Mode 2 Form 1 blocks", mp->mode_2_form_1); + DOES("read Mode 2 Form 2 blocks", mp->mode_2_form_2); + DOES("read digital audio blocks", mp->cd_da_supported); + if (mp->cd_da_supported) + DOES("restart non-streamed digital audio reads accurately", mp->cd_da_accurate); + DOES("support Buffer-Underrun-Free recording", mp->BUF); + DOES("read multi-session CDs", mp->multi_session); + DOES("read fixed-packet CD media using Method 2", mp->method2); + DOES("read CD bar code", mp->read_bar_code); + DOES("read R-W subcode information", mp->rw_supported); + if (mp->rw_supported) + DOES("return R-W subcode de-interleaved and error-corrected", mp->rw_deint_corr); + DOES("read raw P-W subcode data from lead in", mp->pw_in_lead_in); + DOES("return CD media catalog number", mp->UPC); + DOES("return CD ISRC information", mp->ISRC); + DOES("support C2 error pointers", mp->c2_pointers); + DOES("deliver composite A/V data", mp->composite); + printf("\n"); + DOES("play audio CDs", mp->audio_play); + if (mp->audio_play) { + VAL("Number of volume control levels", mp->num_vol_levels); + DOES("support individual volume control setting for each channel", mp->sep_chan_vol); + DOES("support independent mute setting for each channel", mp->sep_chan_mute); + DOES("support digital output on port 1", mp->digital_port_1); + DOES("support digital output on port 2", mp->digital_port_2); + if (mp->digital_port_1 || mp->digital_port_2) { + DOES("send digital data LSB-first", mp->LSBF); + DOES("set LRCK high for left-channel data", mp->RCK); + DOES("have valid data on falling edge of clock", mp->BCK); + SVAL("Length of data in BCLKs", bclk[mp->length]); + } + } + printf("\n"); + SVAL("Loading mechanism type", load[mp->loading_type]); + DOES("support ejection of CD via START/STOP command", mp->eject); + DOES("lock media on power up via prevent jumper", mp->prevent_jumper); + DOES("allow media to be locked in the drive via PREVENT/ALLOW command", mp->lock); + IS("currently in a media-locked state", mp->lock_state); + DOES("support changing side of disk", mp->side_change); + DOES("have load-empty-slot-in-changer feature", mp->sw_slot_sel); + DOES("support Individual Disk Present feature", mp->disk_present_rep); + printf("\n"); + print_speed("Maximum read speed", a_to_u_2_byte(mp->max_read_speed)); + print_speed("Current read speed", a_to_u_2_byte(mp->cur_read_speed)); + print_speed("Maximum write speed", a_to_u_2_byte(mp->max_write_speed)); + if (mp->p_len >= 28) + print_speed("Current write speed", a_to_u_2_byte(mp->v3_cur_write_speed)); + else + print_speed("Current write speed", a_to_u_2_byte(mp->cur_write_speed)); + if (mp->p_len >= 28) { + SVAL("Rotational control selected", rotctl[mp->rot_ctl_sel]); + } + VAL("Buffer size in KB", mp->buffer_size); + + if (mp->p_len >= 24) { + VAL("Copy management revision supported", mp->copy_man_rev); + } + + if (mp->p_len >= 28) { + struct cd_wr_speed_performance *pp; + Uint ndesc; + Uint i; + Uint n; + + ndesc = a_to_u_2_byte(mp->num_wr_speed_des); + pp = mp->wr_speed_des; + printf(" Number of supported write speeds: %d\n", ndesc); + for (i = 0; i < ndesc; i++, pp++) { + printf(" Write speed # %d:", i); + n = a_to_u_2_byte(pp->wr_speed_supp); + printf(" %5d kB/s", n); + printf(" %s", rotctl[pp->rot_ctl_sel]); + printf(" (CD %3ux,", n/176); + printf(" DVD %2ux)\n", n/1385); + } + } + + /* Generic SCSI-3/mmc CD */ +} diff --git a/wodim/scsi_cdr_mmc4.c b/wodim/scsi_cdr_mmc4.c new file mode 100644 index 0000000..cb0958a --- /dev/null +++ b/wodim/scsi_cdr_mmc4.c @@ -0,0 +1,80 @@ +/* + * 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. + * + */ + +/* @(#)scsi_cdr_mmc4.c 1.1 05/05/16 Copyright 1995-2005 J. Schilling */ +/* + * SCSI command functions for cdrecord + * covering MMC-4 + * + * Copyright (c) 1995-2005 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 <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "scsimmc.h" +#include "wodim.h" + +void print_capabilities_mmc4(SCSI *usalp); + +#define DOES(what, flag) printf(" Does %s%s\n", flag?"":"not ", what) + + +void +print_capabilities_mmc4(SCSI *usalp) +{ + int cdrw_types; + + if (usalp->inq->type != INQ_ROMD) + return; + + cdrw_types = get_supported_cdrw_media_types(usalp); + if (cdrw_types != -1) { + printf("\nSupported CD-RW media types according to MMC-4 feature 0x37:\n"); + DOES("write multi speed CD-RW media", (cdrw_types & CDR_CDRW_MULTI)); + DOES("write high speed CD-RW media", (cdrw_types & CDR_CDRW_HIGH)); + DOES("write ultra high speed CD-RW media", (cdrw_types & CDR_CDRW_ULTRA)); + DOES("write ultra high speed+ CD-RW media", (cdrw_types & CDR_CDRW_ULTRAP)); + } +} diff --git a/wodim/scsi_mmc.c b/wodim/scsi_mmc.c new file mode 100644 index 0000000..f8baa1f --- /dev/null +++ b/wodim/scsi_mmc.c @@ -0,0 +1,411 @@ +/* + * 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. + * + */ + +/* @(#)scsi_mmc.c 1.13 05/05/16 Copyright 2002-2005 J. Schilling */ +/* + * SCSI command functions for cdrecord + * covering MMC-3 level and above + * + * Copyright (c) 2002-2005 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. + */ + +/* +Includes code from http://libburnia.pykix.org/browser/libburn/trunk/libburn/mmc.c?format=txt +*/ + +/*#define DEBUG*/ + +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "scsimmc.h" +#include "wodim.h" + +extern int xdebug; + + + +int get_configuration(SCSI *usalp, caddr_t bp, int cnt, int st_feature, + int rt); +static int get_conflen(SCSI *usalp, int st_feature, int rt); +int get_curprofile(SCSI *usalp); +static int get_profiles(SCSI *usalp, caddr_t bp, int cnt); +int print_profiles(SCSI *usalp); +int get_proflist(SCSI *usalp, BOOL *wp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp, + BOOL *ddcdp); +int get_wproflist(SCSI *usalp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp, + BOOL *ddcdp); + +/* + * Get feature codes + */ +int +get_configuration(SCSI *usalp, caddr_t bp, int cnt, int st_feature, int rt) +{ + register struct usal_cmd *scmd = usalp->scmd; + + fillbytes((caddr_t)scmd, sizeof (*scmd), '\0'); + scmd->addr = bp; + scmd->size = cnt; + 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 = 0x46; + scmd->cdb.g1_cdb.lun = usal_lun(usalp); + if (rt & 1) + scmd->cdb.g1_cdb.reladr = 1; + if (rt & 2) + scmd->cdb.g1_cdb.res = 1; + + i_to_2_byte(scmd->cdb.g1_cdb.addr, st_feature); + g1_cdblen(&scmd->cdb.g1_cdb, cnt); + + usalp->cmdname = "get_configuration"; + + return (usal_cmd(usalp)); +} + +/* + * Retrieve feature code list length + */ +static int +get_conflen(SCSI *usalp, int st_feature, int rt) +{ + Uchar cbuf[8]; + int flen; + int i; + + fillbytes(cbuf, sizeof (cbuf), '\0'); + usalp->silent++; + i = get_configuration(usalp, (char *)cbuf, sizeof (cbuf), st_feature, rt); + usalp->silent--; + if (i < 0) + return (-1); + i = sizeof (cbuf) - usal_getresid(usalp); + if (i < 4) + return (-1); + + flen = a_to_u_4_byte(cbuf); + if (flen < 4) + return (-1); + return (flen); +} + +int +get_curprofile(SCSI *usalp) +{ + Uchar cbuf[8]; + int amt; + int flen; + int profile; + int i; + + fillbytes(cbuf, sizeof (cbuf), '\0'); + usalp->silent++; + i = get_configuration(usalp, (char *)cbuf, sizeof (cbuf), 0, 0); + usalp->silent--; + if (i < 0) + return (-1); + + amt = sizeof (cbuf) - usal_getresid(usalp); + if (amt < 8) + return (-1); + flen = a_to_u_4_byte(cbuf); + if (flen < 4) + return (-1); + + profile = a_to_u_2_byte(&cbuf[6]); + + if (xdebug > 1) + usal_prbytes("Features: ", cbuf, amt); + + if (xdebug > 0) + printf("feature len: %d current profile 0x%04X (%s) len %d\n", + flen, profile, + mmc_obtain_profile_name(profile), amt); + + return (profile); +} + +static int +get_profiles(SCSI *usalp, caddr_t bp, int cnt) +{ + int amt; + int flen; + int i; + + flen = get_conflen(usalp, 0, 0); + if (flen < 0) + return (-1); + if (cnt < flen) + flen = cnt; + + fillbytes(bp, cnt, '\0'); + usalp->silent++; + i = get_configuration(usalp, (char *)bp, flen, 0, 0); + usalp->silent--; + if (i < 0) + return (-1); + amt = flen - usal_getresid(usalp); + + flen = a_to_u_4_byte(bp); + if ((flen+4) < amt) + amt = flen+4; + + return (amt); +} + +int +print_profiles(SCSI *usalp) +{ + Uchar cbuf[1024]; + Uchar *p; + int flen; + int curprofile; + int profile; + int i; + int n; + + flen = get_profiles(usalp, (caddr_t)cbuf, sizeof (cbuf)); + if (flen < 0) + return (-1); + + p = cbuf; + if (xdebug > 1) + usal_prbytes("Features: ", cbuf, flen); + + curprofile = a_to_u_2_byte(&p[6]); + if (xdebug > 0) + printf("feature len: %d current profile 0x%04X (%s)\n", + flen, curprofile, + mmc_obtain_profile_name(curprofile)); + + printf("Current: 0x%04X (%s)\n", curprofile, + mmc_obtain_profile_name(curprofile)); + + p += 8; /* Skip feature header */ + n = p[3]; /* Additional length */ + n /= 4; + p += 4; + + for (i = 0; i < n; i++) { + profile = a_to_u_2_byte(p); + if (xdebug > 0) + printf("Profile: 0x%04X (%s)", profile, + mmc_obtain_profile_name(profile)); + else + printf("Profile: "); + printf("0x%04X (%s) %s\n", profile, + mmc_obtain_profile_name(profile), + p[2] & 1 ? "(current)":""); + p += 4; + } + return (curprofile); +} + +int +get_proflist(SCSI *usalp, BOOL *wp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp, + BOOL *ddcdp) +{ + Uchar cbuf[1024]; + Uchar *p; + int flen; + int curprofile; + int profile; + int i; + int n; + BOOL wr = FALSE; + BOOL cd = FALSE; + BOOL dvd = FALSE; + BOOL dvdplus = FALSE; + BOOL ddcd = FALSE; + + flen = get_profiles(usalp, (caddr_t)cbuf, sizeof (cbuf)); + if (flen < 0) + return (-1); + + p = cbuf; + if (xdebug > 1) + usal_prbytes("Features: ", cbuf, flen); + + curprofile = a_to_u_2_byte(&p[6]); + if (xdebug > 0) + printf("feature len: %d current profile 0x%04X (%s)\n", + flen, curprofile, + mmc_obtain_profile_name(curprofile)); + + p += 8; /* Skip feature header */ + n = p[3]; /* Additional length */ + n /= 4; + p += 4; + + for (i = 0; i < n; i++) { + profile = a_to_u_2_byte(p); + p += 4; + if (profile >= 0x0008 && profile < 0x0010) + cd = TRUE; + if (profile > 0x0008 && profile < 0x0010) + wr = TRUE; + + if (profile >= 0x0010 && profile < 0x0018) + dvd = TRUE; + if (profile > 0x0010 && profile < 0x0018) + wr = TRUE; + + if (profile >= 0x0018 && profile < 0x0020) + dvdplus = TRUE; + if (profile > 0x0018 && profile < 0x0020) + wr = TRUE; + + if (profile >= 0x0020 && profile < 0x0028) + ddcd = TRUE; + if (profile > 0x0020 && profile < 0x0028) + wr = TRUE; + } + if (wp) + *wp = wr; + if (cdp) + *cdp = cd; + if (dvdp) + *dvdp = dvd; + if (dvdplusp) + *dvdplusp = dvdplus; + if (ddcdp) + *ddcdp = ddcd; + + return (curprofile); +} + +int +get_wproflist(SCSI *usalp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp, BOOL *ddcdp) +{ + Uchar cbuf[1024]; + Uchar *p; + int flen; + int curprofile; + int profile; + int i; + int n; + BOOL cd = FALSE; + BOOL dvd = FALSE; + BOOL dvdplus = FALSE; + BOOL ddcd = FALSE; + + flen = get_profiles(usalp, (caddr_t)cbuf, sizeof (cbuf)); + if (flen < 0) + return (-1); + p = cbuf; + curprofile = a_to_u_2_byte(&p[6]); + + p += 8; /* Skip feature header */ + n = p[3]; /* Additional length */ + n /= 4; + p += 4; + + for (i = 0; i < n; i++) { + profile = a_to_u_2_byte(p); + p += 4; + if (profile > 0x0008 && profile < 0x0010) + cd = TRUE; + if (profile > 0x0010 && profile < 0x0018) + dvd = TRUE; + if (profile > 0x0018 && profile < 0x0020) + dvdplus = TRUE; + if (profile > 0x0020 && profile < 0x0028) + ddcd = TRUE; + } + if (cdp) + *cdp = cd; + if (dvdp) + *dvdp = dvd; + if (dvdplusp) + *dvdplusp = dvdplus; + if (ddcdp) + *ddcdp = ddcd; + + return (curprofile); +} + + +char *mmc_obtain_profile_name(int profile_number) { + static char *texts[0x53] = {NULL}; + static char *reserved="Reserved/Unknown"; + int i, max_pno = 0x53; + + if (texts[0] == NULL) { + for (i = 0; i<max_pno; i++) + texts[i] = reserved; + /* mmc5r04c.pdf , Table 88, human readable profile names */ + texts[0x01] = "Non-removable disk"; + texts[0x02] = "Removable disk"; + texts[0x03] = "MO erasable"; + texts[0x04] = "Optical write once"; + texts[0x05] = "AS-MO"; + texts[0x08] = "CD-ROM"; + texts[0x09] = "CD-R"; + texts[0x0a] = "CD-RW"; + texts[0x10] = "DVD-ROM"; + texts[0x11] = "DVD-R sequential recording"; + texts[0x12] = "DVD-RAM"; + texts[0x13] = "DVD-RW restricted overwrite"; + texts[0x14] = "DVD-RW sequential recording"; + texts[0x15] = "DVD-R/DL sequential recording"; + texts[0x16] = "DVD-R/DL layer jump recording"; + texts[0x1a] = "DVD+RW"; + texts[0x1b] = "DVD+R"; + texts[0x2a] = "DVD+RW/DL"; + texts[0x2b] = "DVD+R/DL"; + texts[0x40] = "BD-ROM"; + texts[0x41] = "BD-R sequential recording"; + texts[0x42] = "BD-R random recording"; + texts[0x43] = "BD-RE"; + texts[0x50] = "HD-DVD-ROM"; + texts[0x51] = "HD-DVD-R"; + texts[0x52] = "HD-DVD-RAM"; + } + if (profile_number<0 || profile_number>=max_pno) + return ""; + return texts[profile_number]; +} + diff --git a/wodim/scsi_mmc4.c b/wodim/scsi_mmc4.c new file mode 100644 index 0000000..1257093 --- /dev/null +++ b/wodim/scsi_mmc4.c @@ -0,0 +1,83 @@ +/* + * 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. + * + */ + +/* @(#)scsi_mmc4.c 1.1 05/05/16 Copyright 2002-2005 J. Schilling */ +/* + * SCSI command functions for cdrecord + * covering MMC-4 level and above + * + * Copyright (c) 2002-2005 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. + */ + +/* #define DEBUG */ +#include <mconfig.h> + +#include <stdio.h> +#include <standard.h> +#include <stdxlib.h> +#include <unixstd.h> +#include <fctldefs.h> +#include <errno.h> +#include <strdefs.h> +#include <timedefs.h> + +#include <utypes.h> +#include <btorder.h> +#include <intcvt.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "scsimmc.h" +#include "wodim.h" + + int get_supported_cdrw_media_types(SCSI *usalp); + +/* + * Retrieve list of supported cd-rw media types (feature 0x37) + */ +int +get_supported_cdrw_media_types(SCSI *usalp) +{ + Uchar cbuf[16]; + int ret; + fillbytes(cbuf, sizeof (cbuf), '\0'); + + usalp->silent++; + ret = get_configuration(usalp, (char *)cbuf, sizeof (cbuf), 0x37, 2); + usalp->silent--; + + if (ret < 0) + return (-1); + + if (cbuf[3] < 12) /* Couldn't retrieve feature 0x37 */ + return (-1); + + return (int)(cbuf[13]); +} diff --git a/wodim/scsi_scan.c b/wodim/scsi_scan.c new file mode 100644 index 0000000..218d23f --- /dev/null +++ b/wodim/scsi_scan.c @@ -0,0 +1,379 @@ +/* + * 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. + * + */ + +/* @(#)scsi_scan.c 1.19 04/04/16 Copyright 1997-2004 J. Schilling */ +/* + * Scan SCSI Bus. + * Stolen from sformat. Need a more general form to + * re-use it in sformat too. + * + * Copyright (c) 1997-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 <errno.h> +#include <schily.h> + +#include <usal/usalcmd.h> +#include <usal/scsidefs.h> +#include <usal/scsireg.h> +#include <usal/scsitransp.h> + +#include "scsi_scan.h" +#include "wodim.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> + + +static void print_product(FILE *f, struct scsi_inquiry *ip); +int select_target(SCSI *usalp, FILE *f); + +#define MAXDEVCOUNT (256+26) + +extern BOOL check_linux_26(); + +static void print_product(FILE *f, struct scsi_inquiry *ip) { + fprintf(f, "'%.8s' ", ip->vendor_info); + fprintf(f, "'%.16s' ", ip->prod_ident); + fprintf(f, "'%.4s' ", ip->prod_revision); + if (ip->add_len < 31) { + fprintf(f, "NON CCS "); + } + usal_fprintdev(f, ip); +} + +SCSI * open_auto(int64_t need_size, int debug, int lverbose) { + int res; + SCSI * usalp = NULL; + char errstr[80]; + +#ifdef __linux__ + /* quick-and-dirty code but should do what is supposed to, more quickly */ + + /* + * For Linux, try these strategies, in order: + * 1. stat /dev/cdrw or /dev/dvdrw, depending on size we need. + * 2. Read /proc/sys/dev/cdrom/info, look for a CD-R/DVD-R. + * Will fail for kernel 2.4 or if cdrom module not loaded. + * 3. stat /dev/cdrom, just assume that it can write media. + + An example for procfs file contents, beware of the TABs + +--- +CD-ROM information, Id: cdrom.c 3.20 2003/12/17 + +drive name: hdc hda +drive speed: 40 40 +drive # of slots: 1 1 +Can close tray: 1 1 +Can open tray: 1 1 +Can lock tray: 1 1 +Can change speed: 1 1 +Can select disk: 0 0 +Can read multisession: 1 1 +Can read MCN: 1 1 +Reports media changed: 1 1 +Can play audio: 1 1 +Can write CD-R: 0 1 +Can write CD-RW: 0 1 +Can read DVD: 1 1 +Can write DVD-R: 0 1 +Can write DVD-RAM: 0 1 +Can read MRW: 0 1 +Can write MRW: 0 1 +Can write RAM: 0 1 + +--- +*/ + struct stat statbuf; + /* XXX Good guess? BD-RE recorders may not support CDRW anymore... */ + char *type="CD-R", *key="Can write CD-R:", *guessdev="/dev/cdrw", *result=NULL; + FILE *fh; + + if( need_size > 360000*2048 ) { + type="DVD-R"; + guessdev="/dev/dvdrw"; + key="Can write DVD-R:"; + } + + if(need_size>10240) /* don't bother with weird numbers */ + fprintf(stderr, "Looking for a %s drive to store %.2f MiB...\n", type, (float)need_size/1048576.0); + if(0==stat(guessdev, &statbuf)) + result=guessdev; + else if(0!= (fh = fopen("/proc/sys/dev/cdrom/info", "r")) ) { + /* ok, going the hard way */ + char *nameline=NULL; + static char buf[256]; + int kn = strlen(key); + + buf[255]='\0'; + + while(fgets(buf, sizeof(buf), fh)) { + if(0==strncmp(buf, "drive name:", 11)) + nameline=strdup(buf); + if(nameline && 0==strncmp(buf, key, kn)) { + int p=kn; + char *descptr=nameline+11; /* start at the known whitespace */ + while(p<sizeof(buf) && buf[p]) { + if(buf[p]=='1' || buf[p]=='0') { + /* find the beginning of the descriptor */ + for(;isspace((Uchar) *descptr);descptr++) + ; + } + if(buf[p]=='1') { + result=descptr-5; + /* terminate on space/newline and stop there */ + for(;*descptr;descptr++) { + if(isspace((Uchar) *descptr)) + *(descptr--)='\0'; + } + strncpy(result, "/dev/", 5); + break; + } + else { /* no hit, move to after word ending */ + for(; *descptr && ! isspace((Uchar) *descptr); descptr++) + ; + } + p++; + } + } + + } + fclose(fh); + } + + if(result) + fprintf(stderr, "Detected %s drive: %s\n", type, result); + if (0==stat("/dev/cdrom", &statbuf)) { + result = "/dev/cdrom"; + fprintf(stderr, "Using /dev/cdrom of unknown capabilities\n"); + } + if(result) + return usal_open(result, errstr, sizeof(errstr), debug, lverbose); +#endif /* __linux__ */ + + usalp = usal_open(NULL, errstr, sizeof(errstr), debug, lverbose); + if(!usalp) + return NULL; + res = list_devices(usalp, stdout, 1); + if(res>0) + return usalp; + else + usal_close(usalp); + return NULL; +} + +int list_devices(SCSI *usalp, FILE *f, int pickup_first) { + int initiator; + int i; + int bus; + int tgt; + int lun = 0; + BOOL have_tgt; + + int fd, ndevs=0; + struct stat statbuf; + char *lines[MAXDEVCOUNT]; + char buf[256], perms[8]; + + + usalp->silent++; + + /* XXX should be done before opening usal fprintf(stderr, "Beginning native device scan. This may take a while if devices are busy...\n"); */ + + for (bus = 0; bus < 1256; bus++) { + usal_settarget(usalp, bus, 0, 0); + + if (!usal_havebus(usalp, bus)) + continue; + + initiator = usal_initiator_id(usalp); + //fprintf(f, "scsibus%d:\n", bus); + + for (tgt = 0; tgt < 16; tgt++) { + usal_settarget(usalp, bus, tgt, lun); + have_tgt = unit_ready(usalp) || usalp->scmd->error != SCG_FATAL; + + if (!have_tgt && tgt > 7) { + if (usalp->scmd->ux_errno == EINVAL) + break; + continue; + } + + fd=usal_fileno(usalp, bus, tgt, lun); + strcpy(perms,"------"); + if(fd>=0 && 0==fstat(fd, &statbuf)) { + if(statbuf.st_mode&S_IRUSR) perms[0]= 'r'; + if(statbuf.st_mode&S_IWUSR) perms[1]= 'w'; + if(statbuf.st_mode&S_IRGRP) perms[2]= 'r'; + if(statbuf.st_mode&S_IWGRP) perms[3]= 'w'; + if(statbuf.st_mode&S_IROTH) perms[4]= 'r'; + if(statbuf.st_mode&S_IWOTH) perms[5]= 'w'; + } + getdev(usalp, FALSE); + if(usalp->inq->type == INQ_ROMD || usalp->inq->type == INQ_WORM) { + char *p; + + for(p=usalp->inq->vendor_info + 7 ; p >= usalp->inq->vendor_info; p--) { + if(isspace((unsigned char)*p)) + *p='\0'; + else + break; + } + for(p=usalp->inq->prod_ident + 15 ; p >= usalp->inq->prod_ident; p--) { + if(isspace((unsigned char)*p)) + *p='\0'; + else + break; + } + snprintf(buf, sizeof(buf), "%2d dev='%s'\t%s : '%.8s' '%.16s'\n", ndevs, usal_natname(usalp, bus, tgt, lun), perms, usalp->inq->vendor_info, usalp->inq->prod_ident); + /* alternative use, only select the first device */ + if(pickup_first) { + printf("Using drive: %s\n", usal_natname(usalp, bus, tgt, lun)); + return 1; + } + lines[ndevs++]=strdup(buf); + } + + } + } + usalp->silent--; + + /* should have been returned before if there was a recorder */ + if(pickup_first) + return 0; + + /* now start the output */ + + fprintf(stdout, "%s: Overview of accessible drives (%d found) :\n" + "-------------------------------------------------------------------------\n", + get_progname(), ndevs); + for(i=0;i<ndevs;i++) { + fprintf(stdout, "%s", lines[i]); + free(lines[i]); + } + fprintf(stdout, "-------------------------------------------------------------------------\n"); + + return ndevs; +} + +int select_target(SCSI *usalp, FILE *f) { + int initiator; +#ifdef FMT + int cscsibus = usal_scsibus(usalp); + int ctarget = usal_target(usalp); + int clun = usal_lun(usalp); +#endif + int n; + int low = -1; + int high = -1; + int amt = 0; + int bus; + int tgt; + int lun = 0; + BOOL have_tgt; + + usalp->silent++; + + for (bus = 0; bus < 1256; bus++) { + usal_settarget(usalp, bus, 0, 0); + + if (!usal_havebus(usalp, bus)) + continue; + + initiator = usal_initiator_id(usalp); + fprintf(f, "scsibus%d:\n", bus); + + for (tgt = 0; tgt < 16; tgt++) { + n = bus*100 + tgt; + + usal_settarget(usalp, bus, tgt, lun); + have_tgt = unit_ready(usalp) || usalp->scmd->error != SCG_FATAL; + + if (!have_tgt && tgt > 7) { + if (usalp->scmd->ux_errno == EINVAL) + break; + continue; + } + +#ifdef FMT + if (print_disknames(bus, tgt, -1) < 8) + fprintf(f, "\t"); + else + fprintf(f, " "); +#else + fprintf(f, "\t"); +#endif + if (fprintf(f, "%d,%d,%d", bus, tgt, lun) < 8) + fprintf(f, "\t"); + else + fprintf(f, " "); + fprintf(f, "%3d) ", n); + if (tgt == initiator) { + fprintf(f, "HOST ADAPTOR\n"); + continue; + } + if (!have_tgt) { + /* + * Hack: fd -> -2 means no access + */ + fprintf(f, "%c\n", usalp->fd == -2 ? '?':'*'); + continue; + } + amt++; + if (low < 0) + low = n; + high = n; + + getdev(usalp, FALSE); + print_product(f, usalp->inq); + } + } + usalp->silent--; + + if (low < 0) { + errmsgno(EX_BAD, "No target found.\n"); + return (0); + } + n = -1; +#ifdef FMT + getint("Select target", &n, low, high); + bus = n/100; + tgt = n%100; + usal_settarget(usalp, bus, tgt, lun); + return (select_unit(usalp)); + + usal_settarget(usalp, cscsibus, ctarget, clun); +#endif + return (amt); +} + diff --git a/wodim/scsi_scan.h b/wodim/scsi_scan.h new file mode 100644 index 0000000..b1e055b --- /dev/null +++ b/wodim/scsi_scan.h @@ -0,0 +1,44 @@ +/* + * 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. + * + */ + +/* @(#)scsi_scan.h 1.3 01/03/12 Copyright 1997 J. Schilling */ +/* + * Interface to scan SCSI Bus. + * + * Copyright (c) 1997 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. + */ + +#ifndef _SCSI_SCAN_H +#define _SCSI_SCAN_H + +#include <usal/scsitransp.h> + +extern int select_target(SCSI *usalp, FILE *f); +extern int list_devices(SCSI *usalp, FILE *f, int pickup_type); +extern SCSI * open_auto(int64_t need_size, int debug, int lverbose); +extern int scsi_set_streaming(SCSI *usalp, caddr_t addr, int size); + +#endif /* _SCSI_SCAN_H */ diff --git a/wodim/scsimmc.h b/wodim/scsimmc.h new file mode 100644 index 0000000..a0092fc --- /dev/null +++ b/wodim/scsimmc.h @@ -0,0 +1,593 @@ +/* + * 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. + * + */ + +/* @(#)scsimmc.h 1.11 04/03/01 Copyright 1997-2004 J. Schilling */ +/* + * Definitions for SCSI/mmc compliant drives + * + * Copyright (c) 1997-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. + */ + +#ifndef _SCSIMMC_H +#define _SCSIMMC_H + +#include <utypes.h> +#include <btorder.h> + +typedef struct opc { + Uchar opc_speed[2]; + Uchar opc_val[6]; +} opc_t; + +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct disk_info { + Uchar data_len[2]; /* Data len without this info */ + Ucbit disk_status : 2; /* Status of the disk */ + Ucbit sess_status : 2; /* Status of last session */ + Ucbit erasable : 1; /* Disk is erasable */ + Ucbit res2 : 3; /* Reserved */ + Uchar first_track; /* # of first track on disk */ + Uchar numsess; /* # of sessions */ + Uchar first_track_ls; /* First track in last sessaion */ + Uchar last_track_ls; /* Last track in last sessaion */ + Ucbit bg_format_stat : 2; /* Background format status */ + Ucbit dbit : 1; /* Dirty Bit of defect table */ + Ucbit res7_34 : 2; /* Reserved */ + Ucbit uru : 1; /* This is an unrestricted disk */ + Ucbit dbc_v : 1; /* Disk bar code valid */ + Ucbit did_v : 1; /* Disk id valid */ + Uchar disk_type; /* Disk type */ + Uchar res9[3]; /* Reserved */ + Uchar disk_id[4]; /* Disk identification */ + Uchar last_lead_in[4]; /* Last session lead in time */ + Uchar last_lead_out[4]; /* Last session lead out time */ + Uchar disk_barcode[8]; /* Disk bar code */ + Uchar res32; /* Reserved */ + Uchar num_opc_entries; /* # of OPC table entries */ + opc_t opc_table[1]; /* OPC table */ +}; + +#else /* Motorola bitorder */ + +struct disk_info { + Uchar data_len[2]; /* Data len without this info */ + Ucbit res2 : 3; /* Reserved */ + Ucbit erasable : 1; /* Disk is erasable */ + Ucbit sess_status : 2; /* Status of last session */ + Ucbit disk_status : 2; /* Status of the disk */ + Uchar first_track; /* # of first track on disk */ + Uchar numsess; /* # of sessions */ + Uchar first_track_ls; /* First track in last sessaion */ + Uchar last_track_ls; /* Last track in last sessaion */ + Ucbit did_v : 1; /* Disk id valid */ + Ucbit dbc_v : 1; /* Disk bar code valid */ + Ucbit uru : 1; /* This is an unrestricted disk */ + Ucbit res7_34 : 2; /* Reserved */ + Ucbit dbit : 1; /* Dirty Bit of defect table */ + Ucbit bg_format_stat : 2; /* Background format status */ + Uchar disk_type; /* Disk type */ + Uchar res9[3]; /* Reserved */ + Uchar disk_id[4]; /* Disk identification */ + Uchar last_lead_in[4]; /* Last session lead in time */ + Uchar last_lead_out[4]; /* Last session lead out time */ + Uchar disk_barcode[8]; /* Disk bar code */ + Uchar res32; /* Reserved */ + Uchar num_opc_entries; /* # of OPC table entries */ + opc_t opc_table[1]; /* OPC table */ +}; + +#endif + +struct cd_mode_data { + struct scsi_mode_header header; + union cd_pagex { + struct cd_mode_page_05 page05; + struct cd_mode_page_2A page2A; + } pagex; +}; + +struct tocheader { + Uchar len[2]; + Uchar first; + Uchar last; +}; + +/* + * Full TOC entry + */ +struct ftrackdesc { + Uchar sess_number; + +#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ + Ucbit control : 4; + Ucbit adr : 4; +#else /* Motorola byteorder */ + Ucbit adr : 4; + Ucbit control : 4; +#endif + + Uchar track; + Uchar point; + Uchar amin; + Uchar asec; + Uchar aframe; + Uchar res7; + Uchar pmin; + Uchar psec; + Uchar pframe; +}; + +struct fdiskinfo { + struct tocheader hd; + struct ftrackdesc desc[1]; +}; + + + +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct atipdesc { + Ucbit ref_speed : 3; /* Reference speed */ + Ucbit res4_3 : 1; /* Reserved */ + Ucbit ind_wr_power : 3; /* Indicative tgt writing power */ + Ucbit res4_7 : 1; /* Reserved (must be "1") */ + Ucbit res5_05 : 6; /* Reserved */ + Ucbit uru : 1; /* Disk is for unrestricted use */ + Ucbit res5_7 : 1; /* Reserved (must be "0") */ + Ucbit a3_v : 1; /* A 3 Values valid */ + Ucbit a2_v : 1; /* A 2 Values valid */ + Ucbit a1_v : 1; /* A 1 Values valid */ + Ucbit sub_type : 3; /* Disc sub type */ + Ucbit erasable : 1; /* Disk is erasable */ + Ucbit res6_7 : 1; /* Reserved (must be "1") */ + Uchar lead_in[4]; /* Lead in time */ + Uchar lead_out[4]; /* Lead out time */ + Uchar res15; /* Reserved */ + Ucbit clv_high : 4; /* Highes usable CLV recording speed */ + Ucbit clv_low : 3; /* Lowest usable CLV recording speed */ + Ucbit res16_7 : 1; /* Reserved (must be "0") */ + Ucbit res17_0 : 1; /* Reserved */ + Ucbit tgt_y_pow : 3; /* Tgt y val of the power mod fun */ + Ucbit power_mult : 3; /* Power multiplication factor */ + Ucbit res17_7 : 1; /* Reserved (must be "0") */ + Ucbit res_18_30 : 4; /* Reserved */ + Ucbit rerase_pwr_ratio: 3; /* Recommended erase/write power*/ + Ucbit res18_7 : 1; /* Reserved (must be "1") */ + Uchar res19; /* Reserved */ + Uchar a2[3]; /* A 2 Values */ + Uchar res23; /* Reserved */ + Uchar a3[3]; /* A 3 Vaules */ + Uchar res27; /* Reserved */ +}; + +#else /* Motorola bitorder */ + +struct atipdesc { + Ucbit res4_7 : 1; /* Reserved (must be "1") */ + Ucbit ind_wr_power : 3; /* Indicative tgt writing power */ + Ucbit res4_3 : 1; /* Reserved */ + Ucbit ref_speed : 3; /* Reference speed */ + Ucbit res5_7 : 1; /* Reserved (must be "0") */ + Ucbit uru : 1; /* Disk is for unrestricted use */ + Ucbit res5_05 : 6; /* Reserved */ + Ucbit res6_7 : 1; /* Reserved (must be "1") */ + Ucbit erasable : 1; /* Disk is erasable */ + Ucbit sub_type : 3; /* Disc sub type */ + Ucbit a1_v : 1; /* A 1 Values valid */ + Ucbit a2_v : 1; /* A 2 Values valid */ + Ucbit a3_v : 1; /* A 3 Values valid */ + Uchar lead_in[4]; /* Lead in time */ + Uchar lead_out[4]; /* Lead out time */ + Uchar res15; /* Reserved */ + Ucbit res16_7 : 1; /* Reserved (must be "0") */ + Ucbit clv_low : 3; /* Lowest usable CLV recording speed */ + Ucbit clv_high : 4; /* Highes usable CLV recording speed */ + Ucbit res17_7 : 1; /* Reserved (must be "0") */ + Ucbit power_mult : 3; /* Power multiplication factor */ + Ucbit tgt_y_pow : 3; /* Tgt y val of the power mod fun */ + Ucbit res17_0 : 1; /* Reserved */ + Ucbit res18_7 : 1; /* Reserved (must be "1") */ + Ucbit rerase_pwr_ratio: 3; /* Recommended erase/write power*/ + Ucbit res_18_30 : 4; /* Reserved */ + Uchar res19; /* Reserved */ + Uchar a2[3]; /* A 2 Values */ + Uchar res23; /* Reserved */ + Uchar a3[3]; /* A 3 Vaules */ + Uchar res27; /* Reserved */ +}; + +#endif + +struct atipinfo { + struct tocheader hd; + struct atipdesc desc; +}; + +/* + * XXX Check how we may merge Track_info & Rzone_info + */ +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct track_info { + Uchar data_len[2]; /* Data len without this info */ + Uchar track_number; /* Track number for this info */ + Uchar session_number; /* Session number for this info */ + Uchar res4; /* Reserved */ + Ucbit track_mode : 4; /* Track mode (Q-sub control) */ + Ucbit copy : 1; /* This track is a higher copy */ + Ucbit damage : 1; /* if 1 & nwa_valid 0: inc track*/ + Ucbit res5_67 : 2; /* Reserved */ + Ucbit data_mode : 4; /* Data mode of this track */ + Ucbit fp : 1; /* This is a fixed packet track */ + Ucbit packet : 1; /* This track is in packet mode */ + Ucbit blank : 1; /* This is an invisible track */ + Ucbit rt : 1; /* This is a reserved track */ + Ucbit nwa_valid : 1; /* Next writable addr valid */ + Ucbit res7_17 : 7; /* Reserved */ + Uchar track_start[4]; /* Track start address */ + Uchar next_writable_addr[4]; /* Next writable address */ + Uchar free_blocks[4]; /* Free usr blocks in this track*/ + Uchar packet_size[4]; /* Packet size if in fixed mode */ + Uchar track_size[4]; /* # of user data blocks in trk */ +}; + +#else /* Motorola bitorder */ + +struct track_info { + Uchar data_len[2]; /* Data len without this info */ + Uchar track_number; /* Track number for this info */ + Uchar session_number; /* Session number for this info */ + Uchar res4; /* Reserved */ + Ucbit res5_67 : 2; /* Reserved */ + Ucbit damage : 1; /* if 1 & nwa_valid 0: inc track*/ + Ucbit copy : 1; /* This track is a higher copy */ + Ucbit track_mode : 4; /* Track mode (Q-sub control) */ + Ucbit rt : 1; /* This is a reserved track */ + Ucbit blank : 1; /* This is an invisible track */ + Ucbit packet : 1; /* This track is in packet mode */ + Ucbit fp : 1; /* This is a fixed packet track */ + Ucbit data_mode : 4; /* Data mode of this track */ + Ucbit res7_17 : 7; /* Reserved */ + Ucbit nwa_valid : 1; /* Next writable addr valid */ + Uchar track_start[4]; /* Track start address */ + Uchar next_writable_addr[4]; /* Next writable address */ + Uchar free_blocks[4]; /* Free usr blocks in this track*/ + Uchar packet_size[4]; /* Packet size if in fixed mode */ + Uchar track_size[4]; /* # of user data blocks in trk */ +}; + +#endif + +/* + * XXX Check how we may merge Track_info & Rzone_info + */ +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct rzone_info { + Uchar data_len[2]; /* Data len without this info */ + Uchar rzone_num_lsb; /* RZone number LSB */ + Uchar border_num_lsb; /* Border number LSB */ + Uchar res_4; /* Reserved */ + Ucbit res5_04 : 5; /* Reserved */ + Ucbit damage : 1; /* Damaged RZone */ + Ucbit res5_67 : 2; /* Reserved */ + Ucbit res6_04 : 5; /* Reserved */ + Ucbit incremental : 1; /* RZone is to be written incremental */ + Ucbit blank : 1; /* RZone is blank */ + Ucbit rt : 1; /* RZone is reserved */ + Ucbit nwa_v : 1; /* Next WR address is valid */ + Ucbit lra_v : 1; /* Last rec address is valid */ + Ucbit res7_27 : 6; /* Reserved */ + Uchar rzone_start[4]; /* RZone start address */ + Uchar next_recordable_addr[4]; /* Next recordable address */ + Uchar free_blocks[4]; /* Free blocks in RZone */ + Uchar block_factor[4]; /* # of sectors of disc acc unit */ + Uchar rzone_size[4]; /* RZone size */ + Uchar last_recorded_addr[4]; /* Last Recorded addr in RZone */ + Uchar rzone_num_msb; /* RZone number MSB */ + Uchar border_num_msb; /* Border number MSB */ + Uchar res_34_35[2]; /* Reserved */ +}; + +#else /* Motorola bitorder */ + +struct rzone_info { + Uchar data_len[2]; /* Data len without this info */ + Uchar rzone_num_lsb; /* RZone number LSB */ + Uchar border_num_lsb; /* Border number LSB */ + Uchar res_4; /* Reserved */ + Ucbit res5_67 : 2; /* Reserved */ + Ucbit damage : 1; /* Damaged RZone */ + Ucbit res5_04 : 5; /* Reserved */ + Ucbit rt : 1; /* RZone is reserved */ + Ucbit blank : 1; /* RZone is blank */ + Ucbit incremental : 1; /* RZone is to be written incremental */ + Ucbit res6_04 : 5; /* Reserved */ + Ucbit res7_27 : 6; /* Reserved */ + Ucbit lra_v : 1; /* Last rec address is valid */ + Ucbit nwa_v : 1; /* Next WR address is valid */ + Uchar rzone_start[4]; /* RZone start address */ + Uchar next_recordable_addr[4]; /* Next recordable address */ + Uchar free_blocks[4]; /* Free blocks in RZone */ + Uchar block_factor[4]; /* # of sectors of disc acc unit */ + Uchar rzone_size[4]; /* RZone size */ + Uchar last_recorded_addr[4]; /* Last Recorded addr in RZone */ + Uchar rzone_num_msb; /* RZone number MSB */ + Uchar border_num_msb; /* Border number MSB */ + Uchar res_34_35[2]; /* Reserved */ +}; + +#endif + +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct dvd_structure_00 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Ucbit book_version : 4; /* DVD Book version */ + Ucbit book_type : 4; /* DVD Book type */ + Ucbit minimum_rate : 4; /* Minimum data rate (coded) */ + Ucbit disc_size : 4; /* Disc size (coded) */ + Ucbit layer_type : 4; /* Layer type */ + Ucbit track_path : 1; /* 0 = parallel, 1 = opposit dir*/ + Ucbit numlayers : 2; /* Number of Layers (0 == 1) */ + Ucbit res2_7 : 1; /* Reserved */ + Ucbit track_density : 4; /* Track density (coded) */ + Ucbit linear_density : 4; /* Linear data density (coded) */ + Uchar res8; /* Reserved */ + Uchar phys_start[3]; /* Starting Physical sector # */ + Uchar res12; /* Reserved */ + Uchar phys_end[3]; /* End physical data sector # */ + Uchar res16; /* Reserved */ + Uchar end_layer0[3]; /* End sector # in layer */ + Ucbit res20 : 7; /* Reserved */ + Ucbit bca : 1; /* BCA flag bit */ +}; + +#else /* Motorola bitorder */ + +struct dvd_structure_00 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Ucbit book_type : 4; /* DVD Book type */ + Ucbit book_version : 4; /* DVD Book version */ + Ucbit disc_size : 4; /* Disc size (coded) */ + Ucbit minimum_rate : 4; /* Minimum data rate (coded) */ + Ucbit res2_7 : 1; /* Reserved */ + Ucbit numlayers : 2; /* Number of Layers (0 == 1) */ + Ucbit track_path : 1; /* 0 = parallel, 1 = opposit dir*/ + Ucbit layer_type : 4; /* Layer type */ + Ucbit linear_density : 4; /* Linear data density (coded) */ + Ucbit track_density : 4; /* Track density (coded) */ + Uchar res8; /* Reserved */ + Uchar phys_start[3]; /* Starting Physical sector # */ + Uchar res12; /* Reserved */ + Uchar phys_end[3]; /* End physical data sector # */ + Uchar res16; /* Reserved */ + Uchar end_layer0[3]; /* End sector # in layer */ + Ucbit bca : 1; /* BCA flag bit */ + Ucbit res20 : 7; /* Reserved */ +}; + +#endif + +struct dvd_structure_01 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar copyr_prot_type; /* Copyright prot system type */ + Uchar region_mgt_info; /* Region management info */ + Uchar res67[2]; /* Reserved */ +}; + +struct dvd_structure_02 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar key_data[2048]; /* Disc Key data */ +}; + +struct dvd_structure_03 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar bca_info[1]; /* BCA information (12-188 bytes)*/ +}; + +struct dvd_structure_04 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar man_info[2048]; /* Disc manufacturing info */ +}; + +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + +struct dvd_structure_05 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Ucbit res4_03 : 4; /* Reserved */ + Ucbit cgms : 2; /* CGMS (see below) */ + Ucbit res4_6 : 1; /* Reserved */ + Ucbit cpm : 1; /* This is copyrighted material */ + Uchar res57[3]; /* Reserved */ +}; + +#else /* Motorola bitorder */ + +struct dvd_structure_05 { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Ucbit cpm : 1; /* This is copyrighted material */ + Ucbit res4_6 : 1; /* Reserved */ + Ucbit cgms : 2; /* CGMS (see below) */ + Ucbit res4_03 : 4; /* Reserved */ + Uchar res57[3]; /* Reserved */ +}; + +#endif + +#define CGMS_PERMITTED 0 /* Unlimited copy permitted */ +#define CGMS_RES 1 /* Reserved */ +#define CGMS_ONE_COPY 2 /* One copy permitted */ +#define CGMS_NO_COPY 3 /* No copy permitted */ + +struct dvd_structure_0D { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar last_rma_sector[2]; /* Last recorded RMA sector # */ + Uchar rmd_bytes[1]; /* Content of Record man area */ +}; + +struct dvd_structure_0E { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar field_id; /* Field ID (1) */ + Uchar application_code; /* Disc Application code */ + Uchar phys_data; /* Disc Phisical Data */ + Uchar last_recordable_addr[3]; /* Last addr of recordable area */ + Uchar res_a[2]; /* Reserved */ + Uchar field_id_2; /* Field ID (2) */ + Uchar ind_wr_power; /* Recommended writing power */ + Uchar ind_wavelength; /* Wavelength for ind_wr_power */ + Uchar opt_wr_strategy[4]; /* Optimum write Strategy */ + Uchar res_b[1]; /* Reserved */ + Uchar field_id_3; /* Field ID (3) */ + Uchar man_id[6]; /* Manufacturer ID */ + Uchar res_m1; /* Reserved */ + Uchar field_id_4; /* Field ID (4) */ + Uchar man_id2[6]; /* Manufacturer ID */ + Uchar res_m2; /* Reserved */ +}; + +struct dvd_structure_0F { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar res45[2]; /* Reserved */ + Uchar random[2]; /* Random number */ + Uchar year[4]; /* Year (ascii) */ + Uchar month[2]; /* Month (ascii) */ + Uchar day[2]; /* Day (ascii) */ + Uchar hour[2]; /* Hour (ascii) */ + Uchar minute[2]; /* Minute (ascii) */ + Uchar second[2]; /* Second (ascii) */ +}; + +struct dvd_structure_0F_w { + Uchar data_len[2]; /* Data len without this info */ + Uchar res23[2]; /* Reserved */ + Uchar res45[2]; /* Reserved */ + Uchar year[4]; /* Year (ascii) */ + Uchar month[2]; /* Month (ascii) */ + Uchar day[2]; /* Day (ascii) */ + Uchar hour[2]; /* Hour (ascii) */ + Uchar minute[2]; /* Minute (ascii) */ + Uchar second[2]; /* Second (ascii) */ +}; + +struct mmc_cue { + Uchar cs_ctladr; /* CTL/ADR for this track */ + Uchar cs_tno; /* This track number */ + Uchar cs_index; /* Index within this track */ + Uchar cs_dataform; /* Data form */ + Uchar cs_scms; /* Serial copy management */ + Uchar cs_min; /* Absolute time minutes */ + Uchar cs_sec; /* Absolute time seconds */ + Uchar cs_frame; /* Absolute time frames */ +}; + +struct mmc_performance_header { + Uchar p_datalen[4]; /* Performance Data length */ +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + Ucbit p_exept :1; /* Nominal vs. Exept. conditions*/ + Ucbit p_write :1; /* Write vs. Read performance */ + Ucbit p_res_4 :6; /* Reserved bits... */ +#else /* Motorola bitorder */ + Ucbit p_res_4 :6; /* Reserved bits... */ + Ucbit p_write :1; /* Write vs. Read performance */ + Ucbit p_exept :1; /* Nominal vs. Exept. conditions*/ +#endif + Uchar p_res[3]; /* Reserved bytes */ +}; + + +struct mmc_performance { /* Type == 00 (nominal) */ + Uchar start_lba[4]; /* Starting LBA */ + Uchar start_perf[4]; /* Start Performance */ + Uchar end_lba[4]; /* Ending LBA */ + Uchar end_perf[4]; /* Ending Performance */ +}; + +struct mmc_exceptions { /* Type == 00 (execptions) */ + Uchar lba[4]; /* LBA */ + Uchar time[2]; /* Time */ +}; + +struct mmc_write_speed { /* Type == 00 (write speed) */ +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + Ucbit p_mrw :1; /* Suitable for mixed read/write*/ + Ucbit p_exact :1; /* Speed count for whole media */ + Ucbit p_rdd :1; /* Media rotational control */ + Ucbit p_wrc :2; /* Write rotational control */ + Ucbit p_res :3; /* Reserved bits... */ +#else /* Motorola bitorder */ + Ucbit p_res :3; /* Reserved bits... */ + Ucbit p_wrc :2; /* Write rotational control */ + Ucbit p_rdd :1; /* Media rotational control */ + Ucbit p_exact :1; /* Speed count for whole media */ + Ucbit p_mrw :1; /* Suitable for mixed read/write*/ +#endif + Uchar res[3]; /* Reserved Bytes */ + Uchar end_lba[4]; /* Ending LBA */ + Uchar read_speed[4]; /* Read Speed */ + Uchar write_speed[4]; /* Write Speed */ +}; + +#define WRC_DEF_RC 0 /* Media default rotational control */ +#define WRC_CAV 1 /* CAV */ + + +struct mmc_streaming { /* Performance for set streaming*/ +#if defined(_BIT_FIELDS_LTOH) /* Intel bitorder */ + Ucbit p_ra :1; /* Random Acess */ + Ucbit p_exact :1; /* Set values exactly */ + Ucbit p_rdd :1; /* Restore unit defaults */ + Ucbit p_wrc :2; /* Write rotational control */ + Ucbit p_res :3; /* Reserved bits... */ +#else /* Motorola bitorder */ + Ucbit p_res :3; /* Reserved bits... */ + Ucbit p_wrc :2; /* Write rotational control */ + Ucbit p_rdd :1; /* Restore unit defaults */ + Ucbit p_exact :1; /* Set values exactly */ + Ucbit p_ra :1; /* Random Acess */ +#endif + Uchar res[3]; /* Reserved Bytes */ + Uchar start_lba[4]; /* Starting LBA */ + Uchar end_lba[4]; /* Ending LBA */ + Uchar read_size[4]; /* Read Size */ + Uchar read_time[4]; /* Read Time */ + Uchar write_size[4]; /* Write Size */ + Uchar write_time[4]; /* Write Time */ +}; + +#endif /* _SCSIMMC_H */ diff --git a/wodim/sector.c b/wodim/sector.c new file mode 100644 index 0000000..2c253d6 --- /dev/null +++ b/wodim/sector.c @@ -0,0 +1,263 @@ +/* + * 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. + * + */ + +/* @(#)sector.c 1.13 04/03/01 Copyright 2001-2004 J. Schilling */ +/* + * Functions needed to use libedc_ecc from cdrecord + * + * Copyright (c) 2001-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 <utypes.h> +#include <timedefs.h> +#include <schily.h> + +#include "wodim.h" +#include "movesect.h" + +#ifdef HAVE_LIB_EDC_ECC + + +#define LAYER2 +#define EDC_LAYER2 +#define ENCODER +#define EDC_ENCODER +#include <ecc.h> + +#ifdef DO8 +#define HAVE_NEW_LIB_EDC +#endif + +int encspeed(BOOL be_verbose); +void encsectors(track_t *trackp, Uchar *bp, int address, int nsecs); +void scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs); +void encodesector(Uchar *sp, int sectype, int address); +void fillsector(Uchar *sp, int sectype, int address); + +/* + * Sector types known by lib libedc_ecc: + */ +#ifdef __comment__ + /* MMC */ +#define MODE_0 0 /* -> XX 12+4+2336 (12+4uuu von libedc) */ +#define MODE_1 1 /* -> 8 12+4+2048+288 (124+4uuu+288 von libedc)*/ +#define MODE_2 2 /* -> 9 12+4+2336 (12+4uuu von libedc) */ +#define MODE_2_FORM_1 3 /* -> 10/11 12+4+8+2048+280 (12+4hhhuuu+280 von libedc)*/ +#define MODE_2_FORM_2 4 /* -> 12 (eher 13!) 12+4+8+2324+4 (12+4hhhuuu+4 von libedc)*/ +#define AUDIO 5 +#define UNKNOWN 6 +#endif + +/* + * known sector types + */ +#ifndef EDC_MODE_0 +#define EDC_MODE_0 MODE_0 +#endif +#ifndef EDC_MODE_1 +#define EDC_MODE_1 MODE_1 +#endif +#ifndef EDC_MODE_2 +#define EDC_MODE_2 MODE_2 +#endif +#ifndef EDC_MODE_2_FORM_1 +#define EDC_MODE_2_FORM_1 MODE_2_FORM_1 +#endif +#ifndef EDC_MODE_2_FORM_2 +#define EDC_MODE_2_FORM_2 MODE_2_FORM_2 +#endif +#ifndef EDC_AUDIO +#define EDC_AUDIO AUDIO +#endif +#ifndef EDC_UNKNOWN +#define EDC_UNKNOWN UNKNOWN +#endif + +/* + * Compute max sector encoding speed + */ +int +encspeed(BOOL be_verbose) +{ + track_t t[1]; + Uchar sect[2352]; + int i; + struct timeval tv; + struct timeval tv2; + + t[0].sectype = ST_MODE_1; + + /* + * Encoding speed is content dependant. + * Set up a known non-null pattern in the sector before; to make + * the result of this test independant of the current stack content. + */ + for (i = 0; i < 2352; ) { + sect[i++] = 'J'; + sect[i++] = 'S'; + } + gettimeofday(&tv, (struct timezone *)0); + for (i = 0; i < 75000; i++) { /* Goes up to 1000x */ + encsectors(t, sect, 12345, 1); + gettimeofday(&tv2, (struct timezone *)0); + if (tv2.tv_sec >= (tv.tv_sec+1) && + tv2.tv_usec >= tv.tv_usec) + break; + } + if (be_verbose) { + printf("Encoding speed : %dx (%d sectors/s) for libedc from Heiko Eißfeldt\n", + (i+74)/75, i); + } + return ((i+74)/75); +} + +/* + * Encode sectors according to trackp->sectype + */ +void +encsectors(track_t *trackp, Uchar *bp, int address, int nsecs) +{ + int sectype = trackp->sectype; + + if ((sectype & ST_MODE_MASK) == ST_MODE_AUDIO) + return; + + while (--nsecs >= 0) { + encodesector(bp, sectype, address); + address++; + bp += trackp->secsize; + } +} + + +#ifdef CLONE_WRITE + +#define IS_SECHDR(p) ((p)[0] == 0 && \ + (p)[1] == 0xFF && (p)[2] == 0xFF && \ + (p)[3] == 0xFF && (p)[4] == 0xFF && \ + (p)[5] == 0xFF && (p)[6] == 0xFF && \ + (p)[7] == 0xFF && (p)[8] == 0xFF && \ + (p)[9] == 0xFF && (p)[10] == 0xFF && \ + (p)[11] == 0) +/* + * Scramble data sectors without coding (needed for clone writing) + */ +void +scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs) +{ + /* + * In Clone write mode, we cannot expect that the sector type + * of a "track" which really is a file holding the whole disk + * is flagged with something that makes sense. + * + * For this reason, we check each sector if it's a data sector + * and needs scrambling. + */ + while (--nsecs >= 0) { + if (IS_SECHDR(bp)) + scramble_L2(bp); + bp += trackp->secsize; + } +} +#else +void +scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs) +{ + comerrno(EX_BAD, "Cannot write in clone RAW mode.\n"); +} +#endif + +/* + * Encode one sector according to trackp->sectype + */ +void +encodesector(Uchar *sp, int sectype, int address) +{ + if (address < -150) + address += 450150; + else + address += 150; +#define _address address + + + switch (sectype & ST_MODE_MASK) { + + case ST_MODE_0: + do_encode_L2(sp, EDC_MODE_0, _address); + break; + + case ST_MODE_1: + do_encode_L2(sp, EDC_MODE_1, _address); + break; + + case ST_MODE_2: + do_encode_L2(sp, EDC_MODE_2, _address); + break; + + case ST_MODE_2_FORM_1: + sp[16+2] &= ~0x20; /* Form 1 sector */ + sp[16+4+2] &= ~0x20; /* Form 1 sector 2nd copy */ + /* FALLTHROUGH */ + + case ST_MODE_2_MIXED: + do_encode_L2(sp, EDC_MODE_2_FORM_1, _address); + break; + + case ST_MODE_2_FORM_2: + sp[16+2] |= 0x20; /* Form 2 sector */ + sp[16+4+2] |= 0x20; /* Form 2 sector 2nd copy */ + + do_encode_L2(sp, EDC_MODE_2_FORM_2, _address); + break; + + case ST_MODE_AUDIO: + return; + default: + fill2352(sp, '\0'); + return; + } + if ((sectype & ST_NOSCRAMBLE) == 0) { + scramble_L2(sp); +#ifndef EDC_SCRAMBLE_NOSWAP + swabbytes(sp, 2352); +#endif + } +} + +/* + * Create one zero filles encoded sector (according to trackp->sectype) + */ +void +fillsector(Uchar *sp, int sectype, int address) +{ + fill2352(sp, '\0'); + encodesector(sp, sectype, address); +} + +#endif /* HAVE_LIB_EDC_ECC */ diff --git a/wodim/subchan.c b/wodim/subchan.c new file mode 100644 index 0000000..7195992 --- /dev/null +++ b/wodim/subchan.c @@ -0,0 +1,997 @@ +/* + * 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. + * + */ + +/* @(#)subchan.c 1.20 05/06/11 Copyright 2000-2004 J. Schilling */ +/* + * Subchannel processing + * + * Copyright (c) 2000-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 <unixstd.h> +#include <standard.h> +#include <utypes.h> +#include <schily.h> + +#include <usal/scsitransp.h> + +#include "wodim.h" +#include "crc16.h" + +int do_leadin(track_t *trackp); +int write_leadin(SCSI *usalp, cdr_t *dp, track_t *trackp, int leadinstart); +int write_leadout(SCSI *usalp, cdr_t *dp, track_t *trackp); +void fillsubch(track_t *trackp, Uchar *sp, int secno, int nsecs); +void filltpoint(Uchar *sub, int ctrl_adr, int point, msf_t *mp); +void fillttime(Uchar *sub, msf_t *mp); +static void filldsubq(Uchar *sub, int ca, int t, int i, msf_t *mrp, + msf_t *mp); +static void fillmcn(Uchar *sub, Uchar *mcn); +static void fillisrc(Uchar *sub, Uchar *isrc); +static int ascii2q(int c); +static void qpto16(Uchar *sub, Uchar *subq, int dop); +void qpto96(Uchar *sub, Uchar *subq, int dop); +void addrw(Uchar *sub, Uchar *subrwptr); +void qwto16(Uchar *subq, Uchar *subptr); +void subrecodesecs(track_t *trackp, Uchar *bp, int address, int nsecs); +static void subinterleave(Uchar *sub); + +/*#define TEST_CRC*/ +#ifdef TEST_CRC +static void testcrc(void); +#endif + +/*Die 96 Bits == 12 Bytes haben folgendes Aussehen:*/ + +struct q { + Uchar ctrl_adr; /* 0 (ctrl << 4) | adr */ + Uchar track; /* 1 current track # */ + Uchar index; /* 2 current index # */ + Uchar pmin; /* 3 Relative time minutes part */ + Uchar psec; /* 4 Relative time seconds part */ + Uchar pframe; /* 5 Relative time frames part */ + Uchar zero; /* 6 */ + Uchar amin; /* 7 Absolute time minutes part */ + Uchar asec; /* 8 Absolute time seconds part */ + Uchar aframe; /* 9 Absolute time frames part */ + Uchar crc1; /* 10 all bits inverted. Polynom is */ + Uchar crc2; /* 11 X^16 + X^12 + X^5 + 1 */ +}; + +Uchar _subq[110][12]; +int _nsubh; + +extern int lverbose; +extern int xdebug; + +/* + * Prepare master sunchannel data for RAW TOC. + */ +int +do_leadin(track_t *trackp) +{ + int tracks = trackp->tracks; + msf_t m; + int ctrl; + int i; + int toctype = trackp[0].tracktype & TOC_MASK; + + if (_nsubh) { + if (xdebug) + printf("Using CLONE TOC....\n"); + return (0); + } + if (xdebug) + printf("Leadin TOC Type: %d\n", trackp[0].tracktype & TOC_MASK); + if (lverbose > 1) { + for (i = 1; i <= tracks+1; i++) + printf("Track %d start %ld\n", i, trackp[i].trackstart); + } + +#ifdef TEST_CRC + testcrc(); +/* exit(1);*/ +#endif + + fillbytes(_subq, sizeof (_subq), '\0'); + + /* + * Fill in point 0xA0 for first track # on disk + */ + ctrl = (st2mode[trackp[0].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[0])) + ctrl |= TM_ALLOW_COPY << 4; + m.msf_min = trackp[1].trackno; + /* + * Disk Type: 0 = AUDIO/DATA, 0x10 = CDI, 0x20 = XA mode 2 + */ + m.msf_sec = toc2sess[toctype & TOC_MASK]; + m.msf_sec = from_bcd(m.msf_sec); /* convert to BCD */ + m.msf_frame = 0; + filltpoint(_subq[0], ctrl|0x01, 0xA0, &m); + if (lverbose > 2) + usal_prbytes("", _subq[0], 12); + + /* + * Fill in point 0xA1 for last track # on disk + */ + ctrl = (st2mode[trackp[tracks].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[tracks])) + ctrl |= TM_ALLOW_COPY << 4; + m.msf_min = trackp[tracks].trackno; + m.msf_sec = 0; + m.msf_frame = 0; + filltpoint(_subq[1], ctrl|0x01, 0xA1, &m); + if (lverbose > 2) + usal_prbytes("", _subq[1], 12); + + /* + * Fill in point 0xA2 for lead out start time on disk + */ + lba_to_msf(trackp[tracks+1].trackstart, &m); + ctrl = (st2mode[trackp[tracks].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[tracks])) + ctrl |= TM_ALLOW_COPY << 4; + filltpoint(_subq[2], ctrl|0x01, 0xA2, &m); + if (lverbose > 2) + usal_prbytes("", _subq[2], 12); + + /* + * Fill in track start times. + */ + for (i = 1; i <= tracks; i++) { + lba_to_msf(trackp[i].trackstart, &m); + ctrl = (st2mode[trackp[i].sectype & ST_MASK]) << 4; + if (is_copy(&trackp[i])) + ctrl |= TM_ALLOW_COPY << 4; + filltpoint(_subq[i-1+3], ctrl|0x01, to_bcd(trackp[i].trackno), &m); /* track n */ + if (lverbose > 2) + usal_prbytes("", _subq[i-1+3], 12); + } + return (0); +} + +/* + * Write TOC (lead-in) + * + * Use previously prepared master subchannel data to create the + * subchannel frames for the lead-in. + */ +int +write_leadin(SCSI *usalp, cdr_t *dp, track_t *trackp, int leadinstart) +{ + msf_t m; + int i; + Uint j; + Uchar *bp = usalp->bufptr; + Uchar *subp; + Uchar *sp; + int secsize; + int secspt; + int bytespt; + long amount; + int startsec; + long bytes = 0L; + int textoff = 0; + msf_t msf; + + secsize = trackp[0].secsize; + secspt = trackp[0].secspt; + bytespt = secspt * secsize; + + lba_to_msf(leadinstart, &msf); + + fillbytes(bp, bytespt, '\0'); + + if (_nsubh) { + if (xdebug) + printf("Using CLONE LEADIN\n"); + } + if (xdebug) { + printf("Leadinstart: %d %d:%d/%d", + leadinstart, + msf.msf_min, msf.msf_sec, msf.msf_frame); + printf(" FLAGS: 0x%X sect: %X RAW16:%d secs: %d spt: %d\n", + trackp[0].flags, trackp[0].sectype, + is_raw16(&trackp[0]), secsize, secspt); + } + + startsec = leadinstart; + sp = bp; + subp = bp + 2352; + for (i = leadinstart, j = 0; i < -150; i++, j++) { + /* + * TOC hat folgende unterschiedliche Sub Q Frames: + * A0 First Track + * A1 Last Track + * A3 Lead out start + * 1..99 Tracks + * == 3 + N* tracks + * Jeder Frame wird 3x wiederholt. + */ + if (_nsubh) { + if (j >= (3*_nsubh)) + j = 0; + } else { + if (j >= (3*3 + 3*trackp->tracks)) + j = 0; + } + lba_to_msf((long)i, &m); + fillttime(_subq[j/3], &m); + fillcrc(_subq[j/3], 12); + if (xdebug > 2) + usal_prbytes("", _subq[j/3], 12); + if (is_raw16(&trackp[0])) { + qpto16(subp, _subq[j/3], 0); + } else { + extern Uchar *textsub; + extern int textlen; + + qpto96(subp, _subq[j/3], 0); + if (textsub) { + addrw(subp, &textsub[textoff]); + textoff += 96; + if (textoff >= textlen) + textoff = 0; + } +/* if (is_raw96p(&trackp[0]))*/ +/* subinterleave(subp);*/ + } + if ((startsec+secspt-1) == i || i == -151) { + if ((i-startsec+1) < secspt) { + secspt = i-startsec+1; + bytespt = secspt * secsize; + } + encsectors(trackp, bp, startsec, secspt); + + amount = write_secs(usalp, dp, + (char *)bp, startsec, bytespt, secspt, FALSE); + if (amount < 0) { + printf("write leadin data: error after %ld bytes\n", + bytes); + return (-1); + } + bytes += amount; + startsec = i+1; + sp = bp; + subp = bp + 2352; + continue; + } + sp += secsize; + subp += secsize; + } + return (0); +} + +/* + * Write Track 0xAA (lead-out) + */ +int +write_leadout(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int tracks = trackp->tracks; + msf_t m; + msf_t mr; + int ctrl; + int i; + int j; + Uchar *bp = usalp->bufptr; + Uchar *subp; + Uchar *sp; + int secsize; + int secspt; + int bytespt; + long amount; + long startsec; + long endsec; + long bytes = 0L; + int leadoutstart; + Uchar sub[12]; + BOOL p; + msf_t msf; + + fillbytes(sub, 12, '\0'); + + secsize = trackp[tracks+1].secsize; + secspt = trackp[tracks+1].secspt; + bytespt = secspt * secsize; + + leadoutstart = trackp[tracks+1].trackstart; + lba_to_msf(leadoutstart, &msf); + + fillbytes(bp, bytespt, '\0'); + + if (xdebug) { + printf("Leadoutstart: %d %d:%d/%d amt %ld", + leadoutstart, + msf.msf_min, msf.msf_sec, msf.msf_frame, + trackp[tracks+1].tracksecs); + printf(" FLAGS: 0x%X sect: %X RAW16:%d secs: %d spt: %d\n", + trackp[tracks+1].flags, trackp[tracks+1].sectype, + is_raw16(&trackp[tracks+1]), secsize, secspt); + } + + startsec = leadoutstart; + endsec = startsec + trackp[tracks+1].tracksecs; + sp = bp; + subp = bp + 2352; + ctrl = (st2mode[trackp->sectype & ST_MASK]) << 4; + if (is_copy(trackp)) + ctrl |= TM_ALLOW_COPY << 4; + + for (i = leadoutstart, j = 0; i < endsec; i++, j++) { + + lba_to_msf((long)i, &m); + sec_to_msf((long)j, &mr); + filldsubq(sub, ctrl|0x01, 0xAA, 1, &mr, &m); + sub[1] = 0xAA; + fillcrc(sub, 12); + p = (j % 150) < 75; + if (j < 150) + p = FALSE; + if (xdebug > 2) + usal_prbytes(p?"P":" ", sub, 12); + + if (is_raw16(&trackp[0])) { + qpto16(subp, sub, p); + } else { + qpto96(subp, sub, p); +/* if (is_raw96p(&trackp[0]))*/ +/* subinterleave(subp);*/ + } + if ((startsec+secspt-1) == i || i == (endsec-1)) { + if ((i-startsec+1) < secspt) { + secspt = i-startsec+1; + bytespt = secspt * secsize; + } + encsectors(trackp, bp, startsec, secspt); + + amount = write_secs(usalp, dp, + (char *)bp, startsec, bytespt, secspt, FALSE); + if (amount < 0) { + printf("write leadout data: error after %ld bytes\n", + bytes); + return (-1); + } + bytes += amount; + startsec = i+1; + sp = bp; + subp = bp + 2352; + continue; + } + sp += secsize; + subp += secsize; + } + return (0); +} + +/* + * Fill in subchannel data. + * + * This function is used to prepare the sub channels when writing + * the data part of a CD (bewteen lead-in and lead-out). + */ +void +fillsubch(track_t *trackp, + Uchar *sp /* Sector data pointer */, + int secno /* Starting sector # */, + int nsecs /* # of sectors to fill */) +{ + msf_t m; + msf_t mr; + int ctrl; + int i; + int rsecno; + int end; + int secsize = trackp->secsize; + int trackno = trackp->trackno; + int nindex = trackp->nindex; + int curindex; + long *tindex = NULL; + long nextindex = 0L; + Uchar sub[12]; + Uchar *sup; + char *mcn; + /* + * In theory this should make fillsubch() non-reenrtrant but it seems + * that the probability check at the beginning of the function is + * sufficient to make it work as expected. + */ +static long nextmcn = -1000000L; +static long nextisrc = -1000000L; +static Uchar lastindex = 255; + + fillbytes(sub, 12, '\0'); + + mcn = track_base(trackp)->isrc; + rsecno = secno - trackp->trackstart; + if ((secno + nsecs) > (trackp->trackstart + trackp->tracksecs)) { + comerrno(EX_BAD, "Implementation botch: track boundary in buffer.\n"); + } + sup = sp + 2352; + if (mcn && (nextmcn < secno || nextmcn > (secno+100))) { + nextmcn = secno/100*100 + 99; + } + if (trackp->isrc && (nextisrc < secno || nextisrc > (secno+100))) { + nextisrc = secno/100*100 + 49; + } + ctrl = (st2mode[trackp->sectype & ST_MASK]) << 4; + if (is_copy(trackp)) + ctrl |= TM_ALLOW_COPY << 4; + +#ifdef SUB_DEBUG + fprintf(stderr, "Tracknl %d nindex %d trackstart %ld rsecno %d index0start %ld nsecs %d\n", + trackno, nindex, trackp->trackstart, rsecno, trackp->index0start, nsecs); +#endif + + if (rsecno < 0) { + /* + * Called to manually write pregap null data into the pregap + * while 'trackp' points to the curent track. For this reason, + * the sectors are before the start of track 'n' index 0. + */ + curindex = 0; + end = trackp->trackstart; + + } else if (rsecno > trackp->index0start) { + /* + * This track contains pregap of next track. + * We currently are inside this pregap. + */ + trackno++; + curindex = 0; + end = trackp->trackstart + trackp->tracksecs; + } else { + /* + * We are inside the normal data part of this track. + * This is index_1...index_m for track n. + * Set 'end' to 0 in this case although it is only used + * if 'index' is 0. But GCC gives a warning that 'end' + * might be uninitialized. + */ + end = 0; + curindex = 1; + if (nindex > 1) { + tindex = trackp->tindex; + nextindex = trackp->tracksecs; + /* + * find current index in list + */ + for (curindex = nindex; curindex >= 1; curindex--) { + if (rsecno >= tindex[curindex]) { + if (curindex < nindex) + nextindex = tindex[curindex+1]; + break; + } + } + } + } + + for (i = 0; i < nsecs; i++) { + + if (tindex != NULL && rsecno >= nextindex) { + /* + * Skip to next index in list. + */ + if (curindex < nindex) { + curindex++; + nextindex = tindex[curindex+1]; + } + } + if (rsecno == trackp->index0start) { + /* + * This track contains pregap of next track. + */ + trackno++; + curindex = 0; + end = trackp->trackstart + trackp->tracksecs; + } + lba_to_msf((long)secno, &m); + if (curindex == 0) + sec_to_msf((long)end-1 - secno, &mr); + else + sec_to_msf((long)rsecno, &mr); + if (is_scms(trackp)) { + if ((secno % 8) <= 3) { + ctrl &= ~(TM_ALLOW_COPY << 4); + } else { + ctrl |= TM_ALLOW_COPY << 4; + } + } + filldsubq(sub, ctrl|0x01, trackno, curindex, &mr, &m); + if (mcn && (secno == nextmcn)) { + if (curindex == lastindex) { + fillmcn(sub, (Uchar *)mcn); + nextmcn = (secno+1)/100*100 + 99; + } else { + nextmcn++; + } + } + if (trackp->isrc && (secno == nextisrc)) { + if (curindex == lastindex) { + fillisrc(sub, (Uchar *)trackp->isrc); + nextisrc = (secno+1)/100*100 + 49; + } else { + nextisrc++; + } + } + fillcrc(sub, 12); + if (xdebug > 2) + usal_prbytes(curindex == 0 ? "P":" ", sub, 12); + if (is_raw16(trackp)) { + qpto16(sup, sub, curindex == 0); + } else { + qpto96(sup, sub, curindex == 0); +/* if (is_raw96p(trackp))*/ +/* subinterleave(sup);*/ + } + lastindex = curindex; + secno++; + rsecno++; + sup += secsize; + } +} + + +/* + * Fill TOC Point + * Ax Werte einfüllen. + */ +void +filltpoint(Uchar *sub, int ctrl_adr, int point, msf_t *mp) +{ + sub[0] = ctrl_adr; + sub[2] = point; + sub[7] = to_bcd(mp->msf_min); + sub[8] = to_bcd(mp->msf_sec); + sub[9] = to_bcd(mp->msf_frame); +} + +/* + * Fill TOC time + * Aktuelle Zeit in TOC Sub-Q einfüllen. + */ +void +fillttime(Uchar *sub, msf_t *mp) +{ + sub[3] = to_bcd(mp->msf_min); + sub[4] = to_bcd(mp->msf_sec); + sub[5] = to_bcd(mp->msf_frame); +} + +/* + * Q-Sub in Datenbereich füllen. + */ +static void +filldsubq(Uchar *sub, int ca, int t, int i, msf_t *mrp, msf_t *mp) +{ + sub[0] = ca; + sub[1] = to_bcd(t); + sub[2] = to_bcd(i); + sub[3] = to_bcd(mrp->msf_min); + sub[4] = to_bcd(mrp->msf_sec); + sub[5] = to_bcd(mrp->msf_frame); + + sub[7] = to_bcd(mp->msf_min); + sub[8] = to_bcd(mp->msf_sec); + sub[9] = to_bcd(mp->msf_frame); +} + +/* + * Fill MCN + * MCN konvertieren und in Sub-Q einfüllen. + */ +static void +fillmcn(Uchar *sub, Uchar *mcn) +{ + register int i; + register int c; + + sub[0] = ADR_MCN; + for (i = 1; i <= 8; i++) { + c = *mcn++; + if (c >= '0' && c <= '9') + sub[i] = (c - '0') << 4; + else + sub[i] = 0; + + if (c != '\0') + c = *mcn++; + if (c >= '0' && c <= '9') + sub[i] |= (c - '0'); + + if (c == '\0') { + i++; + break; + } + } + for (; i <= 8; i++) + sub[i] = '\0'; +} + +/* + * Fill ISRC + * ISRC konvertieren und in Sub-Q einfüllen. + */ +static void +fillisrc(Uchar *sub, Uchar *isrc) +{ + register int i; + register int j; + Uchar tmp[13]; + Uchar *sp; + + sub[0] = ADR_ISRC; + sp = &sub[1]; + + /* + * Convert into Sub-Q character coding + */ + for (i = 0, j = 0; i < 12; i++) { + if (isrc[i+j] == '-') + j++; + if (isrc[i+j] == '\0') + break; + tmp[i] = ascii2q(isrc[i+j]); + } + for (; i < 13; i++) + tmp[i] = '\0'; + + /* + * The first 5 chars from e.g. "FI-BAR-99-00312" + */ + sp[0] = tmp[0] << 2; + sp[0] |= (tmp[1] >> 4) & 0x03; + sp[1] = (tmp[1] << 4) & 0xF0; + sp[1] |= (tmp[2] >> 2) & 0x0F; + sp[2] = (tmp[2] << 6) & 0xC0; + sp[2] |= tmp[3] & 0x3F; + sp[3] = tmp[4] << 2; + + /* + * Now 7 digits from e.g. "FI-BAR-99-00312" + */ + for (i = 4, j = 5; i < 8; i++) { + sp[i] = tmp[j++] << 4; + sp[i] |= tmp[j++]; + } +} + +/* + * ASCII -> Sub-Q ISRC code conversion + */ +static int +ascii2q(int c) +{ + if (c >= '0' && c <= '9') + return (c - '0'); + else if (c >= '@' && c <= 'o') + return (0x10 + c - '@'); + return (0); +} + +/* + * Q-Sub auf 16 Bytes blähen und P-Sub addieren + * + * OUT: sub, IN: subqptr + */ +static void +qpto16(Uchar *sub, Uchar *subqptr, int dop) +{ + if (sub != subqptr) + movebytes(subqptr, sub, 12); + sub[12] = '\0'; + sub[13] = '\0'; + sub[14] = '\0'; + sub[15] = '\0'; + if (dop) + sub[15] |= 0x80; + +} + +/* + * Q-Sub auf 96 Bytes blähen und P-Sub addieren + * + * OUT: sub, IN: subqptr + */ +void +qpto96(Uchar *sub, Uchar *subqptr, int dop) +{ + Uchar tmp[16]; + Uchar *p; + int c; + int i; + + if (subqptr == sub) { + /* + * Remember 12 byte subchannel data if subchannel + * is overlapping. + */ + movebytes(subqptr, tmp, 12); + subqptr = tmp; + } + /* + * Clear all subchannel bits in the 96 byte target space. + */ + fillbytes(sub, 96, '\0'); + + /* BEGIN 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++; + } +} + +/* + * Add R-W-Sub (96 Bytes) to P-Q-Sub (96 Bytes) + * + * OUT: sub, IN: subrwptr + */ +void +addrw(register Uchar *sub, register Uchar *subrwptr) +{ + register int i; + +#define DO8(a) a; a; a; a; a; a; a; a; + + for (i = 0; i < 12; i++) { + DO8(*sub++ |= *subrwptr++ & 0x3F); + } +} + +/* + * Q-W-Sub (96 Bytes) auf 16 Bytes schrumpfen + * + * OUT: subq, IN: subptr + */ +void +qwto16(Uchar *subq, Uchar *subptr) +{ + register int i; + register int np = 0; + register Uchar *p; + Uchar tmp[96]; + + p = subptr; + for (i = 0; i < 96; i++) + if (*p++ & 0x80) + np++; + p = subptr; + if (subptr == subq) { + /* + * Remember 96 byte subchannel data if subchannel + * is overlapping. + */ + movebytes(subptr, tmp, 96); + p = tmp; + } + + for (i = 0; i < 12; i++) { + subq[i] = 0; + if (*p++ & 0x40) + subq[i] |= 0x80; + if (*p++ & 0x40) + subq[i] |= 0x40; + if (*p++ & 0x40) + subq[i] |= 0x20; + if (*p++ & 0x40) + subq[i] |= 0x10; + if (*p++ & 0x40) + subq[i] |= 0x08; + if (*p++ & 0x40) + subq[i] |= 0x04; + if (*p++ & 0x40) + subq[i] |= 0x02; + if (*p++ & 0x40) + subq[i] |= 0x01; + } + subq[12] = 0; + subq[13] = 0; + subq[14] = 0; + if (np > (96/2)) + subq[15] = 0x80; +} + +/* + * Recode subchannels of sectors from 2352 + 96 bytes to 2352 + 16 bytes + */ +void +subrecodesecs(track_t *trackp, Uchar *bp, int address, int nsecs) +{ + bp += 2352; + while (--nsecs >= 0) { + qwto16(bp, bp); + bp += trackp->isecsize; + } +} + +#ifndef HAVE_LIB_EDC_ECC +void +encsectors(track_t *trackp, Uchar *bp, int address, int nsecs) +{ + int sectype = trackp->sectype; + + if ((sectype & ST_MODE_MASK) == ST_MODE_AUDIO) + return; + + comerrno(EX_BAD, "Can only write audio sectors in RAW mode.\n"); +} + +void +scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs) +{ + comerrno(EX_BAD, "Cannot write in clone RAW mode.\n"); +} +#endif + +/*--------------------------------------------------------------------------*/ +#ifdef TEST_CRC + +Uchar tq[12] = { 0x01, 0x00, 0xA0, 0x98, 0x06, 0x12, 0x00, 0x01, 0x00, 0x00, 0xE3, 0x74 }; + +/* +01 00 A0 98 06 12 00 01 00 00 E3 74 +01 00 A0 98 06 13 00 01 00 00 49 25 +01 00 A1 98 06 14 00 13 00 00 44 21 +01 00 A1 98 06 15 00 13 00 00 EE 70 +01 00 A1 98 06 16 00 13 00 00 00 A2 +01 00 A2 98 06 17 00 70 40 73 E3 85 +01 00 A2 98 06 18 00 70 40 73 86 7C +01 00 A2 98 06 19 00 70 40 73 2C 2D +01 00 01 98 06 20 00 00 02 00 3B 71 +01 00 01 98 06 21 00 00 02 00 91 20 +01 00 01 98 06 22 00 00 02 00 7F F2 +01 00 02 98 06 23 00 03 48 45 BE E0 +01 00 02 98 06 24 00 03 48 45 D9 34 + +*/ + +static int b(int bcd); + + +static int +b(int bcd) +{ + return ((bcd & 0x0F) + 10 * (((bcd)>> 4) & 0x0F)); +} + +static void +testcrc() +{ + struct q q; + int ocrc; + int crc1; + int crc2; + + movebytes(&tq, &q, 12); + crc1 = q.crc1 & 0xFF; + crc2 = q.crc2 & 0xFF; + + /* + * Per RED Book, CRC Bits on disk are inverted. + * Invert them again to make calcCRC() work. + */ + q.crc1 ^= 0xFF; + q.crc2 ^= 0xFF; + + ocrc = calcCRC((Uchar *)&q, 12); + printf("AC: %02X t: %3d (%02X) i: %3d (%02X) %d:%d:%d %d:%d:%d %02X%02X %X (%X)\n", + q.ctrl_adr, + b(q.track), + b(q.track) & 0xFF, + b(q.index), + q.index & 0xFF, + b(q.pmin), + b(q.psec), + b(q.pframe), + b(q.amin), + b(q.asec), + b(q.aframe), + crc1, crc2, + ocrc, + fillcrc((Uchar *)&q, 12) & 0xFFFF); +} +#endif /* TEST_CRC */ + +#ifdef sss +96 / 24 = 4 + +index 1 < - > 18 +index 2 < - > 5 +index 3 < - > 23 + +delay index mod 8 +#endif + +/* + * Sub 96 Bytes Interleave + */ +static void +subinterleave(Uchar *sub) +{ + Uchar *p; + int i; + + for (i = 0, p = sub; i < 4; i++) { + Uchar save; + + /* + * index 1 < - > 18 + * index 2 < - > 5 + * index 3 < - > 23 + */ + save = p[1]; + p[1] = p[18]; + p[18] = save; + + save = p[2]; + p[2] = p[5]; + p[5] = save; + + save = p[3]; + p[3] = p[23]; + p[23] = save; + + p += 24; + } +} diff --git a/wodim/wm_packet.c b/wodim/wm_packet.c new file mode 100644 index 0000000..9566a52 --- /dev/null +++ b/wodim/wm_packet.c @@ -0,0 +1,306 @@ +/* + * 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. + * + */ + +/* @(#)wm_packet.c 1.25 04/03/01 Copyright 1995, 1997, 2001-2004 J. Schilling */ +/* + * CDR write method abtraction layer + * packet writing intercace routines + * + * Copyright (c) 1995, 1997, 2001-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 <stdxlib.h> +#include <unixstd.h> +#include <timedefs.h> +#include <standard.h> +#include <utypes.h> +#include <schily.h> + +#include <usal/scsitransp.h> +#include "wodim.h" +#include "xio.h" + +extern int debug; +extern int verbose; +extern int lverbose; + +extern char *buf; /* The transfer buffer */ + +int write_packet_data(SCSI *usalp, cdr_t *dp, track_t *trackp); + +int +write_packet_data(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int track = trackp->trackno; + int f = -1; + int isaudio; + long startsec; + Llong bytes_read = 0; + Llong bytes = 0; + Llong savbytes = 0; + int count; + Llong tracksize; + int secsize; + int secspt; + int bytespt; + long amount; + int pad; + int retried; + long nextblock; + int bytes_to_read; + BOOL neednl = FALSE; + BOOL islast = FALSE; + char *bp = buf; + struct timeval tlast; + struct timeval tcur; + float secsps = 75.0; +long bsize; +long bfree; +#define BCAP +#ifdef BCAP +int per; +#ifdef XBCAP +int oper = -1; +#endif +#endif + + if (dp->cdr_dstat->ds_flags & DSF_DVD) + secsps = 676.27; + + usalp->silent++; + if ((*dp->cdr_buffer_cap)(usalp, &bsize, &bfree) < 0) + bsize = -1L; + if (bsize == 0) /* If we have no (known) buffer, we cannot */ + bsize = -1L; /* retrieve the buffer fill ratio */ + else + dp->cdr_dstat->ds_buflow = 0; + usalp->silent--; + + if (trackp->xfp != NULL) + f = xfileno(trackp->xfp); + + isaudio = is_audio(trackp); + tracksize = trackp->tracksize; + startsec = trackp->trackstart; + + secsize = trackp->secsize; + secspt = trackp->secspt; + bytespt = secsize * secspt; + + pad = !isaudio && is_pad(trackp); /* Pad only data tracks */ + + if (debug) { + printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n", + secsize, secspt, bytespt, isaudio, pad); + } + + if (lverbose) { + if (tracksize > 0) + printf("\rTrack %02d: 0 of %4lld MB written.", + track, tracksize >> 20); + else + printf("\rTrack %02d: 0 MB written.", track); + flush(); + neednl = TRUE; + } + + gettimeofday(&tlast, (struct timezone *)0); + do { + bytes_to_read = bytespt; + if (tracksize > 0) { + if ((tracksize - bytes_read) > bytespt) + bytes_to_read = bytespt; + else + bytes_to_read = tracksize - bytes_read; + } + /* XXX next wr addr ??? */ + count = get_buf(f, trackp, startsec, &bp, bytes_to_read); + if (count < 0) + comerr("read error on input file\n"); + if (count == 0) + break; + bytes_read += count; + if (tracksize >= 0 && bytes_read >= tracksize) { + count -= bytes_read - tracksize; + if (trackp->padsecs == 0 || (bytes_read/secsize) >= 300) + islast = TRUE; + } + + if (count < bytespt) { + if (debug) { + printf("\nNOTICE: reducing block size for last record.\n"); + neednl = FALSE; + } + + if ((amount = count % secsize) != 0) { + amount = secsize - amount; + fillbytes(&bp[count], amount, '\0'); + count += amount; + printf("\nWARNING: padding up to secsize.\n"); + neednl = FALSE; + } + if (is_packet(trackp) && trackp->pktsize > 0) { + if (count < bytespt) { + amount = bytespt - count; + count += amount; + printf("\nWARNING: padding remainder of packet.\n"); + neednl = FALSE; + } + } + bytespt = count; + secspt = count / secsize; + if (trackp->padsecs == 0 || (bytes_read/secsize) >= 300) + islast = TRUE; + } + + retried = 0; + retry: + /* XXX Fixed-packet writes can be very slow*/ + if (is_packet(trackp) && trackp->pktsize > 0) + usal_settimeout(usalp, 100); + /* XXX */ + if (is_packet(trackp) && trackp->pktsize == 0) { + if ((*dp->cdr_next_wr_address)(usalp, trackp, &nextblock) == 0) { + /* + * Some drives (e.g. Ricoh MPS6201S) do not + * increment the Next Writable Address value to + * point to the beginning of a new packet if + * their write buffer has underflowed. + */ + if (retried && nextblock == startsec) { + startsec += 7; + } else { + startsec = nextblock; + } + } + } + + amount = write_secs(usalp, dp, bp, startsec, bytespt, secspt, islast); + if (amount < 0) { + if (is_packet(trackp) && trackp->pktsize == 0 && !retried) { + printf("%swrite track data: error after %lld bytes, retry with new packet\n", + neednl?"\n":"", bytes); + retried = 1; + neednl = FALSE; + goto retry; + } + printf("%swrite track data: error after %lld bytes\n", + neednl?"\n":"", bytes); + return (-1); + } + bytes += amount; + startsec += amount / secsize; + + if (lverbose && (bytes >= (savbytes + 0x100000))) { + int fper; + int nsecs = (bytes - savbytes) / secsize; + float fspeed; + + gettimeofday(&tcur, (struct timezone *)0); + printf("\rTrack %02d: %4lld", track, bytes >> 20); + if (tracksize > 0) + printf(" of %4lld MB", tracksize >> 20); + else + printf(" MB"); + printf(" written"); + fper = fifo_percent(TRUE); + if (fper >= 0) + printf(" (fifo %3d%%)", fper); +#ifdef BCAP + if (bsize > 0) { /* buffer size known */ + usalp->silent++; + per = (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree); + usalp->silent--; + if (per >= 0) { + per = 100*(bsize - bfree) / bsize; + if (per < 5) + dp->cdr_dstat->ds_buflow++; + if (per < (int)dp->cdr_dstat->ds_minbuf && + (startsec*secsize) > bsize) { + dp->cdr_dstat->ds_minbuf = per; + } + printf(" [buf %3d%%]", per); +#ifdef BCAPDBG + printf(" %3ld %3ld", bsize >> 10, bfree >> 10); +#endif + } + } +#endif + + tlast.tv_sec = tcur.tv_sec - tlast.tv_sec; + tlast.tv_usec = tcur.tv_usec - tlast.tv_usec; + while (tlast.tv_usec < 0) { + tlast.tv_usec += 1000000; + tlast.tv_sec -= 1; + } + fspeed = (nsecs / secsps) / + (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001); + if (fspeed > 999.0) + fspeed = 999.0; + printf(" %5.1fx", fspeed); + printf("."); + savbytes = (bytes >> 20) << 20; + flush(); + neednl = TRUE; + tlast = tcur; + } + } while (tracksize < 0 || bytes_read < tracksize); + + if ((bytes / secsize) < 300) { + if ((trackp->padsecs + (bytes / secsize)) < 300) + trackp->padsecs = 300 - (bytes / secsize); + } + if (trackp->padsecs > 0) { + Llong padbytes; + + /* + * pad_track() is based on secsize. Compute the amount of bytes + * assumed by pad_track(). + */ + padbytes = (Llong)trackp->padsecs * secsize; + + if (neednl) { + printf("\n"); + neednl = FALSE; + } + if ((padbytes >> 20) > 0) { + neednl = TRUE; + } else if (lverbose) { + printf("Track %02d: writing %3lld KB of pad data.\n", + track, (Llong)(padbytes >> 10)); + neednl = FALSE; + } + pad_track(usalp, dp, trackp, startsec, padbytes, + TRUE, &savbytes); + bytes += savbytes; + startsec += savbytes / secsize; + } + printf("%sTrack %02d: Total bytes read/written: %lld/%lld (%lld sectors).\n", + neednl?"\n":"", track, bytes_read, bytes, bytes/secsize); + return (0); +} diff --git a/wodim/wm_session.c b/wodim/wm_session.c new file mode 100644 index 0000000..0505f9c --- /dev/null +++ b/wodim/wm_session.c @@ -0,0 +1,51 @@ +/* + * 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. + * + */ + +/* @(#)wm_session.c 1.4 02/07/07 Copyright 1995, 1997 J. Schilling */ +/* + * CDR write method abtraction layer + * session at once / disk at once writing intercace routines + * + * Copyright (c) 1995, 1997 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 <stdxlib.h> +#include <unixstd.h> +#include <standard.h> +#include <utypes.h> + +#include <usal/scsitransp.h> +#include "wodim.h" + +extern int debug; +extern int verbose; +extern int lverbose; + +extern char *buf; /* The transfer buffer */ + +int write_session_data(SCSI *usalp, cdr_t *dp, track_t *trackp); diff --git a/wodim/wm_track.c b/wodim/wm_track.c new file mode 100644 index 0000000..a3f9196 --- /dev/null +++ b/wodim/wm_track.c @@ -0,0 +1,50 @@ +/* + * 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. + * + */ + +/* @(#)wm_track.c 1.4 04/03/02 Copyright 1995, 1997, 2004 J. Schilling */ +/* + * CDR write method abtraction layer + * track at once writing intercace routines + * + * Copyright (c) 1995, 1997, 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 <stdxlib.h> +#include <unixstd.h> +#include <standard.h> +#include <utypes.h> + +#include "wodim.h" + +extern int debug; +extern int verbose; +extern int lverbose; + +extern char *buf; /* The transfer buffer */ + +int write_track_data(cdr_t *dp, int track, track_t *trackp); diff --git a/wodim/wodim.1 b/wodim/wodim.1 new file mode 100644 index 0000000..53e777c --- /dev/null +++ b/wodim/wodim.1 @@ -0,0 +1,2369 @@ +.\" @(#)wodim.1 06/12/18 Copyright 2006 Cdrkit maintainers +.\" derived from: +.\" @(#)cdrecord.1 1.106 06/02/09 Copyright 1996 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 +.if t .ds m \\(*m +.if n .ds m micro +.TH wodim 1 "Version 2.0" "" "" +.SH NAME +wodim \- write data to optical disk media +.SH SYNOPSIS +.B wodim +.RI [ options "] " track1 .\|.\|. trackn +.SH NOTE +There may be similarities and differences between this program and other disk recording application(s). See the +.B CREDITS +and +.B AUTHORS +sections below to learn about the origin of +.B wodim. + +.SH DESCRIPTION +.B wodim +is used to record data or audio Compact Discs on an Orange Book +CD-Recorder or to write DVD media on a DVD-Recorder. +.PP +The +.I device +is the device file or label offered by the operating system to access the +recorder with SCSI GENERIC (sg) interface. Note that some operating systems may +provide separate device nodes for block\-oriented and sg access. For example, on +older +.I Linux +systems, the sg access was available through +.IR /dev/sg... +files while the block oriented access was done through associated (but not identical) +.IR /dev/hd... +and +.IR /dev/sr... +(or +.IR /dev/scd... +) files. +.PP +In any case, the user running +.B wodim +needs read and write access to the particular device file on a Linux system. It +is recommended to be root or install the application as suid-root, because +certain versions of Linux (kernel) limit the set of SCSI commands allowed for +non-root users. Even if usage without root identity is possible in many cases, +some device drivers still may fail, show unexplainable problems and generally +the problems become harder to debug. The risk for buffer-underruns is also +increased. See the +.IR "PROCESS SCHEDULING PRIORITY" +section below for more details. +.PP +There is an alternative way of specifying the device, using the traditional SCSI descriptions in form of +.IR devicetype:bus/target/lun +specification. However, the success of this method is not guaranteed since it +requires an adaptation scheme for your architecture, and the numbers may vary +depending on the hardware-internal numbering or on the order of hot-plug device +detection. If your operating system does not provide a sufficient framework for +keeping this numbers persistent, don't rely on them. See +.B \-scanbus +and +.B \-\-devices +options below for details. +.PP +There are emulated SCSI compatible device systems, using the SCSI protocols +transported over various hardware/media types. The most known examples is ATAPI +("IDE burners") or USB storage ("external USB case"). If the pseudo-SCSI b/t/l +device address specification is used instead of the native one, you need to +prepend the "devicetype:" description to the emulated "bus/target/lun" device +address. +.PP +If a file /etc/wodim.conf exists, the parameter to the +.B dev= +option may also be a drive name label in that file (see FILES section). +.PP +As a special exception, the device specification can be +.IR -1 +or just omitted, which invokes automatic guessing of an appropriate device for +the selected operation. However, this guessing is not available everywhere and +is not reliable; it is only available for the user's convenience in simple +environments. +.PP +In +.I Track At Once +mode, each +.I track +corresponds to a single file that contains the prepared data for that track. +If the argument is +.RB ` \- ', +standard input is used for that track. +Only one track may be taken from +.IR stdin . +In the other write modes, the direct file to track relation may not be implemented. +In +.B \-clone +mode, a single file contains all data for the whole disk. +To allow DVD writing on platforms that do not implement large file support, +.B wodim +concatenates all file arguments to a single track when writing to DVD media. + +.SH "PROCESS SCHEDULING PRIORITY" +.PP +Wodim tries to get higher process priority using different methods. This is +important because the burn process is usually a realtime task, no long delays +should occur while transmitting fresh data to the recorder. This is especially +important on systems with insufficient RAM where swapping can create delays of +many seconds. +.PP +A possible workaround on underpowered systems is the use of the burnfree or +similar feature, allowing the recorder to resume. +.PP +Root permissions are usually required to get higher process scheduling priority. +.PP +On +.B SVr4 +compliant systems, +.B wodim +uses the real time class to get the highest scheduling priority that is +possible (higher than all kernel processes). +On systems with +.B POSIX real time scheduling +wodim uses real time scheduling too, +but may not be able to gain a priority that is higher than all kernel processes. +.PP +In order to be able to use the SCSI transport subsystem of the OS, run at highest +priority and lock itself into core +.B +wodim +either needs to be run as root, needs to be installed suid root or +must be called via +.B RBACs +pfexec mechanism. + +.SH "GENERAL OPTIONS +.PP +General options must be before any track file name or track option. +.TP +.B \-version +Print version information and exit. +.TP +.B \-v +Increment the level of general verbosity by one. +This is used e.g. to display the progress of the writing process. +.TP +.B \-V +Increment the verbose level in respect of SCSI command transport by one. +This helps to debug problems +during the writing process, that occur in the CD/DVD-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 and may be the reason for a buffer underrun. +.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 libusal +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 usal -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 \-force +Force to continue on some errors. Be careful when using this option. +.B wodim +implements several checks that prevent you from doing unwanted things +like damaging CD-RW media by improper drives. Many of the sanity checks are +disabled when the +.B \-force +option is used. +.sp +This option also implements some tricks that will allow +you to blank bad CD-RW disks. +.TP +.B \-immed +Tell wodim to set the +.B "SCSI IMMED" +flag in certain commands +(load/eject/blank/close_track/close_session). +This can be useful +on broken systems with ATAPI harddisk and CD/DVD writer on the same bus or +with SCSI systems that don't use disconnect/reconnect. +These systems will freeze while blanking or fixating a CD/DVD or while a DVD +writer is filling up a session to the minimum amount (approx. 800 MB). +Setting the +.B \-immed +flag will request the command to return immediately +while the operation proceeds in background, making +the bus usable for the other devices and avoiding the system freeze. +This is an experimental feature which may work or not, depending on the model +of the CD/DVD writer. +A correct solution would be to set up a correct cabling but there seem to be +notebooks around that have been set up the wrong way by the manufacturer. +As it is impossible to fix this problem in notebooks, the +.B \-immed +option has been added. +.sp +A second experimental feature of the +.B \-immed +flag is to tell wodim to try to wait short times while writing to the +media. This is expected to free the IDE bus if the CD/DVD writer and the +data source are connected to the same IDE cable. In this case, the CD/DVD +writer would otherwise usually block the IDE bus for nearly all the time +making it impossible to fetch data from the source drive. See also +.B minbuf= +and +.B \-v +option. +.sp +Use both features at your own risk. +If it turns out that it would make sense to have a separate option +for the wait feature, write to the author and convince him. +.TP +.BI minbuf= value +The # +.B minbuf= +option allows to define the minimum drive buffer fill ratio for the +experimental ATAPI wait mode that is intended to free the IDE bus +to allow hard disk and CD/DVD writer to be on the same IDE cable. +As the wait mode currently only works when the verbose option +.B \-v +has been specified, +.B wodim +implies the verbose option in case the +.B \-immed +or +.B minbuf= +option have been specified. +Valid values for +.B minbuf= +are between 25 and 95 for 25%.\|.\|.95% minimum drive buffer fill ratio. +.TP +.B \-dummy +The CD/DVD-Recorder will go through all steps of the recording process, +but the laser is turned off during this procedure. +It is recommended to run several tests before actually writing to a +Compact Disk or Digital Versatile Disk, +if the timing and load response of the system is not known. +.TP +.B \-clone +Tells +.B wodim +to handle images created by +.IR "readom \-clone" . +The +.B \-clone +may only be used in conjunction with with the +.B \-raw96r +or with the +.B \-raw16 +option. +Using +.B \-clone +together with +.B \-raw96r +is preferred as it allows to write all subchannel data. +The option +.B \-raw16 +should only be used with drives that do not support to write in +.B \-raw96r +mode. +.TP +.B \-dao +.TP +.B \-sao +Set +.B "SAO (Session At Once) +mode which is usually called +.BR "Disk At Once " mode. +This currently only works with MMC drives that support +.B "Session At Once +mode. +Note that wodim needs to know the size of each track in advance for this mode +(see the +.B "genisoimage \-print-size" +option and the +.I EXAMPLES +section for more information). +.TP +.B \-tao +Set +.B "TAO (Track At Once) writing mode. +This is the default write mode in previous +.B wodim +versions. +With most drives, this write mode is required for multi session recording. +.TP +.B \-raw +Set +.B "RAW writing mode. +Using this option defaults to +.BR \-raw96r . +Note that wodim needs to know the size of each track in advance for this mode +(see the +.B "genisoimage \-print-size" +option and the +.I EXAMPLES +section for more information). +.TP +.B \-raw96r +Select +Set +.B "RAW writing mode +with 2352 byte sectors plus 96 bytes of raw P-W subchannel data resulting +in a sector size of 2448 bytes. +This is the preferred raw writing mode as it gives best control over the +CD writing process. +If you find any problems with the layout of a disk or with sub channel +content (e.g. wrong times on the display when playing the CD) and your drive +supports to write in +.B \-raw96r +or +.B \-raw16 +mode, you should give it a try. There are several CD writers with bad firmware +that result in broken disks when writing in TAO or SAO mode. +Writing data disks in raw mode needs significantly more CPU time than other +write modes. If your CPU is too slow, this may result in buffer underruns. +Note that wodim needs to know the size of each track in advance for this mode +(see the +.B "genisoimage \-print-size" +option and the +.I EXAMPLES +section for more information). +.TP +.B \-raw96p +Select +Set +.B "RAW writing mode +with 2352 byte sectors plus 96 bytes of packed P-W subchannel data resulting +in a sector size of 2448 bytes. +This is the less preferred raw writing mode as only a few recorders support +it and some of these recorders have bugs in the firmware implementation. +Don't use this mode if your recorder supports +.B \-raw96r +or +.BR \-raw16 . +Writing data disks in raw mode needs significantly more CPU time than other +write modes. If your CPU is too slow, this may result in buffer underruns. +Note that wodim needs to know the size of each track in advance for this mode +(see the +.B "genisoimage \-print-size" +option and the +.I EXAMPLES +section for more information). +.TP +.B \-raw16 +Select +Set +.B "RAW writing mode +with 2352 byte sectors plus 16 bytes of P-Q subchannel data resulting +in a sector size of 2368 bytes. +If a recorder does not support +.BR \-raw96r , +this is the preferred raw writing mode. +It does not allow to write +.I CD-Text +or +.I CD+Graphics +but it is the only raw writing mode in cheap CD writers. +As these cheap writers in most cases do not support +.B \-dao +mode. +Don't use this mode if your recorder supports +.BR \-raw96r . +Writing data disks in raw mode needs significantly more CPU time than other +write modes. If your CPU is too slow, this may result in buffer underruns. +Note that wodim needs to know the size of each track in advance for this mode +(see the +.B "genisoimage \-print-size" +option and the +.I EXAMPLES +section for more information). +.TP +.B \-multi +Allow multi session CDs to be made. This flag needs to be present +on all sessions of a multi session disk, +except you want to create a session that will be +the last session on the media. +The fixation will be done in a way that allows the CD/DVD-Recorder to +append additional sessions later. This is done by generation a TOC +with a link to the next program area. The so generated media is not +100% compatible to manufactured CDs (except for CDplus). +Use only for recording of multi session CDs. +If this option is present, the default track type is +.BR "CD-ROM XA mode 2 form 1" +and the sector size is 2048 bytes. +The XA sector subheaders will be created by the drive. +The +.I Sony +drives have no hardware support for +.BR "CD-ROM XA mode 2 form 1" . +You have to specify the +.B \-data +option in order to create multi session disks on these drives. +As long as wodim does not have a coder for converting data sectors +to audio sectors, you need to force +.B CD-ROM +sectors by including the +.B \-data +option if you like to record a multisession disk in SAO mode. +Not all drives allow multisession CDs in SAO mode. +.TP +.B \-msinfo +Retrieve multi session info in a form suitable for +.B genisoimage +and print it to standard output. See +.B msifile= +option for another version. +.sp +This option makes only sense with a CD that contains at least +one closed session and is appendable (not finally closed yet). +Some drives create error messages if you try to get the multi +session info for a disk that is not suitable for this operation. +.TP +.BR msifile= filename +Like +.B \-msinfo +option but also stores the multi session info in a file. +.TP +.B \-toc +Retrieve and print out the table of content or PMA of a CD. +With this option, +.B wodim +will work with CD-R drives and with CD-ROM drives. +.TP +.B \-atip +Retrieve and print out the ATIP (absolute Time in Pre-groove) info of a CD/DVD +recordable or CD/DVD re-writable media. +With this option, +.B wodim +will try to retrieve the ATIP info. If the actual drive does not support +to read the ATIP info, it may be that only a reduced set of information +records or even nothing is displayed. Only a limited number of MMC compliant +drives support to read the ATIP info. +.sp +If +.B wodim +is able to retrieve the lead-in start time for the first session, it will try to +decode and print the manufacturer info from the media. +DVD media does not have ATIP information but there is equivalent prerecorded +information that is read out and printed. +.TP +.B \-fix +The disk will only be fixated (i.e. a TOC for a CD-Reader will be written). +This may be used, if for some reason the disk has been written but not +fixated. This option currently does not work with old TEAC drives (CD-R50S and +CD-R55S). +.TP +.B \-nofix +Do not fixate the disk after writing the tracks. This may be used +to create an audio disk in steps. An un-fixated disk can usually not be used +on a non CD-writer type drive but there are audio CD players that will +be able to play such a disk. +.TP +.B \-waiti +Wait for input to become available on standard input before trying to open +the SCSI driver. This allows +.B wodim +to read its input from a pipe even +when writing additional sessions to a multi session disk. +When writing another session to a multi session disk, +.B genisoimage +needs to read the old session from the device before writing output. +This cannot be done if +.B wodim +opens the SCSI driver at the same time. +.TP +.B \-load +Load the media and exit. This only works with a tray loading mechanism +but seems to be useful when using the Kodak disk transporter. +.TP +.B \-lock +Load the media, lock the door and exit. This only works with a tray loading mechanism +but seems to be useful when using the Kodak disk transporter. +.TP +.B \-eject +Eject disk after doing the work. +Some devices (e.g. Philips) need to eject the medium before creating a new +disk. Doing a \-dummy test and immediately creating a real disk would not +work on these devices. +.TP +.BR speed= # +Set the speed factor of the writing process to #. +# is an integer, representing a multiple of the audio speed. +This is about 150\ KB/s for CD-ROM, about 172\ KB/s for CD-Audio and about 1385\ kB/s +for DVD media. +If no +.I speed +option is present, +.B wodim +will try to get a drive specific speed value from the file +.B /etc/wodim.conf +and if it cannot find one, it will try to get the speed value from the +.B CDR_SPEED +environment and later from the +.B CDR_SPEED= +entry in +.BR /etc/wodim.conf . +If no speed value could be found, wodim uses a drive specific default speed. +The default for all new (MMC compliant) drives is to use the maximum supported by the drive. +If you use +.I "speed=0" +with a MMC compliant drive, +.B wodim +will switch to the lowest possible speed for drive and medium. +If you are using an old (non MMC) drive that has problems with +.I "speed=2 +or +.IR "speed=4" , +you should try +.IR "speed=0" . +.TP +.BI blank= type +Blank a CD-RW and exit or blank a CD-RW before writing. The blanking type may be one of: +.RS +.TP 12 +help +Display a list of possible blanking types. +.TP +all +Blank the entire disk. This may take a long time. +.TP +fast +Minimally blank the disk. This results in erasing the PMA, the TOC and the pregap. +.TP +track +Blank a track. +.TP +unreserve +Unreserve a reserved track. +.TP +trtail +Blank the tail of a track. +.TP +unclose +Unclose last session. +.TP +session +Blank the last session. +.RE +Not all drives support all blanking types. It may be necessary to use +.B "blank=all +if a drive reports a specified command as being invalid. +If used together with the +.B \-force +flag, this option may be used to blank CD-RW disks that otherwise cannot be +blanked. Note that you may need to specify +.BI blank= all +because some drives will not continue with certain types of bad CD-RW +disks. Note also that +.B wodim +does its best if the +.B \-force +flag is used but it finally depends on the drive's firmware +whether the blanking operation will succeed or not. +.TP +.B \-format +Format a CD-RW/DVD-RW/DVD+RW disc. +Formatting is currently only implemented for DVD+RW media. +A 'maiden' DVD+RW media needs to +be formatted before you may write to it. +However, as +.B wodim +autodetects the need for formatting in this case and auto formats the medium +before it starts writing, the +.B \-format +option is only needed if you like to forcibly reformat a DVD+RW medium. +.TP +.BR fs= # +Set the FIFO (ring buffer) size to #. +You may use the same syntax as in +.BR dd (1), +.BR sdd (1) +or +.BR star (1). +The number representing the size is taken in bytes unless otherwise specified. +If a number is followed directly by the letter `b', `k', `m', `s' or `f', +the size is multiplied by 512, 1024, 1024*1024, 2048 or 2352. +If the size consists of numbers separated by `x' or `*', multiplication of the +two numbers is performed. +Thus +.I "fs=10x63k +will specify a FIFO size of 630\ kBytes. +.sp +The size specified by the +.I fs= +argument includes the shared memory that is needed for administration. This +is at least one page of memory. +If no +.IR fs = +option is present, +.B wodim +will try to get the FIFO size value from the +.B CDR_FIFOSIZE +environment. +The default FIFO size is currently 4 MB. +.sp +The FIFO is used to increase buffering for the real time writing process. +It allows to run a pipe from +.B genisoimage +directly into +.BR wodim . +If the FIFO is active and a pipe from +.B genisoimage +into +.B wodim +is used to create a CD, +.B wodim +will abort prior to do any modifications on the disk if +.B genisoimage +dies before it starts writing. +The recommended FIFO size is between 4 and 128\ MBytes. +As a rule of thumb, the FIFO size should be at least equal to the size +of the internal buffer of the CD/DVD-Recorder and no more than half of +the physical amount of RAM available in the machine. +If the FIFO size is big enough, the FIFO statistics will print a FIFO +empty count of zero and the FIFO min fill is not below 20%. +It is not wise to use too much space for the FIFO. If you need more +than 8 MB to write a CD at a speed less than 20x from an image on a +local file system on an idle machine, your machine is either underpowered, +has hardware problems or is mis-configured. +If you like to write DVDs or CDs at higher speed, it makes sense +to use at least 16\ MB for the FIFO. +.sp +On old and small machines, you need to be more careful with the FIFO size. +If your machine has less than 256\ MB of physical RAM, you should not +set up a FIFO size that is more than 32\ MB. +The sun4c architecture (e.g. a Sparcstation-2) has only MMU page table entries +for 16\ MBytes per process. Using more than 14\ MBytes for the FIFO +may cause the operating system in this case to spend much time to constantly +reload the MMU tables. Newer machines from Sun do not have this MMU +hardware problem. I have no information on PC-hardware reflecting +this problem. +.sp +Old Linux systems for non x86 platforms have broken definitions for +the shared memory size. You need to fix them and rebuild the kernel +or manually tell +.B wodim +to use a smaller FIFO. +.sp +If you have buffer underruns or similar problems (like a constantly empty +drive buffer) and observe a zero +.IR "fifo empty count" , +you have hardware problems that prevents the data from flowing fast enough +from the kernel memory to the drive. The FIFO size in this case is sufficient, +but you should check for a working DMA setup. +.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 wodim +defaults to a transfer size of 63\ kB. If libusal 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 +.BI dev= target +Sets the SCSI target for the CD/DVD-Recorder, see notes above. +A typical device specification is +.BI dev= 6,0 +\&. +A filename or virtual device name can be passed instead of the symbolic SCSI +numbers. The correct device/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 and Windows 2000/XP, drives are accessible with their device (or +drive) names or with the symbolic SCSI numbers (not recommended, mapping is not +stable and could be completely removed in the future). +.sp +If no +.I dev +option is present, +.B wodim +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 gracetime= # +Set the grace time before starting to write to +.IR # " seconds. +Values below 2 seconds are not recommended to give the kernel or volume +management a chance to learn the new state. +.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 driver= name +Allows the user to manually select a driver for the device. +The reason for the existence of the +.BI driver= name +option is to allow users to use +.B wodim +with drives that are similar to supported drives but not known +directly by +.BR wodim . +All drives made after 1997 should be MMC standard compliant and +thus supported by one of the MMC drivers. +It is most unlikely that +.B wodim +is unable to find the right driver automatically. +Use this option with extreme care. If a wrong driver is used for a +device, the possibility of creating corrupted disks is high. +The minimum problem related to a wrong driver is that the +.B speed= +or +.B \-dummy +will not work. +.br +.RS +.ne 8 +.PP +The following driver names are supported: +.TP +.B help +To get a list of possible drivers together with a short description. +.TP +.B mmc_cd +The generic SCSI-3/mmc CD-ROM driver is auto-selected whenever +.B wodim +finds a MMC compliant drive that does not identify itself to support writing at +all, or that only identifies to support media or write modes not implemented in +.BR wodim . +.TP +.B mmc_cd_dvd +The generic SCSI-3/mmc CD/DVD driver is auto-selected whenever +.B wodim +finds a MMC-2 or MMC-3 compliant drive that seems to support more than +one medium type and the tray is open or no medium could be found to select the +right driver. +This driver tries to close the tray, checks the medium found in the tray and then +branches to the driver that matches the current medium. +.TP +.B mmc_cdr +The generic SCSI-3/mmc CD-R/CD-RW driver is auto-selected whenever +.B wodim +find a MMC compliant drive that only supports to write CDs or a multi system +drive that contains a CD as the current medium. +.TP +.B mmc_cdr_sony +The generic SCSI-3/mmc CD-R/CD-RW driver is auto-selected whenever +.B wodim +would otherwise select the +.B mmc_cdr +driver but the device seems to be made by Sony. +The +.B mmc_cdr_sony +is definitely needed for the Sony CDU 928 as this drive does not completely +implement the MMC standard and some of the MMC SCSI commands have to be +replaced by Sony proprietary commands. It seems that all Sony drives (even +newer ones) still implement the Sony proprietary SCSI commands so it has +not yet become a problem to use this driver for all Sony drives. If you find +a newer Sony drive that does not work with this driver, please report. +.TP +.B mmc_dvd +The generic SCSI-3/mmc-2 DVD-R/DVD-RW driver is auto-selected whenever +.B wodim +finds a MMC-2 or MMC-3 compliant drive that supports to write DVDs and +an appropriate medium is loaded. +There is no Track At Once mode for DVD writers. +.TP +.B mmc_dvdplus +The generic SCSI-3/mmc-3 DVD+R/DVD+RW driver is auto-selected whenever +one of the DVD+ media types that are incompatible to each other is found. +It checks media and then +branches to the driver that matches the current medium. +.TP +.B mmc_dvdplusr +The generic SCSI-3/mmc-3 DVD+R driver is auto-selected whenever +a DVD+R medium is found in an appropriate writer. +Note that for unknown reason, the DVD-Plus alliance does not +like that there is a simulation mode for DVD+R media. +The author of +.B wodim +tries to convince manufacturers to implement a simulation mode for DVD+R +and implement support. +DVD+R only supports one write mode that is somewhere between Track At Once +and Packet writing; this mode is selected in +.B wodim +via a the +.BR \-dao / \-sao +option. +.TP +.B mmc_dvdplusrw +The generic SCSI-3/mmc-3 DVD+RW driver is auto-selected whenever +a DVD+RW medium is found in an appropriate writer. +As DVD+RW media needs to be formatted before its first use, wodim +auto-detects this media state and performs a format before it starts +to write. +Note that for unknown reason, the DVD-Plus alliance does not +like that there is a simulation mode nor a way to erase DVD+RW media. +DVD+RW only supports one write mode that is close to +Packet writing; this mode is selected in +.B wodim +via a the +.BR \-dao / \-sao +option. +.TP +.B cw_7501 +The driver for Matsushita/Panasonic CW-7501 is auto-selected when +.B wodim +finds this old pre MMC drive. +.B wodim +supports all write modes for this drive type. +.TP +.B kodak_pcd_600 +The driver for Kodak PCD-600 is auto-selected when +.B wodim +finds this old pre MMC drive which has been the first high speed (6x) +CD writer for a long time. This drive behaves similar to the +Philips CDD-521 drive. +.TP +.B philips_cdd521 +The driver for Philips CDD-521 is auto-selected when +.B wodim +finds a Philips CDD-521 drive (which is the first CD writer ever made) +or one of the other drives that are known to behave similar to this +drive. +All Philips CDD-521 or similar drives (see other drivers in this list) +do not support Session At Once recording. +.TP +.B philips_cdd521_old +The driver for Philips old CDD-521 is auto-selected when +.B wodim +finds a Philips CDD-521 with very old firmware which has some known limitations. +.TP +.B philips_cdd522 +The driver for Philips CDD-522 is auto-selected when +.B wodim +finds a Philips CDD-522 which is the successor of the 521 or one of its variants +with Kodak label. +.B wodim +does not support Session At Once recording with these drives. +.TP +.B philips_dumb +The driver for Philips CDD-521 with pessimistic assumptions is never auto-selected. +It may be used by hand with drives that behave similar to the Philips CDD-521. +.TP +.B pioneer_dws114x +The driver for Pioneer DW-S114X is auto-selected when +.B wodim +finds one of the old non MMC CD writers from Pioneer. +.TP +.B plasmon_rf4100 +The driver for Plasmon RF 4100 is auto-selected when +.B wodim +finds this specific variant of the Philips CDD-521. +.TP +.B ricoh_ro1060c +The driver for Ricoh RO-1060C is auto-selected when +.B wodim +finds this drive. There is no real support for this drive yet. +.TP +.B ricoh_ro1420c +The driver for Ricoh RO-1420C is auto-selected when +.B wodim +finds a drive with this specific variant of the Philips CDD-521 command set. +.TP +.B scsi2_cd +The generic SCSI-2 CD-ROM driver is auto-selected whenever +.B wodim +finds a pre MMC drive that does not support writing or a pre MMC writer that is +not supported by +.BR wodim . +.TP +.B sony_cdu924 +The driver for Sony CDU-924 / CDU-948 is auto-selected whenever +.B wodim +finds one of the old pre MMC CD writers from Sony. +.TP +.B teac_cdr50 +The driver for Teac CD-R50S, Teac CD-R55S, JVC XR-W2010, Pinnacle RCD-5020 +is auto-selected whenever one of the drives is found that is known to the +non MMC command set used by TEAC and JVC. +Note that many drives from JVC will not work because they do not correctly implement +the documented command set and JVC has been unwilling to fix or document the +bugs. +There is no support for the Session At Once write mode yet. +.TP +.B tyuden_ew50 +The driver for Taiyo Yuden EW-50 is auto-selected when +.B wodim +finds a drive with this specific variant of the Philips CDD-521 command set. +.TP +.B yamaha_cdr100 +The driver for Yamaha CDR-100 / CDR-102 is auto-selected when +.B wodim +finds one of the old pre MMC CD writers from Yamaha. +There is no support for the Session At Once write mode yet. +.TP +.B cdr_simul +The simulation CD-R driver allows to run timing and speed tests +with parameters that match the behavior of CD writers. +.TP +.B dvd_simul +The simulation DVD-R driver allows to run timing and speed tests +with parameters that match the behavior of DVD writers. +.PP + +.sp +There are two special driver entries in the list: +.B cdr_simul +and +.BR dvd_simul . +These driver entries are designed to make timing tests at any speed +or timing tests for drives that do not support the +.B \-dummy +option. +The simulation drivers implement a drive with a buffer size of 1\ MB +that can be changed via the +.B CDR_SIMUL_BUFSIZE +environment variable. +The simulation driver correctly simulates even a buffer underrun condition. +If the +.B \-dummy +option is present, the simulation is not aborted in case of a buffer underrun. +.RE +.TP +.BI driveropts= "option list" +Set driver specific options. The options are specified a comma separated list. +To get a list of valid options use +.BI driveropts= help +together with the +.I \-checkdrive +option. +If you like to set driver options without running a typical +.B wodim +task, you need to use the +.B \-setdropts +option in addition, otherwise the command line parser in +.B wodim +will complain. +Currently implemented driver options are: +.RS +.TP +.B burnfree +Turn the support for Buffer Underrun Free writing on. +This only works for drives that support Buffer Underrun Free technology, which +is available on most drives manufactured in this millennium. +This may be called: +.BR "Sanyo BURN-Proof" , +.BR "Ricoh Just-Link" , +.B "Yamaha Lossless-Link" +or similar. +.sp +This option is deprecated and is mentioned here for documentation purposes +only. The BURN-Free feature is enabled by default if the drive supports it. +However, use of BURN-Free may cause decreased burning quality. Therefore it can +be useful to disable it for certain purposes, eg. when creating a master copy +for mass CD production. +.TP +.B noburnfree +Turn the support for Buffer Underrun Free writing off. +.TP +.BI varirec= value +Turn on the +.B "Plextor VariRec" +writing mode. The mandatory parameter +.I value +is the laser power offset and currently may be selected from +-2, -1, 0, 1, 2. +In addition, you need to set the write speed to 4 in order to allow +.B "VariRec" +to work. +.TP +.BI gigarec= value +Manage the +.B "Plextor GigaRec" +writing mode. The mandatory parameter +.I value +is the disk capacity ratio compared to normal recording and currently may be selected from +0.6, 0.7, 0.8, 1.0, 1.2, 1.3, 1.4. +If values < 1.0 are used, then the effect is similar to the +.B "Yamaha Audio Master Q. R." +feature. If values > 1.0 are used, then the disk capacity is +increased. +.sp +Not all drives support all +.B GigaRec +values. +When a drive uses the +.B GigaRec +feature, the write speed is limited to 8x. +.TP +.B audiomaster +Turn on the +.B "Yamaha Audio Master Q. R." +feature which usually should result in high quality CDs that +have less reading problems in Hi-Fi players. +As this is implemented as a variant of the +Session at Once write mode, it will only work if you select +SAO write mode and there is no need to turn it off. +The +.B "Audio Master" +mode will work with a limited speed but +may also be used with data CDs. In +.B "Audio Master" +mode, the pits on the CD will be written larger then usual so the capacity +of the medium is reduced when turning this feature on. +A 74 minute CD will only have a capacity of 63 minutes if +.B "Audio Master" +is active and the capacity of a 80 minute CD will be reduced to 68 minutes. +.TP +.B forcespeed +Normally, modern drives know the highest possible speed for different +media and may reduce the speed in order to grant best write quality. +This technology may be called: +.BR "Plextor PowerRec" , +.BR "Ricoh Just-Speed" , +.B "Yamaha Optimum Write Speed Control" +or similar. +Some drives (e.g. Plextor, Ricoh and Yamaha) allow to force the drive to +use the selected speed even if the medium is so bad that the +write quality would be poor. This option tells such a drive to +force to use the selected speed regardless of the medium quality. +.sp +Use this option with extreme care and note that the drive should know better +which medium will work at full speed. +The default is to turn +.B forcespeed +off, regardless of the defaults of the drive. +.TP +.B noforcespeed +Turn off the +.B "force speed +feature. +.TP +.B speedread +Some ultra high speed drives such as 48x and faster drives from Plextor +limit the read speed for unknown media to e.g. 40x in order to avoid +damaged disks and drives. +Using this option tells the drive to read any media as fast as possible. +Be very careful as this may cause the media to break in the drive +while reading, resulting in a damaged media and drive! +.TP +.B nospeedread +Turn off unlimited read speed. +.TP +.B singlesession +Turn the drive into a single session only drive. +This allows to read defective or non-compliant (illegal) media with extremely +non-standard additional (broken/illegal) TOC entries in the TOC from the second +or higher session. Some of these disks become +usable if only the information from the first session is used. +You need to enable Single Session mode before you insert the defective disk! +.TP +.B nosinglesession +Turn off single session mode. The drive will again behave as usual. +.TP +.B hidecdr +Hide the fact that a medium might be a recordable medium. +This allows to make CD-Rs look like CD-ROMs and applications believe +that the media in the drive is not a CD-R. +.TP +.B nohidecdr +Turn off hiding CD-R media. +.TP +.B tattooinfo +Use this option together with +.B \-checkdrive +to retrieve the image size information for the +.B "Yamaha DiskT@2 +feature. The images always have a line length of 3744 pixel. +Line number 0 (radius 0) is mapped to the center of the disk. +If you know the inner and outer radius you will be able to create a +pre distorted image that later may appear undistorted on the disk. +.TP +.BI tattoofile= name +Use this option together with +.B \-checkdrive +to write an image prepared for the +.B "Yamaha DiskT@2 +feature to the medium. +The file must be a file with raw image B&W data (one byte per pixel) +in a size as retrieved by a previous call to +.BI tattoofile= name +\&. +If the size of the image equals the maximum possible size +(3744 x 320 pixel), +.B wodim +will use the first part of the file. This first part then will +be written to the leftover space on the CD. +.sp +Note that the image must be mirrored to be readable from the pick up +side of the CD. +.RE +.TP +.B \-setdropts +Set the driveropts specified by +.BI driveropts= "option list" , +the +.B speed +of the drive and the +.B dummy +flag and exit. +This allows wodim to set drive specific parameters that are not directly +used by +.B wodim +like e.g. +.BR "single session mode" ", " "hide cdr" +and similar. +It is needed in case that +.BI driveropts= "option list" +should be called without planning to run a typical +.B wodim +task. +.TP +.B \-checkdrive +Checks if a driver for the current drive is present and exit. +If the drive is a known drive, +.B wodim +uses exit code 0. +.TP +.B \-prcap +Print the drive capabilities for SCSI-3/mmc compliant drives +as obtained from mode page 0x2A. Values marked with +.I kB +use 1000 bytes as kilo-byte, values marked with +.I KB +use 1024 bytes as Kilo-byte. +.TP +.B \-inq +Do an inquiry for the drive, print the inquiry info and exit. +.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 +CD/DVD-Recorder on a system. If some device types are invisible, try using +.B dev=ATA: +or similar option to give a hint about the device type you are looking for. +The numbers printed out as labels are computed by: +.B "bus * 100 + target. +On platforms and device systems without persistent SCSI number management the +results are not reliable. Use the .B \-\-devices option instead. +.TP +.B \-\-devices +Look for useable devices using the system specific functions, eg. probing with +usual device nodes in /dev/*, and display the detections using symbolic device +names in OS specific syntax. +.TP +.B \-reset +Try to reset the SCSI bus where the CD recorder is located. This works not +on all operating systems. +.TP +.B \-abort +Try to send an +.B abort +sequence to the drive. +If you use +.B wodim +only, this should never be needed; but other software may leave a drive +in an unusable condition. +Calling +.B "wodim \-reset +may be needed if a previous write has been interrupted and the software did +not tell the drive that it will not continue to write. +.TP +.B \-overburn +Allow +.B wodim +to write more than the official size of a medium. This feature is usually +called +.I overburning +and depends on the fact that most blank media may hold more space than the +official size. As the official size of the lead-out area on the disk is +90 seconds (6750 sectors) and a disk usually works if there are at least +150 sectors of lead out, all media may be overburned by at least 88 seconds +(6600 sectors). +Most CD recorders only do overburning in +.B SAO +or +.B RAW +mode. Known exceptions are TEAC CD-R50S, TEAC CD-R55S and the Panasonic +CW-7502. +Some drives do not allow to overburn as much as you might like and limit +the size of a CD to e.g. 76 minutes. This problem may be circumvented by +writing the CD in RAW mode because this way the drive has no chance to find +the size before starting to burn. +There is no guarantee that your drive supports overburning at all. +Make a test to check if your drive implements the feature. +.TP +.B \-ignsize +Ignore the known size of the medium. This option should be used with extreme +care, it exists only for debugging purposes don't use it for other reasons. +It is not needed to write disks with more than the nominal capacity. +This option implies +.BR \-overburn . +.TP +.B \-useinfo +Use +.B "*.inf +files to overwrite audio options. +If this option is used, the pregap size information is read from +the +.B "*.inf +file that is associated with the file that contains the audio +data for a track. +.sp +If used together with the +.B \-audio +option, +.B wodim +may be used to write audio CDs from a pipe from +.B icedax +if you call +.B wodim +with the +.B *.inf +files as track parameter list instead of using audio files. +The audio data is read from +.B stdin +in this case. +See +.B EXAMPLES +section below. +.B wodim +first verifies that +.B stdin +is not connected to a terminal and runs some heuristic consistency checks +on the +.B *.inf +files and then sets the track lengths from the information in +the +.B *.inf +files. +.sp +If you like to write from +.BR stdin , +make sure that wodim is called with a large enough FIFO size, reduce the write +speed to a value below the read speed of the source drive and switch the burn-free +option for the recording drive on. +.TP +.BR defpregap= # +Set the default pre-gap size for all tracks except track number 1. +This option currently only makes sense with the TEAC drive when +creating track-at-once disks without the 2 second silence before each track. +.br +This option may go away in future. +.TP +.B \-packet +Set +.B "Packet writing mode. +This is an experimental interface. +.TP +.BR pktsize= # +Set the packet size to #, forces fixed packet mode. +This is an experimental interface. +.TP +.B \-noclose +Do not close the current track, useful only when in packet writing mode. +This is an experimental interface. +.TP +.BI mcn= med_cat_nr +Set the +.B "Media Catalog Number +of the CD to +.IR med_cat_nr . +.TP +.B \-text +Write CD-Text information +based on information taken from a file that contains ascii information +for the text strings. +.B wodim +supports CD-Text information based on the content of the +.B *.inf +files created by +.B icedax +and CD-Text information based on the content from a +.B "CUE sheet +file. +If a +.B "CUE sheet +file contains both (binary CDTEXTFILE and text based SONGWRITER) +entries, then the information based on the CDTEXTFILE entry will win. +.sp +You need to use the +.B \-useinfo +option in addition in order to tell +.B wodim +to read the +.B "*.inf +files or +.BI cuefile= filename +in order to tell +.B wodim +to read a +.B CUE sheet +file in addition. +If you like to write your own CD-Text information, +edit the +.B *.inf +files or the +.B "CUE sheet +file with a text editor and change the fields +that are relevant for CD-Text. +.TP +.BI textfile= filename +Write CD-Text based on information found in the binary file +.IR filename . +This file must contain information in a data format defined in the +SCSI-3 MMC-2 standard and in the Red Book. The four byte size header that is +defined in the SCSI standard is optional and allows to make the recognition of +correct data less ambiguous. +This is the best option to be used to copy CD-Text data from existing CDs +that already carry CD-Text information. To get data in a format suitable +for this option use +.B wodim \-vv \-toc +to extract the information from disk. +If both, +.BI textfile= filename +and CD-Text information from +.B *.inf +or +.B *.cue +files are present, +.BI textfile= filename +will overwrite the other information. +.TP +.BI cuefile= filename +Take all recording related information from a CDRWIN compliant +.B "CUE sheet +file. +No track files are allowed when this option is present and the option +.B \-dao +is currently needed in addition. + +.SH "TRACK OPTIONS +.PP +Track options may be mixed with track file names. +.TP +.BI isrc= ISRC_number +Set the +.B "International Standard Recording Number +for the next track to +.IR ISRC_number . +.TP +.BI index= list +Sets an index list for the next track. +In index list is a comma separated list of numbers that are counting +from index 1. The first entry in this list must contain a 0, the following +numbers must be an ascending list of numbers (counting in 1/75 seconds) that +represent the start of the indices. An index list in the form: +0,7500,15000 sets index 1 to the start of the track, index 2 100 seconds from +the start of the track and index 3 200 seconds from the start of the track. +.TP +.B \-audio +If this flag is present, all subsequent tracks are written in +.B "CD-DA +(similar to Red Book) audio format. +The file with data for this tracks should +contain stereo, 16-bit digital audio with 44100 samples/s. +The byte order should be the following: MSB left, LSB left, +MSB right, LSB right, MSB left and so on. The track should be a multiple of +2352 bytes. It is not possible to put the master image of an audio track +on a raw disk because +data will be read in multiple of 2352 bytes during the recording process. +.sp +If a filename ends in +.I .au +or +.I .wav +the file is considered to be a structured audio data file. +.B wodim +assumes that the file in this case is a Sun audio file or a +Microsoft .WAV file +and extracts the audio data from the files by skipping over the +non-audio header information. +In all other cases, wodim will only work correctly if the +audio data stream does not have any header. +Because many structured audio files do not have an integral +number of blocks (1/75th second) in length, +it is often necessary to specify the +.B \-pad +option as well. +.B wodim +recognizes that audio data in a .WAV file is stored in Intel +(little-endian) byte order, and will automatically byte-swap the data +if the CD recorder requires big-endian data. +.B wodim +will reject any audio file that does not match the Red Book requirements +of 16-bit stereo samples in PCM coding at 44100 samples/second. +.sp +Using other structured audio data formats as input to +.B wodim +will usually work if the structure of the data is the +structure described above (raw pcm data in big-endian byte order). +However, if the data format includes a header, +you will hear a click at the start of a track. +.TP +.I " " +If neither +.I \-data +nor +.I \-audio +have been specified, +.B wodim +defaults to +.I \-audio +for all filenames that end in +.I .au +or +.I .wav +and to +.I \-data +for all other files. +.TP +.B \-swab +If this flag is present, audio data is assumed to be in byte-swapped +(little-endian) order. Some types of CD-Writers e.g. Yamaha, Sony and the +new SCSI-3/mmc drives require audio data to be presented in +little-endian order, +.\" (which is the order in which it's actually recorded on the CD) ???? +while other writers require audio data to be +presented in the big-endian (network) byte order normally used by the +SCSI protocol. +.B wodim +knows if a CD-Recorder needs audio data in big- or little-endian order, +and corrects the byte order of the data stream to match the needs +of the recorder. +You only need the +.I \-swab +flag if your data stream is in Intel (little-endian) byte order. +.sp +Note that the verbose output of +.B wodim +will show you if swapping is necessary to make the byte order of +the input data fit the required byte order of the recorder. +.B wodim +will not show you if the +.I \-swab +flag was actually present for a track. +.TP +.B \-data +If this flag is present, all subsequent tracks are written in +.B "CD-ROM mode 1 +(Yellow Book) format. The data size is a multiple of 2048 bytes. +The file with track data should contain an +.BR ISO-9660 " or " "Rock Ridge +filesystem image (see +.B genisoimage +for more details). If the track data is an +.B ufs +filesystem image, fragment size should be set to 2\ KB or more to allow +CD-drives with 2\ KB sector size to be used for reading. +.TP +.I " " +.I \-data +is the default, if no other flag is present and the file does not +appear to be of one of the well known audio file types. +.TP +.I " " +If neither +.I \-data +nor +.I \-audio +have been specified, +.B wodim +defaults to +.I \-audio +for all filenames that end in +.I .au +or +.I .wav +and to +.I \-data +for all other files. +.TP +.B \-mode2 +If this flag is present, all subsequent tracks are written in +.B "CD-ROM mode 2 +format. The data size is a multiple of 2336 bytes. +.TP +.B \-xa +If this flag is present, all subsequent tracks are written in +.B "CD-ROM XA mode 2 form 1 +format. The data size is a multiple of 2048 bytes. +The XA sector sub headers will be created by the drive. +With this option, the write mode is the same as with the +.B \-multi +option. +.TP +.B \-xa1 +If this flag is present, all subsequent tracks are written in +.B "CD-ROM XA mode 2 form 1 +format. The data size is a multiple of 2056 bytes. +The XA sector sub headers are part of the user data and have to be +supplied by the application that prepares the data to be written. +.TP +.B \-xa2 +If this flag is present, all subsequent tracks are written in +.B "CD-ROM XA mode 2 form 2 +format. The data is a multiple of 2324 bytes. +The XA sector sub headers will be created by the drive. +.TP +.B \-xamix +If this flag is present, all subsequent tracks are written in a way +that allows a mix of +.B "CD-ROM XA mode 2 form 1/2 +format. The data size is a multiple of 2332 bytes. +The XA sector sub headers are part of the user data and have to be +supplied by the application that prepares the data to be written. +The CRC and the P/Q parity ECC/EDC information (depending on the sector +type) have to be supplied by the application that prepares the data to be written. +.TP +.B \-cdi +If this flag is present, the TOC type for the disk is set to +.BR CDI . +This only makes sense with XA disks. +.TP +.B \-isosize +Use the +.B "ISO-9660 +file system size as the size of the next track. +This option is needed if you want +.B wodim +to directly read the image of a track from +a raw disk partition or from a +.I TAO +master CD. In the first case the option +.B \-isosize +is needed to limit the size of the CD to the size of the ISO filesystem. +In the second case the option +.B \-isosize +is needed to prevent +.B wodim +from reading the two run out blocks that are appended by each CD-recorder +in track at once mode. These two run out blocks cannot be read and would +cause a buffer underrun that would cause a defective copy. +Do not use this option on files created by +.B genisoimage +and in case +.B wodim +reads the track data from +.IR stdin . +In the first case, you would prevent +.B wodim +from writing the amount of padding that has been appended by +.B genisoimage +and in the latter case, it will not work because +.I stdin +is not seekable. +.sp +If +.B \-isosize +is used for a track, +.B wodim +will automatically add padding for this track as if the +.B \-pad +option has been used but the amount of padding may be less than the padding +written by +.BR genisoimage . +Note that if you use +.B \-isosize +on a track that contains Sparc boot information, the boot information will +be lost. +.sp +Note also that +this option cannot be used to determine the size of a file system +if the multi session option is present. +.TP +.B \-pad +If the track is a data track, 15 sectors of zeroed data +will be added to the end of this and each subsequent data track. +In this case, the +.B \-pad +option is superseded by the +.B padsize= +option. It will remain however as a shorthand for +.BI padsize= 15s. +If the +.I \-pad +option refers to an audio track, +.B wodim +will pad the audio data to be a multiple of 2352 bytes. +The audio data padding is done with binary zeroes which is +equal to absolute silence. +.sp +.B \-pad +remains valid until disabled by +.BR \-nopad . +.TP +.BR padsize= # +Set the amount of data to be appended as padding to the next track to #. +Opposed to the behavior of the +.B \-pad +option, the value for +.I padsize= +is reset to zero for each new track. +wodim assumes a sector size of 2048 bytes for the +.I padsize= +option, independent from the real +sector size and independent from the write mode. +The megabytes mentioned in the verbose mode output however are counting +the output sector size which is e.g. 2448 bytes when writing in RAW/RAW96 +mode. +See +.BR fs = +option for possible arguments. +To pad the equivalent of 20 minutes on a CD, you may write +.BR padsize= 20x60x75s. +Use this option if your CD-drive is not able to read the last sectors of +a track or if you want to be able to read the CD +on a +.B Linux +system with the ISO-9660 filesystem read ahead bug. +If an empty file is used for track data, +this option may be used to create a disk that is entirely made of padding. +This may e.g. be used to find out how much overburning is possible with a +specific media. +.TP +.B \-nopad +Do not pad the following tracks \- the default. +.TP +.B \-shorttrack +Allow all subsequent tracks to violate the Red Book track length standard +which requires a minimum track length of 4 seconds. +This option is only useful when used in SAO or RAW mode. +Not all drives support this feature. The drive must accept the +resulting CUE sheet or support RAW writing. +.TP +.B \-noshorttrack +Re-enforce the Red Book track length standard. Tracks must be +at least 4 seconds. +.TP +.BR pregap= # +Set the pre-gap size for the next track. +This option currently only makes sense with the TEAC drive when +creating track-at-once disks without the 2 second silence before each track. +.br +This option may go away in future. +.TP +.B \-preemp +If this flag is present, all TOC entries for subsequent audio tracks +will indicate that the audio data has been sampled with 50/15 \*msec +pre-emphasis. +The data, however is not modified during the process of transferring from file +to disk. +This option has no effect on data tracks. +.TP +.B \-nopreemp +If this flag is present, all TOC entries for subsequent audio tracks +will indicate that the audio data has been mastered with linear data \- +this is the default. +.TP +.B \-copy +If this flag is present, all TOC entries for subsequent audio tracks +of the resulting CD +will indicate that the audio data has permission to be copied without limit. +This option has no effect on data tracks. +.TP +.B \-nocopy +If this flag is present, all TOC entries for subsequent audio tracks +of the resulting CD +will indicate that the audio data has permission to be copied only once for +personal use \- +this is the default. +.TP +.B \-scms +If this flag is present, all TOC entries for subsequent audio tracks +of the resulting CD +will indicate that the audio data has no permission to be copied anymore. +.TP +.BR tsize= # +If the master image for the next track has been stored on a raw disk, +use this option +to specify the valid amount of data on this disk. If the image of the next +track is stored in a regular file, the size of that file is taken to determine +the length of this track. +If the track contains an ISO 9660 filesystem image use the +.I \-isosize +option to determine the length of that filesystem image. +.br +In Disk at Once mode and with some drives that use +the TEAC programming interface, even in Track at Once mode, +.B wodim +needs to know the size of each track before starting to write the disk. +wodim now checks this and aborts before starting to write. +If this happens you will need to run +.B "genisoimage -print-size +before and use the output (with `s' appended) as an argument to the +.BR tsize = +option of +.B wodim +(e.g. tsize=250000s). +.br +See +.BR fs = +option for possible arguments. + +.SH EXAMPLES +.PP +For all examples below, it will be assumed that the CD/DVD-Recorder is +connected to the primary SCSI bus of the machine. The SCSI target id is +set to 2. +.PP +To record a pure CD-ROM at double speed, using data from the file +.IR cdimage.raw : +.PP + wodim \-v speed=2 dev=2,0 cdimage.raw +.PP +To create an image for a ISO 9660 filesystem with Rock Ridge extensions: +.PP + genisoimage \-R \-o cdimage.raw /home/joerg/master/tree +.PP +To check the resulting file before writing to CD on Solaris: +.PP + mount \-r \-F fbk \-o type=hsfs /dev/fbk0:cdimage.raw /mnt +.PP +On Linux: +.PP + mount cdimage.raw \-r \-t iso9660 \-o loop /mnt +.PP +Go on with: +.br + ls \-lR /mnt +.br + umount /mnt +.PP +If the overall speed of the system is sufficient and the structure of +the filesystem is not too complex, wodim will run without creating an +image of the ISO 9660 filesystem. Simply run the pipeline: +.PP + genisoimage \-R /master/tree | wodim \-v fs=6m speed=2 dev=2,0 - +.PP +The recommended minimum FIFO size for running this pipeline is 4 MBytes. +As the default FIFO size is 4 MB, the +.B fs= +option needs only be present if you want to use a different FIFO size. +If your system is loaded, you should run genisoimage in the real time class too. +To raise the priority of +.B genisoimage +replace the command +.PP + genisoimage \-R /master/tree +.br +by +.br + priocntl \-e \-c RT \-p 59 genisoimage \-R /master/tree +.sp +on Solaris and by +.sp + nice --18 genisoimage \-R /master/tree +.sp +on systems that don't have +.B "UNIX International +compliant real-time scheduling. +.PP +wodim runs at priority 59 on Solaris, you should run genisoimage +at no more than priority 58. On other systems, you should run genisoimage +at no less than nice --18. +.PP +Creating a CD-ROM without file system image on disk has been tested +on a Sparcstation-2 with a Yamaha CDR-400. It did work up to quad speed +when the machine was not loaded. +A faster machine may be able to handle quad speed also in the loaded case. +.PP +To record a pure CD-DA (audio) at single speed, with each track contained +in a file named +.IR track01.cdaudio , +.IR track02.cdaudio , +etc: +.PP + wodim \-v speed=1 dev=/dev/cdrw -audio track*.cdaudio +.PP +To check if it will be ok to use double speed for the example above. +Use the dummy write option: +.PP + wodim \-v \-dummy speed=2 dev=/dev/cdrw \-audio track*.cdaudio +.PP +To record a mixed-mode CD with an ISO 9660 filesystem from +.I cdimage.raw +on the first track, the other tracks being audio tracks from the files +.IR track01.cdaudio , +.IR track02.cdaudio , +etc: +.PP + wodim \-v dev=2,0 cdimage.raw \-audio track*.cdaudio +.PP +To handle drives that need to know the size of a track before starting to write, +first run +.PP + genisoimage -R -q -print-size /master/tree +.PP +and then run +.PP + genisoimage -R /master/tree | wodim speed=2 dev=2,0 tsize=XXXs - +.PP +where +.I XXX +is replaced by the output of the previous run of genisoimage. +.PP +To copy an audio CD in the most accurate way, first run +.PP + icedax dev=/dev/cdrom \-vall cddb=0 -B \-Owav +.PP +and then run +.PP + wodim dev=/dev/cdrw \-v \-dao \-useinfo \-text *.wav +.PP +This will try to copy track indices and to read CD-Text information from disk. +If there is no CD-Text information, +.B icedax +will try to get the information from freedb.org instead. +.PP +To copy an audio CD from a pipe (without intermediate files), first run +.PP + icedax dev=1,0 \-vall cddb=0 \-info-only +.PP +and then run +.PP + icedax dev=1,0 \-no-infofile \-B \-Oraw \- | \\ +.br + wodim dev=2,0 \-v \-dao \-audio \-useinfo \-text *.inf +.PP +This will get all information (including track size info) from the +.B *.inf +files and then read the audio data from stdin. +.sp +If you like to write from +.BR stdin , +make sure that wodim is called with a large enough FIFO size (e.g. +.BR fs=128m ), +reduce the write speed to a value below the read speed of the source drive +(e.g. +.BR speed=12 ), +and get a CD/DVD drive with BURN-Free feature if it is not available yet. +.PP +To set drive options without writing a CD (e.g. to switch a drive +to single session mode), run +.PP + wodim dev=1,0 \-setdropts driveropts=singlesession +.PP +If you like to do this when no CD is in the drive, call +.PP + wodim dev=1,0 \-force \-setdropts driveropts=singlesession +.PP +To copy a CD in clone mode, first read the master CD using: +.PP + readom dev=b,t,l \-clone f=somefile +.PP +or (in case the CD contains many sectors that are unreadable by intention) +by calling: +.PP + readom dev=1,0 -clone -nocorr f=somefile +.PP +will create the files +.I somefile +and +.IR somefile.toc . +Then write the CD using: +.PP + wodim dev=1,0 -raw96r -clone -v somefile + + +.SH ENVIRONMENT +.TP +.B CDR_DEVICE +This may either hold a device identifier that is suitable to the open +call of the SCSI transport library or a label in the file /etc/wodim.conf. +.TP +.B CDR_SPEED +Sets the default speed value for writing (see also +.B speed= +option). +.TP +.B CDR_FIFOSIZE +Sets the default size of the FIFO (see also +.BR fs= # +option). +.TP +.B CDR_FORCERAWSPEED +If this environment variable is set, +.B wodim +will allow you to write at the full RAW encoding speed a single CPU supports. +This will create high potential of buffer underruns. Use with care. +.TP +.B CDR_FORCESPEED +If this environment variable is set, +.B wodim +will allow you to write at the full DMA speed the system supports. +There is no DMA reserve for reading the data that is to be written from disk. +This will create high potential of buffer underruns. Use with care. +.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 FILES +.TP +/etc/wodim.conf +Default values can be set for the following options in /etc/wodim.conf. +For example: +.SM CDR_FIFOSIZE=8m +or +.SM CDR_SPEED=2 +.RS +.TP +CDR_DEVICE +This may either hold a device identifier that is suitable to the open +call of the SCSI transport library or a label in the file /etc/wodim.conf +that allows to identify a specific drive on the system. +.TP +CDR_SPEED +Sets the default speed value for writing (see also +.B speed= +option). +.TP +CDR_FIFOSIZE +Sets the default size of the FIFO (see also +.BR fs= # +option). +.TP +CDR_MAXFIFOSIZE +Sets the maximum size of the FIFO (see also +.BR fs= # +option). +.TP +Any other keyword (label) is an identifier (symbolic name) for a specific drive +on the system. Such an identifier may not contain the characters ',', '/', '@' +or ':'. +.sp +Each line that follows a label contains a whitespace separated list of items. +Currently, four items are recognized: the drive's target specification, the +default speed that should be used for this drive, the default FIFO size +that should be used for this drive and drive specific options. The values for +.I speed +and +.I fifosize +may be set to -1 to tell wodim to use the global defaults. +.I target +can be -1 to use the auto-guessing of the drive (see above). + +The value for driveropts may be omitted or set to "" if no driveropts are used. +A typical line may look this way: +.sp +plex760= 0,5,0 12 50m varirec=1 +.sp +pioneer= /dev/hdd -1 -1 +.sp +This tells +.B wodim +that a drive named +.I plex760 +is at scsibus 0, target 5, lun 0 and should be used with speed 12 and +a FIFO size of 50 MB. It also uses some device specific parameter. +A second drive may is accessible via the device file /dev/hdd and uses the +default speed and the default FIFO size. +.RE + +.SH SEE ALSO +.BR icedax (1), +.BR readom (1), +.BR genisoimage (1), +.BR ssh (1). + +.SH NOTES +.PP +On Solaris you need to stop the volume management if you like to use the USCSI +fallback SCSI transport code. Even things like +.B "wodim -scanbus +will not work if the volume management is running. +.PP +Disks made in +.B "Track At Once +mode are not suitable as a master for direct mass production by CD manufacturers. +You will need the +.B "disk at once +option to record such disks. +Nevertheless the disks made in +.B "Track At Once +will normally be read in all CD players. Some old +audio CD players however may produce a two second click between two audio tracks. +.PP +The minimal size of a track is 4 seconds or 300 sectors. If you write +smaller tracks, the CD-Recorder will add dummy blocks. This is not an +error, even though the SCSI-error message looks this way. +.PP +The Yamaha CDR-400 and all new SCSI-3/mmc conforming drives are supported +in single and multi-session. +.PP +You should run several tests in all supported speeds of your drive with the +.B \-dummy +option turned on if you are using +.B wodim +on an unknown system. Writing a CD is a real-time process. +.B NFS, CIFS +and other network file systems +won't always deliver constantly the needed data rates. +If you want to use +.B wodim +with CD-images that are located on a +.B NFS +mounted filesystem, be sure that the FIFO size is big enough. +If you want to make sure that buffer underruns are not +caused by your source disk, you may use the command +.PP +.B " wodim -dummy dev=2,0 padsize=600m /dev/null +.PP +to create a disk that is entirely made of dummy data. +.PP +There are also cases where you either need to be root or install +.B wodim +executable with suid-root permissions. First, if you are using a device +manufactured before 1999 which requires a non-MMC driver, you should run +.B wodim +in dummy mode before writing data. If you find a problem doing this, please +report it to the +.B cdrkit +maintainers (see below). +.PP +Second, certain functionality may be unusable because of Linux's SCSI +command filtering. When using +.B wodim +for anything except of pure data writing, you should also test the process in +dummy mode and report trouble to the contact address below. +.PP +If you still want to run +.B wodim +with root permissions, you can set the permissions of the executable to +suid-root. See the additional notes of your system/program distribution or +README.suidroot which is part of the cdrkit source. +.PP +You should not connect old drives that do not support +disconnect/reconnect to either the SCSI bus that is connected to the +CD-Recorder or the source disk. +.PP +A Compact Disc can have no more than 99 tracks. +.PP +When creating a disc with both audio and data tracks, +the data should be on track 1 otherwise you should create +a CDplus disk which is a multi session disk with the first session +containing the audio tracks and the following session containing the data track. +.PP +Many operating systems are not able to read more than a single data track, or +need special software to do so. +.PP +If you have more information or SCSI command manuals for currently +unsupported CD/DVD/BR/HD-DVD-Recorders, please contact the +.B cdrkit +maintainers (see below). +.PP +Many CD recorders have bugs and often require a firmware update to work +correctly. If you experience problems which cannot be solved or explained by the +notes above, please look for instructions on the homepage of the particular +manufacturer. +.PP +Some bugs will force you to power cycle the device or to reboot the machine. +.PP +The FIFO percent output is computed just after a block of data has been written +to the CD/DVD-Recorder. For this reason, there will never be 100% FIFO fill ratio +while the FIFO is in streaming mode. + +.SH DIAGNOSTICS +.PP +You have 4 seconds to abort +.B wodim +start after you see the message: +.PP +Starting to write CD at speed %d in %s mode for %s session. +In most shells you can do that by pressing Ctrl-C. +.PP +A typical error message for a SCSI command looks like: +.sp +.RS +.nf +wodim: 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 +.RE +.sp +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. +.PP +The following message is not an error: +.sp +.RS +.nf +Track 01: Total bytes read/written: 2048/2048 (1 sectors). +wodim: I/O error. flush cache: scsi sendcmd: no error +CDB: 35 00 00 00 00 00 00 00 00 00 +status: 0x2 (CHECK CONDITION) +Sense Bytes: F0 00 05 80 00 00 27 0A 00 00 00 00 B5 00 00 00 00 00 +Sense Key: 0x5 Illegal Request, Segment 0 +Sense Code: 0xB5 Qual 0x00 (dummy data blocks added) Fru 0x0 +Sense flags: Blk -2147483609 (valid) +cmd finished after 0.002s timeout 40s +.fi +.RE +.sp +It simply notifies, that a track that is smaller than the minimum size has been +expanded to 300 sectors. +.SH BUGS +.PP +.B netscsid +does not work properly and is generally unmaintained. It is probably not +compatible with rscsi from +.BR cdrtools +either. Good bugfixes are welcome, talk to Cdrkit maintainers. +.PP +.B cuefile support is very limited, only one file is allowed. For volunteers, +see TODO file in the source. +.PP +.B Specifying an audio file multiple times causes corruption of the second +track (effectively no data plus minimum padding). +.PP +Some of the bugs may be fixed in Joerg Schilling's cdrtools. See there for +details, URL attached below. + +.SH CREDITS +.PP +.TP 15 +Joerg Schilling (schilling@fokus.fhg.de) +.br +For writing cdrecord and libscg which represent the most parts of wodim's code. +.PP +.TP 15 +Bill Swartz (Bill_Swartz@twolf.com) +.br +For helping me with the TEAC driver support +.TP +Aaron Newsome (aaron.d.newsome@wdc.com) +.br +For letting me develop Sony support on his drive +.TP +Eric Youngdale (eric@andante.jic.com) +.br +For supplying mkisofs +.TP +Gadi Oxman (gadio@netvision.net.il) +.br +For tips on the ATAPI standard +.TP +Finn Arne Gangstad (finnag@guardian.no) +.br +For the first FIFO implementation. +.TP +Dave Platt (dplatt@feghoot.ml.org) +.br +For creating the experimental packet writing support, +the first implementation of CD-RW blanking support, +the first .wav file decoder +and many nice discussions on cdrecord. +.TP +Chris P. Ross (cross@eng.us.uu.net) +.br +For the first implementation of a BSDI SCSI transport. +.TP +Grant R. Guenther (grant@torque.net) +.br +For creating the first parallel port transport implementation +for Linux. +.TP +Kenneth D. Merry (ken@kdm.org) +.br +for providing the CAM port for FreeBSD together with Michael Smith (msmith@freebsd.org) +.TP +Heiko Ei\*sfeldt (heiko@hexco.de) +for making libedc_ecc available (needed to write RAW data sectors). + +.SH "MAILING LISTS +If you want to actively take part on the development of wodim, +you may join the developer mailing list via this URL: +.sp +.B +https://alioth.debian.org/mail/?group_id=31006 +.PP +The mail address of the list is: +.B +debburn-devel@lists.alioth.debian.org + +.SH AUTHORS +.B wodim +is currently maintained as part of the cdrkit project by its developers. Most of the code and this manual page was originally written by: +.PP +.nf +Joerg Schilling +Seestr. 110 +D-13353 Berlin +Germany +.fi +.PP +This application is derived from "cdrecord" as included +in the cdrtools package [1] created by Joerg +Schilling, who deserves most of the credit for its success. However, he is not +involved into the development of this spinoff and therefore he shall not be +held responsible for any problems caused by it. Do not refer to this application +as "cdrecord", do not try to get support for wodim by contacting the original +authors. +.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@lists.alioth.debian.org +.br +.PP +If you have definitely found a bug, send a mail to this list or to +.PP +.B +submit@bugs.debian.org +.br +.PP +writing at least a short description into the Subject and "Package: cdrkit" in the first line of the mail body. +.SH SOURCES +.PP +.br +[1] Cdrtools 2.01.01a08 from May 2006, http://cdrecord.berlios.de + diff --git a/wodim/wodim.c b/wodim/wodim.c new file mode 100644 index 0000000..7a54ccc --- /dev/null +++ b/wodim/wodim.c @@ -0,0 +1,4701 @@ +/* + * 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. + * + */ + +/* + * + * Modified by Eduard Bloch in 08/2006 and later + */ + +/* @(#)cdrecord.c 1.310 06/02/09 Copyright 1995-2006 J. Schilling */ +/* + * Record data on a CD/CVD-Recorder + * + * Copyright (c) 1995-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. + * + * 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 <stdxlib.h> +#include <fctldefs.h> +#include <errno.h> +#include <timedefs.h> +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> /* for rlimit */ +#endif +#include <statdefs.h> +#include <unixstd.h> +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#include <strdefs.h> +#include <utypes.h> +#include <intcvt.h> +#include <signal.h> +#include <schily.h> +#include <string.h> +#include <getargs.h> +#ifdef HAVE_PRIV_H +#include <priv.h> +#endif + +#include "xio.h" + +#include <usal/scsireg.h> /* XXX wegen SC_NOT_READY */ +#include <usal/scsitransp.h> +#include <usal/usalcmd.h> /* XXX fuer read_buffer */ +#include "scsi_scan.h" + +#include "auheader.h" +#include "wodim.h" +#include "defaults.h" +#include "movesect.h" + +#ifdef __linux__ +#include <sys/capability.h> /* for rawio capability */ +#endif + +#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0 +#ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */ +#else +#define USE_POSIX_PRIORITY_SCHEDULING +#endif +#endif + +/* + * Map toc/track types into names. + */ +char *toc2name[] = { + "CD-DA", + "CD-ROM", + "CD-ROM XA mode 1", + "CD-ROM XA mode 2", + "CD-I", + "Illegal toc type 5", + "Illegal toc type 6", + "Illegal toc type 7", +}; + +/* + * Map sector types into names. + */ +char *st2name[] = { + "Illegal sector type 0", + "CD-ROM mode 1", + "CD-ROM mode 2", + "Illegal sector type 3", + "CD-DA without preemphasis", + "CD-DA with preemphasis", + "Illegal sector type 6", + "Illegal sector type 7", +}; + +/* + * Map data block types into names. + */ +char *db2name[] = { + "Raw (audio)", + "Raw (audio) with P/Q sub channel", + "Raw (audio) with P/W packed sub channel", + "Raw (audio) with P/W raw sub channel", + "Reserved mode 4", + "Reserved mode 5", + "Reserved mode 6", + "Vendor unique mode 7", + "CD-ROM mode 1", + "CD-ROM mode 2", + "CD-ROM XA mode 2 form 1", + "CD-ROM XA mode 2 form 1 (with subheader)", + "CD-ROM XA mode 2 form 2", + "CD-ROM XA mode 2 form 1/2/mix", + "Reserved mode 14", + "Vendor unique mode 15", +}; + +/* + * Map write modes into names. + */ +static char wm_none[] = "unknown"; +static char wm_ill[] = "illegal"; + +char *wm2name[] = { + wm_none, + "BLANK", + "FORMAT", + wm_ill, + "PACKET", + wm_ill, + wm_ill, + wm_ill, + "TAO", + wm_ill, + wm_ill, + wm_ill, + "SAO", + "SAO/RAW16", /* Most liklely not needed */ + "SAO/RAW96P", + "SAO/RAW96R", + "RAW", + "RAW/RAW16", + "RAW/RAW96P", + "RAW/RAW96R", +}; + +int debug; /* print debug messages */ +static int kdebug; /* print kernel debug messages */ +static int scsi_verbose; /* SCSI verbose flag */ +static int silent; /* SCSI silent flag */ +int lverbose; /* static verbose flag */ +int xdebug; /* extended debug flag */ + +char *buf; /* The transfer buffer */ +long bufsize = -1; /* The size of the transfer buffer */ + +static int gracetime = GRACE_TIME; +static int raw_speed = -1; +static int dma_speed = -1; +static int dminbuf = -1; /* XXX Hack for now drive min buf fill */ +BOOL isgui; +static int didintr; +char *driveropts; +static char *cuefilename = NULL; +static uid_t oeuid = (uid_t)-1; + +struct timeval starttime; +struct timeval wstarttime; +struct timeval stoptime; +struct timeval fixtime; + +static long fs = -1; /* fifo (ring buffer) size */ +static Llong warn_minisize = -1L; + +static int gracewait(cdr_t *dp, BOOL *didgracep); +static void cdrstats(cdr_t *dp); +static void susage(int); +static void usage(int); +static void blusage(int); +static void formattypeusage(int); +static void intr(int sig); +static void catchsig(int sig); +static int scsi_cb(void *arg); +static void intfifo(int sig); +static void exscsi(int excode, void *arg); +static void excdr(int excode, void *arg); +int read_buf(int f, char *bp, int size); +int fill_buf(int f, track_t *trackp, long secno, char *bp, int size); +int get_buf(int f, track_t *trackp, long secno, char **bpp, int size); +int write_secs(SCSI *usalp, cdr_t *dp, char *bp, long startsec, int bytespt, + int secspt, BOOL islast); +static int write_track_data(SCSI *usalp, cdr_t *, track_t *); +int pad_track(SCSI *usalp, cdr_t *dp, track_t *trackp, long startsec, + Llong amt, BOOL dolast, Llong *bytesp); +int write_buf(SCSI *usalp, cdr_t *dp, track_t *trackp, char *bp, + long startsec, Llong amt, int secsize, BOOL dolast, + Llong *bytesp); +static void printdata(int, track_t *); +static void printaudio(int, track_t *); +static void checkfile(int, track_t *); +static int checkfiles(int, track_t *); +static void setleadinout(int, track_t *); +static void setpregaps(int, track_t *); +static long checktsize(int, track_t *); +static void opentracks(track_t *); +static void checksize(track_t *); +static BOOL checkdsize(SCSI *usalp, cdr_t *dp, long tsize, int flags); +static void raise_fdlim(void); +static void raise_memlock(void); +static int gargs(int, char **, int *, track_t *, char **, int *, cdr_t **, + int *, long *, int *, int *); +static void set_trsizes(cdr_t *, int, track_t *); +void load_media(SCSI *usalp, cdr_t *, BOOL); +void unload_media(SCSI *usalp, cdr_t *, int); +void reload_media(SCSI *usalp, cdr_t *); +void set_secsize(SCSI *usalp, int secsize); +static int get_dmaspeed(SCSI *usalp, cdr_t *); +static BOOL do_opc(SCSI *usalp, cdr_t *, int); +static void check_recovery(SCSI *usalp, cdr_t *, int); +void audioread(SCSI *usalp, cdr_t *, int); +static void print_msinfo(SCSI *usalp, cdr_t *); +static void print_toc(SCSI *usalp, cdr_t *); +static void print_track(int, long, struct msf *, int, int, int); +#if !defined(HAVE_SYS_PRIOCNTL_H) +static int rt_raisepri(int); +#endif +void raisepri(int); +static void wait_input(void); +static void checkgui(void); +static int getbltype(char *optstr, long *typep); +static int getformattype(char *optstr, long *typep); +static void print_drflags(cdr_t *dp); +static void print_wrmodes(cdr_t *dp); +static BOOL check_wrmode(cdr_t *dp, int wmode, int tflags); +static void set_wrmode(cdr_t *dp, int wmode, int tflags); +static void linuxcheck(void); + +#ifdef __linux__ +static int get_cap(cap_value_t cap_array); +#endif + +struct exargs { + SCSI *usalp; + cdr_t *dp; + int old_secsize; + int flags; + int exflags; +} exargs; + +void fifo_cleanup(void) { + kill_faio(); +} + +/* shared variables */ +int scandevs = 0; +char *msifile = NULL; + +int main(int argc, char *argv[]) +{ + char *dev = NULL; + int timeout = 40; /* Set default timeout to 40s CW-7502 is slow*/ + int speed = -1; + long flags = 0L; + int blanktype = 0; + int formattype = 0; + int i; + int tracks = 0; + int trackno; + long tsize; + track_t track[MAX_TRACK+2]; /* Max tracks + track 0 + track AA */ + cdr_t *dp = (cdr_t *)0; + long startsec = 0L; + int errs = 0; + SCSI *usalp = NULL; + char errstr[80]; + BOOL gracedone = FALSE; + int ispacket; + BOOL is_cdwr = FALSE; + BOOL is_dvdwr = FALSE; + + buf=strstr(argv[0], "cdrecord"); + if(buf && '\0' == buf[8]) /* lame cheater detected */ + argv[0]="wodim"; + +#ifdef __EMX__ + /* This gives wildcard expansion with Non-Posix shells with EMX */ + _wildcard(&argc, &argv); +#endif + save_args(argc, argv); + oeuid = geteuid(); /* Remember saved set uid */ + + fillbytes(track, sizeof (track), '\0'); + for (i = 0; i < MAX_TRACK+2; i++) + track[i].track = track[i].trackno = i; + track[0].tracktype = TOC_MASK; + raise_fdlim(); + ispacket = gargs(argc, argv, &tracks, track, &dev, &timeout, &dp, &speed, &flags, + &blanktype, &formattype); + if ((track[0].tracktype & TOC_MASK) == TOC_MASK) + comerrno(EX_BAD, "Internal error: Bad TOC type.\n"); + + if (flags & F_VERSION) { + fprintf(stderr, + "Cdrecord-yelling-line-to-tell-frontends-to-use-it-like-version 2.01.01a03-dvd \n" + "Wodim " CDRKIT_VERSION "\n" + "Copyright (C) 2006 Cdrkit suite contributors\n" + "Based on works from Joerg Schilling, Copyright (C) 1995-2006, J. Schilling\n" + ); + exit(0); + } + + checkgui(); + + if (debug || lverbose) { + printf("TOC Type: %d = %s\n", + track[0].tracktype & TOC_MASK, + toc2name[track[0].tracktype & TOC_MASK]); + } + + if ((flags & (F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_INQUIRY|F_SCANBUS|F_RESET)) == 0) { + /* + * Try to lock us im memory (will only work for root) + * but you need access to root anyway to send SCSI commands. + * We need to be root to open /dev/usal? or similar devices + * on other OS variants and we need to be root to be able + * to send SCSI commands at least on AIX and + * Solaris (USCSI only) regardless of the permissions for + * opening files + * + * XXX The following test used to be + * XXX #if defined(HAVE_MLOCKALL) || defined(_POSIX_MEMLOCK) + * XXX but the definition for _POSIX_MEMLOCK did change during + * XXX the last 8 years and the autoconf test is better for + * XXX the static case. sysconf() only makes sense if we like + * XXX to check dynamically. + */ + raise_memlock(); +#if defined(HAVE_MLOCKALL) + /* + * XXX mlockall() needs root privilleges. + */ + if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) { + if(lverbose>2) + fprintf(stderr, + "W: Cannot do mlockall(2). Possibly increased risk for buffer underruns.\n"); + } +#endif + + /* + * XXX raisepri() needs root privilleges. + */ + raisepri(0); /* max priority */ + /* + * XXX shmctl(id, SHM_LOCK, 0) needs root privilleges. + * XXX So if we use SysV shared memory, wee need to be root. + * + * Note that not being able to set up a FIFO bombs us + * back to the DOS ages. Trying to run cdrecord without + * root privillegs is extremely silly, it breaks most + * of the advanced features. We need to be at least installed + * suid root or called by RBACs pfexec. + */ + init_fifo(fs); /* Attach shared memory (still one process) */ + } + + if ((flags & F_WAITI) != 0) { + if (lverbose) + printf("Waiting for data on stdin...\n"); + wait_input(); + } + + /* + * Call usal_remote() to force loading the remote SCSI transport library + * code that is located in librusal instead of the dummy remote routines + * that are located inside libusal. + */ + usal_remote(); + if (dev != NULL && + ((strncmp(dev, "HELP", 4) == 0) || + (strncmp(dev, "help", 4) == 0))) { + usal_help(stderr); + exit(0); + } + + if( (!dev || *dev=='\0'|| 0==strcmp(dev, "-1")) && (flags & F_SCANBUS)==0 ) { + int64_t need_size=0L; + struct stat statbuf; + int t; + + fprintf(stderr, "Device was not specified. Trying to find an appropriate drive...\n"); + + /* estimate how much data user wants to write */ + for(t=1;t<=tracks;t++) { + if(track[t].tracksize>=0) + need_size+=track[t].tracksize; + else if(0==stat(track[t].filename, &statbuf)) + need_size+=statbuf.st_size; + } + usalp=open_auto(need_size, debug, lverbose); + } + + if(!usalp) + usalp = usal_open(dev, errstr, sizeof(errstr), debug, lverbose); + + if(!usalp) + { + errmsg("\nCannot open SCSI driver!\n" + "For possible targets try 'wodim --devices' or 'wodim -scanbus'.\n" + "For possible transport specifiers try 'wodim dev=help'.\n" + "For IDE/ATAPI devices configuration, see the file README.ATAPI.setup from\n" + "the wodim documentation.\n"); + exit(EX_BAD); + } + +#ifdef HAVE_PRIV_SET +#ifdef PRIV_DEBUG + fprintf(stderr, "file_dac_read: %d\n", priv_ineffect(PRIV_FILE_DAC_READ)); +#endif + /* + * Give up privs we do not need anymore. + * We no longer need: + * file_dac_read,proc_lock_memory,proc_priocntl,net_privaddr + * We still need: + * sys_devices + */ + priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY, + PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL); + priv_set(PRIV_OFF, PRIV_PERMITTED, + PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY, + PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, NULL); + priv_set(PRIV_OFF, PRIV_INHERITABLE, + PRIV_FILE_DAC_READ, PRIV_PROC_LOCK_MEMORY, + PRIV_PROC_PRIOCNTL, PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL); +#endif + /* + * This is only for OS that do not support fine grained privs. + * + * XXX Below this point we do not need root privilleges anymore. + */ + if (geteuid() != getuid()) { /* AIX does not like to do this */ + /* If we are not root */ +#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"); + } + +#ifdef __linux__ + /* get the rawio capability */ + if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose>2)) + { + perror("Warning: Cannot gain SYS_RAWIO capability"); + fprintf(stderr, "Possible reason: wodim not installed SUID root.\n"); + } +#endif + + /* + * WARNING: We now are no more able to do any privilleged operation + * unless we have been called by root. + * + * XXX It may be that we later get problems in init_faio() because + * XXX this function calls raisepri() to lower the priority slightly. + */ + usal_settimeout(usalp, timeout); + usalp->verbose = scsi_verbose; + usalp->silent = silent; + usalp->debug = debug; + usalp->kdebug = kdebug; + usalp->cap->c_bsize = DATA_SEC_SIZE; + + if ((flags & F_MSINFO) == 0 || lverbose) { + char *vers; + char *auth; + + + if(lverbose) + fprintf(stderr, "Wodim version: " CDRKIT_VERSION "\n"); + + vers = usal_version(0, SCG_VERSION); + auth = usal_version(0, SCG_AUTHOR); + if(lverbose >1 && auth && vers) + fprintf(stderr, "Using libusal version '%s-%s'.\n", auth, vers); + + + vers = usal_version(usalp, SCG_RVERSION); + auth = usal_version(usalp, SCG_RAUTHOR); + if (lverbose > 1 && vers && auth) + fprintf(stderr, "Using remote transport code version '%s-%s'\n", auth, vers); + } + + if (lverbose && driveropts) + printf("Driveropts: '%s'\n", driveropts); + +/* bufsize = usal_bufsize(usalp, CDR_BUF_SIZE);*/ + bufsize = usal_bufsize(usalp, bufsize); + if (lverbose || debug) + fprintf(stderr, "SCSI buffer size: %ld\n", bufsize); + if ((buf = usal_getbuf(usalp, bufsize)) == NULL) + comerr("Cannot get SCSI I/O buffer.\n"); + + if (scandevs) + return (list_devices(usalp, stdout, 0)); + + if ((flags & F_SCANBUS) != 0) { + select_target(usalp, stdout); + exit(0); + } + if ((flags & F_RESET) != 0) { + if (usal_reset(usalp, SCG_RESET_NOP) < 0) + comerr("Cannot reset (OS does not implement reset).\n"); + if (usal_reset(usalp, SCG_RESET_TGT) >= 0) + exit(0); + if (usal_reset(usalp, SCG_RESET_BUS) < 0) + comerr("Cannot reset target.\n"); + exit(0); + } + + /* + * First try to check which type of SCSI device we + * have. + if (debug || lverbose) + printf("atapi: %d\n", usal_isatapi(usalp)); + */ + usalp->silent++; + test_unit_ready(usalp); /* eat up unit attention */ + usalp->silent--; + if (!do_inquiry(usalp, (flags & F_MSINFO) == 0 || lverbose)) { + errmsgno(EX_BAD, "Cannot do inquiry for CD/DVD-Recorder.\n"); + if (unit_ready(usalp)) + errmsgno(EX_BAD, "The unit seems to be hung and needs power cycling.\n"); + exit(EX_BAD); + } +#ifdef GCONF + /* + * Debug only + */ + { + extern void gconf(SCSI *); + + if (lverbose > 2) + gconf(usalp); + } +#endif + + if ((flags & F_PRCAP) != 0) { + print_capabilities(usalp); + print_capabilities_mmc4(usalp); + exit(0); + } + if ((flags & F_INQUIRY) != 0) + exit(0); + + if (dp == (cdr_t *)NULL) { /* No driver= option specified */ + dp = get_cdrcmds(usalp); /* Calls dp->cdr_identify() */ + } + else if (!is_unknown_dev(usalp) && dp != get_cdrcmds(usalp)) { + errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n"); + } + is_mmc(usalp, &is_cdwr, &is_dvdwr); + if (ispacket) { + if (is_dvdwr) { + track[0].flags |= TI_PACKET; + /*XXX put here to only affect DVD writing, should be in gargs. + * however if set in args for all mode, packet writing is then + * broken for all disc as cdrecord assume that PACKET imply TAO which + * is not true at all???? */ + track[0].flags &= ~TI_TAO; + } + } + + if (dp == (cdr_t *)0) + comerrno(EX_BAD, "Sorry, no supported CD/DVD-Recorder found on this target.\n"); + + /* DVD does not support TAO */ + if (dp->is_dvd) { + if(lverbose>1) + fprintf(stderr, "Using Session At Once (SAO) for DVD mode.\n"); + dp->cdr_flags |= F_SAO; + for (i = 0; i <= MAX_TRACK; i++) { + track[i].flags &= ~TI_TAO; + track[i].flags |= TI_SAO; + } + } + + if (!is_cddrive(usalp)) + comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n"); + /* + * The driver is known, set up data structures... + */ + { + cdr_t *ndp; + dstat_t *dsp; + + ndp = malloc(sizeof (cdr_t)); + dsp = malloc(sizeof (dstat_t)); + if (ndp == NULL || dsp == NULL) + comerr("Cannot allocate memory for driver structure.\n"); + movebytes(dp, ndp, sizeof (cdr_t)); + dp = ndp; + dp->cdr_flags |= CDR_ALLOC; + dp->cdr_cmdflags = flags; + + fillbytes(dsp, sizeof (*dsp), '\0'); + dsp->ds_minbuf = 0xFFFF; + dp->cdr_dstat = dsp; + } + + if ((flags & (F_MSINFO|F_TOC|F_LOAD|F_DLCK|F_EJECT)) == 0 || + tracks > 0 || + cuefilename != NULL) + { + if ((dp->cdr_flags & CDR_ISREADER) != 0) { + errmsgno(EX_BAD, + "Sorry, no CD/DVD-Recorder or unsupported CD/DVD-Recorder found on this target.\n"); + } + + if (!is_mmc(usalp, &is_cdwr, &is_dvdwr)) + is_cdwr = TRUE; /* If it is not MMC, it must be a CD writer */ + + if (is_dvdwr && !set_cdrcmds("mmc_mdvd", (cdr_t **)NULL)) { + errmsgno(EX_BAD, + "Internal error, DVD driver failure. Please report to debburn-devel@lists.alioth.debian.org.\n"); + } + /* + * Only exit if this is not the ProDVD test binary. + */ + if (!is_cdwr) + exit(EX_BAD); + } + + /* + * Set up data structures for current drive state. + */ + if ((*dp->cdr_attach)(usalp, dp) != 0) + comerrno(EX_BAD, "Cannot attach driver for CD/DVD-Recorder.\n"); + + if (lverbose > 1) { + printf("Drive current speed: %d\n", dp->cdr_dstat->ds_dr_cur_wspeed); + printf("Drive default speed: %d\n", dp->cdr_speeddef); + printf("Drive max speed : %d\n", dp->cdr_speedmax); + } + if (speed > (int)dp->cdr_speedmax && (flags & F_FORCE) == 0) + speed = dp->cdr_speedmax; + if (speed < 0) + speed = dp->cdr_speeddef; + + if (lverbose > 1) { + printf("Selected speed : %d\n", speed); + } + dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */ + + exargs.usalp = usalp; + exargs.dp = dp; + exargs.old_secsize = -1; + exargs.flags = flags; + + if ((flags & F_MSINFO) == 0 || lverbose) { + printf("Using %s (%s).\n", dp->cdr_drtext, dp->cdr_drname); + print_drflags(dp); + print_wrmodes(dp); + } + usalp->silent++; + if ((debug || lverbose)) { + tsize = -1; + if ((*dp->cdr_buffer_cap)(usalp, &tsize, (long *)0) < 0 || tsize < 0) { + if (read_buffer(usalp, buf, 4, 0) >= 0) + tsize = a_to_u_4_byte(buf); + } + if (tsize > 0) { + printf("Drive buf size : %lu = %lu KB\n", + tsize, tsize >> 10); + } + } + usalp->silent--; + + dma_speed = get_dmaspeed(usalp, dp); + + if ((debug || lverbose) && dma_speed > 0) { + /* + * We do not yet know what medium type is in... + */ + printf("Drive DMA Speed: %d kB/s %dx CD %dx DVD\n", + dma_speed, dma_speed/176, dma_speed/1385); + } + if ((tracks > 0 || cuefilename != NULL) && (debug || lverbose)) + printf("FIFO size : %lu = %lu KB\n", fs, fs >> 10); + +#ifdef HAVE_LIB_EDC_ECC + if ((flags & F_RAW) != 0 && (dp->cdr_dstat->ds_flags & DSF_DVD) == 0) + raw_speed = encspeed(debug || lverbose); +#endif + + if ((flags & F_CHECKDRIVE) != 0) + exit(0); + + if ((flags & F_ABORT) != 0) { + /* + * flush cache is not supported by CD-ROMs avoid prob with -toc + */ + usalp->silent++; + scsi_flush_cache(usalp, FALSE); + (*dp->cdr_abort_session)(usalp, dp); + usalp->silent--; + exit(0); + } + + if (tracks == 0 && cuefilename == NULL && + (flags & (F_FIX|F_BLANK)) == 0 && (flags & F_EJECT) != 0) { + /* + * Do not check if the unit is ready here to allow to open + * an empty unit too. + */ + unload_media(usalp, dp, flags); + exit(0); + } + flush(); + + if (cuefilename) { + parsecue(cuefilename, track); + tracks = track[0].tracks; + } else { + opentracks(track); + } + + if (tracks > 1) + sleep(2); /* Let the user watch the inquiry messages */ + + if (tracks > 0 && !check_wrmode(dp, flags, track[1].flags)) + comerrno(EX_BAD, "Illegal write mode for this drive.\n"); + + if ((track[0].flags & TI_TEXT) == 0 && /* CD-Text not yet processed */ + (track[MAX_TRACK+1].flags & TI_TEXT) != 0) { + /* + * CD-Text from textfile= or from CUE CDTEXTFILE will win + * over CD-Text from *.inf files and over CD-Text from + * CUE SONGWRITER, ... + */ + packtext(tracks, track); + track[0].flags |= TI_TEXT; + } +#ifdef CLONE_WRITE + if (flags & F_CLONE) { + clone_toc(track); + clone_tracktype(track); + } +#endif + setleadinout(tracks, track); + set_trsizes(dp, tracks, track); + setpregaps(tracks, track); + checkfiles(tracks, track); + tsize = checktsize(tracks, track); + + /* + * Make wm2name[wrmode] work. + * This must be done after the track flags have been set up + * by the functions above. + */ + if (tracks == 0 && (flags & F_BLANK) != 0) + dp->cdr_dstat->ds_wrmode = WM_BLANK; + else if (tracks == 0 && (flags & F_FORMAT) != 0) + dp->cdr_dstat->ds_wrmode = WM_FORMAT; + else + set_wrmode(dp, flags, track[1].flags); + + /* + * Debug only + */ + { + void *cp = NULL; + + (*dp->cdr_gen_cue)(track, &cp, FALSE); + if (cp) + free(cp); + } + + /* + * Create Lead-in data. Only needed in RAW mode. + */ + do_leadin(track); + + + /* + * Install exit handler before we change the drive status. + */ + on_comerr(exscsi, &exargs); + + if ((flags & F_FORCE) == 0) + load_media(usalp, dp, TRUE); + + if ((flags & (F_LOAD|F_DLCK)) != 0) { + if ((flags & F_DLCK) == 0) { + usalp->silent++; /* silently */ + scsi_prevent_removal( + usalp, 0); /* allow manual open */ + usalp->silent--; /* if load failed... */ + } + exit(0); /* we did not change status */ + } + exargs.old_secsize = sense_secsize(usalp, 1); + if (exargs.old_secsize < 0) + exargs.old_secsize = sense_secsize(usalp, 0); + if (debug) + printf("Current Secsize: %d\n", exargs.old_secsize); + usalp->silent++; + if (read_capacity(usalp) < 0) { + if (exargs.old_secsize > 0) + usalp->cap->c_bsize = exargs.old_secsize; + } + usalp->silent--; + if (exargs.old_secsize < 0) + exargs.old_secsize = usalp->cap->c_bsize; + if (exargs.old_secsize != usalp->cap->c_bsize) + errmsgno(EX_BAD, "Warning: blockdesc secsize %d differs from cap secsize %d\n", + exargs.old_secsize, usalp->cap->c_bsize); + + if (lverbose) + printf("Current Secsize: %d\n", exargs.old_secsize); + + if (exargs.old_secsize > 0 && exargs.old_secsize != DATA_SEC_SIZE) { + /* + * Some drives (e.g. Plextor) don't like to write correctly + * in SAO mode if the sector size is set to 512 bytes. + * In addition, wodim -msinfo will not work properly + * if the sector size is not 2048 bytes. + */ + set_secsize(usalp, DATA_SEC_SIZE); + } + + /* + * Is this the right place to do this ? + */ + check_recovery(usalp, dp, flags); + +/*audioread(dp, flags);*/ +/*unload_media(usalp, dp, flags);*/ +/*return 0;*/ + if (flags & F_WRITE) + dp->cdr_dstat->ds_cdrflags |= RF_WRITE; + if (flags & F_BLANK) + dp->cdr_dstat->ds_cdrflags |= RF_BLANK; + if (flags & F_PRATIP || lverbose > 0) { + dp->cdr_dstat->ds_cdrflags |= RF_PRATIP; + } + if (flags & F_IMMED || dminbuf > 0) { + if (dminbuf <= 0) + dminbuf = 50; + if (lverbose <= 0) /* XXX Hack needed for now */ + lverbose++; + dp->cdr_dstat->ds_cdrflags |= RF_WR_WAIT; + } + if ((*dp->cdr_getdisktype)(usalp, dp) < 0) { + errmsgno(EX_BAD, "Cannot get disk type.\n"); + if ((flags & F_FORCE) == 0) + comexit(EX_BAD); + } + if (flags & F_PRATIP) { + comexit(0); + } + /* + * The next actions should depend on the disk type. + */ + if (dma_speed > 0) { + if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0) + dma_speed /= 176; + else + dma_speed /= 1385; + } + + /* + * Init drive to default modes: + * + * We set TAO unconditionally to make checkdsize() work + * currectly in SAO mode too. + * + * At least MMC drives will not return the next writable + * address we expect when the drive's write mode is set + * to SAO. We need this address for mkisofs and thus + * it must be the first user accessible sector and not the + * first sector of the pregap. + * + * XXX The ACER drive: + * XXX Vendor_info : 'ATAPI ' + * XXX Identifikation : 'CD-R/RW 8X4X32 ' + * XXX Revision : '5.EW' + * XXX Will not return from -dummy to non-dummy without + * XXX opening the tray. + */ + usalp->silent++; + if ((*dp->cdr_init)(usalp, dp) < 0) + comerrno(EX_BAD, "Cannot init drive.\n"); + usalp->silent--; + + if (flags & F_SETDROPTS) { + /* + * Note that the set speed function also contains + * drive option processing for speed related drive options. + */ + if ((*dp->cdr_opt1)(usalp, dp) < 0) { + errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n"); + } + if ((*dp->cdr_set_speed_dummy)(usalp, dp, &speed) < 0) { + errmsgno(EX_BAD, "Cannot set speed/dummy.\n"); + } + dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */ + if ((*dp->cdr_opt2)(usalp, dp) < 0) { + errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n"); + } + comexit(0); + } + /* + * XXX If dp->cdr_opt1() ever affects the result for + * XXX the multi session info we would need to move it here. + */ + if (flags & F_MSINFO) { + print_msinfo(usalp, dp); + comexit(0); + } + if (flags & F_TOC) { + print_toc(usalp, dp); + comexit(0); + } +#ifdef XXX + if ((*dp->cdr_check_session)() < 0) { + comexit(EX_BAD); + } +#endif + { + Int32_t omb = dp->cdr_dstat->ds_maxblocks; + + if ((*dp->cdr_opt1)(usalp, dp) < 0) { + errmsgno(EX_BAD, "Cannot set up 1st set of driver options.\n"); + } + if (tsize > 0 && omb != dp->cdr_dstat->ds_maxblocks) { + printf("Disk size changed by user options.\n"); + printf("Checking disk capacity according to new values.\n"); + } + } + if (tsize == 0) { + if (tracks > 0) { + errmsgno(EX_BAD, + "WARNING: Total disk size unknown. Data may not fit on disk.\n"); + } + } else if (tracks > 0) { + /* + * XXX How do we let the user check the remaining + * XXX disk size witout starting the write process? + */ + if (!checkdsize(usalp, dp, tsize, flags)) + comexit(EX_BAD); + } + if (tracks > 0 && fs > 0l) { +#if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID) + /* + * Hack to work around the POSIX design bug in real time + * priority handling: we need to be root even to lower + * our priority. + * Note that we need to find a more general way that works + * even on OS that do not support getreuid() which is *BSD + * and SUSv3 only. + */ + if (oeuid != getuid()) { + if (setreuid(-1, oeuid) < 0) + errmsg("Could set back effective uid.\n"); + } + +#endif + /* + * fork() here to start the extra process needed for + * improved buffering. + */ + if (!init_faio(track, bufsize)) + fs = 0L; + else + on_comerr(excdr, &exargs); + + atexit(fifo_cleanup); + +#if defined(USE_POSIX_PRIORITY_SCHEDULING) && defined(HAVE_SETREUID) + /* + * XXX Below this point we never need root privilleges anymore. + */ + if (geteuid() != getuid()) { /* AIX does not like to do this */ + /* If we are not root */ + if (setreuid(-1, getuid()) < 0) + comerr("Panic cannot set back effective uid.\n"); + } +#ifdef __linux__ + if (get_cap(CAP_SYS_RAWIO) && (debug || lverbose>2)) + perror("Error: Cannot gain SYS_RAWIO capability, is wodim installed SUID root? Reason"); +#endif + +#endif + } + + if ((*dp->cdr_set_speed_dummy)(usalp, dp, &speed) < 0) { + errmsgno(EX_BAD, "Cannot set speed/dummy.\n"); + if ((flags & F_FORCE) == 0) + comexit(EX_BAD); + } + dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */ + if ((flags & F_WRITE) != 0 && raw_speed >= 0) { + int max_raw = (flags & F_FORCE) != 0 ? raw_speed:raw_speed/2; + + if (getenv("CDR_FORCERAWSPEED")) + max_raw = raw_speed; + + for (i = 1; i <= MAX_TRACK; i++) { + /* + * Check for Clone tracks + */ + if ((track[i].sectype & ST_MODE_RAW) != 0) + continue; + /* + * Check for non-data tracks + */ + if ((track[i].sectype & ST_MODE_MASK) == ST_MODE_AUDIO) + continue; + + if (speed > max_raw) { + errmsgno(EX_BAD, + "Processor too slow. Cannot write RAW data at speed %d.\n", + speed); + comerrno(EX_BAD, "Max RAW data speed on this processor is %d.\n", + max_raw); + } + break; + } + } + if (tracks > 0 && (flags & F_WRITE) != 0 && dma_speed > 0) { + int max_dma = (dma_speed+1)*4/5; /* use an empirical formula to estimate available bandwith */ + + if((flags & F_FORCE) != 0 || getenv("CDR_FORCESPEED")) + max_dma = dma_speed; + + if (speed > max_dma) { + errmsgno(EX_BAD, + "DMA speed too slow (OK for %dx). Cannot write at speed %dx.\n", + max_dma, speed); + if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) { + errmsgno(EX_BAD, "Max DMA data speed is %d.\n", max_dma); + comerrno(EX_BAD, "Try to use 'driveropts=burnfree'.\n"); + } + } + } + if ((flags & (F_WRITE|F_BLANK)) != 0 && + (dp->cdr_dstat->ds_flags & DSF_ERA) != 0) { + if (xdebug) { + printf("Current speed %d, medium low speed: %d medium high speed: %d\n", + speed, + dp->cdr_dstat->ds_at_min_speed, + dp->cdr_dstat->ds_at_max_speed); + } + if (dp->cdr_dstat->ds_at_max_speed > 0 && + speed <= 8 && + speed > (int)dp->cdr_dstat->ds_at_max_speed) { + /* + * Be careful here: 10x media may be written faster. + * The current code will work as long as there is no + * writer that can only write faster than 8x + */ + if ((flags & F_FORCE) == 0) { + errmsgno(EX_BAD, + "Write speed %d of medium not sufficient for this writer.\n", + dp->cdr_dstat->ds_at_max_speed); + comerrno(EX_BAD, + "You may have used an ultra low speed medium on a high speed writer.\n"); + } + } + + if ((dp->cdr_dstat->ds_flags & DSF_ULTRASPP_ERA) != 0 && + (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0)) { + if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRAP) == 0) { + comerrno(EX_BAD, + "Trying to use ultra high speed+ medium on a writer which is not\ncompatible with ultra high speed+ media.\n"); + } else if ((flags & F_FORCE) == 0) { + comerrno(EX_BAD, + "Probably trying to use ultra high speed+ medium on improper writer.\n"); + } + } else if ((dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA) != 0 && + (speed < 16 || (dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0)) { + if ((dp->cdr_cdrw_support & CDR_CDRW_ULTRA) == 0) { + comerrno(EX_BAD, + "Trying to use ultra high speed medium on a writer which is not\ncompatible with ultra high speed media.\n"); + } else if ((flags & F_FORCE) == 0) { + comerrno(EX_BAD, + "Probably trying to use ultra high speed medium on improper writer.\n"); + } + } + if (dp->cdr_dstat->ds_at_min_speed >= 4 && + dp->cdr_dstat->ds_at_max_speed > 4 && + dp->cdr_dstat->ds_dr_max_wspeed <= 4) { + if ((flags & F_FORCE) == 0) { + comerrno(EX_BAD, + "Trying to use high speed medium on low speed writer.\n"); + } + } + if ((int)dp->cdr_dstat->ds_at_min_speed > speed) { + if ((flags & F_FORCE) == 0) { + errmsgno(EX_BAD, + "Write speed %d of writer not sufficient for this medium.\n", + speed); + errmsgno(EX_BAD, + "You did use a %s speed medium on an improper writer or\n", + dp->cdr_dstat->ds_flags & DSF_ULTRASP_ERA ? + "ultra high": "high"); + comerrno(EX_BAD, + "you used a speed=# option with a speed too low for this medium.\n"); + } + } + } + if ((flags & (F_BLANK|F_FORCE)) == (F_BLANK|F_FORCE)) { + printf("Waiting for drive to calm down.\n"); + wait_unit_ready(usalp, 120); + if (gracewait(dp, &gracedone) < 0) { + /* + * In case kill() did not work ;-) + */ + errs++; + goto restore_it; + } + scsi_blank(usalp, 0L, blanktype, FALSE); + } + + /* + * Last chance to quit! + */ + if (gracewait(dp, &gracedone) < 0) { + /* + * In case kill() did not work ;-) + */ + errs++; + goto restore_it; + } + + if (dp->profile == 0x2B && flags & F_SAO && tsize > 0) { + printf("Preparing middle zone location for this DVD+R dual layer disc\n"); + if (!dp->cdr_layer_split(usalp, dp, tsize)) { + errmsgno(EX_BAD, "Cannot send structure for middle zone location.\n"); + comexit(EX_BAD); + } + } + + if (tracks > 0 && fs > 0l) { + /* + * Wait for the read-buffer to become full. + * This should be take no extra time if the input is a file. + * If the input is a pipe (e.g. mkisofs) this can take a + * while. If mkisofs dumps core before it starts writing, + * we abort before the writing process started. + */ + if (!await_faio()) { + comerrno(EX_BAD, "Input buffer error, aborting.\n"); + } + } + wait_unit_ready(usalp, 120); + + starttime.tv_sec = 0; + wstarttime.tv_sec = 0; + stoptime.tv_sec = 0; + fixtime.tv_sec = 0; + if (gettimeofday(&starttime, (struct timezone *)0) < 0) + errmsg("Cannot get start time\n"); + + /* + * Blank the media if we were requested to do so + */ + if (flags & F_BLANK) { + /* + * Do not abort if OPC failes. Just give it a chance + * for better laser power calibration than without OPC. + * + * Ricoh drives return with a vendor unique sense code. + * This is most likely because they refuse to do OPC + * on a non blank media. + */ + usalp->silent++; + do_opc(usalp, dp, flags); + usalp->silent--; + wait_unit_ready(usalp, 120); + if (gettimeofday(&starttime, (struct timezone *)0) < 0) + errmsg("Cannot get start time\n"); + + if ((*dp->cdr_blank)(usalp, dp, 0L, blanktype) < 0) { + errmsgno(EX_BAD, "Cannot blank disk, aborting.\n"); + if (blanktype != BLANK_DISC) { + errmsgno(EX_BAD, "Some drives do not support all blank types.\n"); + errmsgno(EX_BAD, "Try again with wodim blank=all.\n"); + } + comexit(EX_BAD); + } + if (gettimeofday(&fixtime, (struct timezone *)0) < 0) + errmsg("Cannot get blank time\n"); + if (lverbose) + prtimediff("Blanking time: ", &starttime, &fixtime); + + /* + * XXX Erst blank und dann format? + * XXX Wenn ja, dann hier (flags & F_FORMAT) testen + * + * EB: nee, besser nicht + */ + if (!wait_unit_ready(usalp, 240) || tracks == 0) { + comexit(0); + } + } + if (flags & F_FORMAT) { + printf("wodim: media format asked\n"); + /* + * Do not abort if OPC failes. Just give it a chance + * for better laser power calibration than without OPC. + * + * Ricoh drives return with a vendor unique sense code. + * This is most likely because they refuse to do OPC + * on a non blank media. + */ + usalp->silent++; + do_opc(usalp, dp, flags); + usalp->silent--; + wait_unit_ready(usalp, 120); + if (gettimeofday(&starttime, (struct timezone *)0) < 0) + errmsg("Cannot get start time\n"); + + if ((*dp->cdr_format)(usalp, dp, formattype) < 0) { + errmsgno(EX_BAD, "Cannot format disk, aborting.\n"); + comexit(EX_BAD); + } + if (gettimeofday(&fixtime, (struct timezone *)0) < 0) + errmsg("Cannot get format time\n"); + if (lverbose) + prtimediff("Formatting time: ", &starttime, &fixtime); + + if (!wait_unit_ready(usalp, 240) || tracks == 0) { + comexit(0); + } + if (gettimeofday(&starttime, (struct timezone *)0) < 0) + errmsg("Cannot get start time\n"); + } + /* + * Reset start time so we will not see blanking time and + * writing time counted together. + */ + if (gettimeofday(&starttime, (struct timezone *)0) < 0) + errmsg("Cannot get start time\n"); + if (tracks == 0 && (flags & F_FIX) == 0) + comerrno(EX_BAD, "No tracks found.\n"); + /* + * Get the number of the next recordable track by reading the TOC and + * use the number the last current track number. + */ + usalp->silent++; + if (read_tochdr(usalp, dp, NULL, &trackno) < 0) { + trackno = 0; + } + usalp->silent--; + + /* If it is DVD, the information in TOC is fabricated :) + The real information is from read disk info command*/ + if((dp->cdr_dstat->ds_disktype&DT_DVD) && (dp->cdr_dstat->ds_trlast>0)){ + trackno=dp->cdr_dstat->ds_trlast-1; + if (lverbose > 2) + printf("trackno=%d\n",trackno); + } + + if ((tracks + trackno) > MAX_TRACK) { + /* + * XXX How many tracks are allowed on a DVD? + */ + comerrno(EX_BAD, "Too many tracks for this disk, last track number is %d.\n", + tracks + trackno); + } + + for (i = 0; i <= tracks+1; i++) { /* Lead-in ... Lead-out */ + track[i].trackno = i + trackno; /* Set up real track # */ + } + + if ((*dp->cdr_opt2)(usalp, dp) < 0) { + errmsgno(EX_BAD, "Cannot set up 2nd set of driver options.\n"); + } + + /* + * Now we actually start writing to the CD/DVD. + * XXX Check total size of the tracks and remaining size of disk. + */ + if ((*dp->cdr_open_session)(usalp, dp, track) < 0) { + comerrno(EX_BAD, "Cannot open new session.\n"); + } + if (!do_opc(usalp, dp, flags)) + comexit(EX_BAD); + + /* + * As long as open_session() will do nothing but + * set up parameters, we may leave fix_it here. + * I case we have to add an open_session() for a drive + * that wants to do something that modifies the disk + * We have to think about a new solution. + */ + if (flags & F_FIX) + goto fix_it; + + /* + * This call may modify trackp[i].trackstart for all tracks. + */ + if ((*dp->cdr_write_leadin)(usalp, dp, track) < 0) + comerrno(EX_BAD, "Could not write Lead-in.\n"); + + if (lverbose && (dp->cdr_dstat->ds_cdrflags & RF_LEADIN) != 0) { + + if (gettimeofday(&fixtime, (struct timezone *)0) < 0) + errmsg("Cannot get lead-in write time\n"); + prtimediff("Lead-in write time: ", &starttime, &fixtime); + } + + if (gettimeofday(&wstarttime, (struct timezone *)0) < 0) + errmsg("Cannot get start time\n"); + for (i = 1; i <= tracks; i++) { + startsec = 0L; + + if ((*dp->cdr_open_track)(usalp, dp, &track[i]) < 0) { + errmsgno(EX_BAD, "Cannot open next track.\n"); + errs++; + break; + } + + if ((flags & (F_SAO|F_RAW)) == 0) { + if ((*dp->cdr_next_wr_address)(usalp, &track[i], &startsec) < 0) { + errmsgno(EX_BAD, "Cannot get next writable address.\n"); + errs++; + break; + } + track[i].trackstart = startsec; + } + if (debug || lverbose) { + printf("Starting new track at sector: %ld\n", + track[i].trackstart); + flush(); + } + if (write_track_data(usalp, dp, &track[i]) < 0) { + if (cdr_underrun(usalp)) { + errmsgno(EX_BAD, + "The current problem looks like a buffer underrun.\n"); + if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) + errmsgno(EX_BAD, "Try to use 'driveropts=burnfree'.\n"); + else { + errmsgno(EX_BAD, "It looks like 'driveropts=burnfree' does not work for this drive.\n"); + errmsgno(EX_BAD, "Please report.\n"); + } + + errmsgno(EX_BAD, + "Make sure that you are root, enable DMA and check your HW/OS set up.\n"); + } else { + errmsgno(EX_BAD, "A write error occured.\n"); + errmsgno(EX_BAD, "Please properly read the error message above.\n"); + } + errs++; + sleep(5); + unit_ready(usalp); + (*dp->cdr_close_track)(usalp, dp, &track[i]); + break; + } + if ((*dp->cdr_close_track)(usalp, dp, &track[i]) < 0) { + /* + * Check for "Dummy blocks added" message first. + */ + if (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST || + usal_sense_code(usalp) != 0xB5) { + errmsgno(EX_BAD, "Cannot close track.\n"); + errs++; + break; + } + } + } +fix_it: + if (gettimeofday(&stoptime, (struct timezone *)0) < 0) + errmsg("Cannot get stop time\n"); + cdrstats(dp); + + if (flags & F_RAW) { + if (lverbose) { + printf("Writing Leadout...\n"); + flush(); + } + write_leadout(usalp, dp, track); + } + if ((flags & F_NOFIX) == 0) { + if (lverbose) { + printf("Fixating...\n"); + flush(); + } + if ((*dp->cdr_fixate)(usalp, dp, track) < 0) { + /* + * Ignore fixating errors in dummy mode. + */ + if ((flags & F_DUMMY) == 0) { + errmsgno(EX_BAD, "Cannot fixate disk.\n"); + errs++; + } + } + if (gettimeofday(&fixtime, (struct timezone *)0) < 0) + errmsg("Cannot get fix time\n"); + if (lverbose) + prtimediff("Fixating time: ", &stoptime, &fixtime); + } + if ((dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) { + dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT; + (*dp->cdr_stats)(usalp, dp); + } + if ((flags & (F_RAW|F_EJECT)) == F_RAW) { + /* + * Most drives seem to forget to reread the TOC from disk + * if they are in RAW mode. + */ + usalp->silent++; + if (read_tochdr(usalp, dp, NULL, NULL) < 0) { + usalp->silent--; + if ((flags & F_DUMMY) == 0) + reload_media(usalp, dp); + } else { + usalp->silent--; + } + } + +restore_it: + /* + * Try to restore the old sector size and stop FIFO. + */ + kill_faio(); + comexit(errs?-2:0); + return (0); +} + +static int +gracewait(cdr_t *dp, BOOL *didgracep) +{ + int i; + BOOL didgrace = FALSE; + + if (didgracep) + didgrace = *didgracep; + + if(warn_minisize>=0) { + fprintf(stderr, "\nWARNING: found a microscopic small track size (%lld bytes).\n" + " Do you really want to write this image? Press Ctrl-C to abort...\n\n", + warn_minisize); + gracetime+=20; + } + if (gracetime < MIN_GRACE_TIME) + gracetime = MIN_GRACE_TIME; + if (gracetime > 999) + gracetime = 999; + + printf("Starting to write CD/DVD at speed %5.1f in %s%s %s mode for %s session.\n", + (float)dp->cdr_dstat->ds_wspeed, + (dp->cdr_cmdflags & F_DUMMY) ? "dummy" : "real", + (dp->cdr_cmdflags & F_FORCE) ? " force" : "", + wm2name[dp->cdr_dstat->ds_wrmode], + (dp->cdr_cmdflags & F_MULTI) ? "multi" : "single"); + if (didgrace) { + printf("No chance to quit anymore."); + goto grace_done; + } + printf("Last chance to quit, starting %s write in %4d seconds.", + (dp->cdr_cmdflags & F_DUMMY)?"dummy":"real", gracetime); + flush(); + signal(SIGINT, intr); + signal(SIGHUP, intr); + signal(SIGTERM, intr); + + for (i = gracetime; --i >= 0; ) { + sleep(1); + if (didintr) { + printf("\n"); + excdr(SIGINT, &exargs); + signal(SIGINT, SIG_DFL); + kill(getpid(), SIGINT); + /* + * In case kill() did not work ;-) + */ + if (didgracep) + *didgracep = FALSE; + return (-1); + } + printf("\b\b\b\b\b\b\b\b\b\b\b\b\b%4d seconds.", i); + flush(); + } +grace_done: + printf(" Operation starts."); + flush(); + signal(SIGINT, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGINT, intfifo); + signal(SIGHUP, intfifo); + signal(SIGTERM, intfifo); + printf("\n"); + + if (didgracep) + *didgracep = TRUE; + return (0); +} + +static void +cdrstats(cdr_t *dp) +{ + float secsps = 75.0; + int nsecs; + float fspeed; + struct timeval tcur; + struct timeval tlast; + BOOL nostop = FALSE; + + if (starttime.tv_sec == 0) + return; + + if (stoptime.tv_sec == 0) { + gettimeofday(&stoptime, (struct timezone *)0); + nostop = TRUE; + } + + if ((dp->cdr_dstat->ds_cdrflags & RF_DID_STAT) != 0) + return; + dp->cdr_dstat->ds_cdrflags |= RF_DID_STAT; + + if (lverbose == 0) + return; + + if (dp->cdr_cmdflags & F_FIX) + return; + + if ((dp->cdr_cmdflags & (F_WRITE|F_BLANK)) == F_BLANK) + return; + + tlast = wstarttime; + tcur = stoptime; + + prtimediff("Writing time: ", &starttime, &stoptime); + + nsecs = dp->cdr_dstat->ds_endsec - dp->cdr_dstat->ds_startsec; + + if (dp->cdr_dstat->ds_flags & DSF_DVD) + secsps = 676.27; + + tlast.tv_sec = tcur.tv_sec - tlast.tv_sec; + tlast.tv_usec = tcur.tv_usec - tlast.tv_usec; + while (tlast.tv_usec < 0) { + tlast.tv_usec += 1000000; + tlast.tv_sec -= 1; + } + if (!nostop && nsecs != 0 && dp->cdr_dstat->ds_endsec > 0) { + /* + * May not be known (e.g. cdrecord -) + * + * XXX if we later allow this code to know how much has + * XXX actually been written, then we may remove the + * XXX dependance from nostop & nsecs != 0 + */ + fspeed = (nsecs / secsps) / + (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001); + if (fspeed > 999.0) + fspeed = 999.0; + if (dp->is_dvd) fspeed /= 9; + printf("Average write speed %5.1fx.\n", fspeed); + } + + if (dp->cdr_dstat->ds_minbuf <= 100) { + printf("Min drive buffer fill was %u%%\n", + (unsigned int)dp->cdr_dstat->ds_minbuf); + } + if (dp->cdr_dstat->ds_buflow > 0) { + printf("Total of %ld possible drive buffer underruns predicted.\n", + (long)dp->cdr_dstat->ds_buflow); + } +} + +/* + * Short usage + */ +static void +susage(int ret) +{ + fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname()); + fprintf(stderr, "\nUse\t%s -help\n", get_progname()); + fprintf(stderr, "to get a list of valid options.\n"); + fprintf(stderr, "\nUse\t%s blank=help\n", get_progname()); + fprintf(stderr, "to get a list of valid blanking options.\n"); + fprintf(stderr, "\nUse\t%s dev=b,t,l driveropts=help -checkdrive\n", get_progname()); + fprintf(stderr, "to get a list of drive specific options.\n"); + fprintf(stderr, "\nUse\t%s dev=help\n", get_progname()); + fprintf(stderr, "to get a list of possible SCSI transport specifiers.\n"); + exit(ret); + /* NOTREACHED */ +} + +static void +usage(int excode) +{ + fprintf(stderr, "Usage: %s [options] track1...trackn\n", get_progname()); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t-version print version information and exit\n"); + fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n"); + fprintf(stderr, "\tgracetime=# set the grace time before starting to write to #.\n"); + 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-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, "\tdriver=name user supplied driver name, use with extreme care\n"); + fprintf(stderr, "\tdriveropts=opt a comma separated list of driver specific options\n"); + fprintf(stderr, "\t-setdropts set driver specific options and exit\n"); + fprintf(stderr, "\t-checkdrive check if a driver for the drive is present\n"); + fprintf(stderr, "\t-prcap print drive capabilities for MMC compliant drives\n"); + fprintf(stderr, "\t-inq do an inquiry for the drive and exit\n"); + fprintf(stderr, "\t-scanbus scan the SCSI and IDE buses and exit\n"); + fprintf(stderr, "\t-reset reset the SCSI bus with the cdrecorder (if possible)\n"); + fprintf(stderr, "\t-abort send an abort sequence to the drive (may help if hung)\n"); + fprintf(stderr, "\t-overburn allow to write more than the official size of a medium\n"); + fprintf(stderr, "\t-ignsize ignore the known size of a medium (may cause problems)\n"); + fprintf(stderr, "\t-useinfo use *.inf files to overwrite audio options.\n"); + fprintf(stderr, "\tspeed=# set speed of drive\n"); + fprintf(stderr, "\tblank=type blank a CD-RW disc (see blank=help)\n"); + fprintf(stderr, "\t-format format a CD-RW/DVD-RW/DVD+RW disc\n"); + fprintf(stderr, "\tformattype=# select the format method for DVD+RW disc\n"); +#ifdef FIFO + fprintf(stderr, "\tfs=# Set fifo size to # (0 to disable, default is %ld MB)\n", + DEFAULT_FIFOSIZE/(1024L*1024L)); +#endif + fprintf(stderr, "\tts=# set maximum transfer size for a single SCSI command\n"); + fprintf(stderr, "\t-load load the disk and exit (works only with tray loader)\n"); + fprintf(stderr, "\t-lock load and lock the disk and exit (works only with tray loader)\n"); + fprintf(stderr, "\t-eject eject the disk after doing the work\n"); + fprintf(stderr, "\t-dummy do everything with laser turned off\n"); + fprintf(stderr, "\t-msinfo retrieve multi-session info for genisoimage\n"); + fprintf(stderr, "\t-msifile=path run -msinfo and copy output to file\n"); + fprintf(stderr, "\t-toc retrieve and print TOC/PMA data\n"); + fprintf(stderr, "\t-atip retrieve and print ATIP data\n"); + fprintf(stderr, "\t-multi generate a TOC that allows multi session\n"); + fprintf(stderr, "\t In this case default track type is CD-ROM XA mode 2 form 1 - 2048 bytes\n"); + fprintf(stderr, "\t-fix fixate a corrupt or unfixated disk (generate a TOC)\n"); + fprintf(stderr, "\t-nofix do not fixate disk after writing tracks\n"); + fprintf(stderr, "\t-waiti wait until input is available before opening SCSI\n"); + fprintf(stderr, "\t-immed Try to use the SCSI IMMED flag with certain long lasting commands\n"); + fprintf(stderr, "\t-force force to continue on some errors to allow blanking bad disks\n"); + fprintf(stderr, "\t-tao Write disk in TAO mode.\n"); + fprintf(stderr, "\t-dao Write disk in SAO mode.\n"); + fprintf(stderr, "\t-sao Write disk in SAO mode.\n"); + fprintf(stderr, "\t-raw Write disk in RAW mode.\n"); + fprintf(stderr, "\t-raw96r Write disk in RAW/RAW96R mode.\n"); + fprintf(stderr, "\t-raw96p Write disk in RAW/RAW96P mode.\n"); + fprintf(stderr, "\t-raw16 Write disk in RAW/RAW16 mode.\n"); +#ifdef CLONE_WRITE + fprintf(stderr, "\t-clone Write disk in clone write mode.\n"); +#endif + fprintf(stderr, "\ttsize=# Length of valid data in next track\n"); + fprintf(stderr, "\tpadsize=# Amount of padding for next track\n"); + fprintf(stderr, "\tpregap=# Amount of pre-gap sectors before next track\n"); + fprintf(stderr, "\tdefpregap=# Amount of pre-gap sectors for all but track #1\n"); + fprintf(stderr, "\tmcn=text Set the media catalog number for this CD to 'text'\n"); + fprintf(stderr, "\tisrc=text Set the ISRC number for the next track to 'text'\n"); + fprintf(stderr, "\tindex=list Set the index list for the next track to 'list'\n"); + fprintf(stderr, "\t-text Write CD-Text from information from *.inf or *.cue files\n"); + fprintf(stderr, "\ttextfile=name Set the file with CD-Text data to 'name'\n"); + fprintf(stderr, "\tcuefile=name Set the file with CDRWIN CUE data to 'name'\n"); + + fprintf(stderr, "\t-audio Subsequent tracks are CD-DA audio tracks\n"); + fprintf(stderr, "\t-data Subsequent tracks are CD-ROM data mode 1 - 2048 bytes (default)\n"); + fprintf(stderr, "\t-mode2 Subsequent tracks are CD-ROM data mode 2 - 2336 bytes\n"); + fprintf(stderr, "\t-xa Subsequent tracks are CD-ROM XA mode 2 form 1 - 2048 bytes\n"); + fprintf(stderr, "\t-xa1 Subsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n"); + fprintf(stderr, "\t-xa2 Subsequent tracks are CD-ROM XA mode 2 form 2 - 2324 bytes\n"); + fprintf(stderr, "\t-xamix Subsequent tracks are CD-ROM XA mode 2 form 1/2 - 2332 bytes\n"); + fprintf(stderr, "\t-cdi Subsequent tracks are CDI tracks\n"); + fprintf(stderr, "\t-isosize Use iso9660 file system size for next data track\n"); + fprintf(stderr, "\t-preemp Audio tracks are mastered with 50/15 microseconds preemphasis\n"); + fprintf(stderr, "\t-nopreemp Audio tracks are mastered with no preemphasis (default)\n"); + fprintf(stderr, "\t-copy Audio tracks have unlimited copy permission\n"); + fprintf(stderr, "\t-nocopy Audio tracks may only be copied once for personal use (default)\n"); + fprintf(stderr, "\t-scms Audio tracks will not have any copy permission at all\n"); + fprintf(stderr, "\t-pad Pad data tracks with %d zeroed sectors\n", PAD_SECS); + fprintf(stderr, "\t Pad audio tracks to a multiple of %d bytes\n", AUDIO_SEC_SIZE); + fprintf(stderr, "\t-nopad Do not pad data tracks (default)\n"); + fprintf(stderr, "\t-shorttrack Subsequent tracks may be non Red Book < 4 seconds if in SAO or RAW mode\n"); + fprintf(stderr, "\t-noshorttrack Subsequent tracks must be >= 4 seconds\n"); + fprintf(stderr, "\t-swab Audio data source is byte-swapped (little-endian/Intel)\n"); + fprintf(stderr, "The type of the first track is used for the toc type.\n"); + fprintf(stderr, "Currently only form 1 tracks are supported.\n"); + exit(excode); +} + +static void +blusage(int ret) +{ + fprintf(stderr, "Blanking options:\n"); + fprintf(stderr, "\tall\t\tblank the entire disk\n"); + fprintf(stderr, "\tdisc\t\tblank the entire disk\n"); + fprintf(stderr, "\tdisk\t\tblank the entire disk\n"); + fprintf(stderr, "\tfast\t\tminimally blank the entire disk (PMA, TOC, pregap)\n"); + fprintf(stderr, "\tminimal\t\tminimally blank the entire disk (PMA, TOC, pregap)\n"); + fprintf(stderr, "\ttrack\t\tblank a track\n"); + fprintf(stderr, "\tunreserve\tunreserve a track\n"); + fprintf(stderr, "\ttrtail\t\tblank a track tail\n"); + fprintf(stderr, "\tunclose\t\tunclose last session\n"); + fprintf(stderr, "\tsession\t\tblank last session\n"); + + exit(ret); + /* NOTREACHED */ +} + +static void +formattypeusage(int ret) +{ + fprintf(stderr, "Formating options:\n"); + fprintf(stderr, "\tfull\t\tstandard formating\n"); + fprintf(stderr, "\tbackground\t\tbackground formating\n"); + fprintf(stderr, "\tforce\t\tforce reformat\n"); + + exit(ret); + /* NOTREACHED */ +} + +/* ARGSUSED */ +static void +intr(int sig) +{ + sig = 0; /* Fake usage for gcc */ + + signal(SIGINT, intr); + + didintr++; +} + +static void +catchsig(int sig) +{ + signal(sig, catchsig); +} + +static int +scsi_cb(void *arg) +{ + comexit(EX_BAD); + /* NOTREACHED */ + return (0); /* Keep lint happy */ +} + +static void +intfifo(int sig) +{ + errmsgno(EX_BAD, "Caught interrupt.\n"); + if (exargs.usalp) { + SCSI *usalp = exargs.usalp; + + if (usalp->running) { + if (usalp->cb_fun != NULL) { + comerrno(EX_BAD, "Second interrupt. Doing hard abort.\n"); + /* NOTREACHED */ + } + usalp->cb_fun = scsi_cb; + usalp->cb_arg = &exargs; + return; + } + } + comexit(sig); +} + +/* ARGSUSED */ +static void +exscsi(int excode, void *arg) +{ + struct exargs *exp = (struct exargs *)arg; + + /* + * Try to restore the old sector size. + */ + if (exp != NULL && exp->exflags == 0) { + if (exp->usalp->running) { + return; + } + /* + * flush cache is not supported by CD-ROMs avoid prob with -toc + */ + exp->usalp->silent++; + scsi_flush_cache(exp->usalp, FALSE); + (*exp->dp->cdr_abort_session)(exp->usalp, exp->dp); + exp->usalp->silent--; + set_secsize(exp->usalp, exp->old_secsize); + unload_media(exp->usalp, exp->dp, exp->flags); + + exp->exflags++; /* Make sure that it only get called once */ + } +} + +static void +excdr(int excode, void *arg) +{ + struct exargs *exp = (struct exargs *)arg; + + exscsi(excode, arg); + + cdrstats(exp->dp); + if ((exp->dp->cdr_dstat->ds_cdrflags & RF_DID_CDRSTAT) == 0) { + exp->dp->cdr_dstat->ds_cdrflags |= RF_DID_CDRSTAT; + (*exp->dp->cdr_stats)(exp->usalp, exp->dp); + } + +#ifdef FIFO + kill_faio(); + wait_faio(); + if (debug || lverbose) + fifo_stats(); +#endif +} + +int +read_buf(int f, char *bp, int size) +{ + char *p = bp; + int amount = 0; + int n; + + do { + do { + n = read(f, p, size-amount); + } while (n < 0 && (geterrno() == EAGAIN || geterrno() == EINTR)); + if (n < 0) + return (n); + amount += n; + p += n; + + } while (amount < size && n > 0); + return (amount); +} + +int +fill_buf(int f, track_t *trackp, long secno, char *bp, int size) +{ + int amount = 0; + int nsecs; + int rsize; + int rmod; + int readoffset = 0; + + nsecs = size / trackp->secsize; + if (nsecs < trackp->secspt) { + /* + * Clear buffer to prepare for last transfer. + * Make sure that a partial sector ends with NULs + */ + fillbytes(bp, trackp->secspt * trackp->secsize, '\0'); + } + + if (!is_raw(trackp)) { + amount = read_buf(f, bp, size); + if (amount != size) { + if (amount < 0) + return (amount); + /* + * We got less than expected, clear rest of buf. + */ + fillbytes(&bp[amount], size-amount, '\0'); + } + if (is_swab(trackp)) + swabbytes(bp, amount); + return (amount); + } + + rsize = nsecs * trackp->isecsize; + rmod = size % trackp->secsize; + if (rmod > 0) { + rsize += rmod; + nsecs++; + } + + readoffset = trackp->dataoff; + amount = read_buf(f, bp + readoffset, rsize); + if (is_swab(trackp)) + swabbytes(bp + readoffset, amount); + + if (trackp->isecsize == 2448 && trackp->secsize == 2368) + subrecodesecs(trackp, (Uchar *)bp, secno, nsecs); + + scatter_secs(trackp, bp + readoffset, nsecs); + + if (amount != rsize) { + if (amount < 0) + return (amount); + /* + * We got less than expected, clear rest of buf. + */ + fillbytes(&bp[amount], rsize-amount, '\0'); + nsecs = amount / trackp->isecsize; + rmod = amount % trackp->isecsize; + amount = nsecs * trackp->secsize; + if (rmod > 0) { + nsecs++; + amount += rmod; + } + } else { + amount = size; + } + if ((trackp->sectype & ST_MODE_RAW) == 0) { + encsectors(trackp, (Uchar *)bp, secno, nsecs); + fillsubch(trackp, (Uchar *)bp, secno, nsecs); + } else { + scrsectors(trackp, (Uchar *)bp, secno, nsecs); + } + return (amount); +} + +int +get_buf(int f, track_t *trackp, long secno, char **bpp, int size) +{ + if (fs > 0) { +/* return (faio_read_buf(f, *bpp, size));*/ + return (faio_get_buf(f, bpp, size)); + } else { + return (fill_buf(f, trackp, secno, *bpp, size)); + } +} + +int +write_secs(SCSI *usalp, cdr_t *dp, char *bp, long startsec, int bytespt, + int secspt, BOOL islast) +{ + int amount; + +again: + usalp->silent++; + amount = (*dp->cdr_write_trackdata)(usalp, bp, startsec, bytespt, secspt, islast); + usalp->silent--; + if (amount < 0) { + if (scsi_in_progress(usalp)) { + /* + * If we sleep too long, the drive buffer is empty + * before we start filling it again. The max. CD speed + * is ~ 10 MB/s (52x RAW writing). The max. DVD speed + * is ~ 25 MB/s (18x DVD 1385 kB/s). + * With 10 MB/s, a 1 MB buffer empties within 100ms. + * With 25 MB/s, a 1 MB buffer empties within 40ms. + */ + if ((dp->cdr_dstat->ds_flags & DSF_DVD) == 0) { + usleep(60000); + } else { +#ifndef _SC_CLK_TCK + usleep(20000); +#else + if (sysconf(_SC_CLK_TCK) < 100) + usleep(20000); + else + usleep(10000); + +#endif + } + goto again; + } + return (-1); + } + return (amount); +} + +static int +write_track_data(SCSI *usalp, cdr_t *dp, track_t *trackp) +{ + int track = trackp->trackno; + int f = -1; + int isaudio; + long startsec; + Llong bytes_read = 0; + Llong bytes = 0; + Llong savbytes = 0; + int count; + Llong tracksize; + int secsize; + int secspt; + int bytespt; + int bytes_to_read; + long amount; + int pad; + BOOL neednl = FALSE; + BOOL islast = FALSE; + char *bp = buf; + struct timeval tlast; + struct timeval tcur; + float secsps = 75.0; +long bsize; +long bfree; +#define BCAP +#ifdef BCAP +int per = 0; +#ifdef XBCAP +int oper = -1; +#endif +#endif + + if (dp->cdr_dstat->ds_flags & DSF_DVD) + secsps = 676.27; + + usalp->silent++; + if ((*dp->cdr_buffer_cap)(usalp, &bsize, &bfree) < 0) + bsize = -1L; + if (bsize == 0) /* If we have no (known) buffer, we cannot */ + bsize = -1L; /* retrieve the buffer fill ratio */ + usalp->silent--; + + + if (is_packet(trackp)) /* XXX Ugly hack for now */ + return (write_packet_data(usalp, dp, trackp)); + + if (trackp->xfp != NULL) + f = xfileno(trackp->xfp); + + isaudio = is_audio(trackp); + tracksize = trackp->tracksize; + startsec = trackp->trackstart; + + secsize = trackp->secsize; + secspt = trackp->secspt; + bytespt = secsize * secspt; + + pad = !isaudio && is_pad(trackp); /* Pad only data tracks */ + + if (debug) { + printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n", + secsize, secspt, bytespt, isaudio, pad); + } + + if (lverbose) { + if (tracksize > 0) + printf("\rTrack %02d: 0 of %4lld MB written.", + track, tracksize >> 20); + else + printf("\rTrack %02d: 0 MB written.", track); + flush(); + neednl = TRUE; + } + + gettimeofday(&tlast, (struct timezone *)0); + do { + bytes_to_read = bytespt; + if (tracksize > 0) { + if ((tracksize - bytes_read) > bytespt) + bytes_to_read = bytespt; + else + bytes_to_read = tracksize - bytes_read; + } + count = get_buf(f, trackp, startsec, &bp, bytes_to_read); + + if (count < 0) + comerr("read error on input file\n"); + if (count == 0) + break; + bytes_read += count; + if (tracksize >= 0 && bytes_read >= tracksize) { + count -= bytes_read - tracksize; + /* + * Paranoia: tracksize is known (trackp->tracksize >= 0) + * At this point, trackp->padsize should alway be set + * if the tracksize is less than 300 sectors. + */ + if (trackp->padsecs == 0 && + (is_shorttrk(trackp) || (bytes_read/secsize) >= 300)) + islast = TRUE; + } + + if (count < bytespt) { + if (debug) { + printf("\nNOTICE: reducing block size for last record.\n"); + neednl = FALSE; + } + + if ((amount = count % secsize) != 0) { + amount = secsize - amount; + count += amount; + printf("\nWARNING: padding up to secsize.\n"); + neednl = FALSE; + } + bytespt = count; + secspt = count / secsize; + /* + * If tracksize is not known (trackp->tracksize < 0) + * we may need to set trackp->padsize + * if the tracksize is less than 300 sectors. + */ + if (trackp->padsecs == 0 && + (is_shorttrk(trackp) || (bytes_read/secsize) >= 300)) + islast = TRUE; + } + + amount = write_secs(usalp, dp, bp, startsec, bytespt, secspt, islast); + if (amount < 0) { + printf("%swrite track data: error after %lld bytes\n", + neednl?"\n":"", bytes); + return (-1); + } + bytes += amount; + startsec += amount / secsize; + + if (lverbose && (bytes >= (savbytes + 0x100000))) { + int fper; + int nsecs = (bytes - savbytes) / secsize; + float fspeed; + + gettimeofday(&tcur, (struct timezone *)0); + printf("\rTrack %02d: %4lld", track, bytes >> 20); + if (tracksize > 0) + printf(" of %4lld MB", tracksize >> 20); + else + printf(" MB"); + printf(" written"); + fper = fifo_percent(TRUE); + if (fper >= 0) + printf(" (fifo %3d%%)", fper); +#ifdef BCAP + if (bsize > 0) { /* buffer size known */ + usalp->silent++; + per = (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree); + usalp->silent--; + if (per >= 0) { + per = 100*(bsize - bfree) / bsize; + if ((bsize - bfree) <= amount || per <= 5) + dp->cdr_dstat->ds_buflow++; + if (per < (int)dp->cdr_dstat->ds_minbuf && + (startsec*secsize) > bsize) { + dp->cdr_dstat->ds_minbuf = per; + } + printf(" [buf %3d%%]", per); +#ifdef BCAPDBG + printf(" %3ld %3ld", bsize >> 10, bfree >> 10); +#endif + } + } +#endif + + tlast.tv_sec = tcur.tv_sec - tlast.tv_sec; + tlast.tv_usec = tcur.tv_usec - tlast.tv_usec; + while (tlast.tv_usec < 0) { + tlast.tv_usec += 1000000; + tlast.tv_sec -= 1; + } + fspeed = (nsecs / secsps) / + (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001); + if (fspeed > 999.0) + fspeed = 999.0; +#ifdef BCAP + if (bsize > 0 && per > dminbuf && + dp->cdr_dstat->ds_cdrflags & RF_WR_WAIT) { + int wsecs = (per-dminbuf)*(bsize/secsize)/100; + int msecs = 0x100000/secsize; + int wt; + int mt; + int s = dp->cdr_dstat->ds_dr_cur_wspeed; + + + if (s <= 0) { + if (dp->cdr_dstat->ds_flags & DSF_DVD) + s = 4; + else + s = 50; + } + if (wsecs > msecs) /* Less that 1 MB */ + wsecs = msecs; + wt = wsecs * 1000 / secsps / fspeed; + mt = (per-dminbuf)*(bsize/secsize)/100 * 1000 / secsps/s; + + if (wt > mt) + wt = mt; + if (wt > 1000) /* Max 1 second */ + wt = 1000; + if (wt < 20) /* Min 20 ms */ + wt = 0; + + if (xdebug) + printf(" |%3d %4dms %5dms|", wsecs, wt, mt); + else + printf(" |%3d %4dms|", wsecs, wt); + if (wt > 0) + usleep(wt*1000); + } +#endif + if (dp->is_dvd) fspeed /= 9; + printf(" %5.1fx", fspeed); + printf("."); + savbytes = (bytes >> 20) << 20; + flush(); + neednl = TRUE; + tlast = tcur; + } +#ifdef XBCAP + if (bsize > 0) { /* buffer size known */ + (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree); + per = 100*(bsize - bfree) / bsize; + if (per != oper) + printf("[buf %3d%%] %3ld %3ld\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", + per, bsize >> 10, bfree >> 10); + oper = per; + flush(); + } + + +#endif + } while (tracksize < 0 || bytes_read < tracksize); + + if (!is_shorttrk(trackp) && (bytes / secsize) < 300) { + /* + * If tracksize is not known (trackp->tracksize < 0) or + * for some strange reason we did not set padsecs properly + * we may need to modify trackp->padsecs if + * tracksize+padsecs is less than 300 sectors. + */ + if ((trackp->padsecs + (bytes / secsize)) < 300) + trackp->padsecs = 300 - (bytes / secsize); + } + if (trackp->padsecs > 0) { + Llong padbytes; + + /* + * pad_track() is based on secsize. Compute the amount of bytes + * assumed by pad_track(). + */ + padbytes = (Llong)trackp->padsecs * secsize; + + if (neednl) { + printf("\n"); + neednl = FALSE; + } + if ((padbytes >> 20) > 0) { + neednl = TRUE; + } else if (lverbose) { + printf("Track %02d: writing %3lld KB of pad data.\n", + track, (Llong)(padbytes >> 10)); + neednl = FALSE; + } + pad_track(usalp, dp, trackp, startsec, padbytes, + TRUE, &savbytes); + bytes += savbytes; + startsec += savbytes / secsize; + } + printf("%sTrack %02d: Total bytes read/written: %lld/%lld (%lld sectors).\n", + neednl?"\n":"", track, bytes_read, bytes, bytes/secsize); + flush(); + return (0); +} + +int +pad_track(SCSI *usalp, cdr_t *dp, track_t *trackp, long startsec, Llong amt, + BOOL dolast, Llong *bytesp) +{ + int track = trackp->trackno; + Llong bytes = 0; + Llong savbytes = 0; + Llong padsize = amt; + int secsize; + int secspt; + int bytespt; + int amount; + BOOL neednl = FALSE; + BOOL islast = FALSE; + struct timeval tlast; + struct timeval tcur; + float secsps = 75.0; +long bsize; +long bfree; +#define BCAP +#ifdef BCAP +int per; +#ifdef XBCAP +int oper = -1; +#endif +#endif + + if (dp->cdr_dstat->ds_flags & DSF_DVD) + secsps = 676.27; + + usalp->silent++; + if ((*dp->cdr_buffer_cap)(usalp, &bsize, &bfree) < 0) + bsize = -1L; + if (bsize == 0) /* If we have no (known) buffer, we cannot */ + bsize = -1L; /* retrieve the buffer fill ratio */ + usalp->silent--; + + secsize = trackp->secsize; + secspt = trackp->secspt; + bytespt = secsize * secspt; + + fillbytes(buf, bytespt, '\0'); + + if ((amt >> 20) > 0) { + printf("\rTrack %02d: 0 of %4lld MB pad written.", + track, amt >> 20); + flush(); + } + gettimeofday(&tlast, (struct timezone *)0); + do { + if (amt < bytespt) { + bytespt = roundup(amt, secsize); + secspt = bytespt / secsize; + } + if (dolast && (amt - bytespt) <= 0) + islast = TRUE; + + if (is_raw(trackp)) { + encsectors(trackp, (Uchar *)buf, startsec, secspt); + fillsubch(trackp, (Uchar *)buf, startsec, secspt); + } + + amount = write_secs(usalp, dp, buf, startsec, bytespt, secspt, islast); + if (amount < 0) { + printf("%swrite track pad data: error after %lld bytes\n", + neednl?"\n":"", bytes); + if (bytesp) + *bytesp = bytes; +(*dp->cdr_buffer_cap)(usalp, (long *)0, (long *)0); + return (-1); + } + amt -= amount; + bytes += amount; + startsec += amount / secsize; + + if (lverbose && (bytes >= (savbytes + 0x100000))) { + int nsecs = (bytes - savbytes) / secsize; + float fspeed; + + gettimeofday(&tcur, (struct timezone *)0); + printf("\rTrack %02d: %4lld", track, bytes >> 20); + if (padsize > 0) + printf(" of %4lld MB", padsize >> 20); + else + printf(" MB"); + printf(" pad written"); + savbytes = (bytes >> 20) << 20; + +#ifdef BCAP + if (bsize > 0) { /* buffer size known */ + usalp->silent++; + per = (*dp->cdr_buffer_cap)(usalp, (long *)0, &bfree); + usalp->silent--; + if (per >= 0) { + per = 100*(bsize - bfree) / bsize; + if ((bsize - bfree) <= amount || per <= 5) + dp->cdr_dstat->ds_buflow++; + if (per < (int)dp->cdr_dstat->ds_minbuf && + (startsec*secsize) > bsize) { + dp->cdr_dstat->ds_minbuf = per; + } + printf(" [buf %3d%%]", per); +#ifdef BCAPDBG + printf(" %3ld %3ld", bsize >> 10, bfree >> 10); +#endif + } + } +#endif + tlast.tv_sec = tcur.tv_sec - tlast.tv_sec; + tlast.tv_usec = tcur.tv_usec - tlast.tv_usec; + while (tlast.tv_usec < 0) { + tlast.tv_usec += 1000000; + tlast.tv_sec -= 1; + } + fspeed = (nsecs / secsps) / + (tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001); + if (fspeed > 999.0) + fspeed = 999.0; + printf(" %5.1fx", fspeed); + printf("."); + flush(); + neednl = TRUE; + tlast = tcur; + } + } while (amt > 0); + + if (bytesp) + *bytesp = bytes; + if (bytes == 0) + return (0); + return (bytes > 0 ? 1:-1); +} + +#ifdef USE_WRITE_BUF +int +write_buf(SCSI *usalp, cdr_t *dp, track_t *trackp, char *bp, long startsec, + Llong amt, int secsize, BOOL dolast, Llong *bytesp) +{ + int track = trackp->trackno; + Llong bytes = 0; + Llong savbytes = 0; +/* int secsize;*/ + int secspt; + int bytespt; + int amount; + BOOL neednl = FALSE; + BOOL islast = FALSE; + +/* secsize = trackp->secsize;*/ +/* secspt = trackp->secspt;*/ + + secspt = bufsize/secsize; + secspt = min(255, secspt); + bytespt = secsize * secspt; + +/* fillbytes(buf, bytespt, '\0');*/ + + if ((amt >> 20) > 0) { + printf("\rTrack %02d: 0 of %4ld MB pad written.", + track, amt >> 20); + flush(); + } + do { + if (amt < bytespt) { + bytespt = roundup(amt, secsize); + secspt = bytespt / secsize; + } + if (dolast && (amt - bytespt) <= 0) + islast = TRUE; + + amount = write_secs(usalp, dp, bp, startsec, bytespt, secspt, islast); + if (amount < 0) { + printf("%swrite track data: error after %ld bytes\n", + neednl?"\n":"", bytes); + if (bytesp) + *bytesp = bytes; +(*dp->cdr_buffer_cap)(usalp, (long *)0, (long *)0); + return (-1); + } + amt -= amount; + bytes += amount; + startsec += amount / secsize; + + if (lverbose && (bytes >= (savbytes + 0x100000))) { + printf("\rTrack %02d: %3ld", track, bytes >> 20); + savbytes = (bytes >> 20) << 20; + flush(); + neednl = TRUE; + } + } while (amt > 0); + + if (bytesp) + *bytesp = bytes; + return (bytes); +} +#endif /* USE_WRITE_BUF */ + +static void +printdata(int track, track_t *trackp) +{ + if (trackp->itracksize >= 0) { + printf("Track %02d: data %4lld MB ", + track, (Llong)(trackp->itracksize >> 20)); + } else { + printf("Track %02d: data unknown length", + track); + } + if (trackp->padsecs > 0) { + Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize; + + if ((padbytes >> 20) > 0) + printf(" padsize: %4lld MB", (Llong)(padbytes >> 20)); + else + printf(" padsize: %4lld KB", (Llong)(padbytes >> 10)); + } + if (trackp->pregapsize != (trackp->flags & TI_DVD)? 0 : 150) { + printf(" pregapsize: %3ld", trackp->pregapsize); + } + if (xdebug) + printf(" START: %ld SECTORS: %ld INDEX0 %ld", + trackp->trackstart, trackp->tracksecs, trackp->index0start); + printf("\n"); +} + +static void +printaudio(int track, track_t *trackp) +{ + if (trackp->itracksize >= 0) { + printf("Track %02d: audio %4lld MB (%02d:%02d.%02d) %spreemp%s%s", + track, (Llong)(trackp->itracksize >> 20), + minutes(trackp->itracksize), + seconds(trackp->itracksize), + hseconds(trackp->itracksize), + is_preemp(trackp) ? "" : "no ", + is_swab(trackp) ? " swab":"", + ((trackp->itracksize < 300L*trackp->isecsize) || + (trackp->itracksize % trackp->isecsize)) && + is_pad(trackp) ? " pad" : ""); + } else { + printf("Track %02d: audio unknown length %spreemp%s%s", + track, is_preemp(trackp) ? "" : "no ", + is_swab(trackp) ? " swab":"", + (trackp->itracksize % trackp->isecsize) && is_pad(trackp) ? " pad" : ""); + } + if (is_scms(trackp)) + printf(" scms"); + else if (is_copy(trackp)) + printf(" copy"); + else + printf(" "); + + if (trackp->padsecs > 0) { + Llong padbytes = (Llong)trackp->padsecs * trackp->isecsize; + + if ((padbytes >> 20) > 0) + printf(" padsize: %4lld MB", (Llong)(padbytes >> 20)); + else + printf(" padsize: %4lld KB", (Llong)(padbytes >> 10)); + printf(" (%02d:%02d.%02d)", + Sminutes(trackp->padsecs), + Sseconds(trackp->padsecs), + Shseconds(trackp->padsecs)); + } + if (trackp->pregapsize != ((trackp->flags & TI_DVD)? 0 : 150) || xdebug > 0) { + printf(" pregapsize: %3ld", trackp->pregapsize); + } + if (xdebug) + printf(" START: %ld SECTORS: %ld INDEX0 %ld", + trackp->trackstart, trackp->tracksecs, trackp->index0start); + printf("\n"); +} + +static void +checkfile(int track, track_t *trackp) +{ + if (trackp->itracksize > 0 && + is_audio(trackp) && + ((!is_shorttrk(trackp) && + (trackp->itracksize < 300L*trackp->isecsize)) || + (trackp->itracksize % trackp->isecsize)) && + !is_pad(trackp)) { + errmsgno(EX_BAD, "Bad audio track size %lld for track %02d.\n", + (Llong)trackp->itracksize, track); + errmsgno(EX_BAD, "Audio tracks must be at least %ld bytes and a multiple of %d.\n", + 300L*trackp->isecsize, trackp->isecsize); + + if (!is_shorttrk(trackp) && (trackp->itracksize < 300L*trackp->isecsize)) + comerrno(EX_BAD, "See -shorttrack option.\n"); + if (!is_pad(trackp) && (trackp->itracksize % trackp->isecsize)) + comerrno(EX_BAD, "See -pad option.\n"); + } + + if (lverbose == 0 && xdebug == 0) + return; + + if (is_audio(trackp)) + printaudio(track, trackp); + else + printdata(track, trackp); +} + +static int +checkfiles(int tracks, track_t *trackp) +{ + int i; + int isaudio = 1; + int starttrack = 1; + int endtrack = tracks; + + if (xdebug) { + /* + * Include Lead-in & Lead-out. + */ + starttrack--; + endtrack++; + } + for (i = starttrack; i <= endtrack; i++) { + if (!is_audio(&trackp[i])) + isaudio = 0; + if (xdebug) + printf("SECTYPE %X ", trackp[i].sectype); + checkfile(i, &trackp[i]); + } + return (isaudio); +} + +static void +setleadinout(int tracks, track_t *trackp) +{ + /* + * Set some values for track 0 (the lead-in) + */ + if (!is_clone(&trackp[0])) { + trackp[0].sectype = trackp[1].sectype; + trackp[0].dbtype = trackp[1].dbtype; + trackp[0].dataoff = trackp[1].dataoff; + + /* + * XXX Which other flags should be copied to Track 0 ? + */ + if (is_audio(&trackp[1])) + trackp[0].flags |= TI_AUDIO; + } + + /* + * Set some values for track 0xAA (the lead-out) + */ + trackp[tracks+1].pregapsize = 0; + trackp[tracks+1].isecsize = trackp[tracks].isecsize; + trackp[tracks+1].secsize = trackp[tracks].secsize; + + if (!is_clone(&trackp[0])) { + trackp[tracks+1].tracktype = trackp[tracks].tracktype; + trackp[tracks+1].sectype = trackp[tracks].sectype; + trackp[tracks+1].dbtype = trackp[tracks].dbtype; + trackp[tracks+1].dataoff = trackp[tracks].dataoff; + } + + trackp[tracks+1].flags = trackp[tracks].flags; +} + +static void +setpregaps(int tracks, track_t *trackp) +{ + int i; + int sectype; + long pregapsize; + track_t *tp; + + sectype = trackp[1].sectype; + sectype &= ST_MASK; + + for (i = 1; i <= tracks; i++) { + tp = &trackp[i]; + if (tp->pregapsize == -1L) { + tp->pregapsize = 150; /* Default CD Pre GAP*/ + if (trackp->flags & TI_DVD) { + tp->pregapsize = 0; + } else if (sectype != (tp->sectype & ST_MASK)) { + tp->pregapsize = 255; /* Pre GAP is 255 */ + tp->flags &= ~TI_PREGAP; + } + } + sectype = tp->sectype & ST_MASK; /* Save old sectype */ + } + trackp[tracks+1].pregapsize = 0; + trackp[tracks+1].index0start = 0; + + for (i = 1; i <= tracks; i++) { + /* + * index0start is set below tracksecks if this track contains + * the pregap (index 0) of the next track. + */ + trackp[i].index0start = trackp[i].tracksecs; + + pregapsize = trackp[i+1].pregapsize; + if (is_pregap(&trackp[i+1]) && pregapsize > 0) + trackp[i].index0start -= pregapsize; + } +} + +/* + * Check total size of the medium + */ +static long +checktsize(int tracks, track_t *trackp) +{ + int i; + Llong curr; + Llong total = -150; /* CD track #1 pregap compensation */ + Ullong btotal; + track_t *tp; + + if (trackp->flags & TI_DVD) + total = 0; + for (i = 1; i <= tracks; i++) { + tp = &trackp[i]; + if (!is_pregap(tp)) + total += tp->pregapsize; + + if (lverbose > 1) { + printf("track: %d start: %lld pregap: %ld\n", + i, total, tp->pregapsize); + } + tp->trackstart = total; + if (tp->itracksize >= 0) { + curr = (tp->itracksize + (tp->isecsize-1)) / tp->isecsize; + curr += tp->padsecs; + /* + * Minimum track size is 4s + */ + if (!is_shorttrk(tp) && curr < 300) + curr = 300; + if ((trackp->flags & TI_DVD) == 0) { + /* + * XXX Was passiert hier bei is_packet() ??? + */ + if (is_tao(tp) && !is_audio(tp)) { + curr += 2; + } + } + total += curr; + } else if (is_sao(tp) || is_raw(tp)) { + errmsgno(EX_BAD, "Track %d has unknown length.\n", i); + comerrno(EX_BAD, + "Use tsize= option in %s mode to specify track size.\n", + is_sao(tp) ? "SAO" : "RAW"); + } + } + tp = &trackp[i]; + tp->trackstart = total; + tp->tracksecs = 6750; /* Size of first session Lead-Out */ + if (!lverbose) + return (total); + + if (trackp->flags & TI_DVD) + btotal = (Ullong)total * 2048; + else + btotal = (Ullong)total * 2352; +/* XXX CD Sector Size ??? */ + if (tracks > 0) { + if (trackp->flags & TI_DVD) { + printf("Total size: %4llu MB = %lld sectors\n", + btotal >> 20, total); + } else { + printf("Total size: %4llu MB (%02d:%02d.%02d) = %lld sectors\n", + btotal >> 20, + minutes(btotal), + seconds(btotal), + hseconds(btotal), total); + btotal += 150 * 2352; + printf("Lout start: %4llu MB (%02d:%02d/%02d) = %lld sectors\n", + btotal >> 20, + minutes(btotal), + seconds(btotal), + frames(btotal), total); + } + } + return (total); +} + +static void +opentracks(track_t *trackp) +{ + track_t *tp; + int i; + int tracks = trackp[0].tracks; + + Llong tracksize; + int secsize; + + for (i = 1; i <= tracks; i++) { + tp = &trackp[i]; + + if (auinfosize(tp->filename, tp)) { + /* + * open stdin + */ + tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0); + } else if (strcmp("-", tp->filename) == 0) { + /* + * open stdin + */ + tp->xfp = xopen(NULL, O_RDONLY|O_BINARY, 0); + } else { + if ((tp->xfp = xopen(tp->filename, + O_RDONLY|O_BINARY, 0)) == NULL) { + comerr("Cannot open '%s'.\n", tp->filename); + } + } + + checksize(tp); + tracksize = tp->itracksize; + secsize = tp->isecsize; + if (!is_shorttrk(tp) && + tracksize > 0 && (tracksize / secsize) < 300) { + + tracksize = roundup(tracksize, secsize); + if ((tp->padsecs + + (tracksize / secsize)) < 300) { + tp->padsecs = + 300 - tracksize / secsize; + } + if (xdebug) { + printf("TRACK %d SECTORS: %ld", + i, tp->tracksecs); + printf(" pasdize %lld (%ld sectors)\n", + (Llong)tp->padsecs * secsize, + tp->padsecs); + } + } +#ifdef AUINFO + if (tp->flags & TI_USEINFO) { + auinfo(tp->filename, i, trackp); + if (lverbose > 0 && i == 1) + printf("pregap1: %ld\n", trackp[1].pregapsize); + } +#endif + /* + * tracksecks is total numbers of sectors in track (starting from + * index 0). + */ + if (tp->padsecs > 0) + tp->tracksecs += tp->padsecs; + + if (debug) { + printf("File: '%s' itracksize: %lld isecsize: %d tracktype: %d = %s sectype: %X = %s dbtype: %s flags %X\n", + tp->filename, (Llong)tp->itracksize, + tp->isecsize, + tp->tracktype & TOC_MASK, toc2name[tp->tracktype & TOC_MASK], + tp->sectype, st2name[tp->sectype & ST_MASK], db2name[tp->dbtype], tp->flags); + } + } +} + +static void +checksize(track_t *trackp) +{ + struct stat st; + Llong lsize; + int f = -1; + + if (trackp->xfp != NULL) + f = xfileno(trackp->xfp); + + /* + * If the current input file is a regular file and + * 'padsize=' has not been specified, + * use fstat() or file parser to get the size of the file. + */ + if (trackp->itracksize < 0 && (trackp->flags & TI_ISOSIZE) != 0) { + lsize = isosize(f); + trackp->itracksize = lsize; + if (trackp->itracksize != lsize) + comerrno(EX_BAD, "This OS cannot handle large ISO-9660 images.\n"); + } + if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) { + lsize = ausize(f); + trackp->itracksize = lsize; + if (trackp->itracksize != lsize) + comerrno(EX_BAD, "This OS cannot handle large audio images.\n"); + } + if (trackp->itracksize < 0 && (trackp->flags & TI_NOAUHDR) == 0) { + lsize = wavsize(f); + trackp->itracksize = lsize; + if (trackp->itracksize != lsize) + comerrno(EX_BAD, "This OS cannot handle large WAV images.\n"); + if (trackp->itracksize > 0) /* Force little endian input */ + trackp->flags |= TI_SWAB; + } + if (trackp->itracksize == AU_BAD_CODING) { + comerrno(EX_BAD, "Inappropriate audio coding in '%s'.\n", + trackp->filename); + } + if (trackp->itracksize < 0 && + fstat(f, &st) >= 0 && S_ISREG(st.st_mode)) { + trackp->itracksize = st.st_size; + } + if (trackp->itracksize >= 0) { + /* + * We do not allow cdrecord to start if itracksize is not + * a multiple of isecsize or we are allowed to pad to secsize via -pad. + * For this reason, we may safely always assume padding. + */ + trackp->tracksecs = (trackp->itracksize + trackp->isecsize -1) / trackp->isecsize; + trackp->tracksize = (trackp->itracksize / trackp->isecsize) * trackp->secsize + + trackp->itracksize % trackp->isecsize; + } else { + trackp->tracksecs = -1L; + } +} + +static BOOL +checkdsize(SCSI *usalp, cdr_t *dp, long tsize, int flags) +{ + long startsec = 0L; + long endsec = 0L; + dstat_t *dsp = dp->cdr_dstat; + int profile; + + usalp->silent++; + (*dp->cdr_next_wr_address)(usalp, (track_t *)0, &startsec); + usalp->silent--; + + /* + * This only should happen when the drive is currently in SAO mode. + * We rely on the drive being in TAO mode, a negative value for + * startsec is not correct here it may be caused by bad firmware or + * by a drive in SAO mode. In SAO mode the drive will report the + * pre-gap as part of the writable area. + */ + if (startsec < 0) + startsec = 0; + + /* + * Size limitations (sectors) for CD's: + * + * 404850 == 90 min Red book calls this the + * first negative time + * allows lead out start up to + * block 404700 + * + * 449850 == 100 min This is the first time that + * is no more representable + * in a two digit BCD number. + * allows lead out start up to + * block 449700 + * + * ~540000 == 120 min The largest CD ever made. + * + * ~650000 == 1.3 GB a Double Density (DD) CD. + */ + + endsec = startsec + tsize; + dsp->ds_startsec = startsec; + dsp->ds_endsec = endsec; + + + if (dsp->ds_maxblocks > 0) { + /* + * dsp->ds_maxblocks > 0 (disk capacity is known). + */ + if (lverbose) + printf("Blocks total: %ld Blocks current: %ld Blocks remaining: %ld\n", + (long)dsp->ds_maxblocks, + (long)dsp->ds_maxblocks - startsec, + (long)dsp->ds_maxblocks - endsec); + + if (endsec > dsp->ds_maxblocks) { + if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */ + /* + * There is no overburning on DVD... + */ + errmsgno(EX_BAD, + "Data does not fit on current disk.\n"); + goto toolarge; + } + errmsgno(EX_BAD, + "WARNING: Data may not fit on current disk.\n"); + + /* XXX Check for flags & CDR_NO_LOLIMIT */ +/* goto toolarge;*/ + } + if (lverbose && dsp->ds_maxrblocks > 0) + printf("RBlocks total: %ld RBlocks current: %ld RBlocks remaining: %ld\n", + (long)dsp->ds_maxrblocks, + (long)dsp->ds_maxrblocks - startsec, + (long)dsp->ds_maxrblocks - endsec); + if (dsp->ds_maxrblocks > 0 && endsec > dsp->ds_maxrblocks) { + errmsgno(EX_BAD, + "Data does not fit on current disk.\n"); + goto toolarge; + } + if ((endsec > dsp->ds_maxblocks && endsec > 404700) || + (dsp->ds_maxrblocks > 404700 && 449850 > dsp->ds_maxrblocks)) { + /* + * Assume that this must be a CD and not a DVD. + * So this is a non Red Book compliant CD with a + * capacity between 90 and 99 minutes. + */ + if (dsp->ds_maxrblocks > 404700) + printf("RedBook total: %ld RedBook current: %ld RedBook remaining: %ld\n", + 404700L, + 404700L - startsec, + 404700L - endsec); + if (endsec > dsp->ds_maxblocks && endsec > 404700) { + if ((flags & (F_IGNSIZE|F_FORCE)) == 0) { + errmsgno(EX_BAD, + "Notice: Most recorders cannot write CD's >= 90 minutes.\n"); + errmsgno(EX_BAD, + "Notice: Use -ignsize option to allow >= 90 minutes.\n"); + } + goto toolarge; + } + } + } else { + /* + * dsp->ds_maxblocks == 0 (disk capacity is unknown). + */ + profile = dp->profile; + if (endsec >= (4200000)) { + errmsgno(EX_BAD, + "ERROR: Could not manage to find medium size, and more than 8.0 GB of data.\n"); + goto toolarge; + } else if (profile != 0x2B) { + if (endsec >= (2300000)) { + errmsgno(EX_BAD, + "ERROR: Could not manage to find medium size, and more than 4.3 GB of data for a non dual layer disc.\n"); + goto toolarge; + } else if (endsec >= (405000-300)) { /*<90 min disk or DVD*/ + errmsgno(EX_BAD, + "WARNING: Could not manage to find medium size, and more than 90 mins of data.\n"); + } else if (endsec >= (333000-150)) { /* 74 min disk*/ + errmsgno(EX_BAD, + "WARNING: Data may not fit on standard 74min disk.\n"); + } + } + } + if (dsp->ds_maxblocks <= 0 || endsec <= dsp->ds_maxblocks) + return (TRUE); + /* FALLTHROUGH */ +toolarge: + if (dsp->ds_maxblocks > 0 && endsec > dsp->ds_maxblocks) { + if ((flags & (F_OVERBURN|F_IGNSIZE|F_FORCE)) != 0) { + if (dsp->ds_flags & DSF_DVD) { /* A DVD and not a CD */ + errmsgno(EX_BAD, + "Notice: -overburn is not expected to work with DVD media.\n"); + } + errmsgno(EX_BAD, + "Notice: Overburning active. Trying to write more than the official disk capacity.\n"); + return (TRUE); + } else { + if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */ + errmsgno(EX_BAD, + "Notice: Use -overburn option to write more than the official disk capacity.\n"); + errmsgno(EX_BAD, + "Notice: Most CD-writers do overburning only on SAO or RAW mode.\n"); + } + return (FALSE); + } + } + if (dsp->ds_maxblocks < 449850) { + if ((dsp->ds_flags & DSF_DVD) == 0) { /* A CD and not a DVD */ + if (endsec <= dsp->ds_maxblocks) + return (TRUE); + errmsgno(EX_BAD, "Cannot write more than remaining DVD capacity.\n"); + return (FALSE); + } + /* + * Assume that this must be a CD and not a DVD. + */ + if (endsec > 449700) { + errmsgno(EX_BAD, "Cannot write CD's >= 100 minutes.\n"); + return (FALSE); + } + } + if ((flags & (F_IGNSIZE|F_FORCE)) != 0) + return (TRUE); + return (FALSE); +} + +static void +raise_fdlim() +{ +#ifdef RLIMIT_NOFILE + + struct rlimit rlim; + + /* + * Set max # of file descriptors to be able to hold all files open + */ + getrlimit(RLIMIT_NOFILE, &rlim); + if (rlim.rlim_cur >= (MAX_TRACK + 10)) + return; + + rlim.rlim_cur = MAX_TRACK + 10; + if (rlim.rlim_cur > rlim.rlim_max) + errmsgno(EX_BAD, + "Warning: low file descriptor limit (%lld)\n", + (Llong)rlim.rlim_max); + setrlimit(RLIMIT_NOFILE, &rlim); + +#endif /* RLIMIT_NOFILE */ +} + +static void +raise_memlock() +{ +#ifdef RLIMIT_MEMLOCK + struct rlimit rlim; + + rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; + + if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) + errmsg("Warning: Cannot raise RLIMIT_MEMLOCK limits.\n"); +#endif /* RLIMIT_MEMLOCK */ +} + +char *opts = +"help,version,checkdrive,prcap,inq,devices,scanbus,reset,abort,overburn,ignsize,useinfo,dev*,timeout#,driver*,driveropts*,setdropts,tsize&,padsize&,pregap&,defpregap&,speed#,load,lock,eject,dummy,msinfo,toc,atip,multi,fix,nofix,waiti,immed,debug#,d+,kdebug#,kd#,verbose+,v+,Verbose+,V+,x+,xd#,silent,s,audio,data,mode2,xa,xa1,xa2,xamix,cdi,isosize,nopreemp,preemp,nocopy,copy,nopad,pad,swab,fs&,ts&,blank&,format,formattype&,pktsize#,packet,noclose,force,tao,dao,sao,raw,raw96r,raw96p,raw16,clone,scms,isrc*,mcn*,index*,cuefile*,textfile*,text,shorttrack,noshorttrack,gracetime#,minbuf#,msifile*"; + +/* + * Defines used to find whether a write mode has been specified. + */ +#define M_TAO 1 /* Track at Once mode */ +#define M_SAO 2 /* Session at Once mode (also known as DAO) */ +#define M_RAW 4 /* Raw mode */ +#define M_PACKET 8 /* Packed mode */ +static int +gargs(int ac, char **av, int *tracksp, track_t *trackp, char **devp, + int *timeoutp, cdr_t **dpp, int *speedp, long *flagsp, int *blankp, + int *formatp) +{ + int cac; + char * const*cav; + char *driver = NULL; + char *dev = NULL; + char *isrc = NULL; + char *mcn = NULL; + char *tindex = NULL; + char *cuefile = NULL; + char *textfile = NULL; + long bltype = -1; + int doformat = 0; + int formattype = -1; + Llong tracksize; + Llong padsize; + long pregapsize; + long defpregap = -1L; + int pktsize; + int speed = -1; + int help = 0; + int version = 0; + int checkdrive = 0; + int setdropts = 0; + int prcap = 0; + int inq = 0; + int scanbus = 0; + int reset = 0; + int doabort = 0; + int overburn = 0; + int ignsize = 0; + int useinfo = 0; + int load = 0; + int lock = 0; + int eject = 0; + int dummy = 0; + int msinfo = 0; + int toc = 0; + int atip = 0; + int multi = 0; + int fix = 0; + int nofix = 0; + int waiti = 0; + int immed = 0; + int audio; + int autoaudio = 0; + int data; + int mode2; + int xa; + int xa1; + int xa2; + int xamix; + int cdi; + int isize; + int ispacket = 0; + int noclose = 0; + int force = 0; + int tao = 0; + int dao = 0; + int raw = 0; + int raw96r = 0; + int raw96p = 0; + int raw16 = 0; + int clone = 0; + int scms = 0; + int preemp = 0; + int nopreemp; + int copy = 0; + int nocopy; + int pad = 0; + int bswab = 0; + int nopad; + int usetext = 0; + int shorttrack = 0; + int noshorttrack; + int flags; + int tracks = *tracksp; + int tracktype = TOC_ROM; +/* int sectype = ST_ROM_MODE1 | ST_MODE_1;*/ + int sectype = SECT_ROM; + int dbtype = DB_ROM_MODE1; + int secsize = DATA_SEC_SIZE; + int dataoff = 16; + int ga_ret; + int wm = 0; + + trackp[0].flags |= TI_TAO; + trackp[1].pregapsize = -1; + *flagsp |= F_WRITE; + + cac = --ac; + cav = ++av; + for (; ; cac--, cav++) { + tracksize = (Llong)-1L; + padsize = (Llong)0L; + pregapsize = defpregap; + audio = data = mode2 = xa = xa1 = xa2 = xamix = cdi = 0; + isize = nopreemp = nocopy = nopad = noshorttrack = 0; + pktsize = 0; + isrc = NULL; + tindex = NULL; + /* + * Get options up to next file type arg. + */ + if ((ga_ret = getargs(&cac, &cav, opts, + &help, &version, &checkdrive, &prcap, + &inq, &scandevs, &scanbus, &reset, &doabort, &overburn, &ignsize, + &useinfo, + devp, timeoutp, &driver, &driveropts, &setdropts, + getllnum, &tracksize, + getllnum, &padsize, + getnum, &pregapsize, + getnum, &defpregap, + &speed, + &load, &lock, + &eject, &dummy, &msinfo, &toc, &atip, + &multi, &fix, &nofix, &waiti, &immed, + &debug, &debug, + &kdebug, &kdebug, + &lverbose, &lverbose, + &scsi_verbose, &scsi_verbose, + &xdebug, &xdebug, + &silent, &silent, + &audio, &data, &mode2, + &xa, &xa1, &xa2, &xamix, &cdi, + &isize, + &nopreemp, &preemp, + &nocopy, ©, + &nopad, &pad, &bswab, getnum, &fs, getnum, &bufsize, + getbltype, &bltype, &doformat, getformattype, &formattype, &pktsize, + &ispacket, &noclose, &force, + &tao, &dao, &dao, &raw, &raw96r, &raw96p, &raw16, + &clone, + &scms, &isrc, &mcn, &tindex, + &cuefile, &textfile, &usetext, + &shorttrack, &noshorttrack, + &gracetime, &dminbuf, &msifile)) < 0) { + errmsgno(EX_BAD, "Bad Option: %s.\n", cav[0]); + susage(EX_BAD); + } + if (help) + usage(0); + if (tracks == 0) { + if (driver) + set_cdrcmds(driver, dpp); + if (version) + *flagsp |= F_VERSION; + if (checkdrive) + *flagsp |= F_CHECKDRIVE; + if (prcap) + *flagsp |= F_PRCAP; + if (inq) + *flagsp |= F_INQUIRY; + if (scanbus || scandevs) /* scandevs behaves similarly WRT in the legacy code, just the scan operation is different */ + *flagsp |= F_SCANBUS; + if (reset) + *flagsp |= F_RESET; + if (doabort) + *flagsp |= F_ABORT; + if (overburn) + *flagsp |= F_OVERBURN; + if (ignsize) + *flagsp |= F_IGNSIZE; + if (load) + *flagsp |= F_LOAD; + if (lock) + *flagsp |= F_DLCK; + if (eject) + *flagsp |= F_EJECT; + if (dummy) + *flagsp |= F_DUMMY; + if (setdropts) + *flagsp |= F_SETDROPTS; + if(msifile) + msinfo++; + if (msinfo) + *flagsp |= F_MSINFO; + if (toc) { + *flagsp |= F_TOC; + *flagsp &= ~F_WRITE; + } + if (atip) { + *flagsp |= F_PRATIP; + *flagsp &= ~F_WRITE; + } + if (multi) { + /* + * 2048 Bytes user data + */ + *flagsp |= F_MULTI; + tracktype = TOC_XA2; + sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1; + sectype = SECT_MODE_2_F1; + dbtype = DB_XA_MODE2; /* XXX -multi nimmt DB_XA_MODE2_F1 !!! */ + secsize = DATA_SEC_SIZE; /* 2048 */ + dataoff = 24; + } + if (fix) + *flagsp |= F_FIX; + if (nofix) + *flagsp |= F_NOFIX; + if (waiti) + *flagsp |= F_WAITI; + if (immed) + *flagsp |= F_IMMED; + if (force) + *flagsp |= F_FORCE; + + if (bltype >= 0) { + *flagsp |= F_BLANK; + *blankp = bltype; + } + if (doformat > 0) { + *flagsp |= F_FORMAT; + *formatp |= FULL_FORMAT; + } + if (formattype >= 0) { + *flagsp |= F_FORMAT; + *formatp |= formattype; + } + if (ispacket) + wm |= M_PACKET; + if (tao) + wm |= M_TAO; + if (dao) { + *flagsp |= F_SAO; + trackp[0].flags &= ~TI_TAO; + trackp[0].flags |= TI_SAO; + wm |= M_SAO; + + } else if ((raw == 0) && (raw96r + raw96p + raw16) > 0) + raw = 1; + if ((raw != 0) && (raw96r + raw96p + raw16) == 0) + raw96r = 1; + if (raw96r) { + if (!dao) + *flagsp |= F_RAW; + trackp[0].flags &= ~TI_TAO; + trackp[0].flags |= TI_RAW; + trackp[0].flags |= TI_RAW96R; + wm |= M_RAW; + } + if (raw96p) { + if (!dao) + *flagsp |= F_RAW; + trackp[0].flags &= ~TI_TAO; + trackp[0].flags |= TI_RAW; + wm |= M_RAW; + } + if (raw16) { + if (!dao) + *flagsp |= F_RAW; + trackp[0].flags &= ~TI_TAO; + trackp[0].flags |= TI_RAW; + trackp[0].flags |= TI_RAW16; + wm |= M_RAW; + } + if (mcn) { +#ifdef AUINFO + setmcn(mcn, &trackp[0]); +#else + trackp[0].isrc = malloc(16); + fillbytes(trackp[0].isrc, 16, '\0'); + strncpy(trackp[0].isrc, mcn, 13); +#endif + mcn = NULL; + } + if ((raw96r + raw96p + raw16) > 1) { + errmsgno(EX_BAD, "Too many raw modes.\n"); + comerrno(EX_BAD, "Only one of -raw16, -raw96p, -raw96r allowed.\n"); + } + if ((tao + ispacket + dao + raw) > 1) { + errmsgno(EX_BAD, "Too many write modes.\n"); + comerrno(EX_BAD, "Only one of -packet, -dao, -raw allowed.\n"); + } + if (dao && (raw96r + raw96p + raw16) > 0) { + if (raw16) + comerrno(EX_BAD, "SAO RAW writing does not allow -raw16.\n"); + if (!clone) + comerrno(EX_BAD, "SAO RAW writing only makes sense in clone mode.\n"); +#ifndef CLONE_WRITE + comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n"); +#endif + comerrno(EX_BAD, "SAO RAW writing not yet implemented.\n"); + } + if (clone) { + *flagsp |= F_CLONE; + trackp[0].flags |= TI_CLONE; +#ifndef CLONE_WRITE + comerrno(EX_BAD, "Clone writing not compiled in.\n"); +#endif + } + if (textfile) { + if (!checktextfile(textfile)) { + if ((*flagsp & F_WRITE) != 0) { + comerrno(EX_BAD, + "Cannot use '%s' as CD-Text file.\n", + textfile); + } + } + if ((*flagsp & F_WRITE) != 0) { + if ((dao + raw96r + raw96p) == 0) + comerrno(EX_BAD, + "CD-Text needs -dao, -raw96r or -raw96p.\n"); + } + trackp[0].flags |= TI_TEXT; + } + version = checkdrive = prcap = inq = scanbus = reset = doabort = + overburn = ignsize = + load = lock = eject = dummy = msinfo = toc = atip = multi = fix = nofix = + waiti = immed = force = dao = setdropts = 0; + raw96r = raw96p = raw16 = clone = 0; + } else if ((version + checkdrive + prcap + inq + scanbus + + reset + doabort + overburn + ignsize + + load + lock + eject + dummy + msinfo + toc + atip + multi + fix + nofix + + waiti + immed + force + dao + setdropts + + raw96r + raw96p + raw16 + clone) > 0 || + mcn != NULL) + comerrno(EX_BAD, "Badly placed option. Global options must be before any track.\n"); + + if (nopreemp) + preemp = 0; + if (nocopy) + copy = 0; + if (nopad) + pad = 0; + if (noshorttrack) + shorttrack = 0; + + if ((audio + data + mode2 + xa + xa1 + xa2 + xamix) > 1) { + errmsgno(EX_BAD, "Too many types for track %d.\n", tracks+1); + comerrno(EX_BAD, "Only one of -audio, -data, -mode2, -xa, -xa1, -xa2, -xamix allowed.\n"); + } + if (ispacket && audio) { + comerrno(EX_BAD, "Audio data cannot be written in packet mode.\n"); + } + /* + * Check whether the next argument is a file type arg. + * If this is true, then we got a track file name. + * If getargs() did previously return NOTAFLAG, we may have hit + * an argument that has been escaped via "--", so we may not + * call getfiles() again in this case. If we would call + * getfiles() and the current arg has been escaped and looks + * like an option, a call to getfiles() would skip it. + */ + if (ga_ret != NOTAFLAG) + ga_ret = getfiles(&cac, &cav, opts); + if (autoaudio) { + autoaudio = 0; + tracktype = TOC_ROM; + sectype = ST_ROM_MODE1 | ST_MODE_1; + sectype = SECT_ROM; + dbtype = DB_ROM_MODE1; + secsize = DATA_SEC_SIZE; /* 2048 */ + dataoff = 16; + } + if (ga_ret == NOTAFLAG && (is_auname(cav[0]) || is_wavname(cav[0]))) { + /* + * We got a track and autodetection decided that it + * is an audio track. + */ + autoaudio++; + audio++; + } + if (data) { + /* + * 2048 Bytes user data + */ + tracktype = TOC_ROM; + sectype = ST_ROM_MODE1 | ST_MODE_1; + sectype = SECT_ROM; + dbtype = DB_ROM_MODE1; + secsize = DATA_SEC_SIZE; /* 2048 */ + dataoff = 16; + } + if (mode2) { + /* + * 2336 Bytes user data + */ + tracktype = TOC_ROM; + sectype = ST_ROM_MODE2 | ST_MODE_2; + sectype = SECT_MODE_2; + dbtype = DB_ROM_MODE2; + secsize = MODE2_SEC_SIZE; /* 2336 */ + dataoff = 16; + } + if (audio) { + /* + * 2352 Bytes user data + */ + tracktype = TOC_DA; + sectype = preemp ? ST_AUDIO_PRE : ST_AUDIO_NOPRE; + sectype |= ST_MODE_AUDIO; + sectype = SECT_AUDIO; + if (preemp) + sectype |= ST_PREEMPMASK; + dbtype = DB_RAW; + secsize = AUDIO_SEC_SIZE; /* 2352 */ + dataoff = 0; + } + if (xa) { + /* + * 2048 Bytes user data + */ + if (tracktype != TOC_CDI) + tracktype = TOC_XA2; + sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1; + sectype = SECT_MODE_2_F1; + dbtype = DB_XA_MODE2; + secsize = DATA_SEC_SIZE; /* 2048 */ + dataoff = 24; + } + if (xa1) { + /* + * 8 Bytes subheader + 2048 Bytes user data + */ + if (tracktype != TOC_CDI) + tracktype = TOC_XA2; + sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_1; + sectype = SECT_MODE_2_F1; + dbtype = DB_XA_MODE2_F1; + secsize = 2056; + dataoff = 16; + } + if (xa2) { + /* + * 2324 Bytes user data + */ + if (tracktype != TOC_CDI) + tracktype = TOC_XA2; + sectype = ST_ROM_MODE2 | ST_MODE_2_FORM_2; + sectype = SECT_MODE_2_F2; + dbtype = DB_XA_MODE2_F2; + secsize = 2324; + dataoff = 24; + } + if (xamix) { + /* + * 8 Bytes subheader + 2324 Bytes user data + */ + if (tracktype != TOC_CDI) + tracktype = TOC_XA2; + sectype = ST_ROM_MODE2 | ST_MODE_2_MIXED; + sectype = SECT_MODE_2_MIX; + dbtype = DB_XA_MODE2_MIX; + secsize = 2332; + dataoff = 16; + } + if (cdi) { + tracktype = TOC_CDI; + } + if (tracks == 0) { + trackp[0].tracktype = tracktype; + trackp[0].dbtype = dbtype; + trackp[0].isecsize = secsize; + trackp[0].secsize = secsize; + if ((*flagsp & F_RAW) != 0) { + trackp[0].secsize = is_raw16(&trackp[0]) ? + RAW16_SEC_SIZE:RAW96_SEC_SIZE; + } + if ((*flagsp & F_DUMMY) != 0) + trackp[0].tracktype |= TOCF_DUMMY; + if ((*flagsp & F_MULTI) != 0) + trackp[0].tracktype |= TOCF_MULTI; + } + + flags = trackp[0].flags; + + if ((sectype & ST_AUDIOMASK) != 0) + flags |= TI_AUDIO; + if (isize) { + flags |= TI_ISOSIZE; + if ((*flagsp & F_MULTI) != 0) + comerrno(EX_BAD, "Cannot get isosize for multi session disks.\n"); + /* + * As we do not get the padding from the ISO-9660 + * formatting utility, we need to force padding here. + */ + flags |= TI_PAD; + if (padsize == (Llong)0L) + padsize = (Llong)PAD_SIZE; + } + + if ((flags & TI_AUDIO) != 0) { + if (preemp) + flags |= TI_PREEMP; + if (copy) + flags |= TI_COPY; + if (scms) + flags |= TI_SCMS; + } + if (pad || ((flags & TI_AUDIO) == 0 && padsize > (Llong)0L)) { + flags |= TI_PAD; + if ((flags & TI_AUDIO) == 0 && padsize == (Llong)0L) + padsize = (Llong)PAD_SIZE; + } + if (shorttrack && (*flagsp & (F_SAO|F_RAW)) != 0) + flags |= TI_SHORT_TRACK; + if (noshorttrack) + flags &= ~TI_SHORT_TRACK; + if (bswab) + flags |= TI_SWAB; + if (ispacket) { + flags |= TI_PACKET; + trackp[0].flags &= ~TI_TAO; + } + if (noclose) + flags |= TI_NOCLOSE; + if (useinfo) + flags |= TI_USEINFO; + + if (ga_ret == NOARGS) { + /* + * All options have already been parsed and no more + * file type arguments are present. + */ + break; + } + if (tracks == 0 && (wm == 0)) { + errmsgno(EX_BAD, "No write mode specified.\n"); + errmsgno(EX_BAD, "Assuming -tao mode.\n"); + errmsgno(EX_BAD, "Future versions of wodim may have different drive dependent defaults.\n"); + tao = 1; + } + tracks++; + + if (tracks > MAX_TRACK) + comerrno(EX_BAD, "Track limit (%d) exceeded\n", + MAX_TRACK); + /* + * Make 'tracks' immediately usable in track structure. + */ + { register int i; + for (i = 0; i < MAX_TRACK+2; i++) + trackp[i].tracks = tracks; + } + + if (strcmp("-", cav[0]) == 0) + *flagsp |= F_STDIN; + + if (!is_auname(cav[0]) && !is_wavname(cav[0])) + flags |= TI_NOAUHDR; + + if ((*flagsp & (F_SAO|F_RAW)) != 0 && (flags & TI_AUDIO) != 0) + flags |= TI_PREGAP; /* Hack for now */ + if (tracks == 1) + flags &= ~TI_PREGAP; + + if (tracks == 1 && (pregapsize != -1L && pregapsize != 150)) + pregapsize = -1L; + trackp[tracks].filename = cav[0]; + trackp[tracks].trackstart = 0L; + trackp[tracks].itracksize = tracksize; + trackp[tracks].tracksize = tracksize; + trackp[tracks].tracksecs = -1L; + if (tracksize >= 0) { + trackp[tracks].tracksecs = (tracksize+secsize-1)/secsize; + if(tracksize<616448) + warn_minisize=tracksize; + } + if (trackp[tracks].pregapsize < 0) + trackp[tracks].pregapsize = pregapsize; + trackp[tracks+1].pregapsize = -1; + trackp[tracks].padsecs = (padsize+2047)/2048; + trackp[tracks].isecsize = secsize; + trackp[tracks].secsize = secsize; + trackp[tracks].flags = flags; + /* + * XXX Dies ist falsch: auch bei SAO/RAW kann + * XXX secsize != isecsize sein. + */ + if ((*flagsp & F_RAW) != 0) { + if (is_raw16(&trackp[tracks])) + trackp[tracks].secsize = RAW16_SEC_SIZE; + else + trackp[tracks].secsize = RAW96_SEC_SIZE; +#ifndef HAVE_LIB_EDC_ECC + if ((sectype & ST_MODE_MASK) != ST_MODE_AUDIO) { + errmsgno(EX_BAD, + "EDC/ECC library not compiled in.\n"); + comerrno(EX_BAD, + "Data sectors are not supported in RAW mode.\n"); + } +#endif + } + trackp[tracks].secspt = 0; /* transfer size is set up in set_trsizes() */ + trackp[tracks].pktsize = pktsize; + trackp[tracks].trackno = tracks; + trackp[tracks].sectype = sectype; +#ifdef CLONE_WRITE + if ((*flagsp & F_CLONE) != 0) { + trackp[tracks].isecsize = 2448; + trackp[tracks].sectype |= ST_MODE_RAW; + dataoff = 0; + } +#endif + trackp[tracks].dataoff = dataoff; + trackp[tracks].tracktype = tracktype; + trackp[tracks].dbtype = dbtype; + trackp[tracks].flags = flags; + trackp[tracks].nindex = 1; + trackp[tracks].tindex = 0; + if (isrc) { +#ifdef AUINFO + setisrc(isrc, &trackp[tracks]); +#else + trackp[tracks].isrc = malloc(16); + fillbytes(trackp[tracks].isrc, 16, '\0'); + strncpy(trackp[tracks].isrc, isrc, 12); +#endif + } + if (tindex) { +#ifdef AUINFO + setindex(tindex, &trackp[tracks]); +#endif + } + } + + if (dminbuf >= 0) { + if (dminbuf < 25 || dminbuf > 95) + comerrno(EX_BAD, + "Bad minbuf=%d option (must be between 25 and 95)\n", + dminbuf); + } + + if (speed < 0 && speed != -1) + comerrno(EX_BAD, "Bad speed option.\n"); + + if (fs < 0L && fs != -1L) + comerrno(EX_BAD, "Bad fifo size option.\n"); + + if (bufsize < 0L && bufsize != -1L) + comerrno(EX_BAD, "Bad transfer size option.\n"); + if (bufsize < 0L) + bufsize = CDR_BUF_SIZE; + if (bufsize > CDR_MAX_BUF_SIZE) + bufsize = CDR_MAX_BUF_SIZE; + + dev = *devp; + cdr_defaults(&dev, &speed, &fs, &driveropts); + if (debug) { + printf("dev: '%s' speed: %d fs: %ld driveropts '%s'\n", + dev, speed, fs, driveropts); + } + if (speed >= 0) + *speedp = speed; + + if (fs < 0L) + fs = DEFAULT_FIFOSIZE; + if (fs < 2*bufsize) { + errmsgno(EX_BAD, "Fifo size %ld too small, turning fifo off.\n", fs); + fs = 0L; + } + + if (dev != *devp && (*flagsp & F_SCANBUS) == 0) + *devp = dev; + + if (*devp && + ((strncmp(*devp, "HELP", 4) == 0) || + (strncmp(*devp, "help", 4) == 0))) { + *flagsp |= F_CHECKDRIVE; /* Set this for not calling mlockall() */ + return ispacket; + } + if (*flagsp & (F_LOAD|F_DLCK|F_SETDROPTS|F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_PRCAP|F_INQUIRY|F_SCANBUS|F_RESET|F_ABORT)) { + if (tracks != 0) { + fprintf(stderr, + "No tracks allowed with -load, -lock, -setdropts, -msinfo, -toc, -atip, -fix,\n" + "-version, -checkdrive, -prcap, -inq, -scanbus, --devices, -reset and -abort options.\n" ); + exit(EXIT_FAILURE); + } + return ispacket; + } + *tracksp = tracks; + if (*flagsp & F_SAO) { + /* + * Make sure that you change WRITER_MAXWAIT & READER_MAXWAIT + * too if you change this timeout. + */ + if (*timeoutp < 200) /* Lead in size is 2:30 */ + *timeoutp = 200; /* 200s is 150s *1.33 */ + } + if (usetext) { + trackp[MAX_TRACK+1].flags |= TI_TEXT; + } + if (cuefile) { +#ifdef FUTURE + if ((*flagsp & F_SAO) == 0 && + (*flagsp & F_RAW) == 0) { +#else + if ((*flagsp & F_SAO) == 0) { +#endif + errmsgno(EX_BAD, "The cuefile= option only works with -dao.\n"); + susage(EX_BAD); + } + if (tracks > 0) { + errmsgno(EX_BAD, "No tracks allowed with the cuefile= option\n"); + susage(EX_BAD); + } + cuefilename = cuefile; + return ispacket; + } + if (tracks == 0 && (*flagsp & (F_LOAD|F_DLCK|F_EJECT|F_BLANK|F_FORMAT)) == 0) { + errmsgno(EX_BAD, "No tracks specified. Need at least one.\n"); + susage(EX_BAD); + } + return ispacket; +} + +static void +set_trsizes(cdr_t *dp, int tracks, track_t *trackp) +{ + int i; + int secsize; + int secspt; + + trackp[1].flags |= TI_FIRST; + trackp[tracks].flags |= TI_LAST; + + if (xdebug) + printf("Set Transfersizes start\n"); + for (i = 0; i <= tracks+1; i++) { + if ((dp->cdr_flags & CDR_SWABAUDIO) != 0 && + is_audio(&trackp[i])) { + trackp[i].flags ^= TI_SWAB; + } + if (!is_audio(&trackp[i])) + trackp[i].flags &= ~TI_SWAB; /* Only swab audio */ + + /* + * Use the biggest sector size to compute how many + * sectors may fit into one single DMA buffer. + */ + secsize = trackp[i].secsize; + if (trackp[i].isecsize > secsize) + secsize = trackp[i].isecsize; + + /* + * We are using SCSI Group 0 write + * and cannot write more than 255 secs at once. + */ + secspt = bufsize/secsize; + secspt = min(255, secspt); + trackp[i].secspt = secspt; + + if (is_packet(&trackp[i]) && trackp[i].pktsize > 0) { + if (trackp[i].secspt >= trackp[i].pktsize) { + trackp[i].secspt = trackp[i].pktsize; + } else { + comerrno(EX_BAD, + "Track %d packet size %d exceeds buffer limit of %d sectors", + i, trackp[i].pktsize, trackp[i].secspt); + } + } + if (xdebug) { + printf("Track %d flags %X secspt %d secsize: %d isecsize: %d\n", + i, trackp[i].flags, trackp[i].secspt, + trackp[i].secsize, trackp[i].isecsize); + } + } + if (xdebug) + printf("Set Transfersizes end\n"); +} + +void +load_media(SCSI *usalp, cdr_t *dp, BOOL doexit) +{ + int code; + int key; + BOOL immed = (dp->cdr_cmdflags&F_IMMED) != 0; + + /* + * Do some preparation before... + */ + usalp->silent++; /* Be quiet if this fails */ + test_unit_ready(usalp); /* First eat up unit attention */ + if ((*dp->cdr_load)(usalp, dp) < 0) { /* now try to load media and */ + if (!doexit) + return; + comerrno(EX_BAD, "Cannot load media.\n"); + } + scsi_start_stop_unit(usalp, 1, 0, immed); /* start unit in silent mode */ + usalp->silent--; + + if (!wait_unit_ready(usalp, 60)) { + code = usal_sense_code(usalp); + key = usal_sense_key(usalp); + usalp->silent++; + scsi_prevent_removal(usalp, 0); /* In case someone locked it */ + usalp->silent--; + + if (!doexit) + return; + if (key == SC_NOT_READY && (code == 0x3A || code == 0x30)) + comerrno(EX_BAD, "No disk / Wrong disk!\n"); + comerrno(EX_BAD, "CD/DVD-Recorder not ready.\n"); + } + + scsi_prevent_removal(usalp, 1); + scsi_start_stop_unit(usalp, 1, 0, immed); + wait_unit_ready(usalp, 120); + usalp->silent++; + if(geteuid() == 0) /* EB: needed? Not allowed for non-root, that is sure. */ + rezero_unit(usalp); /* Is this needed? Not supported by some drvives */ + usalp->silent--; + test_unit_ready(usalp); + scsi_start_stop_unit(usalp, 1, 0, immed); + wait_unit_ready(usalp, 120); +} + +void +unload_media(SCSI *usalp, cdr_t *dp, int flags) +{ + scsi_prevent_removal(usalp, 0); + if ((flags & F_EJECT) != 0) { + if ((*dp->cdr_unload)(usalp, dp) < 0) + errmsgno(EX_BAD, "Cannot eject media.\n"); + } +} + +void +reload_media(SCSI *usalp, cdr_t *dp) +{ + char ans[2]; +#ifdef F_GETFL + int f = -1; +#endif + + errmsgno(EX_BAD, "Drive needs to reload the media to return to proper status.\n"); + unload_media(usalp, dp, F_EJECT); + + /* + * Note that even Notebook drives identify as CDR_TRAYLOAD + */ + if ((dp->cdr_flags & CDR_TRAYLOAD) != 0) { + usalp->silent++; + load_media(usalp, dp, FALSE); + usalp->silent--; + } + + usalp->silent++; + if (((dp->cdr_flags & CDR_TRAYLOAD) == 0) || + !wait_unit_ready(usalp, 5)) { + static FILE *tty = NULL; + + printf("Re-load disk and hit <CR>"); + if (isgui) + printf("\n"); + flush(); + + if (tty == NULL) { + tty = stdin; + if ((dp->cdr_cmdflags & F_STDIN) != 0) + tty = fileluopen(STDERR_FILENO, "rw"); + } +#ifdef F_GETFL + if (tty != NULL) + f = fcntl(fileno(tty), F_GETFL, 0); + if (f < 0 || (f & O_ACCMODE) == O_WRONLY) { +#ifdef SIGUSR1 + signal(SIGUSR1, catchsig); + printf("Controlling file not open for reading, send SIGUSR1 to continue.\n"); + flush(); + pause(); +#endif + } else +#endif + if (rols_fgetline(tty, ans, 1) < 0) + comerrno(EX_BAD, "Aborted by EOF on input.\n"); + } + usalp->silent--; + + load_media(usalp, dp, TRUE); +} + +void +set_secsize(SCSI *usalp, int secsize) +{ + if (secsize > 0) { + /* + * Try to restore the old sector size. + */ + usalp->silent++; + select_secsize(usalp, secsize); + usalp->silent--; + } +} + +static int +get_dmaspeed(SCSI *usalp, cdr_t *dp) +{ + int i; + long t; + int bs; + int tsize; + + if(getenv("CDR_NODMATEST")) + return -1; + + if (debug || lverbose) + fprintf( stderr, + "Beginning DMA speed test. Set CDR_NODMATEST environment variable if device\n" + "communication breaks or freezes immediately after that.\n" ); + + fillbytes((caddr_t)buf, 4, '\0'); + tsize = 0; + usalp->silent++; + i = read_buffer(usalp, buf, 4, 0); + usalp->silent--; + if (i < 0) + return (-1); + tsize = a_to_u_4_byte(buf); + if (tsize <= 0) + return (-1); + + if (gettimeofday(&starttime, (struct timezone *)0) < 0) + return (-1); + + bs = bufsize; + if (tsize < bs) + bs = tsize; + for (i = 0; i < 100; i++) { + if (read_buffer(usalp, buf, bs, 0) < 0) + return (-1); + } + if (gettimeofday(&fixtime, (struct timezone *)0) < 0) { + errmsg("Cannot get DMA stop time\n"); + return (-1); + } + timevaldiff(&starttime, &fixtime); + tsize = bs * 100; + t = fixtime.tv_sec * 1000 + fixtime.tv_usec / 1000; + if (t <= 0) + return (-1); +#ifdef DEBUG + fprintf(stderr, "Read Speed: %lu %ld %ld kB/s %ldx CD %ldx DVD\n", + tsize, t, tsize/t, tsize/t/176, tsize/t/1385); +#endif + + return (tsize/t); +} + + +static BOOL +do_opc(SCSI *usalp, cdr_t *dp, int flags) +{ + if ((flags & F_DUMMY) == 0 && dp->cdr_opc) { + if (debug || lverbose) { + printf("Performing OPC...\n"); + flush(); + } + if (dp->cdr_opc(usalp, NULL, 0, TRUE) < 0) { + errmsgno(EX_BAD, "OPC failed.\n"); + if ((flags & F_FORCE) == 0) + return (FALSE); + } + } + return (TRUE); +} + +static void +check_recovery(SCSI *usalp, cdr_t *dp, int flags) +{ + if ((*dp->cdr_check_recovery)(usalp, dp)) { + errmsgno(EX_BAD, "Recovery needed.\n"); + unload_media(usalp, dp, flags); + comexit(EX_BAD); + } +} + +#ifndef DEBUG +#define DEBUG +#endif +void +audioread(SCSI *usalp, cdr_t *dp, int flags) +{ +#ifdef DEBUG + int speed = 1; + int oflags = dp->cdr_cmdflags; + + dp->cdr_cmdflags &= ~F_DUMMY; + if ((*dp->cdr_set_speed_dummy)(usalp, dp, &speed) < 0) + comexit(-1); + dp->cdr_dstat->ds_wspeed = speed; /* XXX Remove 'speed' in future */ + dp->cdr_cmdflags = oflags; + + if ((*dp->cdr_set_secsize)(usalp, 2352) < 0) + comexit(-1); + usalp->cap->c_bsize = 2352; + + read_scsi(usalp, buf, 1000, 1); + printf("XXX:\n"); + write(1, buf, 512); /* FIXME: handle return value */ + unload_media(usalp, dp, flags); + comexit(0); +#endif +} + +static void +print_msinfo(SCSI *usalp, cdr_t *dp) +{ + long off; + long fa; + + if ((*dp->cdr_session_offset)(usalp, &off) < 0) { + errmsgno(EX_BAD, "Cannot read session offset\n"); + return; + } + if (lverbose) + printf("session offset: %ld\n", off); + + if (dp->cdr_next_wr_address(usalp, (track_t *)0, &fa) < 0) { + errmsgno(EX_BAD, "Cannot read first writable address\n"); + return; + } + printf("%ld,%ld\n", off, fa); + if(msifile) { + FILE *f = fopen(msifile, "w"); + if(f) { + fprintf(f, "%ld,%ld", off, fa); + fclose(f); + } + else { + perror("Unable to write multi session info file"); + exit(EXIT_FAILURE); + } + } +} + +static void +print_toc(SCSI *usalp, cdr_t *dp) +{ + int first; + int last; + long lba; + long xlba; + struct msf msf; + int adr; + int control; + int mode; + int i; + + usalp->silent++; + if (read_capacity(usalp) < 0) { + usalp->silent--; + errmsgno(EX_BAD, "Cannot read capacity\n"); + return; + } + usalp->silent--; + if (read_tochdr(usalp, dp, &first, &last) < 0) { + errmsgno(EX_BAD, "Cannot read TOC/PMA\n"); + return; + } + printf("first: %d last %d\n", first, last); + for (i = first; i <= last; i++) { + read_trackinfo(usalp, i, &lba, &msf, &adr, &control, &mode); + xlba = -150 + + msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min); + if (xlba == lba/4) + lba = xlba; + print_track(i, lba, &msf, adr, control, mode); + } + i = 0xAA; + read_trackinfo(usalp, i, &lba, &msf, &adr, &control, &mode); + xlba = -150 + + msf.msf_frame + (75*msf.msf_sec) + (75*60*msf.msf_min); + if (xlba == lba/4) + lba = xlba; + print_track(i, lba, &msf, adr, control, mode); + if (lverbose > 1) { + usalp->silent++; + if (read_cdtext(usalp) < 0) + errmsgno(EX_BAD, "No CD-Text or CD-Text unaware drive.\n"); + usalp->silent++; + } +} + +static void +print_track(int track, long lba, struct msf *msp, int adr, + int control, int mode) +{ + long lba_512 = lba*4; + + if (track == 0xAA) + printf("track:lout "); + else + printf("track: %3d ", track); + + printf("lba: %9ld (%9ld) %02d:%02d:%02d adr: %X control: %X mode: %d\n", + lba, lba_512, + msp->msf_min, + msp->msf_sec, + msp->msf_frame, + adr, control, mode); +} + +#ifdef HAVE_SYS_PRIOCNTL_H /* The preferred SYSvR4 schduler */ + +#include <sys/procset.h> /* Needed for SCO Openserver */ +#include <sys/priocntl.h> +#include <sys/rtpriocntl.h> + +void +raisepri(int pri) +{ + int pid; + int classes; + int ret; + pcinfo_t info; + pcparms_t param; + rtinfo_t rtinfo; + rtparms_t rtparam; + + pid = getpid(); + + /* get info */ + strcpy(info.pc_clname, "RT"); + classes = priocntl(P_PID, pid, PC_GETCID, (void *)&info); + if (classes == -1) + comerr("Cannot get priority class id priocntl(PC_GETCID)\n"); + + movebytes(info.pc_clinfo, &rtinfo, sizeof (rtinfo_t)); + + /* set priority to max */ + rtparam.rt_pri = rtinfo.rt_maxpri - pri; + rtparam.rt_tqsecs = 0; + rtparam.rt_tqnsecs = RT_TQDEF; + param.pc_cid = info.pc_cid; + movebytes(&rtparam, param.pc_clparms, sizeof (rtparms_t)); + ret = priocntl(P_PID, pid, PC_SETPARMS, (void *)¶m); + if (ret == -1) { + errmsg("WARNING: Cannot set priority class parameters priocntl(PC_SETPARMS)\n"); + errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n"); + } +} + +#else /* HAVE_SYS_PRIOCNTL_H */ + +#if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING -0 >= 0 +/* + * The second best choice: POSIX real time scheduling. + */ +/* + * XXX Ugly but needed because of a typo in /usr/iclude/sched.h on Linux. + * XXX This should be removed as soon as we are sure that Linux-2.0.29 is gone. + */ +#ifdef __linux +#define _P __P +#endif + +#include <sched.h> + +#ifdef __linux +#undef _P +#endif + +static int +rt_raisepri(int pri) +{ + struct sched_param scp; + + /* + * Verify that scheduling is available + */ +#ifdef _SC_PRIORITY_SCHEDULING + if (sysconf(_SC_PRIORITY_SCHEDULING) == -1) { + errmsg("WARNING: RR-scheduler not available, disabling.\n"); + return (-1); + } +#endif + fillbytes(&scp, sizeof (scp), '\0'); + scp.sched_priority = sched_get_priority_max(SCHED_RR) - pri; + if (sched_setscheduler(0, SCHED_RR, &scp) < 0) { + if(lverbose>2) + errmsg("WARNING: Cannot set RR-scheduler\n"); + return (-1); + } + return (0); +} + +#else /* _POSIX_PRIORITY_SCHEDULING */ + +#ifdef __CYGWIN32__ +/* + * Win32 specific priority settings. + */ +/* + * NOTE: Base.h from Cygwin-B20 has a second typedef for BOOL. + * We define BOOL to make all static code use BOOL + * from Windows.h and use the hidden __SBOOL for + * our global interfaces. + * + * NOTE: windows.h from Cygwin-1.x includes a structure field named sample, + * so me may not define our own 'sample' or need to #undef it now. + * With a few nasty exceptions, Microsoft assumes that any global + * defines or identifiers will begin with an Uppercase letter, so + * there may be more of these problems in the future. + * + * NOTE: windows.h defines interface as an alias for struct, this + * is used by COM/OLE2, I guess it is class on C++ + * We man need to #undef 'interface' + */ +#define BOOL WBOOL /* This is the Win BOOL */ +#define format __format /* Avoid format parameter hides global ... */ +#include <windows.h> +#undef format +#undef interface + +static int +rt_raisepri(int pri) +{ + int prios[] = {THREAD_PRIORITY_TIME_CRITICAL, THREAD_PRIORITY_HIGHEST}; + + /* set priority class */ + if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) { + if(debug || lverbose>2) + errmsgno(EX_BAD, "No realtime priority class possible.\n"); + return (-1); + } + + /* set thread priority */ + if (pri >= 0 && pri <= 1 && SetThreadPriority(GetCurrentThread(), prios[pri]) == FALSE) { + errmsgno(EX_BAD, "Could not set realtime priority.\n"); + return (-1); + } + return (0); +} + +#else +/* + * This OS does not support real time scheduling. + */ +static int +rt_raisepri(int pri) +{ + return (-1); +} + +#endif /* __CYGWIN32__ */ + +#endif /* _POSIX_PRIORITY_SCHEDULING */ + +void +raisepri(int pri) +{ + if (rt_raisepri(pri) >= 0) + return; +#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) + + if (setpriority(PRIO_PROCESS, getpid(), -20 + pri) < 0) { + if(debug || lverbose>2) + fprintf(stderr, + "WARNING: Cannot set priority using setpriority()," + "increased risk for buffer underruns.\n"); + } +#else +#ifdef HAVE_DOSSETPRIORITY /* RT priority on OS/2 */ + /* + * Set priority to timecritical 31 - pri (arg) + */ + DosSetPriority(0, 3, 31, 0); + DosSetPriority(0, 3, -pri, 0); +#else +#if defined(HAVE_NICE) && !defined(__DJGPP__) /* DOS has nice but no multitasking */ + if (nice(-20 + pri) == -1) { + errmsg("WARNING: Cannot set priority using nice().\n"); + errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n"); + } +#else + errmsgno(EX_BAD, "WARNING: Cannot set priority on this OS.\n"); + errmsgno(EX_BAD, "WARNING: This causes a high risk for buffer underruns.\n"); +#endif +#endif +#endif +} + +#endif /* HAVE_SYS_PRIOCNTL_H */ + +#ifdef HAVE_SELECT +/* + * sys/types.h and sys/time.h are already included. + */ +#else +# include <stropts.h> +# include <poll.h> + +#ifndef INFTIM +#define INFTIM (-1) +#endif +#endif + +#if defined(HAVE_SELECT) && defined(NEED_SYS_SELECT_H) +#include <sys/select.h> +#endif +#if defined(HAVE_SELECT) && defined(NEED_SYS_SOCKET_H) +#include <sys/socket.h> +#endif + +static void +wait_input() +{ +#ifdef HAVE_SELECT + fd_set in; + + FD_ZERO(&in); + FD_SET(STDIN_FILENO, &in); + select(1, &in, NULL, NULL, 0); +#else + struct pollfd pfd; + + pfd.fd = STDIN_FILENO; + pfd.events = POLLIN; + pfd.revents = 0; + poll(&pfd, (unsigned long)1, INFTIM); +#endif +} + +static void +checkgui() +{ + struct stat st; + + if (fstat(STDERR_FILENO, &st) >= 0 && !S_ISCHR(st.st_mode)) { + isgui = TRUE; + if (lverbose > 1) + printf("Using remote (pipe) mode for interactive i/o.\n"); + } +} + +static int +getbltype(char *optstr, long *typep) +{ + if (streql(optstr, "all")) { + *typep = BLANK_DISC; + } else if (streql(optstr, "disc")) { + *typep = BLANK_DISC; + } else if (streql(optstr, "disk")) { + *typep = BLANK_DISC; + } else if (streql(optstr, "fast")) { + *typep = BLANK_MINIMAL; + } else if (streql(optstr, "minimal")) { + *typep = BLANK_MINIMAL; + } else if (streql(optstr, "track")) { + *typep = BLANK_TRACK; + } else if (streql(optstr, "unreserve")) { + *typep = BLANK_UNRESERVE; + } else if (streql(optstr, "trtail")) { + *typep = BLANK_TAIL; + } else if (streql(optstr, "unclose")) { + *typep = BLANK_UNCLOSE; + } else if (streql(optstr, "session")) { + *typep = BLANK_SESSION; + } else if (streql(optstr, "help")) { + blusage(0); + } else { + fprintf(stderr, "Illegal blanking type '%s'.\n", optstr); + blusage(EX_BAD); + return (-1); + } + return (TRUE); +} + +static int +getformattype(char *optstr, long *typep) +{ + if (streql(optstr, "full")) { + *typep = FULL_FORMAT; + } else if (streql(optstr, "background")) { + *typep = BACKGROUND_FORMAT; + } else if (streql(optstr, "force")) { + *typep = FORCE_FORMAT; + } else if (streql(optstr, "help")) { + formattypeusage(0); + } else { + fprintf(stderr, "Illegal blanking type '%s'.\n", optstr); + formattypeusage(EX_BAD); + return (-1); + } + return (TRUE); +} +static void +print_drflags(cdr_t *dp) +{ + printf("Driver flags : "); + + if ((dp->cdr_flags & CDR_DVD) != 0) + printf("DVD "); + + if ((dp->cdr_flags & CDR_MMC3) != 0) + printf("MMC-3 "); + else if ((dp->cdr_flags & CDR_MMC2) != 0) + printf("MMC-2 "); + else if ((dp->cdr_flags & CDR_MMC) != 0) + printf("MMC "); + + if ((dp->cdr_flags & CDR_SWABAUDIO) != 0) + printf("SWABAUDIO "); + if ((dp->cdr_flags & CDR_BURNFREE) != 0) + printf("BURNFREE "); + if ((dp->cdr_flags & CDR_VARIREC) != 0) + printf("VARIREC "); + if ((dp->cdr_flags & CDR_GIGAREC) != 0) + printf("GIGAREC "); + if ((dp->cdr_flags & CDR_AUDIOMASTER) != 0) + printf("AUDIOMASTER "); + if ((dp->cdr_flags & CDR_FORCESPEED) != 0) + printf("FORCESPEED "); + if ((dp->cdr_flags & CDR_SPEEDREAD) != 0) + printf("SPEEDREAD "); + if ((dp->cdr_flags & CDR_DISKTATTOO) != 0) + printf("DISKTATTOO "); + if ((dp->cdr_flags & CDR_SINGLESESS) != 0) + printf("SINGLESESSION "); + if ((dp->cdr_flags & CDR_HIDE_CDR) != 0) + printf("HIDECDR "); + printf("\n"); +} + +static void +print_wrmodes(cdr_t *dp) +{ + BOOL needblank = FALSE; + + printf("Supported modes: "); + if ((dp->cdr_flags & CDR_TAO) != 0) { + printf("TAO"); + needblank = TRUE; + } + if ((dp->cdr_flags & CDR_PACKET) != 0) { + printf("%sPACKET", needblank?" ":""); + needblank = TRUE; + } + if ((dp->cdr_flags & CDR_SAO) != 0) { + printf("%sSAO", needblank?" ":""); + needblank = TRUE; + } +#ifdef __needed__ + if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW16)) == (CDR_SAO|CDR_SRAW16)) { + printf("%sSAO/R16", needblank?" ":""); + needblank = TRUE; + } +#endif + if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96P)) == (CDR_SAO|CDR_SRAW96P)) { + printf("%sSAO/R96P", needblank?" ":""); + needblank = TRUE; + } + if ((dp->cdr_flags & (CDR_SAO|CDR_SRAW96R)) == (CDR_SAO|CDR_SRAW96R)) { + printf("%sSAO/R96R", needblank?" ":""); + needblank = TRUE; + } + if ((dp->cdr_flags & (CDR_RAW|CDR_RAW16)) == (CDR_RAW|CDR_RAW16)) { + printf("%sRAW/R16", needblank?" ":""); + needblank = TRUE; + } + if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96P)) == (CDR_RAW|CDR_RAW96P)) { + printf("%sRAW/R96P", needblank?" ":""); + needblank = TRUE; + } + if ((dp->cdr_flags & (CDR_RAW|CDR_RAW96R)) == (CDR_RAW|CDR_RAW96R)) { + printf("%sRAW/R96R", needblank?" ":""); + needblank = TRUE; + } + printf("\n"); +} + +static BOOL +check_wrmode(cdr_t *dp, int wmode, int tflags) +{ + int cdflags = dp->cdr_flags; + + if ((tflags & TI_PACKET) != 0 && (cdflags & CDR_PACKET) == 0) { + errmsgno(EX_BAD, "Drive does not support PACKET recording.\n"); + return (FALSE); + } + if ((tflags & TI_TAO) != 0 && (cdflags & CDR_TAO) == 0) { + errmsgno(EX_BAD, "Drive does not support TAO recording.\n"); + return (FALSE); + } + if ((wmode & F_SAO) != 0) { + if ((cdflags & CDR_SAO) == 0) { + errmsgno(EX_BAD, "Drive does not support SAO recording.\n"); + if ((cdflags & CDR_RAW) != 0) + errmsgno(EX_BAD, "Try -raw option.\n"); + return (FALSE); + } +#ifdef __needed__ + if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_SRAW16) == 0) { + errmsgno(EX_BAD, "Drive does not support SAO/RAW16.\n"); + goto badsecs; + } +#endif + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_SRAW96P) == 0) { + errmsgno(EX_BAD, "Drive does not support SAO/RAW96P.\n"); + goto badsecs; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_SRAW96R) == 0) { + errmsgno(EX_BAD, "Drive does not support SAO/RAW96R.\n"); + goto badsecs; + } + } + if ((wmode & F_RAW) != 0) { + if ((cdflags & CDR_RAW) == 0) { + errmsgno(EX_BAD, "Drive does not support RAW recording.\n"); + return (FALSE); + } + if ((tflags & TI_RAW16) != 0 && (cdflags & CDR_RAW16) == 0) { + errmsgno(EX_BAD, "Drive does not support RAW/RAW16.\n"); + goto badsecs; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW && (cdflags & CDR_RAW96P) == 0) { + errmsgno(EX_BAD, "Drive does not support RAW/RAW96P.\n"); + goto badsecs; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R) && (cdflags & CDR_RAW96R) == 0) { + errmsgno(EX_BAD, "Drive does not support RAW/RAW96R.\n"); + goto badsecs; + } + } + return (TRUE); + +badsecs: + if ((wmode & F_SAO) != 0) + cdflags &= ~(CDR_RAW16|CDR_RAW96P|CDR_RAW96R); + if ((wmode & F_RAW) != 0) + cdflags &= ~(CDR_SRAW96P|CDR_SRAW96R); + + if ((cdflags & (CDR_SRAW96R|CDR_RAW96R)) != 0) + errmsgno(EX_BAD, "Try -raw96r option.\n"); + else if ((cdflags & (CDR_SRAW96P|CDR_RAW96P)) != 0) + errmsgno(EX_BAD, "Try -raw96p option.\n"); + else if ((cdflags & CDR_RAW16) != 0) + errmsgno(EX_BAD, "Try -raw16 option.\n"); + return (FALSE); +} + +static void +set_wrmode(cdr_t *dp, int wmode, int tflags) +{ + dstat_t *dsp = dp->cdr_dstat; + + if ((tflags & TI_PACKET) != 0) { + dsp->ds_wrmode = WM_PACKET; + return; + } + if ((tflags & TI_TAO) != 0) { + dsp->ds_wrmode = WM_TAO; + return; + } + if ((wmode & F_SAO) != 0) { + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == 0) { + dsp->ds_wrmode = WM_SAO; + return; + } + if ((tflags & TI_RAW16) != 0) { /* Is this needed? */ + dsp->ds_wrmode = WM_SAO_RAW16; + return; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) { + dsp->ds_wrmode = WM_SAO_RAW96P; + return; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) { + dsp->ds_wrmode = WM_SAO_RAW96R; + return; + } + } + if ((wmode & F_RAW) != 0) { + if ((tflags & TI_RAW16) != 0) { + dsp->ds_wrmode = WM_RAW_RAW16; + return; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) { + dsp->ds_wrmode = WM_RAW_RAW96P; + return; + } + if ((tflags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) { + dsp->ds_wrmode = WM_RAW_RAW96R; + return; + } + } + dsp->ds_wrmode = WM_NONE; +} + +#if defined(linux) || defined(__linux) || defined(__linux__) +#ifdef HAVE_UNAME +#include <sys/utsname.h> +#endif +#endif + +#ifdef __linux__ +static int +get_cap(cap_value_t cap_array) +{ + int ret; + cap_t capa; + capa = cap_get_proc(); + cap_set_flag(capa, CAP_EFFECTIVE, 1, &cap_array, CAP_SET); + ret = cap_set_proc(capa); + cap_free(capa); + return ret; +} +#endif diff --git a/wodim/wodim.dfl b/wodim/wodim.dfl new file mode 100644 index 0000000..41c4201 --- /dev/null +++ b/wodim/wodim.dfl @@ -0,0 +1,48 @@ +# wodim.dfl Copyright 2006 E. Bloch +# Based on cdrecord.dfl (Copyright 1998 J. Schilling) +# +# This file is /etc/wodim.conf +# It contains defaults that are used if no command line option +# or environment is present. +# +# The default device, if not specified elsewhere. +# +#CDR_DEVICE=yamaha +CDR_DEVICE=cdrom + +# +# The default speed, if not specified elswhere. +# +# For MMC compliant drives, the default is to write at maximum speed, so it in +# general does not make sense to set up a default speed in /etc/wodim.conf. +# +#CDR_SPEED=40 + +# +# The default FIFO size if, not specified elswhere. +# +CDR_FIFOSIZE=12m + +# +# CDR_MAXFIFOSIZE can limit the maximum allowed FIFO size. This is useful to +# not let mallicious users allocate too much system memory if no ulimit is set +# or wodim runs with suid-root permissions. +# +# CDR_MAXFIFOSIZE=256m + +# +# The following definitions allow abstract device names. They are used if the +# device name does not contain the the characters ',', ':', '/' and '@' +# +# Unless you have a good reason, use speed == -1 and let wodim use its internal +# drive specific defaults. +# +# drive name device speed fifosize driveropts +# +#default= USCSI:1,0,0 -1 -1 burnfree +#sanyo= 1,4,0 -1 -1 burnfree +#cdrom= 0,6,0 2 1m "" +#remote= REMOTE:rscsi@somehost:1,0,0 16 32m burnfree +# +cdrom= -1 -1 -1 burnfree + diff --git a/wodim/wodim.h b/wodim/wodim.h new file mode 100644 index 0000000..0dfdfdc --- /dev/null +++ b/wodim/wodim.h @@ -0,0 +1,1212 @@ +/* + * 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. + * + */ + +/* @(#)cdrecord.h 1.165 05/06/11 Copyright 1995-2005 J. Schilling */ +/* + * Definitions for cdrecord + * + * Copyright (c) 1995-2005 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. + */ + +/* + * Make sure it is there. We need it for off_t. + */ +#ifndef _INCL_SYS_TYPES_H +#include <sys/types.h> +#define _INCL_SYS_TYPES_H +#endif + +#ifndef _UTYPES_H +#include <utypes.h> +#endif + +/* + * Defines for command line option flags + */ +#define F_DUMMY 0x00000001L /* Do dummy (simulation) writes */ +#define F_TOC 0x00000002L /* Get TOC */ +#define F_EJECT 0x00000004L /* Eject disk after doing the work */ +#define F_LOAD 0x00000008L /* Load disk only */ +#define F_MULTI 0x00000010L /* Create linkable TOC/multi-session */ +#define F_MSINFO 0x00000020L /* Get multi-session info */ +#define F_FIX 0x00000040L /* Fixate disk only */ +#define F_NOFIX 0x00000080L /* Do not fixate disk */ +#define F_VERSION 0x00000100L /* Print version info */ +#define F_CHECKDRIVE 0x00000200L /* Check for driver */ +#define F_INQUIRY 0x00000400L /* Do inquiry */ +#define F_PRCAP 0x00000800L /* Print capabilities */ +#define F_SCANBUS 0x00001000L /* Scan SCSI Bus */ +#define F_RESET 0x00002000L /* Reset SCSI Bus */ +#define F_BLANK 0x00004000L /* Blank CD-RW */ +#define F_PRATIP 0x00008000L /* Print ATIP info */ +#define F_PRDINFO 0x00010000L /* Print disk info (XXX not yet used) */ +#define F_IGNSIZE 0x00020000L /* Ignore disk size */ +#define F_SAO 0x00040000L /* Session at once */ +#define F_RAW 0x00080000L /* Raw mode */ +#define F_WRITE 0x00100000L /* Disk is going to be written */ +#define F_FORCE 0x00200000L /* Force things (e.g. blank on dead disk) */ +#define F_WAITI 0x00400000L /* Wait until data is available on stdin */ +#define F_OVERBURN 0x00800000L /* Allow oveburning */ +#define F_CLONE 0x01000000L /* Do clone writing */ +#define F_STDIN 0x02000000L /* We are using stdin as CD data */ +#define F_IMMED 0x04000000L /* Try tu use IMMED SCSI flag if possible */ +#define F_DLCK 0x08000000L /* Load disk and lock door */ +#define F_SETDROPTS 0x10000000L /* Set driver opts and exit */ +#define F_FORMAT 0x20000000L /* Format media */ +#define F_ABORT 0x40000000L /* Send abort sequence to drive */ + +#ifdef min +#undef min +#endif +#define min(a, b) ((a) < (b) ? (a):(b)) + +#ifdef max +#undef max +#endif +#define max(a, b) ((a) < (b) ? (b):(a)) + +#undef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) + +/* + * NOTICE: You should not make CDR_BUF_SIZE more than + * the buffer size of the CD-Recorder. + * + * The Philips CDD 521 is the recorder with the smallest buffer. + * It only has 256kB of buffer RAM. + * + * WARNING: Philips CDD 521 dies if CDR_BUF_SIZE is to big. + * If you like to support the CDD 521 keep the buffer + * at 63kB. + */ +/*#define CDR_BUF_SIZE (126*1024)*/ +#define CDR_BUF_SIZE (63*1024) +#define CDR_MAX_BUF_SIZE (256*1024) + +/* + * Never set MIN_GRACE_TIME < 3 seconds. We need to give + * the volume management a chance to settle before we + * start writing. + */ +#ifndef MIN_GRACE_TIME +#define MIN_GRACE_TIME 0 /* changed to 0, there is no point in forcing it in this application. Fix your volume management if it breaks because it could not read the medium. */ +#endif +#ifndef GRACE_TIME +#define GRACE_TIME 4 +#endif + +/* + * Some sector sizes used for reading/writing ... + */ +#define DATA_SEC_SIZE 2048 /* 2048 bytes */ +#define MODE2_SEC_SIZE 2336 /* 2336 bytes */ +#define AUDIO_SEC_SIZE 2352 /* 2352 bytes */ +#define RAW16_SEC_SIZE (2352+16) /* 2368 bytes */ +#define RAW96_SEC_SIZE (2352+96) /* 2448 bytes */ + +#define MAX_TRACK 99 /* Red Book track limit */ + +#define PAD_SECS 15 /* NOTE: pad must be less than BUF_SIZE */ +#define PAD_SIZE (PAD_SECS * DATA_SEC_SIZE) + +/* + * FIFO size must be at least 2x CDR_MAX_BUF_SIZE + */ +#define DEFAULT_FIFOSIZE (4L*1024L*1024L) + +#if !defined(HAVE_LARGEFILES) && SIZEOF_LLONG > SIZEOF_LONG +typedef Llong tsize_t; +#else +typedef off_t tsize_t; +#endif + +#ifdef nono +typedef struct tindex { + int dummy; /* Not yet implemented */ +} tindex_t; +#endif + +typedef struct ofile { + struct ofile *next; /* Next open file */ + int f; /* Open file */ + char *filename; /* File name */ + int refcnt; /* open reference count */ +} ofile_t; + +typedef struct track { + void *xfp; /* Open file for this track from xopen()*/ + char *filename; /* File name for this track */ + + tsize_t itracksize; /* Size of track bytes (-1 == until EOF)*/ + /* This is in units of isecsize */ + tsize_t tracksize; /* Size of track bytes (-1 == until EOF)*/ + /* This is in units of secsize */ + + long trackstart; /* Start sector # of this track */ + long tracksecs; /* Size of this track (sectors) */ + long padsecs; /* Pad size for this track (sectors) */ + long pregapsize; /* Pre-gap size for this track (sectors)*/ + long index0start; /* Index 0 start within this tr(sectors)*/ + int isecsize; /* Read input sector size for this track*/ + int secsize; /* Sector size for this track (bytes) */ + int secspt; /* # of sectors to copy for one transfer*/ + int pktsize; /* # of blocks per write packet */ + Uchar dataoff; /* offset of user data in raw sector */ + Uchar tracks; /* Number of tracks on this disk */ + Uchar track; /* Track # as offset in track[] array */ + Uchar trackno; /* Track # on disk for this track */ + Uchar tracktype; /* Track type (toc type) */ + Uchar dbtype; /* Data block type for this track */ + int sectype; /* Sector type */ + int flags; /* Flags (see below) */ + int nindex; /* Number of indices for track */ + long *tindex; /* Track index descriptor */ + char *isrc; /* ISRC code for this track / disk MCN */ + void *text; /* Opaque CD-Text data (txtptr_t *) */ +} track_t; + +#define track_base(tp) ((tp) - (tp)->track) + +/* + * Defines for tp->flags + */ +#define TI_AUDIO 0x00001 /* File is an audio track */ +#define TI_PREEMP 0x00002 /* Audio track recorded w/preemphasis */ +#define TI_MIX 0x00004 /* This is a mixed mode track */ +#define TI_RAW 0x00008 /* Write this track in raw mode */ +#define TI_PAD 0x00010 /* Pad data track */ +#define TI_SWAB 0x00020 /* Swab audio data */ +#define TI_ISOSIZE 0x00040 /* Use iso size for track */ +#define TI_NOAUHDR 0x00080 /* Don't look for audio header */ +#define TI_FIRST 0x00100 /* This is the first track */ +#define TI_LAST 0x00200 /* This is the last track */ +#define TI_PACKET 0x00400 /* Fixed- or variable-packet track */ +#define TI_NOCLOSE 0x00800 /* Don't close the track after writing */ +#define TI_TAO 0x01000 /* This track is written in TAO mode */ +#define TI_PREGAP 0x02000 /* Prev. track incl. pregap of this tr. */ +#define TI_SCMS 0x04000 /* Force to follow the SCMS rules */ +#define TI_COPY 0x08000 /* Allow digital copy */ +#define TI_SHORT_TRACK 0x10000 /* Ignore min 4 second Red Book std. */ +#define TI_RAW16 0x20000 /* This track uses 16 bytes subch. */ +#define TI_RAW96R 0x40000 /* This track uses 96 bytes RAW subch. */ +#define TI_CLONE 0x80000 /* Special clone treatment needed */ +#define TI_TEXT 0x100000 /* This track holds CD-Text information */ +#define TI_DVD 0x200000 /* We are writing a DVD track */ +#define TI_SAO 0x400000 /* This track is written in SAO mode */ +#define TI_USEINFO 0x800000 /* Use information from *.inf files */ +#define TI_QUADRO 0x1000000 /* Four Channel Audio Data */ + + +#define is_audio(tp) (((tp)->flags & TI_AUDIO) != 0) +#define is_preemp(tp) (((tp)->flags & TI_PREEMP) != 0) +#define is_pad(tp) (((tp)->flags & TI_PAD) != 0) +#define is_swab(tp) (((tp)->flags & TI_SWAB) != 0) +#define is_first(tp) (((tp)->flags & TI_FIRST) != 0) +#define is_last(tp) (((tp)->flags & TI_LAST) != 0) +#define is_packet(tp) (((tp)->flags & TI_PACKET) != 0) +#define is_noclose(tp) (((tp)->flags & TI_NOCLOSE) != 0) +#define is_tao(tp) (((tp)->flags & TI_TAO) != 0) +#define is_sao(tp) (((tp)->flags & TI_SAO) != 0) +#define is_raw(tp) (((tp)->flags & TI_RAW) != 0) +#define is_raw16(tp) (((tp)->flags & TI_RAW16) != 0) +#define is_raw96(tp) (((tp)->flags & (TI_RAW|TI_RAW16)) == TI_RAW) +#define is_raw96p(tp) (((tp)->flags & (TI_RAW|TI_RAW16|TI_RAW96R)) == TI_RAW) +#define is_raw96r(tp) (((tp)->flags & (TI_RAW|TI_RAW16|TI_RAW96R)) == (TI_RAW|TI_RAW96R)) +#define is_pregap(tp) (((tp)->flags & TI_PREGAP) != 0) +#define is_scms(tp) (((tp)->flags & TI_SCMS) != 0) +#define is_copy(tp) (((tp)->flags & TI_COPY) != 0) +#define is_shorttrk(tp) (((tp)->flags & TI_SHORT_TRACK) != 0) +#define is_clone(tp) (((tp)->flags & TI_CLONE) != 0) +#define is_text(tp) (((tp)->flags & TI_TEXT) != 0) +#define is_quadro(tp) (((tp)->flags & TI_QUADRO) != 0) + +/* + * Defines for toc type / track type + */ +#define TOC_DA 0 /* CD-DA */ +#define TOC_ROM 1 /* CD-ROM */ +#define TOC_XA1 2 /* CD_ROM XA with first track in mode 1 */ +#define TOC_XA2 3 /* CD_ROM XA with first track in mode 2 */ +#define TOC_CDI 4 /* CDI */ + +#define TOC_MASK 7 /* Mask needed for toctname[] */ + +/* + * Additional flags in toc type / trackp->tracktype + * XXX TOCF_DUMMY istr schon in dp->cdr_cmdflags & F_DUMMY + * XXX TOCF_MULTI istr schon in dp->cdr_cmdflags & F_MULTI + */ +#define TOCF_DUMMY 0x10 /* Write in dummy (simulation) mode */ +#define TOCF_MULTI 0x20 /* Multisession (Open Next Programarea) */ + +#define TOCF_MASK 0xF0 /* All possible flags in tracktype */ + +extern char *toc2name[]; /* Convert toc type to name */ +extern int toc2sess[]; /* Convert toc type to session format */ + +/* + * Defines for sector type + * + * Mode is 2 bits + * Aud is 1 bit + * + * Sector is: aud << 2 | mode + */ +#define ST_ROM_MODE1 1 /* CD-ROM in mode 1 (vanilla cdrom) */ +#define ST_ROM_MODE2 2 /* CD-ROM in mode 2 */ +#define ST_AUDIO_NOPRE 4 /* CD-DA stereo without preemphasis */ +#define ST_AUDIO_PRE 5 /* CD-DA stereo with preemphasis */ + +#define ST_PREEMPMASK 0x01 /* Mask for preemphasis bit */ +#define ST_AUDIOMASK 0x04 /* Mask for audio bit */ +#define ST_MODEMASK 0x03 /* Mask for mode bits in sector type */ +#define ST_MASK 0x07 /* Mask needed for sectname[] */ + +/* + * There are 6 different generic basic sector types. + */ +#define ST_MODE_AUDIO 0x00 /* Generic Audio mode */ +#define ST_MODE_0 0x10 /* Generic Zero mode */ +#define ST_MODE_1 0x20 /* Generic CD-ROM mode (ISO/IEC 10149) */ +#define ST_MODE_2 0x30 /* Generic Mode 2 (ISO/IEC 10149) */ +#define ST_MODE_2_FORM_1 0x40 /* Generic Mode 2 form 1 */ +#define ST_MODE_2_FORM_2 0x50 /* Generic Mode 2 form 2 */ +#define ST_MODE_2_MIXED 0x60 /* Generic Mode 2 mixed form (1/2) */ + +#define ST_MODE_MASK 0x70 /* Mask needed to get generic sectype */ + +#define ST_MODE_RAW 0x08 /* Do not touch EDC & subchannels */ +#define ST_NOSCRAMBLE 0x80 /* Do not srcamble sectors */ + +#define SECT_AUDIO (ST_AUDIO_NOPRE | ST_MODE_AUDIO) +#define SECT_AUDIO_NOPRE (ST_AUDIO_NOPRE | ST_MODE_AUDIO) +#define SECT_AUDIO_PRE (ST_AUDIO_PRE | ST_MODE_AUDIO) +#define SECT_MODE_0 (ST_ROM_MODE1 | ST_MODE_0) +#define SECT_ROM (ST_ROM_MODE1 | ST_MODE_1) +#define SECT_MODE_2 (ST_ROM_MODE2 | ST_MODE_2) +#define SECT_MODE_2_F1 (ST_ROM_MODE2 | ST_MODE_2_FORM_1) +#define SECT_MODE_2_F2 (ST_ROM_MODE2 | ST_MODE_2_FORM_2) +#define SECT_MODE_2_MIX (ST_ROM_MODE2 | ST_MODE_2_MIXED) + +extern char *st2name[]; /* Convert sector type to name */ +extern int st2mode[]; /* Convert sector type to control nibble*/ + +/* + * Control nibble bits: + * + * 0 with preemphasis (audio) / incremental (data) + * 1 digital copy permitted + * 2 data (not audio) track + * 3 4 channels (not 2) + */ +#define TM_PREEM 0x1 /* Audio track with preemphasis */ +#define TM_INCREMENTAL 0x1 /* Incremental data track */ +#define TM_ALLOW_COPY 0x2 /* Digital copy permitted */ +#define TM_DATA 0x4 /* This is a data track */ +#define TM_QUADRO 0x8 /* Four channel audio */ + +/* + * Adr nibble: + */ +#define ADR_NONE 0 /* Sub-Q mode info not supplied */ +#define ADR_POS 1 /* Sub-Q encodes position data */ +#define ADR_MCN 2 /* Sub-Q encodes Media Catalog Number */ +#define ADR_ISRC 3 /* Sub-Q encodes ISRC */ + +/* + * Defines for write type (from SCSI-3/mmc) + */ +#define WT_PACKET 0x0 /* Packet writing */ +#define WT_TAO 0x1 /* Track at once */ +#define WT_SAO 0x2 /* Session at once */ +#define WT_RAW 0x3 /* Raw */ +#define WT_RES_4 0x4 /* Reserved */ +#define WT_RES_5 0x5 /* Reserved */ +#define WT_RES_6 0x6 /* Reserved */ +#define WT_RES_7 0x7 /* Reserved */ +#define WT_RES_8 0x8 /* Reserved */ +#define WT_RES_9 0x9 /* Reserved */ +#define WT_RES_A 0xA /* Reserved */ +#define WT_RES_B 0xB /* Reserved */ +#define WT_RES_C 0xC /* Reserved */ +#define WT_RES_D 0xD /* Reserved */ +#define WT_RES_E 0xE /* Reserved */ +#define WT_RES_F 0xF /* Reserved */ + +/* + * Data block layout: + * + * - Sync pattern 12 Bytes: 0x00 0xFF 0xFF ... 0xFF 0xFF 0x00 + * - Block header 4 Bytes: | minute | second | frame | mode | + * Mode byte: + * Bits 7, 6, 5 Run-in/Run-out/Link + * Bits 4, 3, 2 Reserved + * Bits 1, 0 Mode + * - Rest of sector see below. + * + * Mode 0 Format: + * 0 12 Bytes Sync header + * 12 4 Bytes Block header with Data mode == 0 + * 16 2336 Bytes of zero data + * + * Mode 1 Format: + * 0 12 Bytes Sync header + * 12 4 Bytes Block header with Data mode == 1 + * 16 2048 Bytes of user data + * 2064 4 Bytes CRC for Bytes 0-2063 + * 2068 8 Bytes Zero fill + * 2076 172 Bytes P parity symbols + * 2248 104 Bytes Q parity symbols + * + * Mode 2 Format (formless): + * 0 12 Bytes Sync header + * 12 4 Bytes Block header with Data mode == 2 + * 16 2336 Bytes of user data + * + * Mode 2 form 1 Format: + * 0 12 Bytes Sync header + * 12 4 Bytes Block header with Data mode == 2 + * 16 4 Bytes subheader first copy + * 20 4 Bytes subheader second copy + * 24 2048 Bytes of user data + * 2072 4 Bytes CRC for Bytes 16-2071 + * 2076 172 Bytes P parity symbols + * 2248 104 Bytes Q parity symbols + * + * Mode 2 form 2 Format: + * 0 12 Bytes Sync header + * 12 4 Bytes Block header with Data mode == 2 + * 16 4 Bytes subheader first copy + * 20 4 Bytes subheader second copy + * 24 2324 Bytes of user data + * 2348 4 Bytes Optional CRC for Bytes 16-2347 + */ + +/* + * Mode Byte definitions (the 4th Byte in the Block header) + */ +#define SH_MODE_DATA 0x00 /* User Data Block */ +#define SH_MODE_RI4 0x20 /* Fourth run in Block */ +#define SH_MODE_RI3 0x40 /* Third run in Block */ +#define SH_MODE_RI2 0x60 /* Second run in Block */ +#define SH_MODE_RI1 0x80 /* First run in Block */ +#define SH_MODE_LINK 0xA0 /* Link Block */ +#define SH_MODE_RO2 0xC0 /* Second run out Block */ +#define SH_MODE_RO1 0xE0 /* First run out Block */ +#define SH_MODE_M0 0x00 /* Mode 0 Data */ +#define SH_MODE_M1 0x01 /* Mode 1 Data */ +#define SH_MODE_M2 0x02 /* Mode 2 Data */ +#define SH_MODE_MR 0x03 /* Reserved */ + +/* + * Defines for data block type (from SCSI-3/mmc) + * + * Mandatory are only: + * DB_ROM_MODE1 (8) Mode 1 (ISO/IEC 10149) + * DB_XA_MODE2 (10) Mode 2-F1 (CD-ROM XA form 1) + * DB_XA_MODE2_MIX (13) Mode 2-MIX (CD-ROM XA 1/2+subhdr) + */ +#define DB_RAW 0 /* 2352 bytes of raw data */ +#define DB_RAW_PQ 1 /* 2368 bytes (raw data + P/Q Subchannel) */ +#define DB_RAW_PW 2 /* 2448 bytes (raw data + P-W Subchannel) */ +#define DB_RAW_PW_R 3 /* 2448 bytes (raw data + P-W raw Subchannel)*/ +#define DB_RES_4 4 /* - Reserved */ +#define DB_RES_5 5 /* - Reserved */ +#define DB_RES_6 6 /* - Reserved */ +#define DB_VU_7 7 /* - Vendor specific */ +#define DB_ROM_MODE1 8 /* 2048 bytes Mode 1 (ISO/IEC 10149) */ +#define DB_ROM_MODE2 9 /* 2336 bytes Mode 2 (ISO/IEC 10149) */ +#define DB_XA_MODE2 10 /* 2048 bytes Mode 2 (CD-ROM XA form 1) */ +#define DB_XA_MODE2_F1 11 /* 2056 bytes Mode 2 (CD-ROM XA form 1) */ +#define DB_XA_MODE2_F2 12 /* 2324 bytes Mode 2 (CD-ROM XA form 2) */ +#define DB_XA_MODE2_MIX 13 /* 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */ +#define DB_RES_14 14 /* - Reserved */ +#define DB_VU_15 15 /* - Vendor specific */ + +extern char *db2name[]; /* Convert data block type to name */ + +/* + * Defines for multi session type (from SCSI-3/mmc) + */ +#define MS_NONE 0 /* No B0 pointer. Next session not allowed*/ +#define MS_FINAL 1 /* B0 = FF:FF:FF. Next session not allowed*/ +#define MS_RES 2 /* Reserved */ +#define MS_MULTI 3 /* B0 = Next PA. Next session allowed */ + +/* + * Defines for session format (from SCSI-3/mmc) + */ +#define SES_DA_ROM 0x00 /* CD-DA or CD-ROM disk */ +#define SES_CDI 0x10 /* CD-I disk */ +#define SES_XA 0x20 /* CD-ROM XA disk */ +#define SES_UNDEF 0xFF /* Undefined disk type (read disk info) */ + +/* + * Defines for blanking of CD-RW discs (from SCSI-3/mmc) + */ +#define BLANK_DISC 0x00 /* Erase the entire disc */ +#define BLANK_MINIMAL 0x01 /* Erase the PMA, 1st session TOC, pregap */ +#define BLANK_TRACK 0x02 /* Erase an incomplete track */ +#define BLANK_UNRESERVE 0x03 /* Unreserve a track */ +#define BLANK_TAIL 0x04 /* Erase the tail of a track */ +#define BLANK_UNCLOSE 0x05 /* Unclose the last session */ +#define BLANK_SESSION 0x06 /* Erase the last session */ + +/* + * Defines for formating DVD (custom values) + */ +#define FULL_FORMAT 0x00 /* Interactive format */ +#define BACKGROUND_FORMAT 0x01 /* Background format */ +#define FORCE_FORMAT 0x02 /* Force reformat */ + +/* + * Defines for formating DVD (custom values) + */ +#define FULL_FORMAT 0x00 /* Interactive format */ +#define BACKGROUND_FORMAT 0x01 /* Background format */ +#define FORCE_FORMAT 0x02 /* Force reformat */ + +/* + * Useful definitions for audio tracks + */ +#define msample (44100 * 2) /* one 16bit audio sample */ +#define ssample (msample * 2) /* one stereo sample */ +#define samples(v) ((v) / ssample) /* # of stereo samples */ +#define hsamples(v) ((v) / (ssample/100)) /* 100* # of stereo samples/s*/ +#define fsamples(v) ((v) / (ssample/75)) /* 75* # of stereo samples/s */ + +#define minutes(v) ((int)(samples(v) / 60)) +#define seconds(v) ((int)(samples(v) % 60)) +#define hseconds(v) ((int)(hsamples(v) % 100)) +#define frames(v) ((int)(fsamples(v) % 75)) + +/* + * sector based macros + */ +#define Sminutes(s) ((int)((s) / (60*75))) +#define Sseconds(s) ((int)((s) / 75)) +#define Shseconds(s) ((int)(((s) % 75)*100)/75) +#define Sframes(s) ((int)((s) % 75)) + +typedef struct msf { + char msf_min; + char msf_sec; + char msf_frame; +} msf_t; + +/* + * Definitions for read TOC/PMA/ATIP command + */ +#define FMT_TOC 0 +#define FMT_SINFO 1 +#define FMT_FULLTOC 2 +#define FMT_PMA 3 +#define FMT_ATIP 4 +#define FMT_CDTEXT 5 + +/* + * Definitions for read disk information "recording flags" + * used in UInt16_t "ds_cdrflags". + */ +#define RF_WRITE 0x0001 /* Disk is going to be written */ +#define RF_BLANK 0x0002 /* Disk is going to be erased */ +#define RF_PRATIP 0x0004 /* Print ATIP info */ +#define RF_LEADIN 0x0008 /* Lead-in has been "manually" written */ +#define RF_BURNFREE 0x0010 /* BUFFER underrun free recording */ +#define RF_VARIREC 0x0020 /* Plextor VariRec */ +#define RF_AUDIOMASTER 0x0040 /* Yamaha AudioMaster */ +#define RF_FORCESPEED 0x0080 /* WriteSpeed forced high */ +#define RF_DID_STAT 0x0100 /* Already did call cdrstats() */ +#define RF_DID_CDRSTAT 0x0200 /* Already did call (*dp->cdr_stats)() */ +#define RF_WR_WAIT 0x0400 /* Wait during writing to free bus */ +#define RF_SINGLESESS 0x0800 /* Plextor single sess. mode */ +#define RF_HIDE_CDR 0x1000 /* Plextor hide CDR features */ +#define RF_SPEEDREAD 0x2000 /* Plextor SpeedReed */ +#define RF_GIGAREC 0x4000 /* Plextor GigaRec */ + +/* + * Definitions for read disk information "disk status" + * used in "ds_diskstat". + */ +#define DS_EMPTY 0 /* Empty disk */ +#define DS_APPENDABLE 1 /* Incomplete disk (appendable) */ +#define DS_COMPLETE 2 /* Complete disk (closed/no B0 pointer) */ +#define DS_RESERVED 3 /* Reserved */ + +/* + * Definitions for read disk information "session status" + * used in "ds_sessstat". + */ +#define SS_EMPTY 0 /* Empty session */ +#define SS_APPENDABLE 1 /* Incomplete session */ +#define SS_RESERVED 2 /* Reserved */ +#define SS_COMPLETE 3 /* Complete session (needs DS_COMPLETE) */ + +/* + * Definitions for disk_status write mode + * used in "ds_wrmode". + */ +#define WM_NONE 0 /* No write mode selected */ +#define WM_BLANK 1 /* Blanking mode */ +#define WM_FORMAT 2 /* Formatting */ +#define WM_PACKET 4 /* Packet writing */ +#define WM_TAO 8 /* Track at Once */ +#define WM_SAO 12 /* Session at Once w/ cooked sectors */ +#define WM_SAO_RAW16 13 /* Session at Once RAW+16 byte sectors */ +#define WM_SAO_RAW96P 14 /* Session at Once RAW+96P byte sectors */ +#define WM_SAO_RAW96R 15 /* Session at Once RAW+96R byte sectors */ +#define WM_RAW 16 /* RAW with cooked sectors is impossible*/ +#define WM_RAW_RAW16 17 /* RAW with RAW+16 byte sectors */ +#define WM_RAW_RAW96P 18 /* RAW with RAW+96P byte sectors */ +#define WM_RAW_RAW96R 19 /* RAW with RAW+96R byte sectors */ + +#define wm_base(wm) ((wm)/4*4) /* The basic write mode for this mode */ + +/* + * Definitions for disk_status flags + * used in UInt16_t "ds_flags". + */ +#define DSF_DID_V 0x0001 /* Disk id valid */ +#define DSF_DBC_V 0x0002 /* Disk bar code valid */ +#define DSF_URU 0x0004 /* Disk is for unrestricted use */ +#define DSF_ERA 0x0008 /* Disk is erasable */ +#define DSF_HIGHSP_ERA 0x0010 /* Disk is high speed erasable */ +#define DSF_ULTRASP_ERA 0x0020 /* Disk is ultra speed erasable */ +#define DSF_ULTRASPP_ERA 0x0040 /* Disk is ultra speed+ erasable */ + + +#define DSF_DVD 0x0100 /* Disk is a DVD */ +#define DSF_DVD_PLUS_R 0x0200 /* Disk is a DVD+R */ +#define DSF_DVD_PLUS_RW 0x0400 /* Disk is a DVD+RW */ +#define DSF_NEED_FORMAT 0x0800 /* Disk needs to be formatted */ + +/* + * Definitions for disktype flags + */ +#define DT_CD 0x001 /*is a CD */ +#define DT_DVD 0x002 /*is a DVD */ + +/* + * Definitions for disktype flags + */ +#define DT_CD 0x001 /*is a CD */ +#define DT_DVD 0x002 /*is a DVD */ + +/* + * Definitions for disk_status disk type + * used in "ds_type". + */ +/* None defined yet */ + +typedef struct disk_status dstat_t; + +struct disk_status { + UInt32_t ds_diskid; /* Disk identification */ + UInt16_t ds_cdrflags; /* Recording flags from cdrecord*/ + UInt16_t ds_flags; /* Disk_status flags */ + Uchar ds_wrmode; /* Selected write mode */ + Uchar ds_type; /* Abstract disk type */ + + Uchar ds_disktype; /* Disk type (from TOC/PMA) */ + Uchar ds_diskstat; /* Disk status (MMC) */ + Uchar ds_sessstat; /* Status of last sesion (MMC) */ + Uchar ds_trfirst; /* first track # */ + Uchar ds_trlast; /* last track # */ + Uchar ds_trfirst_ls; /* first track # in last session*/ + Uchar ds_barcode[8]; /* Disk bar code */ + + Int32_t ds_first_leadin; /* Start of first lead in (ATIP)*/ + Int32_t ds_last_leadout; /* Start of last lead out (ATIP)*/ + Int32_t ds_curr_leadin; /* Start of next lead in */ + Int32_t ds_curr_leadout; /* Start of next lead out */ + + Int32_t ds_maxblocks; /* # of official blocks on disk */ + Int32_t ds_maxrblocks; /* # real blocks on disk */ + Int32_t ds_fwa; /* first writable addr */ + + Int32_t ds_startsec; /* Actual start sector */ + Int32_t ds_endsec; /* Actual end sector */ + Int32_t ds_buflow; /* # of times drive buffer empty*/ + + UInt16_t ds_minbuf; /* Minimum drive bufer fill rt. */ + + UInt16_t ds_at_min_speed; /* The minimal ATIP write speed */ + UInt16_t ds_at_max_speed; /* The maximal ATIP write speed */ + UInt16_t ds_dr_cur_rspeed; /* The drive's cur read speed */ + UInt16_t ds_dr_max_rspeed; /* The drive's max read speed */ + UInt16_t ds_dr_cur_wspeed; /* The drive's cur write speed */ + UInt16_t ds_dr_max_wspeed; /* The drive's max write speed */ + UInt16_t ds_wspeed; /* The selected/drive wr. speed */ +}; + +/* + * First approach of a CDR device abstraction layer. + * This interface will change as long as I did not find the + * optimum that fits for all devices. + * + * Called with pointer to whole track array: + * cdr_send_cue() + * cdr_write_leadin() + * cdr_open_session() + * cdr_fixate() + * + * Called with (track_t *) 0 or pointer to current track: + * cdr_next_wr_address() + * + * Called with pointer to current track: + * cdr_open_track() + * cdr_close_track() + * + * Calling sequence: + * cdr_identify() May modify driver + * Here, the cdr_t will be allocated and + * copied to a new writable area. + * cdr_attach() Get drive properties + * cdr_buffer_cap() + * cdr_getdisktype() GET ATIP + * cdr_init() set TAO for -msinfo + * cdr_check_session XXX ???? + * cdr_opt1() set early options + * cdr_set_speed_dummy(usalp, dp, &speed) + * <--- Grace time processing goes here + * { do_opc(); cdr_blank() } + * cdr_opt2() set late options + * cdr_open_session() set up params (no wrt.) + * do_opc() + * cdr_write_leadin() start writing + * LOOP { + * cdr_open_track() + * cdr_next_wr_address() only TAO / Packet + * write_track_data() + * cdr_close_track() + * } + * write_leadout() XXX should go -> driver! + * cdr_fixate() + * cdr_stats() + */ +/*--------------------------------------------------------------------------*/ +typedef struct cdr_cmd cdr_t; + +#ifdef _SCG_SCSITRANSP_H +struct cdr_cmd { + int cdr_dev; /* Numerical device type */ + UInt32_t cdr_cmdflags; /* Command line options */ + UInt32_t cdr_flags; /* Drive related flags */ + UInt8_t cdr_cdrw_support; /* CD-RW write media types */ + UInt16_t cdr_speeddef; /* Default write speed */ + UInt16_t cdr_speedmax; /* Max. write speed */ + + char *cdr_drname; /* Driver ID string */ + char *cdr_drtext; /* Driver ID text */ + struct cd_mode_page_2A *cdr_cdcap; + dstat_t *cdr_dstat; +#ifdef _SCG_SCSIREG_H + /* identify drive */ + cdr_t *(*cdr_identify)(SCSI *usalp, cdr_t *, struct scsi_inquiry *); +#else + /* identify drive */ + cdr_t *(*cdr_identify)(SCSI *usalp, cdr_t *, void *); +#endif + /* init error decoding etc*/ + int (*cdr_attach)(SCSI *usalp, cdr_t *); + /* init drive to useful deflts */ + int (*cdr_init)(SCSI *usalp, cdr_t *); + /* get disk type */ + int (*cdr_getdisktype)(SCSI *usalp, cdr_t *); + /* load disk */ + int (*cdr_load)(SCSI *usalp, cdr_t *); + /* unload disk */ + int (*cdr_unload)(SCSI *usalp, cdr_t *); + /* read buffer capacity */ + int (*cdr_buffer_cap)(SCSI *usalp, long *sizep, long *freep); + /* check if recover is needed */ + int (*cdr_check_recovery)(SCSI *usalp, cdr_t *); + /* do recover */ + int (*cdr_recover)(SCSI *usalp, cdr_t *, int track); + /* set recording speed & dummy write */ + int (*cdr_set_speed_dummy)(SCSI *usalp, cdr_t *, int *speedp); + /* set sector size */ + int (*cdr_set_secsize)(SCSI *usalp, int secsize); + /* get next writable addr. */ + int (*cdr_next_wr_address)(SCSI *usalp, track_t *trackp, long *ap); + /* reserve track for future use */ + int (*cdr_reserve_track)(SCSI *usalp, Ulong len); + int (*cdr_write_trackdata)(SCSI *usalp, caddr_t buf, long daddr, long bytecnt, + int seccnt, BOOL islast); + /* generate cue sheet */ + int (*cdr_gen_cue)(track_t *trackp, void *cuep, BOOL needgap); + /* send cue sheet */ + int (*cdr_send_cue)(SCSI *usalp, cdr_t *, track_t *trackp); + /* write leadin */ + int (*cdr_write_leadin)(SCSI *usalp, cdr_t *, track_t *trackp); + /* open new track */ + int (*cdr_open_track)(SCSI *usalp, cdr_t *, track_t *trackp); + /* close written track */ + int (*cdr_close_track)(SCSI *usalp, cdr_t *, track_t *trackp); + /* open new session */ + int (*cdr_open_session)(SCSI *usalp, cdr_t *, track_t *trackp); + /* really needed ??? */ + int (*cdr_close_session)(SCSI *usalp, cdr_t *); + /* abort current write */ + int (*cdr_abort_session)(SCSI *usalp, cdr_t *); + /* read session offset*/ + int (*cdr_session_offset)(SCSI *usalp, long *soff); + /* write toc on disk */ + int (*cdr_fixate)(SCSI *usalp, cdr_t *, track_t *trackp); + /* final statistics printing*/ + int (*cdr_stats)(SCSI *usalp, cdr_t *); + /* blank something */ + int (*cdr_blank)(SCSI *usalp, cdr_t *, long addr, int blanktype); + /* format media */ + int (*cdr_format)(SCSI *usalp, cdr_t *, int fmtflags); + /* Do OPC */ + int (*cdr_opc)(SCSI *usalp, caddr_t bp, int cnt, int doopc); + /* do early option processing*/ + int (*cdr_opt1)(SCSI *usalp, cdr_t *); + /* do late option processing */ + int (*cdr_opt2)(SCSI *usalp, cdr_t *); + /* calculate optimale split */ + int (*cdr_layer_split)(SCSI *usalp, cdr_t *, long tsize); + int profile; + BOOL is_dvd; +}; +#endif + +/* + * Definitions for cdr_flags + */ +#define CDR_TAO 0x01 /* Drive supports Track at once */ +#define CDR_SAO 0x02 /* Drive supports Sess at once */ +#define CDR_PACKET 0x04 /* Drive supports packet writing*/ +#define CDR_RAW 0x08 /* Drive supports raw writing */ +#define CDR_RAW16 0x10 /* Drive supports RAW raw16 */ +#define CDR_RAW96P 0x20 /* Drive supports RAW raw96 pak */ +#define CDR_RAW96R 0x40 /* Drive supports RAW raw96 raw */ +#ifdef __needed__ +#define CDR_SRAW16 0x100 /* Drive supports SAO raw16 */ +#endif +#define CDR_SRAW96P 0x200 /* Drive supports SAO raw96 pak */ +#define CDR_SRAW96R 0x400 /* Drive supports SAO raw96 raw */ +#define CDR_SWABAUDIO 0x1000 /* Drive swabs audio data */ +#define CDR_ISREADER 0x2000 /* Drive is s CD-ROM reader */ +#define CDR_TRAYLOAD 0x4000 /* Drive loads CD with tray */ +#define CDR_CADDYLOAD 0x8000 /* Drive loads CD with caddy */ +#define CDR_NO_LOLIMIT 0x10000 /* Drive ignores lead-out limit */ +#define CDR_DVD 0x20000 /* Drive is a DVD drive */ +#define CDR_SIMUL 0x40000 /* Drive is simulated */ +#define CDR_BURNFREE 0x80000 /* Drive sup. BUFund. free rec. */ +#define CDR_VARIREC 0x100000 /* Drive sup. VariRec Plex. */ +#define CDR_AUDIOMASTER 0x200000 /* Drive sup. AudioMaster Yamah.*/ +#define CDR_FORCESPEED 0x400000 /* Drive sup. WriteSpeed ctl. */ +#define CDR_DISKTATTOO 0x800000 /* Drive sup. Yamaha DiskT@2 */ +#define CDR_SINGLESESS 0x1000000 /* Drive sup. single sess. mode */ +#define CDR_HIDE_CDR 0x2000000 /* Drive sup. hide CDR features */ +#define CDR_SPEEDREAD 0x4000000 /* Drive sup. SpeedReed */ +#define CDR_GIGAREC 0x8000000 /* Drive sup. GigaRec Plex. */ +#define CDR_MMC 0x10000000 /* Drive is MMC compliant */ +#define CDR_MMC2 0x20000000 /* Drive is MMC-2 compliant */ +#define CDR_MMC3 0x40000000 /* Drive is MMC-3 compliant */ +#ifdef PROTOTYPES +#define CDR_ALLOC 0x80000000UL /* structure is allocated */ +#else +#define CDR_ALLOC 0x80000000 /* structure is allocated */ +#endif + +/* + * Definitions for cdr_cdrw_support + */ +#define CDR_CDRW_NONE 0x00 /* CD-RW writing not supported */ +#define CDR_CDRW_MULTI 0x01 /* CD-RW multi speed supported */ +#define CDR_CDRW_HIGH 0x02 /* CD-RW high speed supported */ +#define CDR_CDRW_ULTRA 0x04 /* CD-RW ultra high speed supported */ +#define CDR_CDRW_ULTRAP 0x08 /* CD-RW ultra high speed+ supported */ +#define CDR_CDRW_ALL 0xFF /* All bits set: unknown - support all */ + +/* + * cdrecord.c + */ +extern int read_buf(int f, char *bp, int size); +extern int fill_buf(int f, track_t *trackp, long secno, char *bp, int size); +extern int get_buf(int f, track_t *trackp, long secno, char **bpp, int size); +#ifdef _SCG_SCSITRANSP_H +extern int write_secs(SCSI *usalp, cdr_t *dp, char *bp, long startsec, + int bytespt, int secspt, BOOL islast); +extern int pad_track(SCSI *usalp, cdr_t *dp, track_t *trackp, + long startsec, Llong amt, + BOOL dolast, Llong *bytesp); +extern void load_media(SCSI *usalp, cdr_t *, BOOL); +extern void unload_media(SCSI *usalp, cdr_t *, int); +extern void reload_media(SCSI *usalp, cdr_t *); +#endif +extern void raisepri(int); +extern int getnum(char *arg, long *valp); + +/* + * cd_misc.c + */ +extern int from_bcd(int b); +extern int to_bcd(int i); +extern long msf_to_lba(int m, int s, int f, BOOL force_positive); +extern BOOL lba_to_msf(long lba, msf_t *mp); +extern void sec_to_msf(long sec, msf_t *mp); +extern void print_min_atip(long li, long lo); + +/* + * fifo.c + */ +extern void init_fifo(long); +extern BOOL init_faio(track_t *track, int); +extern BOOL await_faio(void); +extern void kill_faio(void); +extern int wait_faio(void); +extern int faio_read_buf(int f, char *bp, int size); +extern int faio_get_buf(int f, char **bpp, int size); +extern void fifo_stats(void); +extern int fifo_percent(BOOL addone); + +/* + * wm_session.c + */ +#ifdef _SCG_SCSITRANSP_H +extern int write_session_data(SCSI *usalp, cdr_t *dp, track_t *trackp); +#endif + +/* + * wm_track.c + */ +#ifdef _SCG_SCSITRANSP_H +/*extern int write_track_data __PR((SCSI *usalp, cdr_t *dp, track_t *trackp));*/ +#endif + +/* + * wm_packet.c + */ +#ifdef _SCG_SCSITRANSP_H +extern int write_packet_data(SCSI *usalp, cdr_t *dp, track_t *trackp); +#endif + +/* + * modes.c + */ +#ifdef _SCG_SCSITRANSP_H +extern BOOL get_mode_params(SCSI *usalp, int page, char *pagename, + Uchar *modep, Uchar *cmodep, + Uchar *dmodep, Uchar *smodep, + int *lenp); +extern BOOL set_mode_params(SCSI *usalp, char *pagename, Uchar *modep, + int len, int save, int secsize); +#endif + +/* + * misc.c + */ +#ifdef timerclear +extern void timevaldiff(struct timeval *start, struct timeval *stop); +extern void prtimediff(const char *fmt, struct timeval *start, + struct timeval *stop); +#endif + +/* + * getnum.c + */ +extern int getnum(char *arg, long *valp); +extern int getllnum(char *arg, Llong *lvalp); + +/* + * scsi_cdr.c + */ +#ifdef _SCG_SCSITRANSP_H +extern BOOL unit_ready(SCSI *usalp); +extern BOOL wait_unit_ready(SCSI *usalp, int secs); +extern BOOL scsi_in_progress(SCSI *usalp); +extern BOOL cdr_underrun(SCSI *usalp); +extern int test_unit_ready(SCSI *usalp); +extern int rezero_unit(SCSI *usalp); +extern int request_sense(SCSI *usalp); +extern int request_sense_b(SCSI *usalp, caddr_t bp, int cnt); +extern int inquiry(SCSI *usalp, caddr_t, int); +extern int read_capacity(SCSI *usalp); +#ifdef EOF /* stdio.h has been included */ +extern void print_capacity(SCSI *usalp, FILE *f); +#endif +extern int scsi_load_unload(SCSI *usalp, int); +extern int scsi_prevent_removal(SCSI *usalp, int); +extern int scsi_start_stop_unit(SCSI *usalp, int, int, BOOL immed); + +#define ROTCTL_CLV 0 /* CLV or PCAV */ +#define ROTCTL_CAV 1 /* True CAV */ + +extern int scsi_set_speed(SCSI *usalp, int readspeed, int writespeed, + int rotctl); +extern int scsi_get_speed(SCSI *usalp, int *readspeedp, int *writespeedp); +extern int qic02(SCSI *usalp, int); +extern int write_xscsi(SCSI *usalp, caddr_t, long, long, int); +extern int write_xg0(SCSI *usalp, caddr_t, long, long, int); +extern int write_xg1(SCSI *usalp, caddr_t, long, long, int); +extern int write_xg5(SCSI *usalp, caddr_t, long, long, int); +extern int seek_scsi(SCSI *usalp, long addr); +extern int seek_g0(SCSI *usalp, long addr); +extern int seek_g1(SCSI *usalp, long addr); +extern int scsi_flush_cache(SCSI *usalp, BOOL immed); +extern int read_buffer(SCSI *usalp, caddr_t bp, int cnt, int mode); +extern int write_buffer(SCSI *usalp, char *buffer, long length, int mode, + int bufferid, long offset); +extern int read_subchannel(SCSI *usalp, caddr_t bp, int track, int cnt, + int msf, int subq, int fmt); +extern int read_toc(SCSI *usalp, caddr_t, int, int, int, int); +extern int read_toc_philips(SCSI *usalp, caddr_t, int, int, int, int); +extern int read_header(SCSI *usalp, caddr_t, long, int, int); +extern int read_disk_info(SCSI *usalp, caddr_t, int); + +#define TI_TYPE_LBA 0 /* Address is LBA */ +#define TI_TYPE_TRACK 1 /* Address: 0 -> TOC, xx -> Track xx, 0xFF -> Inv Track */ +#define TI_TYPE_SESS 2 /* Address is session # */ +extern int read_track_info(SCSI *usalp, caddr_t, int type, int addr, int cnt); +extern int read_rzone_info(SCSI *usalp, caddr_t bp, int cnt); +extern int reserve_tr_rzone(SCSI *usalp, long size); +extern int read_dvd_structure(SCSI *usalp, caddr_t bp, int cnt, int addr, + int layer, int fmt); +extern int send_dvd_structure(SCSI *usalp, caddr_t bp, int cnt, int layer, + int fmt); +extern int send_opc(SCSI *usalp, caddr_t, int cnt, int doopc); + +#define CL_TYPE_STOP_DEICE 0 /* Stop De-icing a DVD+RW Media */ +#define CL_TYPE_TRACK 1 /* Close Track # */ +#define CL_TYPE_SESSION 2 /* Close Session/Border / Stop backgrnd. format */ +#define CL_TYPE_INTER_BORDER 3 /* Close intermediate Border */ +#define CL_TYPE_OPEN_SESSION 4 /* Close the Open Session and Record an Extended lead-out */ +#define CL_TYPE_FINALISE_MINRAD 5 /* Finalize the Disc with a Minimum Recorded Radius */ +#define CL_TYPE_FINALISE 6 /* Finalize the disc */ +extern int scsi_close_tr_session(SCSI *usalp, int type, int track, + BOOL immed); +extern int read_master_cue(SCSI *usalp, caddr_t bp, int sheet, int cnt); +extern int send_cue_sheet(SCSI *usalp, caddr_t bp, long size); +extern int read_buff_cap(SCSI *usalp, long *, long *); +extern int scsi_blank(SCSI *usalp, long addr, int blanktype, BOOL immed); +extern BOOL allow_atapi(SCSI *usalp, BOOL new); +extern int mode_select(SCSI *usalp, Uchar *, int, int, int); +extern int mode_sense(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +extern int mode_select_sg0(SCSI *usalp, Uchar *, int, int, int); +extern int mode_sense_sg0(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +extern int mode_select_g0(SCSI *usalp, Uchar *, int, int, int); +extern int mode_select_g1(SCSI *usalp, Uchar *, int, int, int); +extern int mode_sense_g0(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +extern int mode_sense_g1(SCSI *usalp, Uchar *dp, int cnt, int page, int pcf); +extern int read_tochdr(SCSI *usalp, cdr_t *, int *, int *); +extern int read_cdtext(SCSI *usalp); +extern int read_trackinfo(SCSI *usalp, int, long *, struct msf *, int *, + int *, int *); +extern int read_B0(SCSI *usalp, BOOL isbcd, long *b0p, long *lop); +extern int read_session_offset(SCSI *usalp, long *); +extern int read_session_offset_philips(SCSI *usalp, long *); +extern int sense_secsize(SCSI *usalp, int current); +extern int select_secsize(SCSI *usalp, int); +extern BOOL is_cddrive(SCSI *usalp); +extern BOOL is_unknown_dev(SCSI *usalp); +extern int read_scsi(SCSI *usalp, caddr_t, long, int); +extern int read_g0(SCSI *usalp, caddr_t, long, int); +extern int read_g1(SCSI *usalp, caddr_t, long, int); +extern BOOL getdev(SCSI *usalp, BOOL); +#ifdef EOF /* stdio.h has been included */ +extern void printinq(SCSI *usalp, FILE *f); +#endif +extern void printdev(SCSI *usalp); +extern BOOL do_inquiry(SCSI *usalp, BOOL); +extern BOOL recovery_needed(SCSI *usalp, cdr_t *); +extern int scsi_load(SCSI *usalp, cdr_t *); +extern int scsi_unload(SCSI *usalp, cdr_t *); +extern int scsi_cdr_write(SCSI *usalp, caddr_t bp, long sectaddr, + long size, int blocks, BOOL islast); +extern struct cd_mode_page_2A *mmc_cap(SCSI *usalp, Uchar *modep); +extern void mmc_getval(struct cd_mode_page_2A *mp, BOOL *cdrrp, BOOL *cdwrp, + BOOL *cdrrwp, BOOL *cdwrwp, BOOL *dvdp, BOOL *dvdwp); +extern BOOL is_mmc(SCSI *usalp, BOOL *cdwp, BOOL *dvdwp); +extern BOOL mmc_check(SCSI *usalp, BOOL *cdrrp, BOOL *cdwrp, BOOL *cdrrwp, + BOOL *cdwrwp, BOOL *dvdp, BOOL *dvdwp); +extern void print_capabilities(SCSI *usalp); +#endif + +/* + * scsi_cdr.c + */ +#ifdef _SCG_SCSITRANSP_H +extern void print_capabilities_mmc4(SCSI *usalp); +#endif + +/* + * scsi_mmc.c + */ +#ifdef _SCG_SCSITRANSP_H +extern int get_configuration(SCSI *usalp, caddr_t bp, int cnt, + int st_feature, int rt); +extern int get_curprofile(SCSI *usalp); +extern int print_profiles(SCSI *usalp); +extern int get_proflist(SCSI *usalp, BOOL *wp, BOOL *cdp, BOOL *dvdp, + BOOL *dvdplusp, BOOL *ddcdp); +extern int get_wproflist(SCSI *usalp, BOOL *cdp, BOOL *dvdp, + BOOL *dvdplusp, BOOL *ddcdp); +extern char *mmc_obtain_profile_name(int profile_number); +#endif + +/* + * scsi_mmc.c + */ +#ifdef _SCG_SCSITRANSP_H +extern int get_supported_cdrw_media_types(SCSI *usalp); +#endif + +/* + * mmc_misc.c + */ +#ifdef _SCG_SCSITRANSP_H +extern int check_writemodes_mmc(SCSI *usalp, cdr_t *dp); +#endif /* _SCG_SCSITRANSP_H */ + +/* + * cdr_drv.c + */ +#ifdef _SCG_SCSITRANSP_H +#ifdef _SCG_SCSIREG_H +extern cdr_t *drive_identify(SCSI *usalp, cdr_t *, struct scsi_inquiry *ip); +#else +extern cdr_t *drive_identify(SCSI *usalp, cdr_t *, void *ip); +#endif +extern int drive_attach(SCSI *usalp, cdr_t *); +#endif +extern int attach_unknown(void); +#ifdef _SCG_SCSITRANSP_H +extern int blank_dummy(SCSI *usalp, cdr_t *, long addr, int blanktype); +int format_dummy(SCSI *usalp, cdr_t *, int fmtflags); +extern int drive_getdisktype(SCSI *usalp, cdr_t *dp); +extern int cmd_ill(SCSI *usalp); +extern int cmd_dummy(SCSI *usalp, cdr_t *); +extern int no_sendcue(SCSI *usalp, cdr_t *, track_t *trackp); +extern int buf_dummy(SCSI *usalp, long *sp, long *fp); +#endif +extern BOOL set_cdrcmds(char *name, cdr_t **dpp); +#ifdef _SCG_SCSITRANSP_H +extern cdr_t *get_cdrcmds(SCSI *usalp); +#endif + + +/* + * drv_mmc.c + */ +extern void mmc_opthelp(cdr_t *dp, int excode); +extern char *hasdrvopt(char *optstr, char *optname); +#ifdef _SCG_SCSITRANSP_H +extern struct ricoh_mode_page_30 *get_justlink_ricoh(SCSI *usalp, Uchar *mode); +#endif + +/* + * isosize.c + */ +extern Llong isosize(int f); + +/* + * audiosize.c + */ +extern BOOL is_auname(const char *name); +extern off_t ausize(int f); +extern BOOL is_wavname(const char *name); +extern off_t wavsize(int f); + +/* + * auinfo.c + */ +extern BOOL auinfosize(char *name, track_t *trackp); +extern void auinfo(char *name, int track, track_t *trackp); +#ifdef CDTEXT_H +extern textptr_t *gettextptr(int track, track_t *trackp); +#endif +extern void setmcn(char *mcn, track_t *trackp); +extern void setisrc(char *isrc, track_t *trackp); +extern void setindex(char *tindex, track_t *trackp); + +/* + * diskid.c + */ +extern void pr_manufacturer(msf_t *mp, BOOL rw, BOOL audio); +extern int manufacturer_id(msf_t *mp); +extern long disk_rcap(msf_t *mp, long maxblock, BOOL rw, BOOL audio); + +/*--------------------------------------------------------------------------*/ +/* Test only */ +/*--------------------------------------------------------------------------*/ +#ifdef _SCSIMMC_H +/*extern int do_cue __PR((track_t *trackp, struct mmc_cue **cuep));*/ +#else +/*extern int do_cue __PR((track_t *trackp, void *cuep));*/ +#endif + +/* + * subchan.c + */ +extern int do_leadin(track_t *trackp); +#ifdef _SCG_SCSITRANSP_H +extern int write_leadin(SCSI *usalp, cdr_t *dp, track_t *trackp, + int leadinstart); +extern int write_leadout(SCSI *usalp, cdr_t *dp, track_t *trackp); +#endif +extern void fillsubch(track_t *trackp, Uchar *sp, int secno, int nsecs); +extern void filltpoint(Uchar *sub, int ctrl_adr, int point, msf_t *mp); +extern void fillttime(Uchar *sub, msf_t *mp); +extern void qpto96(Uchar *sub, Uchar *subq, int dop); +extern void addrw(Uchar *sub, Uchar *subrwptr); +extern void qwto16(Uchar *subq, Uchar *subptr); +extern void subrecodesecs(track_t *trackp, Uchar *bp, int address, int nsecs); + +/* + * sector.c + */ +extern int encspeed(BOOL be_verbose); +extern void encsectors(track_t *trackp, Uchar *bp, int address, int nsecs); +extern void scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs); +extern void encodesector(Uchar *sp, int sectype, int address); +extern void fillsector(Uchar *sp, int sectype, int address); + +/* + * clone.c + */ +extern void clone_toc(track_t *trackp); +extern void clone_tracktype(track_t *trackp); + +/* + * cdtext.c + */ +extern BOOL checktextfile(char *fname); +extern void packtext(int tracks, track_t *trackp); +#ifdef _SCG_SCSITRANSP_H +extern int write_cdtext(SCSI *usalp, cdr_t *dp, long startsec); +#endif + +/* + * cue.c + */ +extern int parsecue(char *cuefname, track_t trackp[]); +#ifdef EOF /* stdio.h has been included */ +extern void fparsecue(FILE *f, track_t trackp[]); +#endif diff --git a/wodim/xio.c b/wodim/xio.c new file mode 100644 index 0000000..04118cd --- /dev/null +++ b/wodim/xio.c @@ -0,0 +1,164 @@ +/* + * 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. + * + */ + +/* @(#)xio.c 1.11 04/07/11 Copyright 2003-2004 J. Schilling */ +/* + * EXtended I/O functions for cdrecord + * + * Copyright (c) 2003-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 <unixstd.h> +#include <stdxlib.h> +#include <strdefs.h> +#include <standard.h> +#include <fctldefs.h> + +#ifdef NEED_O_BINARY +#include <io.h> /* for setmode() prototype */ +#endif + +#include "xio.h" + +static xio_t x_stdin = { + NULL, /* x_next */ + NULL, /* x_name */ + 0, /* x_off */ + STDIN_FILENO, /* x_file */ + 999, /* x_refcnt */ + O_RDONLY, /* x_oflag */ + 0 /* x_omode */ +}; + +static xio_t *x_root = &x_stdin; +static xio_t **x_tail = NULL; + + +static xio_t *xnewnode(char *name); +void *xopen(char *name, int oflag, int mode); +int xclose(void *vp); + +static xio_t * +xnewnode(char *name) +{ + xio_t *xp; + + if ((xp = malloc(sizeof (xio_t))) == NULL) + return ((xio_t *) NULL); + + xp->x_next = (xio_t *) NULL; + xp->x_name = strdup(name); + if (xp->x_name == NULL) { + free(xp); + return ((xio_t *) NULL); + } + xp->x_off = 0; + xp->x_file = -1; + xp->x_refcnt = 1; + xp->x_oflag = 0; + xp->x_omode = 0; + return (xp); +} + +void * +xopen(char *name, int oflag, int mode) +{ + int f; + xio_t *xp; + xio_t *pp = x_root; + + if (x_tail == NULL) + x_tail = &x_stdin.x_next; + if (name == NULL) { + xp = &x_stdin; + xp->x_refcnt++; +#ifdef NEED_O_BINARY + if ((oflag & O_BINARY) != 0) { + setmode(STDIN_FILENO, O_BINARY); + } +#endif + return (xp); + } + for (; pp; pp = pp->x_next) { + if (pp->x_name == NULL) /* stdin avoid core dump in strcmp() */ + continue; + if ((strcmp(pp->x_name, name) == 0) && + (pp->x_oflag == oflag) && (pp->x_omode == mode)) { + break; + } + } + if (pp) { + pp->x_refcnt++; + return ((void *)pp); + } + if ((f = open(name, oflag, mode)) < 0) + return (NULL); + + if ((xp = xnewnode(name)) == NULL) { + close(f); + return (NULL); + } + xp->x_file = f; + xp->x_oflag = oflag; + xp->x_omode = mode; + *x_tail = xp; + x_tail = &xp->x_next; + return ((void *)xp); +} + +int +xclose(void *vp) +{ + xio_t *xp = vp; + xio_t *pp = x_root; + int ret = 0; + + if (xp == &x_stdin) + return (ret); + if (x_tail == NULL) + x_tail = &x_stdin.x_next; + + if (--xp->x_refcnt <= 0) { + ret = close(xp->x_file); + while (pp) { + if (pp->x_next == xp) + break; + if (pp->x_next == NULL) + break; + pp = pp->x_next; + } + if (pp->x_next == xp) { + if (x_tail == &xp->x_next) + x_tail = &pp->x_next; + pp->x_next = xp->x_next; + } + + free(xp->x_name); + free(xp); + } + return (ret); +} diff --git a/wodim/xio.h b/wodim/xio.h new file mode 100644 index 0000000..a7836b2 --- /dev/null +++ b/wodim/xio.h @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +/* @(#)xio.h 1.2 04/03/02 Copyright 2003-2004 J. Schilling */ +/* + * EXtended I/O functions for cdrecord + * + * Copyright (c) 2003-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. + */ + +#ifndef _XIO_H +#define _XIO_H + +#include <utypes.h> + +typedef struct xio { + struct xio *x_next; + char *x_name; + Ullong x_off; + int x_file; + int x_refcnt; + int x_oflag; + int x_omode; +} xio_t; + +#define xfileno(p) (((xio_t *)(p))->x_file) + +extern void *xopen(char *name, int oflag, int mode); +extern int xclose(void *vp); + +#endif |