From 3a05fb4e8795dab420d3062310b57f88b41a468d Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Tue, 14 Nov 2006 00:58:21 +0000 Subject: [PATCH] Started cleaning libisofs tree --- cdrskin/README | 433 -- cdrskin/add_ts_changes_to_libburn_0_2_4 | 203 - cdrskin/add_ts_changes_to_libburn_0_2_5 | 203 - cdrskin/cdrecord_spy.sh | 37 - cdrskin/cdrfifo.c | 1081 ----- cdrskin/cdrfifo.h | 155 - cdrskin/cdrskin.c | 5580 ----------------------- cdrskin/cdrskin_eng.html | 437 -- cdrskin/cdrskin_timestamp.h | 1 - cdrskin/changelog.txt | 1539 ------- cdrskin/cleanup.c | 214 - cdrskin/cleanup.h | 34 - cdrskin/compile_cdrskin.sh | 218 - cdrskin/make_timestamp.sh | 9 - cdrskin/wiki_plain.txt | 204 - libburn-1.pc.in | 12 - libburn/Makefile | 4 - libburn/Makefile.am | 65 - libburn/asserts.txt | 792 ---- libburn/async.c | 280 -- libburn/async.h | 8 - libburn/back_hacks.h | 54 - libburn/cleanup.c | 214 - libburn/cleanup.h | 34 - libburn/crc.c | 122 - libburn/crc.h | 9 - libburn/debug.c | 35 - libburn/debug.h | 8 - libburn/drive.c | 1232 ----- libburn/drive.h | 73 - libburn/error.h | 8 - libburn/file.c | 187 - libburn/file.h | 22 - libburn/init.c | 246 - libburn/init.h | 8 - libburn/lec.c | 451 -- libburn/lec.h | 12 - libburn/libburn.h | 1243 ----- libburn/libdax_audioxtr.c | 326 -- libburn/libdax_audioxtr.h | 229 - libburn/libdax_msgs.c | 404 -- libburn/libdax_msgs.h | 382 -- libburn/mmc.c | 906 ---- libburn/mmc.h | 54 - libburn/null.c | 27 - libburn/null.h | 10 - libburn/options.c | 209 - libburn/options.h | 78 - libburn/read.c | 282 -- libburn/read.h | 14 - libburn/sbc.c | 48 - libburn/sbc.h | 15 - libburn/sector.c | 825 ---- libburn/sector.h | 35 - libburn/sg-freebsd.c | 769 ---- libburn/sg-linux.c | 870 ---- libburn/sg.c | 13 - libburn/sg.h | 72 - libburn/source.c | 39 - libburn/source.h | 8 - libburn/spc.c | 525 --- libburn/spc.h | 37 - libburn/structure.c | 418 -- libburn/structure.h | 92 - libburn/toc.c | 136 - libburn/toc.h | 48 - libburn/transport.h | 215 - libburn/util.c | 53 - libburn/util.h | 8 - libburn/write.c | 897 ---- libburn/write.h | 34 - test/burn.c | 4 - test/dewav.c | 215 - test/fake_au.c | 164 - test/libburner.c | 684 --- test/master.c | 126 - test/poll.c | 78 - test/rip.c | 54 - test/structest.c | 48 - test/toc.c | 103 - 80 files changed, 25021 deletions(-) delete mode 100644 cdrskin/README delete mode 100755 cdrskin/add_ts_changes_to_libburn_0_2_4 delete mode 100755 cdrskin/add_ts_changes_to_libburn_0_2_5 delete mode 100755 cdrskin/cdrecord_spy.sh delete mode 100644 cdrskin/cdrfifo.c delete mode 100644 cdrskin/cdrfifo.h delete mode 100644 cdrskin/cdrskin.c delete mode 100644 cdrskin/cdrskin_eng.html delete mode 100644 cdrskin/cdrskin_timestamp.h delete mode 100644 cdrskin/changelog.txt delete mode 100644 cdrskin/cleanup.c delete mode 100644 cdrskin/cleanup.h delete mode 100755 cdrskin/compile_cdrskin.sh delete mode 100755 cdrskin/make_timestamp.sh delete mode 100644 cdrskin/wiki_plain.txt delete mode 100644 libburn-1.pc.in delete mode 100644 libburn/Makefile delete mode 100644 libburn/Makefile.am delete mode 100644 libburn/asserts.txt delete mode 100644 libburn/async.c delete mode 100644 libburn/async.h delete mode 100644 libburn/back_hacks.h delete mode 100644 libburn/cleanup.c delete mode 100644 libburn/cleanup.h delete mode 100644 libburn/crc.c delete mode 100644 libburn/crc.h delete mode 100644 libburn/debug.c delete mode 100644 libburn/debug.h delete mode 100644 libburn/drive.c delete mode 100644 libburn/drive.h delete mode 100644 libburn/error.h delete mode 100644 libburn/file.c delete mode 100644 libburn/file.h delete mode 100644 libburn/init.c delete mode 100644 libburn/init.h delete mode 100644 libburn/lec.c delete mode 100644 libburn/lec.h delete mode 100644 libburn/libburn.h delete mode 100644 libburn/libdax_audioxtr.c delete mode 100644 libburn/libdax_audioxtr.h delete mode 100644 libburn/libdax_msgs.c delete mode 100644 libburn/libdax_msgs.h delete mode 100644 libburn/mmc.c delete mode 100644 libburn/mmc.h delete mode 100644 libburn/null.c delete mode 100644 libburn/null.h delete mode 100644 libburn/options.c delete mode 100644 libburn/options.h delete mode 100644 libburn/read.c delete mode 100644 libburn/read.h delete mode 100644 libburn/sbc.c delete mode 100644 libburn/sbc.h delete mode 100644 libburn/sector.c delete mode 100644 libburn/sector.h delete mode 100644 libburn/sg-freebsd.c delete mode 100644 libburn/sg-linux.c delete mode 100644 libburn/sg.c delete mode 100644 libburn/sg.h delete mode 100644 libburn/source.c delete mode 100644 libburn/source.h delete mode 100644 libburn/spc.c delete mode 100644 libburn/spc.h delete mode 100644 libburn/structure.c delete mode 100644 libburn/structure.h delete mode 100644 libburn/toc.c delete mode 100644 libburn/toc.h delete mode 100644 libburn/transport.h delete mode 100644 libburn/util.c delete mode 100644 libburn/util.h delete mode 100644 libburn/write.c delete mode 100644 libburn/write.h delete mode 100644 test/burn.c delete mode 100644 test/dewav.c delete mode 100644 test/fake_au.c delete mode 100644 test/libburner.c delete mode 100644 test/master.c delete mode 100644 test/poll.c delete mode 100644 test/rip.c delete mode 100644 test/structest.c delete mode 100644 test/toc.c diff --git a/cdrskin/README b/cdrskin/README deleted file mode 100644 index 65fde0c..0000000 --- a/cdrskin/README +++ /dev/null @@ -1,433 +0,0 @@ ------------------------------------------------------------------------------- - libburn.pykix.org scdbackup.sourceforge.net/cdrskin_eng.html ------------------------------------------------------------------------------- -Installation instructions at about line 60. First the legal stuff: ------------------------------------------------------------------------------- -This all is under GPL. -(See GPL reference, our clarification and commitment at the end of this text) ------------------------------------------------------------------------------- -Based on and sub project of: -libburn.pykix.org -By Mario Danic and Thomas Schmitt -Copyright (C) 2006 Mario Danic, Thomas Schmitt - -libburn.pykix.org is inspired by and in other components still containing -parts of -Libburn. By Derek Foreman and - Ben Jansens -Copyright (C) 2002-2006 Derek Foreman and Ben Jansens -See toplevel README for an overview of the current copyright situation in -libburn.pykix.org. - ------------------------------------------------------------------------------- -My thanks to the above authors (except myself, of course) for making the -following possible. - -cdrskin. By Thomas Schmitt -Integrated sub project of libburn.pykix.org but also published via: -http://scdbackup.sourceforge.net/cdrskin_eng.html -http://scdbackup.sourceforge.net/cdrskin-0.2.5.tar.gz -Copyright (C) 2006 Thomas Schmitt - ------------------------------------------------------------------------------- - -On top of libburn there is implemented cdrskin 0.2.5, a limited cdrecord -compatibility wrapper which allows to use some libburn features from -the command line. -Interested users of cdrecord are invited to participate in the development -of cdrskin. Contact: scdbackup@gmx.net or libburn-hackers@pykix.org . -We will keep copyright narrow but will of course acknowledge valuable -contributions in a due way. - - -Important : -This software is provided as is. There is no warranty implied and no -protection against possible damages. You use this on your own risk. -Don't blame me or other authors of libburn if anything goes wrong. - -I used it on my own risk with : -SuSE 7.2, kernel 2.4.4, ide-scsi emulation, LITE-ON LTR48125S CD burner, 2002 -SuSE 9.0, kernel 2.4.21, ide-scsi emulation, LG GSA-4082B CD/DVD burner, 2004 - NEC ND-4570A CD/DVD burner, 2006 -RIP-14.4, kernel 2.6.14, no ide-scsi, with all above burners - -It fails to compile or run on SuSE 6.4 (kernel 2.2.14). -It does not find the IDE CD burner on SuSE 7.2 without ide-scsi. -Other people sucessfully tested cdrskin on several kernel 2.6 based x86 Linux -systems, including 64 bit systems. (Further reports are welcome.) - - - Compilation, First Glimpse, Installation - -Obtain cdrskin-0.2.5.tar.gz , take it to a directory of your choice and do: - - tar xzf cdrskin-0.2.5.tar.gz - cd cdrskin-0.2.5 - -Or obtain a libburn.pykix.org SVN snapshot, -go into the toplevel directory of the snapshot (e.g. cd libburn_pykix ), -and execute the autotools script ./bootstrap . Use autools version >= 1.7 . - -Within that toplevel directory of either cdrskin-0.2.5 or libburn then execute: - - ./configure - make - -(Note: there are next-level directories "libburn" and "cdrskin". Those -would be the wrong ones. Meant is the highest directory of tarball resp. -SVN download. Among others containing files "AUTHORS", "configure", -"Makefile.am", as well as directories "libburn" and "cdrskin".) - -This will already produce a cdrskin binary. But it might be necessary to -install libburn in order to use this binary. Installation of libburn is -beyond the scope of cdrskin. For this, see included libburn docs. - -In order to surely get a standalone binary, execute - - cdrskin/compile_cdrskin.sh - -Version identification and help texts available afterwards: - cdrskin/cdrskin -version - cdrskin/cdrskin --help - cdrskin/cdrskin -help - -Install (eventually as superuser) cdrskin to a directory where it can be found: -If cdrskin was already installed by a previous version, or by "make install" -in the course of this installation, then find out where: - which cdrskin -Copy your standalone binary to exactly the address which you get as reply - - cp cdrskin/cdrskin /usr/bin/cdrskin - -Check the version timestamps of the globally installed binary - cdrskin -version - -It is not necessary for the standalone cdrskin binary to have libburn -installed, since it incorporates the necessary libburn parts at compile time. -It will not collide with an installed version of libburn either. -But libpthread must be installed on the system and glibc has to match. (See -below for a way to create a statically linked binary.) - - - Usage - -The user of cdrskin needs rw-permission for the CD burner device. -A list of rw-accessible drives can be obtained by - - cdrskin --devices - -CD devices which offer no rw-permission are invisible to normal users. -The superuser should be able to see any usable drive and then set the -permissions as needed. If this hangs then there is a drive with -unexpected problems (locked, busy, broken, whatever). You might have to -guess the address of your (non-broken) burner by other means, then. -On Linux 2.4 this would be some /dev/sgN and on 2.6. some /dev/hdX. - -The output of cdrskin --devices might look like - - 0 dev='/dev/sg0' rwrwr- : '_NEC' 'DVD_RW ND-4570A' - 1 dev='/dev/sg1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B' - -So full and insecure enabling of both for everybody would look like - - chmod a+rw /dev/sg0 /dev/sg1 - -I strongly discourage to run cdrskin with setuid root or via sudo ! -It is not checked for the necessary degree of hacker safety. - - - Usage examples - -Get an overview of cdrecord style addresses of available devices - cdrskin -scanbus - cdrskin dev=ATA -scanbus - -Note: Adresses reported with dev=ATA are to be used with prefix "ATA:". You may - well use device file addresses as reported with --devices. Examples: - dev=0,1,0 dev=/dev/sg1 dev=ATA:1,0,0 dev=/dev/hdc - See also "Drive Addressing". -Note: Address numbers have changed since cdrskin-0.2.2 in order to become - compatible with cdrecord numbers. To get the old number scheme, use - option --old_pseudo_scsi_adr . See also "Pseudo-SCSI Adresses". - Sorry for any inconvenience. - - -Obtain some info about the drive - cdrskin dev=0,1,0 -checkdrive - -Obtain some info about the drive and the inserted media - cdrskin dev=0,1,0 -atip - -Thoroughly blank a CD-RW - cdrskin -v dev=0,1,0 blank=all -eject - -Blank CD-RW sufficiently for making it ready for overwrite - cdrskin -v dev=0,1,0 blank=fast -eject - -Burn image file my_image.iso to CD - cdrskin -v dev=0,1,0 speed=12 fs=8m -sao driveropts=burnfree padsize=300k \ - -eject my_image.iso - -Burn a compressed afio archive to CD on-the-fly - find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 -tao \ - driveropts=burnfree padsize=300k - - -Burn 6 audio tracks from files with different formats to CD. -Anything except .wav or .au files has to be converted into raw format first. -See below "Audio CD" for specifications. - ogg123 -d raw -f track01.cd /path/to/track1.ogg - oggdec -R -o track02.cd /path/to/track2.ogg - lame --decode -t /path/to/track3.mp3 track03.cd - madplay -o raw:track04.cd /path/to/track4.mp3 - mppdec --raw-le /path/to/track5.mpc track05.cd - - cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \ - -audio -swab track0[1-5].cd /path/to/track6.wav - - - Usage example with http://scdbackup.sourceforge.net - -Address may be a cdrecord-style "scsibus,target,lun" as listed with -cdrskin -scanbus (and hopefully as listed with cdrecord -scanbus) : - - export SCDBACKUP_SCSI_ADR="0,1,0" - -or a device file address as listed by --devices with an accessible drive : - - export SCDBACKUP_SCSI_ADR="/dev/sg1" - -Set usage of cdrskin with appropriate options rather than cdrecord : - - export SCDBACKUP_CDRECORD="cdrskin -v -v" - -Run a backup : - - scdbackup_home - - - Restrictions - -The major restrictions are lifted now: audio, TAO, multi-session do work. -Many cdrecord options are still unsupported, though. - -If you have use cases for them, please report your wishes and expectations. - - - - Inspiration and Standard - -For the original meaning of cdrecord options see : - man cdrecord - (http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html) -Do not bother Joerg Schilling with any cdrskin problems. -(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding - this "don't bother Joerg" demand.) -cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes -have been copied from the message output of cdrecord runs, though. I am -thankful to Joerg Schilling for every single one of them. - -Actually i, Thomas Schmitt, am a devoted user of cdrecord via my project -scdbackup which still runs a bit better with cdrecord than with cdrskin. TAO. -I have the hope that Joerg feels more flattered than annoyed by cdrskin. - - - Drive Addressing - -Drives get addressed either via their cdrecord-style addresses as listed -with option -scanbus (see below "Pseudo-SCSI Adresses") or via the paths -of device files. -Not only device files listed by --devices may be used but also device files -which via their major,minor numbers point to the same device driver as -a listed device file. - -Helpful with Linux kernel 2.4 is a special SCSI feature: -It is possible to address a scsi(-emulated) drive via associated device files -which are not listed by option --devices but point to the same SCSI addresses -as listed device files. This addressing via e.g. /dev/sr0 or /dev/scd1 is -compatible with generic read programs like dd and with write program growisofs. - - Pseudo-SCSI Adresses - -cdrecord and cdrskin share the syntax of SCSI addresses but not necessarily -the meaning of the components. A cdrecord-style address for cdrskin - [prefix:]scsibus,target,lun -can be interpreted in two different modes. - -Standard mode tries to be compatible to original cdrecord. This should be true -with (emulated) SCSI where the /dev/sgN with is looked up with matching -scsibus,target,lun as given by the operating system. -With dev=ATA: or dev=ATAPI: the translation to /dev/hdX is purely literal -but matches the cdrecord addresses on all systems tested so far: - X = 'a' + 2 * scsibus + target -where target only may have the values 0 or 1. - -In this mode, option -scanbus will list only SCSI devices unless option -dev=ATA or dev=ATAPI are given, which will suppress SCSI devices and only -show IDE drives (i.e. /dev/hdX without ide-scsi emulation). - - -In mode --old_pseudo_scsi_adr there is a scsibus,target,lun representation -which has nothing to do with SCSI and thus is not compatible to cdrecord. -Each number triple corresponds either to a device file address or to a -libburn drive number. -Component "scsibus" indicates the translation method. Defined busses are: - 0 target is the libburn drivenumber as listed with --devices - 1 associated to device file /dev/sgN , target chooses N - 2 associated to device file /dev/hdX , target 0='a', 1='b' ..., 25='z' - -So "1,1,0" is /dev/sg1, "2,3,0" is /dev/hdd, "0,2,0" is libburn drive #2 at -some unspecified device file. -This scheme shall help to keep cdrecord-style addresses stable and exchangeable -between users without excluding drives with unexpected device addresses. -The numbering on bus 0 is prone to arbitrary changes caused by changes in -drive accessability. -Further busses may emerge as libburn evolves. "prefix" and "lun" may get -a meaning. To stay upward compatible, use addresses as printed by -scanbus. - - User Defined Device Address Translation - -Some programs or users have their own ideas about the address of their burner. -K3b 0.10 for example derives cdrecord addresses by own examination of the -devices and not by calling cdrecord -scanbus. -Standard mode will hopefully be fully compatible with their ideas. - -Old frontends which do not know dev=ATA or dev=ATAPI and which do ask their -"cdrecord" via -scanbus may be well served with option --old_pseudo_scsi_adr . - -To direct any remaining stubborn callers to the appropriate drives, cdrskin -allows to define device address aliases. Like - cdrskin dev_translation=+1,0,0+/dev/sg1 \ - dev_translation=+ATA:1,0,0+/dev/sg1 \ - dev_translation=-"cd+dvd"-0,1,0 \ - ... -Any of the addresses dev=1,0,0, dev=ATA:1,0,0, dev=cd+dvd will be mapped to -/dev/sg1 resp. to 0,1,0. -The first character after "dev_translation=" defines the character which -separates the two parts of the translation pair. (Above: "+" and "-".) - -In K3b 0.10 it is possible to employ alternative writer programs by setting -their full path (e.g. /usr/bin/cdrskin) in menu - Settings:Configure K3b...:Programs:Search Path -and to make them default in menu - Settings:Configure K3b...:Programs:Programs: -A suitable setting for "cdrecord" in menu - Settings:Configure K3b...:Programs:User Parameters -would then probably be - -v dev_translation=+1,0,0+/dev/sg1 -You will learn from button "Show Debugging Output" after a failed burn run -what cdrecord command was used with what address "dev=...". This address "..." -will be the right one to replace "1,0,0" in above example. - - - Startup Files - -If not --no_rc is the first argument then cdrskin attempts on startup to read -arguments from the following three files: - /etc/defaults/cdrskin - /etc/opt/cdrskin/rc - $HOME/.cdrskinrc -The files are read in the sequence given above. -Each readable line is treated as one single argument. No extra blanks. -A first character '#' marks a comment, empty lines are ignored. - -Example content of a startup file: -# This is the default device -dev=0,1,0 -# To accomodate to eventual remnant cdrskin-0.2.2 addresses -dev_translation=+1,0,0+0,1,0 - -# Some more options ---fifo_start_empty -fs=16m - - - Audio CD - -Lorenzo Taylor enabled option -audio in cdrskin (thanks !) and reports neat -results with audio data files which are : - headerless PCM (i.e. uncompressed) - 44100 Hz sampling rate - 16 bits per sample - stereo (2 channels) - little-endian byte order with option -swab, or big-endian without -swab - -Files with name extension .wav get examined wether they are in Microsoft WAVE -format with above parameters and eventually get extracted by cdrskin itself. -In the same way files with name extension .au get examined wether they are -in SUN's audio format. For both formats, track format -audio and eventual -endianness option -swab are enabled automatically. - -Any other formats are to be converted to format .wav with above parameters -or to be extracted as raw CD track data by commands like those given above -under "Usage examples". Those raw files need option -audio and in most cases -option -swab to mark them as little-endian/Intel/LSB-first 16-bit data. -Incorrect endianness setting results in random noise on CD. - -I myself am not into audio. So libburn-hackers@pykix.org might be the -best address for suggestions, requests and bug reports. - - - Special compilation variations - -You may get a (super fat) statically linked binary by : - cdrskin/compile_cdrskin.sh -static -if your system supports static linking, at all. This will not help with kernels -which do not properly support the necessary low-level interfaces chosen by -your compile-time libraries. - -A size reduced but fully functional binary may be produced by - cdrskin/compile_cdrskin.sh -do_strip - -An extra lean binary with reduced capabilities is created by - cdrskin/compile_cdrskin.sh -do_diet -do_strip -It will not read startup files, will abort on option dev_translation= , -will not have a fifo buffer, and will not be able to put out help texts or -debugging messages. - ------------------------------------------------------------------------------- - - 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 - ------------------------------------------------------------------------------- -cdrskin is currently copyright Thomas Schmitt only. -It adopts the following commitment by the toplevel copyright holders: ------------------------------------------------------------------------------- - -We, the copyright holders, agree on the interpretation that -dynamical linking of our libraries constitutes "use of" and -not "derivation from" our work in the sense of GPL, provided -those libraries are compiled from our unaltered code. - -Thus you may link our libraries dynamically with applications -which are not under GPL. You may distribute our libraries and -application tools in binary form, if you fulfill the usual -condition of GPL to offer a copy of the source code -altered -or unaltered- under GPL. - -We ask you politely to use our work in open source spirit -and with the due reference to the entire open source community. - -If there should really arise the case where above clarification -does not suffice to fulfill a clear and neat request in open source -spirit that would otherwise be declined for mere formal reasons, -only in that case we will duely consider to issue a special license -covering only that special case. -It is the open source idea of responsible freedom which will be -decisive and you will have to prove that you exhausted all own -means to qualify for GPL. - -For now we are firmly committed to maintain one single license: GPL. - -signed for cdrskin: Thomas Schmitt diff --git a/cdrskin/add_ts_changes_to_libburn_0_2_4 b/cdrskin/add_ts_changes_to_libburn_0_2_4 deleted file mode 100755 index 975c565..0000000 --- a/cdrskin/add_ts_changes_to_libburn_0_2_4 +++ /dev/null @@ -1,203 +0,0 @@ -#!/bin/sh - -set -x - -# This script documents how this cdrskin version was derived from -# a vanilla libburn version. It is not intended nor needed for any -# use of cdrskin but included here only to show the technical -# relationship between both projects - which are close friends -# and issue roughly the same software. -# -# Package maintainers are advised to cover rather libburn than -# cdrskin unless they put only emphasis on the cdrecord emulation -# provided by cdrskin. libburn contains cdrskin - cdrskin is an -# oscillating, friendly and coordinated fork of libburn. -# -# Script results are a source tarball and two binaries -# one dynamic and one static in respect to system libs. -# Both binaries are static in respect to libburn. -# -# The script is to be run in the directory above the toplevel -# directory of libburn resp. cdrskin development. -# -# libburn version used: http://libburn.pykix.org -# Downloaded by: -# $ svn co http://libburn-svn.pykix.org/trunk libburn_pykix -# packed up in a tarball just to save it from inadverted changes by -# $ tar czf libburn_svn.tgz libburn_pykix -original="./libburn_svn.tgz" -# Historic moments: -# original="./libburn_svn_A60815.tgz" -# original="./libburn_cdrskin_A60819.tgz" - -# The top level directory in that snapshot is named -intermediate="./libburn_pykix" - -# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin - -changes="./libburn-0.2.3.ts.develop" -skin_rev="0.2.4" - -# The result directory and the name of the result tarballs -target="./cdrskin-${skin_rev}" -cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz" -cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz" - -# (This once earned me an embarrassingly blooping source tarball) -# compile_dir="$changes" - -compile_dir="$target" -compile_cmd="./cdrskin/compile_cdrskin.sh" -compile_static_opts="-static" -compile_result="cdrskin/cdrskin" - -bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0" -bintarget_static="$bintarget_dynamic"-static - -if test -d "$changes" -then - dummy=dummy -else - echo "$0 : FATAL : no directory $changes" >&2 - exit 1 -fi - -for i in "$target" "$intermediate" -do - if test -e "$i" - then - echo "$0 : FATAL : already existing $i" >&2 - exit 2 - fi -done - -if test -f "$original" -then - dummy=dummy -else - echo "$0 : FATAL : no file $original" >&2 - exit 3 -fi - - -# Unpack SVN snapshot. -tar xzf "$original" - - -# Rename the directory to the cdrskin name -mv "$intermediate" "$target" - - -# Copy the changes from the development tree -# -cdrskin_dir="$changes"/cdrskin -libburn_dir="$changes"/libburn -cdrskin_target="$target"/cdrskin -libburn_target="$target"/libburn - -# Create version timestamp -timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" -echo "$timestamp" -echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h - -# Add the cdrskin files -if test -e "$cdrskin_target" -then - rm -rf "$cdrskin_target" -fi -cp -a "$cdrskin_dir" "$cdrskin_target" - -# Remove copied binaries -rm "$cdrskin_target"/*.o -rm "$cdrskin_target"/cdrfifo -rm "$cdrskin_target"/cdrskin -rm "$cdrskin_target"/cleanup -for i in std new make old -do - if test -e "$cdrskin_target"/cdrskin_"$i" - then - rm "$cdrskin_target"/cdrskin_"$i" - fi -done -for i in .deps .dirstamp .libs -do - if test -e "$cdrskin_target"/"$i" - then - rm -rf "$cdrskin_target"/"$i" - fi -done - -# Remove unwanted SVN stuff (TODO: avoid downloading it) -for i in "$target"/.svn "$target"/*/.svn -do - if test "$i" = "$target"'/*/.svn' - then - dummy=dummy - else - if test -e "$i" - then - rm -rf "$i" - fi - fi -done - -## No more : Add own libburn-README in toplevel -# cp -a "$changes"/README "$target" - -## No more : Add modified Makefile.am -# cp -a "$changes"/Makefile.am "$target" - - -# Make SVN state tarball for the libburn team -tar czf "$cdrskin_tarball_svn" "$target" - - -# Get over dependecy on autotools. Rely only on cc, make et. al. -# This is not the same as "make dist" but i can do it without -# having to evaluate the quality of said "make dist" -# -( cd "$target" ; ./bootstrap ) - -# Remove unwanted stuff after bootstrap -for i in "$target"/autom4te.cache -do - if echo "$i" | grep '\*' >/dev/null - then - dummy=dummy - else - if test -e "$i" - then - rm -rf "$i" - fi - fi -done - - -# Pack it up to the new libburn+cdrskin-tarball -tar czf "$cdrskin_tarball" "$target" - -# Produce a static and a dynamic binary -( - cd "$compile_dir" || exit 1 - ./configure - make - $compile_cmd -do_strip - cp "$compile_result" "../$bintarget_dynamic" - if test -n "$compile_static_opts" - then - $compile_cmd $compile_static_opts -do_strip - cp "$compile_result" "../$bintarget_static" - fi -) - -# Remove the build area -# Disable this for debugging the merge process -rm -rf "$target" - -# Show the result -./"$bintarget_dynamic" -version -./"$bintarget_static" -version -ls -l "$cdrskin_tarball" -ls -l "$bintarget_dynamic" -ls -l "$bintarget_static" - diff --git a/cdrskin/add_ts_changes_to_libburn_0_2_5 b/cdrskin/add_ts_changes_to_libburn_0_2_5 deleted file mode 100755 index 8e7b0b1..0000000 --- a/cdrskin/add_ts_changes_to_libburn_0_2_5 +++ /dev/null @@ -1,203 +0,0 @@ -#!/bin/sh - -set -x - -# This script documents how this cdrskin version was derived from -# a vanilla libburn version. It is not intended nor needed for any -# use of cdrskin but included here only to show the technical -# relationship between both projects - which are close friends -# and issue roughly the same software. -# -# Package maintainers are advised to cover rather libburn than -# cdrskin unless they put only emphasis on the cdrecord emulation -# provided by cdrskin. libburn contains cdrskin - cdrskin is an -# oscillating, friendly and coordinated fork of libburn. -# -# Script results are a source tarball and two binaries -# one dynamic and one static in respect to system libs. -# Both binaries are static in respect to libburn. -# -# The script is to be run in the directory above the toplevel -# directory of libburn resp. cdrskin development. -# -# libburn version used: http://libburn.pykix.org -# Downloaded by: -# $ svn co http://libburn-svn.pykix.org/trunk libburn_pykix -# packed up in a tarball just to save it from inadverted changes by -# $ tar czf libburn_svn.tgz libburn_pykix -original="./libburn_svn.tgz" -# Historic moments: -# original="./libburn_svn_A60815.tgz" -# original="./libburn_cdrskin_A60819.tgz" - -# The top level directory in that snapshot is named -intermediate="./libburn_pykix" - -# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin - -changes="./libburn-0.2.3.ts.develop" -skin_rev="0.2.5" - -# The result directory and the name of the result tarballs -target="./cdrskin-${skin_rev}" -cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz" -cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz" - -# (This once earned me an embarrassingly blooping source tarball) -# compile_dir="$changes" - -compile_dir="$target" -compile_cmd="./cdrskin/compile_cdrskin.sh" -compile_static_opts="-static" -compile_result="cdrskin/cdrskin" - -bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0" -bintarget_static="$bintarget_dynamic"-static - -if test -d "$changes" -then - dummy=dummy -else - echo "$0 : FATAL : no directory $changes" >&2 - exit 1 -fi - -for i in "$target" "$intermediate" -do - if test -e "$i" - then - echo "$0 : FATAL : already existing $i" >&2 - exit 2 - fi -done - -if test -f "$original" -then - dummy=dummy -else - echo "$0 : FATAL : no file $original" >&2 - exit 3 -fi - - -# Unpack SVN snapshot. -tar xzf "$original" - - -# Rename the directory to the cdrskin name -mv "$intermediate" "$target" - - -# Copy the changes from the development tree -# -cdrskin_dir="$changes"/cdrskin -libburn_dir="$changes"/libburn -cdrskin_target="$target"/cdrskin -libburn_target="$target"/libburn - -# Create version timestamp -timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" -echo "$timestamp" -echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h - -# Add the cdrskin files -if test -e "$cdrskin_target" -then - rm -rf "$cdrskin_target" -fi -cp -a "$cdrskin_dir" "$cdrskin_target" - -# Remove copied binaries -rm "$cdrskin_target"/*.o -rm "$cdrskin_target"/cdrfifo -rm "$cdrskin_target"/cdrskin -rm "$cdrskin_target"/cleanup -for i in std new make old -do - if test -e "$cdrskin_target"/cdrskin_"$i" - then - rm "$cdrskin_target"/cdrskin_"$i" - fi -done -for i in .deps .dirstamp .libs -do - if test -e "$cdrskin_target"/"$i" - then - rm -rf "$cdrskin_target"/"$i" - fi -done - -# Remove unwanted SVN stuff (TODO: avoid downloading it) -for i in "$target"/.svn "$target"/*/.svn -do - if test "$i" = "$target"'/*/.svn' - then - dummy=dummy - else - if test -e "$i" - then - rm -rf "$i" - fi - fi -done - -## No more : Add own libburn-README in toplevel -# cp -a "$changes"/README "$target" - -## No more : Add modified Makefile.am -# cp -a "$changes"/Makefile.am "$target" - - -# Make SVN state tarball for the libburn team -tar czf "$cdrskin_tarball_svn" "$target" - - -# Get over dependecy on autotools. Rely only on cc, make et. al. -# This is not the same as "make dist" but i can do it without -# having to evaluate the quality of said "make dist" -# -( cd "$target" ; ./bootstrap ) - -# Remove unwanted stuff after bootstrap -for i in "$target"/autom4te.cache -do - if echo "$i" | grep '\*' >/dev/null - then - dummy=dummy - else - if test -e "$i" - then - rm -rf "$i" - fi - fi -done - - -# Pack it up to the new libburn+cdrskin-tarball -tar czf "$cdrskin_tarball" "$target" - -# Produce a static and a dynamic binary -( - cd "$compile_dir" || exit 1 - ./configure - make - $compile_cmd -do_strip - cp "$compile_result" "../$bintarget_dynamic" - if test -n "$compile_static_opts" - then - $compile_cmd $compile_static_opts -do_strip - cp "$compile_result" "../$bintarget_static" - fi -) - -# Remove the build area -# Disable this for debugging the merge process -rm -rf "$target" - -# Show the result -./"$bintarget_dynamic" -version -./"$bintarget_static" -version -ls -l "$cdrskin_tarball" -ls -l "$bintarget_dynamic" -ls -l "$bintarget_static" - diff --git a/cdrskin/cdrecord_spy.sh b/cdrskin/cdrecord_spy.sh deleted file mode 100755 index 54d7c34..0000000 --- a/cdrskin/cdrecord_spy.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# -# Spying on the call to cdrecord. -# -# Move $(which cdrecord) to $(dirname $(which cdrecord))/real_cdrecord . -# Install this sript instead. (Do not forget to revoke this after the test.) -# - -# The report target is set in variable rt. -# The default is this file : -rt=/tmp/cdrecord_spy_log - -# To use a bystanding xterm as target i find out the pty address by -# executing in that terminal -# sleep 12345 -# and then running in another terminal -# ps -ef | grep 'sleep 12345' -# which answers something like -# thomas 21303 30518 0 14:02 pts/23 00:00:00 sleep 12345 -# thomas 21421 30523 0 14:02 pts/24 00:00:00 grep sleep 12345 -# from which i learn that pts/23 is sleeping 12345. Now sleep can be aborted. -# -# rt=/dev/pts/23 - -echo '------------------------------------- cdrecord_spy 0.1.0 -------' >>"$rt" -date >>"$rt" -echo '----------------------------------------------------------------' >>"$rt" -echo "$0" >>"$rt" -for i in "$@" -do - echo "$i" >>"$rt" -done -echo '------------------------------------- cdrecord_spy 0.1.0 - end -' >>"$rt" - -real_cdrecord "$@" - - diff --git a/cdrskin/cdrfifo.c b/cdrskin/cdrfifo.c deleted file mode 100644 index 008468f..0000000 --- a/cdrskin/cdrfifo.c +++ /dev/null @@ -1,1081 +0,0 @@ -/* - cdrfifo.c , Copyright 2006 Thomas Schmitt - - A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently. - By chaining of fifo objects, several fifos can be run simultaneously - in fd-to-fd mode. Modes are controlled by parameter flag of - Cdrfifo_try_to_work(). - - Provided under GPL license within cdrskin and under BSD license elsewise. -*/ - -/* - Compile as standalone tool : - cc -g -o cdrfifo -DCdrfifo_standalonE cdrfifo.c -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cdrfifo.h" - - -/* Macro for creation of arrays of objects (or single objects) */ -#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ)); - - -#define Cdrfifo_buffer_chunK 2048 - -/** Number of follow-up fd pairs */ -#define Cdrfifo_ffd_maX 100 - - -/* 1= enable , 0= disable status messages to stderr */ -static int Cdrfifo_debuG= 0; - - -struct CdrfifO { - int chunk_size; - - int source_fd; - double in_counter; - - double fd_in_counter; - double fd_in_limit; - - char *buffer; - int buffer_size; - int buffer_is_full; - int write_idx; - int read_idx; - - int dest_fd; - double out_counter; - - struct timeval start_time; - double speed_limit; - - /* statistics */ - double interval_counter; - struct timeval interval_start_time; - double interval_start_counter; - int total_min_fill; - int interval_min_fill; - - double put_counter; - double get_counter; - double empty_counter; - double full_counter; - - - /* (sequential) fd chaining */ - /* fds: 0=source, 1=dest */ - int follow_up_fds[Cdrfifo_ffd_maX][2]; - - /* index of first byte in buffer which does not belong to predecessor fd */ - int follow_up_eop[Cdrfifo_ffd_maX]; - - /* index of first byte in buffer which belongs to [this] fd pair */ - int follow_up_sod[Cdrfifo_ffd_maX]; - - /* values for fd_in_limit */ - double follow_up_in_limits[Cdrfifo_ffd_maX]; - - /* number of defined follow-ups */ - int follow_up_fd_counter; - - /* index of currently active (i.e. reading) follow-up */ - int follow_up_fd_idx; - - - /* (simultaneous) peer chaining */ - struct CdrfifO *next; - struct CdrfifO *prev; -}; - - -/** Create a fifo object. - @param ff Returns the address of the new object. - @param source_fd Filedescriptor opened to a readable data stream. - @param dest_fd Filedescriptor opened to a writable data stream. - To work with libburn, it needs to be attached to a - struct burn_source object. - @param chunk_size Size of buffer block for a single transaction (0=default) - @param buffer_size Size of fifo buffer - @param flag Unused yet - @return 1 on success, <=0 on failure -*/ -int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd, - int chunk_size, int buffer_size, int flag) -{ - struct CdrfifO *o; - struct timezone tz; - int i; - - (*ff)= o= TSOB_FELD(struct CdrfifO,1); - if(o==NULL) - return(-1); - if(chunk_size<=0) - chunk_size= Cdrfifo_buffer_chunK; - o->chunk_size= chunk_size; - if(buffer_size%chunk_size) - buffer_size+= chunk_size-(buffer_size%chunk_size); - o->source_fd= source_fd; - o->in_counter= 0.0; - o->fd_in_counter= 0; - o->fd_in_limit= -1.0; - o->buffer= NULL; - o->buffer_is_full= 0; - o->buffer_size= buffer_size; - o->write_idx= 0; - o->read_idx= 0; - o->dest_fd= dest_fd; - o->out_counter= 0.0; - memset(&(o->start_time),0,sizeof(o->start_time)); - gettimeofday(&(o->start_time),&tz); - o->speed_limit= 0.0; - o->interval_counter= 0.0; - memset(&(o->interval_start_time),0,sizeof(o->interval_start_time)); - gettimeofday(&(o->interval_start_time),&tz); - o->interval_start_counter= 0.0; - o->total_min_fill= buffer_size; - o->interval_min_fill= buffer_size; - o->put_counter= 0.0; - o->get_counter= 0.0; - o->empty_counter= 0.0; - o->full_counter= 0.0; - for(i= 0; ifollow_up_fds[i][0]= o->follow_up_fds[i][1]= -1; - o->follow_up_eop[i]= o->follow_up_sod[i]= -1; - o->follow_up_in_limits[i]= -1.0; - } - o->follow_up_fd_counter= 0; - o->follow_up_fd_idx= -1; - o->next= o->prev= NULL; - o->buffer= TSOB_FELD(char,buffer_size); - if(o->buffer==NULL) - goto failed; - return(1); -failed:; - Cdrfifo_destroy(ff,0); - return(-1); -} - - -/** Close any output fds */ -int Cdrfifo_close(struct CdrfifO *o, int flag) -{ - int i; - - if(o->dest_fd!=-1) - close(o->dest_fd); - o->dest_fd= -1; - for(i=0; ifollow_up_fd_counter; i++) - if(o->follow_up_fds[i][1]!=-1) - close(o->follow_up_fds[i][1]); - o->follow_up_fds[i][1]= -1; - return(1); -} - - -/** Release from memory a fifo object previously created by Cdrfifo_new(). - @param ff The victim (gets returned as NULL, call can stand *ff==NULL)) - @param flag Bitfield for control purposes: - bit0= do not close destination fd -*/ -int Cdrfifo_destroy(struct CdrfifO **ff, int flag) -/* flag - bit0= do not close destination fd -*/ -{ - struct CdrfifO *o; - - o= *ff; - if(o==NULL) - return(0); - if(o->next!=NULL) - o->next->prev= o->prev; - if(o->prev!=NULL) - o->prev->next= o->next; - if(!(flag&1)) - Cdrfifo_close(o,0); - - /* eventual closing of source fds is the job of the calling application */ - - if(o->buffer!=NULL) - free((char *) o->buffer); - free((char *) o); - (*ff)= NULL; - return(1); -} - - -int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size, - int flag) -{ - *chunk_size= o->chunk_size; - *buffer_size= o->buffer_size; - return(1); -} - -/** Set a speed limit for buffer output. - @param o The fifo object - @param bytes_per_second >0 catch up slowdowns over the whole run time - <0 catch up slowdowns only over one interval - =0 disable speed limit -*/ -int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second, - int flag) -{ - o->speed_limit= bytes_per_second; - return(1); -} - - -/** Set a fixed size for input in order to cut off any unwanted tail - @param o The fifo object - @param idx index for fds attached via Cdrfifo_attach_follow_up_fds(), - first attached is 0, <0 directs limit to active fd limit - (i.e. first track is -1, second track is 0, third is 1, ...) -*/ -int Cdrfifo_set_fd_in_limit(struct CdrfifO *o, double fd_in_limit, int idx, - int flag) -{ - if(idx<0) { - o->fd_in_limit= fd_in_limit; - return(1); - } - if(idx >= o->follow_up_fd_counter) - return(0); - o->follow_up_in_limits[idx]= fd_in_limit; - return(1); -} - - -int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag) -{ - o->source_fd= source_fd; - o->dest_fd= dest_fd; - return(1); -} - - -int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag) -{ - *source_fd= o->source_fd; - *dest_fd= o->dest_fd; - return(1); -} - - -/** Attach a further pair of input and output fd which will use the same - fifo buffer when its predecessors are exhausted. Reading will start as - soon as reading of the predecessor encounters EOF. Writing will start - as soon as all pending predecessor data are written. - @return index number of new item + 1, <=0 indicates error -*/ -int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd, - int flag) -{ - if(o->follow_up_fd_counter>=Cdrfifo_ffd_maX) - return(0); - o->follow_up_fds[o->follow_up_fd_counter][0]= source_fd; - o->follow_up_fds[o->follow_up_fd_counter][1]= dest_fd; - o->follow_up_fd_counter++; - return(o->follow_up_fd_counter); -} - - -/** Attach a further fifo which shall be processed simultaneously with this - one by Cdrfifo_try_to_work() in fd-to-fd mode. -*/ -int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag) -{ - for(;o->next!=NULL;o= o->next); /* determine end of o-chain */ - for(;next->prev!=NULL;next= next->prev); /* determine start of next-chain */ - next->prev= o; - o->next= next; - return(1); -} - - -static int Cdrfifo_tell_buffer_space(struct CdrfifO *o, int flag) -{ - if(o->buffer_is_full) - return(0); - if(o->write_idx>=o->read_idx) - return((o->buffer_size - o->write_idx) + o->read_idx); - return(o->read_idx - o->write_idx); -} - - -/** Obtain buffer state. - @param o The buffer object - @param fill Returns the number of pending payload bytes in the buffer - @param space Returns the number of unused buffer bytes - @param flag Unused yet - @return -1=error , 0=inactive , 1=reading and writing , - 2=reading ended (but still writing) -*/ -int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag) -/* return : - -1=error - 0=inactive - 1=reading and writing - 2=reading ended, still writing -*/ -{ - *space= Cdrfifo_tell_buffer_space(o,0); - *fill= o->buffer_size-(*space); - if(o->dest_fd==-1) - return(0); - if(o->source_fd<0) - return(2); - return(1); -} - - -int Cdrfifo_get_counters(struct CdrfifO *o, - double *in_counter, double *out_counter, int flag) -{ - *in_counter= o->in_counter; - *out_counter= o->out_counter; - return(1); -} - - -/** reads min_fill and begins measurement interval for next min_fill */ -int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag) -{ - struct timezone tz; - - o->interval_counter++; - gettimeofday(&(o->interval_start_time),&tz); - o->interval_start_counter= o->out_counter; - *min_fill= o->interval_min_fill; - o->interval_min_fill= o->buffer_size - Cdrfifo_tell_buffer_space(o,0); - return(1); -} - - -int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill, - int *interval_min_fill, int flag) -{ - *total_min_fill= o->total_min_fill; - *interval_min_fill= o->interval_min_fill; - return(1); -} - - -/** Get counters which are mentioned by cdrecord at the end of burning. - It still has to be examined wether they mean what i believe they do. -*/ -int Cdrfifo_get_cdr_counters(struct CdrfifO *o, - double *put_counter, double *get_counter, - double *empty_counter, double *full_counter, - int flag) -{ - *put_counter= o->put_counter;; - *get_counter= o->get_counter; - *empty_counter= o->empty_counter; - *full_counter= o->full_counter; - return(1); -} - - -/** Adjust a given buffer fill value so it will not cross an eop boundary. - @param o The fifo to exploit. - @param buffer_fill The byte count to adjust. - @param eop_idx If eop boundary exactly hit: index of follow-up fd pair - @param flag Unused yet. - @return 0= nothing changed , 1= buffer_fill adjusted -*/ -int Cdrfifo_eop_adjust(struct CdrfifO *o,int *buffer_fill, int *eop_idx, - int flag) -{ - int i,eop_is_near= 0,valid_fill; - - *eop_idx= -1; - valid_fill= *buffer_fill; - for(i=0; i<=o->follow_up_fd_idx; i++) { - if(o->follow_up_eop[i]>=0 && o->follow_up_eop[i]>=o->read_idx) { - eop_is_near= 1; - valid_fill= o->follow_up_eop[i]-o->read_idx; - if(valid_fill==0) - *eop_idx= i; - else if(valid_fill<=o->chunk_size) - eop_is_near= 2; /* for debugging. to carry a break point */ - break; - } - } - if(*buffer_fill>valid_fill) - *buffer_fill= valid_fill; - return(!!eop_is_near); -} - - -/* Perform pre-select activities of Cdrfifo_try_to_work() */ -static int Cdrfifo_setup_try(struct CdrfifO *o, struct timeval start_tv, - double start_out_counter, int *still_to_wait, - int *speed_limiter, int *ready_to_write, - fd_set *rds, fd_set *wts, int *max_fd, int flag) -/* flag: - bit0= enable debug pacifier (same with Cdrfifo_debuG) - bit1= do not write, just fill buffer - bit2= fd-to-memory mode (else fd-to-fd mode): - rather than writing a chunk return it and its size in reply_* - bit3= with bit2: do not check destination fd for readiness -*/ -{ - int buffer_space,buffer_fill,eop_reached= -1,eop_is_near= 0,was_closed; - int fd_buffer_fill; - struct timeval current_tv; - struct timezone tz; - double diff_time,diff_counter,limit,min_wait_time; - -setup_try:; - buffer_space= Cdrfifo_tell_buffer_space(o,0); - fd_buffer_fill= buffer_fill= o->buffer_size - buffer_space; - -#ifdef NIX - fprintf(stderr,"cdrfifo_debug: o->write_idx=%d o->read_idx=%d o->source_fd=%d\n",o->write_idx,o->read_idx,o->source_fd); - if(buffer_fill>10) - sleep(1); -#endif - - if(o->follow_up_fd_idx>=0) - eop_is_near= Cdrfifo_eop_adjust(o,&fd_buffer_fill,&eop_reached,0); - - if(fd_buffer_fill<=0 && (o->source_fd==-1 || eop_reached>=0) ) { - was_closed= 0; - if(o->dest_fd!=-1 && !(flag&4)) - close(o->dest_fd); - if(o->dest_fd<0) - was_closed= 1; - else - o->dest_fd= -1; - - if(eop_reached>=0) { /* switch to next output fd */ - o->dest_fd= o->follow_up_fds[eop_reached][1]; - o->read_idx= o->follow_up_sod[eop_reached]; - o->follow_up_eop[eop_reached]= -1; - eop_is_near= 0; - eop_reached= -1; - goto setup_try; - } else { - /* work is really done */ - if((!was_closed) && ((flag&1)||Cdrfifo_debuG)) - fprintf(stderr, - "\ncdrfifo_debug: w=%d r=%d | b=%d s=%d | i=%.f o=%.f (done)\n", - o->write_idx,o->read_idx,buffer_fill,buffer_space, - o->in_counter,o->out_counter); - return(2); - } - } - if(o->interval_counter>0) { - if(o->total_min_fill>buffer_fill && o->source_fd>=0) - o->total_min_fill= buffer_fill; - if(o->interval_min_fill>buffer_fill) - o->interval_min_fill= buffer_fill; - } - *speed_limiter= 0; - if(o->speed_limit!=0) { - gettimeofday(¤t_tv,&tz); - if(o->speed_limit>0) { - diff_time= ((double) current_tv.tv_sec)-((double) o->start_time.tv_sec)+ - (((double) current_tv.tv_usec)-((double) o->start_time.tv_usec))*1e-6; - diff_counter= o->out_counter; - limit= o->speed_limit; - } else if(flag&4) { - if(o->interval_start_time.tv_sec==0) - o->interval_start_time= start_tv; - diff_time= ((double) current_tv.tv_sec) - - ((double) o->interval_start_time.tv_sec) - + (((double) current_tv.tv_usec) - -((double) o->interval_start_time.tv_usec))*1e-6; - diff_counter= o->out_counter - o->interval_start_counter; - limit= -o->speed_limit; - } else { - diff_time= ((double) current_tv.tv_sec) - ((double) start_tv.tv_sec) - + (((double) current_tv.tv_usec) - -((double)start_tv.tv_usec))*1e-6; - diff_counter= o->out_counter - start_out_counter; - limit= -o->speed_limit; - } - if(diff_time>0.0) - if(diff_counter/diff_time>limit) { - min_wait_time= (diff_counter/limit - diff_time)*1.0e6; - if(min_wait_time<*still_to_wait) - *still_to_wait= min_wait_time; - if(*still_to_wait>0) - *speed_limiter= 1; - } - } - if(o->source_fd>=0) { - if(buffer_space>0) { - FD_SET((o->source_fd),rds); - if(*max_fdsource_fd) - *max_fd= o->source_fd; - } else if(o->interval_counter>0) - o->full_counter++; - } - *ready_to_write= 0; - if(o->dest_fd>=0 && (!(flag&2)) && !*speed_limiter) { - if(fd_buffer_fill>=o->chunk_size || o->source_fd<0 || eop_is_near) { - if((flag&(4|8))==(4|8)) { - *still_to_wait= 0; - *ready_to_write= 1; - } else { - FD_SET((o->dest_fd),wts); - if(*max_fddest_fd) - *max_fd= o->dest_fd; - } - } else if(o->interval_counter>0) - o->empty_counter++; - } - return(1); -} - - -/* Perform post-select activities of Cdrfifo_try_to_work() */ -static int Cdrfifo_transact(struct CdrfifO *o, fd_set *rds, fd_set *wts, - char *reply_buffer, int *reply_count, int flag) -/* flag: - bit0= enable debug pacifier (same with Cdrfifo_debuG) - bit1= do not write, just fill buffer - bit2= fd-to-memory mode (else fd-to-fd mode): - rather than writing a chunk return it and its size in reply_* - bit3= with bit2: do not check destination fd for readiness -return: <0 = error , 0 = idle , 1 = did some work -*/ -{ - double buffer_space; - int can_read,can_write,ret,did_work= 0,idx,sod,eop_is_near,eop_idx; - - buffer_space= Cdrfifo_tell_buffer_space(o,0); - if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) { - can_write= o->buffer_size - buffer_space; - if(can_write>o->chunk_size) - can_write= o->chunk_size; - if(o->read_idx+can_write > o->buffer_size) - can_write= o->buffer_size - o->read_idx; - if(o->follow_up_fd_idx>=0) { - eop_is_near= Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0); - if(can_write<=0) - goto after_write; - } - if(flag&4) { - memcpy(reply_buffer,o->buffer+o->read_idx,can_write); - *reply_count= ret= can_write; - } else { - ret= write(o->dest_fd,o->buffer+o->read_idx,can_write); - } - if(ret==-1) { - - /* >>> handle broken pipe */; - fprintf(stderr,"\ncdrfifo: on write: errno=%d , \"%s\"\n",errno, - errno==0?"-no error code available-":strerror(errno)); - - if(!(flag&4)) - close(o->dest_fd); - o->dest_fd= -1; - {ret= -1; goto ex;} - } - did_work= 1; - o->get_counter++; - o->out_counter+= can_write; - o->read_idx+= can_write; - if(o->read_idx>=o->buffer_size) - o->read_idx= 0; - o->buffer_is_full= 0; - } -after_write:; - if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) { - can_read= o->buffer_size - o->write_idx; - if(can_read>o->chunk_size) - can_read= o->chunk_size; - if(o->write_idxread_idx && o->write_idx+can_read > o->read_idx) - can_read= o->read_idx - o->write_idx; - if(o->fd_in_limit>=0.0) - if(can_read > o->fd_in_limit - o->fd_in_counter) - can_read= o->fd_in_limit - o->fd_in_counter; - ret= 0; - if(can_read>0) - ret= read(o->source_fd,o->buffer+o->write_idx,can_read); - if(ret==-1) { - - /* >>> handle input error */; - fprintf(stderr,"\ncdrfifo: on read: errno=%d , \"%s\"\n",errno, - errno==0?"-no error code available-":strerror(errno)); - - o->source_fd= -1; - } else if(ret==0) { /* eof */ - /* activate eventual follow-up source fd */ - if(Cdrfifo_debuG || (flag&1)) - fprintf(stderr,"\ncdrfifo: on read(%d,buffer,%d): eof\n", - o->source_fd,can_read); - if(o->follow_up_fd_idx+1 < o->follow_up_fd_counter) { - idx= ++(o->follow_up_fd_idx); - o->source_fd= o->follow_up_fds[idx][0]; - /* End-Of-Previous */ - if(o->write_idx==0) - o->follow_up_eop[idx]= o->buffer_size; - else - o->follow_up_eop[idx]= o->write_idx; - /* Start-Of-Data . Try to start at next full chunk */ - sod= o->write_idx; - if(o->write_idx%o->chunk_size) - sod+= o->chunk_size - (o->write_idx%o->chunk_size); - /* but do not catch up to the read pointer */ - if((o->write_idx<=o->read_idx && o->read_idx<=sod) || sod==o->read_idx) - sod= o->write_idx; - if(sod>=o->buffer_size) - sod= 0; - o->follow_up_sod[idx]= sod; - o->write_idx= sod; - o->fd_in_counter= 0; - o->fd_in_limit= o->follow_up_in_limits[idx]; - if(Cdrfifo_debuG || (flag&1)) - fprintf(stderr,"\ncdrfio: new fifo source fd : %d\n",o->source_fd); - } else { - o->source_fd= -1; - } - } else { - did_work= 1; - o->put_counter++; - o->in_counter+= ret; - o->fd_in_counter+= ret; - o->write_idx+= ret; - if(o->write_idx>=o->buffer_size) - o->write_idx= 0; - if(o->write_idx==o->read_idx) - o->buffer_is_full= 1; - } - } - ret= !!did_work; -ex:; - return(ret); -} - - -/** Check for pending data at the fifo's source file descriptor and wether the - fifo is ready to take them. Simultaneously check the buffer for existing - data and the destination fd for readiness to accept some. If so, a small - chunk of data is transfered to and/or from the fifo. - This is done for the given fifo object and all members of its next-chain. - The check and transactions are repeated until a given timespan has elapsed. - libburn applications call this function in the burn loop instead of sleep(). - It may also be used instead of read(). Then it returns as soon as an output - transaction would be performed. See flag:bit2. - @param o The fifo object - @param wait_usec The time in microseconds after which the function shall - return. - @param reply_buffer with bit2: Returns write-ready buffer chunk and must - be able to take at least chunk_size bytes - @param reply_count with bit2: Returns number of writeable bytes in reply - @param flag Bitfield for control purposes: - bit0= Enable debug pacifier (same with Cdrfifo_debuG) - bit1= Do not write, just fill buffer - bit2= fd-to-memory mode (else fd-to-fd mode): - Rather than writing a chunk return it and its size. - No simultaneous processing of chained fifos. - bit3= With bit2: do not check destination fd for readiness - @return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done -*/ -int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec, - char *reply_buffer, int *reply_count, int flag) -{ - struct timeval wt,start_tv,current_tv; - struct timezone tz; - fd_set rds,wts,exs; - int ready,ret,max_fd= -1,buffer_space,dummy,still_active= 0; - int did_work= 0,elapsed,still_to_wait,speed_limiter= 0,ready_to_write= 0; - double start_out_counter; - struct CdrfifO *ff; - - start_out_counter= o->out_counter; - gettimeofday(&start_tv,&tz); - still_to_wait= wait_usec; - if(flag&4) - *reply_count= 0; - -try_again:; - /* is there still a destination open ? */ - for(ff= o; ff!=NULL; ff= ff->next) - if(ff->dest_fd!=-1) - break; - if(ff==NULL) - return(2); - FD_ZERO(&rds); - FD_ZERO(&wts); - FD_ZERO(&exs); - - for(ff= o; ff!=NULL; ff= ff->next) { - ret= Cdrfifo_setup_try(ff,start_tv,start_out_counter, - &still_to_wait,&speed_limiter,&ready_to_write, - &rds,&wts,&max_fd,flag&15); - if(ret<=0) - return(ret); - else if(ret==2) { - /* This fifo is done */; - } else - still_active= 1; - if(flag&2) - break; - } - if(!still_active) - return(2); - - if(still_to_wait>0 || max_fd>=0) { - wt.tv_sec= still_to_wait/1000000; - wt.tv_usec= still_to_wait%1000000; - ready= select(max_fd+1,&rds,&wts,&exs,&wt); - } else - ready= 0; - if(ready<=0) { - if(!ready_to_write) - goto check_wether_done; - FD_ZERO(&rds); - } - if(ready_to_write) - FD_SET((o->dest_fd),&wts); - - for(ff= o; ff!=NULL; ff= ff->next) { - ret= Cdrfifo_transact(ff,&rds,&wts,reply_buffer,reply_count,flag&15); - if(ret<0) - goto ex; - if(ret>0) - did_work= 1; - if(flag&2) - break; - } - -check_wether_done:; - if((flag&4) && *reply_count>0) - {ret= 1; goto ex;} - gettimeofday(¤t_tv,&tz); - elapsed= (current_tv.tv_sec-start_tv.tv_sec)*1000000 + - (((int) current_tv.tv_usec) - ((int) start_tv.tv_usec)); - still_to_wait= wait_usec-elapsed; - if(still_to_wait>0) - goto try_again; - ret= !!did_work; -ex:; - if(flag&4) { - gettimeofday(¤t_tv,&tz); - elapsed= (current_tv.tv_sec - o->interval_start_time.tv_sec)*1000000 - + (((int) current_tv.tv_usec) - - ((int) o->interval_start_time.tv_usec)); - } else - elapsed= wait_usec; - if(elapsed>=wait_usec) { - if((flag&1)||Cdrfifo_debuG) { - fprintf(stderr,"\n"); - for(ff= o; ff!=NULL; ff= ff->next) { - buffer_space= Cdrfifo_tell_buffer_space(ff,0); - fprintf(stderr, - "cdrfifo_debug: w=%d r=%d | b=%d s=%d | i=%.f o=%.f\n", - ff->write_idx,ff->read_idx, - ff->buffer_size-buffer_space,buffer_space, - ff->in_counter,ff->out_counter); - } - } - if(flag&4) - Cdrfifo_next_interval(o,&dummy,0); - } - return(ret); -} - - -/** Fill the fifo as far as possible without writing to destination fd */ -int Cdrfifo_fill(struct CdrfifO *o, int flag) -{ - int ret,fill= 0,space,state; - - while(1) { - state= Cdrfifo_get_buffer_state(o,&fill,&space,0); - if(state==-1) { - - /* >>> handle error */; - - return(0); - } else if(state!=1) - break; - if(space<=0) - break; - ret= Cdrfifo_try_to_work(o,100000,NULL,NULL,2); - if(ret<0) { - - /* >>> handle error */; - - return(0); - } - if(ret==2) - break; - } - o->total_min_fill= fill; - o->interval_min_fill= fill; - return(1); -} - - -int Cdrfifo_close_all(struct CdrfifO *o, int flag) -{ - struct CdrfifO *ff; - - if(o==NULL) - return(0); - for(ff= o; ff->prev!=NULL; ff= ff->prev); - for(; ff!=NULL; ff= ff->next) - Cdrfifo_close(ff,0); - return(1); -} - - - -#ifdef Cdrfifo_standalonE - -/* ---------------------------------------------------------------------- */ - -/** Application example. See also cdrskin.c */ - - -double Scanf_io_size(char *text, int flag) -/* - bit0= default value -1 rather than 0 -*/ -{ - int c; - double ret= 0.0; - - if(flag&1) - ret= -1.0; - if(text[0]==0) - return(ret); - sscanf(text,"%lf",&ret); - c= text[strlen(text)-1]; - if(c=='k' || c=='K') ret*= 1024.0; - if(c=='m' || c=='M') ret*= 1024.0*1024.0; - if(c=='g' || c=='G') ret*= 1024.0*1024.0*1024.0; - if(c=='t' || c=='T') ret*= 1024.0*1024.0*1024.0*1024.0; - if(c=='p' || c=='P') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0; - if(c=='e' || c=='E') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0*1024.0; - if(c=='s' || c=='S') ret*= 2048.0; - return(ret); -} - - -/* This is a hardcoded test mock-up for two simultaneous fifos of which the - first one simulates the cdrskin fifo feeding libburn and the second one - simulates libburn and the burner at given speed. Both have two fd pairs - (i.e. tracks). The tracks are read from /u/test/cdrskin/in_[12] and - written to /u/test/cdrskin/out_[12]. -*/ -int Test_multi(int fs_size, double speed_limit, double interval, int flag) -/* - bit0= debugging verbousity -*/ -{ - int fd_in[4],fd_out[4],ret,pipe_fds[4][2],real_out[4],pipe_idx; - int i,iv; - char buf[10240]; - struct CdrfifO *ff1= NULL,*ff2= NULL; - - /* open four pairs of fds */ - fd_in[0]= open("/u/test/cdrskin/in_1",O_RDONLY); - fd_in[1]= open("/u/test/cdrskin/in_2",O_RDONLY); - fd_out[2]= open("/u/test/cdrskin/out_1", - O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); - fd_out[3]= open("/u/test/cdrskin/out_2", - O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); - if(pipe(pipe_fds[0])==-1) - return(-3); - if(pipe(pipe_fds[1])==-1) - return(-3); - fd_out[0]= pipe_fds[0][1]; - fd_out[1]= pipe_fds[1][1]; - fd_in[2]= pipe_fds[0][0]; - fd_in[3]= pipe_fds[1][0]; - for(i=0;i<4;i++) { - if(fd_in[i]==-1) - return(-1); - if(fd_out[i]==-1) - return(-2); - } - - /* Create two fifos with two sequential fd pairs each and chain them for - simultaneous usage. */ - Cdrfifo_new(&ff1,fd_in[0],fd_out[0],2048,fs_size,0); - Cdrfifo_new(&ff2,fd_in[2],fd_out[2],2048,2*1024*1024,0); /*burner cache 2 MB*/ - if(ff1==NULL || ff2==NULL) - return(-3); - Cdrfifo_set_speed_limit(ff2,speed_limit,0); - ret= Cdrfifo_attach_follow_up_fds(ff1,fd_in[1],fd_out[1],0); - if(ret<=0) - return(-4); - ret= Cdrfifo_attach_follow_up_fds(ff2,fd_in[3],fd_out[3],0); - if(ret<=0) - return(-4); - Cdrfifo_attach_peer(ff1,ff2,0); - - /* Let the fifos work */ - iv= interval*1e6; - while(1) { - ret= Cdrfifo_try_to_work(ff1,iv,NULL,NULL,flag&1); - if(ret<0 || ret==2) { /* <0 = error , 2 = work is done */ - fprintf(stderr,"\ncdrfifo: fifo ended work with ret=%d\n",ret); - if(ret<0) - return(-7); - break; - } - } - return(1); -} - - -int main(int argc, char **argv) -{ - int i,ret,exit_value= 0,verbous= 1,fill_buffer= 0,min_fill,fifo_percent,fd; - double fs_value= 4.0*1024.0*1024.0,bs_value= 2048,in_counter,out_counter; - double interval= 1.0,speed_limit= 0.0; - char output_file[4096]; - struct CdrfifO *ff= NULL; - - strcpy(output_file,"-"); - fd= 1; - - for(i= 1; i1000.0) - interval= 1; - } else if(strncmp(argv[i],"of=",3)==0) { - if(strcmp(argv[i]+3,"-")==0 || argv[i][3]==0) - continue; - fd= open(argv[i]+3,O_WRONLY|O_CREAT); - if(fd<0) { - fprintf(stderr,"cdrfifo: FATAL : cannot open output file '%s'\n", - argv[i]+3); - fprintf(stderr,"cdrfifo: errno=%d , \"%s\"\n", - errno,errno==0?"-no error code available-":strerror(errno)); - {exit_value= 4; goto ex;} - } - } else if(strncmp(argv[i],"sl=",3)==0) { - speed_limit= Scanf_io_size(argv[i]+3,0); - } else if(strncmp(argv[i],"vb=",3)==0) { - sscanf(argv[i]+3,"%d",&verbous); - - } else if(strcmp(argv[i],"-multi_test")==0) { - - if(speed_limit==0.0) - speed_limit= 10*150*1024; - ret= Test_multi((int) fs_value,speed_limit,interval,(verbous>=2)); - fprintf(stderr,"Test_multi(): ret= %d\n",ret); - exit(ret<0); - - } else { - fprintf(stderr,"cdrfifo 0.3 : stdin-to-stdout fifo buffer.\n"); - fprintf(stderr,"usage : %s [bs=block_size] [fl=fillfirst]\n",argv[0]); - fprintf(stderr," [fs=fifo_size] [iv=interval] [of=output_file]\n"); - fprintf(stderr," [sl=bytes_per_second_limit] [vb=verbosity]\n"); - fprintf(stderr,"fl=1 reads full buffer before writing starts.\n"); - fprintf(stderr,"sl>0 allows catch up for whole run time.\n"); - fprintf(stderr,"sl<0 allows catch up for single interval.\n"); - fprintf(stderr,"vb=0 is silent, vb=2 is debug.\n"); - fprintf(stderr,"example: cdrfifo bs=8k fl=1 fs=32m iv=0.1 sl=-5400k\n"); - if(strcmp(argv[i],"-help")!=0 && strcmp(argv[i],"--help")!=0) { - fprintf(stderr,"\ncdrfifo: FATAL : option not recognized: '%s'\n", - argv[i]); - exit_value= 1; - } - goto ex; - } - } - if(verbous>=1) { - fprintf(stderr, - "cdrfifo: bs=%.lf fl=%d fs=%.lf iv=%lf of='%s' sl=%.lf vb=%d\n", - bs_value,fill_buffer,fs_value,interval,output_file,speed_limit, - verbous); - } - - ret= Cdrfifo_new(&ff,0,fd,(int) bs_value,(int) fs_value,0); - if(ret<=0) { - fprintf(stderr, - "cdrfifo: FATAL : creation of fifo object with %.lf bytes failed\n", - fs_value); - {exit_value= 3; goto ex;} - } - if(speed_limit!=0.0) - Cdrfifo_set_speed_limit(ff,speed_limit,0); - if(fill_buffer) { - ret= Cdrfifo_fill(ff,0); - if(ret<=0) { - fprintf(stderr, - "cdrfifo: FATAL : initial filling of fifo buffer failed\n"); - {exit_value= 4; goto ex;} - } - } - while(1) { - ret= Cdrfifo_try_to_work(ff,(int) (interval*1000000.0), - NULL,NULL,(verbous>=2)); - if(ret<0) { - fprintf(stderr,"\ncdrfifo: FATAL : fifo aborted. errno=%d , \"%s\"\n", - errno,errno==0?"-no error code available-":strerror(errno)); - {exit_value= 4; goto ex;} - } else if(ret==2) { - if(verbous>=1) { - double put_counter,get_counter,empty_counter,full_counter; - int total_min_fill; - Cdrfifo_get_counters(ff,&in_counter,&out_counter,0); - fprintf(stderr,"\ncdrfifo: done : %.lf bytes in , %.lf bytes out\n", - in_counter,out_counter); - Cdrfifo_get_min_fill(ff,&total_min_fill,&min_fill,0); - fifo_percent= 100.0*((double) total_min_fill)/fs_value; - if(fifo_percent==0 && total_min_fill>0) - fifo_percent= 1; - Cdrfifo_get_cdr_counters(ff,&put_counter,&get_counter, - &empty_counter,&full_counter,0); - fprintf(stderr,"cdrfifo: fifo had %.lf puts and %.lf gets.\n", - put_counter,get_counter); - fprintf(stderr, -"cdrfifo: fifo was %.lf times empty and %.lf times full, min fill was %d%%.\n", - empty_counter,full_counter,fifo_percent); - } - break; - } - Cdrfifo_next_interval(ff,&min_fill,0); - } - -ex:; - Cdrfifo_destroy(&ff,0); - exit(exit_value); -} - - -#endif /* Cdrfifo_standalonE */ - diff --git a/cdrskin/cdrfifo.h b/cdrskin/cdrfifo.h deleted file mode 100644 index 17d0b0c..0000000 --- a/cdrskin/cdrfifo.h +++ /dev/null @@ -1,155 +0,0 @@ - -/* - cdrfifo.c , Copyright 2006 Thomas Schmitt - - A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently. - By chaining of fifo objects, several fifos can be run simultaneously - in fd-to-fd mode. Modes are controlled by parameter flag of - Cdrfifo_try_to_work(). - - Provided under GPL license within cdrskin and under BSD license elsewise. -*/ - -#ifndef Cdrfifo_headerfile_includeD -#define Cdrfifo_headerfile_includeD - - -/** The fifo buffer which will smoothen the data stream from data provider - to data consumer. Although this is not a mandatory lifesaver for modern - burners any more, a fifo can speed up burning of data which is delivered - with varying bandwidths (e.g. compressed archives created on the fly - or mkisofs running at its speed limit.). - This structure is opaque to applications and may only be used via - the Cdrfifo*() methods described in cdrfifo.h . -*/ -struct CdrfifO; - - -/** Create a fifo object. - @param ff Returns the address of the new object. - @param source_fd Filedescriptor opened to a readable data stream. - @param dest_fd Filedescriptor opened to a writable data stream. - To work with libburn, it needs to be attached to a - struct burn_source object. - @param chunk_size Size of buffer block for a single transaction (0=default) - @param buffer_size Size of fifo buffer - @param flag unused yet - @return 1 on success, <=0 on failure -*/ -int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd, - int chunk_size, int buffer_size, int flag); - -/** Release from memory a fifo object previously created by Cdrfifo_new(). - @param ff The victim (gets returned as NULL, call can stand *ff==NULL) - @param flag Bitfield for control purposes: - bit0= do not close destination fd -*/ -int Cdrfifo_destroy(struct CdrfifO **ff, int flag); - -/** Close any output fds */ -int Cdrfifo_close(struct CdrfifO *o, int flag); - -/** Close any output fds of o and its chain peers */ -int Cdrfifo_close_all(struct CdrfifO *o, int flag); - -int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size, - int flag); - -/** Set a speed limit for buffer output. - @param o The fifo object - @param bytes_per_second >0 catch up slowdowns over the whole run time - <0 catch up slowdowns only over one interval - =0 disable speed limit -*/ -int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second, - int flag); - -/** Set a fixed size for input in order to cut off any unwanted tail - @param o The fifo object - @param idx index for fds attached via Cdrfifo_attach_follow_up_fds(), - first attached is 0, <0 directs limit to active fd limit - (i.e. first track is -1, second track is 0, third is 1, ...) -*/ -int Cdrfifo_set_fd_in_limit(struct CdrfifO *o, double fd_in_limit, int idx, - int flag); - - -int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag); -int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag); - - -/** Attach a further pair of input and output fd which will use the same - fifo buffer when its predecessors are exhausted. Reading will start as - soon as reading of the predecessor encounters EOF. Writing will start - as soon as all pending predecessor data are written. - @return index number of new item + 1, <=0 indicates error -*/ -int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd, - int flag); - -/** Attach a further fifo which shall be processed simultaneously with this - one by Cdrfifo_try_to_work() in fd-to-fd mode. -*/ -int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag); - - -/** Obtain buffer state. - @param o The buffer object - @param fill Returns the number of pending payload bytes in the buffer - @param space Returns the number of unused buffer bytes - @param flag unused yet - @return -1=error , 0=inactive , 1=reading and writing , - 2=reading ended (but still writing) -*/ -int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag); - -int Cdrfifo_get_counters(struct CdrfifO *o, - double *in_counter, double *out_counter, int flag); - -/** reads min_fill and begins measurement interval for next min_fill */ -int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag); - -int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill, - int *interval_min_fill, int flag); - -int Cdrfifo_get_cdr_counters(struct CdrfifO *o, - double *put_counter, double *get_counter, - double *empty_counter, double *full_counter, - int flag); - - -/** Check for pending data at the fifo's source file descriptor and wether the - fifo is ready to take them. Simultaneously check the buffer for existing - data and the destination fd for readiness to accept some. If so, a small - chunk of data is transfered to and/or from the fifo. - This is done for the given fifo object and all members of its next-chain. - The check and transactions are repeated until a given timespan has elapsed. - libburn applications call this function in the burn loop instead of sleep(). - It may also be used instead of read(). Then it returns as soon as an output - transaction would be performed. See flag:bit2. - @param o The fifo object - @param wait_usec The time in microseconds after which the function shall - return. - @param reply_buffer with bit2: Returns write-ready buffer chunk and must - be able to take at least chunk_size bytes - @param reply_count with bit2: Returns number of writeable bytes in reply_pt - @param flag Bitfield for control purposes: - bit0= Enable debug pacifier (same with Cdrfifo_debuG) - bit1= Do not write, just fill buffer - bit2= fd-to-memory mode (else fd-to-fd mode): - Rather than writing a chunk return it and its size. - No simultaneous processing of chained fifos. - bit3= With bit2: do not check destination fd for readiness - @return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done -*/ -int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec, - char *reply_buffer, int *reply_count, int flag); - -/** Fill the fifo as far as possible without writing to destination fd - @return 1 on success, <=0 on failure -*/ -int Cdrfifo_fill(struct CdrfifO *o, int flag); - - -#endif /* Cdrfifo_headerfile_includeD */ - diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c deleted file mode 100644 index d0927a7..0000000 --- a/cdrskin/cdrskin.c +++ /dev/null @@ -1,5580 +0,0 @@ - -/* - cdrskin.c , Copyright 2006 Thomas Schmitt -Provided under GPL. See future commitment below. - -A cdrecord compatible command line interface for libburn. - -This project is neither directed against original cdrecord nor does it exploit -any source code of said program. It rather tries to be an alternative method -to burn CD which is not based on the same code as cdrecord. -See also : http://scdbackup.sourceforge.net/cdrskin_eng.html - -Interested users of cdrecord are encouraged to contribute further option -implementations as they need them. Contributions will get published under GPL -but it is essential that the authors allow a future release under LGPL and/or -BSD license. - -There is a script test/cdrecord_spy.sh which may be installed between -the cdrecord command and real cdrecord in order to learn about the options -used by your favorite cdrecord frontend. Edit said script and install it -according to the instructions given inside. - -The implementation of an option would probably consist of -- necessary structure members for structs CdrpreskiN and/or CdrskiN -- code in Cdrpreskin_setup() and Cdrskin_setup() which converts - argv[i] into CdrpreskiN/CdrskiN members (or into direct actions) -- removal of option from ignore list "ignored_partial_options" resp. - "ignored_full_options" in Cdrskin_setup() -- functions which implement the option's run time functionality -- eventually calls of those functions in Cdrskin_run() -- changes to be made within Cdrskin_burn() or Cdrskin_blank() or other - existing methods -See option blank= for an example. - ------------------------------------------------------------------------------- -About compliance with *strong urge* of API towards burn_drive_scan_and_grab() - -For a more comprehensive example of the advised way to behave with libburn -see test/libburner.c . - -cdrskin was the initiator of the whitelist functionality within libburn. -Now it has problems to obviously comply with the new API best practice -presciptions literally. Therefore this explanation: - -On start it restricts the library to a single drive if it already knows the -persistent address by option dev= . This is done with a combination of -burn_drive_add_whitelist() and burn_drive_scan(). Not compliant to the -literal strong urge but in fact exactly fulfilling the reason for that -urge in the API: any scanned drive might be opened exclusively after -burn_drive_scan(). It is kernel dependent wether this behavior is on, off -or switchable. The sysdamin will want it on - but only for one drive. - -So with dev=... cdrskin complies to the spirit of the strong urge. -Without dev=... it has to leave out the whitelist in order to enable bus -scanning and implicit drive address 0. A tradition of 9 months shall not -be broken. So burns without dev= will stay possible - but harmless only -on single drive systems. - -Burns without dev= resp. with dev=number are harmless on multi-drive systems. - -This is because Cdrskin_grab_drive() either drops the unwanted drives or -it enforces a restart of the library with the desired drive's persistent -address. This restart then really uses the strongly urged function -burn_drive_scan_and_grab(). -Thus, cdrskin complies with the new spirit of API by closing down libburn -or by dropping unused drives as soon as the persistent drive address is -known and the drive is to be used with a long running operation. To my -knowlege all long running operations in cdrskin need a grabbed drive. - -This spaghetti approach seems necessary to keep small the impact of new API -urge on cdrskin's stability. cdrskin suffers from having donated the body -parts which have been transplanted to libburn in order to create - burn_drive_scan_and_grab() . The desired sysadmin friendlyness was already -achieved by most cdrskin runs. The remaining problem situations should now -be defused by releasing any short time grabbed flocks of drives during the -restart of libburn. - ------------------------------------------------------------------------------- -This program is currently copyright Thomas Schmitt only. -The copyrights of several components of libburn.pykix.org are willfully tangled -at toplevel to form an irrevocable commitment to true open source spirit. -We have chosen the GPL for legal compatibility and clearly express that it -shall not hamper the use of our software by non-GPL applications which show -otherwise the due respect to the open source community. -See toplevel README and cdrskin/README for that commitment. - -For a short time, this place showed a promise to release a BSD license on -mere request. I have to retract that promise now, and replace it by the -promise to make above commitment reality in a way that any BSD conformant -usage in due open source spirit will be made possible somehow and in the -particular special case. I will not raise public protest if you spawn yourself -a BSD license from an (outdated) cdrskin.c which still bears that old promise. -Note that this extended commitment is valid only for cdrskin.[ch], -cdrfifo.[ch] and cleanup.[ch], but not for libburn.pykix.org as a whole. - -cdrskin is originally inspired by libburn-0.2/test/burniso.c : -(c) Derek Foreman and Ben Jansens - ------------------------------------------------------------------------------- - -Compilation within cdrskin-* : - - cd cdrskin - cc -g -I.. -DCdrskin_build_timestamP='...' \ - -o cdrskin cdrskin.c cdrfifo.c cleanup.c \ - -L../libburn/.libs -lburn -lpthread - -or - - cd .. - cc -g -I. -DCdrskin_build_timestamP='...' \ - -o cdrskin/cdrskin cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cleanup.c \ - libburn/async.o libburn/crc.o libburn/debug.o libburn/drive.o \ - libburn/file.o libburn/init.o libburn/lec.o \ - libburn/mmc.o libburn/options.o libburn/sbc.o libburn/sector.o \ - libburn/sg.o libburn/spc.o libburn/source.o libburn/structure.o \ - libburn/toc.o libburn/util.o libburn/write.o \ - libburn/libdax_audioxtr.o libburn/libdax_msgs.o \ - -lpthread - -*/ - - -/** The official program version */ -#ifndef Cdrskin_prog_versioN -#define Cdrskin_prog_versioN "0.2.5" -#endif - -/** The source code release timestamp */ -#include "cdrskin_timestamp.h" -#ifndef Cdrskin_timestamP -#define Cdrskin_timestamP "-none-given-" -#endif - -/** The binary build timestamp is to be set externally by the compiler */ -#ifndef Cdrskin_build_timestamP -#define Cdrskin_build_timestamP "-none-given-" -#endif - - -#ifdef Cdrskin_libburn_versioN -#undef Cdrskin_libburn_versioN -#endif - -/** use this to accomodate to the CVS version as of Feb 20, 2006 -#define Cdrskin_libburn_cvs_A60220_tS 1 -*/ -#ifdef Cdrskin_libburn_cvs_A60220_tS - -#define Cdrskin_libburn_versioN "0.2.tsA60220" -#define Cdrskin_libburn_no_burn_preset_device_opeN 1 -#ifndef Cdrskin_oldfashioned_api_usE -#define Cdrskin_oldfashioned_api_usE 1 -#endif - -#endif /* Cdrskin_libburn_cvs_A60220_tS */ - - -#ifdef Cdrskin_libburn_0_2_2 -#define Cdrskin_libburn_versioN "0.2.2" -#define Cdrskin_libburn_from_pykix_svN 1 -#endif - -#ifdef Cdrskin_libburn_0_2_3 -#define Cdrskin_libburn_versioN "0.2.3" -#define Cdrskin_libburn_from_pykix_svN 1 -#define Cdrskin_libburn_has_is_enumerablE 1 -#define Cdrskin_libburn_has_convert_fs_adR 1 -#define Cdrskin_libburn_has_convert_scsi_adR 1 -#define Cdrskin_libburn_has_burn_msgS 1 -#define Cdrskin_libburn_has_burn_aborT 1 -#define Cdrskin_libburn_has_cleanup_handleR 1 -#define Cdrskin_libburn_has_audioxtR 1 -#define Cdrskin_libburn_has_get_start_end_lbA 1 -#define Cdrskin_libburn_has_burn_disc_unsuitablE 1 -#define Cdrskin_libburn_has_read_atiP 1 -#define Cdrskin_libburn_has_buffer_progresS 1 -#define Cdrskin_libburn_has_pretend_fulL 1 -#define Cdrskin_libburn_has_multI 1 -#endif - -#ifndef Cdrskin_libburn_versioN -#define Cdrskin_libburn_versioN "0.2.2" -#define Cdrskin_libburn_from_pykix_svN 1 -#endif - -#ifdef Cdrskin_libburn_from_pykix_svN - -#define Cdrskin_libburn_does_ejecT 1 -#define Cdrskin_libburn_has_drive_get_adR 1 -#define Cdrskin_progress_track_does_worK 1 -#define Cdrskin_is_erasable_on_load_does_worK 1 -#define Cdrskin_grab_abort_does_worK 1 -#define Cdrskin_allow_libburn_taO 1 - -#ifdef Cdrskin_new_api_tesT - -/* put macros under test caveat here */ - -/* could be i repaired this with getting -atip minimum speed */ -#ifdef Cdrskin_libburn_has_read_atiP -#define Cdrskin_atip_speed_is_oK 1 -#endif - -#endif - -#ifdef Cdrskin_oldfashioned_api_usE - -/* switch back to pre-0.2.2 libburn usage */; - -#endif - -#endif /* Cdrskin_libburn_from_pykix_svN */ - - -/* These macros activate cdrskin workarounds for deficiencies resp. - problematic features of libburn which hopefully will change in - future. */ - -/** Work around the fact that neither /dev/sg0 (kernel 2.4 + ide-scsi) nor - /dev/hdc (kernel 2.6) get ejected by icculus.org/burn */ -#ifndef Cdrskin_libburn_does_ejecT -#define Cdrskin_burn_drive_eject_brokeN 1 -#endif - -/** Work around the fact that after loading media speed report is wrong */ -#ifndef Cdrskin_atip_speed_is_oK -#define Cdrskin_atip_speed_brokeN 1 -#endif - -/** Work around the fact that burn_drive_get_status() always reports to do - track 0 in icculus.org/burn */ -#ifndef Cdrskin_progress_track_does_worK -#define Cdrskin_progress_track_brokeN 1 -#endif - -/** Work around the fact that a drive interrupted at burn_drive_grab() never - leaves status BURN_DRIVE_GRABBING in icculus.org/burn */ -#ifndef Cdrskin_grab_abort_does_worK -#define Cdrskin_grab_abort_brokeN 1 -#endif - -/** Work around the fact that a freshly loaded tray with media reports - arbitrary media erasability in icculuc.org/burn */ -#ifndef Cdrskin_is_erasable_on_load_does_worK -#define Cdrskin_is_erasable_on_load_is_brokeN 1 -#endif - -/** http://libburn.pykix.org/ticket/41 reports of big trouble without - padding any track to a full sector -*/ -#define Cdrskin_all_tracks_with_sector_paD 1 - - -/** A macro which is able to eat up a function call like printf() */ -#ifdef Cdrskin_extra_leaN -#define ClN(x) -#else -#define ClN(x) x -#endif - - -/** Verbosity level for pacifying progress messages */ -#define Cdrskin_verbose_progresS 1 - -/** Verbosity level for command recognition and execution logging */ -#define Cdrskin_verbose_cmD 2 - -/** Verbosity level for reporting of debugging messages */ -#define Cdrskin_verbose_debuG 3 - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../libburn/libburn.h" - -#ifdef Cdrskin_libburn_has_audioxtR -#include "../libburn/libdax_audioxtr.h" -#endif - -#ifdef Cdrskin_libburn_has_cleanup_handleR -#define Cleanup_set_handlers burn_set_signal_handling -#define Cleanup_app_handler_T burn_abort_handler_t -#else -#include "cleanup.h" -#endif - - -/** The size of a string buffer for pathnames and similar texts */ -#define Cdrskin_strleN 4096 - -/** The maximum length +1 of a drive address */ -#ifndef Cdrskin_oldfashioned_api_usE -#define Cdrskin_adrleN BURN_DRIVE_ADR_LEN -#else -#define Cdrskin_adrleN 80 -#endif - - -/* --------------------------------------------------------------------- */ - -/* Imported from scdbackup-0.8.5/src/cd_backup_planer.c */ - -/** Macro for creation of arrays of objects (or single objects) */ -#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ)); - - -/** Convert a text so that eventual characters special to the shell are - made literal. Note: this does not make a text terminal-safe ! - @param in_text The text to be converted - @param out_text The buffer for the result. - It should have size >= strlen(in_text)*5+2 - @param flag Unused yet - @return For convenience out_text is returned -*/ -char *Text_shellsafe(char *in_text, char *out_text, int flag) -{ - int l,i,w=0; - - /* enclose everything by hard quotes */ - l= strlen(in_text); - out_text[w++]= '\''; - for(i=0;i0) if(line[l-1]=='\r') line[--l]= 0; - if(l>0) if(line[l-1]=='\n') line[--l]= 0; - if(l>0) if(line[l-1]=='\r') line[--l]= 0; - return(ret); -} - - -/** Destroy a synthetic argument array */ -int Sfile_destroy_argv(int *argc, char ***argv, int flag) -{ - int i; - - if(*argc>0 && *argv!=NULL){ - for(i=0;i<*argc;i++){ - if((*argv)[i]!=NULL) - free((*argv)[i]); - } - free((char *) *argv); - } - *argc= 0; - *argv= NULL; - return(1); -} - - -/** Read a synthetic argument array from a list of files. - @param progname The content for argv[0] - @param filenames The paths of the filex from where to read - @param filenamecount The number of paths in filenames - @param argc Returns the number of read arguments (+1 for progname) - @param argv Returns the array of synthetic arguments - @param argidx Returns source file indice of argv[] items - @param arglno Returns source file line numbers of argv[] items - @param flag Bitfield for control purposes: - bit0= read progname as first argument from line - bit1= just release argument array argv and return - bit2= tolerate failure to open file - @return 1=ok , 0=cannot open file , -1=cannot create memory objects -*/ -int Sfile_multi_read_argv(char *progname, char **filenames, int filename_count, - int *argc, char ***argv, int **argidx, int **arglno, - int flag) -{ - int ret,i,pass,maxl=0,l,argcount=0,line_no; - char buf[Cdrskin_strleN]; - FILE *fp= NULL; - - Sfile_destroy_argv(argc,argv,0); - if(flag&2) - return(1); - if((*argidx)!=NULL) - free((char *) *argidx); - if((*arglno)!=NULL) - free((char *) *arglno); - *argidx= *arglno= NULL; - - for(pass=0;pass<2;pass++) { - if(!(flag&1)){ - argcount= 1; - if(pass==0) - maxl= strlen(progname)+1; - else { - (*argv)[0]= (char *) malloc(strlen(progname)+1); - if((*argv)[0]==NULL) - {ret= -1; goto ex;} - strcpy((*argv)[0],progname); - } - } else { - argcount= 0; - if(pass==0) - maxl= 1; - } - for(i=0; i0) - fprintf(stderr,"cdrskin: DEBUG : Reading arguments from file '%s'\n", - filenames[i]); -#endif - - line_no= 0; - while(Sfile_fgets(buf,sizeof(buf)-1,fp)!=NULL) { - line_no++; - l= strlen(buf); - if(l==0 || buf[0]=='#') - continue; - if(pass==0){ - if(l>maxl) - maxl= l; - } else { - if(argcount >= *argc) - break; - (*argv)[argcount]= (char *) malloc(l+1); - if((*argv)[argcount]==NULL) - {ret= -1; goto ex;} - strcpy((*argv)[argcount],buf); - (*argidx)[argcount]= i; - (*arglno)[argcount]= line_no; - } - argcount++; - } - fclose(fp); fp= NULL; - } - if(pass==0){ - *argc= argcount; - if(argcount>0) { - *argv= (char **) malloc(argcount*sizeof(char *)); - *argidx= (int *) malloc(argcount*sizeof(int)); - *arglno= (int *) malloc(argcount*sizeof(int)); - if(*argv==NULL || *argidx==NULL || *arglno==NULL) - {ret= -1; goto ex;} - } - for(i=0;i<*argc;i++) { - (*argv)[i]= NULL; - (*argidx)[i]= -1; - (*arglno)[i]= -1; - } - } - } - - ret= 1; -ex:; - if(fp!=NULL) - fclose(fp); - return(ret); -} - - -/** Combine environment variable HOME with given filename - @param filename Address relative to $HOME - @param fileadr Resulting combined address - @param fa_size Size of array fileadr - @param flag Unused yet - @return 1=ok , 0=no HOME variable , -1=result address too long -*/ -int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag) -{ - char *home; - - strcpy(fileadr,filename); - home= getenv("HOME"); - if(home==NULL) - return(0); - if(strlen(home)+strlen(filename)+1>=fa_size) - return(-1); - strcpy(fileadr,home); - if(filename[0]!=0){ - strcat(fileadr,"/"); - strcat(fileadr,filename); - } - return(1); -} - - -#endif /* ! Cdrskin_extra_leaN */ - - -/* --------------------------------------------------------------------- */ - -/** Address translation table for users/applications which do not look - for the output of -scanbus but guess a Bus,Target,Lun on their own. -*/ - -/** The maximum number of entries in the address translation table */ -#define Cdradrtrn_leN 256 - -/** The address prefix which will prevent translation */ -#define Cdrskin_no_transl_prefiX "LITERAL_ADR:" - - -struct CdradrtrN { - char *from_address[Cdradrtrn_leN]; - char *to_address[Cdradrtrn_leN]; - int fill_counter; -}; - - -#ifndef Cdrskin_extra_leaN - -/** Create a device address translator object */ -int Cdradrtrn_new(struct CdradrtrN **trn, int flag) -{ - struct CdradrtrN *o; - int i; - - (*trn)= o= TSOB_FELD(struct CdradrtrN,1); - if(o==NULL) - return(-1); - for(i= 0;ifrom_address[i]= NULL; - o->to_address[i]= NULL; - } - o->fill_counter= 0; - return(1); -} - - -/** Release from memory a device address translator object */ -int Cdradrtrn_destroy(struct CdradrtrN **o, int flag) -{ - int i; - struct CdradrtrN *trn; - - trn= *o; - if(trn==NULL) - return(0); - for(i= 0;ifill_counter;i++) { - if(trn->from_address[i]!=NULL) - free(trn->from_address[i]); - if(trn->to_address[i]!=NULL) - free(trn->to_address[i]); - } - free((char *) trn); - *o= NULL; - return(1); -} - - -/** Add a translation pair to the table - @param trn The translator which shall learn - @param from The user side address - @param to The cdrskin side address - @param flag Bitfield for control purposes: - bit0= "from" contains from+to address, to[0] contains delimiter -*/ -int Cdradrtrn_add(struct CdradrtrN *trn, char *from, char *to, int flag) -{ - char buf[2*Cdrskin_adrleN+1],*from_pt,*to_pt; - int cnt; - - cnt= trn->fill_counter; - if(cnt>=Cdradrtrn_leN) - return(-1); - if(flag&1) { - if(strlen(from)>=sizeof(buf)) - return(0); - strcpy(buf,from); - to_pt= strchr(buf,to[0]); - if(to_pt==NULL) - return(0); - *(to_pt)= 0; - from_pt= buf; - to_pt++; - } else { - from_pt= from; - to_pt= to; - } - if(strlen(from)>=Cdrskin_adrleN || strlen(to)>=Cdrskin_adrleN) - return(0); - trn->from_address[cnt]= malloc(strlen(from_pt)+1); - trn->to_address[cnt]= malloc(strlen(to_pt)+1); - if(trn->from_address[cnt]==NULL || - trn->to_address[cnt]==NULL) - return(-2); - strcpy(trn->from_address[cnt],from_pt); - strcpy(trn->to_address[cnt],to_pt); - trn->fill_counter++; - return(1); -} - - -/** Apply eventual device address translation - @param trn The translator - @param from The address from which to translate - @param driveno With backward translation only: The libburn drive number - @param to The result of the translation - @param flag Bitfield for control purposes: - bit0= translate backward - @return <=0 error, 1=no translation found, 2=translation found, - 3=collision avoided -*/ -int Cdradrtrn_translate(struct CdradrtrN *trn, char *from, int driveno, - char to[Cdrskin_adrleN], int flag) -{ - int i,ret= 1; - char *adr; - - to[0]= 0; - adr= from; - if(flag&1) - goto backward; - - if(strncmp(adr,Cdrskin_no_transl_prefiX, - strlen(Cdrskin_no_transl_prefiX))==0) { - adr= adr+strlen(Cdrskin_no_transl_prefiX); - ret= 2; - } else { - for(i=0;ifill_counter;i++) - if(strcmp(adr,trn->from_address[i])==0) - break; - if(ifill_counter) { - adr= trn->to_address[i]; - ret= 2; - } - } - if(strlen(adr)>=Cdrskin_adrleN) - return(-1); - strcpy(to,adr); - return(ret); - -backward:; - if(strlen(from)>=Cdrskin_adrleN) - sprintf(to,"%s%d",Cdrskin_no_transl_prefiX,driveno); - else - strcpy(to,from); - for(i=0;ifill_counter;i++) - if(strcmp(from,trn->to_address[i])==0 && - strlen(trn->from_address[i])fill_counter) { - ret= 2; - strcpy(to,trn->from_address[i]); - } else { - for(i=0;ifill_counter;i++) - if(strcmp(from,trn->from_address[i])==0) - break; - if(ifill_counter) - if(strlen(from)+strlen(Cdrskin_no_transl_prefiX)boss= boss; - o->trackno= trackno; - o->source_path[0]= 0; - o->source_fd= -1; - o->is_from_stdin= !!(flag&2); - o->fixed_size= 0.0; - o->padding= 0.0; - o->set_by_padsize= 0; - o->sector_pad_up= Cdrskin_all_tracks_with_sector_paD; - o->track_type= BURN_MODE1; - o->sector_size= 2048.0; - o->track_type_by_default= 1; - o->swap_audio_bytes= 0; - o->extracting_container= 0; - o->fifo_enabled= 0; - o->fifo= NULL; - o->fifo_outlet_fd= -1; - o->fifo_size= 0; - o->fifo_start_empty= 0; - o->ff_fifo= NULL; - o->ff_idx= -1; - o->libburn_track= NULL; - ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size),&(o->padding), - &(o->set_by_padsize),&(skin_track_type), - &(o->track_type_by_default),&(o->swap_audio_bytes), - 0); - if(ret<=0) - goto failed; - Cdrtrack_set_track_type(o,skin_track_type,0); - -#ifndef Cdrskin_extra_leaN - ret= Cdrskin_get_fifo_par(boss, &(o->fifo_enabled),&(o->fifo_size), - &(o->fifo_start_empty),0); - if(ret<=0) - goto failed; -#endif /* ! Cdrskin_extra_leaN */ - - if(flag&1) - o->fifo_start_empty= 1; - return(1); -failed:; - Cdrtrack_destroy(track,0); - return(-1); -} - - -/** Release from memory a track object previously created by Cdrtrack_new() */ -int Cdrtrack_destroy(struct CdrtracK **o, int flag) -{ - struct CdrtracK *track; - - track= *o; - if(track==NULL) - return(0); - -#ifndef Cdrskin_extra_leaN - Cdrfifo_destroy(&(track->fifo),0); -#endif - - if(track->libburn_track!=NULL) - burn_track_free(track->libburn_track); - free((char *) track); - *o= NULL; - return(1); -} - - -int Cdrtrack_set_track_type(struct CdrtracK *o, int track_type, int flag) -{ - if(track_type==BURN_AUDIO) { - o->track_type= BURN_AUDIO; - o->sector_size= 2352.0; - } else { - o->track_type= BURN_MODE1; - o->sector_size= 2048.0; - } - return(1); -} - - -/** - @param flag Bitfield for control purposes: - bit0= size returns number of actually processed source bytes - rather than the predicted fixed_size (if available). - padding returns the difference from number of written - bytes. -*/ -int Cdrtrack_get_size(struct CdrtracK *track, double *size, double *padding, - double *sector_size, int flag) -{ - - *size= track->fixed_size; - *padding= track->padding; -#ifdef Cdrskin_allow_libburn_taO - if((flag&1) && track->libburn_track!=NULL) { - off_t readcounter= 0,writecounter= 0; - - burn_track_get_counters(track->libburn_track,&readcounter,&writecounter); - *size= readcounter; - *padding= writecounter-readcounter; -/* - fprintf(stderr,"cdrskin_debug: sizeof(off_t)=%d\n", - sizeof(off_t)); -*/ - } - -#endif - *sector_size= track->sector_size; - return(1); -} - - -int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag) -{ - *fifo= track->fifo; - return(1); -} - - -/** Try wether automatic audio extraction is appropriate and eventually open - a file descriptor to the raw data. - @return -3 identified as .wav but with cdrecord-inappropriate parameters - -2 could not open track source, no use in retrying - -1 severe error - 0 not appropriate to extract, burn plain file content - 1 to be extracted, *fd is a filedescriptor delivering raw data -*/ -int Cdrtrack_extract_audio(struct CdrtracK *track, int *fd, off_t *xtr_size, - int flag) -{ - int l, ok= 0; -#ifdef Cdrskin_libburn_has_audioxtR - struct libdax_audioxtr *xtr= NULL; - char *fmt,*fmt_info; - int num_channels,sample_rate,bits_per_sample,msb_first,ret; -#endif - - *fd= -1; - - if(track->track_type!=BURN_AUDIO && !track->track_type_by_default) - return(0); - l= strlen(track->source_path); - if(l>=4) - if(strcmp(track->source_path+l-4,".wav")==0) - ok= 1; - if(l>=3) - if(strcmp(track->source_path+l-3,".au")==0) - ok= 1; - if(!ok) - return(0); - - if(track->track_type_by_default) { - Cdrtrack_set_track_type(track,BURN_AUDIO,0); - track->track_type_by_default= 2; - fprintf(stderr,"cdrskin: NOTE : Activated -audio for '%s'\n", - track->source_path); - } - -#ifdef Cdrskin_libburn_has_audioxtR - - ret= libdax_audioxtr_new(&xtr,track->source_path,0); - if(ret<=0) - return(ret); - libdax_audioxtr_get_id(xtr,&fmt,&fmt_info, - &num_channels,&sample_rate,&bits_per_sample,&msb_first,0); - if((strcmp(fmt,".wav")!=0 && strcmp(fmt,".au")!=0) || - num_channels!=2 || sample_rate!=44100 || bits_per_sample!=16) { - fprintf(stderr,"cdrskin: ( %s )\n",fmt_info); - fprintf(stderr,"cdrskin: FATAL : Inappropriate audio coding in '%s'.\n", - track->source_path); - {ret= -3; goto ex;} - } - libdax_audioxtr_get_size(xtr,xtr_size,0); - ret= libdax_audioxtr_detach_fd(xtr,fd,0); - if(ret<=0) - {ret= -1*!!ret; goto ex;} - track->swap_audio_bytes= !!msb_first; - track->extracting_container= 1; - fprintf(stderr,"cdrskin: NOTE : %.f %saudio bytes in '%s'\n", - (double) *xtr_size, (msb_first ? "" : "(-swab) "), - track->source_path); - ret= 1; -ex: - libdax_audioxtr_destroy(&xtr,0); - return(ret); - -#else /* Cdrskin_libburn_has_audioxtR */ - - return(0); - -#endif -} - - -/** Deliver an open file descriptor corresponding to the source path of track. - @return <=0 error, 1 success -*/ -int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag) -{ - int is_wav= 0, size_from_file= 0; - off_t xtr_size= 0; - struct stat stbuf; - - if(track->source_path[0]=='-' && track->source_path[1]==0) - *fd= 0; - else if(track->source_path[0]=='#' && - (track->source_path[1]>='0' && track->source_path[1]<='9')) - *fd= atoi(track->source_path+1); - else { - *fd= -1; - is_wav= Cdrtrack_extract_audio(track,fd,&xtr_size,0); - if(is_wav==-1) - return(-1); - if(is_wav==-3) - return(0); - if(is_wav==0) - *fd= open(track->source_path,O_RDONLY); - if(*fd==-1) { - fprintf(stderr,"cdrskin: failed to open source address '%s'\n", - track->source_path); - fprintf(stderr,"cdrskin: errno=%d , \"%s\"\n",errno, - errno==0?"-no error code available-":strerror(errno)); - return(0); - } - if(track->fixed_size<=0) { - if(xtr_size>0) { - track->fixed_size= xtr_size; - size_from_file= 1; - } else { - if(fstat(*fd,&stbuf)!=-1) { - if((stbuf.st_mode&S_IFMT)==S_IFREG) { - track->fixed_size= stbuf.st_size; - size_from_file= 1; - } /* all other types are assumed of open ended size */ - } - } - } - } - -#ifdef Cdrskin_allow_libburn_taO - - if(track->fixed_size < Cdrtrack_minimum_sizE * track->sector_size - && (track->fixed_size>0 || size_from_file)) { - -#else - - if(track->fixed_size < Cdrtrack_minimum_sizE * track->sector_size) { - -#endif - - if(track->track_type == BURN_AUDIO) { - /* >>> cdrecord: We differ in automatic padding with audio: - Audio tracks must be at least 705600 bytes and a multiple of 2352. - */ - fprintf(stderr, - "cdrskin: FATAL : Audio tracks must be at least %.f bytes\n", - Cdrtrack_minimum_sizE*track->sector_size); - return(0); - } else { - fprintf(stderr, - "cdrskin: NOTE : Enforcing minimum track size of %.f bytes\n", - Cdrtrack_minimum_sizE*track->sector_size); - track->fixed_size= Cdrtrack_minimum_sizE*track->sector_size; - } - } - track->source_fd= *fd; - return(*fd>=0); -} - - -#ifndef Cdrskin_extra_leaN - -/** Install a fifo object between data source and libburn. - Its parameters are known to track. - @param outlet_fd Returns the filedescriptor of the fifo outlet. - @param previous_fifo Object address for chaining or follow-up attachment. - @param flag Bitfield for control purposes: - bit0= Debugging verbosity - bit1= Do not create and attach a new fifo - but attach new follow-up fd pair to previous_fifo - bit2= Do not enforce fixed_size if not container extraction - @return <=0 error, 1 success -*/ -int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd, - struct CdrfifO *previous_fifo, int flag) -{ - struct CdrfifO *ff; - int source_fd,pipe_fds[2],ret; - - *outlet_fd= -1; - if(track->fifo_size<=0) - return(2); - ret= Cdrtrack_open_source_path(track,&source_fd,0); - if(ret<=0) - return(ret); - if(pipe(pipe_fds)==-1) - return(0); - - Cdrfifo_destroy(&(track->fifo),0); - if(flag&2) { - ret= Cdrfifo_attach_follow_up_fds(previous_fifo,source_fd,pipe_fds[1],0); - if(ret<=0) - return(ret); - track->ff_fifo= previous_fifo; - track->ff_idx= ret-1; - } else { - - /* >>> ??? obtain track sector size and use instead of 2048 ? */ - - ret= Cdrfifo_new(&ff,source_fd,pipe_fds[1],2048,track->fifo_size,0); - if(ret<=0) - return(ret); - if(previous_fifo!=NULL) - Cdrfifo_attach_peer(previous_fifo,ff,0); - track->fifo= track->ff_fifo= ff; - track->ff_idx= -1; - } - track->fifo_outlet_fd= pipe_fds[0]; - - if((track->extracting_container || !(flag&4)) && track->fixed_size>0) - Cdrfifo_set_fd_in_limit(track->ff_fifo,track->fixed_size,track->ff_idx,0); - - if(flag&1) - printf( - "cdrskin_debug: track %d fifo replaced source_address '%s' by '#%d'\n", - track->trackno+1,track->source_path,track->fifo_outlet_fd); - sprintf(track->source_path,"#%d",track->fifo_outlet_fd); - track->source_fd= track->fifo_outlet_fd; - *outlet_fd= track->fifo_outlet_fd; - return(1); -} - - -/** Read data into the fifo until either it is full or the data source is - exhausted. - @return <=0 error, 1 success -*/ -int Cdrtrack_fill_fifo(struct CdrtracK *track, int flag) -{ - int ret,buffer_fill,buffer_space; - - if(track->fifo==NULL || track->fifo_start_empty) - return(2); - printf("Waiting for reader process to fill input buffer ... "); - fflush(stdout); - ret= Cdrfifo_fill(track->fifo,0); - if(ret<=0) - return(ret); - -/** Ticket 55: check fifos for input, throw error on 0-bytes from stdin - @return <=0 abort run, 1 go on with burning -*/ - if(track->is_from_stdin) { - ret= Cdrfifo_get_buffer_state(track->fifo,&buffer_fill,&buffer_space,0); - if(ret<0 || buffer_fill<=0) { - fprintf(stderr,"\ncdrskin: FATAL : (First track) fifo did not read a single byte from stdin\n"); - return(0); - } - } - return(1); -} - -#endif /* ! Cdrskin_extra_leaN */ - - -/** Create a corresponding libburn track object and add it to the libburn - session. This may change the trackno index set by Cdrtrack_new(). -*/ -int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno, - struct burn_session *session, int flag) -/* - bit0= debugging verbosity - bit1= apply padding hack (<<< should be unused for now) -*/ -{ - struct burn_track *tr; - struct burn_source *src= NULL; - double padding,lib_padding; - int ret,sector_pad_up; - double fixed_size; - int source_fd; - - track->trackno= trackno; - tr= burn_track_create(); - track->libburn_track= tr; - - /* Note: track->track_type may get set in here */ - if(track->source_fd==-1) { - ret= Cdrtrack_open_source_path(track,&source_fd,0); - if(ret<=0) - goto ex; - } - - padding= 0.0; - sector_pad_up= track->sector_pad_up; - if(track->padding>0) { - if(track->set_by_padsize || track->track_type!=BURN_AUDIO) - padding= track->padding; - else - sector_pad_up= 1; - } - if(flag&2) - lib_padding= 0.0; - else - lib_padding= padding; - if(flag&1) { - if(sector_pad_up) { - ClN(fprintf(stderr,"cdrskin_debug: track %d telling burn_track_define_data() to pad up last sector\n",trackno+1)); - } - if(lib_padding>0 || !sector_pad_up) { - ClN(fprintf(stderr, - "cdrskin_debug: track %d telling burn_track_define_data() to pad %.f bytes\n", - trackno+1,lib_padding)); - } - } - burn_track_define_data(tr,0,(int) lib_padding,sector_pad_up, - track->track_type); - burn_track_set_byte_swap(tr, - (track->track_type==BURN_AUDIO && track->swap_audio_bytes)); - fixed_size= track->fixed_size; - if((flag&2) && track->padding>0) { - if(flag&1) - ClN(fprintf(stderr,"cdrskin_debug: padding hack : %.f + %.f = %.f\n", - track->fixed_size,track->padding, - track->fixed_size+track->padding)); - fixed_size+= track->padding; - } - src= burn_fd_source_new(track->source_fd,-1,(off_t) fixed_size); - - if(src==NULL) { - fprintf(stderr, - "cdrskin: FATAL : Could not create libburn data source object\n"); - {ret= 0; goto ex;} - } - if(burn_track_set_source(tr,src)!=BURN_SOURCE_OK) { - fprintf(stderr,"cdrskin: FATAL : libburn rejects data source object\n"); - {ret= 0; goto ex;} - } - burn_session_add_track(session,tr,BURN_POS_END); - ret= 1; -ex: - if(src!=NULL) - burn_source_free(src); - return(ret); -} - - -/** Release libburn track information after a session is done */ -int Cdrtrack_cleanup(struct CdrtracK *track, int flag) -{ - if(track->libburn_track==NULL) - return(0); - burn_track_free(track->libburn_track); - track->libburn_track= NULL; - return(1); -} - - -int Cdrtrack_ensure_padding(struct CdrtracK *track, int flag) -/* -flag: - bit0= debugging verbosity -*/ -{ - if(track->track_type!=BURN_AUDIO) - return(2); - if(flag&1) - fprintf(stderr,"cdrskin_debug: enforcing -pad on last -audio track\n"); - track->sector_pad_up= 1; - return(1); -} - - -#ifndef Cdrskin_extra_leaN - -/** Try to read bytes from the track's fifo outlet and eventually discard - them. Not to be called unless the track is completely written. -*/ -int Cdrtrack_has_input_left(struct CdrtracK *track, int flag) -{ - struct timeval wt; - fd_set rds,wts,exs; - int ready,ret; - char buf[2]; - - if(track->fifo_outlet_fd<=0) - return(0); - FD_ZERO(&rds); - FD_ZERO(&wts); - FD_ZERO(&exs); - FD_SET(track->fifo_outlet_fd,&rds); - wt.tv_sec= 0; - wt.tv_usec= 0; - ready= select(track->fifo_outlet_fd+1,&rds,&wts,&exs,&wt); - if(ready<=0) - return(0); - ret= read(track->fifo_outlet_fd,buf,1); - if(ret>0) - return(1); - return(0); -} - -#endif /* ! Cdrskin_extra_leaN */ - - -/* --------------------------------------------------------------------- */ - -/** The list of startup file names */ -#define Cdrpreskin_rc_nuM 3 - -static char Cdrpreskin_sys_rc_nameS[Cdrpreskin_rc_nuM][80]= { - "/etc/default/cdrskin", - "/etc/opt/cdrskin/rc", - "placeholder for $HOME/.cdrskinrc" -}; - - -/** A structure which bundles several parameters for creation of the CdrskiN - object. It finally becomes a managed subordinate of the CdrskiN object. -*/ -struct CdrpreskiN { - - /* to be transfered into skin */ - int verbosity; - char queue_severity[81]; - char print_severity[81]; - - /** Stores eventually given absolute device address before translation */ - char raw_device_adr[Cdrskin_adrleN]; - - /** Stores an eventually given translated absolute device address between - Cdrpreskin_setup() and Cdrskin_create() . - */ - char device_adr[Cdrskin_adrleN]; - - /** The eventual address translation table */ - struct CdradrtrN *adr_trn; - - /** Memorizes the abort handling mode from presetup to creation of - control object. Defined handling modes are: - 0= no abort handling - 1= try to cancel, release, exit (leave signal mode as set by caller) - 2= try to ignore all signals - 3= mode 1 in normal operation, mode 2 during abort handling - 4= mode 1 in normal operation, mode 0 during abort handling - -1= install abort handling 1 only in Cdrskin_burn() after burning started - */ - int abort_handler; - - /** Wether to allow getuid()!=geteuid() */ - int allow_setuid; - - /** Wether to allow user provided addresses like #4 */ - int allow_fd_source; - - /** Wether an option is given which needs a full bus scan */ - int no_whitelist; - - /** Wether the translated device address shall not follow softlinks, device - clones and SCSI addresses */ - int no_convert_fs_adr; - - /** Wether Bus,Target,Lun addresses shall be converted literally as old - Pseudo SCSI-Adresses. New default is to use (possibly system emulated) - real SCSI addresses via burn_drive_convert_scsi_adr() and literally - emulated and cdrecord-incompatible ATA: addresses. */ - int old_pseudo_scsi_adr; - - /** Wether bus scans shall exit!=0 if no drive was found */ - int scan_demands_drive; - - /** Wether to abort when a busy drive is encountered during bus scan */ - int abort_on_busy_drive; - - /** Wether to try to avoid collisions when opening drives */ - int drive_exclusive; - - /** Wether to try to wait for unwilling drives to become willing to open */ - int drive_blocking; - - /** Explicit write mode option is determined before skin processes - any track arguments */ - char write_mode_name[80]; - -#ifndef Cdrskin_extra_leaN - - /** List of startupfiles */ - char rc_filenames[Cdrpreskin_rc_nuM][Cdrskin_strleN]; - int rc_filename_count; - - /** Non-argument options from startupfiles */ - int pre_argc; - char **pre_argv; - int *pre_argidx; - int *pre_arglno; - -#endif /* ! Cdrskin_extra_leaN */ - -}; - - - -/** Create a preliminary cdrskin program run control object. It will become - part of the final control object. - @param preskin Returns pointer to resulting - @param flag Bitfield for control purposes: unused yet - @return <=0 error, 1 success -*/ -int Cdrpreskin_new(struct CdrpreskiN **preskin, int flag) -{ - struct CdrpreskiN *o; - int i; - - (*preskin)= o= TSOB_FELD(struct CdrpreskiN,1); - if(o==NULL) - return(-1); - - o->verbosity= 0; - strcpy(o->queue_severity,"NEVER"); - strcpy(o->print_severity,"SORRY"); - o->raw_device_adr[0]= 0; - o->device_adr[0]= 0; - o->adr_trn= NULL; - o->abort_handler= 3; - o->allow_setuid= 0; - o->allow_fd_source= 0; - o->no_whitelist= 0; - o->no_convert_fs_adr= 0; -#ifdef Cdrskin_libburn_has_convert_scsi_adR - o->old_pseudo_scsi_adr= 0; -#else - o->old_pseudo_scsi_adr= 1; -#endif - o->scan_demands_drive= 0; - o->abort_on_busy_drive= 0; - o->drive_exclusive= 1; - o->drive_blocking= 0; - strcpy(o->write_mode_name,"DEFAULT"); - -#ifndef Cdrskin_extra_leaN - o->rc_filename_count= Cdrpreskin_rc_nuM; - for(i=0;irc_filename_count-1;i++) - strcpy(o->rc_filenames[i],Cdrpreskin_sys_rc_nameS[i]); - o->rc_filenames[o->rc_filename_count-1][0]= 0; - o->pre_argc= 0; - o->pre_argv= NULL; - o->pre_argidx= NULL; - o->pre_arglno= NULL; -#endif /* ! Cdrskin_extra_leaN */ - - return(1); -} - - -int Cdrpreskin_destroy(struct CdrpreskiN **preskin, int flag) -{ - struct CdrpreskiN *o; - - o= *preskin; - if(o==NULL) - return(0); - -#ifndef Cdrskin_extra_leaN - if((o->pre_arglno)!=NULL) - free((char *) o->pre_arglno); - if((o->pre_argidx)!=NULL) - free((char *) o->pre_argidx); - if(o->pre_argc>0 && o->pre_argv!=NULL) - Sfile_destroy_argv(&(o->pre_argc),&(o->pre_argv),0); - Cdradrtrn_destroy(&(o->adr_trn),0); -#endif /* ! Cdrskin_extra_leaN */ - - free((char *) o); - *preskin= NULL; - return(1); -} - - -int Cdrpreskin_set_severities(struct CdrpreskiN *preskin, char *queue_severity, - char *print_severity, int flag) -{ -/* - if(preskin->verbosity>=Cdrskin_verbose_debuG) - fprintf(stderr, - "cdrskin: DEBUG : queue_severity='%s' print_severity='%s'\n", - queue_severity,print_severity); -*/ - - if(queue_severity!=NULL) - strcpy(preskin->queue_severity,queue_severity); - if(print_severity!=NULL) - strcpy(preskin->print_severity,print_severity); -#ifdef Cdrskin_libburn_has_burn_msgS - burn_msgs_set_severities(preskin->queue_severity, preskin->print_severity, - "cdrskin: "); -#endif - return(1); -} - - -int Cdrpreskin_initialize_lib(struct CdrpreskiN *preskin, int flag) -{ - int ret; - - ret= burn_initialize(); - if(ret==0) { - fprintf(stderr,"cdrskin : FATAL : Initialization of libburn failed\n"); - return(0); - } - Cdrpreskin_set_severities(preskin,NULL,NULL,0); - return(1); -} - - -/** Enable queuing of libburn messages or disable and print queue content. - @param flag Bitfield for control purposes: - bit0= enable queueing, else disable and print -*/ -int Cdrpreskin_queue_msgs(struct CdrpreskiN *o, int flag) -{ -#ifdef Cdrskin_libburn_has_burn_msgS -#ifndef Cdrskin_extra_leaN -#define Cdrskin_debug_libdax_msgS 1 -#endif -/* <<< In cdrskin there is not much sense in queueing library messages. - It is done here only for debugging */ -#ifdef Cdrskin_debug_libdax_msgS - - int ret; - static char queue_severity[81]= {"NEVER"}, print_severity[81]= {"SORRY"}; - static int queueing= 0; - char msg[BURN_MSGS_MESSAGE_LEN],msg_severity[81],filler[81]; - int error_code,os_errno,first,i; - - if(flag&1) { - if(!queueing) { - strcpy(queue_severity,o->queue_severity); - strcpy(print_severity,o->print_severity); - } - if(o->verbosity>=Cdrskin_verbose_debuG) - Cdrpreskin_set_severities(o,"DEBUG","NEVER",0); - else - Cdrpreskin_set_severities(o,"SORRY","NEVER",0); - queueing= 1; - return(1); - } - - if(queueing) - Cdrpreskin_set_severities(o,queue_severity,print_severity,0); - queueing= 0; - - for(first= 1; ; first= 0) { - ret= burn_msgs_obtain("ALL",&error_code,msg,&os_errno,msg_severity); - if(ret==0) - break; - if(ret<0) { - fprintf(stderr, - "cdrskin: NOTE : Please inform libburn-hackers@pykix.org about:\n"); - fprintf(stderr, - "cdrskin: burn_msgs_obtain() returns %d\n",ret); - break; - } - if(first) - fprintf(stderr, -"cdrskin: -------------------- Messages from Libburn ---------------------\n"); - for(i=0;msg_severity[i]!=0;i++) - filler[i]= ' '; - filler[i]= 0; - fprintf(stderr,"cdrskin: %s : %s\n",msg_severity,msg); - if(strcmp(msg_severity,"DEBUG")!=0 && os_errno!=0) - fprintf(stderr,"cdrskin: %s ( errno=%d '%s')\n", - filler,os_errno,strerror(os_errno)); - } - if(first==0) - fprintf(stderr, -"cdrskin: ----------------------------------------------------------------\n"); - -#endif /* Cdrskin_debug_libdax_msgS */ -#endif /* Cdrskin_libburn_has_burn_msgS */ - - return(1); -} - - -/** Convert a cdrecord-style device address into a libburn device address or - into a libburn drive number. It depends on the "scsibus" number of the - cdrecord-style address which kind of libburn address emerges: - bus=0 : drive number , bus=1 : /dev/sgN , bus=2 : /dev/hdX - (This call intentionally has no CdrpreskiN argument) - @param flag Bitfield for control purposes: - bit0= old_pseudo_scsi_adr - @return 1 success, 0=no recognizable format, -1=severe error, - -2 could not find scsi device, -3 address format error -*/ -int Cdrpreskin__cdrecord_to_dev(char *adr, char device_adr[Cdrskin_adrleN], - int *driveno, int flag) -{ - int comma_seen= 0,digit_seen= 0,busno= 0,k,lun_no= -1; - - *driveno= -1; - device_adr[0]= 0; - if(strlen(adr)==0) - return(0); - - /* read the trailing numeric string as device address code */ - /* accepts "1" , "0,1,0" , "ATA:0,1,0" , ... */ - for(k= strlen(adr)-1;k>=0;k--) { - if(adr[k]==',' && !comma_seen) { - sscanf(adr+k+1,"%d",&lun_no); - comma_seen= 1; - digit_seen= 0; - continue; - } - if(adr[k]<'0' || adr[k]>'9') - break; - digit_seen= 1; - } - if(!digit_seen) { - k= strlen(adr)-1; - if(adr[k]==':' || (adr[k]>='A' && adr[k]<='Z')) { /* empty prefix ? */ - *driveno= 0; - return(1); - } - return(0); - } - sscanf(adr+k+1,"%d",driveno); - - digit_seen= 0; - if(k>0) if(adr[k]==',') { - for(k--;k>=0;k--) { - if(adr[k]<'0' || adr[k]>'9') - break; - digit_seen= 1; - } - if(digit_seen) { - sscanf(adr+k+1,"%d",&busno); - if(flag&1) { - /* look for symbolic bus : 1=/dev/sgN 2=/dev/hdX */ - if(busno==1) { - sprintf(device_adr,"/dev/sg%d",*driveno); - } else if(busno==2) { - sprintf(device_adr,"/dev/hd%c",'a'+(*driveno)); - } else if(busno!=0) { - fprintf(stderr, - "cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus out of {0,1,2}\n"); - return(-3); - } - } else { - if(busno<0) { - fprintf(stderr, - "cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus number >= 0\n"); - return(-3); - } - if((strncmp(adr,"ATA",3)==0 && (adr[3]==0 || adr[3]==':')) || - (strncmp(adr,"ATAPI",5)==0 && (adr[5]==0 || adr[5]==':'))) { - - if(busno>12 || (*driveno)<0 || (*driveno)>1) { - fprintf(stderr, -"cdrskin: FATAL : dev=ATA:Bus,Target,Lun expects Bus {0..12}, Target {0,1}\n"); - return(-3); - } - sprintf(device_adr,"/dev/hd%c",'a'+(2*busno)+(*driveno)); - -#ifdef Cdrskin_libburn_has_convert_scsi_adR - } else { - int ret; - - ret= burn_drive_convert_scsi_adr(busno,-1,-1,*driveno,lun_no, - device_adr); - if(ret==0) { - fprintf(stderr, - "cdrskin: FATAL : Cannot find /dev/sgN with Bus,Target,Lun = %d,%d,%d\n", - busno,*driveno,lun_no); - fprintf(stderr, - "cdrskin: HINT : This drive may be in use by another program currently\n"); - return(-2); - } else if(ret<0) - return(-1); - return(1); - -#endif /* Cdrskin_libburn_has_convert_scsi_adR */ - } - } - } - } - return(1); -} - - -#ifndef Cdrskin_extra_leaN - -/** Load content startup files into preskin cache */ -int Cdrpreskin_read_rc(struct CdrpreskiN *o, char *progname, int flag) -{ - int ret,i; - char *filenames_v[3]; - - for(i=0;irc_filename_count;i++) - filenames_v[i]= o->rc_filenames[i]; - Sfile_home_adr_s(".cdrskinrc",o->rc_filenames[o->rc_filename_count-1], - Cdrskin_strleN,0); - ret= Sfile_multi_read_argv(progname,filenames_v,o->rc_filename_count, - &(o->pre_argc),&(o->pre_argv), - &(o->pre_argidx),&(o->pre_arglno),4); - return(ret); -} - -#endif /* ! Cdrskin_extra_leaN */ - - -/** Interpret those arguments which do not need libburn or which influence the - startup of libburn and/or the creation of the CdrskiN object. This is run - before libburn gets initialized and before Cdrskin_new() is called. - Options which need libburn or a CdrskiN object are processed in a different - function named Cdrskin_setup(). - @param flag Bitfield for control purposes: - bit0= do not finalize setup - bit1= do not read and interpret rc files - @return <=0 error, 1 success , 2 end program run with exit value 0 -*/ -int Cdrpreskin_setup(struct CdrpreskiN *o, int argc, char **argv, int flag) -/* -return: - <=0 error - 1 ok - 2 end program run (--help) -*/ -{ - int i,ret; - char *value_pt; - -#ifndef Cdrskin_extra_leaN - if(argc>1) { - if(strcmp(argv[1],"--no_rc")==0 || strcmp(argv[1],"-version")==0 || - strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-help")==0) - flag|= 2; - } - if(!(flag&2)) { - ret= Cdrpreskin_read_rc(o,argv[0],0); - if(ret<0) - return(-1); - if(o->pre_argc>1) { - ret= Cdrpreskin_setup(o,o->pre_argc,o->pre_argv,flag|1|2); - if(ret<=0) - return(ret); - /* ??? abort on ret==2 ? */ - } - } -#endif - - if(argc==1) { - fprintf(stderr,"cdrskin: SORRY : no options given. Try option --help\n"); - return(0); - } - for (i= 1;iabort_handler= 3; - - } else if(strcmp(argv[i],"--allow_setuid")==0) { - o->allow_setuid= 1; - - } else if(strcmp(argv[i],"blank=help")==0 || - strcmp(argv[i],"-blank=help")==0) { - -#ifndef Cdrskin_extra_leaN - - 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\n"); - fprintf(stderr, - "\tminimal\t\tminimally blank the entire disk\n"); - -#else /* ! Cdrskin_extra_leaN */ - - goto see_cdrskin_eng_html; - -#endif /* ! Cdrskin_extra_leaN */ - - if(argc==2) - {ret= 2; goto final_checks;} - - } else if(strcmp(argv[i],"--bragg_with_audio")==0) { - /* OBSOLETE 0.2.3 */; - - } else if(strcmp(argv[i],"--demand_a_drive")==0) { - o->scan_demands_drive= 1; - - } else if(strcmp(argv[i],"--devices")==0) { - printf("Note: If this hangs for a while then there is a drive with\n"); - printf(" unexpected problems (e.g. ill DMA).\n"); - printf(" One may exclude such a device file by removing r- and w-\n"); - printf(" permissions for all cdrskin users.\n"); - o->no_whitelist= 1; - - } else if(strncmp(argv[i],"dev_translation=",16)==0) { - -#ifndef Cdrskin_extra_leaN - - if(o->adr_trn==NULL) { - ret= Cdradrtrn_new(&(o->adr_trn),0); - if(ret<=0) - goto no_adr_trn_mem; - } - if(argv[i][16]==0) { - fprintf(stderr, - "cdrskin: FATAL : dev_translation= : missing separator character\n"); - return(0); - } - ret= Cdradrtrn_add(o->adr_trn,argv[i]+17,argv[i]+16,1); - if(ret==-2) { -no_adr_trn_mem:; - fprintf(stderr, - "cdrskin: FATAL : address_translation= : cannot allocate memory\n"); - } else if(ret==-1) - fprintf(stderr, - "cdrskin: FATAL : address_translation= : table full (%d items)\n", - Cdradrtrn_leN); - else if(ret==0) - fprintf(stderr, - "cdrskin: FATAL : address_translation= : no address separator '%c' found\n", - argv[i][17]); - if(ret<=0) - return(0); - -#else /* ! Cdrskin_extra_leaN */ - - fprintf(stderr, - "cdrskin: FATAL : dev_translation= is not available in lean version\n"); - return(0); - -#endif /* Cdrskin_extra_leaN */ - - - } else if(strncmp(argv[i],"-dev=",5)==0) { - value_pt= argv[i]+5; - goto set_dev; - } else if(strncmp(argv[i],"dev=",4)==0) { - value_pt= argv[i]+4; -set_dev:; - if(strcmp(value_pt,"help")==0) { - -#ifndef Cdrskin_extra_leaN - - printf("Supported SCSI transports for this platform:\n"); - fflush(stdout); - fprintf(stderr,"\nTransport name:\t\tlibburn\n"); - fprintf(stderr, - "Transport descr.:\tOpen-source library for writing optical discs\n"); - fprintf(stderr,"Transp. layer ind.:\t\n"); - fprintf(stderr,"Target specifier:\tbus,target,lun\n"); - fprintf(stderr,"Target example:\t\t1,2,0\n"); - fprintf(stderr,"SCSI Bus scanning:\tsupported\n"); - fprintf(stderr, - "Open via UNIX device:\tsupported (see option --devices)\n"); - -#else /* ! Cdrskin_extra_leaN */ - - goto see_cdrskin_eng_html; - -#endif /* Cdrskin_extra_leaN */ - - {ret= 2; goto final_checks;} - } - if(strlen(value_pt)>=sizeof(o->raw_device_adr)) - goto dev_too_long; - strcpy(o->raw_device_adr,value_pt); - - } else if(strcmp(argv[i],"--drive_abort_on_busy")==0) { - o->abort_on_busy_drive= 1; - - } else if(strcmp(argv[i],"--drive_blocking")==0) { - o->drive_blocking= 1; - - } else if(strcmp(argv[i],"--drive_not_exclusive")==0) { - o->drive_exclusive= 0; - - } else if(strcmp(argv[i],"--drive_scsi_exclusive")==0) { - o->drive_exclusive= 2; - - } else if(strcmp(argv[i],"driveropts=help")==0 || - strcmp(argv[i],"-driveropts=help")==0) { - -#ifndef Cdrskin_extra_leaN - - fprintf(stderr,"Driver options:\n"); - fprintf(stderr,"burnfree\tPrepare writer to use BURN-Free technology\n"); - fprintf(stderr,"noburnfree\tDisable using BURN-Free technology\n"); - -#else /* ! Cdrskin_extra_leaN */ - - goto see_cdrskin_eng_html; - -#endif /* Cdrskin_extra_leaN */ - - if(argc==2 || (i==2 && argc==3 && strncmp(argv[1],"dev=",4)==0)) - {ret= 2; goto final_checks;} - - } else if(strcmp(argv[i],"--help")==0) { - -#ifndef Cdrskin_extra_leaN - - printf("\n"); - printf("Usage: %s [options|source_addresses]\n", argv[0]); - printf("Burns preformatted data to CD-R or CD-RW via libburn.\n"); - printf("For the cdrecord compatible options which control the work of\n"); - printf( - "blanking and burning see output of option -help rather than --help.\n"); - printf("Non-cdrecord options:\n"); - printf(" --abort_handler do not leave the drive in busy state\n"); - printf(" --allow_setuid disable setuid blocker (very insecure !)\n"); - printf( - " --any_track allow source_addresses to match '^-.' or '='\n"); - printf(" --demand_a_drive exit !=0 on bus scans with empty result\n"); - printf(" --devices list accessible devices (tells /dev/...)\n"); - printf( - " dev_translation= set input address alias\n"); - printf(" e.g.: dev_translation=+ATA:1,0,0+/dev/sg1\n"); - printf(" --drive_abort_on_busy abort process if busy drive is found\n"); - printf(" (might be triggered by a busy hard disk)\n"); - printf(" --drive_blocking try to wait for busy drive to become free\n"); - printf(" (might be stalled by a busy hard disk)\n"); - printf(" --drive_not_exclusive do not ask kernel to prevent opening\n"); - printf(" busy drives. Effect is kernel dependend.\n"); - printf( - " --drive_scsi_exclusive try to exclusively reserve device files\n"); - printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n"); -#ifdef Cdrskin_burn_drive_eject_brokeN - printf( - " eject_device= set the device address for command eject\n"); -#endif - printf(" --fifo_disable disable fifo despite any fs=...\n"); - printf(" --fifo_per_track use a separate fifo for each track\n"); - printf( - " --fifo_start_empty do not wait for full fifo before burn start\n"); - printf( - " grab_drive_and_wait= grab drive, wait given number of\n"); - printf( - " seconds, release drive, and do normal work\n"); - printf( - " --ignore_signals try to ignore any signals rather than to abort\n"); - printf(" --no_abort_handler exit even if the drive is in busy state\n"); - printf(" --no_blank_appendable refuse to blank appendable CD-RW\n"); - printf(" --no_convert_fs_adr only literal translations of dev=\n"); - printf( - " --no_rc as first argument: do not read startup files\n"); - printf(" --old_pseudo_scsi_adr use and report literal Bus,Target,Lun\n"); - printf(" rather than real SCSI and pseudo ATA.\n"); - printf( - " --single_track accept only last argument as source_address\n"); - -#ifdef Cdrskin_allow_libburn_taO - printf( - " tao_to_sao_tsize= use num as fixed track size if in a\n"); - printf( - " non-TAO mode track data are read from \"-\"\n"); - printf( - " and no tsize= was specified.\n"); -#else - printf( - " tao_to_sao_tsize= substitute -tao by -sao and eventually\n"); - printf(" augment input from \"-\" by tsize=\n"); - printf(" (set tao_to_sao_tsize=0 to disable it)\n"); -#endif - - printf( - "Preconfigured arguments are read from the following startup files\n"); - printf( - "if they exist and are readable. The sequence is as listed here:\n"); - printf(" /etc/default/cdrskin /etc/opt/cdrskin/rc $HOME/.cdrskinrc\n"); - printf("Each file line is a single argument. No whitespace.\n"); - printf( - "By default any argument that does not match grep '^-.' or '=' is\n"); - printf( - "used as track source. If it is \"-\" then stdin is used.\n"); - printf("cdrskin : http://scdbackup.sourceforge.net/cdrskin_eng.html\n"); - printf(" mailto:scdbackup@gmx.net (Thomas Schmitt)\n"); - printf("libburn : http://libburn.pykix.org\n"); - printf("cdrecord : ftp://ftp.berlios.de/pub/cdrecord/\n"); - printf("My respect to the authors of cdrecord and libburn.\n"); - printf("scdbackup: http://scdbackup.sourceforge.net/main_eng.html\n"); - printf("\n"); - -#else /* ! Cdrskin_extra_leaN */ - -see_cdrskin_eng_html:; - printf("This is a capability reduced lean version without help texts.\n"); - printf("See http://scdbackup.sourceforge.net/cdrskin_eng.html\n"); - -#endif /* Cdrskin_extra_leaN */ - - - {ret= 2; goto final_checks;} - } else if(strcmp(argv[i],"-help")==0) { - -#ifndef Cdrskin_extra_leaN - - fprintf(stderr,"Usage: %s [options|source_addresses]\n",argv[0]); - fprintf(stderr,"Note: This is not cdrecord. See cdrskin start message on stdout. See --help.\n"); - fprintf(stderr,"Options:\n"); - fprintf(stderr,"\t-version\tprint version information and exit\n"); - fprintf(stderr, - "\tdev=target\tpseudo-SCSI target to use as CD-Recorder\n"); - fprintf(stderr, - "\tgracetime=#\tset the grace time before starting to write to #.\n"); - fprintf(stderr,"\t-v\t\tincrement verbose level by one\n"); - fprintf(stderr, - "\tdriveropts=opt\topt= one of {burnfree,noburnfree,help}\n"); - fprintf(stderr, - "\t-checkdrive\tcheck if a driver for the drive is present\n"); - fprintf(stderr,"\t-scanbus\tscan the SCSI bus and exit\n"); - fprintf(stderr,"\tspeed=#\t\tset speed of drive\n"); - fprintf(stderr,"\tblank=type\tblank a CD-RW disc (see blank=help)\n"); - fprintf(stderr, - "\tfs=#\t\tSet fifo size to # (0 to disable, default is 4 MB)\n"); - fprintf(stderr, - "\t-eject\t\teject the disk after doing the work (might be ignored)\n"); - fprintf(stderr,"\t-dummy\t\tdo everything with laser turned off\n"); -#ifdef Cdrskin_libburn_has_multI - fprintf(stderr, - "\t-msinfo\t\tretrieve multi-session info for mkisofs >= 1.10\n"); -#endif - fprintf(stderr,"\t-toc\t\tretrieve and print TOC/PMA data\n"); - fprintf(stderr, - "\t-atip\t\tretrieve media state, print \"Is *erasable\"\n"); -#ifdef Cdrskin_libburn_has_multI - fprintf(stderr, - "\t-multi\t\tgenerate a TOC that allows multi session\n"); -#endif - fprintf(stderr, - "\t-force\t\tforce to continue on some errors to allow blanking\n"); -#ifdef Cdrskin_allow_libburn_taO - fprintf(stderr,"\t-tao\t\tWrite disk in TAO mode.\n"); -#endif - fprintf(stderr,"\t-dao\t\tWrite disk in SAO mode.\n"); - fprintf(stderr,"\t-sao\t\tWrite disk in SAO mode.\n"); - fprintf(stderr,"\t-raw96r\t\tWrite disk in RAW/RAW96R mode\n"); - fprintf(stderr,"\ttsize=#\t\tannounces exact size of source data\n"); - fprintf(stderr,"\tpadsize=#\tAmount of padding\n"); - fprintf(stderr,"\t-audio\t\tSubsequent tracks are CD-DA audio tracks\n"); - fprintf(stderr, - "\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)\n"); - fprintf(stderr,"\t-pad\t\tpadsize=30k\n"); - fprintf(stderr, - "\t-nopad\t\tDo not pad (default, but applies only to data tracks)\n"); - fprintf(stderr, - "\t-swab\t\tAudio data source is byte-swapped (little-endian/Intel)\n"); - fprintf(stderr,"\t-help\t\tprint this text to stderr and exit\n"); - fprintf(stderr, - "Without option -data, .wav and .au files are extracted and burned as -audio.\n"); - fprintf(stderr, - "By default any argument that does not match grep '^-.' or '=' is used\n"); - fprintf(stderr, - "as track source address. Address \"-\" means stdin.\n"); - fprintf(stderr, - "cdrskin will ensure that an announced tsize= is written even if\n"); - fprintf(stderr, - "the source delivers fewer bytes. But 0 bytes from stdin with fifo\n"); - fprintf(stderr, - "enabled will lead to abort and no burn attempt at all.\n"); - -#else /* ! Cdrskin_extra_leaN */ - - fprintf(stderr,"Note: This is not cdrecord. See cdrskin start message on stdout.\n"); - fprintf(stderr, - "(writer profile: -atip retrieve, blank=type, -eject after work)\n"); - goto see_cdrskin_eng_html; - -#endif /* Cdrskin_extra_leaN */ - - {ret= 2; goto final_checks;} - - } else if(strcmp(argv[i],"--ignore_signals")==0) { - o->abort_handler= 2; - - } else if(strcmp(argv[i],"--no_abort_handler")==0) { - o->abort_handler= 0; - - } else if(strcmp(argv[i],"--no_convert_fs_adr")==0) { - o->no_convert_fs_adr= 1; - - } else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) { - o->old_pseudo_scsi_adr= 1; - - } else if(strcmp(argv[i],"--no_rc")==0) { - if(i!=1) - fprintf(stderr, - "cdrskin: NOTE : option --no_rc would only work as first argument.\n"); - - } else if(strcmp(argv[i],"-raw96r")==0) { - strcpy(o->write_mode_name,"RAW/RAW96R"); - - } else if(strcmp(argv[i],"-sao")==0 || strcmp(argv[i],"-dao")==0) { - strcpy(o->write_mode_name,"SAO"); - - } else if(strcmp(argv[i],"-scanbus")==0) { - o->no_whitelist= 1; - - } else if(strcmp(argv[i],"-tao")==0) { - strcpy(o->write_mode_name,"TAO"); - - } else if(strcmp(argv[i],"-v")==0 || strcmp(argv[i],"-verbose")==0) { - (o->verbosity)++; - printf("cdrskin: verbosity level : %d\n",o->verbosity); - if(o->verbosity>=Cdrskin_verbose_debuG) - Cdrpreskin_set_severities(o,"NEVER","DEBUG",0); - - } else if(strcmp(argv[i],"-version")==0) { - printf( - "Cdrecord 2.01-Emulation Copyright (C) 2006, see libburn.pykix.org\n"); - printf("libburn version : %s\n",Cdrskin_libburn_versioN); - -#ifndef Cdrskin_extra_leaN - printf("cdrskin version : %s\n",Cdrskin_prog_versioN); -#else - printf("cdrskin version : %s.lean (capability reduced lean version)\n", - Cdrskin_prog_versioN); -#endif - - printf("Version timestamp : %s\n",Cdrskin_timestamP); - printf("Build timestamp : %s\n",Cdrskin_build_timestamP); - {ret= 2; goto final_checks;} - } - - } - ret= 1; -final_checks:; - if(flag&1) - goto ex; - - if(o->allow_setuid==0 && getuid()!=geteuid()) { - fprintf(stderr, - "cdrskin: SORRY : uid and euid differ. Will abort for safety concerns.\n"); - fprintf(stderr, - "cdrskin: HINT : Consider to allow rw-access to the writer device and\n"); - fprintf(stderr, - "cdrskin: HINT : to run cdrskin under your normal user identity.\n"); - fprintf(stderr, - "cdrskin: HINT : Option --allow_setuid disables this safety check.\n"); - ret= 0; goto ex; - } - - if(strlen(o->raw_device_adr)>0 && !o->no_whitelist) { - int driveno,hret; - char *adr,buf[Cdrskin_adrleN]; - - adr= o->raw_device_adr; - -#ifndef Cdrskin_extra_leaN - if(o->adr_trn!=NULL) { - hret= Cdradrtrn_translate(o->adr_trn,adr,-1,buf,0); - if(hret<=0) { - fprintf(stderr, - "cdrskin: FATAL : address translation failed (address too long ?) \n"); - {ret= 0; goto ex;} - } - adr= buf; - } -#endif /* ! Cdrskin_extra_leaN */ - - if(adr[0]=='/') { - if(strlen(adr)>=sizeof(o->device_adr)) { -dev_too_long:; - fprintf(stderr, - "cdrskin: FATAL : dev=... too long (max. %d characters)\n", - sizeof(o->device_adr)-1); - {ret= 0; goto ex;} - } - strcpy(o->device_adr,adr); - } else { - ret= Cdrpreskin__cdrecord_to_dev(adr,o->device_adr,&driveno, - !!o->old_pseudo_scsi_adr); - if(ret==-2 || ret==-3) - {ret= 0; goto ex;} - if(ret<0) - goto ex; - if(ret==0) { - strcpy(o->device_adr,adr); - ret= 1; - } - } - -#ifdef Cdrskin_libburn_has_convert_fs_adR - - if(strlen(o->device_adr)>0 && !o->no_convert_fs_adr) { - int lret; - char link_adr[Cdrskin_strleN+1]; - - strcpy(link_adr,o->device_adr); - lret = burn_drive_convert_fs_adr(link_adr,o->device_adr); - if(lret<0) { - fprintf(stderr, - "cdrskin: NOTE : Please inform libburn-hackers@pykix.org about:\n"); - fprintf(stderr, - "cdrskin: burn_drive_convert_fs_adr() returned %d\n",lret); - } - } - -#endif /* Cdrskin_libburn_has_convert_fs_adR */ - - } - - /* A60927 : note to myself : no "ret= 1;" here. It breaks --help , -version */ - -ex:; - -#ifndef Cdrskin_extra_leaN - if(ret<=0 || !(flag&1)) - Cdradrtrn_destroy(&(o->adr_trn),0); -#endif - - return(ret); -} - - -/* --------------------------------------------------------------------- */ - - - -/** The maximum number of tracks */ -#define Cdrskin_track_maX 99 - - -/** Work around the fact that libburn leaves the track input fds open - after the track is done. This can hide a few overflow bytes buffered - by the fifo-to-libburn pipe which would cause a broken-pipe error - if libburn would close that outlet. - This macro enables a coarse workaround which tries to read bytes from - the track inlets after burning has ended. Probably not a good idea if - libburn would close the inlet fds. -*/ -#define Cdrskin_libburn_leaves_inlet_opeN 1 - - -/** List of furter wishes towards libburn: - - write mode which does not demand a track size in advance - - obtain minimum drive speed (for cdrskin -atip) - - obtain MMC profile of inserted media (for cdrskin -v -atip) - - a possibility to implement cdrskin -multi - - a possibilty to implement cdrskin -reset -*/ - - -/** Limit to prevent int rollovers within libburn as long as not everything is - changed to 64 bit off_t : 2 GB minus 800 MB for eventual computations. */ -#define Cdrskin_tracksize_maX 1308622848 - - -/* Some constants obtained by hearsay and experiments */ - -/** The payload speed factor for reporting progress: 1x = 150 kB/s */ -static double Cdrskin_cd_speed_factoR= 150.0*1024.0; - -/** The speed conversion factor consumer x-speed to libburn speed as used with - burn_drive_set_speed() burn_drive_get_write_speed() -*/ -static double Cdrskin_libburn_cd_speed_factoR= 176.0; - -/** Add-on for burn_drive_set_speed() to accomodate to the slightley oversized - speed ideas of my LG DVDRAM GSA-4082B. LITE-ON LTR-48125S tolerates it. -*/ -static double Cdrskin_libburn_cd_speed_addoN= 50.0; - - -/** The program run control object. Defaults: see Cdrskin_new(). */ -struct CdrskiN { - - /** Settings already interpreted by Cdrpreskin_setup */ - struct CdrpreskiN *preskin; - - /** Job: what to do, plus some parameters. */ - int verbosity; - double x_speed; - int gracetime; - int dummy_mode; - int force_is_set; - int single_track; - - int do_devices; - - int do_scanbus; - - int do_checkdrive; - - int do_msinfo; - int msinfo_fd; - - int do_atip; - - int do_blank; - int blank_fast; - int no_blank_appendable; - - int do_burn; - int burnfree; - /** The write mode (like SAO or RAW96/R). See libburn. - Controled by preskin->write_mode_name */ - enum burn_write_types write_type; - int block_type; - int multi; - - int do_eject; - char eject_device[Cdrskin_strleN]; - - - /** The current data source and its eventual parameters. - source_path may be either "-" for stdin, "#N" for open filedescriptor N - or the address of a readable file. - */ - char source_path[Cdrskin_strleN]; - double fixed_size; - double padding; - int set_by_padsize; - - /** track_type may be set to BURN_MODE1, BURN_AUDIO, etc. */ - int track_type; - int track_type_by_default; /* 0= explicit, 1=not set, 2=by file extension */ - int swap_audio_bytes; - - /** The list of tracks with their data sources and parameters */ - struct CdrtracK *tracklist[Cdrskin_track_maX]; - int track_counter; - /** a guess about what track might be processing right now */ - int supposed_track_idx; - - int fifo_enabled; - /** Optional fifo between input fd and libburn. It uses a pipe(2) to transfer - data to libburn. This fifo may be actually the start of a chain of fifos - which are to be processed simultaneously. - The fifo object knows the real input fd and the fd[1] of the pipe. - This is just a reference pointer. The fifos are managed by the tracks - which either line up their fifos or share the fifo of the first track. - */ - struct CdrfifO *fifo; - /** fd[0] of the fifo pipe. This is from where libburn reads its data. */ - int fifo_outlet_fd; - int fifo_size; - int fifo_start_empty; - int fifo_per_track; - - - /** User defined address translation */ - struct CdradrtrN *adr_trn; - - - /** The drives known to libburn after scan */ - struct burn_drive_info *drives; - unsigned int n_drives; - /** The drive selected for operation by CdrskiN */ - int driveno; - - - /** Progress state info: wether libburn is actually processing payload data */ - int is_writing; - /** Previously detected drive state */ - enum burn_drive_status previous_drive_status; - - /** abort parameters */ - int abort_max_wait; - - /** Engagement info for eventual abort */ - int lib_is_initialized; - pid_t control_pid; /* pid of the thread that calls libburn */ - int drive_is_grabbed; - int drive_is_busy; /* Wether drive was told to do something cancel-worthy */ - struct burn_drive *grabbed_drive; - - /** Abort test facility */ - double abort_after_bytecount; - - - /** Some intermediate option info which is stored until setup finalization */ - double tao_to_sao_tsize; - int stdin_source_used; - -}; - -int Cdrskin_destroy(struct CdrskiN **o, int flag); -int Cdrskin_grab_drive(struct CdrskiN *skin, int flag); -int Cdrskin_release_drive(struct CdrskiN *skin, int flag); - - -/** Create a cdrskin program run control object. - @param skin Returns pointer to resulting - @param flag Bitfield for control purposes: - bit0= library is already initialized - @return <=0 error, 1 success -*/ -int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag) -{ - struct CdrskiN *o; - int ret,i; - - (*skin)= o= TSOB_FELD(struct CdrskiN,1); - if(o==NULL) - return(-1); - o->preskin= preskin; - o->verbosity= preskin->verbosity; - o->x_speed= -1.0; - o->gracetime= 0; - o->dummy_mode= 0; - o->force_is_set= 0; - o->single_track= 0; - o->do_devices= 0; - o->do_scanbus= 0; - o->do_checkdrive= 0; - o->do_msinfo= 0; - o->msinfo_fd= -1; - o->do_atip= 0; - o->do_blank= 0; - o->blank_fast= 0; - o->no_blank_appendable= 0; - o->do_burn= 0; - o->write_type= BURN_WRITE_SAO; - o->block_type= BURN_BLOCK_SAO; - o->multi= 0; - o->burnfree= 0; - o->do_eject= 0; - o->eject_device[0]= 0; - o->source_path[0]= 0; - o->fixed_size= 0.0; - o->padding= 0.0; - o->set_by_padsize= 0; - o->track_type= BURN_MODE1; - o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */ - o->track_type_by_default= 1; - for(i=0;itracklist[i]= NULL; - o->track_counter= 0; - o->supposed_track_idx= -1; - o->fifo_enabled= 1; - o->fifo= NULL; - o->fifo_outlet_fd= -1; - o->fifo_size= 4*1024*1024; - o->fifo_start_empty= 0; - o->fifo_per_track= 0; - o->adr_trn= NULL; - o->drives= NULL; - o->n_drives= 0; - o->driveno= 0; - o->is_writing= 0; - o->previous_drive_status = BURN_DRIVE_IDLE; - o->abort_max_wait= 74*60; - o->lib_is_initialized= (flag&1); - o->control_pid= getpid(); - o->drive_is_grabbed= 0; - o->drive_is_busy= 0; - o->grabbed_drive= NULL; - o->abort_after_bytecount= -1.0; - o->tao_to_sao_tsize= 0.0; - o->stdin_source_used= 0; - -#ifndef Cdrskin_extra_leaN - ret= Cdradrtrn_new(&(o->adr_trn),0); - if(ret<=0) - goto failed; -#endif /* ! Cdrskin_extra_leaN */ - - return(1); -failed:; - Cdrskin_destroy(skin,0); - return(-1); -} - - -/** Release from memory a cdrskin object */ -int Cdrskin_destroy(struct CdrskiN **o, int flag) -{ - struct CdrskiN *skin; - int i; - - skin= *o; - if(skin==NULL) - return(0); - if(skin->drive_is_grabbed) - Cdrskin_release_drive(skin,0); - for(i=0;itrack_counter;i++) - Cdrtrack_destroy(&(skin->tracklist[i]),0); - -#ifndef Cdrskin_extra_leaN - Cdradrtrn_destroy(&(skin->adr_trn),0); -#endif /* ! Cdrskin_extra_leaN */ - - Cdrpreskin_destroy(&(skin->preskin),0); - if(skin->drives!=NULL) - burn_drive_info_free(skin->drives); - free((char *) skin); - *o= NULL; - return(1); -} - - -/** Set the eventual output fd for the result of Cdrskin_msinfo() -*/ -int Cdrskin_set_msinfo_fd(struct CdrskiN *skin, int result_fd, int flag) -{ - skin->msinfo_fd= result_fd; - return(1); -} - - -/** Return information about current track source */ -int Cdrskin_get_source(struct CdrskiN *skin, char *source_path, - double *fixed_size, double *padding, - int *set_by_padsize, int *track_type, - int *track_type_by_default, int *swap_audio_bytes, - int flag) -{ - strcpy(source_path,skin->source_path); - *fixed_size= skin->fixed_size; - *padding= skin->padding; - *set_by_padsize= skin->set_by_padsize; - *track_type= skin->track_type; - *track_type_by_default= skin->track_type_by_default; - *swap_audio_bytes= skin->swap_audio_bytes; - return(1); -} - - -#ifndef Cdrskin_extra_leaN - -/** Return information about current fifo setting */ -int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled, - int *fifo_size, int *fifo_start_empty, int flag) -{ - *fifo_enabled= skin->fifo_enabled; - *fifo_size= skin->fifo_size; - *fifo_start_empty= skin->fifo_start_empty; - return(1); -} - - -/** Create and install fifo objects between track data sources and libburn. - The sources and parameters are known to skin. - @return <=0 error, 1 success -*/ -int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag) -{ - struct CdrfifO *ff= NULL; - int ret,i,hflag; - - skin->fifo= NULL; - for(i=0;itrack_counter;i++) { - hflag= (skin->verbosity>=Cdrskin_verbose_debuG); - if(i==skin->track_counter-1) - hflag|= 4; - if(skin->verbosity>=Cdrskin_verbose_cmD) { - if(skin->fifo_per_track) - printf("cdrskin: track %d establishing fifo of %d bytes\n", - i+1,skin->fifo_size); - else if(i==0) - printf("cdrskin: establishing fifo of %d bytes\n",skin->fifo_size); - else { - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr,"cdrskin_debug: attaching track %d to fifo\n",i+1)); - hflag|= 2; - } - } - ret= Cdrtrack_attach_fifo(skin->tracklist[i],&(skin->fifo_outlet_fd),ff, - hflag); - if(ret<=0) { - fprintf(stderr,"cdrskin: FATAL : failed to attach fifo.\n"); - return(0); - } - if(i==0 || skin->fifo_per_track) - Cdrtrack_get_fifo(skin->tracklist[i],&ff,0); - if(i==0) - skin->fifo= ff; - } - return(1); -} - - -/** Read data into the track fifos until either #1 is full or its data source - is exhausted. - @return <=0 error, 1 success -*/ -int Cdrskin_fill_fifo(struct CdrskiN *skin, int flag) -{ - int ret; - - ret= Cdrtrack_fill_fifo(skin->tracklist[0],0); - if(ret<=0) - return(ret); - printf("input buffer ready.\n"); - fflush(stdout); - return(1); -} - -#endif /* ! Cdrskin_extra_leaN */ - - -/** Inform libburn about the consumer x-speed factor of skin */ -int Cdrskin_adjust_speed(struct CdrskiN *skin, int flag) -{ - int k_speed; - - if(skin->x_speed<0) - k_speed= 0; /* libburn.h promises 0 to be max speed. */ - else if(skin->x_speed==0) /* cdrecord specifies 0 as minimum speed. */ - k_speed= Cdrskin_libburn_cd_speed_factoR+Cdrskin_libburn_cd_speed_addoN; - else - k_speed= skin->x_speed*Cdrskin_libburn_cd_speed_factoR + - Cdrskin_libburn_cd_speed_addoN; - - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr,"cdrskin_debug: k_speed= %d\n",k_speed)); - - burn_drive_set_speed(skin->drives[skin->driveno].drive,k_speed,k_speed); - return(1); -} - - -/** Shutdown library and restart again on single drive which gets grabbed. - Does only work with a valid skin->driveno or with an already set - skin->preskin->device_adr . - @param flag Bitfield for control purposes: - bit0= skin->driveno points to a valid drive. The library - will get reopened with that drive listed as only one - and already grabbed. - bit1= do not load drive tray - @return 1 = success , - 0 = failure, drive is released, library initialized - -1 = failure, library is finished (and could not get initialized) -*/ -int Cdrskin_reinit_lib_with_adr(struct CdrskiN *skin, int flag) -{ - int ret; - - if(skin->drive_is_grabbed) - Cdrskin_release_drive(skin,0); - if(flag&1) - burn_drive_get_adr(&(skin->drives[skin->driveno]), - skin->preskin->device_adr); - if(strlen(skin->preskin->device_adr)<=0) { - fprintf(stderr, - "cdrskin: FATAL : unable to determine persistent drive address\n"); - ret= 0; goto ex; - } - burn_drive_info_free(skin->drives); - burn_finish(); - if(!burn_initialize()) { - fflush(stdout); - fprintf(stderr,"cdrskin : FATAL : Re-initialization of libburn failed\n"); - {ret= -1; goto ex;} - } - ret= Cdrskin_grab_drive(skin,1|(flag&2));/* uses burn_drive_scan_and_grab() */ - if(ret<=0) - {ret=0; goto ex;} - - ret= 1; -ex: - return(ret); -} - - -/** Obtain access to a libburn drive for writing or information retrieval. - If libburn is not restricted to a single persistent address then the - unused drives are dropped. This might be done by shutting down and - restartiing libburn with the wanted drive only. Thus, after this call, - libburn is supposed to have open only the reserved drive. - All other drives should be free for other use. - Warning: Do not store struct burn_drive pointer over this call. - Any such pointer might be invalid afterwards. - @param flag Bitfield for control purposes: - bit0= bus is unscanned, device is known, - use burn_drive_scan_and_grab() - bit1= do not load drive tray - bit2= do not issue error message on failure - @return <=0 error, 1 success -*/ -int Cdrskin_grab_drive(struct CdrskiN *skin, int flag) -{ - int ret,i; - struct burn_drive *drive; -#ifdef Cdrskin_grab_abort_brokeN - int restore_handler= 0; -#endif - - i= 0;/* as long as its use is conditional, so gcc -Wall does not complain */ - - if(skin->drive_is_grabbed) - Cdrskin_release_drive(skin,0); - - if(flag&1) { - skin->driveno= 0; - drive= NULL; - skin->grabbed_drive= drive; - } else { - drive= skin->drives[skin->driveno].drive; - skin->grabbed_drive= drive; - } - -#ifdef Cdrskin_grab_abort_brokeN - - /* There seems to be no way to get a drive out of status BURN_DRIVE_GRABBING - So try to block out signals if there is a signal handler installed */ - if(skin->preskin->abort_handler==1 || - skin->preskin->abort_handler==3 || - skin->preskin->abort_handler==4) { - Cleanup_set_handlers(NULL,NULL,2); - restore_handler= 1; - } - -#endif /* ! Cdrskin_grab_abort_brokeN */ - -#ifndef Cdrskin_oldfashioned_api_usE - - - if(flag&1) { - ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr, - !(flag&2)); - if(ret<=0) { - if(!(flag&4)) - fprintf(stderr,"cdrskin: FATAL : unable to open drive '%s'\n", - skin->preskin->device_adr); - goto ex; - } - skin->driveno= 0; - drive= skin->drives[skin->driveno].drive; - skin->grabbed_drive= drive; - } else { - if(strlen(skin->preskin->device_adr)<=0) { - -#define Cdrskin_drop_drives_by_forgeT 1 -#ifdef Cdrskin_drop_drives_by_forgeT - - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr, - "cdrskin_debug: Cdrskin_grab_drive() dropping unwanted drives (%d)\n", - skin->n_drives-1)); - for(i=0;in_drives;i++) { - if(i==skin->driveno) - continue; - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr, - "cdrskin_debug: Cdrskin_grab_drive() dropped drive number %d\n",i)); - ret= burn_drive_info_forget(&(skin->drives[i]), 0); - if(ret==1 || ret==2) - continue; - fprintf(stderr, - "cdrskin: NOTE : Please inform libburn-hackers@pykix.org about:\n"); - fprintf(stderr, - "cdrskin: burn_drive_info_forget() returns %d\n",ret); - } - -#else - - ret= Cdrskin_reinit_lib_with_adr(skin,1|(flag&2)); - goto ex; /* this calls Cdrskin_grab() with persistent address or fails */ - -#endif /* ! Cdrskin_drop_drives_by_forgeT */ - - } - -#else - - { - -#endif /* Cdrskin_oldfashioned_api_usE */ - - ret= burn_drive_grab(drive,!(flag&2)); - if(ret==0) { - if(!(flag&4)) - fprintf(stderr,"cdrskin: FATAL : unable to open drive %d\n", - skin->driveno); - goto ex; - } - -#ifdef Cdrskin_is_erasable_on_load_is_brokeN - /* RIP-14.5 + LITE-ON 48125S produce a false status if tray was unloaded */ - /* Therefore the first grab was just for loading */ - skin->drive_is_grabbed= 1; /* message to eventual abort handler */ - burn_drive_release(drive,0); - skin->drive_is_grabbed= 0; - - /* now grab the drive for real */ - ret= burn_drive_grab(drive,!(flag&2)); - if(ret==0) { - if(!(flag&4)) - fprintf(stderr,"cdrskin: FATAL : unable to open drive %d\n", - skin->driveno); - goto ex; - } -#endif /* ! Cdrskin_is_erasable_on_load_is_brokeN */ - - } - skin->drive_is_grabbed= 1; - ret= 1; -ex:; - -#ifdef Cdrskin_grab_abort_brokeN - if(restore_handler) { - int Cdrskin_abort_handler(struct CdrskiN *, int, int); - Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,4); - } -#endif /* Cdrskin_grab_abort_brokeN */ - - if(ret<=0) { - skin->drive_is_grabbed= 0; - skin->grabbed_drive= NULL; - } - return(ret); -} - - -/** Release grabbed libburn drive - @param flag Bitfield for control purposes: - bit0= eject -*/ -int Cdrskin_release_drive(struct CdrskiN *skin, int flag) -{ - if((!skin->drive_is_grabbed) || skin->grabbed_drive==NULL) { - fprintf(stderr,"cdrskin: CAUGHT : release of non-grabbed drive.\n"); - return(0); - } - burn_drive_release(skin->grabbed_drive,(flag&1)); - skin->drive_is_grabbed= 0; - skin->grabbed_drive= NULL; - return(1); -} - - -/** Clean up resources in abort situations. To be called by Cleanup subsystem - but hardly ever by the application. The program must exit afterwards. -*/ -int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag) -{ - -#ifdef Cdrskin_libburn_has_burn_aborT - - int ret; - -#else - - int wait_grain= 100000,first_status= 1; - double start_time,last_time,current_time; - -#endif /* ! Cdrskin_libburn_has_burn_aborT */ - - struct burn_progress p; - enum burn_drive_status drive_status= BURN_DRIVE_GRABBING; - - if(getpid()!=skin->control_pid) { - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr, - "\ncdrskin_debug: ABORT : [%d] Thread rejected: pid=%d, signum=%d\n", - skin->control_pid,getpid(),signum)); - return(-2); /* do only process the control thread */ - } - if(skin->preskin->abort_handler==3) - Cleanup_set_handlers(NULL,NULL,2); /* ignore all signals */ - else if(skin->preskin->abort_handler==4) - Cleanup_set_handlers(NULL,NULL,1); /* allow abort */ - fprintf(stderr, - "\ncdrskin: ABORT : Handling started. Please do not press CTRL+C now.\n"); - if(skin->preskin->abort_handler==3) - fprintf(stderr,"cdrskin: ABORT : Trying to ignore any further signals\n"); - -#ifndef Cdrskin_extra_leaN - if(skin->fifo!=NULL) - Cdrfifo_close_all(skin->fifo,0); -#endif - -#ifdef Cdrskin_libburn_has_burn_aborT - - /* Only for user info */ - if(skin->grabbed_drive!=NULL) - drive_status= burn_drive_get_status(skin->grabbed_drive,&p); - if(drive_status!=BURN_DRIVE_IDLE) { - fprintf(stderr,"cdrskin: ABORT : Abort processing depends on CD speed and buffer size\n"); - fprintf(stderr,"cdrskin: ABORT : Usually it is done with 4x speed after about a MINUTE\n"); - fprintf(stderr,"cdrskin: URGE : But wait at least the normal burning time before any kill -9\n"); - } - - ret= burn_abort(skin->abort_max_wait, burn_abort_pacifier, "cdrskin: "); - if(ret<=0) { - fprintf(stderr, - "\ncdrskin: ABORT : Cannot cancel burn session and release drive.\n"); - return(0); - } - fprintf(stderr,"\n"); - -#else /* Cdrskin_libburn_has_burn_aborT */ - - if(skin->grabbed_drive!=NULL) { - drive_status= burn_drive_get_status(skin->grabbed_drive,&p); - if(drive_status!=BURN_DRIVE_IDLE && !skin->drive_is_grabbed) - skin->drive_is_grabbed= 2; - if(drive_status!=BURN_DRIVE_IDLE && !skin->drive_is_busy) - skin->drive_is_busy= 2; - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr,"cdrskin_debug: ABORT : Drive status: %d\n", - (int) drive_status)); - } - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr, - "cdrskin_debug: ABORT : drive_is_grabbed=%d , drive_is_busy=%d (%X)\n", - skin->drive_is_grabbed,skin->drive_is_busy, - (unsigned int) skin->grabbed_drive)); - - if(skin->drive_is_grabbed) { - if(skin->drive_is_busy && skin->grabbed_drive!=NULL) { - if(drive_status==BURN_DRIVE_WRITING || drive_status==BURN_DRIVE_READING) { - fprintf(stderr,"cdrskin: ABORT : Trying to cancel drive operation.\n"); - burn_drive_cancel(skin->grabbed_drive); - } else if(drive_status==BURN_DRIVE_GRABBING) { - -#ifndef Cdrskin_oldfashioned_api_usE - int ret; - - fprintf(stderr, - "cdrskin: ABORT : Trying to close drive in process of grabbing\n"); - - /* >>> ??? rather inquire driveno from - skin->grabbed_drive->global_index ? */; - - ret= burn_drive_info_forget(&(skin->drives[skin->driveno]),1); - if(ret<=0) - fprintf(stderr, - "cdrskin: ABORT : Attempt to close drive failed (ret= %d)\n",ret); - else { - skin->drive_is_grabbed= 0; - skin->grabbed_drive= NULL; - goto try_to_finish_lib; - } - -#else - /* >>> what to do in this state ? */; -#endif /* Cdrskin_oldfashioned_api_usE */ - - } else if(drive_status!=BURN_DRIVE_IDLE) { - fprintf(stderr, - "cdrskin: ABORT : Will wait for current operation to end\n"); - } - if(drive_status!=BURN_DRIVE_IDLE) { - fprintf(stderr,"cdrskin: ABORT : Abort processing depends on CD speed and buffer size\n"); - fprintf(stderr,"cdrskin: ABORT : Usually it is done with 4x speed after about a MINUTE\n"); - fprintf(stderr,"cdrskin: URGE : But wait at least the normal burning time before any kill -9\n"); - } - last_time= start_time= Sfile_microtime(0); - while(1) { - drive_status= burn_drive_get_status(skin->grabbed_drive,&p); - if(drive_status==BURN_DRIVE_IDLE) - break; - usleep(wait_grain); - current_time= Sfile_microtime(0); - if(current_time-last_time>=1.0) { - if(first_status) - fprintf(stderr,"\n"); - first_status= 0; - fprintf(stderr,"\rcdrskin: ABORT : Status %d. Waiting for status %d since %d seconds (%d max)", - (int) drive_status, (int) BURN_DRIVE_IDLE, - (int) (current_time-start_time),skin->abort_max_wait); - last_time= current_time; - } - if(current_time-start_time>=skin->abort_max_wait) { - fprintf(stderr, - "\ncdrskin: ABORT : Cannot cancel burn session and release drive.\n"); - return(0); - } - } - fprintf(stderr,"\ncdrskin: ABORT : Status %d.\n",(int) drive_status); - } - fprintf(stderr,"cdrskin: ABORT : Trying to release drive.\n"); - Cdrskin_release_drive(skin,0); - } - -#ifndef Cdrskin_oldfashioned_api_usE -try_to_finish_lib:; -#endif - - if(skin->lib_is_initialized) { - fprintf(stderr,"cdrskin: ABORT : Trying to finish libburn.\n"); - burn_finish(); - } - -#endif /* ! Cdrskin_libburn_has_burn_aborT */ - - fprintf(stderr, - "cdrskin: ABORT : Drive is released and library is shut down now.\n"); - fprintf(stderr, - "cdrskin: ABORT : Program done. Even if you do not see a shell prompt.\n"); - return(1); -} - - -/** Convert a libburn device address into a libburn drive number - @return <=0 error, 1 success -*/ -int Cdrskin_driveno_of_location(struct CdrskiN *skin, char *devicename, - int *driveno, int flag) -{ - int i,ret; - char adr[Cdrskin_adrleN]; - - for(i=0;in_drives;i++) { - -#ifdef Cdrskin_libburn_has_drive_get_adR - ret= burn_drive_get_adr(&(skin->drives[i]), adr); - if(ret<=0) - continue; -#else - ret= 1; /* to please gcc -Wall */ - strcpy(adr,skin->drives[i].location); -#endif - - if(strcmp(adr,devicename)==0) { - *driveno= i; - return(1); - } - } - return(0); -} - - -/** Convert a cdrskin address into a libburn drive number - @return <=0 error, 1 success -*/ -int Cdrskin_dev_to_driveno(struct CdrskiN *skin, char *in_adr, int *driveno, - int flag) -{ - int ret; - char *adr,translated_adr[Cdrskin_adrleN],synthetic_adr[Cdrskin_adrleN]; - - adr= in_adr; - -#ifndef Cdrskin_extra_leaN - /* user defined address translation */ - ret= Cdradrtrn_translate(skin->adr_trn,adr,-1,translated_adr,0); - if(ret<=0) { - fprintf(stderr, - "cdrskin: FATAL : address translation failed (address too long ?) \n"); - return(0); - } - if(skin->verbosity>=Cdrskin_verbose_cmD && strcmp(adr,translated_adr)!=0) - printf("cdrskin: dev_translation=... : dev='%s' to dev='%s'\n", - adr,translated_adr); - adr= translated_adr; -#endif /* ! Cdrskin_extra_leaN */ - - if(adr[0]=='/') { - ret= Cdrskin_driveno_of_location(skin,adr,driveno,0); - if(ret<=0) { -location_not_found:; - fprintf(stderr, - "cdrskin: FATAL : cannot find '%s' among accessible drive devices.\n", - adr); - fprintf(stderr, - "cdrskin: HINT : use option --devices for a list of drive devices.\n"); - return(0); - } - return(1); - } - ret= Cdrpreskin__cdrecord_to_dev(adr,synthetic_adr,driveno, - !!skin->preskin->old_pseudo_scsi_adr); - if(ret<=0) { -wrong_devno:; - if(skin->n_drives<=0) { - fprintf(stderr,"cdrskin: FATAL : No accessible drives.\n"); - } else { - fprintf(stderr, - "cdrskin: FATAL : Address does not lead to an accessible drive: %s\n", - in_adr); - fprintf(stderr, - "cdrskin: HINT : dev= expects /dev/xyz, Bus,Target,0 or a number [0,%d]\n", - skin->n_drives-1); - } - return(0); - } - if(strlen(synthetic_adr)>0) { - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: converted address '%s' to '%s'\n",adr,synthetic_adr); - ret= Cdrskin_driveno_of_location(skin,synthetic_adr,driveno,0); - if(ret<=0) { - fprintf(stderr, - "cdrskin: failure while using address converted from '%s'\n",adr); - adr= synthetic_adr; - goto location_not_found; - } - } - if((*driveno)>=skin->n_drives || (*driveno)<0) { - fprintf(stderr,"cdrskin: obtained drive number %d from '%s'\n", - *driveno,adr); - goto wrong_devno; - } - return(1); -} - - -/** Convert a libburn drive number into a cdrecord-style address which - represents a device address if possible and the drive number else. - @param flag Bitfield for control purposes: - bit0= do not apply user defined address translation - @return <0 error, - pseudo transport groups: - 0 volatile drive number, - 1 /dev/sgN, 2 /dev/hdX, - 1000000+busno = non-pseudo SCSI bus - 2000000+busno = pseudo-ATA|ATAPI SCSI bus (currently busno==2) -*/ -int Cdrskin_driveno_to_btldev(struct CdrskiN *skin, int driveno, - char btldev[Cdrskin_adrleN], int flag) -{ - int k,ret,still_untranslated= 1,hret; - char *loc= NULL,buf[Cdrskin_adrleN],adr[Cdrskin_adrleN]; - - if(driveno<0 || driveno>skin->n_drives) - goto fallback; - -#ifdef Cdrskin_libburn_has_drive_get_adR - ret= burn_drive_get_adr(&(skin->drives[driveno]), adr); - if(ret<=0) - goto fallback; - loc= adr; -#else - adr[0]= 0; /* to please gcc -Wall */ - loc= skin->drives[driveno].location; - if(loc==NULL) - goto fallback; -#endif - -#ifdef Cdrskin_libburn_has_convert_scsi_adR - if(!skin->preskin->old_pseudo_scsi_adr) { - int host_no= -1,channel_no= -1,target_no= -1,lun_no= -1, bus_no= -1; - - ret= burn_drive_obtain_scsi_adr(loc,&bus_no,&host_no,&channel_no, - &target_no,&lun_no); - if(ret<=0) { - if(strncmp(loc,"/dev/hd",7)==0) - if(loc[7]>='a' && loc[7]<='z') - if(loc[8]==0) { - bus_no= (loc[7]-'a')/2; - sprintf(btldev,"%d,%d,0",bus_no,(loc[7]-'a')%2); - {ret= 2000000 + bus_no; goto adr_translation;} - } - goto fallback; - } else { - sprintf(btldev,"%d,%d,%d",bus_no,target_no,lun_no); - ret= 1000000+bus_no; - goto adr_translation; - } - } -#endif - - if(strncmp(loc,"/dev/sg",7)==0) { - for(k= 7;loc[k]!=0;k++) - if(loc[k]<'0' || loc[k]>'9') - break; - if(loc[k]==0 && k>7) { - sprintf(btldev,"1,%s,0",loc+7); - {ret= 1; goto adr_translation;} - } - } - if(strncmp(loc,"/dev/hd",7)==0) - if(loc[7]>='a' && loc[7]<='z') - if(loc[8]==0) { - sprintf(btldev,"2,%d,0",loc[7]-'a'); - {ret= 2; goto adr_translation;} - } -fallback:; - if(skin->preskin->old_pseudo_scsi_adr) { - sprintf(btldev,"0,%d,0",driveno); - } else { - if(loc!=NULL) - strcpy(btldev,loc); - else - sprintf(btldev,"%d",driveno); - } - ret= 0; - -adr_translation:; -#ifndef Cdrskin_extra_leaN - /* user defined address translation */ - if(!(flag&1)) { - if(ret>0) { - /* try wether a translation points to loc */ - hret= Cdradrtrn_translate(skin->adr_trn,loc,driveno,buf,1); - if(hret==2) { - still_untranslated= 0; - strcpy(btldev,buf); - } - } - if(still_untranslated) { - Cdradrtrn_translate(skin->adr_trn,btldev,driveno,buf,1); - strcpy(btldev,buf); - } - } -#endif /* ! Cdrskin_extra_leaN */ - - return(ret); -} - - -/** Report media status s to the user */ -int Cdrskin_report_disc_status(struct CdrskiN *skin, enum burn_disc_status s, - int flag) -{ - printf("cdrskin: status %d ",s); - if (s==BURN_DISC_FULL) { - printf("burn_disc_full \"There is a disc with data on it in the drive\"\n"); - } else if(s==BURN_DISC_BLANK) { - printf("burn_disc_blank \"The drive holds a blank disc\"\n"); - } else if(s==BURN_DISC_APPENDABLE) { - printf( - "BURN_DISC_APPENDABLE \"There is an incomplete disc in the drive\"\n"); - } else if(s==BURN_DISC_EMPTY) { - printf("BURN_DISC_EMPTY \"There is no disc at all in the drive\"\n"); - } else if(s==BURN_DISC_UNREADY) { - printf("BURN_DISC_UNREADY \"The current status is not yet known\"\n"); - -#ifdef Cdrskin_libburn_has_burn_disc_unsuitablE - - } else if(s==BURN_DISC_UNGRABBED) { - printf("BURN_DISC_UNGRABBED \"API usage error: drive not grabbed\"\n"); - } else if(s==BURN_DISC_UNSUITABLE) { - printf("BURN_DISC_UNSUITABLE \"Media is not suitable\"\n"); - -#endif /* Cdrskin_libburn_has_burn_disc_unsuitablE */ - - } else - printf("-unknown status code-\n"); - return(1); -} - - -/** Perform operations -scanbus or --devices - @param flag Bitfield for control purposes: - bit0= perform --devices rather than -scanbus - @return <=0 error, 1 success -*/ -int Cdrskin_scanbus(struct CdrskiN *skin, int flag) -{ - int ret,i,busno,first_on_bus,pseudo_transport_group= 0,skipped_devices= 0; - int busmax= 16; - char shellsafe[5*Cdrskin_strleN+2],perms[40],btldev[Cdrskin_adrleN]; - char adr[Cdrskin_adrleN],*raw_dev,*drives_shown= NULL; - struct stat stbuf; - - drives_shown= malloc(skin->n_drives+1); - if(drives_shown==NULL) - {ret= -1; goto ex;} - for(i=0;in_drives;i++) - drives_shown[i]= 0; - if(flag&1) { - printf("cdrskin: Overview of accessible drives (%d found) :\n", - skin->n_drives); - printf("-----------------------------------------------------------------------------\n"); - for(i=0;in_drives;i++) { - -#ifdef Cdrskin_libburn_has_drive_get_adR - ret= burn_drive_get_adr(&(skin->drives[i]), adr); - if(ret<=0) { - /* >>> one should massively complain */; - continue; - } -#else - strcpy(adr,skin->drives[i].location); -#endif - - if(stat(adr,&stbuf)==-1) { - sprintf(perms,"errno=%d",errno); - } else { - strcpy(perms,"------"); - if(stbuf.st_mode&S_IRUSR) perms[0]= 'r'; - if(stbuf.st_mode&S_IWUSR) perms[1]= 'w'; - if(stbuf.st_mode&S_IRGRP) perms[2]= 'r'; - if(stbuf.st_mode&S_IWGRP) perms[3]= 'w'; - if(stbuf.st_mode&S_IROTH) perms[4]= 'r'; - if(stbuf.st_mode&S_IWOTH) perms[5]= 'w'; - } - if(strlen(adr)>=Cdrskin_strleN) - Text_shellsafe("failure:oversized string",shellsafe,0); - else - Text_shellsafe(adr,shellsafe,0); - printf("%d dev=%s %s : '%s' '%s'\n", - i,shellsafe,perms,skin->drives[i].vendor,skin->drives[i].product); - } - printf("-----------------------------------------------------------------------------\n"); - } else { - if(!skin->preskin->old_pseudo_scsi_adr) { - pseudo_transport_group= 1000000; - raw_dev= skin->preskin->raw_device_adr; - if(strncmp(raw_dev,"ATA",3)==0 && (raw_dev[3]==0 || raw_dev[3]==':')) - pseudo_transport_group= 2000000; - if(strncmp(raw_dev,"ATAPI",5)==0 && (raw_dev[5]==0 || raw_dev[5]==':')) - pseudo_transport_group= 2000000; - if(pseudo_transport_group==2000000) { - fprintf(stderr,"scsidev: 'ATA'\ndevname: 'ATA'\n"); - fprintf(stderr,"scsibus: -2 target: -2 lun: -2\n"); - } - } - /* >>> fprintf(stderr,"Linux sg driver version: 3.1.25\n"); */ - printf("Using libburn version '%s'.\n", Cdrskin_libburn_versioN); - if(pseudo_transport_group!=1000000) - if(skin->preskin->old_pseudo_scsi_adr) - printf("cdrskin: NOTE : The printed addresses are not cdrecord compatible !\n"); - - for(busno= 0;busno<=busmax;busno++) { - first_on_bus= 1; - for(i=0;in_drives;i++) { - ret= Cdrskin_driveno_to_btldev(skin,i,btldev,1); - if(busno==busmax && drives_shown[i]==0) { - if(ret/1000000 != pseudo_transport_group) { - skipped_devices++; - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr,"cdrskin_debug: skipping drive '%s%s'\n", - ((ret/1000000)==2?"ATA:":""), btldev)); - continue; - } - } else if(ret != pseudo_transport_group + busno) - continue; - if(first_on_bus) - printf("scsibus%d:\n",busno); - first_on_bus= 0; - printf("\t%s\t %d) '%-8s' '%-16s' '%-4s' Removable CD-ROM\n", - btldev,i,skin->drives[i].vendor,skin->drives[i].product, - skin->drives[i].revision); - drives_shown[i]= 1; - } - } - } - if(skipped_devices>0) { - if(skipped_devices>1) - printf("cdrskin: NOTE : There were %d drives not shown.\n", - skipped_devices); - else - printf("cdrskin: NOTE : There was 1 drive not shown.\n"); - printf("cdrskin: HINT : To surely see all drives try option: --devices\n"); - if(pseudo_transport_group!=2000000) - printf("cdrskin: HINT : or try options: dev=ATA -scanbus\n"); - } - ret= 1; -ex:; - if(drives_shown!=NULL) - free((char *) drives_shown); - return(ret); -} - - -/** Perform -checkdrive . - @param flag Bitfield for control purposes: - bit0= do not print message about pseudo-checkdrive - @return <=0 error, 1 success -*/ -int Cdrskin_checkdrive(struct CdrskiN *skin, int flag) -{ - struct burn_drive_info *drive_info; - int ret; - char btldev[Cdrskin_adrleN]; - - if(!(flag&1)) - printf("cdrskin: pseudo-checkdrive on drive %d\n",skin->driveno); - if(skin->driveno>=skin->n_drives || skin->driveno<0) { - fprintf(stderr,"cdrskin: FATAL : there is no drive #%d\n",skin->driveno); - {ret= 0; goto ex;} - } - drive_info= &(skin->drives[skin->driveno]); - ret= Cdrskin_driveno_to_btldev(skin,skin->driveno,btldev,0); - if(ret>=0) - fprintf(stderr,"scsidev: '%s'\n",btldev); - printf("Device type : %s\n","Removable CD-ROM"); - printf("Vendor_info : '%s'\n",drive_info->vendor); - printf("Identifikation : '%s'\n",drive_info->product); - printf("Revision : '%s'\n",drive_info->revision); - printf("Driver flags : %s\n","BURNFREE"); -#ifdef Cdrskin_allow_libburn_taO - - /* <<< */ - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr, - "cdrskin_debug: block_types: tao=%4.4X sao=%4.4X raw=%4.4X\n", - drive_info->tao_block_types,drive_info->sao_block_types, - drive_info->raw_block_types)); - - printf("Supported modes:"); - if((drive_info->tao_block_types & (BURN_BLOCK_MODE1|BURN_BLOCK_RAW0)) - == (BURN_BLOCK_MODE1|BURN_BLOCK_RAW0)) - printf(" TAO"); - if(drive_info->sao_block_types & BURN_BLOCK_SAO) - printf(" SAO"); - if(drive_info->raw_block_types & BURN_BLOCK_RAW96R) - printf(" RAW/RAW96R"); - printf("\n"); - -#else - printf("Supported modes: %s\n","SAO RAW/R96R"); -#endif - ret= 1; -ex:; - return(ret); -} - - -int Cdrskin_obtain_nwa(struct CdrskiN *skin, int *nwa, int flag) -{ - int ret,lba; - struct burn_drive *drive; - struct burn_write_opts *o= NULL; - - /* Set write opts in order to provoke MODE SELECT. LG GSA-4082B needs it. */ - drive= skin->drives[skin->driveno].drive; - o= burn_write_opts_new(drive); - if(o!=NULL) { - burn_write_opts_set_perform_opc(o, 0); - burn_write_opts_set_write_type(o,skin->write_type,skin->block_type); - burn_write_opts_set_underrun_proof(o,skin->burnfree); - } -#ifdef Cdrskin_libburn_has_multI - ret= burn_disc_track_lba_nwa(drive,o,0,&lba,nwa); -#else - ret= 0; - lba= 0;/* silence gcc warning */ -#endif - if(o!=NULL) - burn_write_opts_free(o); - return(ret); -} - - -/** Print lba of first track of last session and Next Writeable Address of - the next unwritten session. -*/ -int Cdrskin_msinfo(struct CdrskiN *skin, int flag) -{ - int num_sessions, session_no, ret, num_tracks; - int nwa= -123456789, lba= -123456789, aux_lba; - char msg[80]; - enum burn_disc_status s; - struct burn_drive *drive; - struct burn_disc *disc= NULL; - struct burn_session **sessions; - struct burn_track **tracks; - struct burn_toc_entry toc_entry; - - ret= Cdrskin_grab_drive(skin,0); - if(ret<=0) - return(ret); - drive= skin->drives[skin->driveno].drive; - while(burn_drive_get_status(drive,NULL) != BURN_DRIVE_IDLE) - usleep(100002); - while ((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(100002); - if(s!=BURN_DISC_APPENDABLE) { - Cdrskin_report_disc_status(skin,s,0); - fprintf(stderr, - "cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) CD\n"); - {ret= 0; goto ex;} - } - disc= burn_drive_get_disc(drive); - if(disc==NULL) { - fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n"); - {ret= 0; goto ex;} - } - sessions= burn_disc_get_sessions(disc,&num_sessions); - for(session_no= 0; session_no0) - nwa= aux_lba+6900; - else - nwa= aux_lba+11400; - } - if(skin->msinfo_fd>=0) { - sprintf(msg,"%d,%d\n",lba,nwa); - write(skin->msinfo_fd,msg,strlen(msg)); - } else - printf("%d,%d\n",lba,nwa); - ret= 1; -ex:; - - /* must calm down my NEC ND-4570A afterwards */ - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr,"cdrskin_debug: doing extra release-grab cycle\n")); - Cdrskin_release_drive(skin,0); - Cdrskin_grab_drive(skin,0); - - Cdrskin_release_drive(skin,0); - return(ret); -} - - -/** Perform -toc under control of Cdrskin_atip(). - @param flag Bitfield for control purposes: - bit0= do not list sessions separately (do it cdrecord style) - @return <=0 error, 1 success -*/ -int Cdrskin_toc(struct CdrskiN *skin, int flag) -{ - int num_sessions= 0,num_tracks= 0,lba= 0,track_count= 0,total_tracks= 0; - int session_no, track_no; - struct burn_drive *drive; - struct burn_disc *disc= NULL; - struct burn_session **sessions; - struct burn_track **tracks; - struct burn_toc_entry toc_entry; - - drive= skin->drives[skin->driveno].drive; - - disc= burn_drive_get_disc(drive); - if(disc==NULL) - goto cannot_read; - sessions= burn_disc_get_sessions(disc,&num_sessions); - if(flag&1) { - for(session_no= 0; session_no>> From where does cdrecord take "mode" ? */ - - /* This is not the "mode" as printed by cdrecord : - printf(" mode: %d\n",burn_track_get_mode(tracks[track_no])); - */ - /* own guess: cdrecord says "1" on data and "0" on audio : */ - printf(" mode: %d\n",((toc_entry.control&7)<4?0:1)); - - } - if((flag&1) && session_nodriveno); - ret= Cdrskin_checkdrive(skin,1); - if(ret<=0) - return(ret); - ret= Cdrskin_grab_drive(skin,0); - if(ret<=0) - return(ret); - drive= skin->drives[skin->driveno].drive; - while(burn_drive_get_status(drive,NULL) != BURN_DRIVE_IDLE) - usleep(100002); - while ((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(100002); - Cdrskin_report_disc_status(skin,s,0); - if(s==BURN_DISC_APPENDABLE && skin->no_blank_appendable) { - is_not_really_erasable= 1; - } else if(s==BURN_DISC_EMPTY) { - if(skin->verbosity>=Cdrskin_verbose_progresS) - printf("Current: none\n"); - ret= 0; goto ex; - } - - -#ifdef Cdrskin_atip_speed_brokeN - - /* <<< terrible stunt to get correct media speed info */ - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(fprintf(stderr, - "cdrskin_debug: redoing startup for speed inquiry stabilization\n")); - - -#ifndef Cdrskin_oldfashioned_api_usE - - if(strlen(skin->preskin->device_adr)<=0) - burn_drive_get_adr(&(skin->drives[skin->driveno]), - skin->preskin->device_adr); - - Cdrskin_release_drive(skin,0); - burn_finish(); - if(!burn_initialize()) { - fflush(stdout); - fprintf(stderr,"cdrskin : FATAL : Re-initialization of libburn failed\n"); - {ret= 0; goto ex;} - } - ret= Cdrskin_grab_drive(skin,1); /* uses burn_drive_scan_and_grab() */ - if(ret<=0) - return(ret); - drive= skin->drives[skin->driveno].drive; - -#else /* ! Cdrskin_oldfashioned_api_usE */ - - Cdrskin_release_drive(skin,0); - burn_finish(); - if(!burn_initialize()) { - fflush(stdout); - fprintf(stderr,"cdrskin : FATAL : Re-initialization of libburn failed\n"); - {ret= 0; goto ex;} - } - if(strlen(skin->preskin->device_adr)>0) - burn_drive_add_whitelist(skin->preskin->device_adr); - while(!burn_drive_scan(&(skin->drives),&(skin->n_drives))) - usleep(1002); - ret= Cdrskin_grab_drive(skin,0); - if(ret<=0) - return(ret); - drive= skin->drives[skin->driveno].drive; - -#endif /* Cdrskin_oldfashioned_api_usE */ - -#endif /* Cdrskin_atip_speed_brokeN */ - -#ifdef Cdrskin_libburn_has_read_atiP - ret= burn_disc_read_atip(drive); - if(ret>0) { - ret= burn_drive_get_min_write_speed(drive); - x_speed_min= ((double) ret)/Cdrskin_libburn_cd_speed_factoR; - } -#endif - -#ifdef Cdrskin_libburn_has_burn_disc_unsuitablE - if(burn_disc_get_status(drive) == BURN_DISC_UNSUITABLE) { - printf("Current: UNSUITABLE MEDIA\n"); - {ret= 0; goto ex;} - } -#endif - - ret= burn_drive_get_write_speed(drive); - x_speed_max= ((double) ret)/Cdrskin_libburn_cd_speed_factoR; - if(x_speed_min<0) - x_speed_min= x_speed_max; - printf("cdrskin: burn_drive_get_write_speed = %d (%.1fx)\n",ret,x_speed_max); - if(skin->verbosity>=Cdrskin_verbose_progresS) { - if(burn_disc_erasable(drive)) - printf("Current: CD-RW\n"); - else - printf("Current: CD-R\n"); - } - printf("ATIP info from disk:\n"); - if(burn_disc_erasable(drive)) { - if(is_not_really_erasable) - printf(" Is erasable (but not while in this incomplete state)\n"); - else - printf(" Is erasable\n"); - } else { - printf(" Is not erasable\n"); - } - -#ifdef Cdrskin_libburn_has_get_start_end_lbA - { int start_lba,end_lba,min,sec,fr; - ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0); - if(ret>0) { - burn_lba_to_msf(start_lba,&min,&sec,&fr); - printf(" ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n", - start_lba,min,sec,fr); - burn_lba_to_msf(end_lba,&min,&sec,&fr); - printf(" ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n", - end_lba,min,sec,fr); - } - } -#endif /* Cdrskin_libburn_has_get_start_end_lbA */ - - printf(" 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max); - ret= 1; - if(flag&1) - Cdrskin_toc(skin,1);/*cdrecord seems to ignore -toc errors if -atip is ok */ -ex:; - Cdrskin_release_drive(skin,0); - return(ret); -} - - -#ifndef Cdrskin_extra_leaN - -/** Emulate the gracetime= behavior of cdrecord - @param flag Bitfield for control purposes: - bit0= do not print message about pseudo-checkdrive -*/ -int Cdrskin_wait_before_action(struct CdrskiN *skin, int flag) -/* flag: bit0= BLANK rather than write mode */ -{ - int i; - - if(skin->verbosity>=Cdrskin_verbose_progresS) { - char speed_text[80]; - if(skin->x_speed<0) - strcpy(speed_text,"MAX"); - else if(skin->x_speed==0) - strcpy(speed_text,"MIN"); - else - sprintf(speed_text,"%.f",skin->x_speed); - printf( - "Starting to write CD/DVD at speed %s in %s %s mode for single session.\n", - speed_text,(skin->dummy_mode?"dummy":"real"), - (flag&1?"BLANK":skin->preskin->write_mode_name)); - printf("Last chance to quit, starting real write in %3d seconds.", - skin->gracetime); - fflush(stdout); - } - for(i= skin->gracetime-1;i>=0;i--) { - usleep(1000000); - if(skin->verbosity>=Cdrskin_verbose_progresS) { - printf("\b\b\b\b\b\b\b\b\b\b\b\b\b %3d seconds.",i); - fflush(stdout); - } - } - if(skin->verbosity>=Cdrskin_verbose_progresS) - {printf(" Operation starts.\n");fflush(stdout);} - return(1); -} - -#endif /* Cdrskin_extra_leaN */ - - -/** Perform blank=[all|fast] - @return <=0 error, 1 success -*/ -int Cdrskin_blank(struct CdrskiN *skin, int flag) -{ - enum burn_disc_status s; - struct burn_progress p; - struct burn_drive *drive; - int ret,loop_counter= 0,hint_force= 0; - double start_time; - - start_time= Sfile_microtime(0); /* will be refreshed later */ - ret= Cdrskin_grab_drive(skin,0); - if(ret<=0) - return(ret); - drive= skin->drives[skin->driveno].drive; - - while(burn_drive_get_status(drive,NULL) != BURN_DRIVE_IDLE) - usleep(100002); - while ((s = burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(100002); - if(skin->verbosity>=Cdrskin_verbose_progresS) - Cdrskin_report_disc_status(skin,s,0); - -#ifdef Cdrskin_libburn_has_pretend_fulL - if(s==BURN_DISC_UNSUITABLE) { - if(skin->force_is_set) { - fprintf(stderr, - "cdrskin: NOTE : -force blank=... : Treating unsuitable media as burn_disc_full\n"); - ret= burn_disc_pretend_full(drive); - s= burn_disc_get_status(drive); - } else - hint_force= 1; - } -#endif /* Cdrskin_libburn_has_pretend_fulL */ - - if(s!=BURN_DISC_FULL && - (s!=BURN_DISC_APPENDABLE || skin->no_blank_appendable)) { - Cdrskin_release_drive(skin,0); - if(s==BURN_DISC_BLANK) { - fprintf(stderr, - "cdrskin: NOTE : blank=... : media was already blank (and still is)\n"); - return(2); - } else if(s==BURN_DISC_APPENDABLE) { - fprintf(stderr, - "cdrskin: FATAL : blank=... : media is still appendable\n"); - } else { - fprintf(stderr, - "cdrskin: FATAL : blank=... : no blankworthy disc found\n"); - if(hint_force) - fprintf(stderr, - "cdrskin: HINT : If you are certain to have a CD-RW, try option -force\n"); - } - return(0); - } - if(!burn_disc_erasable(drive)) { - fprintf(stderr, - "cdrskin: FATAL : blank=... : media is not erasable\n"); - return(0); - } - if(skin->dummy_mode) { - fprintf(stderr, - "cdrskin: would have begun to blank disc if not in -dummy mode\n"); - goto blanking_done; - } - fprintf(stderr,"cdrskin: beginning to blank disc\n"); - Cdrskin_adjust_speed(skin,0); - -#ifndef Cdrskin_extra_leaN - Cdrskin_wait_before_action(skin,1); -#endif /* ! Cdrskin_extra_leaN */ - - skin->drive_is_busy= 1; - burn_disc_erase(drive,skin->blank_fast); - - loop_counter= 0; - start_time= Sfile_microtime(0); - while(burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { - if(loop_counter>0) - if(skin->verbosity>=Cdrskin_verbose_progresS) { - int percent= 50; - - if(p.sectors>0) /* i want a display of 1 to 99 percent */ - percent= 1.0+((double) p.sector+1.0)/((double) p.sectors)*98.0; - fprintf(stderr, - "\rcdrskin: blanking ( done %2d%% , %lu seconds elapsed ) ", - percent,(unsigned long) (Sfile_microtime(0)-start_time)); - } - sleep(1); - loop_counter++; - } -blanking_done:; - skin->drive_is_busy= 0; - if(skin->verbosity>=Cdrskin_verbose_progresS) { - fprintf(stderr, - "\rcdrskin: blanking done \n"); - printf("Blanking time: %.3fs\n",Sfile_microtime(0)-start_time); - fflush(stdout); - } - Cdrskin_release_drive(skin,0); - return(1); -} - - -/** Report burn progress. This is done partially in cdrecord style. - Actual reporting happens only if write progress hit the next MB or if in - non-write-progress states a second has elapsed since the last report. - After an actual report a new statistics interval begins. - @param drive_status As obtained from burn_drive_get_status() - @param p Progress information from burn_drive_get_status() - @param start_time Timestamp of burn start in seconds - @param last_time Timestamp of report interval start in seconds - @param total_count Returns the total number of bytes written so far - @param total_count Returns the number of bytes written during interval - @param flag Bitfield for control purposes: - bit0= report in growisofs style rather than cdrecord style - @return <=0 error, 1 seems to be writing payload, 2 doing something else -*/ -int Cdrskin_burn_pacifier(struct CdrskiN *skin, - enum burn_drive_status drive_status, - struct burn_progress *p, - double start_time, double *last_time, - double *total_count, double *last_count, - int *min_buffer_fill, int flag) -/* - bit0= growisofs style -*/ -{ - double bytes_to_write,written_bytes= 0.0,written_total_bytes= 0.0,buffer_size; - double fixed_size,padding,sector_size,speed_factor; - double measured_total_speed,measured_speed; - double elapsed_time,elapsed_total_time,current_time; - double estim_time,estim_minutes,estim_seconds,percent; - int ret,fifo_percent,fill,space,advance_interval=0,new_mb,old_mb,time_to_tell; - int fs,bs,old_track_idx,buffer_fill; - char fifo_text[80],mb_text[40]; - char *debug_mark= ""; /* use this to prepend a marker text for experiments */ - - /* for debugging */ - static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out; - - current_time= Sfile_microtime(0); - elapsed_total_time= current_time-start_time; - elapsed_time= current_time-*last_time; - time_to_tell= (elapsed_time>=1.0)&&(elapsed_total_time>=1.0); - - if(drive_status==BURN_DRIVE_WRITING) { - ; - } else if(drive_status==BURN_DRIVE_WRITING_LEADIN - -#ifdef Cdrskin_allow_libburn_taO - || drive_status==BURN_DRIVE_WRITING_PREGAP -#endif - - ) { - if(time_to_tell || skin->is_writing) { - if(skin->verbosity>=Cdrskin_verbose_progresS) { - if(skin->is_writing) - fprintf(stderr,"\n"); - fprintf(stderr, - "\rcdrskin: working pre-track (burning since %.f seconds) ", - elapsed_total_time); - } - skin->is_writing= 0; - advance_interval= 1; - } - {ret= 2; goto ex;} - } else if(drive_status==BURN_DRIVE_WRITING_LEADOUT - -#ifdef Cdrskin_allow_libburn_taO - || drive_status==BURN_DRIVE_CLOSING_TRACK - || drive_status==BURN_DRIVE_CLOSING_SESSION -#endif - - ) { - -#ifdef Cdrskin_allow_libburn_taO - if(drive_status==BURN_DRIVE_CLOSING_SESSION && - skin->previous_drive_status!=drive_status) - {printf("\nFixating...\n"); fflush(stdout);} -#endif - - if(time_to_tell || skin->is_writing) { - if(skin->verbosity>=Cdrskin_verbose_progresS) { - if(skin->is_writing) - fprintf(stderr,"\n"); - fprintf(stderr, - "\rcdrskin: working post-track (burning since %.f seconds) ", - elapsed_total_time); - } - skin->is_writing= 0; - advance_interval= 1; - } - {ret= 2; goto ex;} - } else - goto thank_you_for_patience; - - old_track_idx= skin->supposed_track_idx; -#ifdef Cdrskin_progress_track_brokeN - /* with libburn.0.2 there is always reported 0 as p->track */ - if(written_bytes<0) { /* track hop ? */ - if(skin->supposed_track_idx+1track_counter) - skin->supposed_track_idx++; - } - /* >>> ask eventual fifo about writing fd */; - if(p->track>0) - skin->supposed_track_idx= p->track; -#else /* Cdrskin_progress_track_brokeN */ - skin->supposed_track_idx= p->track; -#endif /* ! Cdrskin_progress_track_brokeN */ - - if(old_track_idx>=0 && old_track_idxsupposed_track_idx) { - Cdrtrack_get_size(skin->tracklist[old_track_idx],&fixed_size,&padding, - §or_size,1); - if(skin->verbosity>=Cdrskin_verbose_progresS) - printf("\n"); - printf("%sTrack %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n", - debug_mark,old_track_idx+1,fixed_size,fixed_size+padding, - (fixed_size+padding)/sector_size); - } - - sector_size= 2048.0; - if(skin->supposed_track_idx>=0 && - skin->supposed_track_idxtrack_counter) - Cdrtrack_get_size(skin->tracklist[skin->supposed_track_idx],&fixed_size, - &padding,§or_size,0); - - bytes_to_write= ((double) p->sectors)*sector_size; - written_total_bytes= ((double) p->sector)*sector_size; - written_bytes= written_total_bytes-*last_count; - - if(written_total_bytes<1024*1024) { -thank_you_for_patience:; - if(time_to_tell || (skin->is_writing && elapsed_total_time>=1.0)) { - if(skin->verbosity>=Cdrskin_verbose_progresS) { - if(skin->is_writing) - fprintf(stderr,"\n"); - fprintf(stderr, - "\rcdrskin: thank you for being patient since %.f seconds ", - elapsed_total_time); - } - advance_interval= 1; - } - skin->is_writing= 0; - {ret= 2; goto ex;} - } - new_mb= written_total_bytes/(1024*1024); - old_mb= (*last_count)/(1024*1024); - if(new_mb==old_mb && !(written_total_bytes>=skin->fixed_size && - skin->fixed_size>0 && time_to_tell)) - {ret= 1; goto ex;} - - -#ifndef Cdrskin_extra_leaN - - percent= 0.0; - if(bytes_to_write>0) - percent= written_total_bytes/bytes_to_write*100.0; - measured_total_speed= 0.0; - measured_speed= 0.0; - estim_time= -1.0; - estim_minutes= -1.0; - estim_seconds= -1.0; - if(elapsed_total_time>0.0) { - measured_total_speed= written_total_bytes/elapsed_total_time; - estim_time= (bytes_to_write-written_bytes)/measured_total_speed; - if(estim_time>0.0 && estim_time<86400.0) { - estim_minutes= ((int) estim_time)/60; - estim_seconds= estim_time-estim_minutes*60.0; - if(estim_seconds<0.0) - estim_seconds= 0.0; - } - } - if(elapsed_time>0.0) - measured_speed= written_bytes/elapsed_time; - else if(written_bytes>0.0) - measured_speed= 99.91*Cdrskin_cd_speed_factoR; - if(measured_speed<=0.0 && written_total_bytes>=skin->fixed_size && - skin->fixed_size>0) { - if(!skin->is_writing) - goto thank_you_for_patience; - skin->is_writing= 0; - measured_speed= measured_total_speed; - } else - skin->is_writing= 1; - if(skin->supposed_track_idx<0) - skin->supposed_track_idx= 0; - if(*last_count<=0.0) - printf("%-78.78s\r",""); - if(skin->verbosity>=Cdrskin_verbose_progresS) { - if(flag&1) { - printf("%.f/%.f (%2.1f%%) @%1.1f, remaining %.f:%2.2d\n", - written_total_bytes,bytes_to_write,percent, - measured_speed/Cdrskin_cd_speed_factoR, - estim_minutes,(int) estim_seconds); - } else { - fill= 0; - fifo_percent= 50; - fifo_text[0]= 0; - curr_fifo_in= last_fifo_in; - curr_fifo_out= last_fifo_out; - if(skin->fifo!=NULL) { - ret= Cdrfifo_get_buffer_state(skin->fifo,&fill,&space,0); - buffer_size= fill+space; - if(ret==2 || ret==0) { - fifo_percent= 100; - } else if(ret>0 && buffer_size>0.0) { - /* obtain minimum fill of pacifier interval */ - Cdrfifo_next_interval(skin->fifo,&fill,0); - fifo_percent= 100.0*((double) fill)/buffer_size; - if(fifo_percent<100 && fill>0) - fifo_percent++; - } - if(skin->verbosity>=Cdrskin_verbose_debuG) { - Cdrfifo_get_counters(skin->fifo,&curr_fifo_in,&curr_fifo_out,0); - Cdrfifo_get_sizes(skin->fifo,&bs,&fs,0); - } - } - if(skin->fifo_size>0) { - sprintf(fifo_text,"(fifo %3d%%) ",fifo_percent); - if(skin->verbosity>=Cdrskin_verbose_debuG) { - fprintf(stderr, - "\ncdrskin_debug: fifo >= %9d / %d : %8.f in, %8.f out\n", - fill,space+fill, - curr_fifo_in-last_fifo_in,curr_fifo_out-last_fifo_out); - last_fifo_in= curr_fifo_in; - last_fifo_out= curr_fifo_out; - } - } - if(skin->supposed_track_idx >= 0 && - skin->supposed_track_idx < skin->track_counter) { - /* fixed_size,padding are fetched above via Cdrtrack_get_size() */; - } else if(skin->fixed_size!=0) { - fixed_size= skin->fixed_size; - padding= skin->padding; - } - if(fixed_size) { - sprintf(mb_text,"%4d of %4d", - (int) (written_total_bytes/1024.0/1024.0), - (int) ((fixed_size+padding)/1024.0/1024.0)); - } else - sprintf(mb_text,"%4d",(int) (written_total_bytes/1024.0/1024.0)); - speed_factor= Cdrskin_cd_speed_factoR*sector_size/2048; - - buffer_fill= 50; -#ifdef Cdrskin_libburn_has_buffer_progresS - if(p->buffer_capacity>0) - buffer_fill= (double) (p->buffer_capacity - p->buffer_available)*100.0 - / (double) p->buffer_capacity; - -#endif /* Cdrskin_libburn_has_buffer_progresS */ - if(buffer_fill<*min_buffer_fill) - *min_buffer_fill= buffer_fill; - - printf("\r%sTrack %-2.2d: %s MB written %s[buf %3d%%] %4.1fx.", - debug_mark,skin->supposed_track_idx+1,mb_text,fifo_text, - buffer_fill,measured_speed/speed_factor); - fflush(stdout); - } - if(skin->is_writing==0) { - printf("\n"); - goto thank_you_for_patience; - } - } - -#else /* ! Cdrskin_extra_leaN */ - - if(skin->supposed_track_idx<0) - skin->supposed_track_idx= 0; - if(written_bytes<=0.0 && written_total_bytes>=skin->fixed_size && - skin->fixed_size>0) { - if(!skin->is_writing) - goto thank_you_for_patience; - skin->is_writing= 0; - } else { - if(!skin->is_writing) - printf("\n"); - skin->is_writing= 1; - } - printf("\rTrack %-2.2d: %3d MB written ", - skin->supposed_track_idx+1,(int) (written_total_bytes/1024.0/1024.0)); - fflush(stdout); - if(skin->is_writing==0) - printf("\n"); - -#endif /* Cdrskin_extra_leaN */ - - - advance_interval= 1; - ret= 1; -ex:; - if(advance_interval) { - if(written_total_bytes>0) - *last_count= written_total_bytes; - else - *last_count= 0.0; - if(*last_count>*total_count) - *total_count= *last_count; - *last_time= current_time; - } - skin->previous_drive_status= drive_status; - return(ret); -} - - -/** Determines the effective write mode and checks wether the drive promises - to support it. - @param s state of target media, obtained from burn_disc_get_status(), - submit BURN_DISC_BLANK if no real state is available -*/ -int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s, - int flag) -{ - int ok; - struct burn_drive_info *drive_info; - - if(strcmp(skin->preskin->write_mode_name,"DEFAULT")==0) { - -#ifdef Cdrskin_allow_libburn_taO - if(s == BURN_DISC_APPENDABLE) - strcpy(skin->preskin->write_mode_name,"TAO"); - else -#endif - - strcpy(skin->preskin->write_mode_name,"SAO"); - } - if(strcmp(skin->preskin->write_mode_name,"RAW/RAW96R")==0) { - skin->write_type= BURN_WRITE_RAW; - skin->block_type= BURN_BLOCK_RAW96R; - -#ifdef Cdrskin_allow_libburn_taO - } else if(strcmp(skin->preskin->write_mode_name,"TAO")==0) { - strcpy(skin->preskin->write_mode_name,"TAO"); - skin->write_type= BURN_WRITE_TAO; - skin->block_type= BURN_BLOCK_MODE1; -#endif /* Cdrskin_allow_libburn_taO */ - - } else { - strcpy(skin->preskin->write_mode_name,"SAO"); - skin->write_type= BURN_WRITE_SAO; - skin->block_type= BURN_BLOCK_SAO; - } - - /* check wether desired type combination is available with drive */ - if(skin->driveno<0 || skin->driveno>skin->n_drives) { - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(printf("cdrskin_debug: WARNING : No drive selected with Cdrskin_activate_write_mode\n")); - goto it_is_done; - } - - drive_info= skin->drives+skin->driveno; - ok= 0; - if(skin->write_type==BURN_WRITE_RAW) - ok= !!(drive_info->raw_block_types & BURN_BLOCK_RAW96R); - else if(skin->write_type==BURN_WRITE_SAO) - ok= !!(drive_info->sao_block_types & BURN_BLOCK_SAO); - else if(skin->write_type==BURN_WRITE_TAO) - ok= ((drive_info->tao_block_types & (BURN_BLOCK_MODE1|BURN_BLOCK_RAW0)) - == (BURN_BLOCK_MODE1|BURN_BLOCK_RAW0)); - if(!ok) { - if(! skin->force_is_set) { - - /* >>> if write mode was not set explicitely: try to find a better one */; - - } - fprintf(stderr, - "cdrskin: %s : Drive indicated refusal for write mode %s.\n", - (skin->force_is_set?"WARNING":"FATAL"), - skin->preskin->write_mode_name); - if(! skin->force_is_set) { - fprintf(stderr,"cdrskin: HINT : If you are certain that the drive will do, try option -force\n"); - return(0); - } - } -it_is_done:; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: write type : %s\n", skin->preskin->write_mode_name); - return(1); -} - - -/** Burn data via libburn according to the parameters set in skin. - @return <=0 error, 1 success -*/ -int Cdrskin_burn(struct CdrskiN *skin, int flag) -{ - struct burn_disc *disc; - struct burn_session *session; - struct burn_write_opts *o; - enum burn_disc_status s; - enum burn_drive_status drive_status; - struct burn_progress p; - struct burn_drive *drive; - int ret,loop_counter= 0,max_track= -1,i,hflag,nwa; - int fifo_disabled= 0,fifo_percent,total_min_fill,mb,min_buffer_fill= 101; - double put_counter,get_counter,empty_counter,full_counter; - double start_time,last_time; - double total_count= 0.0,last_count= 0.0,size,padding,sector_size= 2048.0; - double sectors; - - printf("cdrskin: beginning to burn disk\n"); - - disc= burn_disc_create(); - session= burn_session_create(); - ret= burn_disc_add_session(disc,session,BURN_POS_END); - if(ret==0) { - fprintf(stderr,"cdrskin: FATAL : cannot add session to disc object.\n"); - return(0); - } - - skin->fixed_size= 0.0; - for(i=0;itrack_counter;i++) { - hflag= (skin->verbosity>=Cdrskin_verbose_debuG); - if(i==skin->track_counter-1) - Cdrtrack_ensure_padding(skin->tracklist[i],hflag&1); - ret= Cdrtrack_add_to_session(skin->tracklist[i],i,session,hflag); - if(ret<=0) { - fprintf(stderr,"cdrskin: FATAL : cannot add track %d to session.\n",i+1); - return(0); - } - Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size,0); - if(size>0) - skin->fixed_size+= size+padding; - } - - ret= Cdrskin_grab_drive(skin,0); - if(ret<=0) - return(ret); - drive= skin->drives[skin->driveno].drive; - - while(burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE) - usleep(100002); /* >>> ??? add a timeout ? */ - - while((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(100002); /* >>> ??? add a timeout ? */ - - if(skin->verbosity>=Cdrskin_verbose_progresS) - Cdrskin_report_disc_status(skin,s,0); - - ret= Cdrskin_activate_write_mode(skin,s,0); - if(ret<=0) { - fprintf(stderr, - "cdrskin: FATAL : Cannot activate the desired write mode\n"); - ret= 0; goto ex; - } - -#ifdef Cdrskin_libburn_has_multI - if (s == BURN_DISC_APPENDABLE) { - -#ifdef Cdrskin_allow_sao_for_appendablE - ; -#else - if(skin->write_type!=BURN_WRITE_TAO) { - Cdrskin_release_drive(skin,0); - fprintf(stderr,"cdrskin: FATAL : For now only write mode -tao can be used with appendable disks\n"); - return(0); - } -#endif /* ! Cdrskin_allow_sao_for_appendablE */ - - } else if (s != BURN_DISC_BLANK) { -#else - if (s != BURN_DISC_BLANK) { -#endif - Cdrskin_release_drive(skin,0); - fprintf(stderr,"cdrskin: FATAL : no blank media detected.\n"); - return(0); - } - - -#ifndef Cdrskin_extra_leaN - - if(skin->verbosity>=Cdrskin_verbose_progresS) { - for(i=0;itrack_counter;i++) { - Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size,0); - if(size<=0) { - printf("Track %-2.2d: data unknown length",i+1); - } else { - mb= size/1024.0/1024.0; - printf("Track %-2.2d: data %5d MB ",i+1,mb); - } - if(padding>0) - printf(" padsize: %.f KB\n",padding/1024.0); - else - printf("\n"); - } - if(skin->fixed_size<=0) { - printf("Total size: 0 MB (00:00.00) = 0 sectors\n"); - printf("Lout start: 0 MB (00:02/00) = 0 sectors\n"); - } else { - /* >>> This is quite a fake. Need to learn about 12:35.25 and "Lout" - ??? Is there a way to obtain the toc in advance (print_cue()) ? */ - double seconds; - int min,sec,frac; - - mb= skin->fixed_size/1024.0/1024.0; - seconds= skin->fixed_size/150.0/1024.0+2.0; - min= seconds/60.0; - sec= seconds-min*60; - frac= (seconds-min*60-sec)*100; - if(frac>99) - frac= 99; - sectors= (int) (skin->fixed_size/sector_size); - if(sectors*sector_size != skin->fixed_size) - sectors++; - printf("Total size: %5d MB (%-2.2d:%-2.2d.%-2.2d) = %d sectors\n", - mb,min,sec,frac,(int) sectors); - seconds+= 2; - min= seconds/60.0; - sec= seconds-min*60; - frac= (seconds-min*60-sec)*100; - if(frac>99) - frac= 99; - printf("Lout start: %5d MB (%-2.2d:%-2.2d/%-2.2d) = %d sectors\n", - mb,min,sec,frac,(int) sectors); - } - } - - Cdrskin_wait_before_action(skin,0); - ret= Cdrskin_fill_fifo(skin,0); - if(ret<=0) { - fprintf(stderr,"cdrskin: FATAL : filling of fifo failed\n"); - goto ex; - } - -#endif /* ! Cdrskin_extra_leaN */ - - - o= burn_write_opts_new(drive); - burn_write_opts_set_perform_opc(o, 0); - -#ifdef Cdrskin_libburn_has_multI - if(skin->multi) - fprintf(stderr, - "cdrskin: NOTE : Option -multi set. Media will be appendable.\n"); - burn_write_opts_set_multi(o,skin->multi); -#endif - - burn_write_opts_set_write_type(o,skin->write_type,skin->block_type); - if(skin->dummy_mode) { - fprintf(stderr, - "cdrskin: NOTE : -dummy mode will prevent actual writing\n"); - burn_write_opts_set_simulate(o, 1); - } - burn_write_opts_set_underrun_proof(o,skin->burnfree); - - Cdrskin_adjust_speed(skin,0); - if(skin->verbosity>=Cdrskin_verbose_progresS) { - ret= Cdrskin_obtain_nwa(skin, &nwa,0); - if(ret>0) - printf("Starting new track at sector: %d\n",nwa); - } - skin->drive_is_busy= 1; - burn_disc_write(o, disc); - if(skin->preskin->abort_handler==-1) - Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,4); - last_time= start_time= Sfile_microtime(0); - - burn_write_opts_free(o); - - while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) { - - /* >>> how do i learn about success or failure ? */ - - ; - } - loop_counter= 0; - while (1) { - drive_status= burn_drive_get_status(drive, &p); - if(drive_status==BURN_DRIVE_IDLE) - break; - - /* >>> how do i learn about success or failure ? */ - - if(loop_counter>0) - Cdrskin_burn_pacifier(skin,drive_status,&p,start_time,&last_time, - &total_count,&last_count,&min_buffer_fill,0); - - - /* <<< debugging : artificial abort without a previous signal */; - if(skin->abort_after_bytecount>=0.0 && - total_count>=skin->abort_after_bytecount) { - /* whatever signal handling is installed: this thread is the boss now */ - fprintf(stderr, - "cdrskin: DEVELOPMENT : synthetic abort by abort_after_bytecount=%.f\n", - skin->abort_after_bytecount); - skin->control_pid= getpid(); - ret= Cdrskin_abort_handler(skin,0,0); - fprintf(stderr,"cdrskin: done (aborted)\n"); - exit(1); - } - - - if(max_tracksupposed_track_idx) - max_track= skin->supposed_track_idx; - -#ifndef Cdrskin_extra_leaN - if(skin->fifo==NULL || fifo_disabled) { - usleep(20000); - } else { - ret= Cdrfifo_try_to_work(skin->fifo,20000,NULL,NULL,0); - if(ret<0) { - int abh; - - abh= skin->preskin->abort_handler; - if(abh!=2) - fprintf(stderr, - "\ncdrskin: FATAL : fifo encountered error during burn loop.\n"); - if(abh==0) { - ret= -1; goto ex; - } else if(abh==1 || abh==3 || abh==4 || abh==-1) { - Cdrskin_abort_handler(skin,0,0); - fprintf(stderr,"cdrskin: done (aborted)\n"); - exit(10); - } else { - if(skin->verbosity>=Cdrskin_verbose_debuG) - fprintf(stderr, - "\ncdrskin_debug: Cdrfifo_try_to_work() returns %d\n",ret); - } - } - if(ret==2) { /* <0 = error , 2 = work is done */ - if(skin->verbosity>=Cdrskin_verbose_debuG) - fprintf(stderr,"\ncdrskin_debug: fifo ended work with ret=%d\n",ret); - fifo_disabled= 1; - } - } -#else /* ! Cdrskin_extra_leaN */ - usleep(20000); -#endif /* Cdrskin_extra_leaN */ - - loop_counter++; - } - skin->drive_is_busy= 0; - if(skin->verbosity>=Cdrskin_verbose_progresS) - printf("\n"); - if(max_track<0) { - printf("Track 01: Total bytes read/written: %.f/%.f (%.f sectors).\n", - total_count,total_count,total_count/sector_size); - } else { - Cdrtrack_get_size(skin->tracklist[max_track],&size,&padding,§or_size,1); - printf( - "Track %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n", - max_track+1,size,size+padding,(size+padding)/sector_size); - } - if(skin->verbosity>=Cdrskin_verbose_progresS) - printf("Writing time: %.3fs\n",Sfile_microtime(0)-start_time); - - -#ifndef Cdrskin_extra_leaN - - if(skin->fifo!=NULL && skin->fifo_size>0) { - int dummy,final_fill; - Cdrfifo_get_buffer_state(skin->fifo,&final_fill,&dummy,0); - if(final_fill>0) { -fifo_full_at_end:; - fprintf(stderr, - "cdrskin: FATAL : Fifo still contains data after burning has ended.\n"); - fprintf(stderr, - "cdrskin: FATAL : %.d bytes left.\n",final_fill); - fprintf(stderr, - "cdrskin: FATAL : This indicates an overflow of the last track.\n"); - fprintf(stderr, - "cdrskin: NOTE : The media might appear ok but is probably truncated.\n"); - ret= -1; goto ex; - } - -#ifdef Cdrskin_libburn_leaves_inlet_opeN - for(i= 0;itrack_counter;i++) { - ret= Cdrtrack_has_input_left(skin->tracklist[i],0); - if(ret>0) { - fprintf(stderr, - "cdrskin: FATAL : fifo outlet of track #%d is still buffering some bytes.\n", - i+1); - goto fifo_full_at_end; - } - } -#endif /* Cdrskin_libburn_leaves_inlet_opeN */ - - } - - if(skin->verbosity>=Cdrskin_verbose_progresS) { - if(skin->fifo!=NULL && skin->fifo_size>0) { - int dummy; - - Cdrfifo_get_min_fill(skin->fifo,&total_min_fill,&dummy,0); - fifo_percent= 100.0*((double) total_min_fill)/(double) skin->fifo_size; - if(fifo_percent==0 && total_min_fill>0) - fifo_percent= 1; - Cdrfifo_get_cdr_counters(skin->fifo,&put_counter,&get_counter, - &empty_counter,&full_counter,0); - fflush(stdout); - fprintf(stderr,"Cdrskin: fifo had %.f puts and %.f gets.\n", - put_counter,get_counter); - fprintf(stderr, - "Cdrskin: fifo was %.f times empty and %.f times full, min fill was %d%%.\n", - empty_counter,full_counter,fifo_percent); - } - if(min_buffer_fill>100) - min_buffer_fill= 50; - printf("Min drive buffer fill was %d%%\n", min_buffer_fill); - } - -#endif /* ! Cdrskin_extra_leaN */ - - - if(skin->verbosity>=Cdrskin_verbose_progresS) - printf("cdrskin: burning done\n"); - ret= 1; -ex:; - skin->drive_is_busy= 0; - if(skin->verbosity>=Cdrskin_verbose_debuG) - ClN(printf("cdrskin_debug: do_eject= %d\n",skin->do_eject)); - Cdrskin_release_drive(skin,0); - for(i= 0;itrack_counter;i++) - Cdrtrack_cleanup(skin->tracklist[i],0); - burn_session_free(session); - burn_disc_free(disc); - return(ret); -} - - -/** Work around the failure of libburn to eject the tray. - This employs a system(2) call and is therefore an absolute no-no for any - pseudo user identities. - @return <=0 error, 1 success -*/ -int Cdrskin_eject(struct CdrskiN *skin, int flag) -{ - -#ifndef Cdrskin_burn_drive_eject_brokeN - -#ifndef Cdrskin_oldfashioned_api_usE - int i,ret,max_try= 5; - - if(!skin->do_eject) - return(1); - - /* A60923 : - Still not in libburn-0.2.2 : prevent SIGSEV on non-existent drive */ - if(skin->n_drives<=skin->driveno || skin->driveno < 0) - return(2); - - /* <<< A61012 : retry loop might now be obsolete - (a matching bug in burn_disc_write_sync() was removed ) */ - for(i= 0;i0 || i>=max_try-1) - break; - if(skin->verbosity>=Cdrskin_verbose_progresS) - fprintf(stderr, - "cdrskin: NOTE : Attempt #%d of %d failed to grab drive for eject\n", - i+1,max_try); - usleep(1000000); - } - if(ret>0) { - ret= Cdrskin_release_drive(skin,1); - if(ret<=0) - goto sorry_failed_to_eject; - } else { -sorry_failed_to_eject:; - fprintf(stderr,"cdrskin: SORRY : Failed to finally eject tray.\n"); - return(0); - } - return(1); - -#else - - if(!skin->do_eject) - return(1); - if(Cdrskin_grab_drive(skin,2)>0) { - Cdrskin_release_drive(skin,1); - } else { - fprintf(stderr,"cdrskin: SORRY : Failed to finally eject tray.\n"); - return(0); - } - return(1); - -#endif - -#else /* Cdrskin_burn_drive_eject_brokeN */ - - int ret; - char adr[Cdrskin_adrleN]; - char cmd[5*Cdrskin_strleN+16],shellsafe[5*Cdrskin_strleN+2]; - - if(!skin->do_eject) - return(1); - if(skin->verbosity>=Cdrskin_verbose_progresS) - printf("cdrskin: trying to eject media\n"); - if(getuid()!=geteuid()) { - fprintf(stderr, - "cdrskin: SORRY : uid and euid differ. Will not start external eject.\n"); - fprintf(stderr, - "cdrskin: HINT : Consider to allow rw-access to the writer device and\n"); - fprintf(stderr, - "cdrskin: HINT : to run cdrskin under your normal user identity.\n"); - return(0); - } - -#ifdef Cdrskin_libburn_has_drive_get_adR - ret= burn_drive_get_adr(&(skin->drives[skin->driveno]), adr); - if(ret<=0) - adr[0]= 0; -#else - strcpy(adr,skin->drives[skin->driveno].location); -#endif - - if(strlen(skin->eject_device)>0) - sprintf(cmd,"eject %s",Text_shellsafe(skin->eject_device,shellsafe,0)); - else if(strcmp(adr,"/dev/sg0")==0) - sprintf(cmd,"eject /dev/sr0"); - else - sprintf(cmd,"eject %s",Text_shellsafe(adr,shellsafe,0)); - ret= system(cmd); - if(ret==0) - return(1); - return(0); - -#endif /* Cdrskin_burn_drive_eject_brokeN */ - -} - - -/** Interpret all arguments of the program after libburn has been initialized - and drives have been scanned. This call reports to stderr any valid - cdrecord options which are not implemented yet. - @param flag Bitfield for control purposes: - bit0= do not finalize setup - bit1= do not interpret (again) skin->preskin->pre_argv - @return <=0 error, 1 success -*/ -int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag) -{ - int i,k,ret,source_has_size=0; - double value,grab_and_wait_value= -1.0; - char *cpt,*value_pt,adr[Cdrskin_adrleN]; - struct stat stbuf; - - /* cdrecord 2.01 options which are not scheduled for implementation, yet */ - static char ignored_partial_options[][41]= { - "timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=", - "pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=", - "pktsize=", "cuefile=", - "" - }; - static char ignored_full_options[][41]= { - "-d", "-Verbose", "-V", "-silent", "-s", "-setdropts", "-prcap", "-inq", - "-reset", "-abort", "-overburn", "-ignsize", "-useinfo", "-format", "-load", - "-lock", "-fix", "-nofix", "-waiti", - "-immed", "-raw", "-raw96p", "-raw16", - "-clone", "-text", "-mode2", "-xa", "-xa1", "-xa2", "-xamix", - "-cdi", "-isosize", "-preemp", "-nopreemp", "-copy", "-nocopy", - "-scms", "-shorttrack", "-noshorttrack", "-packet", "-noclose", - "" - }; - - /* are we pretending to be cdrecord ? */ - cpt= strrchr(argv[0],'/'); - if(cpt==NULL) - cpt= argv[0]; - else - cpt++; - if(strcmp(cpt,"cdrecord")==0 && !(flag&1)) { - fprintf(stderr,"\n"); - fprintf(stderr, - "Note: This is not cdrecord by Joerg Schilling. Do not bother him.\n"); - fprintf(stderr, - " See cdrskin start message on stdout. See --help. See -version.\n"); - fprintf(stderr,"\n"); - /* allow automatic -tao to -sao redirection */ - skin->tao_to_sao_tsize=650*1024*1024; - } - -#ifndef Cdrskin_extra_leaN - if(!(flag&2)) { - if(skin->preskin->pre_argc>1) { - ret= Cdrskin_setup(skin,skin->preskin->pre_argc,skin->preskin->pre_argv, - flag|1|2); - if(ret<=0) - return(ret); - } - } -#endif - - for (i= 1;iabort_after_bytecount); - - } else if(strcmp(argv[i],"--abort_handler")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strncmp(argv[i],"-abort_max_wait=",16)==0) { - value_pt= argv[i]+16; - goto set_abort_max_wait; - } else if(strncmp(argv[i],"abort_max_wait=",15)==0) { - value_pt= argv[i]+15; -set_abort_max_wait:; - value= Scanf_io_size(value_pt,0); - if(value<0 || value>86400) { - fprintf(stderr, - "cdrskin: NOTE : ignored out-of-range value: abort_max_wait=%s\n", - value_pt); - } else { - skin->abort_max_wait= value; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf( - "cdrskin: maximum waiting time with abort handling : %d seconds\n", - skin->abort_max_wait); - } - - } else if(strcmp(argv[i],"--allow_setuid")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--any_track")==0) { - skin->single_track= -1; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf( - "cdrskin: --any_track : will accept any unknown option as track source\n"); - - } else if(strcmp(argv[i],"-atip")==0) { - if(skin->do_atip<1) - skin->do_atip= 1; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: will put out some -atip style lines\n"); - - } else if(strcmp(argv[i],"-audio")==0) { - skin->track_type= BURN_AUDIO; - skin->track_type_by_default= 0; - - } else if(strncmp(argv[i],"-blank=",7)==0) { - cpt= argv[i]+7; - goto set_blank; - } else if(strncmp(argv[i],"blank=",6)==0) { - cpt= argv[i]+6; -set_blank:; - if(strcmp(cpt,"all")==0 || strcmp(cpt,"disc")==0 - || strcmp(cpt,"disk")==0) { - skin->do_blank= 1; - skin->blank_fast= 0; - } else if(strcmp(cpt,"fast")==0 || strcmp(cpt,"minimal")==0) { - skin->do_blank= 1; - skin->blank_fast= 1; - } else if(strcmp(cpt,"help")==0) { - /* is handled in Cdrpreskin_setup() */; - } else { - fprintf(stderr,"cdrskin: FATAL : blank option '%s' not supported yet\n", - cpt); - return(0); - } - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: blank mode : blank=%s\n", - (skin->blank_fast?"fast":"all")); - - } else if(strcmp(argv[i],"--bragg_with_audio")==0) { - /* OBSOLETE 0.2.3 : was handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-checkdrive")==0) { - skin->do_checkdrive= 1; - - } else if(strcmp(argv[i],"-data")==0) { - - /* >>> !!! All Subsequent Tracks Option */ - - skin->track_type= BURN_MODE1; - skin->track_type_by_default= 0; - - } else if(strcmp(argv[i],"--demand_a_drive")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--devices")==0) { - skin->do_devices= 1; - - -#ifndef Cdrskin_extra_leaN - - } else if(strncmp(argv[i],"dev_translation=",16)==0) { - - if(argv[i][16]==0) { - fprintf(stderr, - "cdrskin: FATAL : dev_translation= : missing separator character\n"); - return(0); - } - ret= Cdradrtrn_add(skin->adr_trn,argv[i]+17,argv[i]+16,1); - if(ret==-2) - fprintf(stderr, - "cdrskin: FATAL : address_translation= : cannot allocate memory\n"); - else if(ret==-1) - fprintf(stderr, - "cdrskin: FATAL : address_translation= : table full (%d items)\n", - Cdradrtrn_leN); - else if(ret==0) - fprintf(stderr, - "cdrskin: FATAL : address_translation= : no address separator '%c' found\n", - argv[i][17]); - if(ret<=0) - return(0); - -#endif /* Cdrskin_extra_leaN */ - - - } else if(strncmp(argv[i],"-dev=",5)==0) { - /* is handled in Cdrpreskin_setup() */; - } else if(strncmp(argv[i],"dev=",4)==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--drive_abort_on_busy")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--drive_blocking")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--drive_not_exclusive")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strncmp(argv[i],"-driveropts=",12)==0) { - value_pt= argv[i]+12; - goto set_driveropts; - } else if(strncmp(argv[i],"driveropts=",11)==0) { - value_pt= argv[i]+11; -set_driveropts:; - if(strcmp(value_pt,"burnfree")==0 || strcmp(value_pt,"burnproof")==0) { - skin->burnfree= 1; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: burnfree : on\n"); - } else if(strcmp(argv[i]+11,"noburnfree")==0 || - strcmp(argv[i]+11,"noburnproof")==0 ) { - skin->burnfree= 0; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: burnfree : off\n"); - } else if(strcmp(argv[i]+11,"help")==0) { - /* handled in Cdrpreskin_setup() */; - } else - goto ignore_unknown; - - } else if(strcmp(argv[i],"-dummy")==0) { - skin->dummy_mode= 1; - - } else if(strcmp(argv[i],"-eject")==0) { - skin->do_eject= 1; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: eject after work : on\n"); - - } else if(strncmp(argv[i],"eject_device=",13)==0) { - if(strlen(argv[i]+13)>=sizeof(skin->eject_device)) { - fprintf(stderr, - "cdrskin: FATAL : eject_device=... too long. (max: %d, given: %d)\n", - sizeof(skin->eject_device)-1,strlen(argv[i]+13)); - return(0); - } - strcpy(skin->eject_device,argv[i]+13); - if(skin->verbosity>=Cdrskin_verbose_cmD) -#ifdef Cdrskin_burn_drive_eject_brokeN - printf("cdrskin: eject_device : %s\n",skin->eject_device); -#else - printf("cdrskin: ignoring obsolete eject_device=%s\n", - skin->eject_device); -#endif - - -#ifndef Cdrskin_extra_leaN - - } else if(strcmp(argv[i],"--fifo_disable")==0) { - skin->fifo_enabled= 0; - skin->fifo_size= 0; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: option fs=... disabled\n"); - - } else if(strcmp(argv[i],"--fifo_start_empty")==0) { - skin->fifo_start_empty= 1; - - } else if(strcmp(argv[i],"--fifo_per_track")==0) { - skin->fifo_per_track= 1; - - } else if(strcmp(argv[i],"-force")==0) { - skin->force_is_set= 1; - - } else if(strncmp(argv[i],"-fs=",4)==0) { - value_pt= argv[i]+4; - goto fs_equals; - } else if(strncmp(argv[i],"fs=",3)==0) { - value_pt= argv[i]+3; -fs_equals:; - if(skin->fifo_enabled) { - value= Scanf_io_size(value_pt,0); - if(value<0.0 || value>1024.0*1024.0*1024.0) { - fprintf(stderr, - "cdrskin: FATAL : fs=N expects a size between 0 and 1g\n"); - return(0); - } - skin->fifo_size= value; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: fifo size : %d\n",skin->fifo_size); - } - - } else if(strncmp(argv[i],"grab_drive_and_wait=",20)==0) { - value_pt= argv[i]+20; - grab_and_wait_value= Scanf_io_size(value_pt,0); - - } else if(strncmp(argv[i],"-gracetime=",11)==0) { - value_pt= argv[i]+11; - goto gracetime_equals; - } else if(strncmp(argv[i],"gracetime=",10)==0) { - value_pt= argv[i]+10; -gracetime_equals:; - sscanf(value_pt,"%d",&(skin->gracetime)); - -#else /* ! Cdrskin_extra_leaN */ - - } else if( - strcmp(argv[i],"--fifo_disable")==0 || - strcmp(argv[i],"--fifo_start_empty")==0 || - strcmp(argv[i],"--fifo_per_track")==0 || - strncmp(argv[i],"-fs=",4)==0 || - strncmp(argv[i],"fs=",3)==0 || - strncmp(argv[i],"-gracetime=",11)==0 || - strncmp(argv[i],"gracetime=",10)==0) { - fprintf(stderr, - "cdrskin: NOTE : lean version ignores option: '%s'\n", - argv[i]); - -#endif /* Cdrskin_extra_leaN */ - - - } else if(strcmp(argv[i],"--help")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-help")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--ignore_signals")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-multi")==0) { -#ifdef Cdrskin_libburn_has_multI - skin->multi= 1; -#else - fprintf(stderr,"cdrskin: SORRY : Option -multi is not available yet.\n"); -#endif - - } else if(strcmp(argv[i],"-msinfo")==0) { -#ifdef Cdrskin_libburn_has_multI - skin->do_msinfo= 1; -#else - fprintf(stderr,"cdrskin: SORRY : Option -msinfo is not available yet.\n"); - return(0); -#endif - - } else if(strcmp(argv[i],"--no_abort_handler")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--no_blank_appendable")==0) { - skin->no_blank_appendable= 1; - - } else if(strcmp(argv[i],"--no_convert_fs_adr")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"--no_rc")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-nopad")==0) { - skin->padding= 0.0; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: padding : off\n"); - - } else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-pad")==0) { - skin->padding= 15*2048; - skin->set_by_padsize= 0; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: padding : %.f\n",skin->padding); - - } else if(strncmp(argv[i],"-padsize=",9)==0) { - value_pt= argv[i]+9; - goto set_padsize; - } else if(strncmp(argv[i],"padsize=",8)==0) { - value_pt= argv[i]+8; -set_padsize:; - skin->padding= Scanf_io_size(argv[i]+8,0); - skin->set_by_padsize= 1; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: padding : %.f\n",skin->padding); - - } else if(strcmp(argv[i],"-raw96r")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-sao")==0 || strcmp(argv[i],"-dao")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if(strcmp(argv[i],"-scanbus")==0) { - skin->do_scanbus= 1; - - } else if(strcmp(argv[i],"--single_track")==0) { - skin->single_track= 1; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf( - "cdrskin: --single_track : will only accept last argument as track source\n"); - - } else if(strncmp(argv[i],"-speed=",7)==0) { - value_pt= argv[i]+7; - goto set_speed; - } else if(strncmp(argv[i],"speed=",6)==0) { - value_pt= argv[i]+6; -set_speed:; - sscanf(value_pt,"%lf",&(skin->x_speed)); - if(skin->x_speed<1.0 && skin->x_speed!=0.0 && skin->x_speed!=-1) { - fprintf(stderr,"cdrskin: FATAL : speed= must be -1, 0 or at least 1\n"); - return(0); - } - - /* >>> cdrecord speed=0 -> minimum speed , libburn -> maximum speed */; - - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: speed : %f\n",skin->x_speed); - - } else if(strcmp(argv[i],"-swab")==0) { - skin->swap_audio_bytes= 0; - - } else if(strcmp(argv[i],"-tao")==0) { - /* is partly handled in Cdrpreskin_setup() */; - -#ifndef Cdrskin_allow_libburn_taO - - if(skin->tao_to_sao_tsize<=0.0) { - fprintf(stderr,"cdrskin: FATAL : libburn does not support -tao yet.\n"); - fprintf(stderr,"cdrskin: HINT : Try option tao_to_sao_tsize=650m\n"); - return(0); - } - printf("cdrskin: NOTE : substituting mode -tao by mode -sao\n"); - strcpy(skin->preskin->write_mode_name,"SAO"); - -#endif /* ! Cdrskin_allow_libburn_taO */ - - } else if(strncmp(argv[i],"tao_to_sao_tsize=",17)==0) { - skin->tao_to_sao_tsize= Scanf_io_size(argv[i]+17,0); - if(skin->tao_to_sao_tsize>Cdrskin_tracksize_maX) - goto track_too_large; - if(skin->verbosity>=Cdrskin_verbose_cmD) -#ifdef Cdrskin_allow_libburn_taO - printf("cdrskin: size default for non-tao write modes: %.f\n", -#else - printf("cdrskin: replace -tao by -sao with fixed size : %.f\n", -#endif - skin->tao_to_sao_tsize); - - } else if(strcmp(argv[i],"-toc")==0) { - skin->do_atip= 2; - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: will put out some -atip style lines plus -toc\n"); - - } else if(strncmp(argv[i],"-tsize=",7)==0) { - value_pt= argv[i]+7; - goto set_tsize; - } else if(strncmp(argv[i],"tsize=",6)==0) { - value_pt= argv[i]+6; -set_tsize:; - skin->fixed_size= Scanf_io_size(value_pt,0); - if(skin->fixed_size>Cdrskin_tracksize_maX) { -track_too_large:; - fprintf(stderr,"cdrskin: FATAL : track size too large\n"); - return(0); - } - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: fixed track size : %.f\n",skin->fixed_size); - - } else if(strcmp(argv[i],"-v")==0 || strcmp(argv[i],"-verbose")==0) { - /* is handled in Cdrpreskin_setup() */; - - } else if( i==argc-1 || - (skin->single_track==0 && strchr(argv[i],'=')==NULL - && !(argv[i][0]=='-' && argv[i][1]!=0) ) || - (skin->single_track==-1)) { - if(strlen(argv[i])>=sizeof(skin->source_path)) { - fprintf(stderr, - "cdrskin: FATAL : source_address too long. (max: %d, given: %d)\n", - sizeof(skin->source_path)-1,strlen(argv[i])); - return(0); - } - source_has_size= 0; - strcpy(skin->source_path,argv[i]); - if(strcmp(skin->source_path,"-")==0) { - if(skin->stdin_source_used) { - fprintf(stderr, - "cdrskin: FATAL : \"-\" (stdin) can be used as track source only once.\n"); - return(0); - } - skin->stdin_source_used= 1; - } else if(argv[i][0]=='#' && (argv[i][1]>='0' && argv[i][1]<='9')) { - if(skin->preskin->allow_fd_source==0) { - fprintf(stderr, - "cdrskin: SORRY : '%s' is a reserved source path with cdrskin\n", - argv[i]); - fprintf(stderr, - "cdrskin: SORRY : which would use an open file descriptor as source.\n"); - fprintf(stderr, - "cdrskin: SORRY : Its usage is dangerous and disabled for now.\n"); - return(0); - } - } else { - if(stat(skin->source_path,&stbuf)!=-1) { - if((stbuf.st_mode&S_IFMT)==S_IFREG) - source_has_size= 1; - else if((stbuf.st_mode&S_IFMT)==S_IFDIR) { - fprintf(stderr, - "cdrskin: FATAL : source address is a directory: '%s'\n", - skin->source_path); - return(0); - } - } - } - if(! source_has_size) { - if(skin->fixed_size<=0.0) { - if(strcmp(skin->preskin->write_mode_name,"TAO")==0) { - /* with TAO it is ok to have an undefined track length */; - -#ifdef Cdrskin_allow_libburn_taO - } else if(strcmp(skin->preskin->write_mode_name,"DEFAULT")==0) { - strcpy(skin->preskin->write_mode_name,"TAO"); -#endif - - } else if(skin->tao_to_sao_tsize>0.0) { - skin->fixed_size= skin->tao_to_sao_tsize; - printf( - "cdrskin: NOTE : augmenting non-tao write mode by tao_to_sao_tsize\n"); - printf("cdrskin: NOTE : fixed size : %.f\n",skin->fixed_size); - } else { - fprintf(stderr, -#ifdef Cdrskin_allow_libburn_taO - "cdrskin: FATAL : Track source '%s' needs -tao or tsize= or tao_to_sao_tsize=\n", -#else - "cdrskin: FATAL : Track source '%s' needs a fixed tsize= or tao_to_sao_tsize=\n", -#endif - skin->source_path); - return(0); - } - } - } - if(skin->track_counter>=Cdrskin_track_maX) { - fprintf(stderr,"cdrskin: FATAL : too many tracks given. (max %d)\n", - Cdrskin_track_maX); - return(0); - } - ret= Cdrtrack_new(&(skin->tracklist[skin->track_counter]),skin, - skin->track_counter, - (strcmp(skin->source_path,"-")==0)<<1); - if(ret<=0) { - fprintf(stderr, - "cdrskin: FATAL : creation of track control object failed.\n"); - return(ret); - } - skin->track_counter++; - if(skin->verbosity>=Cdrskin_verbose_cmD) { - if(strcmp(skin->source_path,"-")==0) - printf("cdrskin: track %d data source : '-' (i.e. standard input)\n", - skin->track_counter); - else - printf("cdrskin: track %d data source : '%s'\n", - skin->track_counter,skin->source_path); - } - /* reset track options */ - if(skin->set_by_padsize) - skin->padding= 0; /* cdrecord-ProDVD-2.01b31 resets to 30k - the man page says padsize= is reset to 0 - Joerg Schilling will change in 2.01.01 to 0 */ - skin->fixed_size= 0; - } else { -ignore_unknown:; - fprintf(stderr,"cdrskin: NOTE : ignoring unknown option : '%s'\n", - argv[i]); - } - } - - if(flag&1) /* no finalizing yet */ - return(1); - - if(skin->verbosity>=Cdrskin_verbose_cmD) { - if(skin->preskin->abort_handler==1) - printf("cdrskin: installed abort handler.\n"); - else if(skin->preskin->abort_handler==2) - printf("cdrskin: will try to ignore any signals.\n"); - else if(skin->preskin->abort_handler==3) - printf("cdrskin: installed hard abort handler.\n"); - else if(skin->preskin->abort_handler==4) - printf("cdrskin: installed soft abort handler.\n"); - else if(skin->preskin->abort_handler==-1) - printf("cdrskin: will install abort handler in eventual burn loop.\n"); - } - - if(strlen(skin->preskin->raw_device_adr)>0 || - strlen(skin->preskin->device_adr)>0) { - if(strlen(skin->preskin->device_adr)>0) - cpt= skin->preskin->device_adr; - else - cpt= skin->preskin->raw_device_adr; - if(strcmp(cpt,"ATA")!=0 && strcmp(cpt,"ATAPI")!=0 && strcmp(cpt,"SCSI")!=0){ - ret= Cdrskin_dev_to_driveno(skin,cpt,&(skin->driveno),0); - if(ret<=0) - return(ret); - if(skin->verbosity>=Cdrskin_verbose_cmD) { - -#ifdef Cdrskin_libburn_has_drive_get_adR - ret= burn_drive_get_adr(&(skin->drives[skin->driveno]), adr); - if(ret<=0) - adr[0]= 0; -#else - strcpy(adr,skin->drives[skin->driveno].location); -#endif - - printf("cdrskin: active drive number : %d '%s'\n", - skin->driveno,adr); - } - } - } - if(grab_and_wait_value>0) { - Cdrskin_grab_drive(skin,0); - for(k= 0; ktrack_counter>0) { - skin->do_burn= 1; - -#ifndef Cdrskin_extra_leaN - ret= Cdrskin_attach_fifo(skin,0); - if(ret<=0) - return(ret); -#endif /* ! Cdrskin_extra_leaN */ - - } - return(1); -} - - -/** Initialize libburn, create a CdrskiN program run control object, - set eventual device whitelist, and obtain the list of available drives. - @param o Returns the CdrskiN object created - @param lib_initialized Returns wether libburn was initialized here - @param exit_value Returns after error the proposal for an exit value - @param flag Unused yet - @return <=0 error, 1 success -*/ -int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin, - int *exit_value, int flag) -{ - int ret; - struct CdrskiN *skin; - - *o= NULL; - *exit_value= 0; - -#ifndef Cdrskin_libburn_no_burn_preset_device_opeN - burn_preset_device_open((*preskin)->drive_exclusive, - (*preskin)->drive_blocking, - (*preskin)->abort_on_busy_drive); -#endif - - if(strlen((*preskin)->device_adr)>0) { /* disable scan for all others */ - printf("cdrskin: NOTE : greying out all drives besides given dev='%s'\n", - (*preskin)->device_adr); - burn_drive_add_whitelist((*preskin)->device_adr); - } - - ret= Cdrskin_new(&skin,*preskin,1); - if(ret<=0) { - fprintf(stderr,"cdrskin: FATAL : creation of control object failed\n"); - {*exit_value= 2; goto ex;} - } - *preskin= NULL; /* the preskin object now is under management of skin */ - *o= skin; - if(skin->preskin->abort_handler==1 || skin->preskin->abort_handler==3 || - skin->preskin->abort_handler==4) - Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,4); - else if(skin->preskin->abort_handler==2) - Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,2|8); - - printf("cdrskin: scanning for devices ...\n"); - fflush(stdout); - - /* In cdrskin there is not much sense in queueing library messages. - It is done here only for debugging */ - Cdrpreskin_queue_msgs(skin->preskin,1); - - while (!burn_drive_scan(&(skin->drives), &(skin->n_drives))) { - usleep(20000); - /* >>> ??? set a timeout ? */ - } - - /* This prints the eventual queued messages */ - Cdrpreskin_queue_msgs(skin->preskin,0); - - printf("cdrskin: ... scanning for devices done\n"); - fflush(stdout); -ex:; - return((*exit_value)==0); -} - - -/** Perform the activities which were ordered by setup - @param skin Knows what to do - @param exit_value Returns the proposal for an exit value - @param flag Unused yet - @return <=0 error, 1 success -*/ -int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag) -{ - int ret; - - *exit_value= 0; - if(skin->do_devices) { - if(skin->n_drives<=0 && skin->preskin->scan_demands_drive) - {*exit_value= 4; goto no_drive;} - ret= Cdrskin_scanbus(skin,1); - if(ret<=0) { - fprintf(stderr,"cdrskin: FATAL : --devices failed.\n"); - {*exit_value= 4; goto ex;} - } - } - if(skin->do_scanbus) { - if(skin->n_drives<=0 && skin->preskin->scan_demands_drive) - {*exit_value= 5; goto no_drive;} - ret= Cdrskin_scanbus(skin,0); - if(ret<=0) - fprintf(stderr,"cdrskin: FATAL : -scanbus failed.\n"); - {*exit_value= 5*(ret<=0); goto ex;} - } - if(skin->do_checkdrive) { - ret= Cdrskin_checkdrive(skin,0); - {*exit_value= 6*(ret<=0); goto ex;} - } - if(skin->do_msinfo) { - if(skin->n_drives<=0) - {*exit_value= 12; goto no_drive;} - ret= Cdrskin_msinfo(skin,0); - if(ret<=0) - {*exit_value= 12; goto ex;} - } - if(skin->do_atip) { - if(skin->n_drives<=0) - {*exit_value= 7; goto no_drive;} - ret= Cdrskin_atip(skin,(skin->do_atip>1)); - if(ret<=0) - {*exit_value= 7; goto ex;} - } - if(skin->do_blank) { - if(skin->n_drives<=0) - {*exit_value= 8; goto no_drive;} - ret= Cdrskin_blank(skin,0); - if(ret<=0) - {*exit_value= 8; goto ex;} - } - if(skin->do_burn) { - if(skin->n_drives<=0) - {*exit_value= 10; goto no_drive;} - ret= Cdrskin_burn(skin,0); - if(ret<=0) - {*exit_value= 10; goto ex;} - } -ex:; - return((*exit_value)==0); -no_drive:; - fprintf(stderr,"cdrskin: FATAL : This run would need an accessible drive\n"); - goto ex; -} - - -int main(int argc, char **argv) -{ - int ret,exit_value= 0,lib_initialized= 0,i,result_fd= -1; - struct CdrpreskiN *preskin= NULL; - struct CdrskiN *skin= NULL; - char *lean_id= ""; -#ifdef Cdrskin_extra_leaN - lean_id= ".lean"; -#endif - - /* For -msinfo: Redirect normal stdout to stderr */ - for(i=1; in_drives<=0) { - fprintf(stderr,"cdrskin: NOTE : No usable drive detected.\n"); - if(getuid()!=0) { - fprintf(stderr, - "cdrskin: HINT : Run this program as superuser with option --devices\n"); - fprintf(stderr, - "cdrskin: HINT : Allow rw-access to the dev='...' file of the burner.\n"); - fprintf(stderr, - "cdrskin: HINT : Busy drives are invisible. (Busy = open O_EXCL)\n"); - } - } - Cdrskin_set_msinfo_fd(skin,result_fd,0); - - ret= Cdrskin_setup(skin,argc,argv,0); - if(ret<=0) - {exit_value= 3; goto ex;} - if(skin->verbosity>=Cdrskin_verbose_cmD) - printf("cdrskin: called as : %s\n",argv[0]); - - if(skin->verbosity>=Cdrskin_verbose_debuG) { -#ifdef Cdrskin_oldfashioned_api_usE - ClN(fprintf(stderr,"cdrskin_debug: Compiled with option -oldfashioned\n")); -#endif -#ifdef Cdrskin_new_api_tesT - ClN(fprintf(stderr,"cdrskin_debug: Compiled with option -experimental\n")); -#endif - } - - Cdrskin_run(skin,&exit_value,0); - -ex:; - if(skin!=NULL) { - Cleanup_set_handlers(NULL,NULL,1); - Cdrskin_eject(skin,0); - Cdrskin_destroy(&skin,0); - } - Cdrpreskin_destroy(&preskin,0); - if(lib_initialized) - burn_finish(); - exit(exit_value); -} diff --git a/cdrskin/cdrskin_eng.html b/cdrskin/cdrskin_eng.html deleted file mode 100644 index 8c0f265..0000000 --- a/cdrskin/cdrskin_eng.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - - - -cdrskin homepage english - - - - - -
-

Homepage of


cdrskin


- - -

Limited cdrecord compatibility wrapper for libburn

-
- -

-

Purpose:

-
    -
  • Burns preformatted data to CD-R or CD-RW
  • -
-

-

- -


- -

-

Hardware requirements:

-A CD recorder suitable for -libburn.pykix.org -(SCSI or IDE/ATAPI writers compliant to mmc standard). -
-

- -

-

Software requirements :

-
-
Linux kernel 2.4 or higher
-
With kernel 2.4 the drive has to be under ide-scsi emulation.
-
With kernel 2.6 the drive should not be under ide-scsi.
-
libpthread
-
is supposed to be a standard system component.
-
-

- -

-

-GPL software included:
-

-
-
libburn-0.2.3 stabilized SVN snapshot
-
(by Derek Foreman, Ben Jansens, and team of libburn.pykix.org)
-
transfers data to CD
-
-

- -

-This program system has been tested on Intel/AMD Linux systems only.
-Ports to other usable systems are appreciated. Reports are welcome. -

- -
- -

-

Special features:

-
    -
  • Source code is independent of -cdrecord -
  • -
-

- -

-

Commands:

-
-
The goal is to provide some of cdrecord's options in a compatible way. -This has been achieved quite sufficiently for the needs of backup tool -scdbackup -and for data CD projects of K3b -(see examples). -Suitability for audio CD frontends has been improved much and is now being -evaluated.
-Further enhancements depend on people who can describe and discuss their -wishes as well as on the development of libburn.
-

-
Get an overview of drives:
-
$ cdrskin -scanbus
-
$ cdrskin dev=ATA -scanbus
-
$ cdrskin --devices
-
Get info about a particular drive or loaded media:
-
$ cdrskin dev=0,1,0 -checkdrive
-
$ cdrskin dev=ATA:1,0,0 -atip
-
$ cdrskin dev=/dev/hdc -toc
-
Make used CD-RW writable again:
-
$ cdrskin -v dev=/dev/sg1 blank=all -eject
-
$ cdrskin -v dev=/dev/dvd blank=fast -eject
-
Write ISO-9660 filesystem image:
-
$ cdrskin -v dev=/dev/hdc speed=12 fs=8m driveropts=burnfree -sao -eject padsize=300k my_image.iso
-
Write compressed afio archive on-the-fly via cdrskin-0.2.4 :
-
$ find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree padsize=300k -sao tsize=650m -
-
Write compressed afio archive on-the-fly via cdrskin-0.2.5 :
-
$ find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree padsize=300k -tao -
-
Write audio tracks:
-
$ cdrskin -v dev=ATA:1,0,0 speed=48 driveropts=burnfree -sao track1.wav track2.au -audio -swab track3.raw -
-
-
cdrskin -help
-
reports the cdrecord compatible options
-
cdrskin --help
-
reports the non-cdrecord options
-
man cdrecord
-
documents the standard for which cdrskin is striving. -Do not bother Joerg Schilling with any cdrskin problems. -(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding - this "don't bother Joerg" demand.) -
-
-

- -

-

Known deficiencies:

-
    -
    -
  • -Burns only a single closed session. No -multi option yet. -Note: Development version 0.2.5 offers multi-session now. See below. -
  • -
  • -No TAO mode in cdrskin-0.2.4 and therefore no writing on-the-fly without -a predefined source size.
    -Note: Development version 0.2.5 offers TAO now. See below. -
  • -
  • -cdrskin -scanbus or --devices hangs for quite a while if there is -a CD drive which does not work properly (e.g. because it has individual -problems with DMA). -So if the superuser gets no result with cdrskin --devices then one should -disable DMA with the problematic CD drives -(like: hdparm -d0 /dev/hdd ) -and try again.
    -In severe cases it might be necessary to guess the device name /dev/sgN resp. -/dev/hdX of the non-ill burner if it cannot be found otherwise among its -ill peers. Alternatively one can guess the address of the ill device, remove -rw-permissions and retry the bus scan as non-superuser. -
-

- -
- -

-

-
Download as source code (see README):
-
cdrskin-0.2.4.pl01.tar.gz -(510 KB). -
-
-The "stable" cdrskin tarballs are source code identical with "stable" -libburn releases or with "stabilized" libburn SVN snapshots. They get -produced via a different procedure, though.
-cdrskin is part of libburn - full libburn is provided with cdrskin releases. -
-
 
-
Download as single x86 binaries (untar and move to /usr/bin/cdrskin):
-
-cdrskin_0.2.4.pl01-x86-suse9_0.tar.gz, (60 KB), -
-
runs on SuSE 9.0 (2.4.21) , RIP-14.4 (2.6.14) , - Gentoo (2.6.15 x86_64 Athlon).
-
-
-cdrskin_0.2.4.pl01-x86-suse9_0-static.tar.gz, (260 KB), -static compiled, -
-
runs on SuSE 7.2 (2.4.4), and on the systems above.
-
-
-
-
Documentation:
-
README a short introduction
-
cdrskin --help non-cdrecord options
-
cdrskin -help cdrecord compatible options
-
 
-
-
Contact:
-
Thomas Schmitt, scdbackup@gmx.net
-
-
License:
-
GPL, an Open Source approved license
-
 
-
-

- -
- -

-Enhancements towards previous stable version cdrskin-0.2.2: -

    -
  • cdrecord compatibility with drive addresses of form [ATA:]Bus,Target,Lun. -
    (use option --old_pseudo_scsi_adr to get back the incompatible - Bus,Traget,Lun addressing of version 0.2.2) -
  • -
  • Drives adressable via links and device siblings (/dev/cdrom , /dev/scd0). -
  • -
  • Automatic -audio extraction with .wav files and .au files. -
  • -
  • Bug fix about failure to eject.
  • -
  • Comments and empty lines allowed in startup files.
  • -
  • Options -scanbus and --devices print SORRY messages about busy drives. -
  • -
  • Drive buffer fill indicator reports realistic percentage numbers.
  • -
  • Option -toc is supported, drive firmware revision gets displayed.
  • -
-

- -
- -

-

-

Development snapshot, version 0.2.5 :

-
Enhancements towards stable version 0.2.4: -
    -
  • Option -tao is fully enabled. - With single track or with undefined size from standard input, - default is -tao. With other multi-track sessions, default is -sao. - (The latter is an intentional deviation from cdrecord defaults.) -
  • -
  • Status report during blank, preparation and finalization improved.
  • -
  • Bug fixed: Trailing trash appended to .wav files caused error message - and, if exceeding fifo size, could even stall a burn. - (Workaround: disable fifo by fs=0)
  • -
  • Bug fixed: False speed with first pacifier cycle. Potential program - abort by floating point exception (NaN).
  • -
  • multi-session CDs: -multi, -msinfo, - writing to appendable CDs (for now restricted to write mode TAO).
  • -
-
-
 
-
README 0.2.5 -
cdrskin_0.2.5 --help
-
cdrskin_0.2.5 -help
-
 
-
Maintainers of cdrskin unstable packages please use SVN of - libburn.pykix.org
-
Download: svn co http://libburn-svn.pykix.org/trunk libburn_pykix -
-
Build: cd libburn_pykix ; ./bootstrap ; ./configure ; make -
-
Build of SVN versions needs -autotools of at least version 1.7 installed. -But after the run of ./bootstrap, only -vanilla tools like make and gcc are needed.
- -
 
-
The following downloads are intended for adventurous end users or -admins with full system souvereignty.
-
Source (./bootstrap is already applied, build tested, for more see above -upcoming README ): -
-
-cdrskin-0.2.5.tar.gz -(500 KB). -
-
Binary (untar and move to /usr/bin/cdrskin):
-
-cdrskin_0.2.5-x86-suse9_0.tar.gz, (60 KB). -
-
-cdrskin_0.2.5-x86-suse9_0-static.tar.gz, (260 KB) -
-
-

- -
- -

-Many thanks to Joerg Schilling for cdrecord, -
-and to Derek Foreman and Ben Jansens for creating libburn. -
-Historic versions based on Derek's and Ben's -icculus.org/burn :
-cdrskin-0.1.2.0.2.ts.tar.gz
-cdrskin-0.1.3.0.2.ts.tar.gz -

- -
- - -

-

-
Example for a setup of device permissions. To be done by the superuser:
-
(CD devices which offer no r-permission are invisible to normal users.)
-
(CD devices which offer no w-permission are not useable.)
-
# cdrskin --devices
-
...
-
0  dev='/dev/sg0'  rwrwr- :  'TEAC' 'CD-ROM CD-532S'
-
1  dev='/dev/hdc'  rwrw-- :  'LITE-ON' 'LTR-48125S'
-
# chmod a+rw /dev/sg0 /dev/hdc
-
-

- -
- -
-

- -Example how to setup K3b to use cdrskin for burning data CD projects. -
-(
K3b -is a GUI frontend which uses cdrecord for CD burning.) -

- -
- - -

-

-
Example for a test session with a cdrecord based scdbackup installation:
-
$ cdrskin -scanbus
-
...
-
-If your system is stricken with some ill CD device then this can stall -and you will have to press Ctrl+C to abort. -In this case, you may execute -export SCDBACKUP_NO_SCANBUS=1 -and try again. -
-
-
    2,0,0    0)  'TEAC' 'CD-ROM CD-532S' '?' Removable CD-ROM
-
$ cdrskin -scanbus dev=ATA
-
...
-
    1,0,0    1)  'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM
-
$ export SCDBACKUP_SCSI_ADR="ATA:1,0,0"
-
$ export SCDBACKUP_CDRECORD="cdrskin -v -v tao_to_sao_tsize=650m"
-
$ scdbackup_home
-
-
-
Example for a permanent configuration of cdrskin based scdbackup
-
$ cd scdbackup-0.8.6/inst
-
$ export SCDBACKUP_USE_CDRSKIN=1
-
$ ./CONFIGURE_CD
-
...
-
cdrskin 0.2.4 : limited cdrecord compatibility wrapper for libburn
-
...
-
------------------- SCSI devices. To be used like    0,0,0
-
    2,0,0    0)  'TEAC' 'CD-ROM CD-532S' '?' Removable CD-ROM
-
------------------- end of SCSI device list
-
------------------- ATA devices. To be used like ATA:0,0,0 -
    1,0,0    1)  'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM
-
...
-
    * Your cdrecord offers -driveropts=burnfree with your recorder.
-
...
-
scdbackup for CD 0.8.6 : First stage of installation done.
-
...
-
Now give it a try. Run : scdbackup_home
-
$ unset SCDBACKUP_USE_CDRSKIN
-
-
-
To get back to using cdrecord :
-
$ cd scdbackup-0.8.6/inst
-
$ export SCDBACKUP_USE_CDRSKIN=0
-
$ ./CONFIGURE_CD
-
...
-
$ unset SCDBACKUP_USE_CDRSKIN
-
-

- -
- -
-

-

About the relationship of cdrecord and cdrskin

-First of all: this relationship is single sided, as cdrskin has to be aware of -cdrecord but not vice versa. -
-
-I am a long time user of cdrecord and it works fine for me. -Especially i do appreciate its write mode -tao which allows to pipe arbitrary -data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well -maintained. So for me - there would be not problem with it. -
-But the author of cdrecord and the Linux kernel people foster a very hostile -relationship. Ok, that's their business, not mine (or ours if you are with me). -One has to be aware, though, that this relationship might lead to a situation -where cdrecord is no longer available for certain Linux kernels. -
-To have my own project prepared for such a time, i began to implement its -cdrecord gestures on top of libburn. -From now on i invite other interested users of cdrecord to teach cdrskin -the gestures necessary for their cdrecord applications. -Contact me. Let's see what we can achieve. -
-
-I am aware that libburn and cdrskin still have way to go until you can simply -install cdrskin as cdrecord and may expect any application to run with it. -Currently i do not encourage this approach, but of course such a replacement -opportunity is the long term goal of a cdrecord compatibility wrapper. -
-
-It is very important to me that this project is not perceived as hostile -towards Joerg Schilling and his ongoing work. -I owe him much. For cdrecord, for mkisofs, for star. Chapeau. -
-

-
- -
- -Enjoying free Open Source hosting by www.webframe.org
- -100 % Microsoft free
-and by sourceforge.net
- -SourceForge Logo - -
-
-
-
Links to my other published software projects : -
-scdbackup, multi volume CD backup -
-(a second source of above)
-
Some Tools for Image Collectors -
(a second source of above)
-
-pppoem, a DSL throughput monitor (mainly for Linux kernel 2.4) -
-

-Legal statement: This website does not serve any commercial purpose.
-
- - diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h deleted file mode 100644 index 7c205ed..0000000 --- a/cdrskin/cdrskin_timestamp.h +++ /dev/null @@ -1 +0,0 @@ -#define Cdrskin_timestamP "2006.11.12.185342" diff --git a/cdrskin/changelog.txt b/cdrskin/changelog.txt deleted file mode 100644 index 9b19b1d..0000000 --- a/cdrskin/changelog.txt +++ /dev/null @@ -1,1539 +0,0 @@ ------------------------------------------------------------------------------- - libburn.pykix.org scdbackup.sourceforge.net/cdrskin ------------------------------------------------------------------------------- - -Deliberate deviations of cdrskin from cdrecord compatibility: - -+ cdrskin does drive operations (on its drive 0) without a dev= option - -+ gracetime=0 is allowed and set by default - -+ -pad is always set for audio tracks - -+ -sao is default for multi-track sessions with all track lengths defined - -+ premature end of source is not an error and leads to full announced tracksize - -+ -msinfo pushes all other messages to stderr. It works independent of - other options which would prevent it with cdrecord (-atip, -scanbus, ...) - ------------------------------------------------------------------------------- - Changelog ------------------------------------------------------------------------------- - -19 Aug 2006 [committed] -README -cdrskin/README cdrskin/cdrskin.c cdrskin/add_ts_changes_to_libburn_0_2_1 \ -cdrskin/cdrskin_timestamp.h cdrskin/compile_cdrskin.sh -cdrskin-0.1.4 "stable" released on base of August 15 2006 version of -libburn-svn.pykix.org/trunk after initial merge of libburn and cdrskin-0.1.3 . - ------------------------------------------------------------------------------- - -19 Aug 2006 [committed 16] -cdrskin/changelog.txt -cdrskin-0.1.5 development started. -Introduced this changelog. ----------------------------------- Format (still emerging): - -Day Month Year [eventual commit mark with revision number] -affected files , naked, one by line, -[eventually = internal snapshot tarball] -More ore less concise description. - ----------------------------------- End of Format - -20 Aug 2006 [committed together with next change, i fear] -libburn/sg.c -Hopefully fixed a file descriptor resource leak in sg_grab(). -All scanned drives (seem to) stay open once, the grabbed one got re-opened -and its stored first file descriptor got forgotten. Now we try to detect -and re-use the still open fd. - -21 Aug 2006 [committed] -libburn/libburn.h -libburn/sg.c -libburn/init.c -= libburn_cdrskin_A60819.tgz -cdrskin/cdrskin.c [committed later as revision 11] -O_EXCL experiments imported from cdrskin-0.1.3 -In default configuration and on compliant kernels expect that a busy drive is -invisible to further cdrskin instances. The user gets hints in case of empty -bus scan result resp. busy drive given with dev=... -Wether cdrecord and cdrskin respect each other would have to be evaluated. -Options to play with: - --demand_a_drive exit !=0 on bus scans with empty result - --drive_abort_on_busy abort process if busy drive is found - (might be triggered by a busy hard disk) - --drive_blocking try to wait for busy drive to become free - (might be stalled by a busy hard disk) - --drive_not_exclusive do not ask kernel to prevent opening - busy drives. Effect is kernel dependend. - grab_drive_and_wait= grab drive, wait given number of - seconds, release drive, and do normal work - -21 Aug 2006 [committed] -libburn/write.c -Rectified non-ANSI-C comment, complained by gcc. - -21 Aug 2006 [committed 13] -cdrskin/cdrskin_eng.html -The homepage moved in from scdbackup's internal doc collection. - -21 Aug 2006 [committed with revision 11, i fear] -cdrskin/cdrskin.c -Removed flaw: -Help text of tao_to_sao_tsize= clarified. - -21 Aug 2006 [committed 12] -cdrskin/wiki_plain.txt -The initial filling of the cdrskin wiki on libburn.pykix.org . -I am not sure about the future fate of this text. I plan to keep it up to -date with the online wiki for now. The online version will be considered -the original. - -21 Aug 2006 [committed 15] -cdrskin/cdrskin_timestamp.h -Timestamping the new version. - -21 Aug 2006 [committed 14] -cdrskin/add_ts_changes_to_libburn_0_2_1 -cdrskin/compile_cdrskin.sh -Readjusted relationship glue of libburn and cdrskin. - ---------------------------------------------------------------------- cycled - - -27 Aug 2006 [40] -libburn/mmc.c -libburn/sg.c -Inserted prints to see how sg_issue_command() is called (printing is disabled now) - -21 Aug 2006 [17] -README -Reported obvious need for automake >=1.7 - -21 Aug 2006 [18] -cdrskin/cdrskin_eng.html -cdrskin/README -Reported obvious need for automake >=1.7 - -22 Aug 2006 [19] -libburn/drive.c -libburn/drive.h -New internal function burn_drive_is_open() - -23 Aug 2006 [20] -cdrskin/cdrskin.c -Implemented Lorenzo Taylor's audio patch manually by copy+paste -as i wanted to fully understand it. -Hopefully did not break it that way. - -24 Aug 2006 [21] -libburn/libburn.h -libburn/drive.c -Introduced API functions burn_drive_scan_and_grab() burn_drive_get_adr() - -24 Aug 2006 [22] -cdrskin/compile_cdrskin.sh -Experimental option cdrskin/compile_cdrskin.sh -newapi - -24 Aug 2006 [23] -cdrskin/cdrskin.c -First test of possibility to obey the self imposed rules of Revison 21 - -24 Aug 2006 [25] -cdrskin/cdrskin.c -Fixed undefined track_type introduced by revision 20. -(We broke cdrskin, but i did not break the patch. Success.) - -24 Aug 2006 [30] -libburn/libburn.h -Hopefully fixed an unintended line break in API doxygen - -25 Aug 2006 [32] -cdrskin/cdrskin.c -Installed protection against resource leak in Cdrskin_grab_drive() -Just to be sure. - -25 Aug 2006 [33] -libburn/drive.c -burn_drive_free() now closes all open drive file descriptors - -25 Aug 2006 [34] -libburn/libburn.h -Adjusted statement at API documention of burn_initialize() - -25 Aug 2006 [35] -cdrskin/cdrskin.c -Worked forth in order to make cdrskin fully newapi compliant - -26 Aug 2006 [37] -Makefile.am -libburn/back_hacks.h -libburn/drive.c -libburn/init.c -Allowed to blank appendable files and installed first back_hacks.h variable ever - -26 Aug 2006 [38] -test/burniso.c -Rewrote it to new API practice, inflated explanation comments, SAO mode - -27 Aug 2006 [39] -cdrskin/cdrskin.c -Implemented Lorenzos blank-appendable patch plus option --no_blank_appendable - -27 Aug 2006 [44] -test/blank.c -Rewrote test/blank.c to new API practice, inflated explanation comments - -27 Aug 2006 [41] -cdrskin/cdrskin.c -Fixed obscure sigsegv introduced with 35 or 39 by obeying libburn.h text -(could be a fandango starting in burn_drive_info_free) - -27 Aug 2006 [45] -test/burniso.c -Disabled inner burn_drive_info_free like in cdrskin, polished a bit - -27 Aug 2006 [43] -libburn/libburn.h -Changed some 'release' to 'close' with specs of burn_drive_scan_and_grab - -28 Aug 2006 [46] -test/burniso.c -Polished a bit more for doxygen - -28 Aug 2006 [50] -libburn/libburn.h -cdrskin/cdrskin.c -Wrote into API the imperative not to use drive.location but burn_drive_get_adr - -28 Aug 2006 [47] -test/burniso.c -Integrated functionality of test/devices.c into test/burniso.c -Proposed to rename it to test/libburner.c - -28 Aug 2006 [51] -cdrskin/cdrskin.c -Closed a pitfall with reading from '-' and no tsize= or tao_to_sao_tsize= -Ticket 55 - -28 Aug 2006 [52] -cdrskin/cdrskin.c -Added personal commitment to grant BSD license on request. Insisted in GPL for now. - -28 Aug 2006 [53] -cdrskin/cdrskin.c -Forced each track to have a minimum size of 600 kB -Ticket 55 - -29 Aug 2006 [58] -test/burniso.c -Integrated functionality of test/blank.c into test/burniso.c - -29 Aug 2006 [55] -cdrskin/cdrskin.c -Made cdrskin ready to make good use of now working libburn-eject - -29 Aug 2006 [56] -cdrskin/cdrskin.c -Avoided unwanted tray loading on eject of never grabbed drive - -29 Aug 2006 [57] -cdrskin/cdrskin.c -Disabled unconditionality of eject introduced by 55 or 56 - -30 Aug 2006 [59] -test/burniso.c -Repaired SIGSEGV caused by releasing ungrabbed drive after mere bus scan - -30 Aug 2006 [60] -test/libburner.c -Makefile.am -My proposal for new souvereign app as API doc and reference for API decisions - -31 Aug 2006 [61] -libburn/sg.c -cdrskin/cdrskin.c -Outcommented "experimental:" messages of O_EXCL development - -31 Aug 2006 [62] -test/libburner.c -Added 300 kB of padding to get rid of warning in doc, plus end sector padding - -31 Aug 2006 [63] -cdrskin/cdrskin.c -Promoted "newapi" functionality and libburn-eject from test to standard - -31 Aug 2006 [64] -cdrskin/cdrskin.c -Made cdrskin abort if fifo filling before burn yields 0 bytes (ticket 55) - -1 Sep 2006 [65] -cdrskin/README -cdrskin/cdrskin.c -cdrskin/cdrskin_eng.html -Updated cdrskin help tests and docs: -audio, obsolete eject_device= - -1 Sep 2006 [66] -libburn/write.c -cdrskin/cdrskin.c -Implemented track number patch by bonfire-app@wanadoo.fr, tickets 58 and 9 - -1 Sep 2006 [67] -cdrskin/cdrskin.c -Added clarifying URGE to ABORT texts - -1 Sep 2006 [71] -test/libburner.c -Made "read-ahead" comment sufficiently ambigous: "buffer"|"filesystem" == "" - -1 Sep 2006 [72] [73] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Rowed back from revision 64. Now #ifdef Cdrskin_fifo_abort_on_emptY - -1 Sep 2006 [74] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Rowed forth from revision 73. Now hopefully compliant to man cdrecord. - -1 Sep 2006 [78] -cdrskin/cdrskin.c -Made -pad behave cdrecord-ly on audio tracks (not tested acousticly) - -2 Sep 2006 [85] -test/libburner.c -Added upcoming clarification of copyright and license aspiration - -3 Sep 2006 [86] -README -Added upcoming clarification of copyright and license aspiration - -3 Sep 2006 [87] [88] -cdrskin/README -cdrskin/cdrskin.c -Added upcoming clarification of copyright and license aspiration - -3 Sep 2006 [91] -cdrskin/changelog.txt -cdrskin/cdrskin_timestamp.h -Opened new cdrskin-0.1.5 upload cycle. This marks a should-be-stable phase. - ----------------------------------------------------- cycled - 2006.09.03.132934 - - -3 Sep 2006 [89] -doc/comments_test_ts -Made a try to get doxygen portal page readable by html dl lists - -4 Sep 2006 [92] -cdrskin/README -Made changes as reported by Lorenzo on libburn-hackers today - -4 Sep 2006 [93] -libburn/transport.h -libburn/drive.h -libburn/drive.c -libburn/init.c -libburn/libburn.h -Integrated elmom patch proposal #3 from ticket #62 -/* ts A60904 : ticket 62, contribution by elmom */ - -4 Sep 2006 [94] -cdrskin/README -Removed reference to frontend "burn" (needs a patch to work for .mp3) - -5 Sep 2006 [95] -doc/comments_test_ts -Made a try to get doxygen portal page readable by pre tags and truncation - -5 Sep 2006 [96] -test/libburner.c -Rearranged definitions and header inclusions. Is safer so. - -5 Sep 2006 [97] -test/libburner.c -Re-inserted lost tab. - -6 Sep 2006 [trac] -closed ticket 55: burn of empty tracks from stdin is now forbidden - -6 Sep 2006 [98] -libburn/libburn.h -libburn/drive.c -Added new parameter "force" to API-experimental burn_drive_info_forget() - -6 Sep 2006 [99] -doc/comments -Made doc test portal the official doc portal - -6 Sep 2006 [100] -cdrskin/cdrfifo.c -Added an initial value on proposal by Bart Vanherck - -7 Sep 2006 [101] -test/libburner.c -Changed a macro name from Burniso_ to Libburner_ - -7 Sep 2006 [102] [103] -libburn/libburn.h -libburn/drive.c -cdrskin/cdrskin.c -Implemented first use of API-experimental burn_drive_info_forget() in cdrskin signal handler - -7 Sep 2006 [104] -cdrskin/cdrskin.c -Tried to make abort messages clearer - -7 Sep 2006 [105] -Makefile.am -test/testburner.c -Prepared test bed for burn_drive_info_forget() as regular API call - -7 Sep 2006 [106] -test/testburner.c -Removed a remnant piece of rather unhealthy test code - -7 Sep 2006 [106] -test/testburner.c -Corrected test reciepe - -7 Sep 2006 [107] -test/libburner.c -Added constraint --stdin_size >= 600k, better bus scan behavior - -8 Sep 2006 2006 [109] -libburn/drive.c -test/testburner.c -cdrskin/cdrskin.c -Hopefully ensured correct burn_disc_erasable() already after first grab - -9 Sep 2006 2006 [112] -libburn/drive.c -cdrskin/cdrskin.c -Hunted down the bug which let newapi-cdrskin fail with drive 1 - -10 Sep 2006 [113] -libburn/drive.c -test/libburner.c -test/testburner.c -cdrskin/cdrskin.c -Slowed down highspeed loops waiting for drive status changes - -10 Sep 2006 [114] -cdrskin/compile_cdrskin.sh -Aliased switch name -newapi by -experimental - -10 Sep 2006 [115] -test/libburner.c -test/testburner.c -cdrskin/cdrskin.c -Re-enabled call to burn_drive_info_free() after repair by revision 93 - -11 Sep 2006 [116] -cdrskin/compile_cdrskin.sh -Changed -newapi to -experimental in help text - -11 Sep 2006 [117] -libburn/drive.c -Removed a bug introduced with revison 93 - -11 Sep 2006 [118] -libburn/libburn.h -test/libburner.c -Officialized burn_drive_info_forget() - -11 Sep 2006 [119] [120] -Makefile.am -test/testburner.c -Deleted until next occasion: testburner - -12 Sep Sep 2006 [124] -cdrskin/cdrskin.c -Repaired regression of -eject which loaded tray again - -12 Sep 2006 [126] -cdrskin/cdrskin.c -Replaced -experimental method of closing libburn by burn_drive_info_forget() - -12 Sep 2006 [129] -cdrskin/cdrskin.c -Added automated padding to last audio track (ticket 41) - -2006.09.13.093350 [130] -cdrskin/make_timestamp.sh -Prepared for new revision timestamps to mark cdrskin test versions -From now on cdrskin/cdrskin_timestamp.h is to be part of any commit. - -15 Sep 2006 [135] -Makefile.am -Replaced a few 8-blanks by tab - -15 Sep 2006 [136] -README -Moved installation instructions in front of overview paragraph - -15 Sep 2006 [137] -Makefile.am -cdrskin/README -Made cdrskin an installable program - -2006.09.15.092509 [138] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Prepared cdrskin-build for version leap - - ------------------------------ cycled (last cdrskin-0.1.5 ?) - 2006.09.15.101326 - -2006.09.15.101326 [139] -cdrskin/README -cdrskin/changelog.txt -New upload of scdbackup.sourceforge.net/cdrskin-0.1.5.tar.gz - -2006.09.15.174748 [143] -cdrskin/cdrskin.c -Revoked change of 1 Sep 2006 revision 78 (full -nopad) (ticket 41) - -16 Sep 2006 [144] -libburn/libburn.h -Made doxygen happy with parameter of burn_drive_get_adr - -2006.09.16.194730 [145] -000_CAUTION_RELEASE_CANDIDATE -zzz_CAUTION_RELEASE_CANDIDATE -README -Makefile.am -cdrskin/README -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Perfomed version leap in respect to SVN - -2006.09.19.124540 [160] [161] -cdrskin/cdrskin.c -Allowed driveropts=burnproof as alias for burnfree - -2006.09.19.140716 [162] [163] -cdrskin/cdrskin.c -Added error message in case of failed eject - -2006.09.20.134219 [175] [176] [177] -cdrskin/cdrskin.c -Fixed bug with dev=1,1,0 (ticket 75) - -21 Sep 2006 [186] -configure.ac -Makefile.am -Forwarded changes from 0.2.2 to 0.2.3 - -Sep 2006 [187] [188] [189] [190] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -cdrskin/cdrskin_eng.html -cdrskin/README -cdrskin/changelog.txt -- cdrskin/add_ts_changes_to_libburn_0_2_1 -+ cdrskin/add_ts_changes_to_libburn_0_2_3 -Makefile.am -cdrskin/cdrskin_timestamp.h -Performed development version leap to cdrskin-0.2.3 - ------------------------------------- cycled - cdrskin-0.2.3 - 2006.09.21.082411 - -21 Sep 2006 [191] -README -Clarified build from SVN versus tarball - -2006.09.21.173012 [192] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Gave up compile options -tarball_0_2 , -cvs_A51208 , -libburn_0_2_1 -Now standard and therefore no longer needed as macros: -Cdrskin_libburn_p_sectoR -Cdrskin_libburn_with_fd_sourcE -Cdrskin_libburn_largefilE -Cdrskin_libburn_padding_does_worK - -2006.09.21.185623 [193] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Officialized gestures of pre-0.2.3 -experimental, introduced -oldfashioned - -2006.09.21.194006 [194] -cdrskin/cdrskin.c -Investigating failure to open drive on eject - -2006.09.22.133027 [195] -libburn/libburn.h -libburn/sg.c -libburn/sg.h -libburn/drive.c -cdrskin/cdrskin.c -Implemented resolving of softlinks (ticket 33) - -2006.09.22.170220 [196] -libburn/libburn.h -libburn/sg.c -libburn/sg.h -libburn/drive.c -cdrskin/cdrskin.c -Implemented new API function burn_drive_convert_fs_adr() - - -2006.09.22.172307 [197] -cdrskin/cdrskin.c -Fixed SIGSEGV of -eject on non-existent device address - -22 Sep 2006 [198] -libburn/sg.c -libburn/sg.h -libburn/drive.c -Implemented finding matching /dev/sgN from /dev/srM or /dev/scdK -(ioctl(): SCSI_IOCTL_GET_IDLUN) - -2006.09.22.195414 [199] -cdrskin/cdrskin.c -Removed bug prone implementation of link resolving (now only via libburn) - -2006.09.22.202631 [200] -cdrskin/cdrskin.c -Kept new address conversion from hopping on libburn drive numbers - -2006.09.22.203939 [201] -cdrskin/cdrskin.c -Fixed --no_follow_links and renamed to --no_convert_fs_adr - -2006.09.23.080015 [202] -libburn/drive.c -Restructured SCSI search, removed a potential bug with hdX - -23 Sep 2006 [203] -libburn/libburn.h -Made burn_drive_convert_scsi_adr() a new API function - -23 Sep 2006 [204] -libburn/drive.c -libburn/sg.c -Changed outdated comments - -23 Sep 2006 [205] -libburn/libburn.h -libburn/drive.c -Introduced new API function burn_drive_obtain_scsi_adr() - -2006.09.23.100001 [not in libburn-0.2.2 yet] -cdrskin-0.2.2/cdrskin/cdrskin.c -Backported bug fix of revision 197. Version timestamp : 2006.09.23.100001 - -23 Sep 2006 [206] [207] -libburn/drive.c -libburn/sg.c -Enabled unused SCSI part of struct burn_drive. Switched persistent address to burn_drive.devname - -2006.09.23.114858 [208] -cdrskin/cdrskin.c -Implemented --no_pseudo_scsi_adr - -2006.09.23.132755 [209] -cdrskin/cdrskin.c -libburn/drive.c -Removed a bug with SCSI address of scanned drives without such address - -23 Sep 2006 [210] -cdrskin/README -Explained the new addressing mode - -2006.09.23.182444 [211] -cdrskin/README -cdrskin/cdrskin.c -Bus,Target,Lun for dev=ATA and dev=ATAPI, real SCSI addressing by default - -2006.09.23.183608 [212] -cdrskin/cdrskin.c -Made small improvement with debug message - -2006.09.24.171706 [214] -Makefile.am -libburn/libburn.h -libburn/libdax_msgs.h -libburn/libdax_msgs.c -libburn/init.c -cdrskin/compile_cdrskin.sh -cdrskin/cdrskin.c -Added an error message handling facility (ticket 74) - -2006.09.24.180836 [215] -libburn/init.c -libburn/sg.c -libburn/libdax_msgs.h -libburn/libdax_msgs.c -cdrskin/cdrskin.c -Made use of new message handling facility and removed first bugs - -24 Sep 2006 [216] -libburn/libdax_msgs.h -Recorded error_code 0x00020001 - -24 Sep 2006 [217] [218] -Makefile.am -libburn/libburn.h -libburn/write.c -libburn/drive.c -cdrskin/compile_cdrskin.sh -Obsoleted libburn/message.[ch] - -25 Sep 2006 [219] -libburn/read.c -libburn/write.c -Removed inclusion of libburn/message.h - -2006.09.25.104629 [220] -libburn/init.c -libburn/drive.c -cdrskin/cdrskin.c -Converted "libburn_experimental:" messages of address conversion into "DEBUG" - -2006.09.25.141035 [221] -libburn/libdax_msgs.h -libburn/libdax_msgs.c -libburn/drive.c -libburn/sg.h -libburn/sg.c -Implemented sg_close_drive_fd (ticket 74) - -2006.09.25.144506 [222] -libburn/libdax_msgs.c -Achieved minimum strerror thread safety (strerror_r is burned by Unix and GNU) - -2006.09.26.114552 [223] -libburn/libburn.h -libburn/init.c -libburn/libdax_msgs.c -cdrskin/cdrskin.c -Made first use of queued messages and fixed several bugs with that - -2006.09.26.142824 [224] -libburn/sg.c -libburn/libdax_msgs.h -cdrskin/cdrskin.c -Made changes with usage of queued messages - -24 Sep 2006 [225] -Makefile.am -libburn/libburn.h -libburn/write.c -libburn/drive.c -- libburn/message.c -- libburn/message.h -Removed libburn/message.[ch] - -2006.09.26.205504 [227] -libburn/drive.c -Enhanced softlink resolution - -2006.09.26.210711 [228] -libburn/drive.c -Fixed bug in enhanced softlink resolution - -2006.09.27.063147 [229] -cdrskin/cdrskin.c -Fixed bug with relative device addresses and Cdrpreskin__cdrecord_to_dev() - -2006.09.27.074910 [230] -cdrskin/cdrskin.c -Fixed broken -version and --help (second time for same mistake) - -2006.09.27.080826 [231] -cdrskin/README -cdrskin/cdrskin.c -Allowed comments and empty lines in startup files - -2006.09.27.082057 [232] -cdrskin/cdrskin.c -Prevented reading of startup files with first arg -version, -help or --help - -2006.09.27.115919 [233] -libburn/drive.c -libburn/sg.h -libburn/sg.c -libburn/libdax_msgs.h -cdrskin/cdrskin.c -Disabled but did not discarded failed attempt to lock against growisofs - -2006.09.27.120656 [234] -libburn/drive.h -libburn/init.c -libburn/transport.h -libburn/libburn.h -Disabled but did not discarded failed attempt to lock against growisofs - -2006.09.27.134332 [235] -libburn/sg.c -Kept /dev/hdX from all having SCSI address 0,0,0 - -2006.09.27.142312 [236] -libburn/drive.c -Curbed endless links to 20 hops - -2006.09.27.143843 [237] -libburn/sg.c -Removed obsolete code and comments - -2006.09.28.074434 [238] -cdrskin/cdrskin.c -Enabled optional growisofs lock attempt via --drive_scsi_exclusive - -28 Sep 2006 [239] -libburn/libburn.h -Made official exclusive==2 with burn_preset_device_open() - ------------------------------------- cycled - cdrskin-0.2.3 - 2006.09.28.100934 - -2006.09.28.115152 [240] -cdrskin/cdrskin.c -Restored vanished line at end of -help text and added a new one - -2006.10.01.104140 [243] -libburn/drive.c -cdrskin/cdrskin.c -Enhanced Cdrpreskin__cdrecord_to_dev so it warns of invisible SCSI drive. - -2006.10.02.103418 [244] -libburn/libburn.h -libburn/drive.h -libburn/drive.c -libburn/libdax_msgs.h -libburn/libdax_msgs.c -cdrskin/cdrskin.c -Implemented burn_abort() and made use of it - -2006.10.03.162719 [245] -Makefile.am -libburn/libburn.h -libburn/init.c -libburn/cleanup.h -libburn/cleanup.c -cdrskin/cleanup.h -cdrskin/cleanup.c -test/libburner.c -cdrskin/compile_cdrskin.sh -cdrskin/cdrskin.c -Implemented new API function burn_set_signal_handling(), libburner uses it - -5 Oct 2006 [246] -libburn/drive.c -Uploaded forgotten part of revision 245 - -2006.10.05.142628 [247] -libburn/libburn.h -libburn/transport.h -libburn/sg.c -libburn/sg.h -libburn/drive.c -cdrskin/cdrskin.c -Made use of SCSI_IOCTL_GET_BUS_NUMBER in hope of cdrecord compatibility - -6 Oct 2006 [248] -+ libburn/asserts.txt -Listed findings on assert() within libburn - -7 Oct 2006 [249] -libburn/async.c -libburn/libdax_msgs.h -libburn/asserts.txt -Got rid by soft means of assert() in async.c - -2006.10.07.121234 [250] -libburn/libburn.h -libburn/async.c -libburn/drive.h -libburn/drive.c -libburn/init.c -libburn/libdax_msgs.h -libburn/sg.c -libburn/asserts.txt -Got rid of assert() in drive.c by soft means - -2006.10.07.132916 [251] -libburn/init.c -libburn/async.c -Got rid of assert() in init.c by soft means - -2006.10.07.142454 [252] -libburn/libburn.h -libburn/async.c -libburn/options.c -libburn/sector.c -libburn/spc.c -libburn/libdax_msgs.h -Got rid of assert() in options.c by soft means - -7 Oct 2006 [253] -libburn/read.c -Got rid of assert() in read.c by soft means - -2006.10.07.170913 [254] -libburn/sg.c -libburn/asserts.txt -Got rid of some assert() in sg.c by soft means - -2006.10.07.175427 [255] -libburn/spc.c -libburn/async.c -libburn/libdax_msgs.h -Got rid of assert() in spc.c by soft means - -2006.10.08.095016 [256] -libburn/structure.c -libburn/sector.c -libburn/spc.c -libburn/libdax_msgs.h -libburn/asserts.txt -Got rid of assert() in structure.c by soft means - -8 Oct 2006 [257] -libburn/toc.c -Got rid of assert() in toc.c by soft means - -8 Oct 2006 [258] -libburn/util.c -Got rid of assert() in util.c by soft means - -2006.10.09.083438 [259] -libburn/write.c -libburn/structure.c -libburn/libdax_msgs.h -libburn/asserts.txt -Got rid of assert() in write.c by soft means - -2006.10.09.123518 [260] -libburn/mmc.c -libburn/read.c -libburn/sector.c -libburn/mmc.h -libburn/transport.h -libburn/asserts.txt -Got rid of assert() in mmc.c by soft means - -2006.10.10.112545 [261] -libburn/sector.h -libburn/sector.c -libburn/async.c -libburn/write.h -libburn/write.c -libburn/libdax_msgs.h -libburn/asserts.txt -Got rid of assert() in sector.c by soft means - -2006.10.10.175444 [262] -libburn/sg.c -libburn/libdax_msgs.h -Got rid of assert() in sg.c by soft means - -10 Oct 2006 [263] -libburn/asserts.txt -Got rid of assert() in libburn - -2006.10.11.191959 [264] -cdrskin/cdrskin.c -cdrskin/README -Changed pseudo-cdrecord addresses: /dev/hdX = ATA:(X-'a')/2,(X-'a')%2,0 - -13 Oct 2006 [270] -Makefile.am -libburn/sg.c -libburn/cleanup.c -libburn/sg-linux.c -libburn/read.c -libburn/drive.c -libburn/sbc.c -libburn/transport.h -cdrskin/cleanup.c -Made libburn and cdrskin build on my Linux again - -2006.10.13.114554 [271] -cdrskin/cdrskin.c -libburn/write.c -libburn/sg-linux.c -libburn/libdax_msgs.h -Removed bug in burn_disc_write_sync(): BURN_DRIVE_IDLE, then d->sync_cache() - -2006.10.14.105224 [272] -libburn/sg.h -libburn/sg-freebsd.c -libburn/sg-linux.c -libburn/drive.c -Introduced burn_drive_enumerator_t to allow more complete sg-freebsd implementation - -2006.10.15.133035 [274] -cdrskin/cdrskin.c -Changed ambigous include statement of libburn.h - -15 Oct 2006 2006 [275] -Makefile.am -libburn/libdax_msgs.h -+ libburn/libdax_audioxtr.h -+ libburn/libdax_audioxtr.c -Implemented a first attempt of a .wav decapitator (ticket 38) - -15 Oct 2006 2006 [276] -+ test/dewav.c -Implemented a first attempt of a .wav decapitator (ticket 38) - -15 Oct 2006 2006 [277] -test/dewav.c -Fixed permissions of eventually created output file - -15 Oct 2006 2006 [278] -test/dewav.c -cdrskin/compile_cdrskin.sh -Hunting a malloc/free memory problem - -15 Oct 2006 2006 [279] -libburn/libdax_audioxtr.c -Hopefully fixed memory problem which causes sigabrt on free - -15 Oct 2006 2006 [280] -libburn/libdax_audioxtr.c -Hopefully fixed problem with stdin as audio source - -15 Oct 2006 2006 [281] -test/dewav.c -Made helptext print to stderr rather than stdout - -2006.10.17.141053 [283] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -libburn/libdax_audioxtr.h -libburn/libdax_audioxtr.c -test/dewav.c -Roughly implemented automatic .wav extraction in cdrskin - -2006.10.17.164140 [284] -cdrskin/cdrskin.c -libburn/libdax_audioxtr.h -libburn/libdax_audioxtr.c -test/dewav.c -Implemented some cdrecord pickiness for .wav extraction - -18 Oct 2006 [285] -test/libburner.c -Added --audio and multi-track, removed --verbose, hid --burn_for_real - -2006.10.18.174334 [286] -cdrskin/cdrskin.c -Removed assumption BURN_DRIVE_IDLE==0 - -18 Oct 2006 [287] -cdrskin/README -Changed audio statements to reflect new situation - -18 Oct 2006 [288] -cdrskin/README -Removed a typo - -19 Oct 2006 [292] -test/libburner.c -Freed all tracks after burning and not only last one - -2006.10.19.094543 [293] -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Made cdrskin use libburn/cleanup.[oh] by default (not cdrskin/cleanup.[ch]) - ------------------------------------- cycled - cdrskin-0.2.3 - 2006.10.19.105730 - -2006.10.19.162254 [294] -cdrskin/cdrskin.c -cdrskin/cdrskin_eng.html -cdrskin/changelog.txt -Updated documentation about cdrskin-0.2.3 - -2006.10.19.164742 [295] -cdrskin/cdrskin.c -Corrected -help text - -2006.10.20.113421 [297] -libburn/libburn.h -libburn/mmc.c -libburn/sg-linux.c -libburn/sg-freebsd.c -libburn/drive.c -cdrskin/cdrskin.c -Made cdrskin produce "ATIP start of lead" (on non-blank media for now) - -20 Oct 2006 [298] -doc/comments -Updated help text of libburner - -2006.10.20.151602 [299] -libburn/libburn.h -libburn/drive.c -libburn/mmc.c -libburn/libdax_msgs.h -cdrskin/cdrskin.c -Classified media with TOC read error as unsuitable (rather than as blank) - -2006.10.21.103352 [300] -libburn/libburn.h -libburn/transport.h -libburn/drive.c -libburn/mmc.c -libburn/spc.c -libburn/sg-linux.c -libburn/sg-freebsd.c -libburn/libdax_msgs.h -cdrskin/cdrskin.c -Implemented some ATIP functionality - -2006.10.21.103653 [301] [302] -libburn/libburn.h -Clarified relation of burn_disc_read_atip() and burn_drive_get_start_end_lba() - -2006.10.21.185102 [303] -libburn/sg.h -libburn/mmc.h -libburn/mmc.c -libburn/sbc.h -libburn/sbc.c -libburn/spc.h -libburn/spc.c -libburn/drive.h -libburn/drive.c -libburn/transport.h -libburn/sg-linux.c -libburn/sg-freebsd.c -Split enumerate_common() into logic-layer, command-layer, transport-layer - -2006.10.22.130341 [304] -libburn/libburn.h -libburn/mmc.c -libburn/drive.c -libburn/cleanup.c -cdrskin/cleanup.c -cdrskin/cdrskin.c -Implemented cdrskin -toc - -2006.10.22.131452 [305] -cdrskin/cdrskin.c -Regulated coexistence of options -toc and -atip - -23 Oct 2006 [306] -libburn/mmc.c -Made clarification in remark about atip speed conversion - -2006.10.23.074430 [307] -cdrskin/cdrskin.c -Made use of burn_drive_info.revision as firmware revision text - -2006.10.23.113116 [308] -libburn/libburn.h -libburn/transport.h -libburn/mmc.h -libburn/mmc.c -libburn/write.c -cdrskin/cdrskin.c -cdrskin/cdrskin_eng.html -cdrskin/README -Made available drive buffer fill during write - -23 Oct 2006 [309] -libburn/sg-freebsd.c -Updated tangling of FreeBSD code with mmc.c :( - - -2006.10.23.134719 [310] -cdrskin/cdrskin.c -Corrected -toc track counter and notified about "hidden" tracks - -2006.10.24.075039 [311] -libburn/libdax_audioxtr.h -libburn/libdax_audioxtr.c -test/dewav.c -cdrskin/cdrskin.c -Introduced extraction of .au (but not its usage within cdrskin) - -2006.10.24.102107 [312] -libburn/libburn.h -libburn/structure.h -libburn/structure.c -libburn/sector.c -cdrskin/cdrskin.c -cdrskin/README -Enabled byte swapping for audio track sources, added anti option -swab - -2006.10.24.130259 [313] -test/dewav.c -cdrskin/cdrskin.c -cdrskin/README -Enabled automatic extraction of .au - -24 Oct 2006 [314] -Makefile.am -+ test/fake_au.c -Introduced temporary test program to produce SUN .au files - ------------------------------------- cycled - cdrskin-0.2.3 - 2006.10.24.144650 - -2006.10.24.165427 [315] -libburn/sector.c -Closed some loopholes for byte swapping. - - -2006.10.24.165610 [316] -cdrskin/cdrskin.c -Enabled audio byte swapping by default (to be disabled via option -swab) - ------------------------------------- cycled - cdrskin-0.2.3 - 2006.10.24.173602 - -25 Oct 2006 [317] -cdrskin/README -cdrskin/cdrskin_eng.html -cdrskin/wiki_plain.txt -Announced full -audio compatibility with cdrecord - ------------------------------------- cycled - cdrskin-0.2.3 - 2006.10.25.160540 - -2006.10.27.114326 [319 branch] -- cdrskin/add_ts_changes_to_libburn_0_2_3 -+ cdrskin/add_ts_changes_to_libburn_0_2_4 -cdrskin/README -cdrskin/cdrskin.c -cdrskin/cdrskin_eng.html -cdrskin/changelog.txt -README -Performed cdrskin version leap to cdrskin-0.2.4 - -2006.10.28.093922 [320 branch] -cdrskin/cdrskin_timestamp.h -Set final timestamp 2006.10.28.093922 - ------------------------------------- cycled - cdrskin-0.2.4 - 2006.10.28.093922 - -2006.10.28.115213 [321 trunk] [322 trunk] -- cdrskin/add_ts_changes_to_libburn_0_2_3 -+ cdrskin/add_ts_changes_to_libburn_0_2_4 -+ cdrskin/add_ts_changes_to_libburn_0_2_5 -cdrskin/README -cdrskin/cdrskin.c -cdrskin/cdrskin_eng.html -cdrskin/changelog.txt -README -Performed cdrskin version leap to cdrskin-0.2.5 - -28 Oct 2006 [323 branch] -- cdrskin/add_ts_changes_to_libburn_0_2_3 -cdrskin/add_ts_changes_to_libburn_0_2_4 -Corrected misnaming of my development directory - -28 Oct 2006 [324 trunk] -cdrskin/add_ts_changes_to_libburn_0_2_4 -cdrskin/add_ts_changes_to_libburn_0_2_5 -Corrected misnaming of my development directory - -2006.10.28.132532 [325 branch] -cdrskin/cdrskin.c -Corrected last-minute bug which made every track from file an audio track - -2006.10.28.151521 [326 trunk] -cdrskin/cdrskin.c -Corrected bug which made every track from file an audio track - -29 Oct 2006 [327 branch] [328 trunk] -+ CONTRIBUTORS -Copied missing file from libburn-0.2.2 - -29 Oct 2006 [329 branch] [330 trunk] -Makefile.am -Added to EXTRA_DIST cdrskin/cleanup.[ch] - -29 Oct 2006 [331 branch] [332 trunk] -Makefile.am -Added to EXTRA_DIST libburn/sg-*.[ch] - -29 Oct 2006 [333 branch] [334 trunk] -Makefile.am -Deleted from to EXTRA_DIST libburn/sg-*.h - -30 Oct 2006 [337] -libburn/transport.h -libburn/mmc.c -libburn/sg-freebsd.c -Made MMC command CLOSE TRACK/SESSION available to struct burn_drive - -2006.10.31.115606 [338] -libburn/transport.h -libburn/spc.c -libburn/mmc.c -libburn/write.h -libburn/write.c -libburn/sector.c -libburn/libdax_msgs.h -libburn/sg.h -libburn/sg-linux.c -cdrskin/cdrskin.c -Made single track TAO work (sector i/o still wants fixed size, though) - -2006.10.31.184736 [339] -libburn/sector.c -libburn/source.c -libburn/structure.h -libburn/structure.c -libburn/write.c -cdrskin/cdrskin.c -Made single track TAO work without fixed size (compile -experimental) - -2006.11.01.163934 [340] -libburn/libburn.h -libburn/source.c -libburn/write.h -libburn/write.c -libburn/structure.c -libburn/structure.h -libburn/sector.c -cdrskin/cdrskin.c -cdrskin/compile_cdrskin.sh -Adapted cdrskin pacifier to possibly unknown track size - -2006.11.01.172004 [341] -configure.ac -bootstrap -test/libburner.c -Repaired broken macro settings during Linux build - -2 Nov 2006 [342] -cdrskin/README -Mentioned -tao and experimental compile - -2006.11.02.211816 [343] -libburn/libburn.h -libburn/write.c -cdrskin/cdrskin.c -Installed status communications about closing session ("Fixating") - -3 Nov 2006 [344] -test/libburner.c -Changed status report during blanking (there are no "sectors") - -2006.11.03.063307 [345] -cdrskin/cdrskin.c -Removed some obsolete debugging messages - -2006.11.03.151137 [346] -libburn/structure.h -libburn/structure.c -libburn/write.h -libburn/write.c -libburn/sector.c -libburn/libdax_msgs.h -Installed decent abort behavior with TAO - -2006.11.03.202403 [347] -libburn/write.c -Enabled TAO for multiple -data tracks (-audio still ends after 0 bytes) - -2006.11.04.092909 [348] -libburn/spc.c -libburn/sector.c -Enabled audio tracks with TAO - -2006.11.02.140329 (pl01) [351 tags/CdrskinZeroTwoFourPlZeroOne] -../cdrskin-0.2.4.patch01/configure.ac -../cdrskin-0.2.4.patch01/bootstrap -../cdrskin-0.2.4.patch01/cdrskin/README -../cdrskin-0.2.4.patch01/cdrskin/add_ts_changes_to_libburn_0_2_4_patch01 -../cdrskin-0.2.4.patch01/cdrskin/cdrskin_timestamp.h -../cdrskin-0.2.4.patch01/test/libburner.c -Revoked autotools aspect of revision 290 - -2006.11.06.073810 [352] -cdrskin/cdrskin.c -cdrskin/cdrskin_eng.html -cdrskin/changelog.txt -Adapted documentation to reflect experimental TAO mode - ------------------------------------- cycle - cdrskin-0.2.5 - 2006.11.06.085056 - -2006.11.06.114159 [353] -libburn/libburn.h -libburn/spc.c -libburn/options.c -cdrskin/cdrskin.c -New API burn_write_opts_set_multi(). (But libburn cannot burn next session yet) - -2006.11.06.121409 [354] -cdrskin/cdrskin.c -Made -toc on multiple sessions more compatible - -2006.11.06.155237 [355] -libburn/libburn.h -libburn/drive.c -libburn/write.c -libburn/mmc.c -libburn/sg-linux.c -cdrskin/cdrskin.c -Made CD with unclosed track blankable (by -force) - -2006.11.06.195743 [356] -libburn/transport.h -libburn/mmc.c -libburn/spc.c -libburn/write.c -libburn/sg-linux.c -Cared for some SCSI error conditions which were ignored up to now - -2006.11.07.114514 [357] -cdrskin/cdrskin.c -Made -tao default for single track or stdin, -sao for any other multi-track - -7 Nov 2006 [358] -cdrskin/cdrskin_eng.html -cdrskin/changelog.txt -Prepared next cdrskin-0.2.5 upload cycle - -7 Nov 2006 [359] -cdrskin/changelog.txt -cdrskin/README -cdrskin/wiki_plain.txt -Updated documentation about TAO - -2006.11.07.152018 [360] -cdrskin/cdrskin.c -cdrskin/changelog.txt -Updated documentation about TAO - ------------------------------------- cycle - cdrskin-0.2.5 - 2006.11.07.152018 -* Enabled TAO - - -2006.11.08.165648 [361] -cdrskin/cdrfifo.h -cdrskin/cdrfifo.c -cdrskin/cdrskin.c -Avoided error message and nonzero exit with trailing trash on .wav - -8 Nov 2006 [362] -cdrskin/cdrskin_eng.html -Mentioned bug fix about trailing trash - -2006.11.08.172918 [363] -libburn/write.c -Made track write counter of SAO count rather too much than too few bytes - -8 Nov 2006 [364] -cdrskin/changelog.txt -Prepared next cdrskin-0.2.5 upload cycle - ------------------------------------- cycle - cdrskin-0.2.5 - 2006.11.08.181016 -* Bug fixed: Trailing trash appended to .wav files caused error message - and, if exceeding fifo size, could even stall a burn. - -2006.11.09.112832 [365] -cdrskin/cdrskin.c -Check desired write and block type with burn_drive_info.*_block_types - -2006.11.09.113729 [366] -libburn/sg-linux.c -Silenced SCSI error (debugging) messages about missing media - -2006.11.09.151431 [367] -cdrskin/cdrskin.c -Corrected first speed measurement report in TAO mode (which was random) - -2006.11.09.193030 [368] -libburn/libburn.h -libburn/write.c -cdrskin/cdrskin.c -Experimentally enabled burning to BURN_DISC_APPENDABLE (tested with TAO only) - -2006.11.10.093843 [369] -cdrskin/cdrskin.c -doc/comments -Expressing more self-confidence - -2006.11.10.172212 [370] -cdrskin/cdrskin.c -Provisory -msinfo (very verbous on stderr) - -2006.11.10.184047 [371] -cdrskin/cdrskin.c -Made it work with fifos and other non-plain files as track sources - -2006.11.10.185209 [372] -cdrskin/cdrskin.c -Read -msinfo from first track of last session and not from last track - -2006.11.11.122402 [373] -libburn/libburn.h -libburn/transport.h -libburn/mmc.h -libburn/mmc.c -libburn/write.c -libburn/drive.c -libburn/libdax_msgs.h -New API function burn_disc_track_lba_nwa() - -2006.11.11.122907 [374] [375] -cdrskin/cdrskin.c -Implemented not so provisory -msinfo - -2006.11.11.124020 [376] [377] -cdrskin/cdrskin.c -Reacted on some warnings of gcc -O2 - -2006.11.11.134752 [378] -cdrskin/cdrskin.c -Implemented handling of unsuitable disk states with -msinfo - -2006.11.11.152037 [379] -cdrskin/cdrskin.c -Demanded (for now) -tao for writing to appendable CDs - -2006.11.11.152748 [380] -cdrskin/cdrskin.c -Generally enabled -multi, -msinfo and writing to appendable CDs in TAO mode - -11 Nov 2006 [] -cdrskin/changelog.txt -Prepared next cdrskin-0.2.5 cycle - ------------------------------------- cycle - cdrskin-0.2.5 - 2006.11.11. -* Bug fixed: False speed with first pacifier cycle. Potential SIGFPE by NaN. -* multi-session CDs (for now restricted to write mode TAO) by -multi, -msinfo - - - ------------------------------------- cycle - cdrskin-0.2.5 - - - [] -Enable multi-session for write modes other than TAO - - - [] -Liberate generic SCSI code from sg-linux.c (scsi_notify_error(), scsi_error()) - - [] -Coordinate scsi_notify_error() and scsi_error() about harmless conditions - - -2006 [] --reset: ioctl(fd,CDROMRESET) ioctl(fd,SG_SCSI_RESET,SG_SCSI_RESET_DEVICE) - -2006 [] -Open O_EXCL all devices in address resolution chain -(Might help with non-standard hdX device siblings) - -2006 [] -Convert libburn_experimental: into LIBDAX_MSGS_SEV_DEBUG -Convert burn_print() into libdax_msgs_submit() - -2006 [] -Test unlocking of all drives by burn_drive_info_free() -Test unlocking of single drive by burn_drive_grab(), burn_drive_release() - -2006 [] -Clear outdated persistent read buffer after small CD image was read (ticket 57) - - - diff --git a/cdrskin/cleanup.c b/cdrskin/cleanup.c deleted file mode 100644 index 6c9f3b6..0000000 --- a/cdrskin/cleanup.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - cleanup.c , Copyright 2006 Thomas Schmitt - - A signal handler which cleans up an application and exits. - - Provided under GPL license within GPL projects, BSD license elsewise. -*/ - -/* - cc -g -o cleanup -DCleanup_standalonE cleanup.c -*/ - -#include -#include -#include -#include -#include -#include - -#include -typedef void (*sighandler_t)(int); - - -#include "cleanup.h" - -#ifdef __FreeBSD__ - -/* Signals to be caught */ -static int signal_list[]= { - SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, - SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, - SIGTTOU, - SIGBUS, SIGPROF, SIGSYS, SIGTRAP, - SIGVTALRM, SIGXCPU, SIGXFSZ, -1 -}; -static char *signal_name_list[]= { - "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", - "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", - "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", - "SIGTTOU", - "SIGBUS", "SIGPROF", "SIGSYS", "SIGTRAP", - "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" -}; -static int signal_list_count= 23; - -#else /* __FreeBSD__ */ - -/* Signals to be caught */ -static int signal_list[]= { - SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, - SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, - SIGTTOU, - SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, - SIGVTALRM, SIGXCPU, SIGXFSZ, -1 -}; -static char *signal_name_list[]= { - "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", - "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", - "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", - "SIGTTOU", - "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", - "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" -}; -static int signal_list_count= 24; - -#endif /* ! __FreeBSD__ */ - -/* Signals not to be caught */ -static int non_signal_list[]= { - SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1 -}; -static int non_signal_list_count= 4; - - -/* run time dynamic part */ -static char cleanup_msg[4096]= {""}; -static int cleanup_exiting= 0; - -static void *cleanup_app_handle= NULL; -static Cleanup_app_handler_T cleanup_app_handler= NULL; -static int cleanup_perform_app_handler_first= 0; - - -static int Cleanup_handler_exit(int exit_value, int signum, int flag) -{ - int ret; - - if(cleanup_msg[0]!=0) - fprintf(stderr,"\n%s\n",cleanup_msg); - if(cleanup_perform_app_handler_first) - if(cleanup_app_handler!=NULL) { - ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); - if(ret==2 || ret==-2) - return(2); - } - if(cleanup_exiting) { - fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n", - getpid(),signum); - return(0); - } - cleanup_exiting= 1; - alarm(0); - if(!cleanup_perform_app_handler_first) - if(cleanup_app_handler!=NULL) { - ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); - if(ret==2 || ret==-2) - return(2); - } - exit(exit_value); -} - - -static void Cleanup_handler_generic(int signum) -{ - int i; - - sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno); - for(i= 0; imax_sig) - max_sig= signal_list[i]; - if(signal_list[i]=non_signal_list_count) { - if(i==SIGABRT && (flag&8)) - signal(i,Cleanup_handler_generic); - else - signal(i,sig_handler); - } - } - return(1); -} - - -#ifdef Cleanup_standalonE - -struct Demo_apP { - char *msg; -}; - - -int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag) -{ - printf("Handling exit of demo application on signal %d. msg=\"%s\"\n", - signum,demoapp->msg); - return(1); -} - - -main() -{ - struct Demo_apP demoapp; - - demoapp.msg= "Good Bye"; - Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); - - if(1) { /* change to 0 in order to wait for external signals */ - char *cpt= NULL,c; - printf("Intentionally provoking SIGSEGV ...\n"); - c= *cpt; - } else { - printf("killme: %d\n",getpid()); - sleep(3600); - } - - Cleanup_set_handlers(NULL,NULL,1); - exit(0); -} - -#endif /* Cleanup_standalonE */ diff --git a/cdrskin/cleanup.h b/cdrskin/cleanup.h deleted file mode 100644 index a9d3551..0000000 --- a/cdrskin/cleanup.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - cleanup.c , Copyright 2006 Thomas Schmitt - - A signal handler which cleans up an application and exits. - - Provided under GPL license within GPL projects, BSD license elsewise. -*/ - -#ifndef Cleanup_includeD -#define Cleanup_includeD 1 - - -/** Layout of an application provided cleanup function using an application - provided handle as first argument and the signal number as second - argument. The third argument is a flag bit field with no defined bits yet. - If the handler returns 2 or -2 then it has delegated exit() to some other - instance and the Cleanup handler shall return rather than exit. -*/ -typedef int (*Cleanup_app_handler_T)(void *, int, int); - - -/** Establish exiting signal handlers on (hopefully) all signals that are - not ignored by default or non-catchable. - @param handle Opaque object which knows how to cleanup application - @param handler Function which uses handle to perform application cleanup - @param flag Control Bitfield - bit0= reset to default signal handling -*/ -int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, - int flag); - - -#endif /* ! Cleanup_includeD */ - diff --git a/cdrskin/compile_cdrskin.sh b/cdrskin/compile_cdrskin.sh deleted file mode 100755 index e82e807..0000000 --- a/cdrskin/compile_cdrskin.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/bin/sh - -# compile_cdrskin.sh -# Copyright 2005 - 2006 Thomas Schmitt, scdbackup@gmx.net, GPL -# to be executed within ./libburn-* resp ./cdrskin-* - -debug_opts= -def_opts= -largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1" -libvers="-DCdrskin_libburn_0_2_3" -cleanup_src_or_obj="libburn/cleanup.o" -libdax_msgs_o="libburn/libdax_msgs.o" -libdax_audioxtr_o="libburn/libdax_audioxtr.o" -do_strip=0 -static_opts= -warn_opts="-Wall" -fifo_source="cdrskin/cdrfifo.c" -compile_cdrskin=1 -compile_cdrfifo=0 -compile_dewav=0 - -for i in "$@" -do - if test "$i" = "-compile_cdrfifo" - then - compile_cdrfifo=1 - elif test "$i" = "-compile_dewav" - then - compile_dewav=1 - elif test "$i" = "-cvs_A60220" - then - libvers="-DCdrskin_libburn_cvs_A60220_tS" - libdax_audioxtr_o= - libdax_msgs_o="libburn/message.o" - cleanup_src_or_obj="cdrskin/cleanup.c" - elif test "$i" = "-libburn_0_2_2" - then - libvers="-DCdrskin_libburn_0_2_2" - libdax_audioxtr_o= - libdax_msgs_o="libburn/message.o" - cleanup_src_or_obj="cdrskin/cleanup.c" - elif test "$i" = "-libburn_0_2_3" - then - libvers="-DCdrskin_libburn_0_2_3" - libdax_audioxtr_o="libburn/libdax_audioxtr.o" - libdax_msgs_o="libburn/libdax_msgs.o" - cleanup_src_or_obj="libburn/cleanup.o" - elif test "$i" = "-newapi" -o "$i" = "-experimental" - then - def_opts="$def_opts -DCdrskin_new_api_tesT" - elif test "$i" = "-oldfashioned" - then - def_opts="$def_opts -DCdrskin_oldfashioned_api_usE" - elif test "$i" = "-no_largefile" - then - largefile_opts= - elif test "$i" = "-do_not_compile_cdrskin" - then - compile_cdrskin=0 - elif test "$i" = "-do_diet" - then - fifo_source= - def_opts="$def_opts -DCdrskin_extra_leaN" - warn_opts= - elif test "$i" = "-do_strip" - then - do_strip=1 - elif test "$i" = "-g" - then - debug_opts="$debug_opts -g" - elif test "$i" = "-O2" - then - debug_opts="$debug_opts -O2" - elif test "$i" = "-help" -o "$i" = "--help" -o "$i" = "-h" - then - echo "cdrskin/compile_cdrskin.sh : to be executed within top level directory" - echo "Options:" - echo " -compile_cdrfifo compile program cdrskin/cdrfifo." - echo " -compile_dewav compile program test/dewav without libburn." - echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006." - echo " -libburn_0_2_2 set macro to match libburn-0.2.2." - echo " -libburn_0_2_3 set macro to match current libburn-SVN." - echo " -no_largefile do not use 64 bit off_t (must match libburn)." - echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin." - echo " -experimental use newly introduced libburn features." - echo " -oldfashioned use pre-0.2.2 libburn features only." - echo " -do_diet produce capability reduced lean version." - echo " -do_strip apply program strip to compiled programs." - echo " -g compile with cc option -g." - echo " -O2 compile with cc option -O2." - echo " -static compile with cc option -static." - exit 0 - elif test "$i" = "-static" - then - static_opts="-static" - fi -done - - -timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" -echo "Version timestamp : $(sed -e 's/#define Cdrskin_timestamP "//' -e 's/"$//' cdrskin/cdrskin_timestamp.h)" -echo "Build timestamp : $timestamp" - -if test "$compile_cdrskin" -then - echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj" - cc -I. \ - $warn_opts \ - $static_opts \ - $debug_opts \ - $libvers \ - $largefile_opts \ - $def_opts \ - \ - -DCdrskin_build_timestamP='"'"$timestamp"'"' \ - \ - -o cdrskin/cdrskin \ - \ - cdrskin/cdrskin.c \ - $fifo_source \ - \ - $cleanup_src_or_obj \ - \ - libburn/async.o \ - libburn/debug.o \ - libburn/drive.o \ - libburn/file.o \ - libburn/init.o \ - libburn/options.o \ - libburn/source.o \ - libburn/structure.o \ - \ - libburn/sg.o \ - libburn/write.o \ - $libdax_audioxtr_o \ - $libdax_msgs_o \ - \ - libburn/mmc.o \ - libburn/sbc.o \ - libburn/spc.o \ - libburn/util.o \ - \ - libburn/sector.o \ - libburn/toc.o \ - \ - libburn/crc.o \ - libburn/lec.o \ - \ - -lpthread - - ret=$? - if test "$ret" = 0 - then - dummy=dummy - else - echo >&2 - echo "+++ FATAL : Compilation of cdrskin failed" >&2 - echo >&2 - exit 1 - fi -fi - -if test "$compile_cdrfifo" = 1 -then - echo "compiling program cdrskin/cdrfifo.c $static_opts $debug_opts" - cc $static_opts $debug_opts \ - -DCdrfifo_standalonE \ - -o cdrskin/cdrfifo \ - cdrskin/cdrfifo.c - - ret=$? - if test "$ret" = 0 - then - dummy=dummy - else - echo >&2 - echo "+++ FATAL : Compilation of cdrfifo failed" >&2 - echo >&2 - exit 2 - fi -fi - -if test "$compile_dewav" = 1 -then - echo "compiling program test/dewav.c -DDewav_without_libburN $static_opts $debug_opts" - cc $static_opts $debug_opts \ - -DDewav_without_libburN \ - -o test/dewav \ - test/dewav.c \ - libburn/libdax_audioxtr.o \ - libburn/libdax_msgs.o \ - \ - -lpthread - - ret=$? - if test "$ret" = 0 - then - dummy=dummy - else - echo >&2 - echo "+++ FATAL : Compilation of test/dewav failed" >&2 - echo >&2 - exit 2 - fi -fi - -if test "$do_strip" = 1 -then - echo "stripping result cdrskin/cdrskin" - strip cdrskin/cdrskin - if test "$compile_cdrfifo" = 1 - then - echo "stripping result cdrskin/cdrfifo" - strip cdrskin/cdrfifo - fi -fi - -echo 'done.' diff --git a/cdrskin/make_timestamp.sh b/cdrskin/make_timestamp.sh deleted file mode 100755 index 957a2c4..0000000 --- a/cdrskin/make_timestamp.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Create version timestamp cdrskin/cdrskin_timestamp.h -# to be executed within ./libburn-* resp ./cdrskin-* - -timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" -echo "Version timestamp : $timestamp" -echo '#define Cdrskin_timestamP "'"$timestamp"'"' >cdrskin/cdrskin_timestamp.h - diff --git a/cdrskin/wiki_plain.txt b/cdrskin/wiki_plain.txt deleted file mode 100644 index 56da798..0000000 --- a/cdrskin/wiki_plain.txt +++ /dev/null @@ -1,204 +0,0 @@ --------------------------------------------------------------------------- - cdrskin Wiki - plain text copy --------------------------------------------------------------------------- - -cdrskin-0.2.5 is the cdrecord compatibility middleware of libburn. - -Its paragon, cdrecord, is a powerful GPL'ed burn program included in Joerg -Schilling's cdrtools. cdrskin strives to be a second source for the services -traditionally provided by cdrecord. Currently it does CD-R and CD-RW. -Its future ability to burn DVD media depends on the development of libburn. - -cdrskin does not contain any bytes copied from cdrecord's sources. -Many bytes have been copied from the message output of cdrecord -runs, though. The most comprehensive technical overview of cdrskin -can be found in cdrskin/README . Online available as : -http://libburn.pykix.org/browser/trunk/cdrskin/README?format=raw - --------------------------------------------------------------------------- - -cdrskin with CD media fails to match its paragon cdrecord on one major field: -Multi session. - -Convenient TAO burn mode is provided in development version 0.2.5 but not in -current "stable" release 0.2.4. - -cdrskin does not provide DVD burning yet. See advise to use dvd+rw-tools -at the end of this text. - --------------------------------------------------------------------------- - -About the command line options of cdrskin: - -There are two families of options: cdrecord-compatible ones and options -which are specific to cdrskin. The latter are mostly used to configure -cdrskin for its task to emulate cdrecord. There are some, nevertheless, -which provide rather exotic unique features of cdrskin. - -The cdrecord-compatible options are listed in the output of - -cdrskin -help - -where the option "help" has *one* dash. -For these options you may expect program behavior that is roughly the -same as described in original man 1 cdrecord . - -Online: http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html - -The cdrskin-specific options are listed by - -cdrskin --help - -where the option "help" has *two* dashes. - -Those have no man page yet. Some are very experimental and should only be -used in coordination with the libburn developer team. -Some are of general user interest, though: - --------------------------------------------------------------------------- - ---devices allows the sysadmin to scan the system for possible drives -and displays their detected properties. -The drives are listed one per line, with fields: - -libburn-drive-number sysadmin-device-file permissions : vendor type - -0 dev='/dev/sg0' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B' - -This feature is valuable since cdrskin -scanbus will not give you -the device file name and its current permissions. -cdrskin will accept of course the proposed dev= option as address -for any usage of the drive. - -Different from cdrecord, cdrskin is intended to be run without special -privileges, i.e. no superuser setuid. It is intended that the sysadmin -controls drive accessability by rw-permissions of the drive rather than -by x-permission of the burn binary. To be usable with cdrskin, the drive -has to offer both, r- and w-permission. - --------------------------------------------------------------------------- - ---fifo_start_empty is a throughput enhancer for unsteady data streams -like they are produced by a compressing archiver program when piping to -CD on-the-fly. It makes better use of the general property of a FIFO -buffer to transport surplus bandwidth into the future. Yep. A time machine. -One-way, i fear. - -FIFO originally was introduced by cdrecord's author Joerg Schilling in order -to protect mediocre burner hardware from suffering buffer underruns -and thus producing misburns (at 1x speed on CD-R media at the price of a -DVD-RAM nowadays). This purpose would not justify a fifo any more - -given the limited life time of burners and the seamless underrun protection -of contemporary consumer drives. - -With an unsteady data stream the task of the buffer is to soak up peak -performance and to release it steadily at the drive's maximum speed. -The larger the buffer the more reserves can be built up and the longer -input drought can be compensated. - -Original cdrecord has the historical property, though, to first wait until -the buffer is completely filled. Best practice for fighting drive -underruns, of course. -With a very fat fs=# buffer (128 MB for 12x CD is not unrealistic) this -can cause a big delay until burning finally starts and takes its due time. - ---fifo_start_empty makes cdrskin start burning without waiting for the -FIFO to be full resp. the data stream to end. It can make use of the -seconds spend with drive preparation and lead-in, it risks a few drive -buffer underruns at the beginning of burn - but modern drives stand this. - -Note: no FIFO can give you better average throughput than the average -throughput of the data source and the throughput of the burner. -It can be used, though, to bring the effective throughput very close -to the theoretical limit. Especially with high speed media. - --------------------------------------------------------------------------- - ---no_rc allows you to surely ban influence from systemwide or user specific -default settings of cdrskin. Possible locations for such settings: - -/etc/default/cdrskin - -/etc/opt/cdrskin/rc - -$HOME/.cdrskinrc - --------------------------------------------------------------------------- - -tao_to_sao_tsize= allows the - actually unsupported - cdrecord option --tao and defines a default track size to be used if - as custom with -tao - -no option tsize=# is given. - -Since -tao is supported in cdrskin-0.2.5 the TAO-to-SAO workaround on its way -to obsolescence. Nevertheless, tao_to_sao_tsize= allows to preset a default -size for SAO mode which is in effect only if no track size is available. - -As in general with cdrskin tsize=# the data source does not have to provide -the full annouced amount of data. Missing data will be padded up by 0-bytes. -Surplus data is supposed to cause an error, though. The burn will then -be a failure in any way. - --------------------------------------------------------------------------- - -dev_translation= may be needed to foist cdrskin to -frontend programs of cdrecord which do *not* ask cdrecord -scanbus but -which make own assumptions and guesses about cdrecord's device addresses. - -Normally, cdrskin understands all addresses which are suitable for cdrecord -under Linux. See cdrskin/README, "Pseudo-SCSI Adresses". -This option is mainly for (yet unknown) exotic configurations or very -stubborn frontend programs. - -If a frontend refuses to work with cdrskin, look into the error protocol -of that frontend, look at the output of a run of cdrskin --devices and give -cdrskin the necessary hint. -Example: Your frontend insists in using "0,0,0" and --devices reported -dev='/dev/hdc' resp. cdrskin dev=ATA -scanbus reported "1,0,0" then this -would be the appropriate translation: - -dev_translation=+0,0,0+/dev/hdc - -The "+" character is a separator to be choosen by you. -Currently i am not aware of the need to choose any other than "+" -unless you get playful with custom translations like - -dev_translation=-"cd+dvd"-1,0,0 - -See http://scdbackup.sourceforge.net/k3b_on_cdrskin.html -for an illustrated example with K3b 0.10 . - --------------------------------------------------------------------------- - -DVD advise: - -For burning of DVD media the cdrskin project currently advises to use -Andy Polyakov's dvd+rw-tools which despite their historic name burn -for me on above burner: DVD+RW, DVD+R, DVD-RW, DVD-R . - -http://fy.chalmers.se/~appro/linux/DVD+RW/tools - -They are not compatible or related to cdrecord resp. cdrecord-ProDVD -(now obsoleted by original source cdrtools cdrecord with identical -capabilities besides the license key). - -If there is sincere and well motivated interest, the cdrskin project could try -to employ growisofs as DVD burning engine. The cdrskin project would prefer to -wait for DVD support being included in libburn, though. -A very limited and specialized cdrecord-compatibility wrapper for growisofs -serves in my project scdbackup. It is not overly hard to make one that serves -some very few fixed use cases. - -To my knowledge, Linux kernels 2.6 do write to DVD+RW via block devices as -they would write to a traditional tape device. Try old tape archiver -commands with addresses like /dev/sr0 or /dev/hdc rather than /dev/mt0 . -I have heard rumors that DVD-RW in mode "restricted overwrite" would be -block device ready, too. My burner is not a real friend of DVD-RW and -in an experiment the burn worked fine - but the result was not identical -to the stream sent to the device. I had similar failure with DVD-RAM, too. - -Beware of the impact of a slow block device on overall system i/o buffering. -It is wise to curb its input to a speed which it is able to deliver to media. -Else your i/o dedicated RAM might buffer a big amount of stream data. - --------------------------------------------------------------------------- - diff --git a/libburn-1.pc.in b/libburn-1.pc.in deleted file mode 100644 index 38f4530..0000000 --- a/libburn-1.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libburn -Description: Disc reading/writing library -Version: @VERSION@ -Requires: -Libs: -L${libdir} -lburn -Libs.private: @THREAD_LIBS@ @LIBBURN_ARCH_LIBS@ -Cflags: -I${includedir}/libburn diff --git a/libburn/Makefile b/libburn/Makefile deleted file mode 100644 index 062350d..0000000 --- a/libburn/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -all clean: - $(MAKE) -C .. -$(MAKEFLAGS) $@ - -.PHONY: all clean diff --git a/libburn/Makefile.am b/libburn/Makefile.am deleted file mode 100644 index 144ece7..0000000 --- a/libburn/Makefile.am +++ /dev/null @@ -1,65 +0,0 @@ -pkgconfigdir=$(libdir)/pkgconfig -libincludedir=$(includedir)/libburn - -lib_LTLIBRARIES = libburn.la - -libburn_la_SOURCES = \ - async.c \ - async.h \ - crc.c \ - crc.h \ - debug.c \ - debug.h \ - drive.c \ - drive.h \ - file.c \ - file.h \ - init.c \ - init.h \ - lec.c \ - lec.h \ - message.c \ - message.h \ - mmc.c \ - mmc.h \ - null.c \ - null.h \ - options.c \ - options.h \ - read.c \ - read.h \ - sbc.c \ - sbc.h \ - sector.c \ - sector.h \ - sg.c \ - sg.h \ - spc.c \ - spc.h \ - source.h \ - source.c \ - structure.c \ - structure.h \ - toc.c \ - toc.h \ - transport.h \ - util.c \ - util.h \ - write.c \ - write.h - -libinclude_HEADERS = libburn.h - -## ========================================================================= ## -indent_files = $(libburn_la_SOURCES) - -indent: $(indent_files) - indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \ - -cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \ - -lp -saf -sai -nprs -npsl -saw -sob -ss -ut \ - -sbi0 -nsc -ts8 -npcs -ncdb -fca \ - $^ - -.PHONY: indent - -## ========================================================================= ## diff --git a/libburn/asserts.txt b/libburn/asserts.txt deleted file mode 100644 index b079158..0000000 --- a/libburn/asserts.txt +++ /dev/null @@ -1,792 +0,0 @@ -List of assert() calls in libburn. 6 Oct 2006. - -Format: - ------------------------------------------------------------------------------- - - Number) grep'ed line - (++ before number means: is fully done, + means is done so far ) -function(): -Description of abort condition. - -Possible callers and their relation to the abort condition. - -: Error Evaluation -=> Consequences - -Eventual implementation timestamp - ------------------------------------------------------------------------------- - -++ 1) libburn/async.c: assert(a != NULL); /* wasn't found.. this should not be possible */ -static remove_worker(): -A thread describing structure (struct w_list) could not be found in -order to be released. - -Called by API burn_drive_scan() -Called by static erase_worker_func() , thread under API burn_disc_erase() -Called by static write_disc_worker_func(), thread under API burn_disc_write() -All three want to clean up after they are done. - -: Severe Libburn Error -=> issue LIBDAX_MSGS_SEV_WARNING - -ts A61006 - ------------------------------------------------------------------------------- - -++ 2) libburn/async.c: assert(!(workers && workers->drive)); -API burn_drive_scan(): -Before spawning a thread, the function refuses work because another -drive activity is going on. - -: Severe Application Error -=> return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_SORRY - -ts A61006 - ------------------------------------------------------------------------------- - -+ 3) libburn/async.c: assert(workers == NULL); -API burn_drive_scan(): -After thread is done and remover_worker() succeeded, there is still a -worker registered. Shall probably detect roguely appeared burn or -erase runs. (I consider to install a mutex shielded function for that.) - -: Severe Libburn Error -=> Same as 1) - -ts A61006 - ------------------------------------------------------------------------------- - -++ 4) libburn/async.c: assert(drive); - libburn/async.c: assert(!SCAN_GOING()); - libburn/async.c: assert(!find_worker(drive)); -API burn_disc_erase(): -Wants to see a drive (assumes NULL == 0), wants to see no scan and -wants to see no other worker on that drive. I.e. this would tolerate -a parallel activity on another drive. - -: Severe Application Error -=> (no return value), issue LIBDAX_MSGS_SEV_SORRY - -ts A61006 - ------------------------------------------------------------------------------- - -++ 5) libburn/async.c: assert(!SCAN_GOING()); - libburn/async.c: assert(!find_worker(opts->drive)); -API burn_disc_write(): -Same as 4) - -: Severe Application Error -=> Same as 4) - -ts A61006 - ---------------------------------------------------------------------- - -++ 6) libburn/drive.c: assert(d->busy == BURN_DRIVE_IDLE); -API burn_drive_release(): -A drive is not idle on release. - -: Severe Application Error -=> Same as 4) - -ts A61007 - ------------------------------------------------------------------------------- - -++ 7) libburn/drive.c: assert(d->released); -burn_wait_all() -A drive is found grabbed. - -Called by burn_drive_scan_sync(), thread under API burn_drive_scan() -Called by API burn_finish - -: Severe Application Error -=> rename and redefine burn_wait_all() : now burn_drives_are_clear() -=> change all use of burn_wait_all() -=> Move tests up to burn_drive_scan() -=> There: return -1; issue LIBDAX_MSGS_SEV_SORRY - -ts A61007 - ------------------------------------------------------------------------------- - -++ 8) libburn/drive.c: assert(!d->released); -API burn_disc_get_status() -Attempt to read status of non-grabbed drive. - -: Severe Application Error -=> extend enum burn_disc_status by BURN_DISC_UNGRABBED -=> return BURN_DISC_UNGRABBED, issue LIBDAX_MSGS_SEV_SORRY - -ts A61007 - ------------------------------------------------------------------------------- - -++ 9) libburn/drive.c: assert( /* (write_type >= BURN_WRITE_PACKET) && */ -burn_drive_get_block_types(): -Will not work on BURN_WRITE below BURN_WRITE_RAW. - -Called by -nobody- ? - -: Severe Application Error -=> inactivate unused function - -ts A61007 - ------------------------------------------------------------------------------- - -++ 10) libburn/drive.c: assert(d->idata); - libburn/drive.c: assert(d->mdata); -static drive_getcaps(): -sg.c:enumerate_common() did not succeed in creating a proper struct burn_drive -Called by burn_drive_scan_sync() - -: Severe System Error -=> This could possibly really stay an abort() because the reason is - a plain failure of the system's memory management. -=> Detect this failure already in enumerate_common(), - issue LIBDAX_MSGS_SEV_FATAL, return - -ts A61007 - ------------------------------------------------------------------------------- - -++ 11) libburn/drive.c: assert(burn_running); -burn_drive_scan_sync(): -The library was not initialized. - -Called as thread by API burn_drive_scan() - -: Severe Application Error -=> Move this test up to burn_drive_scan() -=> There: return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_FATAL - -ts A61007 - ------------------------------------------------------------------------------- - -++ 12) libburn/drive.c: assert(d->released == 1); -burn_drive_scan_sync(): -Inactivated - -: (Severe Application Error) -=> throw out inactivated code - -ts A61007 - ------------------------------------------------------------------------------- - -++ 13) libburn/drive.c: assert(strlen(d->devname) < BURN_DRIVE_ADR_LEN); -burn_drive_raw_get_adr(): -An enumerated device address is longer than the API's maximum length - -Called by API burn_drive_get_adr() -Called by API burn_drive_obtain_scsi_adr() - -: Severe Libburn Error -=> return -1; in all three functions, enhance burn_drive_get_adr @return docs -=> issue LIBDAX_MSGS_SEV_SORRY - -ts A61007 - ------------------------------------------------------------------------------- - -++ 14) libburn/drive.c: assert(drive_info->drive!=NULL); -API burn_drive_get_adr(): -Drive info has no drive attached. - -: Severe Libburn Error (unlikely, will eventually SIGSEGV on NULL) -=> delete assert - -ts A61007 - ------------------------------------------------------------------------------- - -++ 15) libburn/init.c: assert(burn_running); -API burn_finish(): -The library is not initialized - -: Severe Application Error -=> return (assume no msg system) - -ts A61007 - ------------------------------------------------------------------------------- - -++ 16) libburn/init.c: assert(burn_running); -API burn_preset_device_open(): -The library is not initialized - -: Severe Application Error -=> return (assume no msg system) - -ts A61007 - ------------------------------------------------------------------------------- - -++ 17) libburn/mmc.c: assert(o->drive == d); -mmc_close_disc(): -alias: struct burn_drive.close_disc() -Parameters struct burn_drive and struct burn_write_opts do not match - -Called by -nobody- ? - -( => Disable unused function ? ) -=> removed redundant parameter struct burn_drive - -ts A61009 - ------------------------------------------------------------------------------- - -++ 18) libburn/mmc.c: assert(o->drive == d); -mmc_close_session(): -Same as 17) -alias: struct burn_drive.close_session() - -Called by -nobody- ? - -( => Disable unused function ? ) -=> removed redundant parameter struct burn_drive - -ts A61009 - ------------------------------------------------------------------------------- - -++ 19) libburn/mmc.c: assert(buf->bytes >= buf->sectors); /* can be == at 0... */ -mmc_write_12(): -- Unclear what .bytes and .sectors mean in struct buffer - - -Called by -nobody- ? - -=> problems with filling the write buffer have to be handled by callers -=> delete assert - -ts A61009 - ------------------------------------------------------------------------------- - -++ 20) libburn/mmc.c: assert(buf->bytes >= buf->sectors); /* can be == at 0... */ -mmc_write(): -- Unclear what .bytes and .sectors mean in struct buffer - - -libburn/mmc.c: c.page->sectors = errorblock - start + 1; -mmc_read_sectors() by toc_find_modes() by mmc_read_toc() alias drive.read_toc() -by burn_drive_grab() -This seems to be unrelated to mmc_write(). - -libburn/sector.c: out->sectors++; -get_sector() -Seems to hand out sector start pointer in opts->drive->buffer -and to count reservation transactions as well as reserved bytes. -Ensures out->bytes >= out->sectors - - -libburn/mmc.c: c.page->bytes = s->count * 8; -mmc_send_cue_sheet() -Does not use mmc_write() but directly (sg_)issue_command() - -libburn/sector.c: out->bytes += seclen; -get_sector() -See above -Ensures out->bytes >= out->sectors - -libburn/spc.c: c.page->bytes = 8 + 2 + d->mdata->retry_page_length; -spc_select_error_params() -Does not use mmc_write() but directly (sg_)issue_command() - -libburn/spc.c: c.page->bytes = 8 + 2 + d->mdata->write_page_length; -spc_select_error_params() -Does not use mmc_write() but directly (sg_)issue_command() - -libburn/spc.c: c.page->bytes = 8 + 2 + 0x32; -spc_probe_write_modes() -Does not use mmc_write() but directly (sg_)issue_command() - -alias struct burn_drive.write() -Called by static get_sector, by many -Called by burn_write_flush -Called by burn_write_track - -=> problems with filling the write buffer have to be handled by callers -=> delete assert - -ts A61009 - ------------------------------------------------------------------------------- - -++ 21) libburn/mmc.c: assert(((dlen - 2) % 11) == 0); -mmc_read_toc(): -- Is defunct - - -=> :) - -ts A61009 - ------------------------------------------------------------------------------- - -++ 22) libburn/mmc.c: assert(len >= 0); -mmc_read_sectors(): -Catches a bad parameter - -alias: struct burn_drive.read_sectors() -Called by API burn_disc_read() , - is defunct -, one could catch the problem -Called by toc_find_modes(), problem cannot occur: mem.sectors = 1; - -: Severe Libburn Error -(=> in burn_disc_read() check page.sectors before d->read_sectors() ) -=> :) - -ts A61009 - ------------------------------------------------------------------------------- - -++ 23) libburn/mmc.c: assert(d->busy); -mmc_read_sectors(): -Catches use of a drive that is not marked as busy - -alias: struct burn_drive.read_sectors() -Called by API burn_disc_read() , - is defunct -, busy = BURN_DRIVE_READING; -Called by toc_find_modes(), does the same assert. To be solved there. - -: Severe Libburn Error -=> :) - -ts A61009 - ------------------------------------------------------------------------------- - -++ 24) libburn/options.c: assert(0); -API burn_write_opts_set_write_type(): -Detects unsuitable enum burn_write_types write_type and int block_type. -API promises return 0 on failure - -: Severe Application Error -=> issue LIBDAX_MSGS_SEV_SORRY -=> should also detect problem of 26) : wrong write_type,block_type combination - by calling sector_get_outmode() and checking for -1 -=> should also detect problem of 41) : unknown block_type - by spc_block_type() and checking for -1 -=> delete assert(0) - -ts A61007 - ------------------------------------------------------------------------------- - -++ 25) libburn/read.c: assert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000)); - libburn/read.c: assert(!d->busy); - libburn/read.c: assert(d->toc->valid); - libburn/read.c: assert(o->datafd != -1); -API burn_disc_read(): -- ? - - -burn_disc_read() is defunct -OPTIONS_VERSION does not occur outside this line - -( => one would return ) -( 22) => catch page.sectors<0 before d->read_sectors() ) -( 37) => catch ! d->mdata->valid ) -=> :) - -ts A61007 - ------------------------------------------------------------------------------- - -++ 26) libburn/sector.c: assert(0); /* return BURN_MODE_UNIMPLEMENTED :) */ -static get_outmode(): -burn_write_opts is wrongly programmed with .write_type and .block_type - -: Severe Application Error -=> This gets handled by burn_write_opts_set_write_type() - ts A61007 by new semi-public sector_get_outmode() -=> delete assert() - -ts A61007 - ------------------------------------------------------------------------------- - -++ 27) libburn/sector.c: assert(outlen >= inlen); - libburn/sector.c: assert(outmode & BURN_MODE_RAW); - libburn/sector.c: assert(offset != -1); -static convert_data(): -Several unacceptable settings within struct burn_write_opts - -Called by sector_toc() sector_pregap() sector_postgap() sector_lout() - sector_data() - -: Severe Application Error -=> change return type of convert_data() -=> all callers interpret return value and eventually return failure - -ts A61007 - ------------------------------------------------------------------------------- - -++ 28) libburn/sector.c: assert(0); -static char_to_isrc(): -Called by subcode_user() with data set by API burn_track_set_isrc() -Some character conversion fails on wrong input - -: Severe Application Error -=> burn_track_set_isrc() has to make sure that only good data are set -=> char_to_isrc() returns 0 as default -=> delete assert() - -ts A61008 - ------------------------------------------------------------------------------- - -++ 29) libburn/sector.c: assert(qmode == 1 || qmode == 2 || qmode == 3); -subcode_user(): -- can not happen - - -: Unknown reason of assert() -=> remove assert() - -ts A61010 - ------------------------------------------------------------------------------- - -++ 30) libburn/sector.c: assert(modebyte == 1); -sector_headers(): -Does only accept modes BURN_AUDIO, BURN_MODE1 or write_type BURN_WRITE_SAO - -Called by sector_toc() sector_pregap() sector_postgap() sector_lout() - sector_data() - -: Severe Libburn Error -=> new functions sector_headers_is_ok(), burn_disc_write_is_ok() - help to catch problem in API burn_disc_write() -=> issue LIBDAX_MSGS_SEV_FATAL - -ts A61009 - ------------------------------------------------------------------------------- - -++ 31) libburn/sector.c: assert(0); -process_q() -- defunct - - -=> :) - -ts A61009 - ------------------------------------------------------------------------------- - -++ 32) libburn/sg.c: assert("drive busy" == "non fatal"); -sg_handle_busy_device(): -Intentional abort preset by the app - -=> change to abort() - -ts A61007 - ------------------------------------------------------------------------------- - -++ 33) libburn/sg.c: assert(fd != -1337); -sg_grab(): -The drive device file could not be opened - -:Severe External Problem -=> obsolete by normal drive open failure handling - -ts A61007 - ------------------------------------------------------------------------------- - -++ 34) libburn/sg.c: assert(!c->page); -sg_issue_command(): -An SCSI command of direction NO_TRANSFER may not have a .page != NULL. - -Since it is about exposing a libburn detail towards the sg driver, i believe -it is sufficient to just not use it. - -: Libburn Error -=> enhance internal logics of sg_issue_command() - -ts A61007 - ------------------------------------------------------------------------------- - -++ 35) libburn/sg.c: assert(c->page->bytes > 0); -sg_issue_command(): -An SCSI command of direction TO_DRIVE wants to transfer 0 bytes. - -: Severe Libburn Error -=> set command.error = 1 and return 0 - -ts A61010 - ------------------------------------------------------------------------------- - -++ 36) libburn/sg.c: assert(err != -1); -sg_issue_command(): -The transfer of the command via ioctl() failed - -: Severe Transport Level Problem -=> close drive fd, set idle and released -=> set command.error = 1 and return -1 - -ts A61010 - ------------------------------------------------------------------------------- - -++ 37) libburn/spc.c: assert(d->mdata->valid); -spc_select_error_params(): -Drive was not properly programmed - -alias struct burn_drive.send_parameters() -Called by burn_disc_read, - defunct - - -: Severe Application Error -=> moved up as mangled assert to burn_disc_read() - -ts A61007 - ------------------------------------------------------------------------------- - -++ 38) libburn/spc.c: assert(d->mdata->cdr_write || d->mdata->cdrw_write || -spc_sense_write_params(): -Drive does not offer write of any known media type - -alias struct burn_drive.read_disc_info() -Called by API burn_drive_grab (assert test made there in soft) - -: Severe Command Level Problem -=> remove assert() - -ts A61007 - ------------------------------------------------------------------------------- - -++ 39) libburn/spc.c: assert(o->drive == d); -spc_select_write_params(): -Drive does not match struct burn_write_opts - -alias struct burn_drive.send_write_parameters() -Called by mmc_close_disc() (-defunct- ?), mmc_close_session() (-defunct- ?), - burn_write_track() (d = o->drive;), - burn_disc_write_sync() d = (o->drive;) - -: Severe Libburn Error -=> remove assert() - -ts A61007 - ------------------------------------------------------------------------------- - -++ 40) libburn/spc.c: assert(d->mdata->valid); -spc_select_write_params(): -Drive was not properly programmed - -Called by (see 39) - burn_write_track() by burn_write_session() by burn_disc_write_sync() - burn_disc_write_sync() indirectly by API burn_disc_write() - -: Severe Libburn Error -=> caught in burn_disc_write() now - -ts A61007 - ------------------------------------------------------------------------------- - -++ 41) libburn/spc.c: assert(0); -spc_block_type(): -Unknown value with enum burn_block_types - -Called by spc_select_write_params, uses burn_write_opts.block_type, - set by API burn_write_opts_set_write_type() - -: Severe Application Error -=> catch in API burn_write_opts_set_write_type - by calling spc_block_type() -=> delete assert - -ts A61007 - ------------------------------------------------------------------------------- - -++ 42) libburn/structure.c: assert(!(pos > BURN_POS_END));\ -macro RESIZE -An illegal list index is given by the app. - -( TO->NEW##s obviusly means to append "s" to cpp result of TO->NEW ) -Used by API burn_session_add_track() and API burn_disc_add_session() - -: Severe Application Error -=> replace assert by if-and-return-0 - -ts A61008 - ------------------------------------------------------------------------------- - -++ 43) libburn/structure.c: assert(s->track != NULL); -API burn_session_remove_track() -An application supplied pointer is NULL - -: Severe Application Error -=> replace by if-and-return-0 - -ts A61008 - ------------------------------------------------------------------------------- - -++ 44) libburn/structure.c: assert((country[i] >= '0' || country[i] < '9') && - libburn/structure.c: assert((owner[i] >= '0' || owner[i] < '9') && - libburn/structure.c: assert(year <= 99); - libburn/structure.c: assert(serial <= 99999); -API burn_track_set_isrc(): -Illegal texts supplied by application. -The logical expression is always true ! - -: Severe Application Error -=> issue LIBDAX_MSGS_SEV_SORRY and return -=> delete assert -=> delete assert 28) in char_to_isrc() - -ts A61008 - ------------------------------------------------------------------------------- - -++ 45) libburn/toc.c: assert(0); /* unhandled! find out ccd's -static write_clonecd2(): - - - defunct -, - unused - - -=> mangle assert - -ts A61008 - ------------------------------------------------------------------------------- - -++ 46) libburn/toc.c: assert(d->busy); -toc_find_modes(): -The drive to work on is not marked busy - -Called by mmc_read_toc() alias read_toc() by ... burn_drive_grab() - -: Severe Libburn Error -=> to be prevented on the higher levels -=> delete assert - -ts A61008 - ------------------------------------------------------------------------------- - -++ 47) libburn/util.c: assert(s); -burn_strdup() -Abort on NULL string which would elsewise cause a SIGSEGV - -Used once in enumerate_common() with a string that worked with open(2) before - -: Severe Libburn Error -=> delete assert - -ts A61008 - ------------------------------------------------------------------------------- - -++ 48) libburn/util.c: assert(s); -burn_strndup(): - unused - -Same as 47 - -: Severe Libburn Error -=> return NULL -=> delete assert - -ts A61008 - ------------------------------------------------------------------------------- - -++ 49) libburn/util.c: assert(n > 0); -burn_strndup(): - unused - -Prevent problems by negative copy length - -: Severe Libburn Error -=> return NULL -=> delete assert - -ts A61008 - ------------------------------------------------------------------------------- - -++ 50) libburn/write.c: assert(0); -static type_to_ctrl(): -Unsuitable mode to be converted into "ctrl" -Called by static type_to_form() finally burn_create_toc_entries() - -: Severe Application Error -=> to be caught in burn_track_define_data by calling for test type_to_form() -=> return -1; - -ts A61008 - ------------------------------------------------------------------------------- - -++ 51) libburn/write.c: assert(0); - libburn/write.c: assert(0); /* XXX someone's gonna want this sometime */ -static type_to_form(): -Does not like BURN_MODE0 or BURN_MODE2 but tolerates unknown modes - -Called by static burn_create_toc_entries() by burn_disc_write_sync() - -: Undocumented Libburn Restriction -=> set *form = -1 , *ctladr = 0xff , return -=> make function non-static -=> call for test in API burn_track_define_data() - -ts A61009 - ------------------------------------------------------------------------------- - -++ 52) libburn/write.c: assert(ptr); -static add_cue(): -realloc() failed - -Called by burn_create_toc_entries() by burn_disc_write_sync() -(burn_create_toc_entries is ignorant towards own potential memory problems) -(This could possibly really stay an abort() because the reason is - a plain failure of the system's memory management.) - -: Severe System Error -=> change return type of add_cue to int -=> react on return -1 in burn_create_toc_entries, return NULL on failure -=> abort burn_disc_write_sync() on NULL return - -ts A61009 - ------------------------------------------------------------------------------- - -++ 53) libburn/write.c: assert(d->toc_entry == NULL); -burn_create_toc_entries(): -Multiple usage of struct burn_drive.toc_entry - -Called by burn_disc_write_sync() -This will probably trigger an abort with disc->sessions > 1 -(disc->sessions is incremented in macro RESIZE() as "NEW##s") - -: Design Problem -( => ? disallow multiple sessions ? ) -=> replace assert by soft means and wait what happens - -ts A61009 - ------------------------------------------------------------------------------- - -++ 54) libburn/write.c: assert(0); -burn_sector_length(): -Only BURN_AUDIO, BURN_MODE_RAW, BURN_MODE1 are allowed - -Called by get_sector(), convert_data(), ... - -=> call burn_sector_length() for test in API burn_track_define_data() -=> replace assert by -1 - -ts A61009 - ------------------------------------------------------------------------------- - diff --git a/libburn/async.c b/libburn/async.c deleted file mode 100644 index e48d719..0000000 --- a/libburn/async.c +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include "libburn.h" -#include "transport.h" -#include "drive.h" -#include "write.h" -#include "options.h" -#include "async.h" -#include "init.h" - -#include -#include - -/* -#include -*/ -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - -#define SCAN_GOING() (workers && !workers->drive) - -typedef void *(*WorkerFunc) (void *); - -struct scan_opts -{ - struct burn_drive_info **drives; - unsigned int *n_drives; - - int done; -}; - -struct erase_opts -{ - struct burn_drive *drive; - int fast; -}; - -struct write_opts -{ - struct burn_drive *drive; - struct burn_write_opts *opts; - struct burn_disc *disc; -}; - -struct w_list -{ - struct burn_drive *drive; - pthread_t thread; - - struct w_list *next; - - union w_list_data - { - struct scan_opts scan; - struct erase_opts erase; - struct write_opts write; - } u; -}; - -static struct w_list *workers; - -static struct w_list *find_worker(struct burn_drive *d) -{ - struct w_list *a; - - for (a = workers; a; a = a->next) - if (a->drive == d) - return a; - return NULL; -} - -static void add_worker(struct burn_drive *d, WorkerFunc f, void *data) -{ - struct w_list *a; - struct w_list *tmp; - - a = malloc(sizeof(struct w_list)); - a->drive = d; - a->u = *(union w_list_data *)data; - - /* insert at front of the list */ - a->next = workers; - tmp = workers; - workers = a; - - if (d) - d->busy = BURN_DRIVE_SPAWNING; - - if (pthread_create(&a->thread, NULL, f, a)) { - free(a); - workers = tmp; - return; - } -} - -static void remove_worker(pthread_t th) -{ - struct w_list *a, *l = NULL; - - for (a = workers; a; l = a, a = a->next) - if (a->thread == th) { - if (l) - l->next = a->next; - else - workers = a->next; - free(a); - break; - } - - /* ts A61006 */ - /* a ssert(a != NULL);/ * wasn't found.. this should not be possible */ - if (a == NULL) - libdax_msgs_submit(libdax_messenger, -1, 0x00020101, - LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, - "remove_worker() cannot find given worker item", 0, 0); -} - -static void *scan_worker_func(struct w_list *w) -{ - burn_drive_scan_sync(w->u.scan.drives, w->u.scan.n_drives); - w->u.scan.done = 1; - return NULL; -} - -int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives) -{ - struct scan_opts o; - int ret = 0; - - /* ts A61006 : moved up from burn_drive_scan_sync , former Assert */ - if (!burn_running) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020109, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Library not running (on attempt to scan)", 0, 0); - *drives = NULL; - *n_drives = 0; - return -1; - } - - /* cant be anything working! */ - - /* ts A61006 */ - /* a ssert(!(workers && workers->drive)); */ - if (workers != NULL && workers->drive != NULL) { -drive_is_active:; - libdax_msgs_submit(libdax_messenger, -1, 0x00020102, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "A drive operation is still going on (want to scan)", - 0, 0); - *drives = NULL; - *n_drives = 0; - return -1; - } - - if (!workers) { - /* start it */ - - /* ts A61007 : test moved up from burn_drive_scan_sync() - was burn_wait_all() */ - if (!burn_drives_are_clear()) - goto drive_is_active; - *drives = NULL; - *n_drives = 0; - - o.drives = drives; - o.n_drives = n_drives; - o.done = 0; - add_worker(NULL, (WorkerFunc) scan_worker_func, &o); - } else if (workers->u.scan.done) { - /* its done */ - ret = workers->u.scan.done; - remove_worker(workers->thread); - - /* ts A61006 */ - /* a ssert(workers == NULL); */ - if (workers != NULL) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020101, - LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, - "After scan a drive operation is still going on", - 0, 0); - return -1; - } - - } else { - /* still going */ - } - return ret; -} - -static void *erase_worker_func(struct w_list *w) -{ - burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast); - remove_worker(pthread_self()); - return NULL; -} - -void burn_disc_erase(struct burn_drive *drive, int fast) -{ - struct erase_opts o; - - /* ts A61006 */ - /* a ssert(drive); */ - /* a ssert(!SCAN_GOING()); */ - /* a ssert(!find_worker(drive)); */ - if((drive == NULL)) { - libdax_msgs_submit(libdax_messenger, drive->global_index, - 0x00020104, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "NULL pointer caught in burn_disc_erase", 0, 0); - return; - } - if ((SCAN_GOING()) || find_worker(drive)) { - libdax_msgs_submit(libdax_messenger, drive->global_index, - 0x00020102, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "A drive operation is still going on (want to erase)", - 0, 0); - return; - } - - o.drive = drive; - o.fast = fast; - add_worker(drive, (WorkerFunc) erase_worker_func, &o); -} - -static void *write_disc_worker_func(struct w_list *w) -{ - burn_disc_write_sync(w->u.write.opts, w->u.write.disc); - - /* the options are refcounted, free out ref count which we added below - */ - burn_write_opts_free(w->u.write.opts); - - remove_worker(pthread_self()); - return NULL; -} - -void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) -{ - struct write_opts o; - - /* ts A61006 */ - /* a ssert(!SCAN_GOING()); */ - /* a ssert(!find_worker(opts->drive)); */ - if ((SCAN_GOING()) || find_worker(opts->drive)) { - libdax_msgs_submit(libdax_messenger, opts->drive->global_index, - 0x00020102, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "A drive operation is still going on (want to write)", - 0, 0); - return; - } - /* ts A61007 : obsolete Assert in spc_select_write_params() */ - if (!opts->drive->mdata->valid) { - libdax_msgs_submit(libdax_messenger, - opts->drive->global_index, 0x00020113, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Drive capabilities not inquired yet", 0, 0); - return; - } - /* ts A61009 : obsolete Assert in sector_headers() */ - if (! burn_disc_write_is_ok(opts, disc)) /* issues own msgs */ - return; - - o.drive = opts->drive; - o.opts = opts; - o.disc = disc; - - opts->refcount++; - - add_worker(opts->drive, (WorkerFunc) write_disc_worker_func, &o); -} - -void burn_async_join_all(void) -{ - void *ret; - - while (workers) - pthread_join(workers->thread, &ret); -} diff --git a/libburn/async.h b/libburn/async.h deleted file mode 100644 index 0e1d667..0000000 --- a/libburn/async.h +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__ASYNC_H -#define BURN__ASYNC_H - -void burn_async_join_all(void); -struct burn_write_opts; -#endif /* BURN__ASYNC_H */ diff --git a/libburn/back_hacks.h b/libburn/back_hacks.h deleted file mode 100644 index b086620..0000000 --- a/libburn/back_hacks.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - - This file bundles variables which disable changes in libburn which are - not yet completely accepted. - - The use of these variables is *strongly discouraged* unless you have sincere - reason and are willing to share your gained knowledge with the libburn - developers. - - Do *not silently rely* on these variables with your application. Tell us - that you needed one or more of them. They are subject to removal as soon - as consense has been found about correctness of the change they revoke. - - Value 0 means that the new behavior is enabled. Any other value enables - the described old time behavior. - - If you doubt one of the changes here broke your application, then do - *in your application*, *not here* : - - - #include "libburn/back_hacks.h" like you include "libburn/libburn.h" - - - Set the libburn_back_hack_* variable of your choice to 1. - In your app. Not here. - - - Then start and use libburn as usual. Watch out for results. - - - If you believe to have detected a flaw in our change, come forward - and report it to the libburn developers. Thanks in advance. :) - -*/ - -/** Do not define this macro in your application. Only libburn/init.c is - entitled to set it. -*/ -#ifdef BURN_BACK_HACKS_INIT - - -/** Corresponds to http://libburn.pykix.org/ticket/42 - Reinstates the old ban not to blank appendable CD-RW. We see no reason - for this ban yet. It appears unusual. But maybe it patches a bug. -*/ -int libburn_back_hack_42= 0; - - -#else /* BURN_BACK_HACKS_INIT */ - -/* Note: no application programmer info beyond this point */ - - -extern int libburn_back_hack_42; - -#endif /* ! BURN_BACK_HACKS_INIT */ - - diff --git a/libburn/cleanup.c b/libburn/cleanup.c deleted file mode 100644 index 6c9f3b6..0000000 --- a/libburn/cleanup.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - cleanup.c , Copyright 2006 Thomas Schmitt - - A signal handler which cleans up an application and exits. - - Provided under GPL license within GPL projects, BSD license elsewise. -*/ - -/* - cc -g -o cleanup -DCleanup_standalonE cleanup.c -*/ - -#include -#include -#include -#include -#include -#include - -#include -typedef void (*sighandler_t)(int); - - -#include "cleanup.h" - -#ifdef __FreeBSD__ - -/* Signals to be caught */ -static int signal_list[]= { - SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, - SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, - SIGTTOU, - SIGBUS, SIGPROF, SIGSYS, SIGTRAP, - SIGVTALRM, SIGXCPU, SIGXFSZ, -1 -}; -static char *signal_name_list[]= { - "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", - "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", - "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", - "SIGTTOU", - "SIGBUS", "SIGPROF", "SIGSYS", "SIGTRAP", - "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" -}; -static int signal_list_count= 23; - -#else /* __FreeBSD__ */ - -/* Signals to be caught */ -static int signal_list[]= { - SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, - SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, - SIGTTOU, - SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, - SIGVTALRM, SIGXCPU, SIGXFSZ, -1 -}; -static char *signal_name_list[]= { - "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", - "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", - "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", - "SIGTTOU", - "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", - "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" -}; -static int signal_list_count= 24; - -#endif /* ! __FreeBSD__ */ - -/* Signals not to be caught */ -static int non_signal_list[]= { - SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1 -}; -static int non_signal_list_count= 4; - - -/* run time dynamic part */ -static char cleanup_msg[4096]= {""}; -static int cleanup_exiting= 0; - -static void *cleanup_app_handle= NULL; -static Cleanup_app_handler_T cleanup_app_handler= NULL; -static int cleanup_perform_app_handler_first= 0; - - -static int Cleanup_handler_exit(int exit_value, int signum, int flag) -{ - int ret; - - if(cleanup_msg[0]!=0) - fprintf(stderr,"\n%s\n",cleanup_msg); - if(cleanup_perform_app_handler_first) - if(cleanup_app_handler!=NULL) { - ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); - if(ret==2 || ret==-2) - return(2); - } - if(cleanup_exiting) { - fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n", - getpid(),signum); - return(0); - } - cleanup_exiting= 1; - alarm(0); - if(!cleanup_perform_app_handler_first) - if(cleanup_app_handler!=NULL) { - ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); - if(ret==2 || ret==-2) - return(2); - } - exit(exit_value); -} - - -static void Cleanup_handler_generic(int signum) -{ - int i; - - sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno); - for(i= 0; imax_sig) - max_sig= signal_list[i]; - if(signal_list[i]=non_signal_list_count) { - if(i==SIGABRT && (flag&8)) - signal(i,Cleanup_handler_generic); - else - signal(i,sig_handler); - } - } - return(1); -} - - -#ifdef Cleanup_standalonE - -struct Demo_apP { - char *msg; -}; - - -int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag) -{ - printf("Handling exit of demo application on signal %d. msg=\"%s\"\n", - signum,demoapp->msg); - return(1); -} - - -main() -{ - struct Demo_apP demoapp; - - demoapp.msg= "Good Bye"; - Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); - - if(1) { /* change to 0 in order to wait for external signals */ - char *cpt= NULL,c; - printf("Intentionally provoking SIGSEGV ...\n"); - c= *cpt; - } else { - printf("killme: %d\n",getpid()); - sleep(3600); - } - - Cleanup_set_handlers(NULL,NULL,1); - exit(0); -} - -#endif /* Cleanup_standalonE */ diff --git a/libburn/cleanup.h b/libburn/cleanup.h deleted file mode 100644 index a9d3551..0000000 --- a/libburn/cleanup.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - cleanup.c , Copyright 2006 Thomas Schmitt - - A signal handler which cleans up an application and exits. - - Provided under GPL license within GPL projects, BSD license elsewise. -*/ - -#ifndef Cleanup_includeD -#define Cleanup_includeD 1 - - -/** Layout of an application provided cleanup function using an application - provided handle as first argument and the signal number as second - argument. The third argument is a flag bit field with no defined bits yet. - If the handler returns 2 or -2 then it has delegated exit() to some other - instance and the Cleanup handler shall return rather than exit. -*/ -typedef int (*Cleanup_app_handler_T)(void *, int, int); - - -/** Establish exiting signal handlers on (hopefully) all signals that are - not ignored by default or non-catchable. - @param handle Opaque object which knows how to cleanup application - @param handler Function which uses handle to perform application cleanup - @param flag Control Bitfield - bit0= reset to default signal handling -*/ -int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, - int flag); - - -#endif /* ! Cleanup_includeD */ - diff --git a/libburn/crc.c b/libburn/crc.c deleted file mode 100644 index fddc5b4..0000000 --- a/libburn/crc.c +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include "crc.h" - -static unsigned short ccitt_table[256] = { - 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 -}; - -unsigned long crc32_table[256] = { - 0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L, - 0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L, - 0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L, - 0x06C00C00L, 0x96510D01L, 0x97E10E01L, 0x07700F00L, - 0x99011001L, 0x09901100L, 0x08201200L, 0x98B11301L, - 0x0B401400L, 0x9BD11501L, 0x9A611601L, 0x0AF01700L, - 0x0D801800L, 0x9D111901L, 0x9CA11A01L, 0x0C301B00L, - 0x9FC11C01L, 0x0F501D00L, 0x0EE01E00L, 0x9E711F01L, - 0x82012001L, 0x12902100L, 0x13202200L, 0x83B12301L, - 0x10402400L, 0x80D12501L, 0x81612601L, 0x11F02700L, - 0x16802800L, 0x86112901L, 0x87A12A01L, 0x17302B00L, - 0x84C12C01L, 0x14502D00L, 0x15E02E00L, 0x85712F01L, - 0x1B003000L, 0x8B913101L, 0x8A213201L, 0x1AB03300L, - 0x89413401L, 0x19D03500L, 0x18603600L, 0x88F13701L, - 0x8F813801L, 0x1F103900L, 0x1EA03A00L, 0x8E313B01L, - 0x1DC03C00L, 0x8D513D01L, 0x8CE13E01L, 0x1C703F00L, - 0xB4014001L, 0x24904100L, 0x25204200L, 0xB5B14301L, - 0x26404400L, 0xB6D14501L, 0xB7614601L, 0x27F04700L, - 0x20804800L, 0xB0114901L, 0xB1A14A01L, 0x21304B00L, - 0xB2C14C01L, 0x22504D00L, 0x23E04E00L, 0xB3714F01L, - 0x2D005000L, 0xBD915101L, 0xBC215201L, 0x2CB05300L, - 0xBF415401L, 0x2FD05500L, 0x2E605600L, 0xBEF15701L, - 0xB9815801L, 0x29105900L, 0x28A05A00L, 0xB8315B01L, - 0x2BC05C00L, 0xBB515D01L, 0xBAE15E01L, 0x2A705F00L, - 0x36006000L, 0xA6916101L, 0xA7216201L, 0x37B06300L, - 0xA4416401L, 0x34D06500L, 0x35606600L, 0xA5F16701L, - 0xA2816801L, 0x32106900L, 0x33A06A00L, 0xA3316B01L, - 0x30C06C00L, 0xA0516D01L, 0xA1E16E01L, 0x31706F00L, - 0xAF017001L, 0x3F907100L, 0x3E207200L, 0xAEB17301L, - 0x3D407400L, 0xADD17501L, 0xAC617601L, 0x3CF07700L, - 0x3B807800L, 0xAB117901L, 0xAAA17A01L, 0x3A307B00L, - 0xA9C17C01L, 0x39507D00L, 0x38E07E00L, 0xA8717F01L, - 0xD8018001L, 0x48908100L, 0x49208200L, 0xD9B18301L, - 0x4A408400L, 0xDAD18501L, 0xDB618601L, 0x4BF08700L, - 0x4C808800L, 0xDC118901L, 0xDDA18A01L, 0x4D308B00L, - 0xDEC18C01L, 0x4E508D00L, 0x4FE08E00L, 0xDF718F01L, - 0x41009000L, 0xD1919101L, 0xD0219201L, 0x40B09300L, - 0xD3419401L, 0x43D09500L, 0x42609600L, 0xD2F19701L, - 0xD5819801L, 0x45109900L, 0x44A09A00L, 0xD4319B01L, - 0x47C09C00L, 0xD7519D01L, 0xD6E19E01L, 0x46709F00L, - 0x5A00A000L, 0xCA91A101L, 0xCB21A201L, 0x5BB0A300L, - 0xC841A401L, 0x58D0A500L, 0x5960A600L, 0xC9F1A701L, - 0xCE81A801L, 0x5E10A900L, 0x5FA0AA00L, 0xCF31AB01L, - 0x5CC0AC00L, 0xCC51AD01L, 0xCDE1AE01L, 0x5D70AF00L, - 0xC301B001L, 0x5390B100L, 0x5220B200L, 0xC2B1B301L, - 0x5140B400L, 0xC1D1B501L, 0xC061B601L, 0x50F0B700L, - 0x5780B800L, 0xC711B901L, 0xC6A1BA01L, 0x5630BB00L, - 0xC5C1BC01L, 0x5550BD00L, 0x54E0BE00L, 0xC471BF01L, - 0x6C00C000L, 0xFC91C101L, 0xFD21C201L, 0x6DB0C300L, - 0xFE41C401L, 0x6ED0C500L, 0x6F60C600L, 0xFFF1C701L, - 0xF881C801L, 0x6810C900L, 0x69A0CA00L, 0xF931CB01L, - 0x6AC0CC00L, 0xFA51CD01L, 0xFBE1CE01L, 0x6B70CF00L, - 0xF501D001L, 0x6590D100L, 0x6420D200L, 0xF4B1D301L, - 0x6740D400L, 0xF7D1D501L, 0xF661D601L, 0x66F0D700L, - 0x6180D800L, 0xF111D901L, 0xF0A1DA01L, 0x6030DB00L, - 0xF3C1DC01L, 0x6350DD00L, 0x62E0DE00L, 0xF271DF01L, - 0xEE01E001L, 0x7E90E100L, 0x7F20E200L, 0xEFB1E301L, - 0x7C40E400L, 0xECD1E501L, 0xED61E601L, 0x7DF0E700L, - 0x7A80E800L, 0xEA11E901L, 0xEBA1EA01L, 0x7B30EB00L, - 0xE8C1EC01L, 0x7850ED00L, 0x79E0EE00L, 0xE971EF01L, - 0x7700F000L, 0xE791F101L, 0xE621F201L, 0x76B0F300L, - 0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L, - 0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L, - 0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L -}; - -unsigned short crc_ccitt(unsigned char *q, int len) -{ - unsigned short crc = 0; - - while (len-- > 0) - crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8); - return ~crc; -} -unsigned int crc_32(unsigned char *data, int len) -{ - unsigned int crc = 0; - - while (len-- > 0) - crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8); - return crc; -} diff --git a/libburn/crc.h b/libburn/crc.h deleted file mode 100644 index a4846a3..0000000 --- a/libburn/crc.h +++ /dev/null @@ -1,9 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__CRC_H -#define BURN__CRC_H - -unsigned short crc_ccitt(unsigned char *, int len); -unsigned int crc_32(unsigned char *, int len); - -#endif /* BURN__CRC_H */ diff --git a/libburn/debug.c b/libburn/debug.c deleted file mode 100644 index b4abab7..0000000 --- a/libburn/debug.c +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifdef WIN32 -#include -#endif - -#include -#include -#include "libburn.h" -#include "debug.h" - -static int burn_verbosity = 0; - -void burn_set_verbosity(int v) -{ - burn_verbosity = v; -} - -void burn_print(int level, const char *a, ...) -{ -#ifdef WIN32 - char debug_string_data[256]; -#endif - va_list vl; - - if (level <= burn_verbosity) { - va_start(vl, a); -#ifdef WIN32 - vsprintf(debug_string_data, a, vl); - OutputDebugString(debug_string_data); -#else - vfprintf(stderr, a, vl); -#endif - } -} diff --git a/libburn/debug.h b/libburn/debug.h deleted file mode 100644 index b566de0..0000000 --- a/libburn/debug.h +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__DEBUG_H -#define BURN__DEBUG_H - -void burn_print(int level, const char *a, ...); - -#endif /* BURN__DEBUG_H */ diff --git a/libburn/drive.c b/libburn/drive.c deleted file mode 100644 index cf79bcf..0000000 --- a/libburn/drive.c +++ /dev/null @@ -1,1232 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include -#include - -/* #include ts A61013 : not in Linux man 3 malloc */ - -#include -#include -#include - -/* ts A61007 */ -/* #include */ - -#include -#include -#include -#include -#include "libburn.h" -#include "drive.h" -#include "transport.h" -#include "debug.h" -#include "init.h" -#include "toc.h" -#include "util.h" -#include "sg.h" -#include "structure.h" -#include "back_hacks.h" - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - -static struct burn_drive drive_array[255]; -static int drivetop = -1; - -/* ts A61021 : the unspecific part of sg.c:enumerate_common() -*/ -int burn_setup_drive(struct burn_drive *d, char *fname) -{ - d->devname = burn_strdup(fname); - memset(&d->params, 0, sizeof(struct params)); - d->released = 1; - d->status = BURN_DISC_UNREADY; - return 1; -} - -/* ts A60904 : ticket 62, contribution by elmom */ -/* splitting former burn_drive_free() (which freed all, into two calls) */ -void burn_drive_free(struct burn_drive *d) -{ - if (d->global_index == -1) - return; - /* ts A60822 : close open fds before forgetting them */ - if (burn_drive_is_open(d)) - sg_close_drive(d); - free((void *) d->idata); - free((void *) d->mdata); - if(d->toc_entry != NULL) - free((void *) d->toc_entry); - free(d->devname); - d->global_index = -1; -} - -void burn_drive_free_all(void) -{ - int i; - - for (i = 0; i < drivetop + 1; i++) - burn_drive_free(&(drive_array[i])); - drivetop = -1; - memset(drive_array, 0, sizeof(drive_array)); -} - - -/* ts A60822 */ -int burn_drive_is_open(struct burn_drive *d) -{ - /* ts A61021 : moved decision to sg.c */ - return d->drive_is_open(d); -} - - -/* ts A60906 */ -int burn_drive_force_idle(struct burn_drive *d) -{ - d->busy = BURN_DRIVE_IDLE; - return 1; -} - - -/* ts A60906 */ -int burn_drive_is_released(struct burn_drive *d) -{ - return !!d->released; -} - - -/* ts A60906 */ -/** Inquires drive status in respect to degree of app usage. - @param return -2 = drive is forgotten - -1 = drive is closed (i.e. released explicitely) - 0 = drive is open, not grabbed (after scan, before 1st grab) - 1 = drive is grabbed but BURN_DRIVE_IDLE - 10 = drive is grabbing (BURN_DRIVE_GRABBING) - 100 = drive is busy in cancelable state - 1000 = drive is in non-cancelable state - Expect a monotonous sequence of usage severity to emerge in future. -*/ -int burn_drive_is_occupied(struct burn_drive *d) -{ - if(d->global_index < 0) - return -2; - if(!burn_drive_is_open(d)) - return -1; - if(d->busy == BURN_DRIVE_GRABBING) - return 10; - if(d->released) - return 0; - if(d->busy == BURN_DRIVE_IDLE) - return 1; - if(d->busy == BURN_DRIVE_READING || d->busy == BURN_DRIVE_WRITING) - return 50; - return 1000; -} - - -/* -void drive_read_lead_in(int dnum) -{ - mmc_read_lead_in(&drive_array[dnum], get_4k()); -} -*/ -unsigned int burn_drive_count(void) -{ - return drivetop + 1; -} - -int burn_drive_grab(struct burn_drive *d, int le) -{ - int errcode; - int was_equal = 0, must_equal = 3, max_loop = 20; - - /* ts A60907 */ - int loop_count, old_speed = -1234567890, new_speed = -987654321; - int old_erasable = -1234567890, new_erasable = -987654321; - - if (!d->released) { - burn_print(1, "can't grab - already grabbed\n"); - return 0; - } - errcode = d->grab(d); - - if (errcode == 0) { - burn_print(1, "low level drive grab failed\n"); - return 0; - } - d->busy = BURN_DRIVE_GRABBING; - - if (le) - d->load(d); - - d->lock(d); - - /* ts A61020 : this was BURN_DISC_BLANK as pure guess */ - d->status = BURN_DISC_UNREADY; - - if (d->mdata->cdr_write || d->mdata->cdrw_write || - d->mdata->dvdr_write || d->mdata->dvdram_write) { - -#ifdef Libburn_grab_release_and_grab_agaiN - - d->read_disc_info(d); - -#else - /* ts A60908 */ - /* Trying to stabilize the disc status after eventual load - without closing and re-opening the drive */ - /* This seems to work for burn_disc_erasable() . - Speed values on RIP-14 and LITE-ON 48125S are stable - and false, nevertheless. So cdrskin -atip is still - forced to finish-initialize. */ - /* - fprintf(stderr,"libburn: experimental: read_disc_info()\n"); - */ - for (loop_count = 0; loop_count < max_loop; loop_count++){ - old_speed = new_speed; - old_erasable = new_erasable; - - d->read_disc_info(d); - if(d->status == BURN_DISC_UNSUITABLE) - break; - - new_speed = burn_drive_get_write_speed(d); - new_erasable = burn_disc_erasable(d); - if (new_speed == old_speed && - new_erasable == old_erasable) { - was_equal++; - if (was_equal >= must_equal) - break; - } else - was_equal = 0; - /* - if (loop_count >= 1 && was_equal == 0) - fprintf(stderr,"libburn: experimental: %d : speed %d:%d erasable %d:%d\n", - loop_count,old_speed,new_speed,old_erasable,new_erasable); - */ - usleep(100000); - } -#endif /* ! Libburn_grab_release_and_grab_agaiN */ - - } else { - d->read_toc(d); - } - d->busy = BURN_DRIVE_IDLE; - return 1; -} - -struct burn_drive *burn_drive_register(struct burn_drive *d) -{ -#ifdef Libburn_ticket_62_re_register_is_possiblE - int i; -#endif - - d->block_types[0] = 0; - d->block_types[1] = 0; - d->block_types[2] = 0; - d->block_types[3] = 0; - d->toc_temp = 0; - d->nwa = 0; - d->alba = 0; - d->rlba = 0; - d->cancel = 0; - d->busy = BURN_DRIVE_IDLE; - d->toc_entries = 0; - d->toc_entry = NULL; - d->disc = NULL; - d->erasable = 0; - -#ifdef Libburn_ticket_62_re_register_is_possiblE - /* ts A60904 : ticket 62, contribution by elmom */ - /* Not yet accepted because no use case seen yet */ - - /* This is supposed to find an already freed drive struct among - all the the ones that have been used before */ - for (i = 0; i < drivetop + 1; i++) - if (drive_array[i].global_index == -1) - break; - d->global_index = i; - memcpy(&drive_array[i], d, sizeof(struct burn_drive)); - pthread_mutex_init(&drive_array[i].access_lock, NULL); - if (drivetop < i) - drivetop = i; - return &(drive_array[i]); - -#else /* Libburn_ticket_62_re_register_is_possiblE */ - /* old A60904 : */ - /* Still active by default */ - - d->global_index = drivetop + 1; - memcpy(&drive_array[drivetop + 1], d, sizeof(struct burn_drive)); - pthread_mutex_init(&drive_array[drivetop + 1].access_lock, NULL); - return &drive_array[++drivetop]; - -#endif /* ! Libburn_ticket_62_re_register_is_possiblE */ - -} - - -/* unregister most recently registered drive */ -int burn_drive_unregister(struct burn_drive *d) -{ - if(d->global_index != drivetop) - return 0; - burn_drive_free(d); - drivetop--; - return 1; -} - - -/* ts A61021 : after-setup activities from sg.c:enumerate_common() -*/ -struct burn_drive *burn_drive_finish_enum(struct burn_drive *d) -{ - struct burn_drive *t; - /* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ - int mmc_function_spy(char * text); - - t = burn_drive_register(d); - - /* ts A60821 */ - mmc_function_spy("enumerate_common : -------- doing grab"); - - /* try to get the drive info */ - if (t->grab(t)) { - burn_print(2, "getting drive info\n"); - t->getcaps(t); - t->unlock(t); - t->released = 1; - } else { - burn_print(2, "unable to grab new located drive\n"); - burn_drive_unregister(t); - t = NULL; - } - - /* ts A60821 */ - mmc_function_spy("enumerate_common : ----- would release "); - - return t; -} - - -void burn_drive_release(struct burn_drive *d, int le) -{ - if (d->released) { - /* ts A61007 */ - /* burn_print(1, "second release on drive!\n"); */ - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x00020105, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Drive is already released", 0, 0); - return; - } - - /* ts A61007 */ - /* ts A60906: one should not assume BURN_DRIVE_IDLE == 0 */ - /* a ssert(d->busy == BURN_DRIVE_IDLE); */ - if (d->busy != BURN_DRIVE_IDLE) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x00020106, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Drive is busy on attempt to close", 0, 0); - return; - } - - /* ts A61020 : mark media info as invalid */ - d->start_lba= -2000000000; - d->end_lba= -2000000000; - - d->unlock(d); - if (le) - d->eject(d); - - d->release(d); - - d->status = BURN_DISC_UNREADY; - d->released = 1; - if (d->toc_entry != NULL) - free(d->toc_entry); - d->toc_entry = NULL; - d->toc_entries = 0; - if (d->disc != NULL) { - burn_disc_free(d->disc); - d->disc = NULL; - } -} - - - -/* ts A61007 : former void burn_wait_all() */ -int burn_drives_are_clear(void) -{ - int i; - - for (i = burn_drive_count() - 1; i >= 0; --i) { - /* ts A60904 : ticket 62, contribution by elmom */ - if (drive_array[i].global_index == -1) - continue; - if (drive_array[i].released) - continue; - return 0; - } - return 1; -} - - -#if 0 -void burn_wait_all(void) -{ - unsigned int i; - int finished = 0; - struct burn_drive *d; - - while (!finished) { - finished = 1; - d = drive_array; - for (i = burn_drive_count(); i > 0; --i, ++d) { - - /* ts A60904 : ticket 62, contribution by elmom */ - if (d->global_index==-1) - continue; - - a ssert(d->released); - } - if (!finished) - sleep(1); - } -} -#endif - - -void burn_disc_erase_sync(struct burn_drive *d, int fast) -{ -/* ts A60924 : libburn/message.c gets obsoleted - burn_message_clear_queue(); -*/ - - burn_print(1, "erasing drive %s %s\n", d->idata->vendor, - d->idata->product); - - /* ts A60825 : allow on parole to blank appendable CDs */ - if ( ! (d->status == BURN_DISC_FULL || - (d->status == BURN_DISC_APPENDABLE && - ! libburn_back_hack_42) ) ) - return; - d->cancel = 0; - d->busy = BURN_DRIVE_ERASING; - d->erase(d, fast); - /* reset the progress */ - d->progress.session = 0; - d->progress.sessions = 1; - d->progress.track = 0; - d->progress.tracks = 1; - d->progress.index = 0; - d->progress.indices = 1; - d->progress.start_sector = 0; - d->progress.sectors = 0x10000; - d->progress.sector = 0; - /* read the initial 0 stage */ - while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0) - sleep(1); - while ((d->progress.sector = d->get_erase_progress(d)) > 0 || - !d->test_unit_ready(d)) - sleep(1); - d->progress.sector = 0x10000; - d->busy = BURN_DRIVE_IDLE; -} - -enum burn_disc_status burn_disc_get_status(struct burn_drive *d) -{ - /* ts A61007 */ - /* a ssert(!d->released); */ - if (d->released) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x00020108, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Drive is not grabbed on disc status inquiry", - 0, 0); - return BURN_DISC_UNGRABBED; - } - - return d->status; -} - -int burn_disc_erasable(struct burn_drive *d) -{ - return d->erasable; -} -enum burn_drive_status burn_drive_get_status(struct burn_drive *d, - struct burn_progress *p) -{ - if (p) { - memcpy(p, &(d->progress), sizeof(struct burn_progress)); - /* TODO: add mutex */ - } - return d->busy; -} - -void burn_drive_cancel(struct burn_drive *d) -{ - pthread_mutex_lock(&d->access_lock); - d->cancel = 1; - pthread_mutex_unlock(&d->access_lock); -} - -/* ts A61007 : defunct because unused */ -#if 0 -int burn_drive_get_block_types(struct burn_drive *d, - enum burn_write_types write_type) -{ - burn_print(12, "write type: %d\n", write_type); - a ssert( /* (write_type >= BURN_WRITE_PACKET) && */ - (write_type <= BURN_WRITE_RAW)); - return d->block_types[write_type]; -} -#endif - -static void strip_spaces(char *str) -{ - char *tmp; - - tmp = str + strlen(str) - 1; - while (isspace(*tmp)) - *(tmp--) = '\0'; - - tmp = str; - while (*tmp) { - if (isspace(*tmp) && isspace(*(tmp + 1))) { - char *tmp2; - - for (tmp2 = tmp + 1; *tmp2; ++tmp2) - *(tmp2 - 1) = *tmp2; - *(tmp2 - 1) = '\0'; - } else - ++tmp; - } -} - -static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out) -{ - struct burn_scsi_inquiry_data *id; - - /* ts A61007 : now prevented in enumerate_common() */ -#if 0 - a ssert(d->idata); - a ssert(d->mdata); -#endif - - if (!d->idata->valid || !d->mdata->valid) - return 0; - - id = (struct burn_scsi_inquiry_data *)d->idata; - - memcpy(out->vendor, id->vendor, sizeof(id->vendor)); - strip_spaces(out->vendor); - memcpy(out->product, id->product, sizeof(id->product)); - strip_spaces(out->product); - memcpy(out->revision, id->revision, sizeof(id->revision)); - strip_spaces(out->revision); - strncpy(out->location, d->devname, 16); - out->location[16] = '\0'; - out->buffer_size = d->mdata->buffer_size; - out->read_dvdram = !!d->mdata->dvdram_read; - out->read_dvdr = !!d->mdata->dvdr_read; - out->read_dvdrom = !!d->mdata->dvdrom_read; - out->read_cdr = !!d->mdata->cdr_read; - out->read_cdrw = !!d->mdata->cdrw_read; - out->write_dvdram = !!d->mdata->dvdram_write; - out->write_dvdr = !!d->mdata->dvdr_write; - out->write_cdr = !!d->mdata->cdr_write; - out->write_cdrw = !!d->mdata->cdrw_write; - out->write_simulate = !!d->mdata->simulate; - out->c2_errors = !!d->mdata->c2_pointers; - out->drive = d; - /* update available block types for burners */ - if (out->write_dvdram || out->write_dvdr || - out->write_cdrw || out->write_cdr) - d->probe_write_modes(d); - out->tao_block_types = d->block_types[BURN_WRITE_TAO]; - out->sao_block_types = d->block_types[BURN_WRITE_SAO]; - out->raw_block_types = d->block_types[BURN_WRITE_RAW]; - out->packet_block_types = d->block_types[BURN_WRITE_PACKET]; - return 1; -} - -int burn_drive_scan_sync(struct burn_drive_info *drives[], - unsigned int *n_drives) -{ - /* state vars for the scan process */ - /* ts A60904 : did set some default values to feel comfortable */ - static int scanning = 0, scanned = 0, found = 0; - static unsigned num_scanned = 0, count = 0; - unsigned int i; - - /* ts A61007 : moved up to burn_drive_scan() */ - /* a ssert(burn_running); */ - - if (!scanning) { - scanning = 1; - - /* ts A61007 : test moved up to burn_drive_scan() - burn_wait_all() is obsoleted */ -#if 0 - /* make sure the drives aren't in use */ - burn_wait_all(); /* make sure the queue cleans up - before checking for the released - state */ -#endif /* 0 */ - - /* refresh the lib's drives */ - sg_enumerate(); - ata_enumerate(); - count = burn_drive_count(); - if (count) - *drives = - malloc(sizeof(struct burn_drive_info) * count); - else - *drives = NULL; - *n_drives = scanned = found = num_scanned = 0; - } - - for (i = 0; i < count; ++i) { - if (scanned & (1 << i)) - continue; /* already scanned the device */ - - while (!drive_getcaps(&drive_array[i], - &(*drives)[num_scanned])) { - sleep(1); - } - scanned |= 1 << i; - found |= 1 << i; - num_scanned++; - (*n_drives)++; - } - - if (num_scanned == count) { - /* done scanning */ - scanning = 0; - return 1; - } - return 0; -} - - -void burn_drive_info_free(struct burn_drive_info drive_infos[]) -{ -/* ts A60904 : ticket 62, contribution by elmom */ -/* clarifying the meaning and the identity of the victim */ - - /* ts A60904 : This looks a bit weird. - burn_drive_info is not the manager of burn_drive but only its - spokesperson. To my knowlege drive_infos from burn_drive_scan() - are not memorized globally. */ - if(drive_infos != NULL) - free((void *) drive_infos); - - burn_drive_free_all(); -} - -/* ts A61001 : internal call */ -int burn_drive_forget(struct burn_drive *d, int force) -{ - int occup; - - occup = burn_drive_is_occupied(d); -/* - fprintf(stderr, "libburn: experimental: occup == %d\n",occup); -*/ - if(occup <= -2) - return 2; - if(occup > 0) - if(force < 1) - return 0; - if(occup > 10) - return 0; - - /* >>> do any drive calming here */; - - - burn_drive_force_idle(d); - if(occup > 0 && !burn_drive_is_released(d)) - burn_drive_release(d,0); - burn_drive_free(d); - return 1; -} - -/* API call */ -int burn_drive_info_forget(struct burn_drive_info *info, int force) -{ - return burn_drive_forget(info->drive, force); -} - -struct burn_disc *burn_drive_get_disc(struct burn_drive *d) -{ - /* ts A61022: SIGSEGV on calling this function with blank media */ - if(d->disc == NULL) - return NULL; - - d->disc->refcnt++; - return d->disc; -} - -void burn_drive_set_speed(struct burn_drive *d, int r, int w) -{ - d->set_speed(d, r, w); -} - -int burn_msf_to_sectors(int m, int s, int f) -{ - return (m * 60 + s) * 75 + f; -} - -void burn_sectors_to_msf(int sectors, int *m, int *s, int *f) -{ - *m = sectors / (60 * 75); - *s = (sectors - *m * 60 * 75) / 75; - *f = sectors - *m * 60 * 75 - *s * 75; -} - -int burn_drive_get_read_speed(struct burn_drive *d) -{ - return d->mdata->max_read_speed; -} - -int burn_drive_get_write_speed(struct burn_drive *d) -{ - return d->mdata->max_write_speed; -} - -/* ts A61021 : New API function */ -int burn_drive_get_min_write_speed(struct burn_drive *d) -{ - return d->mdata->min_write_speed; -} - - -/* ts A51221 */ -static char *enumeration_whitelist[BURN_DRIVE_WHITELIST_LEN]; -static int enumeration_whitelist_top = -1; - -/** Add a device to the list of permissible drives. As soon as some entry is in - the whitelist all non-listed drives are banned from enumeration. - @return 1 success, <=0 failure -*/ -int burn_drive_add_whitelist(char *device_address) -{ - char *new_item; - if(enumeration_whitelist_top+1 >= BURN_DRIVE_WHITELIST_LEN) - return 0; - enumeration_whitelist_top++; - new_item = malloc(strlen(device_address) + 1); - if (new_item == NULL) - return -1; - strcpy(new_item, device_address); - enumeration_whitelist[enumeration_whitelist_top] = new_item; - return 1; -} - -/** Remove all drives from whitelist. This enables all possible drives. */ -void burn_drive_clear_whitelist(void) -{ - int i; - for (i = 0; i <= enumeration_whitelist_top; i++) - free(enumeration_whitelist[i]); - enumeration_whitelist_top = -1; -} - -int burn_drive_is_banned(char *device_address) -{ - int i; - if(enumeration_whitelist_top<0) - return 0; - for (i = 0; i <= enumeration_whitelist_top; i++) - if (strcmp(enumeration_whitelist[i], device_address) == 0) - return 0; - return 1; -} - -/* ts A60823 */ -/** Aquire a drive with known persistent address. -*/ -int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr, - int load) -{ - unsigned int n_drives; - int ret; - - burn_drive_clear_whitelist(); - burn_drive_add_whitelist(adr); -/* - fprintf(stderr,"libburn: experimental: burn_drive_scan_and_grab(%s)\n", - adr); -*/ - while (1) { - ret = burn_drive_scan(drive_infos, &n_drives); - if (ret < 0) - return -1; - if (ret > 0) - break; - usleep(1002); - } - if (n_drives <= 0) - return 0; -/* - fprintf(stderr, "libburn: experimental: n_drives == %d\n",n_drives); -*/ - - ret = burn_drive_grab(drive_infos[0]->drive, load); - if (ret != 1) - return -1; - return 1; -} - -/* ts A60925 */ -/** Simple debug message frontend to libdax_msgs_submit(). - If arg is not NULL, then fmt MUST contain exactly one %s and no - other sprintf() %-formatters. -*/ -int burn_drive_adr_debug_msg(char *fmt, char *arg) -{ - int ret; - char msg[4096], *msgpt; - - msgpt= msg; - if(arg != NULL) - sprintf(msg, fmt, arg); - else - msgpt= fmt; - if(libdax_messenger == NULL) - return 0; - ret = libdax_msgs_submit(libdax_messenger, -1, 0x00000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - msgpt, 0, 0); - return ret; -} - -/* ts A60923 */ -/** Inquire the persistent address of the given drive. */ -int burn_drive_raw_get_adr(struct burn_drive *d, char adr[]) -{ - if (strlen(d->devname) >= BURN_DRIVE_ADR_LEN) { - libdax_msgs_submit(libdax_messenger, d->global_index, - 0x00020110, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Persistent drive address too long", 0, 0); - return -1; - } - strcpy(adr,d->devname); - return 1; -} - -/* ts A60823 - A60923 */ -/** Inquire the persistent address of the given drive. */ -int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]) -{ - int ret; - - ret = burn_drive_raw_get_adr(drive_info->drive, adr); - return ret; -} - - -/* ts A60922 ticket 33 */ -/** Evaluate wether the given address would be enumerated by libburn */ -int burn_drive_is_enumerable_adr(char *adr) -{ - return sg_is_enumerable_adr(adr); -} - -#define BURN_DRIVE_MAX_LINK_DEPTH 20 - -/* ts A60922 ticket 33 */ -/* Try to find an enumerated address with the given stat.st_rdev number */ -int burn_drive_resolve_link(char *path, char adr[], int *recursion_count) -{ - int ret; - char link_target[4096], msg[4096+100], link_adr[4096], *adrpt; - - burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )", path); - if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) { - burn_drive_adr_debug_msg( - "burn_drive_resolve_link aborts because link too deep", - NULL); - return 0; - } - (*recursion_count)++; - ret = readlink(path, link_target, sizeof(link_target)); - if (ret == -1) { - burn_drive_adr_debug_msg("readlink( %s ) returns -1", path); - return 0; - } - if (ret >= sizeof(link_target) - 1) { - sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret); - burn_drive_adr_debug_msg(msg, NULL); - return -1; - } - link_target[ret] = 0; - adrpt= link_target; - if (link_target[0] != '/') { - strcpy(link_adr, path); - if ((adrpt = strrchr(link_adr, '/')) != NULL) { - strcpy(adrpt + 1, link_target); - adrpt = link_adr; - } else - adrpt = link_target; - } - ret = burn_drive_convert_fs_adr_sub(adrpt, adr, recursion_count); - sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d", - link_target, ret); - burn_drive_adr_debug_msg(msg, NULL); - return ret; -} - -/* ts A60922 - A61014 ticket 33 */ -/* Try to find an enumerated address with the given stat.st_rdev number */ -int burn_drive_find_devno(dev_t devno, char adr[]) -{ - char fname[4096], msg[4096+100]; - int ret = 0, first = 1; - struct stat stbuf; - burn_drive_enumerator_t enm; - - while (1) { - ret = sg_give_next_adr(&enm, fname, sizeof(fname), first); - if(ret <= 0) - break; - first = 0; - ret = stat(fname, &stbuf); - if(ret == -1) - continue; - if(devno != stbuf.st_rdev) - continue; - if(strlen(fname) >= BURN_DRIVE_ADR_LEN) - return -1; - - sprintf(msg, "burn_drive_find_devno( 0x%lX ) found %s", - (long) devno, fname); - burn_drive_adr_debug_msg(msg, NULL); - strcpy(adr, fname); - { ret = 1; goto ex;} - } - ret = 0; -ex:; - if (first == 0) - sg_give_next_adr(&enm, fname, sizeof(fname), -1); - return ret; -} - -/* ts A60923 */ -/** Try to obtain host,channel,target,lun from path. - @return 1 = success , 0 = failure , -1 = severe error -*/ -int burn_drive_obtain_scsi_adr(char *path, - int *bus_no, int *host_no, int *channel_no, - int *target_no, int *lun_no) -{ - int ret, i; - char adr[BURN_DRIVE_ADR_LEN]; - - /* open drives cannot be inquired by sg_obtain_scsi_adr() */ - for (i = 0; i < drivetop + 1; i++) { - if (drive_array[i].global_index < 0) - continue; - ret = burn_drive_raw_get_adr(&(drive_array[i]),adr); - if (ret < 0) - return -1; - if (ret == 0) - continue; - if (strcmp(adr, path) == 0) { - *host_no = drive_array[i].host; - *channel_no = drive_array[i].channel; - *target_no = drive_array[i].id; - *lun_no = drive_array[i].lun; - *bus_no = drive_array[i].bus_no; - if (*host_no < 0 || *channel_no < 0 || - *target_no < 0 || *lun_no < 0) - return 0; - return 1; - } - } - - ret = sg_obtain_scsi_adr(path, bus_no, host_no, channel_no, - target_no, lun_no); - return ret; -} - -/* ts A60923 */ -int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no, - int target_no, int lun_no, char adr[]) -{ - char fname[4096],msg[4096+100]; - int ret = 0, first = 1, i_bus_no = -1; - int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; - burn_drive_enumerator_t enm; - - sprintf(msg,"burn_drive_convert_scsi_adr( %d,%d,%d,%d,%d )", - bus_no, host_no, channel_no, target_no, lun_no); - burn_drive_adr_debug_msg(msg, NULL); - - while (1) { - ret= sg_give_next_adr(&enm, fname, sizeof(fname), first); - if(ret <= 0) - break; - first = 0; - ret = burn_drive_obtain_scsi_adr(fname, &i_bus_no, &i_host_no, - &i_channel_no, &i_target_no, &i_lun_no); - if(ret <= 0) - continue; - if(bus_no >=0 && i_bus_no != bus_no) - continue; - if(host_no >=0 && i_host_no != host_no) - continue; - if(channel_no >= 0 && i_channel_no != channel_no) - continue; - if(target_no >= 0 && i_target_no != target_no) - continue; - if(lun_no >= 0 && i_lun_no != lun_no) - continue; - if(strlen(fname) >= BURN_DRIVE_ADR_LEN) - { ret = -1; goto ex;} - burn_drive_adr_debug_msg( - "burn_drive_convert_scsi_adr() found %s", fname); - strcpy(adr, fname); - { ret = 1; goto ex;} - } - ret = 0; -ex:; - if (first == 0) - sg_give_next_adr(&enm, fname, sizeof(fname), -1); - return ret; -} - -/* ts A60922 ticket 33 */ -/* Try to find an enumerated address with the same host,channel,target,lun - as path */ -int burn_drive_find_scsi_equiv(char *path, char adr[]) -{ - int ret = 0; - int bus_no, host_no, channel_no, target_no, lun_no; - char msg[4096]; - - ret = burn_drive_obtain_scsi_adr(path, &bus_no, &host_no, &channel_no, - &target_no, &lun_no); - if(ret <= 0) { - sprintf(msg,"burn_drive_obtain_scsi_adr( %s ) returns %d\n", - path, ret); - burn_drive_adr_debug_msg(msg, NULL); - return 0; - } - sprintf(msg, "burn_drive_find_scsi_equiv( %s ) : (%d),%d,%d,%d,%d", - path, bus_no, host_no, channel_no, target_no, lun_no); - burn_drive_adr_debug_msg(msg, NULL); - - ret= burn_drive_convert_scsi_adr(-1, host_no, channel_no, target_no, - lun_no, adr); - return ret; -} - - -/* ts A60922 ticket 33 */ -/** Try to convert a given existing filesystem address into a persistent drive - address. */ -int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count) -{ - int ret; - struct stat stbuf; - - burn_drive_adr_debug_msg("burn_drive_convert_fs_adr( %s )", path); - if(burn_drive_is_enumerable_adr(path)) { - if(strlen(path) >= BURN_DRIVE_ADR_LEN) - return -1; - burn_drive_adr_debug_msg( - "burn_drive_is_enumerable_adr( %s ) is true", path); - strcpy(adr, path); - return 1; - } - - if(lstat(path, &stbuf) == -1) { - burn_drive_adr_debug_msg("lstat( %s ) returns -1", path); - return 0; - } - if((stbuf.st_mode & S_IFMT) == S_IFLNK) { - ret = burn_drive_resolve_link(path, adr, rec_count); - if(ret > 0) - return 1; - burn_drive_adr_debug_msg("link fallback via stat( %s )", path); - if(stat(path, &stbuf) == -1) { - burn_drive_adr_debug_msg("stat( %s ) returns -1",path); - return 0; - } - } - if((stbuf.st_mode&S_IFMT) == S_IFBLK || - (stbuf.st_mode&S_IFMT) == S_IFCHR) { - ret = burn_drive_find_devno(stbuf.st_rdev, adr); - if(ret > 0) - return 1; - ret = burn_drive_find_scsi_equiv(path, adr); - if(ret > 0) - return 1; - } - burn_drive_adr_debug_msg("Nothing found for %s", path); - return 0; -} - -/** Try to convert a given existing filesystem address into a persistent drive - address. */ -int burn_drive_convert_fs_adr(char *path, char adr[]) -{ - int ret, rec_count = 0; - - ret = burn_drive_convert_fs_adr_sub(path, adr, &rec_count); - return ret; -} - - -/** A pacifier function suitable for burn_abort. - @param handle If not NULL, a pointer to a text suitable for printf("%s") -*/ -int burn_abort_pacifier(void *handle, int patience, int elapsed) -{ - char *prefix= "libburn : "; - - if(handle!=NULL) - prefix= handle; - fprintf(stderr, - "\r%sABORT : Waiting for drive to finish ( %d s, %d max)", - (char *) prefix, elapsed, patience); - return(1); -} - - -/** Abort any running drive operation and finis libburn. - @param patience Maximum number of seconds to wait for drives to finish - @param pacifier_func Function to produce appeasing messages. See - burn_abort_pacifier() for an example. - @return 1 ok, all went well - 0 had to leave a drive in unclean state - <0 severe error, do no use libburn again -*/ -int burn_abort(int patience, - int (*pacifier_func)(void *handle, int patience, int elapsed), - void *handle) -{ - int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1; - unsigned long wait_grain= 100000; - time_t start_time, current_time, pacifier_time, end_time; - - current_time = start_time = pacifier_time = time(0); - end_time = start_time + patience; - while(current_time-end_time < patience) { - still_not_done = 0; - - for(i = 0; i < drivetop + 1; i++) { - occup = burn_drive_is_occupied(&(drive_array[i])); - if(occup == -2) - continue; - if(occup <= 10) { - burn_drive_forget(&(drive_array[i]), 1); - } else if(occup <= 100) { - if(first_round) - burn_drive_cancel(&(drive_array[i])); - still_not_done++; - } else if(occup <= 1000) { - still_not_done++; - } - } - first_round = 0; - - if(still_not_done == 0) - break; - usleep(wait_grain); - current_time = time(0); - if(current_time>pacifier_time) { - if(pacifier_func != NULL && !pacifier_off) { - ret = (*pacifier_func)(handle, patience, - current_time-start_time); - pacifier_off = (ret <= 0); - } - pacifier_time = current_time; - } - } - burn_finish(); - return(still_not_done == 0); -} - - -/* ts A61020 API function */ -int burn_drive_get_start_end_lba(struct burn_drive *d, - int *start_lba, int *end_lba, int flag) -{ - if (d->start_lba == -2000000000 || d->end_lba == -2000000000) - return 0; - *start_lba = d->start_lba; - *end_lba= d->end_lba; - return 1; -} - - -/* ts A61020 API function */ -int burn_disc_pretend_blank(struct burn_drive *d) -{ - if (d->status != BURN_DISC_UNREADY && - d->status != BURN_DISC_UNSUITABLE) - return 0; - d->status = BURN_DISC_BLANK; - return 1; -} - -/* ts A61106 API function */ -int burn_disc_pretend_full(struct burn_drive *d) -{ - if (d->status != BURN_DISC_UNREADY && - d->status != BURN_DISC_UNSUITABLE) - return 0; - d->status = BURN_DISC_FULL; - return 1; -} - -/* ts A61021: new API function */ -int burn_disc_read_atip(struct burn_drive *d) -{ - if (burn_drive_is_released(d)) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x0002010e, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Attempt to read ATIP from ungrabbed drive", - 0, 0); - return -1; - } - d->read_atip(d); - /* >>> some control of success would be nice :) */ - return 1; -} - -/* ts A61110 : new API function */ -int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, - int trackno, int *lba, int *nwa) -{ - int ret; - - if (burn_drive_is_released(d)) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x0002011b, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Attempt to read track info from ungrabbed drive", - 0, 0); - return -1; - } - if (d->busy != BURN_DRIVE_IDLE) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x0002011c, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Attempt to read track info from busy drive", - 0, 0); - return -1; - } - if (o!=NULL) - d->send_write_parameters(d, o); - ret = d->get_nwa(d, trackno, lba, nwa); - return ret; -} - diff --git a/libburn/drive.h b/libburn/drive.h deleted file mode 100644 index f511966..0000000 --- a/libburn/drive.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __DRIVE -#define __DRIVE - -#include "libburn.h" -#include "toc.h" -#include "structure.h" - -struct burn_drive; -struct command; -struct mempage; - -#define LEAD_IN 1 -#define GAP 2 -#define USER_DATA 3 -#define LEAD_OUT 4 -#define SYNC 5 - -#define SESSION_LEADOUT_ENTRY(d,s) (d)->toc->session[(s)].leadout_entry - -#define CURRENT_SESSION_START(d) \ - burn_msf_to_lba(d->toc->session[d->currsession].start_m, \ - d->toc->session[d->currsession].start_s, \ - d->toc->session[d->currsession].start_f) - -#define SESSION_END(d,s) \ - TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (s))) - -#define PREVIOUS_SESSION_END(d) \ - TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (d)->currsession-1)) - -#define LAST_SESSION_END(d) \ - TOC_ENTRY_PLBA((d)->toc, \ - SESSION_LEADOUT_ENTRY((d), (d)->toc->sessions-1)) - -struct burn_drive *burn_drive_register(struct burn_drive *); -int burn_drive_unregister(struct burn_drive *d); - -unsigned int burn_drive_count(void); - -/* ts A61007 */ -/* void burn_wait_all(void); */ -int burn_drives_are_clear(void); - -int burn_sector_length_write(struct burn_drive *d); -int burn_track_control(struct burn_drive *d, int); -void burn_write_empty_sector(int fd); -void burn_write_empty_subcode(int fd); -void burn_drive_free(struct burn_drive *d); -void burn_drive_free_all(void); - -int burn_drive_scan_sync(struct burn_drive_info *drives[], - unsigned int *n_drives); -void burn_disc_erase_sync(struct burn_drive *d, int fast); -int burn_drive_get_block_types(struct burn_drive *d, - enum burn_write_types write_type); - -int burn_drive_is_open(struct burn_drive *d); -int burn_drive_is_occupied(struct burn_drive *d); -int burn_drive_forget(struct burn_drive *d, int force); -int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count); - -/* ts A61021 : the unspecific part of sg.c:enumerate_common() -*/ -int burn_setup_drive(struct burn_drive *d, char *fname); - -/* ts A61021 : after-setup activities from sg.c:enumerate_common() -*/ -struct burn_drive *burn_drive_finish_enum(struct burn_drive *d); - - -#endif /* __DRIVE */ diff --git a/libburn/error.h b/libburn/error.h deleted file mode 100644 index 74d4f68..0000000 --- a/libburn/error.h +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- indent-tabs-mode; t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __ERROR_H -#define __ERROR_H - -#define BE_CANCELLED 1 - -#endif /* __ERROR_H */ diff --git a/libburn/file.c b/libburn/file.c deleted file mode 100644 index 809b842..0000000 --- a/libburn/file.c +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include -#include -#include -#include -#include -#include "source.h" -#include "libburn.h" -#include "file.h" - -/* main channel data can be padded on read, but 0 padding the subs will make -an unreadable disc */ - - -/* This is a generic OS oriented function wrapper which compensates - shortcommings of read() in respect to a guaranteed amount of return data. - See man 2 read , paragraph "RETURN VALUE". - Possibly libburn/file.c is not the right storage location for this. - To make it ready for a move, this function is not declared static. -*/ -static int read_full_buffer(int fd, unsigned char *buffer, int size) -{ - int ret,summed_ret = 0; - - /* make safe against partial buffer returns */ - while (1) { - ret = read(fd, buffer + summed_ret, size - summed_ret); - if (ret <= 0) - break; - summed_ret += ret; - if (summed_ret >= size) - break; - } - if (ret < 0) /* error encountered. abort immediately */ - return ret; - return summed_ret; -} - - -static int file_read(struct burn_source *source, - unsigned char *buffer, - int size) -{ - struct burn_source_fd *fs = source->data; - - return read_full_buffer(fs->datafd, buffer, size); -} - -static int file_read_sub(struct burn_source *source, - unsigned char *buffer, - int size) -{ - struct burn_source_file *fs = source->data; - - return read_full_buffer(fs->subfd, buffer, size); -} - -static void file_free(struct burn_source *source) -{ - struct burn_source_file *fs = source->data; - - close(fs->datafd); - if (source->read_sub) - close(fs->subfd); - free(fs); -} - -static off_t file_size(struct burn_source *source) -{ - struct stat buf; - struct burn_source_file *fs = source->data; - - if (fstat(fs->datafd, &buf) == -1) - return (off_t) 0; - /* for now we keep it compatible to the old (int) return value */ - if(buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */ - return (off_t) 1308622848; - return (off_t) buf.st_size; -} - -struct burn_source *burn_file_source_new(const char *path, const char *subpath) -{ - struct burn_source_file *fs; - struct burn_source *src; - int fd1, fd2 = 0; - - if (!path) - return NULL; - fd1 = open(path, O_RDONLY); - if (fd1 == -1) - return NULL; - if (subpath) { - fd2 = open(subpath, O_RDONLY); - if (fd2 == -1) { - close(fd1); - return NULL; - } - } - fs = malloc(sizeof(struct burn_source_file)); - fs->datafd = fd1; - - if (subpath) - fs->subfd = fd2; - - src = burn_source_new(); - src->read = file_read; - if (subpath) - src->read_sub = file_read_sub; - - src->get_size = file_size; - src->free_data = file_free; - src->data = fs; - return src; -} - - -/* ------ provisory location for the new source subclass fd --------- */ - -static off_t fd_get_size(struct burn_source *source) -{ - struct stat buf; - struct burn_source_fd *fs = source->data; - - if (fs->fixed_size > 0) - return fs->fixed_size; - if (fstat(fs->datafd, &buf) == -1) - return (off_t) 0; - /* for now we keep it compatible to the old (int) return value */ - if (buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */ - return (off_t) 1308622848; - return buf.st_size; -} - -static int fd_read(struct burn_source *source, - unsigned char *buffer, - int size) -{ - struct burn_source_fd *fs = source->data; - - return read_full_buffer(fs->datafd, buffer, size); -} - - -static int fd_read_sub(struct burn_source *source, - unsigned char *buffer, - int size) -{ - struct burn_source_fd *fs = source->data; - - return read_full_buffer(fs->subfd, buffer, size); -} - - -static void fd_free_data(struct burn_source *source) -{ - struct burn_source_fd *fs = source->data; - - close(fs->datafd); - if (source->read_sub) - close(fs->subfd); - free(fs); -} - - -struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size) -{ - struct burn_source_fd *fs; - struct burn_source *src; - - if (datafd == -1) - return NULL; - fs = malloc(sizeof(struct burn_source_fd)); - fs->datafd = datafd; - fs->subfd = subfd; - fs->fixed_size = size; - - src = burn_source_new(); - src->read = fd_read; - if(subfd != -1) - src->read = fd_read_sub; - src->get_size = fd_get_size; - src->free_data = fd_free_data; - src->data = fs; - return src; -} - diff --git a/libburn/file.h b/libburn/file.h deleted file mode 100644 index 96c1a69..0000000 --- a/libburn/file.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__FILE_H -#define BURN__FILE_H - -struct burn_source_file -{ - int datafd; - int subfd; -}; - - -/* ------ provisory location for the new source subclass fd --------- */ - -struct burn_source_fd -{ - int datafd; - int subfd; - off_t fixed_size; -}; - -#endif /* LIBBURN__FILE_H */ diff --git a/libburn/init.c b/libburn/init.c deleted file mode 100644 index 7e89eec..0000000 --- a/libburn/init.c +++ /dev/null @@ -1,246 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include - -/* ts A61007 */ -/* #include */ - -#include -#include -#include - -#include "init.h" -#include "sg.h" -#include "error.h" -#include "libburn.h" -#include "drive.h" - -/* ts A60825 : The storage location for back_hacks.h variables. */ -#define BURN_BACK_HACKS_INIT 1 -#include "back_hacks.h" - -/* ts A60924 : a new message handling facility */ -#include "libdax_msgs.h" -struct libdax_msgs *libdax_messenger= NULL; - - -int burn_running = 0; - -/* ts A60813 : wether to use O_EXCL and/or O_NONBLOCK in libburn/sg.c */ -int burn_sg_open_o_excl = 1; - -/* O_NONBLOCK was hardcoded in enumerate_ata() which i hardly use. - For enumerate_sg() it seems ok. - So it should stay default mode until enumerate_ata() without O_NONBLOCK - has been thoroughly tested. */ -int burn_sg_open_o_nonblock = 1; - -/* wether to take a busy drive as an error */ -/* Caution: this is implemented by a rough hack and eventually leads - to unconditional abort of the process */ -int burn_sg_open_abort_busy = 0; - - -/* ts A61002 */ - -#include "cleanup.h" - -/* Parameters for builtin abort handler */ -static char abort_message_prefix[81] = {"libburn : "}; -static pid_t abort_control_pid= 0; - - -/* ts A60925 : ticket 74 */ -/** Create the messenger object for libburn. */ -int burn_msgs_initialize(void) -{ - int ret; - - if(libdax_messenger == NULL) { - ret = libdax_msgs_new(&libdax_messenger,0); - if (ret <= 0) - return 0; - } - libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER, - LIBDAX_MSGS_SEV_FATAL, "libburn: ", 0); - return 1; -} - -/* ts A60924 : ticket 74 : Added use of global libdax_messenger */ -int burn_initialize(void) -{ - int ret; - - if (burn_running) - return 1; - ret = burn_msgs_initialize(); - if (ret <= 0) - return 0; - burn_running = 1; - return 1; -} - -void burn_finish(void) -{ - /* ts A61007 : assume no messageing system */ - /* a ssert(burn_running); */ - if (!burn_running) - return; - - /* ts A61007 */ - /* burn_wait_all(); */ - if (!burn_drives_are_clear()) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020107, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Drive is busy on attempt to shut down library", 0, 0); - return; - } - - /* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */ - burn_drive_free_all(); - - /* ts A60924 : ticket 74 */ - libdax_msgs_destroy(&libdax_messenger,0); - - burn_running = 0; -} - - -/* ts A60813 */ -/** API function. See libburn.h */ -void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy) -{ - /* ts A61007 */ - /* a ssert(burn_running); */ - if (!burn_running) - return; - - burn_sg_open_o_excl= exclusive; - burn_sg_open_o_nonblock= !blocking; - burn_sg_open_abort_busy= !!abort_on_busy; -} - - -/* ts A60924 : ticket 74 */ -/** Control queueing and stderr printing of messages from libburn. - Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - "NOTE", "UPDATE", "DEBUG", "ALL". - @param queue_severity Gives the minimum limit for messages to be queued. - Default: "NEVER". If you queue messages then you - must consume them by burn_msgs_obtain(). - @param print_severity Does the same for messages to be printed directly - to stderr. - @param print_id A text prefix to be printed before the message. - @return >0 for success, <=0 for error - -*/ -int burn_msgs_set_severities(char *queue_severity, - char *print_severity, char *print_id) -{ - int ret, queue_sevno, print_sevno; - - ret = libdax_msgs__text_to_sev(queue_severity, &queue_sevno, 0); - if (ret <= 0) - return 0; - ret = libdax_msgs__text_to_sev(print_severity, &print_sevno, 0); - if (ret <= 0) - return 0; - ret = libdax_msgs_set_severities(libdax_messenger, queue_sevno, - print_sevno, print_id, 0); - if (ret <= 0) - return 0; - return 1; -} - - -/* ts A60924 : ticket 74 */ -#define BURM_MSGS_MESSAGE_LEN 4096 - -/** Obtain the oldest pending libburn message from the queue which has at - least the given minimum_severity. This message and any older message of - lower severity will get discarded from the queue and is then lost forever. - Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" - will discard the whole queue. - @param error_code Will become a unique error code as liste in - libburn/libdax_msgs.h - @param msg_text Must provide at least BURM_MSGS_MESSAGE_LEN bytes. - @param os_errno Will become the eventual errno related to the message - @param severity Will become the severity related to the message and - should provide at least 80 bytes. - @return 1 if a matching item was found, 0 if not, <0 for severe errors -*/ -int burn_msgs_obtain(char *minimum_severity, - int *error_code, char msg_text[], int *os_errno, - char severity[]) -{ - int ret, minimum_sevno, sevno, priority; - char *textpt, *sev_name; - struct libdax_msgs_item *item = NULL; - - ret = libdax_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0); - if (ret <= 0) - return 0; - ret = libdax_msgs_obtain(libdax_messenger, &item, minimum_sevno, - LIBDAX_MSGS_PRIO_ZERO, 0); - if (ret <= 0) - goto ex; - ret = libdax_msgs_item_get_msg(item, error_code, &textpt, os_errno, 0); - if (ret <= 0) - goto ex; - strncpy(msg_text, textpt, BURM_MSGS_MESSAGE_LEN-1); - if(strlen(textpt) >= BURM_MSGS_MESSAGE_LEN) - msg_text[BURM_MSGS_MESSAGE_LEN-1] = 0; - - severity[0]= 0; - ret = libdax_msgs_item_get_rank(item, &sevno, &priority, 0); - if(ret <= 0) - goto ex; - ret = libdax_msgs__sev_to_text(sevno, &sev_name, 0); - if(ret <= 0) - goto ex; - strcpy(severity,sev_name); - - ret = 1; -ex: - libdax_msgs_destroy_item(libdax_messenger, &item, 0); - return ret; -} - -int burn_builtin_abort_handler(void *handle, int signum, int flag) -{ - if(getpid() != abort_control_pid) - return -2; - Cleanup_set_handlers(NULL, NULL, 2); - fprintf(stderr,"%sABORT : Trying to shut down drive and library\n", - abort_message_prefix); - fprintf(stderr, - "%sABORT : Wait the normal burning time before any kill -9\n", - abort_message_prefix); - close(0); /* somehow stdin as input blocks abort until EOF */ - burn_abort(4440, burn_abort_pacifier, abort_message_prefix); - fprintf(stderr, - "\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n", - abort_message_prefix); - return(1); -} - -void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, - int mode) -{ - if(handler == NULL && mode == 0) { - handler = burn_builtin_abort_handler; -/* - fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle)); -*/ - - } - strcpy(abort_message_prefix, "libburn : "); - if(handle != NULL) - strncpy(abort_message_prefix, (char *) handle, - sizeof(abort_message_prefix)-1); - abort_message_prefix[sizeof(abort_message_prefix)-1] = 0; - abort_control_pid= getpid(); - Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4); -} - diff --git a/libburn/init.h b/libburn/init.h deleted file mode 100644 index c3e9b9a..0000000 --- a/libburn/init.h +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__INIT_H -#define BURN__INIT_H - -extern int burn_running; - -#endif /* BURN__INIT_H */ diff --git a/libburn/lec.c b/libburn/lec.c deleted file mode 100644 index 9141593..0000000 --- a/libburn/lec.c +++ /dev/null @@ -1,451 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* borrowed HEAVILY from cdrdao */ - -#include -#include "lec.h" - -#define LEC_HEADER_OFFSET 12 -#define LEC_MODE1_P_PARITY_OFFSET 2076 -#define LEC_MODE1_Q_PARITY_OFFSET 2248 - -static unsigned char gf8_ilog[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 unsigned char gf8_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 unsigned char gf8_q_coeffs[2][45] = { - {97, 251, 133, 60, 82, 160, 155, 201, 8, 112, 246, 11, 21, 42, 157, - 169, 80, 174, 232, 230, 172, 211, 241, 18, 68, 216, 44, 121, 9, 200, - 75, 103, 221, 252, 96, 176, 88, 167, 114, 76, 199, 26, 1, 0, 0}, - {190, 96, 250, 132, 59, 81, 159, 154, 200, 7, 111, 245, 10, 20, 41, - 156, 168, 79, 173, 231, 229, 171, 210, 240, 17, 67, 215, 43, 120, 8, - 199, 74, 102, 220, 251, 95, 175, 87, 166, 113, 75, 198, 25, 0, 0} -}; -static unsigned char gf8_p_coeffs[2][26] = { - {230, 172, 211, 241, 18, 68, 216, 44, 121, 9, 200, 75, 103, 221, 252, - 96, 176, 88, 167, 114, 76, 199, 26, 1, 0, 0}, - {231, 229, 171, 210, 240, 17, 67, 215, 43, 120, 8, 199, 74, 102, 220, - 251, 95, 175, 87, 166, 113, 75, 198, 25, 0, 0} -}; - -static 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, -}; - -void scramble(unsigned char *inout) -{ - unsigned char *r = inout + 12; - unsigned char *s = yellowbook_scrambler; - unsigned int i; - - for (i = 2340; i; i--) { - *r++ ^= *s++; - } -} - -/* Calculate the P parities for the sector. - * The 43 P vectors of length 24 are combined with the GF8_P_COEFFS. - */ -void parity_p(unsigned char *sector) -{ - int i, j; - unsigned char p0_msb, p1_msb; - unsigned char p0_lsb, p1_lsb; - unsigned char *p_msb_start, *p_lsb_start; - unsigned char *p_msb, *p_lsb; - unsigned char *coeffs0, *coeffs1; - unsigned char *p0, *p1; - unsigned char d; - unsigned short c; - - p_lsb_start = sector + LEC_HEADER_OFFSET; - p_msb_start = sector + LEC_HEADER_OFFSET + 1; - - p1 = sector + LEC_MODE1_P_PARITY_OFFSET; - p0 = sector + LEC_MODE1_P_PARITY_OFFSET + 2 * 43; - - for (i = 0; i <= 42; i++) { - p_lsb = p_lsb_start; - p_msb = p_msb_start; - - coeffs0 = gf8_p_coeffs[0]; - coeffs1 = gf8_p_coeffs[1]; - - p0_lsb = p1_lsb = p0_msb = p1_msb = 0; - - for (j = 0; j <= 23; j++) { - d = *p_lsb; - - if (d != 0) { - c = gf8_log[d] + *coeffs0; - if (c >= 255) - c -= 255; - p0_lsb ^= gf8_ilog[c]; - - c = gf8_log[d] + *coeffs1; - if (c >= 255) - c -= 255; - p1_lsb ^= gf8_ilog[c]; - } - - d = *p_msb; - - if (d != 0) { - c = gf8_log[d] + *coeffs0; - if (c >= 255) - c -= 255; - p0_msb ^= gf8_ilog[c]; - - c = gf8_log[d] + *coeffs1; - if (c >= 255) - c -= 255; - p1_msb ^= gf8_ilog[c]; - } - - coeffs0++; - coeffs1++; - - p_lsb += 2 * 43; - p_msb += 2 * 43; - } - - *p0 = p0_lsb; - *(p0 + 1) = p0_msb; - - *p1 = p1_lsb; - *(p1 + 1) = p1_msb; - - p0 += 2; - p1 += 2; - - p_lsb_start += 2; - p_msb_start += 2; - } -} - -/* Calculate the Q parities for the sector. - * The 26 Q vectors of length 43 are combined with the GF8_Q_COEFFS. - */ -void parity_q(unsigned char *sector) -{ - int i, j; - unsigned char q0_msb, q1_msb; - unsigned char q0_lsb, q1_lsb; - unsigned char *q_msb_start, *q_lsb_start; - unsigned char *q_msb, *q_lsb; - unsigned char *coeffs0, *coeffs1; - unsigned char *q0, *q1, *q_start; - unsigned char d; - unsigned short c; - - q_lsb_start = sector + LEC_HEADER_OFFSET; - q_msb_start = sector + LEC_HEADER_OFFSET + 1; - - q_start = sector + LEC_MODE1_Q_PARITY_OFFSET; - q1 = sector + LEC_MODE1_Q_PARITY_OFFSET; - q0 = sector + LEC_MODE1_Q_PARITY_OFFSET + 2 * 26; - - for (i = 0; i <= 25; i++) { - q_lsb = q_lsb_start; - q_msb = q_msb_start; - - coeffs0 = gf8_q_coeffs[0]; - coeffs1 = gf8_q_coeffs[1]; - - q0_lsb = q1_lsb = q0_msb = q1_msb = 0; - - for (j = 0; j <= 42; j++) { - d = *q_lsb; - - if (d != 0) { - c = gf8_log[d] + *coeffs0; - if (c >= 255) - c -= 255; - q0_lsb ^= gf8_ilog[c]; - - c = gf8_log[d] + *coeffs1; - if (c >= 255) - c -= 255; - q1_lsb ^= gf8_ilog[c]; - } - - d = *q_msb; - - if (d != 0) { - c = gf8_log[d] + *coeffs0; - if (c >= 255) - c -= 255; - q0_msb ^= gf8_ilog[c]; - - c = gf8_log[d] + *coeffs1; - if (c >= 255) - c -= 255; - q1_msb ^= gf8_ilog[c]; - } - - coeffs0++; - coeffs1++; - - q_lsb += 2 * 44; - q_msb += 2 * 44; - - if (q_lsb >= q_start) { - q_msb -= 2 * 1118; - q_lsb -= 2 * 1118; - } - } - - *q0 = q0_lsb; - *(q0 + 1) = q0_msb; - - *q1 = q1_lsb; - *(q1 + 1) = q1_msb; - - q0 += 2; - q1 += 2; - - q_lsb_start += 2 * 43; - q_msb_start += 2 * 43; - } -} diff --git a/libburn/lec.h b/libburn/lec.h deleted file mode 100644 index f698030..0000000 --- a/libburn/lec.h +++ /dev/null @@ -1,12 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __LEC -#define __LEC - -#define RS_L12_BITS 8 - -void scramble(unsigned char *); -void parity_p(unsigned char *in); -void parity_q(unsigned char *in); - -#endif /* __LEC */ diff --git a/libburn/libburn.h b/libburn/libburn.h deleted file mode 100644 index f0f9d93..0000000 --- a/libburn/libburn.h +++ /dev/null @@ -1,1243 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef LIBBURN_H -#define LIBBURN_H - -/* Needed for off_t which is the (POSIX-ly) appropriate type for - expressing a file or stream size. - - XXX we should enforce 64-bitness for off_t - ts A61101 : this is usually done by the build system (if it is not broken) -*/ -#include - -#ifndef DOXYGEN - -#if defined(__cplusplus) -#define BURN_BEGIN_DECLS \ - namespace burn { \ - extern "C" { -#define BURN_END_DECLS \ - } \ - } -#else -#define BURN_BEGIN_DECLS -#define BURN_END_DECLS -#endif - -BURN_BEGIN_DECLS - -#endif - -/** References a physical drive in the system */ -struct burn_drive; - -/** References a whole disc */ -struct burn_disc; - -/** References a single session on a disc */ -struct burn_session; - -/** References a single track on a disc */ -struct burn_track; - -/* ts A61111 */ -/** References a set of write parameters */ -struct burn_write_opts; - -/** Session format for normal audio or data discs */ -#define BURN_CDROM 0 -/** Session format for obsolete CD-I discs */ -#define BURN_CDI 0x10 -/** Session format for CDROM-XA discs */ -#define BURN_CDXA 0x20 - -#define BURN_POS_END 100 - -/** Mask for mode bits */ -#define BURN_MODE_BITS 127 - -/** Track mode - mode 0 data - 0 bytes of user data. it's all 0s. mode 0. get it? HAH -*/ -#define BURN_MODE0 (1 << 0) -/** Track mode - mode "raw" - all 2352 bytes supplied by app - FOR DATA TRACKS ONLY! -*/ -#define BURN_MODE_RAW (1 << 1) -/** Track mode - mode 1 data - 2048 bytes user data, and all the LEC money can buy -*/ -#define BURN_MODE1 (1 << 2) -/** Track mode - mode 2 data - defaults to formless, 2336 bytes of user data, unprotected - | with a data form if required. -*/ -#define BURN_MODE2 (1 << 3) -/** Track mode modifier - Form 1, | with MODE2 for reasonable results - 2048 bytes of user data, 4 bytes of subheader -*/ -#define BURN_FORM1 (1 << 4) -/** Track mode modifier - Form 2, | with MODE2 for reasonable results - lots of user data. not much LEC. -*/ -#define BURN_FORM2 (1 << 5) -/** Track mode - audio - 2352 bytes per sector. may be | with 4ch or preemphasis. - NOT TO BE CONFUSED WITH BURN_MODE_RAW - Audio data must be 44100Hz 16bit stereo with no riff or other header at - beginning. Extra header data will cause pops or clicks. Audio data should - also be in little-endian byte order. Big-endian audio data causes static. -*/ -#define BURN_AUDIO (1 << 6) -/** Track mode modifier - 4 channel audio. */ -#define BURN_4CH (1 << 7) -/** Track mode modifier - Digital copy permitted, can be set on any track.*/ -#define BURN_COPY (1 << 8) -/** Track mode modifier - 50/15uS pre-emphasis */ -#define BURN_PREEMPHASIS (1 << 9) -/** Input mode modifier - subcodes present packed 16 */ -#define BURN_SUBCODE_P16 (1 << 10) -/** Input mode modifier - subcodes present packed 96 */ -#define BURN_SUBCODE_P96 (1 << 11) -/** Input mode modifier - subcodes present raw 96 */ -#define BURN_SUBCODE_R96 (1 << 12) - -/** Possible disc writing style/modes */ -enum burn_write_types -{ - /** Packet writing. - currently unsupported - */ - BURN_WRITE_PACKET, - /** Track At Once recording. - 2s gaps between tracks, no fonky lead-ins - */ - BURN_WRITE_TAO, - /** Session At Once. - block type MUST be BURN_BLOCK_SAO - */ - BURN_WRITE_SAO, - /** Raw disc at once recording. - all subcodes must be provided by lib or user - only raw block types are supported - */ - BURN_WRITE_RAW -}; - -/** Data format to send to the drive */ -enum burn_block_types -{ - /** sync, headers, edc/ecc provided by lib/user */ - BURN_BLOCK_RAW0 = 1, - /** sync, headers, edc/ecc and p/q subs provided by lib/user */ - BURN_BLOCK_RAW16 = 2, - /** sync, headers, edc/ecc and packed p-w subs provided by lib/user */ - BURN_BLOCK_RAW96P = 4, - /** sync, headers, edc/ecc and raw p-w subs provided by lib/user */ - BURN_BLOCK_RAW96R = 8, - /** only 2048 bytes of user data provided by lib/user */ - BURN_BLOCK_MODE1 = 256, - /** 2336 bytes of user data provided by lib/user */ - BURN_BLOCK_MODE2R = 512, - /** 2048 bytes of user data provided by lib/user - subheader provided in write parameters - are we ever going to support this shit? I vote no. - (supposed to be supported on all drives...) - */ - BURN_BLOCK_MODE2_PATHETIC = 1024, - /** 2048 bytes of data + 8 byte subheader provided by lib/user - hey, this is also dumb - */ - BURN_BLOCK_MODE2_LAME = 2048, - /** 2324 bytes of data provided by lib/user - subheader provided in write parameters - no sir, I don't like it. - */ - BURN_BLOCK_MODE2_OBSCURE = 4096, - /** 2332 bytes of data supplied by lib/user - 8 bytes sub header provided in write parameters - this is the second least suck mode2, and is mandatory for - all drives to support. - */ - BURN_BLOCK_MODE2_OK = 8192, - /** SAO block sizes are based on cue sheet, so use this. */ - BURN_BLOCK_SAO = 16384 -}; - -/** Possible status' of the drive in regard to the disc in it. */ -enum burn_disc_status -{ - /** The current status is not yet known */ - BURN_DISC_UNREADY, - /** The drive holds a blank disc */ - BURN_DISC_BLANK, - /** There is no disc at all in the drive */ - BURN_DISC_EMPTY, - /** There is an incomplete disc in the drive */ - BURN_DISC_APPENDABLE, - /** There is a disc with data on it in the drive */ - BURN_DISC_FULL, - - /* ts A61007 */ - /** The drive was not grabbed when the status was inquired */ - BURN_DISC_UNGRABBED, - - /* ts A61020 */ - /** The media seems not to be suitable for burning */ - BURN_DISC_UNSUITABLE -}; - - -/** Possible data source return values */ -enum burn_source_status -{ - /** The source is ok */ - BURN_SOURCE_OK, - /** The source is at end of file */ - BURN_SOURCE_EOF, - /** The source is unusable */ - BURN_SOURCE_FAILED -}; - - -/** Possible busy states for a drive */ -enum burn_drive_status -{ - /** The drive is not in an operation */ - BURN_DRIVE_IDLE, - /** The library is spawning the processes to handle a pending - operation (A read/write/etc is about to start but hasn't quite - yet) */ - BURN_DRIVE_SPAWNING, - /** The drive is reading data from a disc */ - BURN_DRIVE_READING, - /** The drive is writing data to a disc */ - BURN_DRIVE_WRITING, - /** The drive is writing Lead-In */ - BURN_DRIVE_WRITING_LEADIN, - /** The drive is writing Lead-Out */ - BURN_DRIVE_WRITING_LEADOUT, - /** The drive is erasing a disc */ - BURN_DRIVE_ERASING, - /** The drive is being grabbed */ - BURN_DRIVE_GRABBING, - - /* ts A61102 */ - /** The drive gets written zeroes before the track payload data */ - BURN_DRIVE_WRITING_PREGAP, - /** The drive is told to close a track (TAO only) */ - BURN_DRIVE_CLOSING_TRACK, - /** The drive is told to close a session (TAO only) */ - BURN_DRIVE_CLOSING_SESSION - -}; - -/** Information about a track on a disc - this is from the q sub channel of the - lead-in area of a disc. The documentation here is very terse. - See a document such as mmc3 for proper information. -*/ -struct burn_toc_entry -{ - /** Session the track is in */ - unsigned char session; - /** Type of data. for this struct to be valid, it must be 1 */ - unsigned char adr; - /** Type of data in the track */ - unsigned char control; - /** Zero. Always. Really. */ - unsigned char tno; - /** Track number or special information */ - unsigned char point; - unsigned char min; - unsigned char sec; - unsigned char frame; - unsigned char zero; - /** Track start time minutes for normal tracks */ - unsigned char pmin; - /** Track start time seconds for normal tracks */ - unsigned char psec; - /** Track start time frames for normal tracks */ - unsigned char pframe; -}; - - -/** Data source for tracks */ -struct burn_source { - /** Reference count for the data source. Should be 1 when a new source - is created. Increment it to take a reference for yourself. Use - burn_source_free to destroy your reference to it. */ - int refcount; - - /** Read data from the source */ - int (*read)(struct burn_source *, - unsigned char *buffer, - int size); - - /** Read subchannel data from the source (NULL if lib generated) */ - int (*read_sub)(struct burn_source *, - unsigned char *buffer, - int size); - - /** Get the size of the source's data */ - off_t (*get_size)(struct burn_source *); - - /** Clean up the source specific data */ - void (*free_data)(struct burn_source *); - - /** Next source, for when a source runs dry and padding is disabled - THIS IS AUTOMATICALLY HANDLED, DO NOT TOUCH - */ - struct burn_source *next; - - /** Source specific data */ - void *data; -}; - - -/** Information on a drive in the system */ -struct burn_drive_info -{ - /** Name of the vendor of the drive */ - char vendor[9]; - /** Name of the drive */ - char product[17]; - /** Revision of the drive */ - char revision[5]; - /** Location of the drive in the filesystem. */ - char location[17]; - /** This is currently the string which is used as persistent - drive address. But be warned: there is NO GUARANTEE that this - will stay so. Always use function burn_drive_get_adr() to - inquire a persistent address. ^^^^^^ ALWAYS ^^^^^^ */ - - /** Can the drive read DVD-RAM discs */ - unsigned int read_dvdram:1; - /** Can the drive read DVD-R discs */ - unsigned int read_dvdr:1; - /** Can the drive read DVD-ROM discs */ - unsigned int read_dvdrom:1; - /** Can the drive read CD-R discs */ - unsigned int read_cdr:1; - /** Can the drive read CD-RW discs */ - unsigned int read_cdrw:1; - - /** Can the drive write DVD-RAM discs */ - unsigned int write_dvdram:1; - /** Can the drive write DVD-R discs */ - unsigned int write_dvdr:1; - /** Can the drive write CD-R discs */ - unsigned int write_cdr:1; - /** Can the drive write CD-RW discs */ - unsigned int write_cdrw:1; - - /** Can the drive simulate a write */ - unsigned int write_simulate:1; - - /** Can the drive report C2 errors */ - unsigned int c2_errors:1; - - /** The size of the drive's buffer (in kilobytes) */ - int buffer_size; - /** - * The supported block types in tao mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int tao_block_types; - /** - * The supported block types in sao mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int sao_block_types; - /** - * The supported block types in raw mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int raw_block_types; - /** - * The supported block types in packet mode. - * They should be tested with the desired block type. - * See also burn_block_types. - */ - int packet_block_types; - - /** The value by which this drive can be indexed when using functions - in the library. This is the value to pass to all libbburn functions - that operate on a drive. */ - struct burn_drive *drive; -}; - - -/** Operation progress report. All values are 0 based indices. - * */ -struct burn_progress { - /** The total number of sessions */ - int sessions; - /** Current session.*/ - int session; - /** The total number of tracks */ - int tracks; - /** Current track. */ - int track; - /** The total number of indices */ - int indices; - /** Curent index. */ - int index; - /** The starting logical block address */ - int start_sector; - /** The number of sector */ - int sectors; - /** The current sector being processed */ - int sector; - - /* ts A61023 */ - /** The capacity of the drive buffer */ - unsigned buffer_capacity; - /** The free space in the drive buffer (might be slightly outdated) */ - unsigned buffer_available; -}; - -/** Initialize the library. - This must be called before using any other functions in the library. It - may be called more than once with no effect. - It is possible to 'restart' the library by shutting it down and - re-initializing it. This is necessary if you follow the older and - more general way of accessing a drive via burn_drive_scan() and - burn_drive_grab(). See burn_drive_scan_and_grab() with its strong - urges and its explanations. - @return Nonzero if the library was able to initialize; zero if - initialization failed. -*/ -int burn_initialize(void); - -/** Shutdown the library. - This should be called before exiting your application. Make sure that all - drives you have grabbed are released before calling this. -*/ -void burn_finish(void); - - -/* ts A61002 */ -/** Abort any running drive operation and finally call burn_finish(). - You MUST calm down the busy drive if an aborting event occurs during a - burn run. For that you may call this function either from your own signal - handling code or indirectly by activating the builtin signal handling: - burn_set_signal_handling("my_app_name : ", NULL, 0); - Else you may eventually call burn_drive_cancel() on the active drive and - wait for it to assume state BURN_DRIVE_IDLE. - @param patience Maximum number of seconds to wait for drives to finish - @param pacifier_func If not NULL: a function to produce appeasing messages. - See burn_abort_pacifier() for an example. - @return 1 ok, all went well - 0 had to leave a drive in unclean state - <0 severe error, do no use libburn again -*/ -int burn_abort(int patience, - int (*pacifier_func)(void *handle, int patience, int elapsed), - void *handle); - -/** A pacifier function suitable for burn_abort. - @param handle If not NULL, a pointer to a text suitable for printf("%s") - @param patience Maximum number of seconds to wait - @param elapsed Elapsed number of seconds -*/ -int burn_abort_pacifier(void *handle, int patience, int elapsed); - - -/** ts A61006 : This is for development only. Not suitable for applications. - Set the verbosity level of the library. The default value is 0, which means - that nothing is output on stderr. The more you increase this, the more - debug output should be displayed on stderr for you. - @param level The verbosity level desired. 0 for nothing, higher positive - values for more information output. -*/ -void burn_set_verbosity(int level); - -/* ts A60813 */ -/** Set parameters for behavior on opening device files. To be called early - after burn_initialize() and before any bus scan. But not mandatory at all. - Parameter value 1 enables a feature, 0 disables. - Default is (1,0,0). Have a good reason before you change it. - @param exclusive 1 = Try to open only devices which are not marked as busy - and try to mark them busy if opened sucessfully. (O_EXCL) - There are kernels which simply don't care about O_EXCL. - Some have it off, some have it on, some are switchable. - 2 = in case of a SCSI device, also try to open exclusively - the matching /dev/sr, /dev/scd and /dev/st . - 0 = no attempt to make drive access exclusive. - @param blocking Try to wait for drives which do not open immediately but - also do not return an error as well. (O_NONBLOCK) - This might stall indefinitely with /dev/hdX hard disks. - @param abort_on_busy Unconditionally abort process when a non blocking - exclusive opening attempt indicates a busy drive. - Use this only after thorough tests with your app. -*/ -void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy); - - -/* ts A60823 */ -/** Aquire a drive with known persistent address.This is the sysadmin friendly - way to open one drive and to leave all others untouched. It bundles - the following API calls to form a non-obtrusive way to use libburn: - burn_drive_add_whitelist() , burn_drive_scan() , burn_drive_grab() - You are *strongly urged* to use this call whenever you know the drive - address in advance. - If not, then you have to use directly above calls. In that case, you are - *strongly urged* to drop any unintended drive which will be exclusively - occupied and not closed by burn_drive_scan(). - This can be done by shutting down the library including a call to - burn_finish(). You may later start a new libburn session and should then - use the function described here with an address obtained after - burn_drive_scan() via burn_drive_get_adr(&(drive_infos[driveno]), adr) . - Another way is to drop the unwanted drives by burn_drive_info_forget(). - @param drive_infos On success returns a one element array with the drive - (cdrom/burner). Thus use with driveno 0 only. On failure - the array has no valid elements at all. - The returned array should be freed via burn_drive_info_free() - when it is no longer needed, and before calling a scan - function again. - This is a result from call burn_drive_scan(). See there. - Use with driveno 0 only. - @param adr The persistent address of the desired drive. Either obtained - by burn_drive_get_adr() or guessed skillfully by application - resp. its user. - @param load Nonzero to make the drive attempt to load a disc (close its - tray door, etc). - @return 1 = success , 0 = drive not found , -1 = other error -*/ -int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], - char* adr, int load); - - -/* ts A51221 */ -/** Maximum number of particularly permissible drive addresses */ -#define BURN_DRIVE_WHITELIST_LEN 255 -/** Add a device to the list of permissible drives. As soon as some entry is in - the whitelist all non-listed drives are banned from scanning. - @return 1 success, <=0 failure -*/ -int burn_drive_add_whitelist(char *device_address); - -/** Remove all drives from whitelist. This enables all possible drives. */ -void burn_drive_clear_whitelist(void); - - -/** Scan for drives. This function MUST be called until it returns nonzero. - No drives may be in use when this is called. - All drive pointers are invalidated by using this function. Do NOT store - drive pointers across calls to this function or death AND pain will ensue. - After this call all drives depicted by the returned array are subject - to eventual (O_EXCL) locking. See burn_preset_device_open(). This state - ends either with burn_drive_info_forget() or with burn_drive_release(). - It is unfriendly to other processes on the system to hold drives locked - which one does not definitely plan to use soon. - @param drive_infos Returns an array of drive info items (cdroms/burners). - The returned array must be freed by burn_drive_info_free() - before burn_finish(), and also before calling this function - burn_drive_scan() again. - @param n_drives Returns the number of drive items in drive_infos. - @return 0 while scanning is not complete - >0 when it is finished sucessfully, - <0 when finished but failed. -*/ -int burn_drive_scan(struct burn_drive_info *drive_infos[], - unsigned int *n_drives); - -/* ts A60904 : ticket 62, contribution by elmom */ -/** Release memory about a single drive and any exclusive lock on it. - Become unable to inquire or grab it. Expect FATAL consequences if you try. - @param drive_info pointer to a single element out of the array - obtained from burn_drive_scan() : &(drive_infos[driveno]) - @param force controls degree of permissible drive usage at the moment this - function is called, and the amount of automatically provided - drive shutdown : - 0= drive must be ungrabbed and BURN_DRIVE_IDLE - 1= try to release drive resp. accept BURN_DRIVE_GRABBING - Use these two only. Further values are to be defined. - @return 1 on success, 2 if drive was already forgotten, - 0 if not permissible, <0 on other failures, -*/ -int burn_drive_info_forget(struct burn_drive_info *drive_info, int force); - - -/** Free a burn_drive_info array returned by burn_drive_scan -*/ -void burn_drive_info_free(struct burn_drive_info drive_infos[]); - - -/* ts A60823 */ -/** Maximum length+1 to expect with a persistent drive address string */ -#define BURN_DRIVE_ADR_LEN 1024 - -/** Inquire the persistent address of the given drive. - @param drive_info The drive to inquire. Usually some &(drive_infos[driveno]) - @param adr An application provided array of at least BURN_DRIVE_ADR_LEN - characters size. The persistent address gets copied to it. - @return >0 success , <=0 error (due to libburn internal problem) -*/ -int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]); - -/* ts A60922 ticket 33 */ -/** Evaluate wether the given address would be a possible persistent drive - address of libburn. - @return 1 means yes, 0 means no -*/ -int burn_drive_is_enumerable_adr(char *adr); - -/* ts A60922 ticket 33 */ -/** Try to convert a given existing filesystem address into a persistent drive - address. This succeeds with symbolic links or if a hint about the drive's - system address can be read from the filesystem object and a matching drive - is found. - @param path The address of an existing file system object - @param adr An application provided array of at least BURN_DRIVE_ADR_LEN - characters size. The persistent address gets copied to it. - @return 1 = success , 0 = failure , -1 = severe error -*/ -int burn_drive_convert_fs_adr(char *path, char adr[]); - -/* ts A60923 */ -/** Try to convert a given SCSI address of bus,host,channel,target,lun into - a persistent drive address. If a SCSI address component parameter is < 0 - then it is not decisive and the first enumerated address which matches - the >= 0 parameters is taken as result. - Note: bus and (host,channel) are supposed to be redundant. - @param adr An application provided array of at least BURN_DRIVE_ADR_LEN - characters size. The persistent address gets copied to it. - @return 1 = success , 0 = failure , -1 = severe error -*/ -int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no, - int target_no, int lun_no, char adr[]); - -/* ts A60923 - A61005 */ -/** Try to obtain bus,host,channel,target,lun from path. If there is an SCSI - address at all, then this call should succeed with a persistent - drive address obtained via burn_drive_get_adr(). It is also supposed to - succeed with any device file of a (possibly emulated) SCSI device. - @return 1 = success , 0 = failure , -1 = severe error -*/ -int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no, - int *channel_no, int *target_no, int *lun_no); - -/** Grab a drive. This must be done before the drive can be used (for reading, - writing, etc). - @param drive The drive to grab. This is found in a returned - burn_drive_info struct. - @param load Nonzero to make the drive attempt to load a disc (close its - tray door, etc). - @return 1 if it was possible to grab the drive, else 0 -*/ -int burn_drive_grab(struct burn_drive *drive, int load); - - -/** Release a drive. This should not be done until the drive is no longer - busy (see burn_drive_get_status). The drive is (O_EXCL) unlocked - afterwards. - @param drive The drive to release. - @param eject Nonzero to make the drive eject the disc in it. -*/ -void burn_drive_release(struct burn_drive *drive, int eject); - - -/** Returns what kind of disc a drive is holding. This function may need to be - called more than once to get a proper status from it. See burn_status - for details. - @param drive The drive to query for a disc. - @return The status of the drive, or what kind of disc is in it. - Note: BURN_DISC_UNGRABBED indicates wrong API usage -*/ -enum burn_disc_status burn_disc_get_status(struct burn_drive *drive); - - -/* ts A61020 */ -/** WARNING: This revives an old bug-like behavior that might be dangerous. - Sets the drive status to BURN_DISC_BLANK if it is BURN_DISC_UNREADY - or BURN_DISC_UNSUITABLE. Thus marking media as writable which actually - failed to declare themselves either blank or (partially) filled. - @return 1 drive status has been set , 0 = unsuitable drive status -*/ -int burn_disc_pretend_blank(struct burn_drive *drive); - - -/* ts A61106 */ -/** WARNING: This overrides the safety measures against unsuitable media. - Sets the drive status to BURN_DISC_FULL if it is BURN_DISC_UNREADY - or BURN_DISC_UNSUITABLE. Thus marking media as blankable which actually - failed to declare themselves either blank or (partially) filled. -*/ -int burn_disc_pretend_full(struct burn_drive *drive); - - -/* ts A61021 */ -/** Reads ATIP information from inserted media. To be obtained via - burn_drive_get_write_speed(), burn_drive_get_min_write_speed(), - burn_drive_get_start_end_lba(). The drive must be grabbed for this call. - @param drive The drive to query. - @return 1=sucess, 0=no valid ATIP info read, -1 severe error -*/ -int burn_disc_read_atip(struct burn_drive *drive); - - -/* ts A61020 */ -/** Returns start and end lba of the media which is currently inserted - in the given drive. The drive has to be grabbed to have hope for reply. - Shortcomming (not a feature): unless burn_disc_read_atip() was called - only blank media will return valid info. - @param drive The drive to query. - @param start_lba Returns the start lba value - @param end_lba Returns the end lba value - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 if lba values are valid , 0 if invalid -*/ -int burn_drive_get_start_end_lba(struct burn_drive *drive, - int *start_lba, int *end_lba, int flag); - -/* ts A61110 */ -/** Read start lba and Next Writeable Address of a track from media. - Usually a track lba is obtained from the result of burn_track_get_entry(). - This call retrieves an updated lba, eventual nwa, and can address the - invisible track to come. - The drive must be grabbed for this call. One may not issue this call - during ongoing burn_disc_write() or burn_disc_erase(). - @param d The drive to query. - @param o If not NULL: write parameters to be set on drive before query - @param trackno 0=next track to come, >0 number of existing track - @return 1=nwa is valid , 0=nwa is not valid , -1=error -*/ -int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, - int trackno, int *lba, int *nwa); - - -/** Tells whether a disc can be erased or not - @return Non-zero means erasable -*/ -int burn_disc_erasable(struct burn_drive *d); - -/** Returns the progress and status of a drive. - @param drive The drive to query busy state for. - @param p Returns the progress of the operation, NULL if you don't care - @return the current status of the drive. See also burn_drive_status. -*/ -enum burn_drive_status burn_drive_get_status(struct burn_drive *drive, - struct burn_progress *p); - -/** Creates a write_opts struct for burning to the specified drive - must be freed with burn_write_opts_free - @param drive The drive to write with - @return The write_opts, NULL on error -*/ -struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive); - -/** Frees a write_opts struct created with burn_write_opts_new - @param opts write_opts to free -*/ -void burn_write_opts_free(struct burn_write_opts *opts); - -/** Creates a read_opts struct for reading from the specified drive - must be freed with burn_write_opts_free - @param drive The drive to read from - @return The read_opts -*/ -struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive); - -/** Frees a read_opts struct created with burn_read_opts_new - @param opts write_opts to free -*/ -void burn_read_opts_free(struct burn_read_opts *opts); - -/** Erase a disc in the drive. The drive must be grabbed successfully BEFORE - calling this functions. Always ensure that the drive reports a status of - BURN_DISC_FULL before calling this function. An erase operation is not - cancellable, as control of the operation is passed wholly to the drive and - there is no way to interrupt it safely. - @param drive The drive with which to erase a disc. - @param fast Nonzero to do a fast erase, where only the disc's headers are - erased; zero to erase the entire disc. -*/ -void burn_disc_erase(struct burn_drive *drive, int fast); - -/* ts A61109 : this is defunct */ -/** Read a disc from the drive and write it to an fd pair. The drive must be - grabbed successfully BEFORE calling this function. Always ensure that the - drive reports a status of BURN_DISC_FULL before calling this function. - @param drive The drive from which to read a disc. - @param o The options for the read operation. -*/ -void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o); - -/** Write a disc in the drive. The drive must be grabbed successfully before - calling this function. Always ensure that the drive reports a status of - BURN_DISC_BLANK before calling this function. - @param o The options for the writing operation. - @param disc The struct burn_disc * that described the disc to be created -*/ -void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc); - -/** Cancel an operation on a drive. - This will only work when the drive's busy state is BURN_DRIVE_READING or - BURN_DRIVE_WRITING. - @param drive The drive on which to cancel the current operation. -*/ -void burn_drive_cancel(struct burn_drive *drive); - -/** Convert a minute-second-frame (MSF) value to sector count - @param m Minute component - @param s Second component - @param f Frame component - @return The sector count -*/ -int burn_msf_to_sectors(int m, int s, int f); - -/** Convert a sector count to minute-second-frame (MSF) - @param sectors The sector count - @param m Returns the minute component - @param s Returns the second component - @param f Returns the frame component -*/ -void burn_sectors_to_msf(int sectors, int *m, int *s, int *f); - -/** Convert a minute-second-frame (MSF) value to an lba - @param m Minute component - @param s Second component - @param f Frame component - @return The lba -*/ -int burn_msf_to_lba(int m, int s, int f); - -/** Convert an lba to minute-second-frame (MSF) - @param lba The lba - @param m Returns the minute component - @param s Returns the second component - @param f Returns the frame component -*/ -void burn_lba_to_msf(int lba, int *m, int *s, int *f); - -/** Create a new disc (for DAO recording)*/ -struct burn_disc *burn_disc_create(void); - -/** Delete disc and decrease the reference count on all its sessions - @param d The disc to be freed -*/ -void burn_disc_free(struct burn_disc *d); - -/** Create a new session (For SAO at once recording, or to be added to a - disc for DAO) -*/ -struct burn_session *burn_session_create(void); - -/** Free a session (and decrease reference count on all tracks inside) - @param s Session to be freed -*/ -void burn_session_free(struct burn_session *s); - -/** Add a session to a disc at a specific position, increasing the - sessions's reference count. - @param d Disc to add the session to - @param s Session to add to the disc - @param pos position to add at (BURN_POS_END is "at the end") - @return 0 for failure, 1 for success -*/ -int burn_disc_add_session(struct burn_disc *d, struct burn_session *s, - unsigned int pos); - -/** Remove a session from a disc - @param d Disc to remove session from - @param s Session pointer to find and remove -*/ -int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s); - - -/** Create a track (for TAO recording, or to put in a session) */ -struct burn_track *burn_track_create(void); - -/** Free a track - @param t Track to free -*/ -void burn_track_free(struct burn_track *t); - -/** Add a track to a session at specified position - @param s Session to add to - @param t Track to insert in session - @param pos position to add at (BURN_POS_END is "at the end") - @return 0 for failure, 1 for success -*/ -int burn_session_add_track(struct burn_session *s, struct burn_track *t, - unsigned int pos); - -/** Remove a track from a session - @param s Session to remove track from - @param t Track pointer to find and remove - @return 0 for failure, 1 for success -*/ -int burn_session_remove_track(struct burn_session *s, struct burn_track *t); - - -/** Define the data in a track - @param t the track to define - @param offset The lib will write this many 0s before start of data - @param tail The number of extra 0s to write after data - @param pad 1 means the lib should pad the last sector with 0s if the - track isn't exactly sector sized. (otherwise the lib will - begin reading from the next track) - @param mode data format (bitfield) -*/ -void burn_track_define_data(struct burn_track *t, int offset, int tail, - int pad, int mode); - - -/* ts A61024 */ -/** Define wether a track shall swap bytes of its input stream. - @param t The track to change - @param swap_source_bytes 0=do not swap, 1=swap byte pairs - @return 1=success , 0=unacceptable value -*/ -int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes); - - -/** Set the ISRC details for a track - @param t The track to change - @param country the 2 char country code. Each character must be - only numbers or letters. - @param owner 3 char owner code. Each character must be only numbers - or letters. - @param year 2 digit year. A number in 0-99 (Yep, not Y2K friendly). - @param serial 5 digit serial number. A number in 0-99999. -*/ -void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, - unsigned char year, unsigned int serial); - -/** Disable ISRC parameters for a track - @param t The track to change -*/ -void burn_track_clear_isrc(struct burn_track *t); - -/** Hide the first track in the "pre gap" of the disc - @param s session to change - @param onoff 1 to enable hiding, 0 to disable -*/ -void burn_session_hide_first_track(struct burn_session *s, int onoff); - -/** Get the drive's disc struct - free when done - @param d drive to query - @return the disc struct or NULL on failure -*/ -struct burn_disc *burn_drive_get_disc(struct burn_drive *d); - -/** Set the track's data source - @param t The track to set the data source for - @param s The data source to use for the contents of the track - @return An error code stating if the source is ready for use for - writing the track, or if an error occured - -*/ -enum burn_source_status burn_track_set_source(struct burn_track *t, - struct burn_source *s); - -/** Free a burn_source (decrease its refcount and maybe free it) - @param s Source to free -*/ -void burn_source_free(struct burn_source *s); - -/** Creates a data source for an image file (and maybe subcode file) */ -struct burn_source *burn_file_source_new(const char *path, - const char *subpath); - -/** Creates a data source for an image file (a track) from an open - readable filedescriptor, an eventually open readable subcodes file - descriptor and eventually a fixed size in bytes. - @param datafd The source of data. - @param subfd The eventual source for subcodes. Not used if -1. - @param size The eventual fixed size of eventually both fds. - If this value is 0, the size will be determined from datafd. -*/ -struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size); - -/** Tells how long a track will be on disc - >>> NOTE: Not reliable with tracks of undefined length -*/ -int burn_track_get_sectors(struct burn_track *); - - -/* ts A61101 */ -/** Tells how many source bytes have been read and how many data bytes have - been written by the track during burn */ -int burn_track_get_counters(struct burn_track *t, - off_t *read_bytes, off_t *written_bytes); - - -/** Sets drive read and write speed - @param d The drive to set speed for - @param read Read speed in k/s (0 is max) - @param write Write speed in k/s (0 is max) -*/ -void burn_drive_set_speed(struct burn_drive *d, int read, int write); - -/* these are for my debugging, they will disappear */ -void burn_structure_print_disc(struct burn_disc *d); -void burn_structure_print_session(struct burn_session *s); -void burn_structure_print_track(struct burn_track *t); - -/** Sets the write type for the write_opts struct - @param opts The write opts to change - @param write_type The write type to use - @param block_type The block type to use - @return Returns 1 on success and 0 on failure. -*/ -int burn_write_opts_set_write_type(struct burn_write_opts *opts, - enum burn_write_types write_type, - int block_type); - -/** Supplies toc entries for writing - not normally required for cd mastering - @param opts The write opts to change - @param count The number of entries - @param toc_entries -*/ -void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, - int count, - struct burn_toc_entry *toc_entries); - -/** Sets the session format for a disc - @param opts The write opts to change - @param format The session format to set -*/ -void burn_write_opts_set_format(struct burn_write_opts *opts, int format); - -/** Sets the simulate value for the write_opts struct - @param opts The write opts to change - @param sim If non-zero, the drive will perform a simulation instead of a burn - @return Returns 1 on success and 0 on failure. -*/ -int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim); - -/** Controls buffer underrun prevention - @param opts The write opts to change - @param underrun_proof if non-zero, buffer underrun protection is enabled - @return Returns 1 on success and 0 on failure. -*/ -int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts, - int underrun_proof); - -/** Sets whether to use opc or not with the write_opts struct - @param opts The write opts to change - @param opc If non-zero, optical power calibration will be performed at - start of burn - -*/ -void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc); - -void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, int has_mediacatalog); - -void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned char mediacatalog[13]); - - -/* ts A61106 */ -/* Sets the multi flag which eventually marks the emerging session as not being - the last one and thus creating a BURN_DISC_APPENDABLE media. - @param multi 1=media will be appendable, 0=media will be closed (default) -*/ -void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi); - - -/** Sets whether to read in raw mode or not - @param opts The read opts to change - @param raw_mode If non-zero, reading will be done in raw mode, so that everything in the data tracks on the - disc is read, including headers. -*/ -void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw_mode); - -/** Sets whether to report c2 errors or not - @param opts The read opts to change - @param c2errors If non-zero, report c2 errors. -*/ -void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors); - -/** Sets whether to read subcodes from audio tracks or not - @param opts The read opts to change - @param subcodes_audio If non-zero, read subcodes from audio tracks on the disc. -*/ -void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts, - int subcodes_audio); - -/** Sets whether to read subcodes from data tracks or not - @param opts The read opts to change - @param subcodes_data If non-zero, read subcodes from data tracks on the disc. -*/ -void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts, - int subcodes_data); - -/** Sets whether to recover errors if possible - @param opts The read opts to change - @param hardware_error_recovery If non-zero, attempt to recover errors if possible. -*/ -void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts, - int hardware_error_recovery); - -/** Sets whether to report recovered errors or not - @param opts The read opts to change - @param report_recovered_errors If non-zero, recovered errors will be reported. -*/ -void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts, - int report_recovered_errors); - -/** Sets whether blocks with unrecoverable errors should be read or not - @param opts The read opts to change - @param transfer_damaged_blocks If non-zero, blocks with unrecoverable errors will still be read. -*/ -void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts, - int transfer_damaged_blocks); - -/** Sets the number of retries to attempt when trying to correct an error - @param opts The read opts to change - @param hardware_error_retries The number of retries to attempt when correcting an error. -*/ -void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts, - unsigned char hardware_error_retries); - -/** Gets the maximum write speed for a drive - @param d Drive to query - @return Maximum write speed in K/s -*/ -int burn_drive_get_write_speed(struct burn_drive *d); - - -/* ts A61021 */ -/** Gets the minimum write speed for a drive. This might differ from - burn_drive_get_write_speed() only after burn_disc_read_atip() - @param d Drive to query - @return Minimum write speed in K/s -*/ -int burn_drive_get_min_write_speed(struct burn_drive *d); - - -/** Gets the maximum read speed for a drive - @param d Drive to query - @return Maximum read speed in K/s -*/ -int burn_drive_get_read_speed(struct burn_drive *d); - -/** Gets a copy of the toc_entry structure associated with a track - @param t Track to get the entry from - @param entry Struct for the library to fill out -*/ -void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry); - -/** Gets a copy of the toc_entry structure associated with a session's lead out - @param s Session to get the entry from - @param entry Struct for the library to fill out -*/ -void burn_session_get_leadout_entry(struct burn_session *s, - struct burn_toc_entry *entry); - -/** Gets an array of all the sessions for the disc - THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A SESSION - @param d Disc to get session array for - @param num Returns the number of sessions in the array - @return array of sessions -*/ -struct burn_session **burn_disc_get_sessions(struct burn_disc *d, - int *num); - -int burn_disc_get_sectors(struct burn_disc *d); - -/** Gets an array of all the tracks for a session - THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A TRACK - @param s session to get track array for - @param num Returns the number of tracks in the array - @return array of tracks -*/ -struct burn_track **burn_session_get_tracks(struct burn_session *s, - int *num); - -int burn_session_get_sectors(struct burn_session *s); - -/** Gets the mode of a track - @param track the track to query - @return the track's mode -*/ -int burn_track_get_mode(struct burn_track *track); - -/** Returns whether the first track of a session is hidden in the pregap - @param session the session to query - @return non-zero means the first track is hidden -*/ -int burn_session_get_hidefirst(struct burn_session *session); - -/** Returns the library's version in its parts - @param major The major version number - @param minor The minor version number - @param micro The micro version number -*/ -void burn_version(int *major, int *minor, int *micro); - - -/* ts A60924 : ticket 74 */ -/** Control queueing and stderr printing of messages from libburn. - Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - "NOTE", "UPDATE", "DEBUG", "ALL". - @param queue_severity Gives the minimum limit for messages to be queued. - Default: "NEVER". If you queue messages then you - must consume them by burn_msgs_obtain(). - @param print_severity Does the same for messages to be printed directly - to stderr. Default: "FATAL". - @param print_id A text prefix to be printed before the message. - @return >0 for success, <=0 for error - -*/ -int burn_msgs_set_severities(char *queue_severity, - char *print_severity, char *print_id); - -/* ts A60924 : ticket 74 */ -#define BURN_MSGS_MESSAGE_LEN 4096 - -/** Obtain the oldest pending libburn message from the queue which has at - least the given minimum_severity. This message and any older message of - lower severity will get discarded from the queue and is then lost forever. - Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", - "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" - will discard the whole queue. - @param error_code Will become a unique error code as liste in - libburn/libdax_msgs.h - @param msg_text Must provide at least BURN_MSGS_MESSAGE_LEN bytes. - @param os_errno Will become the eventual errno related to the message - @param severity Will become the severity related to the message and - should provide at least 80 bytes. - @return 1 if a matching item was found, 0 if not, <0 for severe errors -*/ -int burn_msgs_obtain(char *minimum_severity, - int *error_code, char msg_text[], int *os_errno, - char severity[]); - - -/* ts A61002 */ -/* The prototype of a handler function suitable for burn_set_abort_handling(). - Such a function has to return -2 if it does not want the process to - exit with value 1. -*/ -typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag); - -/** Control builtin signal handling. See also burn_abort(). - @param handle Opaque handle eventually pointing to an application - provided memory object - @param handler A function to be called on signals. It will get handle as - argument. It should finally call burn_abort(). See there. - @param mode : 0 call handler(handle, signum, 0) on nearly all signals - 1 enable system default reaction on all signals - 2 try to ignore nearly all signals - 10 like mode 2 but handle SIGABRT like with mode 0 - Arguments (text, NULL, 0) activate the builtin abort handler. It will - eventually call burn_abort() and then perform exit(1). If text is not NULL - then it is used as prefix for pacifier messages of burn_abort_pacifier(). -*/ -void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, - int mode); - -#ifndef DOXYGEN - -BURN_END_DECLS - -#endif - -#endif /*LIBBURN_H*/ diff --git a/libburn/libdax_audioxtr.c b/libburn/libdax_audioxtr.c deleted file mode 100644 index 5f9037d..0000000 --- a/libburn/libdax_audioxtr.c +++ /dev/null @@ -1,326 +0,0 @@ - -/* libdax_audioxtr - Audio track data extraction facility of libdax and libburn. - Copyright (C) 2006 Thomas Schmitt , provided under GPL -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - - -/* Only this single source module is entitled to do this */ -#define LIBDAX_AUDIOXTR_H_INTERNAL 1 - -/* All clients of the extraction facility must do this */ -#include "libdax_audioxtr.h" - - -int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag) -{ - int ret= -1; - struct libdax_audioxtr *o; - - o= *xtr= (struct libdax_audioxtr *) malloc(sizeof(struct libdax_audioxtr)); - if(o==NULL) - return(-1); - strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1); - o->path[LIBDAX_AUDIOXTR_STRLEN]= 0; - o->fd= -1; - strcpy(o->fmt,"unidentified"); - o->fmt_info[0]= 0; - o->data_size= 0; - o->extract_count= 0; - - o->num_channels= 0; - o->sample_rate= 0; - o->bits_per_sample= 0; - o->msb_first= 0; - - o->wav_subchunk2_size= 0; - - o->au_data_location= 0; - o->au_data_size= 0xffffffff; - - ret= libdax_audioxtr_open(o,0); - if(ret<=0) - {ret= -2*(ret<0); goto failure;} - - return(1); -failure: - libdax_audioxtr_destroy(xtr,0); - return(ret); -} - - -int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag) -{ - struct libdax_audioxtr *o; - - o= *xtr; - if(o==NULL) - return(0); - if(o->fd>=0 && strcmp(o->path,"-")!=0) - close(o->fd); - free((char *) o); - *xtr= NULL; - return(1); -} - - -static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag) -{ - int ret; - char msg[LIBDAX_AUDIOXTR_STRLEN+80]; - - if(strcmp(o->path,"-")==0) - o->fd= 0; - else - o->fd= open(o->path, O_RDONLY); - if(o->fd<0) { - sprintf(msg,"Cannot open audio source file : %s",o->path); - libdax_msgs_submit(libdax_messenger,-1,0x00020200, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - msg, errno, 0); - return(-1); - } - ret= libdax_audioxtr_identify(o,0); - if(ret<=0) { - sprintf(msg,"Audio source file has unsuitable format : %s",o->path); - libdax_msgs_submit(libdax_messenger,-1,0x00020201, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); - return(0); - } - ret= libdax_audioxtr_init_reading(o,0); - if(ret<=0) { - sprintf(msg,"Failed to prepare reading of audio data : %s",o->path); - libdax_msgs_submit(libdax_messenger,-1,0x00020202, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); - return(0); - } - return(1); -} - - -static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag) -{ - int ret; - char buf[45]; - - /* check wether this is a MS WAVE file .wav */ - /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ - - if(o->fd!=0) { - ret= lseek(o->fd,0,SEEK_SET); - if(ret==-1) - return(0); - } - ret= read(o->fd, buf, 44); - if(ret<44) - return(0); - buf[44]= 0; /* as stopper for any string operations */ - - if(strncmp(buf,"RIFF",4)!=0) /* ChunkID */ - return(0); - if(strncmp(buf+8,"WAVE",4)!=0) /* Format */ - return(0); - if(strncmp(buf+12,"fmt ",4)!=0) /* Subchunk1ID */ - return(0); - if(buf[16]!=16 || buf[17]!=0 || buf[18]!=0 || buf[19]!=0) /* Subchunk1Size */ - return(0); - if(buf[20]!=1 || buf[21]!=0) /* AudioFormat must be 1 (Linear quantization) */ - return(0); - - strcpy(o->fmt,".wav"); - o->msb_first= 0; - o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0); - o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0); - o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0); - sprintf(o->fmt_info, - ".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d", - o->num_channels,o->sample_rate,o->bits_per_sample); - o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0); - o->data_size= o->wav_subchunk2_size; - return(1); -} - - -static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag) -{ - int ret,encoding; - char buf[24]; - - /* Check wether this is a Sun Audio, .au file */ - /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ - - if(o->fd!=0) { - ret= lseek(o->fd,0,SEEK_SET); - if(ret==-1) - return(0); - } - ret= read(o->fd, buf, 24); - if(ret<24) - return(0); - - if(strncmp(buf,".snd",4)!=0) - return(0); - strcpy(o->fmt,".au"); - o->msb_first= 1; - o->au_data_location= libdax_audioxtr_to_int(o,(unsigned char *)buf+4,4,1); - o->au_data_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+8,4,1); - encoding= libdax_audioxtr_to_int(o,(unsigned char *)buf+12,4,1); - if(encoding==2) - o->bits_per_sample= 8; - else if(encoding==3) - o->bits_per_sample= 16; - else if(encoding==4) - o->bits_per_sample= 24; - else if(encoding==5) - o->bits_per_sample= 32; - else - o->bits_per_sample= -encoding; - o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *)buf+16,4,1); - o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *)buf+20,4,1); - if(o->au_data_size!=0xffffffff) - o->data_size= o->au_data_size; - else - o->data_size= 0; - sprintf(o->fmt_info, - ".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d", - o->num_channels,o->sample_rate,o->bits_per_sample); - - /* <<< for testing only */; - return(1); - - return(o->bits_per_sample>0); /* Audio format must be linear PCM */ -} - - -static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag) -{ - int ret; - - ret= libdax_audioxtr_identify_wav(o, 0); - if(ret!=0) - return(ret); - if(o->fd==0) /* cannot rewind stdin */ - return(0); - ret= libdax_audioxtr_identify_au(o, 0); - if(ret!=0) - return(ret); - return(0); -} - - -/* @param flag bit0=msb_first */ -static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o, - unsigned char *bytes, int len, int flag) -{ - unsigned int ret= 0; - int i; - - if(flag&1) - for(i= 0; i=0; i--) - ret= ret*256+bytes[i]; - return(ret); -} - - -static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag) -{ - int ret; - - - /* currently this only works for MS WAVE files .wav and Sun .au*/; - if(o->fd==0) /* stdin: hope no read came after libdax_audioxtr_identify() */ - return(1); - - o->extract_count= 0; - if(strcmp(o->fmt,".wav")==0) - ret= lseek(o->fd,44,SEEK_SET); - else if(strcmp(o->fmt,".au")==0) - ret= lseek(o->fd,o->au_data_location,SEEK_SET); - else - ret= -1; - if(ret==-1) - return(0); - - return(1); -} - - -int libdax_audioxtr_get_id(struct libdax_audioxtr *o, - char **fmt, char **fmt_info, - int *num_channels, int *sample_rate, int *bits_per_sample, - int *msb_first, int flag) -{ - *fmt= o->fmt; - *fmt_info= o->fmt_info; - *num_channels= o->num_channels; - *sample_rate= o->sample_rate; - *bits_per_sample= o->bits_per_sample; - *msb_first= o->msb_first; - return(1); -} - - -int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag) -{ - *size= o->data_size; - return(1); -} - - -int libdax_audioxtr_read(struct libdax_audioxtr *o, - char buffer[], int buffer_size, int flag) -{ - int ret; - - if(buffer_size<=0 || o->fd<0) - return(-2); - if(o->data_size>0 && !(flag&1)) - if(buffer_size > o->data_size - o->extract_count) - buffer_size= o->data_size - o->extract_count; - if(buffer_size<=0) - return(0); - ret= read(o->fd,buffer,buffer_size); - if(ret>0) - o->extract_count+= ret; - return(ret); -} - - -int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag) -{ - if(o->fd<0) - return(-1); - if(strcmp(o->fmt,".wav")!=0 && strcmp(o->fmt,".au")!=0) - return(0); - if(flag&1) { - *fd= o->fd; - } else { - *fd= dup(o->fd); - if(*fd>=0 && strcmp(o->path,"-")!=0) - close(o->fd); - } - if(*fd>=0) { - o->fd= -1; - return(1); - } - return(-1); -} - diff --git a/libburn/libdax_audioxtr.h b/libburn/libdax_audioxtr.h deleted file mode 100644 index 72b62bf..0000000 --- a/libburn/libdax_audioxtr.h +++ /dev/null @@ -1,229 +0,0 @@ - -/* libdax_audioxtr - Audio track data extraction facility of libdax and libburn. - Copyright (C) 2006 Thomas Schmitt , provided under GPL -*/ - -#ifndef LIBDAX_AUDIOXTR_H_INCLUDED -#define LIBDAX_AUDIOXTR_H_INCLUDED 1 - - /* Public Macros */ - -/* Maximum size for address paths and fmt_info strings */ -#define LIBDAX_AUDIOXTR_STRLEN 4096 - - - /* Public Opaque Handles */ - -/** Extractor object encapsulating intermediate states of extraction. - The clients of libdax_audioxtr shall only allocate pointers to this - struct and get a storage object via libdax_audioxtr_new(). - Appropriate initial value for the pointer is NULL. -*/ -struct libdax_audioxtr; - - - /* Public Functions */ - - /* Calls initiated from inside libdax/libburn */ - - - /* Calls from applications (to be forwarded by libdax/libburn) */ - - -/** Open an audio file, check wether suitable, create extractor object. - @param xtr Opaque handle to extractor. Gets attached extractor object. - @param path Address of the audio file to extract. "-" is stdin (but might - be not suitable for all futurely supported formats). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success - 0 unsuitable format - -1 severe error - -2 path not found -*/ -int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag); - - -/** Obtain identification parameters of opened audio source. - @param xtr Opaque handle to extractor - @param fmt Gets pointed to the audio file format id text: ".wav" , ".au" - @param fmt_info Gets pointed to a format info text telling parameters - @param num_channels e.g. 1=mono, 2=stereo, etc - @param sample_rate e.g. 11025, 44100 - @param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ... - @param msb_first Byte order of samples: 0=Intel 1=Motorola - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr, - char **fmt, char **fmt_info, - int *num_channels, int *sample_rate, - int *bits_per_sample, int *msb_first, int flag); - - -/** Obtain a prediction about the extracted size based on internal information - of the formatted file. - @param xtr Opaque handle to extractor - @param size Gets filled with the predicted size - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 prediction was possible , 0 no prediction could be made -*/ -int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag); - - -/** Obtain next buffer full of extracted data in desired format (only raw audio - for now). - @param xtr Opaque handle to extractor - @param buffer Gets filled with extracted data - @param buffer_size Maximum number of bytes to be filled into buffer - @param flag Bitfield for control purposes - bit0= do not stop at predicted end of data - @return >0 number of valid buffer bytes, - 0 End of file - -1 operating system reports error - -2 usage error by application -*/ -int libdax_audioxtr_read(struct libdax_audioxtr *xtr, - char buffer[], int buffer_size, int flag); - - -/** Try to obtain a file descriptor which will deliver extracted data - to normal calls of read(2). This may fail because the format is - unsuitable for that, but ".wav" is ok. If this call succeeds the xtr - object will have forgotten its file descriptor and libdax_audioxtr_read() - will return a usage error. One may use *fd after libdax_audioxtr_destroy() - and will have to close it via close(2) when done with it. - @param xtr Opaque handle to extractor - @param fd Eventually returns the file descriptor number - @param flag Bitfield for control purposes - bit0= do not dup(2) and close(2) but hand out original fd - @return 1 success, 0 cannot hand out fd , -1 severe error -*/ -int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag); - - -/** Clean up after extraction and destroy extractor object. - @param xtr Opaque handle to extractor, *xtr is allowed to be NULL, - *xtr is set to NULL by this function - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 = destroyed object, 0 = was already destroyed -*/ -int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag); - - - -#ifdef LIDBAX_AUDIOXTR________________ - - --- place documentation text here --- - - -#endif /* LIDBAX_AUDIOXTR_________________ */ - - - -/* - *Never* set this macro outside libdax_audioxtr.c ! - The entrails of this facility are not to be seen by - the other library components or the applications. -*/ -#ifdef LIBDAX_AUDIOXTR_H_INTERNAL - - /* Internal Structures */ - -/** Extractor object encapsulating intermediate states of extraction */ -struct libdax_audioxtr { - - /* Source of the encoded audio data */ - char path[LIBDAX_AUDIOXTR_STRLEN]; - - /* File descriptor to path. Anything else than 0 must be lseek-able */ - int fd; - - /* Format identifier. E.g. ".wav" */ - char fmt[80]; - - /* Format parameter info text */ - char fmt_info[LIBDAX_AUDIOXTR_STRLEN]; - - /* 1= mono, 2= stereo, etc. */ - int num_channels; - - /* 8000, 44100, etc. */ - int sample_rate; - - /* 8 bits = 8, 16 bits = 16, etc. */ - int bits_per_sample; - - /* Byte order of samples: 0=Intel 1=Motorola */ - int msb_first; - - /* Number of bytes to extract (0= unknown/unlimited) */ - off_t data_size; - - /* Number of extracted data bytes */ - off_t extract_count; - - - /* Format dependent parameters */ - - /* MS WAVE Format */ - /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ - - /* == NumSamples * NumChannels * BitsPerSample/8 - This is the number of bytes in the data. */ - unsigned wav_subchunk2_size; - - - /* Sun Audio, .au */ - /* info used: http://www.opengroup.org/public/pubs/external/auformat.html */ - - /* Number of bytes in non-payload header part */ - unsigned au_data_location; - - /* Number of payload bytes or 0xffffffff */ - unsigned au_data_size; - -}; - - - /* Internal Functions */ - -/** Open the audio source pointed to by .path and evaluate suitability. - @return -1 failure to open, 0 unsuitable format, 1 success -*/ -static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag); - - -/** Identify format and evaluate suitability. - @return 0 unsuitable format, 1 format is suitable -*/ -static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag); - -/** Specialized identifier for .wav */ -static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag); -/** Specialized identifier for .au */ -static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag); - - -/** Convert a byte string into a number (currently only little endian) - @param flag Bitfield for control purposes - bit0=msb_first - @return The resulting number -*/ -static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o, - unsigned char *bytes, int len, int flag); - - -/** Prepare for reading of first buffer. - @return 0 error, 1 success -*/ -static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag); - - - -#endif /* LIBDAX_AUDIOXTR_H_INTERNAL */ - - -#endif /* ! LIBDAX_AUDIOXTR_H_INCLUDED */ - diff --git a/libburn/libdax_msgs.c b/libburn/libdax_msgs.c deleted file mode 100644 index 5f179ae..0000000 --- a/libburn/libdax_msgs.c +++ /dev/null @@ -1,404 +0,0 @@ - -/* libdax_msgs - Message handling facility of libdax. - Copyright (C) 2006 Thomas Schmitt , provided under GPL -*/ - -#include -#include -#include -#include -#include -#include -#include - -/* Only this single source module is entitled to do this */ -#define LIBDAX_MSGS_H_INTERNAL 1 - -/* All participants in the messaging system must do this */ -#include "libdax_msgs.h" - - -/* ----------------------------- libdax_msgs_item ------------------------- */ - - -static int libdax_msgs_item_new(struct libdax_msgs_item **item, - struct libdax_msgs_item *link, int flag) -{ - int ret; - struct libdax_msgs_item *o; - struct timeval tv; - struct timezone tz; - - (*item)= o= - (struct libdax_msgs_item *) malloc(sizeof(struct libdax_msgs_item)); - if(o==NULL) - return(-1); - o->timestamp= 0.0; - ret= gettimeofday(&tv,&tz); - if(ret==0) - o->timestamp= tv.tv_sec+0.000001*tv.tv_usec; - o->process_id= getpid(); - o->driveno= -1; - o->severity= LIBDAX_MSGS_SEV_ALL; - o->priority= LIBDAX_MSGS_PRIO_ZERO; - o->error_code= 0; - o->msg_text= NULL; - o->os_errno= 0; - o->prev= link; - o->next= NULL; - if(link!=NULL) { - if(link->next!=NULL) { - link->next->prev= o; - o->next= link->next; - } - link->next= o; - } - return(1); -} - - -/** Detaches item from its queue and eventually readjusts start, end pointers - of the queue */ -int libdax_msgs_item_unlink(struct libdax_msgs_item *o, - struct libdax_msgs_item **chain_start, - struct libdax_msgs_item **chain_end, int flag) -{ - if(o->prev!=NULL) - o->prev->next= o->next; - if(o->next!=NULL) - o->next->prev= o->prev; - if(chain_start!=NULL) - if(*chain_start == o) - *chain_start= o->next; - if(chain_end!=NULL) - if(*chain_end == o) - *chain_end= o->prev; - o->next= o->prev= NULL; - return(1); -} - - -int libdax_msgs_item_destroy(struct libdax_msgs_item **item, - int flag) -{ - struct libdax_msgs_item *o; - - o= *item; - if(o==NULL) - return(0); - libdax_msgs_item_unlink(o,NULL,NULL,0); - if(o->msg_text!=NULL) - free((char *) o->msg_text); - free((char *) o); - *item= NULL; - return(1); -} - - -int libdax_msgs_item_get_msg(struct libdax_msgs_item *item, - int *error_code, char **msg_text, int *os_errno, - int flag) -{ - *error_code= item->error_code; - *msg_text= item->msg_text; - *os_errno= item->os_errno; - return(1); -} - - -int libdax_msgs_item_get_origin(struct libdax_msgs_item *item, - double *timestamp, pid_t *process_id, int *driveno, - int flag) -{ - *timestamp= item->timestamp; - *process_id= item->process_id; - *driveno= item->driveno; - return(1); -} - - -int libdax_msgs_item_get_rank(struct libdax_msgs_item *item, - int *severity, int *priority, int flag) -{ - *severity= item->severity; - *priority= item->priority; - return(1); -} - - -/* ------------------------------- libdax_msgs ---------------------------- */ - - -int libdax_msgs_new(struct libdax_msgs **m, int flag) -{ - struct libdax_msgs *o; - - (*m)= o= (struct libdax_msgs *) malloc(sizeof(struct libdax_msgs)); - if(o==NULL) - return(-1); - o->oldest= NULL; - o->youngest= NULL; - o->count= 0; - o->queue_severity= LIBDAX_MSGS_SEV_ALL; - o->print_severity= LIBDAX_MSGS_SEV_NEVER; - strcpy(o->print_id,"libdax: "); - -#ifndef LIBDAX_MSGS_SINGLE_THREADED - pthread_mutex_init(&(o->lock_mutex),NULL); -#endif - - return(1); -} - - -int libdax_msgs_destroy(struct libdax_msgs **m, int flag) -{ - struct libdax_msgs *o; - struct libdax_msgs_item *item, *next_item; - - o= *m; - if(o==NULL) - return(0); - -#ifndef LIBDAX_MSGS_SINGLE_THREADED - if(pthread_mutex_destroy(&(o->lock_mutex))!=0) { - pthread_mutex_unlock(&(o->lock_mutex)); - pthread_mutex_destroy(&(o->lock_mutex)); - } -#endif - - for(item= o->oldest; item!=NULL; item= next_item) { - next_item= item->next; - libdax_msgs_item_destroy(&item,0); - } - free((char *) o); - *m= NULL; - return(1); -} - - -int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity, - int print_severity, char *print_id, int flag) -{ - m->queue_severity= queue_severity; - m->print_severity= print_severity; - strncpy(m->print_id,print_id,80); - m->print_id[80]= 0; - return(1); -} - - -static int libdax_msgs_lock(struct libdax_msgs *m, int flag) -{ - -#ifndef LIBDAX_MSGS_SINGLE_THREADED - int ret; - - ret= pthread_mutex_lock(&(m->lock_mutex)); - if(ret!=0) - return(0); -#endif - - return(1); -} - - -static int libdax_msgs_unlock(struct libdax_msgs *m, int flag) -{ - -#ifndef LIBDAX_MSGS_SINGLE_THREADED - int ret; - - ret= pthread_mutex_unlock(&(m->lock_mutex)); - if(ret!=0) - return(0); -#endif - - return(1); -} - - -int libdax_msgs__text_to_sev(char *severity_name, int *severity, - int flag) -{ - if(strncmp(severity_name,"NEVER",5)==0) - *severity= LIBDAX_MSGS_SEV_NEVER; - else if(strncmp(severity_name,"ABORT",5)==0) - *severity= LIBDAX_MSGS_SEV_ABORT; - else if(strncmp(severity_name,"FATAL",5)==0) - *severity= LIBDAX_MSGS_SEV_FATAL; - else if(strncmp(severity_name,"SORRY",5)==0) - *severity= LIBDAX_MSGS_SEV_SORRY; - else if(strncmp(severity_name,"WARNING",7)==0) - *severity= LIBDAX_MSGS_SEV_WARNING; - else if(strncmp(severity_name,"HINT",4)==0) - *severity= LIBDAX_MSGS_SEV_HINT; - else if(strncmp(severity_name,"NOTE",4)==0) - *severity= LIBDAX_MSGS_SEV_NOTE; - else if(strncmp(severity_name,"UPDATE",6)==0) - *severity= LIBDAX_MSGS_SEV_UPDATE; - else if(strncmp(severity_name,"DEBUG",5)==0) - *severity= LIBDAX_MSGS_SEV_DEBUG; - else if(strncmp(severity_name,"ALL",3)==0) - *severity= LIBDAX_MSGS_SEV_ALL; - else { - *severity= LIBDAX_MSGS_SEV_NEVER; - return(0); - } - return(1); -} - - -int libdax_msgs__sev_to_text(int severity, char **severity_name, - int flag) -{ - if(flag&1) { - *severity_name= - "NEVER\nABORT\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL"; - return(1); - } - *severity_name= ""; - if(severity>=LIBDAX_MSGS_SEV_NEVER) - *severity_name= "NEVER"; - else if(severity>=LIBDAX_MSGS_SEV_ABORT) - *severity_name= "ABORT"; - else if(severity>=LIBDAX_MSGS_SEV_FATAL) - *severity_name= "FATAL"; - else if(severity>=LIBDAX_MSGS_SEV_SORRY) - *severity_name= "SORRY"; - else if(severity>=LIBDAX_MSGS_SEV_WARNING) - *severity_name= "WARNING"; - else if(severity>=LIBDAX_MSGS_SEV_HINT) - *severity_name= "HINT"; - else if(severity>=LIBDAX_MSGS_SEV_NOTE) - *severity_name= "NOTE"; - else if(severity>=LIBDAX_MSGS_SEV_UPDATE) - *severity_name= "UPDATE"; - else if(severity>=LIBDAX_MSGS_SEV_DEBUG) - *severity_name= "DEBUG"; - else if(severity>=LIBDAX_MSGS_SEV_ALL) - *severity_name= "ALL"; - else { - *severity_name= ""; - return(0); - } - return(1); -} - - -int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code, - int severity, int priority, char *msg_text, - int os_errno, int flag) -{ - int ret; - char *textpt,*sev_name,sev_text[81]; - struct libdax_msgs_item *item= NULL; - - if(severity >= m->print_severity) { - if(msg_text==NULL) - textpt= ""; - else - textpt= msg_text; - sev_text[0]= 0; - ret= libdax_msgs__sev_to_text(severity,&sev_name,0); - if(ret>0) - sprintf(sev_text,"%s : ",sev_name); - - fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt); - if(os_errno!=0) { - ret= libdax_msgs_lock(m,0); - if(ret<=0) - return(-1); - fprintf(stderr,"%s( Most recent system error: %d '%s' )\n", - m->print_id,os_errno,strerror(os_errno)); - libdax_msgs_unlock(m,0); - } - - } - if(severity < m->queue_severity) - return(0); - - ret= libdax_msgs_lock(m,0); - if(ret<=0) - return(-1); - ret= libdax_msgs_item_new(&item,m->youngest,0); - if(ret<=0) - goto failed; - item->driveno= driveno; - item->error_code= error_code; - item->severity= severity; - item->priority= priority; - if(msg_text!=NULL) { - item->msg_text= malloc(strlen(msg_text)+1); - if(item->msg_text==NULL) - goto failed; - strcpy(item->msg_text,msg_text); - } - item->os_errno= os_errno; - if(m->oldest==NULL) - m->oldest= item; - m->youngest= item; - m->count++; - libdax_msgs_unlock(m,0); - -/* -fprintf(stderr,"libdax_experimental: message submitted to queue (now %d)\n", - m->count); -*/ - - return(1); -failed:; - libdax_msgs_item_destroy(&item,0); - libdax_msgs_unlock(m,0); - return(-1); -} - - -int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item, - int severity, int priority, int flag) -{ - int ret; - struct libdax_msgs_item *im, *next_im= NULL; - - *item= NULL; - ret= libdax_msgs_lock(m,0); - if(ret<=0) - return(-1); - for(im= m->oldest; im!=NULL; im= next_im) { - for(; im!=NULL; im= next_im) { - next_im= im->next; - if(im->severity>=severity) - break; - libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); - libdax_msgs_item_destroy(&im,0); /* severity too low: delete */ - } - if(im==NULL) - break; - if(im->priority>=priority) - break; - } - if(im==NULL) - {ret= 0; goto ex;} - libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); - *item= im; - ret= 1; -ex:; - libdax_msgs_unlock(m,0); - return(ret); -} - - -int libdax_msgs_destroy_item(struct libdax_msgs *m, - struct libdax_msgs_item **item, int flag) -{ - int ret; - - ret= libdax_msgs_lock(m,0); - if(ret<=0) - return(-1); - ret= libdax_msgs_item_destroy(item,0); - libdax_msgs_unlock(m,0); - return(ret); -} - diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h deleted file mode 100644 index a4c2296..0000000 --- a/libburn/libdax_msgs.h +++ /dev/null @@ -1,382 +0,0 @@ - -/* libdax_msgs - Message handling facility of libdax. - Copyright (C) 2006 Thomas Schmitt , provided under GPL -*/ - - -/* - *Never* set this macro outside libdax_msgs.c ! - The entrails of the message handling facility are not to be seen by - the other library components or the applications. -*/ -#ifdef LIBDAX_MSGS_H_INTERNAL - - -#ifndef LIBDAX_MSGS_SINGLE_THREADED -#include -#endif - - -struct libdax_msgs_item { - - double timestamp; - pid_t process_id; - int driveno; - - int severity; - int priority; - - /* Apply for your developer's error code range at - libburn-hackers@pykix.org - Report introduced codes in the list below. */ - int error_code; - - char *msg_text; - int os_errno; - - struct libdax_msgs_item *prev,*next; - -}; - - -struct libdax_msgs { - - struct libdax_msgs_item *oldest; - struct libdax_msgs_item *youngest; - int count; - - int queue_severity; - int print_severity; - char print_id[81]; - -#ifndef LIBDAX_MSGS_SINGLE_THREADED - pthread_mutex_t lock_mutex; -#endif - - -}; - -#endif /* LIBDAX_MSGS_H_INTERNAL */ - - -#ifndef LIBDAX_MSGS_H_INCLUDED -#define LIBDAX_MSGS_H_INCLUDED 1 - - -#ifndef LIBDAX_MSGS_H_INTERNAL - - - /* Public Opaque Handles */ - -/** A pointer to this is a opaque handle to a message handling facility */ -struct libdax_msgs; - -/** A pointer to this is a opaque handle to a single message item */ -struct libdax_msgs_item; - -#endif /* ! LIBDAX_MSGS_H_INTERNAL */ - - - /* Public Macros */ - - -/* Registered Severities */ - -/* It is well advisable to let applications select severities via strings and - forwarded functions libdax_msgs__text_to_sev(), libdax_msgs__sev_to_text(). - These macros are for use by libdax/libburn only. -*/ - -/** Use this to get messages of any severity. Do not use for submitting. -*/ -#define LIBDAX_MSGS_SEV_ALL 0x00000000 - -/** Debugging messages not to be visible to normal users by default -*/ -#define LIBDAX_MSGS_SEV_DEBUG 0x10000000 - -/** Update of a progress report about long running actions -*/ -#define LIBDAX_MSGS_SEV_UPDATE 0x20000000 - -/** Not so usual events which were gracefully handled -*/ -#define LIBDAX_MSGS_SEV_NOTE 0x30000000 - -/** Possibilities to achieve a better result -*/ -#define LIBDAX_MSGS_SEV_HINT 0x40000000 - -/** Warnings about problems which could not be handled optimally -*/ -#define LIBDAX_MSGS_SEV_WARNING 0x50000000 - -/** Non-fatal error messages indicating that parts of the action failed - but processing will/should go on -*/ -#define LIBDAX_MSGS_SEV_SORRY 0x60000000 - -/** An error message which puts the whole operation of libdax in question -*/ -#define LIBDAX_MSGS_SEV_FATAL 0x70000000 - -/** A message from an abort handler which will finally finish libburn -*/ -#define LIBDAX_MSGS_SEV_ABORT 0x71000000 - -/** A severity to exclude resp. discard any possible message. - Do not use this severity for submitting. -*/ -#define LIBDAX_MSGS_SEV_NEVER 0x7fffffff - - -/* Registered Priorities */ - -/* Priorities are to be used by libburn/libdax only. */ - -#define LIBDAX_MSGS_PRIO_ZERO 0x00000000 -#define LIBDAX_MSGS_PRIO_LOW 0x10000000 -#define LIBDAX_MSGS_PRIO_MEDIUM 0x20000000 -#define LIBDAX_MSGS_PRIO_HIGH 0x30000000 -#define LIBDAX_MSGS_PRIO_TOP 0x7ffffffe - -/* Do not use this priority for submitting */ -#define LIBDAX_MSGS_PRIO_NEVER 0x7fffffff - - - /* Public Functions */ - - /* Calls initiated from inside libdax/libburn */ - - -/** Create new empty message handling facility with queue. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -int libdax_msgs_new(struct libdax_msgs **m, int flag); - - -/** Destroy a message handling facility and all its eventual messages. - The submitted pointer gets set to NULL. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for pointer to NULL -*/ -int libdax_msgs_destroy(struct libdax_msgs **m, int flag); - - -/** Submit a message to a message handling facility. - @param driveno libdax drive number. Use -1 if no number is known. - @param error_code Unique error code. Use only registered codes. See below. - The same unique error_code may be issued at different - occasions but those should be equivalent out of the view - of a libdax application. (E.g. "cannot open ATA drive" - versus "cannot open SCSI drive" would be equivalent.) - @param severity The LIBDAX_MSGS_SEV_* of the event. - @param priority The LIBDAX_MSGS_PRIO_* number of the event. - @param msg_text Printable and human readable message text. - @param os_errno Eventual error code from operating system (0 if none) - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on rejection, <0 for severe errors -*/ -int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code, - int severity, int priority, char *msg_text, - int os_errno, int flag); - - - /* Calls from applications (to be forwarded by libdax/libburn) */ - - -/** Convert a registered severity number into a severity name - @param flag Bitfield for control purposes: - bit0= list all severity names in a newline separated string - @return >0 success, <=0 failure -*/ -int libdax_msgs__sev_to_text(int severity, char **severity_name, - int flag); - - -/** Convert a severity name into a severity number, - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -int libdax_msgs__text_to_sev(char *severity_name, int *severity, - int flag); - - -/** Set minimum severity for messages to be queued (default - LIBDAX_MSGS_SEV_ALL) and for messages to be printed directly to stderr - (default LIBDAX_MSGS_SEV_NEVER). - @param print_id A text of at most 80 characters to be printed before - any eventually printed message (default is "libdax: "). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return always 1 for now -*/ -int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity, - int print_severity, char *print_id, int flag); - - -/** Obtain a message item that has at least the given severity and priority. - Usually all older messages of lower severity are discarded then. If no - item of sufficient severity was found, all others are discarded from the - queue. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 if a matching item was found, 0 if not, <0 for severe errors -*/ -int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item, - int severity, int priority, int flag); - - -/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted - pointer gets set to NULL. - Caution: Copy eventually obtained msg_text before destroying the item, - if you want to use it further. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for pointer to NULL, <0 for severe errors -*/ -int libdax_msgs_destroy_item(struct libdax_msgs *m, - struct libdax_msgs_item **item, int flag); - - -/** Obtain from a message item the three application oriented components as - submitted with the originating call of libdax_msgs_submit(). - Caution: msg_text becomes a pointer into item, not a copy. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on invalid item, <0 for servere errors -*/ -int libdax_msgs_item_get_msg(struct libdax_msgs_item *item, - int *error_code, char **msg_text, int *os_errno, - int flag); - - -/** Obtain from a message item the submitter identification submitted - with the originating call of libdax_msgs_submit(). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on invalid item, <0 for servere errors -*/ -int libdax_msgs_item_get_origin(struct libdax_msgs_item *item, - double *timestamp, pid_t *process_id, int *driveno, - int flag); - - -/** Obtain from a message item severity and priority as submitted - with the originating call of libdax_msgs_submit(). - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 on success, 0 on invalid item, <0 for servere errors -*/ -int libdax_msgs_item_get_rank(struct libdax_msgs_item *item, - int *severity, int *priority, int flag); - - -#ifdef LIDBAX_MSGS_________________ - - - /* Registered Error Codes */ - - -Format: error_code (LIBDAX_MSGS_SEV_*,LIBDAX_MSGS_PRIO_*) = explanation -If no severity or priority are fixely associates, use "(,)". - ------------------------------------------------------------------------------- -Range "libdax_msgs" : 0x00000000 to 0x0000ffff - - 0x00000000 (ALL,ZERO) = Initial setting in new libdax_msgs_item - 0x00000001 (DEBUG,ZERO) = Test error message - 0x00000002 (DEBUG,ZERO) = Debugging message - - ------------------------------------------------------------------------------- -Range "elmom" : 0x00010000 to 0x0001ffff - - - ------------------------------------------------------------------------------- -Range "scdbackup" : 0x00020000 to 0x0002ffff - - Acessing and defending drives: - - 0x00020001 (SORRY,LOW) = Cannot open busy device - 0x00020002 (SORRY,HIGH) = Encountered error when closing drive - 0x00020003 (SORRY,HIGH) = Could not grab drive - 0x00020004 (NOTE,HIGH) = Opened O_EXCL scsi sibling - 0x00020005 (FATAL,HIGH) = Failed to open device - 0x00020006 (FATAL,HIGH) = Too many scsi siblings - 0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings - - General library operations: - - 0x00020101 (WARNING,HIGH) = Cannot find given worker item - 0x00020102 (SORRY,HIGH) = A drive operation is still going on - 0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on - 0x00020104 (SORRY,HIGH) = NULL pointer caught - 0x00020105 (SORRY,HIGH) = Drive is already released - 0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close - 0x00020107 (SORRY,HIGH) = Drive is busy on attempt to shut down library - 0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry - 0x00020108 (FATAL,HIGH) = Could not allocate new drive object - 0x00020109 (FATAL,HIGH) = Library not running - 0x0002010a (FATAL,HIGH) = Unsuitable track mode - 0x0002010b (FATAL,HIGH) = Burn run failed - 0x0002010c (FATAL,HIGH) = Failed to transfer command to drive - 0x0002010d (DEBUG,HIGH) = Could not inquire TOC - 0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive - 0x0002010f (DEBUG,HIGH) = SCSI error condition on command - 0x00020110 (FATAL,HIGH) = Persistent drive address too long - 0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object - 0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type - 0x00020113 (FATAL,HIGH) = Drive capabilities not inquired yet - 0x00020114 (SORRY,HIGH) = Attempt to set ISRC with bad data - 0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value - 0x00020116 (FATAL,HIGH) = Track mode has unusable value - 0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use - 0x00020118 (DEBUG,HIGH) = Closing track - 0x00020119 (DEBUG,HIGH) = Closing session - 0x0002011a (NOTE,HIGH) = Padding up track to minimum size - 0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive - 0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive - 0x0002011d (FATAL,HIGH) = SCSI error condition on write - - libdax_audioxtr: - 0x00020200 (SORRY,HIGH) = Cannot open audio source file - 0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format - 0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data - - ------------------------------------------------------------------------------- - -#endif /* LIDBAX_MSGS_________________ */ - - - -#ifdef LIBDAX_MSGS_H_INTERNAL - - /* Internal Functions */ - - -/** Lock before doing side effect operations on m */ -static int libdax_msgs_lock(struct libdax_msgs *m, int flag); - -/** Unlock after effect operations on m are done */ -static int libdax_msgs_unlock(struct libdax_msgs *m, int flag); - - -/** Create new empty message item. - @param link Previous item in queue - @param flag Bitfield for control purposes (unused yet, submit 0) - @return >0 success, <=0 failure -*/ -static int libdax_msgs_item_new(struct libdax_msgs_item **item, - struct libdax_msgs_item *link, int flag); - -/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted - pointer gets set to NULL. - @param flag Bitfield for control purposes (unused yet, submit 0) - @return 1 for success, 0 for pointer to NULL -*/ -static int libdax_msgs_item_destroy(struct libdax_msgs_item **item, int flag); - - -#endif /* LIBDAX_MSGS_H_INTERNAL */ - - -#endif /* ! LIBDAX_MSGS_H_INCLUDED */ diff --git a/libburn/mmc.c b/libburn/mmc.c deleted file mode 100644 index a4f8392..0000000 --- a/libburn/mmc.c +++ /dev/null @@ -1,906 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* ts A61009 */ -/* #include */ - -#include -#include -#include -#include -#include -#include "error.h" -#include "sector.h" -#include "libburn.h" -#include "transport.h" -#include "mmc.h" -#include "spc.h" -#include "drive.h" -#include "debug.h" -#include "toc.h" -#include "structure.h" -#include "options.h" - - -#ifdef Libburn_log_in_and_out_streaM -/* <<< ts A61031 */ -#include -#include -#include -#endif /* Libburn_log_in_and_out_streaM */ - - -/* ts A61005 */ -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - - - -static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 }; -static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 }; -static unsigned char MMC_GET_DISC_INFO[] = - { 0x51, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; -static unsigned char MMC_READ_CD[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_ERASE[] = { 0xA1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_SEND_OPC[] = { 0x54, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_SET_SPEED[] = - { 0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_WRITE_12[] = - { 0xAA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_WRITE_10[] = { 0x2A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_GET_CONFIGURATION[] = - { 0x46, 0, 0, 0, 0, 0, 16, 0, 0 }; -static unsigned char MMC_SYNC_CACHE[] = { 0x35, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_GET_EVENT[] = { 0x4A, 1, 0, 0, 16, 0, 0, 0, 8, 0 }; -static unsigned char MMC_CLOSE[] = { 0x5B, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char MMC_TRACK_INFO[] = { 0x52, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; -static unsigned char MMC_SEND_CUE_SHEET[] = - { 0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* ts A61023 : get size and free space of drive buffer */ -static unsigned char MMC_READ_BUFFER_CAPACITY[] = { 0x5C, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; - - -static int mmc_function_spy_do_tell = 0; - -int mmc_function_spy(char * text) -{ - - if (mmc_function_spy_do_tell) - fprintf(stderr,"libburn: experimental: mmc_function_spy: %s\n", - text); - return 1; -} - -int mmc_function_spy_ctrl(int do_tell) -{ - mmc_function_spy_do_tell= !!do_tell; - return 1; -} - - -void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s) -{ - struct buffer buf; - struct command c; - - - mmc_function_spy("mmc_send_cue_sheet"); - c.retry = 1; - c.oplen = sizeof(MMC_SEND_CUE_SHEET); - memcpy(c.opcode, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET)); - c.page = &buf; - c.page->bytes = s->count * 8; - c.page->sectors = 0; - c.opcode[6] = (c.page->bytes >> 16) & 0xFF; - c.opcode[7] = (c.page->bytes >> 8) & 0xFF; - c.opcode[8] = c.page->bytes & 0xFF; - c.dir = TO_DRIVE; - memcpy(c.page->data, s->data, c.page->bytes); - d->issue_command(d, &c); -} - -/* ts A61110 : added parameters trackno, lba, nwa. Redefined return value. - @return 1=nwa is valid , 0=nwa is not valid , -1=error */ -int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) -{ - struct buffer buf; - struct command c; - unsigned char *data; - - mmc_function_spy("mmc_get_nwa"); - c.retry = 1; - c.oplen = sizeof(MMC_TRACK_INFO); - memcpy(c.opcode, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO)); - c.opcode[1] = 1; - if(trackno<=0) - c.opcode[5] = 0xFF; - else - c.opcode[5] = trackno; - c.page = &buf; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - data = c.page->data; - - *lba = (data[8] << 24) + (data[9] << 16) - + (data[10] << 8) + data[11]; - *nwa = (data[12] << 24) + (data[13] << 16) - + (data[14] << 8) + data[15]; - /* ts A61106 : MMC-1 Table 142 : NWA_V = NWA Valid Flag */ - if (!(data[7]&1)) { - libdax_msgs_submit(libdax_messenger, -1, 0x00000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - "mmc_get_nwa: Track Info Block: NWA_V == 0", 0, 0); - return 0; - } - return 1; -} - -/* ts A61009 : function is obviously unused. */ -/* void mmc_close_disc(struct burn_drive *d, struct burn_write_opts *o) */ -void mmc_close_disc(struct burn_write_opts *o) -{ - struct burn_drive *d; - - mmc_function_spy("mmc_close_disc"); - - libdax_msgs_submit(libdax_messenger, -1, 0x00000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - "HOW THAT ? mmc_close_disc() was called", 0, 0); - - /* ts A61009 : made impossible by removing redundant parameter d */ - /* a ssert(o->drive == d); */ - d = o->drive; - - o->multi = 0; - spc_select_write_params(d, o); - mmc_close(d, 1, 0); -} - -/* ts A61009 : function is obviously unused. */ -/* void mmc_close_session(struct burn_drive *d, struct burn_write_opts *o) */ -void mmc_close_session(struct burn_write_opts *o) -{ - struct burn_drive *d; - - mmc_function_spy("mmc_close_session"); - - libdax_msgs_submit(libdax_messenger, -1, 0x00000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - "HOW THAT ? mmc_close_session() was called", 0, 0); - - /* ts A61009 : made impossible by removing redundant parameter d */ - /* a ssert(o->drive == d); */ - d = o->drive; - - o->multi = 3; - spc_select_write_params(d, o); - mmc_close(d, 1, 0); -} - -void mmc_close(struct burn_drive *d, int session, int track) -{ - struct command c; - - mmc_function_spy("mmc_close"); - - c.retry = 1; - c.oplen = sizeof(MMC_CLOSE); - memcpy(c.opcode, MMC_CLOSE, sizeof(MMC_CLOSE)); - - /* ts A61030 : shifted !!session rather than or-ing plain session */ - c.opcode[2] = ((!!session)<<1) | !!track; - - c.opcode[4] = track >> 8; - c.opcode[5] = track & 0xFF; - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -void mmc_get_event(struct burn_drive *d) -{ - struct buffer buf; - struct command c; - - mmc_function_spy("mmc_get_event"); - c.retry = 1; - c.oplen = sizeof(MMC_GET_EVENT); - memcpy(c.opcode, MMC_GET_EVENT, sizeof(MMC_GET_EVENT)); - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - burn_print(12, "0x%x:0x%x:0x%x:0x%x\n", - c.page->data[0], c.page->data[1], c.page->data[2], - c.page->data[3]); - burn_print(12, "event: %d:%d:%d:%d\n", c.page->data[4], - c.page->data[5], c.page->data[6], c.page->data[7]); -} - - -void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf) -{ - struct command c; - int len; - - mmc_function_spy("mmc_write_12"); - len = buf->sectors; - - /* ts A61009 */ - /* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */ - - burn_print(100, "trying to write %d at %d\n", len, start); - memcpy(c.opcode, MMC_WRITE_12, sizeof(MMC_WRITE_12)); - c.retry = 1; - c.oplen = sizeof(MMC_WRITE_12); - c.opcode[2] = start >> 24; - c.opcode[3] = (start >> 16) & 0xFF; - c.opcode[4] = (start >> 8) & 0xFF; - c.opcode[5] = start & 0xFF; - c.opcode[6] = len >> 24; - c.opcode[7] = (len >> 16) & 0xFF; - c.opcode[8] = (len >> 8) & 0xFF; - c.opcode[9] = len & 0xFF; - c.page = buf; - c.dir = TO_DRIVE; - - d->issue_command(d, &c); -} - -int mmc_write(struct burn_drive *d, int start, struct buffer *buf) -{ - int cancelled; - struct command c; - int len; - -#ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ - static int tee_fd= -1; - if(tee_fd==-1) - tee_fd= open("/tmp/libburn_sg_written", - O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); -#endif /* Libburn_log_in_and_out_streaM */ - - mmc_function_spy("mmc_write"); - pthread_mutex_lock(&d->access_lock); - cancelled = d->cancel; - pthread_mutex_unlock(&d->access_lock); - - if (cancelled) - return BE_CANCELLED; - - len = buf->sectors; - - /* ts A61009 : buffer fill problems are to be handled by caller */ - /* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */ - - burn_print(100, "trying to write %d at %d\n", len, start); - memcpy(c.opcode, MMC_WRITE_10, sizeof(MMC_WRITE_10)); - c.retry = 1; - c.oplen = sizeof(MMC_WRITE_10); - c.opcode[2] = start >> 24; - c.opcode[3] = (start >> 16) & 0xFF; - c.opcode[4] = (start >> 8) & 0xFF; - c.opcode[5] = start & 0xFF; - c.opcode[6] = 0; - c.opcode[7] = (len >> 8) & 0xFF; - c.opcode[8] = len & 0xFF; - c.page = buf; - c.dir = TO_DRIVE; -/* - burn_print(12, "%d, %d, %d, %d - ", c->opcode[2], c->opcode[3], c->opcode[4], c->opcode[5]); - burn_print(12, "%d, %d, %d, %d\n", c->opcode[6], c->opcode[7], c->opcode[8], c->opcode[9]); -*/ - -#ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ - if(tee_fd!=-1) { - write(tee_fd,c.page->data,len*2048); - } -#endif /* Libburn_log_in_and_out_streaM */ - - d->issue_command(d, &c); - - /* ts A61112 : react on eventual error condition */ - if (c.error && c.sense[2]!=0) { - - /* >>> make this scsi_notify_error() when liberated */ - if (c.sense[2]!=0) { - char msg[80]; - sprintf(msg, - "SCSI error condition on write : key=%X asc=%2.2Xh ascq=%2.2Xh", - c.sense[2],c.sense[12],c.sense[13]); - libdax_msgs_submit(libdax_messenger, d->global_index, - 0x0002011d, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); - } - pthread_mutex_lock(&d->access_lock); - d->cancel = 1; - pthread_mutex_unlock(&d->access_lock); - return BE_CANCELLED; - } - - return 0; -} - -void mmc_read_toc(struct burn_drive *d) -{ -/* read full toc, all sessions, in m/s/f form, 4k buffer */ - struct burn_track *track; - struct burn_session *session; - struct buffer buf; - struct command c; - int dlen; - int i, bpl= 12; - unsigned char *tdata; - - mmc_function_spy("mmc_read_toc"); - memcpy(c.opcode, MMC_GET_TOC, sizeof(MMC_GET_TOC)); - c.retry = 1; - c.oplen = sizeof(MMC_GET_TOC); - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - if (c.error) { - - /* ts A61020 : this snaps on non-blank DVD media */ - /* ts A61106 : also snaps on CD with unclosed track/session */ - /* Very unsure wether this old measure is ok. - Obviously higher levels do not care about this. - DVD+RW burns go on after passing through here. - - d->busy = BURN_DRIVE_IDLE; - */ - libdax_msgs_submit(libdax_messenger, d->global_index, - 0x0002010d, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, - "Could not inquire TOC (non-blank DVD media ?)", 0,0); - d->status = BURN_DISC_UNSUITABLE; - d->toc_entries = 0; - /* Prefering memory leaks over fandangos */ - d->toc_entry = malloc(sizeof(struct burn_toc_entry)); - - return; - } - - dlen = c.page->data[0] * 256 + c.page->data[1]; - d->toc_entries = (dlen - 2) / 11; -/* - some drives fail this check. - - ts A61007 : if re-enabled then not via Assert. - a ssert(((dlen - 2) % 11) == 0); -*/ - d->toc_entry = malloc(d->toc_entries * sizeof(struct burn_toc_entry)); - tdata = c.page->data + 4; - - burn_print(12, "TOC:\n"); - - d->disc = burn_disc_create(); - - for (i = 0; i < c.page->data[3]; i++) { - session = burn_session_create(); - burn_disc_add_session(d->disc, session, BURN_POS_END); - burn_session_free(session); - } - - /* ts A61022 */ - burn_print(bpl, "-----------------------------------\n"); - - for (i = 0; i < d->toc_entries; i++, tdata += 11) { - - /* ts A61022: was burn_print level 12 */ - burn_print(bpl, "S %d, PT %2.2Xh, TNO %d :", tdata[0],tdata[3], - tdata[2]); - burn_print(bpl, " MSF(%d:%d:%d)", tdata[4],tdata[5],tdata[6]); - burn_print(bpl, " PMSF(%d:%d:%d %d)", - tdata[8], tdata[9], tdata[10], - burn_msf_to_lba(tdata[8], tdata[9], tdata[10]) - ); - burn_print(bpl, " - control %d, adr %d\n", tdata[1] & 0xF, - tdata[1] >> 4); - -/* - fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]); -*/ - - if (tdata[3] == 1) { - if (burn_msf_to_lba(tdata[8], tdata[9], tdata[10])) { - d->disc->session[0]->hidefirst = 1; - track = burn_track_create(); - burn_session_add_track(d->disc-> - session[tdata[0] - 1], - track, BURN_POS_END); - burn_track_free(track); - - } - } - if (tdata[3] < 100) { - track = burn_track_create(); - burn_session_add_track(d->disc->session[tdata[0] - 1], - track, BURN_POS_END); - track->entry = &d->toc_entry[i]; - burn_track_free(track); - } - d->toc_entry[i].session = tdata[0]; - d->toc_entry[i].adr = tdata[1] >> 4; - d->toc_entry[i].control = tdata[1] & 0xF; - d->toc_entry[i].tno = tdata[2]; - d->toc_entry[i].point = tdata[3]; - d->toc_entry[i].min = tdata[4]; - d->toc_entry[i].sec = tdata[5]; - d->toc_entry[i].frame = tdata[6]; - d->toc_entry[i].zero = tdata[7]; - d->toc_entry[i].pmin = tdata[8]; - d->toc_entry[i].psec = tdata[9]; - d->toc_entry[i].pframe = tdata[10]; - if (tdata[3] == 0xA0) - d->disc->session[tdata[0] - 1]->firsttrack = tdata[8]; - if (tdata[3] == 0xA1) - d->disc->session[tdata[0] - 1]->lasttrack = tdata[8]; - if (tdata[3] == 0xA2) - d->disc->session[tdata[0] - 1]->leadout_entry = - &d->toc_entry[i]; - } - - /* ts A61022 */ - burn_print(bpl, "-----------------------------------\n"); - - if (d->status != BURN_DISC_APPENDABLE) - d->status = BURN_DISC_FULL; - toc_find_modes(d); -} - -void mmc_read_disc_info(struct burn_drive *d) -{ - struct buffer buf; - unsigned char *data; - struct command c; - - mmc_function_spy("mmc_read_disc_info"); - memcpy(c.opcode, MMC_GET_DISC_INFO, sizeof(MMC_GET_DISC_INFO)); - c.retry = 1; - c.oplen = sizeof(MMC_GET_DISC_INFO); - c.page = &buf; - c.page->sectors = 0; - c.page->bytes = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - if (c.error) { - d->busy = BURN_DRIVE_IDLE; - return; - } - - data = c.page->data; - d->erasable = !!(data[2] & 16); - - /* ts A61020 */ - d->start_lba = d->end_lba = -2000000000; - -/* - fprintf(stderr, "libburn_experimental: data[2]= %d 0x%x\n", - (unsigned) data[2], (unsigned) data[2]); -*/ - switch (data[2] & 3) { - case 0: - d->toc_entries = 0; - d->start_lba = burn_msf_to_lba(data[17], data[18], data[19]); - d->end_lba = burn_msf_to_lba(data[21], data[22], data[23]); - -/* - fprintf(stderr, "libburn_experimental: start_lba = %d (%d %d %d) , end_lba = %d (%d %d %d)\n", - d->start_lba, data[17], data[18], data[19], - d->end_lba, data[21], data[22], data[23]); -*/ - - d->status = BURN_DISC_BLANK; - break; - case 1: - d->status = BURN_DISC_APPENDABLE; - case 2: - mmc_read_toc(d); - break; - } -} - -void mmc_read_atip(struct burn_drive *d) -{ - struct buffer buf; - struct command c; - - /* ts A61021 */ - unsigned char *data; - /* Speed values from A1: - With 4 cdrecord tells "10" or "8" where MMC-1 says "8". - cdrecord "8" appear on 4xCD-RW and thus seem to be quite invalid. - My CD-R (>=24 speed) tell no A1. - The higher non-MMC-1 values are hearsay. - */ - static int speed_value[16]= { 0, 2, 4, 6, 10, -5, 16, -7, - 24, 32, 40, 48, -12, -13, -14, -15}; - - mmc_function_spy("mmc_read_atip"); - memcpy(c.opcode, MMC_GET_ATIP, sizeof(MMC_GET_ATIP)); - c.retry = 1; - c.oplen = sizeof(MMC_GET_ATIP); - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - burn_print(1, "atip shit for you\n"); - - - /* ts A61021 */ - data = c.page->data; - d->erasable= !!(data[6]&64); - d->start_lba= burn_msf_to_lba(data[8],data[9],data[10]); - d->end_lba= burn_msf_to_lba(data[12],data[13],data[14]); - if (data[6]&4) { - if (speed_value[(data[16]>>4)&7] > 0) - d->mdata->min_write_speed = - speed_value[(data[16]>>4)&7]*176; - if (speed_value[(data[16])&15] > 0) - d->mdata->max_write_speed = - speed_value[(data[16])&15]*176; - } - -#ifdef Burn_mmc_be_verbous_about_atiP - { int i; - fprintf(stderr,"libburn_experimental: Returned ATIP Data\n"); - for(i= 0; i<28; i++) - fprintf(stderr,"%3.3d (0x%2.2x)%s", - data[i],data[i],((i+1)%5 ? " ":"\n")); - fprintf(stderr,"\n"); - - fprintf(stderr, - "libburn_experimental: Indicative Target Writing Power= %d\n", - (data[4]>>4)&7); - fprintf(stderr, - "libburn_experimental: Reference speed= %d ->%d\n", - data[4]&7, speed_value[data[4]&7]); - fprintf(stderr, - "libburn_experimental: Is %sunrestricted\n", - (data[5]&64?"":"not ")); - fprintf(stderr, - "libburn_experimental: Is %serasable, sub-type %d\n", - (data[6]&64?"":"not "),(data[6]>>3)&3); - fprintf(stderr, - "libburn_experimental: lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n", - burn_msf_to_lba(data[8],data[9],data[10]), - data[8],data[9],data[10]); - fprintf(stderr, - "libburn_experimental: lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n", - burn_msf_to_lba(data[12],data[13],data[14]), - data[12],data[13],data[14]); - if(data[6]&4) - fprintf(stderr, - "libburn_experimental: A1 speed low %d speed high %d\n", - speed_value[(data[16]>>4)&7], speed_value[(data[16])&7]); - if(data[6]&2) - fprintf(stderr, - "libburn_experimental: A2 speed low %d speed high %d\n", - speed_value[(data[20]>>4)&7], speed_value[(data[20])&7]); - if(data[6]&1) - fprintf(stderr, - "libburn_experimental: A3 speed low %d speed high %d\n", - speed_value[(data[24]>>4)&7], speed_value[(data[24])&7]); - } - -#endif /* Burn_mmc_be_verbous_about_atiP */ - -/* ts A61020 -http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf , table 77 : - - 0 ATIP Data Length MSB - 1 ATIP Data Length LSB - 2 Reserved - 3 Reserved - 4 bit7=1, bit4-6="Indicative Target Writing Power", bit3=reserved , - bit0-2="Reference speed" - 5 bit7=0, bit6="URU" , bit0-5=reserved - 6 bit7=1, bit6="Disc Type", bit3-4="Disc Sub-Type", - bit2="A1", bit1="A2", bit0="A3" - 7 reserved - 8 ATIP Start Time of lead-in (Min) - 9 ATIP Start Time of lead-in (Sec) -10 ATIP Start Time of lead-in (Frame) -11 reserved -12 ATIP Last Possible Start Time of lead-out (Min) -13 ATIP Last Possible Start Time of lead-out (Sec) -14 ATIP Last Possible Start Time of lead-out (Frame) -15 reserved -16 bit7=0, bit4-6="Lowest Usable CLV Recording speed" - bit0-3="Highest Usable CLV Recording speed" -17 bit7=0, bit4-6="Power Multiplication Factor p", - bit1-3="Target y value of the Modulation/Power function", bit0=reserved -18 bit7=1, bit4-6="Recommended Erase/Write Power Ratio (P(inf)/W(inf))" - bit0-3=reserved -19 reserved -20-22 A2 Values -23 reserved -24-26 A3 Values -27 reserved - -Disc Type - zero indicates CD-R media; one indicates CD-RW media. - -Disc Sub-Type - shall be set to zero. - -A1 - when set to one, indicates that bytes 16-18 are valid. - -Lowest Usable CLV Recording Speed -000b Reserved -001b 2X -010b - 111b Reserved - -Highest CLV Recording Speeds -000b Reserved -001b 2X -010b 4X -011b 6X -100b 8X -101b - 111b Reserved - -MMC-3 seems to recommend MODE SENSE (5Ah) page 2Ah rather than A1, A2, A3. -This page is loaded in libburn function spc_sense_caps() . -Speed is given in kbytes/sec there. But i suspect this to be independent -of media. So one would habe to associate the speed descriptor blocks with -the ATIP media characteristics ? How ? - -*/ -} - -void mmc_read_sectors(struct burn_drive *d, - int start, - int len, - const struct burn_read_opts *o, struct buffer *buf) -{ - int temp; - int errorblock, req; - struct command c; - - mmc_function_spy("mmc_read_sectors"); - - /* ts A61009 : to be ensured by callers */ - /* a ssert(len >= 0); */ - -/* if the drive isn't busy, why the hell are we here? */ - /* ts A61006 : i second that question */ - /* a ssert(d->busy); */ - - burn_print(12, "reading %d from %d\n", len, start); - memcpy(c.opcode, MMC_READ_CD, sizeof(MMC_READ_CD)); - c.retry = 1; - c.oplen = sizeof(MMC_READ_CD); - temp = start; - c.opcode[5] = temp & 0xFF; - temp >>= 8; - c.opcode[4] = temp & 0xFF; - temp >>= 8; - c.opcode[3] = temp & 0xFF; - temp >>= 8; - c.opcode[2] = temp & 0xFF; - c.opcode[8] = len & 0xFF; - len >>= 8; - c.opcode[7] = len & 0xFF; - len >>= 8; - c.opcode[6] = len & 0xFF; - req = 0xF8; - - /* ts A61106 : LG GSA-4082B dislikes this. key=5h asc=24h ascq=00h - - if (d->busy == BURN_DRIVE_GRABBING || o->report_recovered_errors) - req |= 2; - */ - - c.opcode[10] = 0; -/* always read the subcode, throw it away later, since we don't know - what we're really reading -*/ - if (d->busy == BURN_DRIVE_GRABBING || (o->subcodes_audio) - || (o->subcodes_data)) - c.opcode[10] = 1; - - c.opcode[9] = req; - c.page = buf; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - if (c.error) { - burn_print(12, "got an error over here\n"); - burn_print(12, "%d, %d, %d, %d\n", c.sense[3], c.sense[4], - c.sense[5], c.sense[6]); - errorblock = - (c.sense[3] << 24) + (c.sense[4] << 16) + - (c.sense[5] << 8) + c.sense[6]; - c.page->sectors = errorblock - start + 1; - burn_print(1, "error on block %d\n", errorblock); - burn_print(12, "error on block %d\n", errorblock); - burn_print(12, "returning %d sectors\n", c.page->sectors); - } -} - -void mmc_erase(struct burn_drive *d, int fast) -{ - struct command c; - - mmc_function_spy("mmc_erase"); - memcpy(c.opcode, MMC_ERASE, sizeof(MMC_ERASE)); - c.opcode[1] = 16; /* IMMED set to 1 */ - c.opcode[1] |= !!fast; - c.retry = 1; - c.oplen = sizeof(MMC_ERASE); - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -void mmc_read_lead_in(struct burn_drive *d, struct buffer *buf) -{ - int len; - struct command c; - - mmc_function_spy("mmc_read_lead_in"); - len = buf->sectors; - memcpy(c.opcode, MMC_READ_CD, sizeof(MMC_READ_CD)); - c.retry = 1; - c.oplen = sizeof(MMC_READ_CD); - c.opcode[5] = 0; - c.opcode[4] = 0; - c.opcode[3] = 0; - c.opcode[2] = 0xF0; - c.opcode[8] = 1; - c.opcode[7] = 0; - c.opcode[6] = 0; - c.opcode[9] = 0; - c.opcode[10] = 2; - c.page = buf; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); -} - -void mmc_perform_opc(struct burn_drive *d) -{ - struct command c; - - mmc_function_spy("mmc_perform_opc"); - memcpy(c.opcode, MMC_SEND_OPC, sizeof(MMC_SEND_OPC)); - c.retry = 1; - c.oplen = sizeof(MMC_SEND_OPC); - c.opcode[1] = 1; - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -void mmc_set_speed(struct burn_drive *d, int r, int w) -{ - struct command c; - - /* ts A61112 : MMC standards prescribe FFFFh as max speed. - But libburn.h prescribes 0. */ - if (r<=0 || r>0xffff) - r = 0xffff; - if (w<=0 || w>0xffff) - w = 0xffff; - - mmc_function_spy("mmc_set_speed"); - memcpy(c.opcode, MMC_SET_SPEED, sizeof(MMC_SET_SPEED)); - c.retry = 1; - c.oplen = sizeof(MMC_SET_SPEED); - c.opcode[2] = r >> 8; - c.opcode[3] = r & 0xFF; - c.opcode[4] = w >> 8; - c.opcode[5] = w & 0xFF; - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -void mmc_get_configuration(struct burn_drive *d) -{ - struct buffer buf; - int len; - struct command c; - - mmc_function_spy("mmc_get_configuration"); - memcpy(c.opcode, MMC_GET_CONFIGURATION, sizeof(MMC_GET_CONFIGURATION)); - c.retry = 1; - c.oplen = sizeof(MMC_GET_CONFIGURATION); - c.page = &buf; - c.page->sectors = 0; - c.page->bytes = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - burn_print(1, "got it back\n"); - len = (c.page->data[0] << 24) - + (c.page->data[1] << 16) - + (c.page->data[2] << 8) - + c.page->data[3]; - burn_print(1, "all %d bytes of it\n", len); - burn_print(1, "%d, %d, %d, %d\n", - c.page->data[0], - c.page->data[1], c.page->data[2], c.page->data[3]); -} - -void mmc_sync_cache(struct burn_drive *d) -{ - struct command c; - - mmc_function_spy("mmc_sync_cache"); - memcpy(c.opcode, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE)); - c.retry = 1; - c.oplen = sizeof(MMC_SYNC_CACHE); - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - - -/* ts A61023 : http://libburn.pykix.org/ticket/14 - get size and free space of drive buffer -*/ -int mmc_read_buffer_capacity(struct burn_drive *d) -{ - struct buffer buf; - struct command c; - unsigned char *data; - - mmc_function_spy("mmc_read_buffer_capacity"); - memcpy(c.opcode, MMC_READ_BUFFER_CAPACITY, - sizeof(MMC_READ_BUFFER_CAPACITY)); - c.retry = 1; - c.oplen = sizeof(MMC_READ_BUFFER_CAPACITY); - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - /* >>> ??? error diagnostics */ - - data = c.page->data; - - d->progress.buffer_capacity = - (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7]; - d->progress.buffer_available = - (data[8]<<24)|(data[9]<<16)|(data[10]<<8)|data[11]; - return 1; -} - - -/* ts A61021 : the mmc specific part of sg.c:enumerate_common() -*/ -int mmc_setup_drive(struct burn_drive *d) -{ - d->read_atip = mmc_read_atip; - d->read_toc = mmc_read_toc; - d->write = mmc_write; - d->erase = mmc_erase; - d->read_sectors = mmc_read_sectors; - d->perform_opc = mmc_perform_opc; - d->set_speed = mmc_set_speed; - d->send_cue_sheet = mmc_send_cue_sheet; - d->sync_cache = mmc_sync_cache; - d->get_nwa = mmc_get_nwa; - d->close_disc = mmc_close_disc; - d->close_session = mmc_close_session; - d->close_track_session = mmc_close; - d->read_buffer_capacity = mmc_read_buffer_capacity; - - /* ts A61020 */ - d->start_lba= -2000000000; - d->end_lba= -2000000000; - - return 1; -} - diff --git a/libburn/mmc.h b/libburn/mmc.h deleted file mode 100644 index b2f873f..0000000 --- a/libburn/mmc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __MMC -#define __MMC - -struct burn_drive; -struct burn_write_opts; -struct command; -struct buffer; -struct cue_sheet; - -/* MMC commands */ - -void mmc_read(struct burn_drive *); - -/* ts A61009 : removed redundant parameter d in favor of o->drive */ -/* void mmc_close_session(struct burn_drive *, struct burn_write_opts *); */ -/* void mmc_close_disc(struct burn_drive *, struct burn_write_opts *); */ -void mmc_close_session(struct burn_write_opts *o); -void mmc_close_disc(struct burn_write_opts *o); - -void mmc_close(struct burn_drive *, int session, int track); -void mmc_get_event(struct burn_drive *); -int mmc_write(struct burn_drive *, int start, struct buffer *buf); -void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf); -void mmc_sync_cache(struct burn_drive *); -void mmc_load(struct burn_drive *); -void mmc_eject(struct burn_drive *); -void mmc_erase(struct burn_drive *, int); -void mmc_read_toc(struct burn_drive *); -void mmc_read_disc_info(struct burn_drive *); -void mmc_read_atip(struct burn_drive *); -void mmc_read_sectors(struct burn_drive *, - int, - int, const struct burn_read_opts *, struct buffer *); -void mmc_set_speed(struct burn_drive *, int, int); -void mmc_read_lead_in(struct burn_drive *, struct buffer *); -void mmc_perform_opc(struct burn_drive *); -void mmc_get_configuration(struct burn_drive *); - -/* ts A61110 : added parameters trackno, lba, nwa. Redefined return value. - @return 1=nwa is valid , 0=nwa is not valid , -1=error */ -int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa); - -void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *); - -/* ts A61023 : get size and free space of drive buffer */ -int mmc_read_buffer_capacity(struct burn_drive *d); - -/* ts A61021 : the mmc specific part of sg.c:enumerate_common() -*/ -int mmc_setup_drive(struct burn_drive *d); - -#endif /*__MMC*/ diff --git a/libburn/null.c b/libburn/null.c deleted file mode 100644 index 415e0a4..0000000 --- a/libburn/null.c +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include "null.h" -#include "libburn.h" -#include - -#include -int null_read(struct burn_source *source, unsigned char *buffer, int size) -{ - memset(buffer, 0, size); - return size; -} - -struct burn_source *burn_null_source_new(void) -{ - struct burn_source *src; - - src = malloc(sizeof(struct burn_source)); - src->refcount = 1; - src->read = null_read; - src->read_sub = NULL; - - src->get_size = 0; - src->free_data = NULL; - src->data = NULL; - return src; -} diff --git a/libburn/null.h b/libburn/null.h deleted file mode 100644 index 1a7aae3..0000000 --- a/libburn/null.h +++ /dev/null @@ -1,10 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__NULL_H -#define BURN__NULL_H - -struct burn_source; -int null_read(struct burn_source *source, unsigned char *buffer, int size); -struct burn_source *burn_null_source_new(void); - -#endif /* LIBBURN__NULL_H */ diff --git a/libburn/options.c b/libburn/options.c deleted file mode 100644 index c4c01b3..0000000 --- a/libburn/options.c +++ /dev/null @@ -1,209 +0,0 @@ -#include "libburn.h" -#include "options.h" -#include "transport.h" - -/* ts A61007 */ -/* #include */ - -#include -#include - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - - -struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive) -{ - struct burn_write_opts *opts; - - opts = malloc(sizeof(struct burn_write_opts)); - if (opts == NULL) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020111, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Could not allocate new auxiliary object", 0, 0); - return NULL; - } - opts->drive = drive; - opts->refcount = 1; - opts->write_type = BURN_WRITE_TAO; - opts->block_type = BURN_BLOCK_MODE1; - opts->toc_entry = NULL; - opts->toc_entries = 0; - opts->simulate = 0; - opts->underrun_proof = drive->mdata->underrun_proof; - opts->perform_opc = 1; - opts->has_mediacatalog = 0; - opts->format = BURN_CDROM; - opts->multi = 0; - opts->control = 0; - return opts; -} - -void burn_write_opts_free(struct burn_write_opts *opts) -{ - if (--opts->refcount <= 0) - free(opts); -} - -struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive) -{ - struct burn_read_opts *opts; - - opts = malloc(sizeof(struct burn_read_opts)); - opts->drive = drive; - opts->refcount = 1; - opts->raw = 0; - opts->c2errors = 0; - opts->subcodes_audio = 0; - opts->subcodes_data = 0; - opts->hardware_error_recovery = 0; - opts->report_recovered_errors = 0; - opts->transfer_damaged_blocks = 0; - opts->hardware_error_retries = 3; - - return opts; -} - -void burn_read_opts_free(struct burn_read_opts *opts) -{ - if (--opts->refcount <= 0) - free(opts); -} - -int burn_write_opts_set_write_type(struct burn_write_opts *opts, - enum burn_write_types write_type, - int block_type) -{ - int sector_get_outmode(enum burn_write_types write_type, - enum burn_block_types block_type); - int spc_block_type(enum burn_block_types b); - - /* ts A61007 */ - if (! ( (write_type == BURN_WRITE_SAO && block_type == BURN_BLOCK_SAO) - || (opts->drive->block_types[write_type] & block_type) ) ) { -bad_combination:; - libdax_msgs_submit(libdax_messenger, -1, 0x00020112, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Bad combination of write_type and block_type", 0, 0); - return 0; - } - /* ts A61007 : obsoleting Assert in sector.c:get_outmode() */ - if (sector_get_outmode(write_type, (enum burn_block_types) block_type) - == -1) - goto bad_combination; - /* ts A61007 : obsoleting Assert in spc.c:spc_block_type() */ - if (spc_block_type((enum burn_block_types) block_type) == -1) - goto bad_combination; - - opts->write_type = write_type; - opts->block_type = block_type; - return 1; - - /* a ssert(0); */ -} - -void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count, - struct burn_toc_entry *toc_entries) -{ - opts->toc_entries = count; - opts->toc_entry = malloc(count * sizeof(struct burn_toc_entry)); - memcpy(opts->toc_entry, &toc_entries, - sizeof(struct burn_toc_entry) * count); -} - -void burn_write_opts_set_format(struct burn_write_opts *opts, int format) -{ - opts->format = format; -} - -int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim) -{ - if (opts->drive->mdata->simulate) { - opts->simulate = sim; - return 1; - } - return 0; -} - -int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts, - int underrun_proof) -{ - if (opts->drive->mdata->underrun_proof) { - opts->underrun_proof = underrun_proof; - return 1; - } - return 0; -} - -void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc) -{ - opts->perform_opc = opc; -} - -void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, - int has_mediacatalog) -{ - opts->has_mediacatalog = has_mediacatalog; -} - -void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, - unsigned char mediacatalog[13]) -{ - memcpy(opts->mediacatalog, &mediacatalog, 13); -} - -/* ts A61106 */ -void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi) -{ - opts->multi = !!multi; -} - - - -void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw) -{ - opts->raw = raw; -} - -void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors) -{ - opts->c2errors = c2errors; -} - -void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts, - int subcodes_audio) -{ - opts->subcodes_audio = subcodes_audio; -} - -void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts, - int subcodes_data) -{ - opts->subcodes_data = subcodes_data; -} - -void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts, - int hardware_error_recovery) -{ - opts->hardware_error_recovery = hardware_error_recovery; -} - -void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts, - int report_recovered_errors) -{ - opts->report_recovered_errors = report_recovered_errors; -} - -void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts, - int transfer_damaged_blocks) -{ - opts->transfer_damaged_blocks = transfer_damaged_blocks; -} - -void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts, - unsigned char - hardware_error_retries) -{ - opts->hardware_error_retries = hardware_error_retries; -} - diff --git a/libburn/options.h b/libburn/options.h deleted file mode 100644 index aebfdb5..0000000 --- a/libburn/options.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef BURN__OPTIONS_H -#define BURN__OPTIONS_H - -#include "libburn.h" - -/** Options for disc writing operations. This should be created with - burn_write_opts_new() and freed with burn_write_opts_free(). */ -struct burn_write_opts -{ - /** Drive the write opts are good for */ - struct burn_drive *drive; - - /** For internal use. */ - int refcount; - - /** The method/style of writing to use. */ - enum burn_write_types write_type; - /** format of the data to send to the drive */ - enum burn_block_types block_type; - - /** Number of toc entries. if this is 0, they will be auto generated*/ - int toc_entries; - /** Toc entries for the disc */ - struct burn_toc_entry *toc_entry; - - /** Simulate the write so that the disc is not actually written */ - unsigned int simulate:1; - /** If available, enable a drive feature which prevents buffer - underruns if not enough data is available to keep up with the - drive. */ - unsigned int underrun_proof:1; - /** Perform calibration of the drive's laser before beginning the - write. */ - unsigned int perform_opc:1; - /** A disc can have a media catalog number */ - int has_mediacatalog; - unsigned char mediacatalog[13]; - /** Session format */ - int format; - /* internal use only */ - unsigned char control; - unsigned char multi; -}; - -/** Options for disc reading operations. This should be created with - burn_read_opts_new() and freed with burn_read_opts_free(). */ -struct burn_read_opts -{ - /** Drive the read opts are good for */ - struct burn_drive *drive; - - /** For internal use. */ - int refcount; - - /** Read in raw mode, so that everything in the data tracks on the - disc is read, including headers. Not needed if just reading a - filesystem off a disc, but it should usually be used when making a - disc image or copying a disc. */ - unsigned int raw:1; - /** Report c2 errors. Useful for statistics reporting */ - unsigned int c2errors:1; - /** Read subcodes from audio tracks on the disc */ - unsigned int subcodes_audio:1; - /** Read subcodes from data tracks on the disc */ - unsigned int subcodes_data:1; - /** Have the drive recover errors if possible */ - unsigned int hardware_error_recovery:1; - /** Report errors even when they were recovered from */ - unsigned int report_recovered_errors:1; - /** Read blocks even when there are unrecoverable errors in them */ - unsigned int transfer_damaged_blocks:1; - - /** The number of retries the hardware should make to correct - errors. */ - unsigned char hardware_error_retries; -}; - -#endif /* BURN__OPTIONS_H */ diff --git a/libburn/read.c b/libburn/read.c deleted file mode 100644 index 72f60d7..0000000 --- a/libburn/read.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* #include ts A61013 : not in Linux man 3 malloc */ - -#include -#include -#include - -/* ts A61007 */ -/* #include */ - -#include -#include -#include -#include "sector.h" -#include "libburn.h" -#include "drive.h" -#include "transport.h" - -/* ts A60925 : obsoleted by libdax_msgs.h -#include "message.h" -*/ - -#include "crc.h" -#include "debug.h" -#include "init.h" -#include "lec.h" -#include "toc.h" -#include "util.h" -#include "sg.h" -#include "read.h" -#include "options.h" - -void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o) -{ -#if 0 - int i, end, maxsects, finish; - int seclen; - int drive_lba; - unsigned short crc; - unsigned char fakesub[96]; - struct buffer page; - int speed; - - /* ts A61007 : if this function gets revived, then these - tests have to be done more graceful */ - a ssert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000)); - a ssert(!d->busy); - a ssert(d->toc->valid); - a ssert(o->datafd != -1); - - /* moved up from spc_select_error_params alias d->send_parameters() */ - a ssert(d->mdata->valid); - -/* XXX not sure this is a good idea. copy it? */ -/* XXX also, we have duplicated data now, do we remove the fds from struct -drive, or only store a subset of the _opts structs in drives */ - - /* set the speed on the drive */ - speed = o->speed > 0 ? o->speed : d->mdata->max_read_speed; - d->set_speed(d, speed, 0); - - d->params.retries = o->hardware_error_retries; - - d->send_parameters(d, o); - - d->cancel = 0; - d->busy = BURN_DRIVE_READING; - d->currsession = 0; -/* drive_lba = 232000; - d->currtrack = 18; -*/ - d->currtrack = 0; - drive_lba = 0; -/* XXX removal of this line obviously breaks * - d->track_end = burn_track_end(d, d->currsession, d->currtrack);*/ - printf("track ends at %d\n", d->track_end); - page.sectors = 0; - page.bytes = 0; - - if (o->subfd != -1) { - memset(fakesub, 0xFF, 12); - memset(fakesub + 12, 0, 84); - fakesub[13] = 1; - fakesub[14] = 1; - fakesub[20] = 2; - fakesub[12] = (d->toc->toc_entry[0].control << 4) + - d->toc->toc_entry[0].adr; - crc = crc_ccitt(fakesub + 12, 10); - fakesub[22] = crc >> 8; - fakesub[23] = crc & 0xFF; - write(o->subfd, fakesub, 96); - } - while (1) { - seclen = burn_sector_length_read(d, o); - - burn_print(12, "received %d blocks\n", page.sectors); - for (i = 0; i < page.sectors; i++) { - burn_packet_process(d, page.data + seclen * i, o); - d->track_end--; - drive_lba++; - } - - if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) { - burn_print(1, "finished or cancelled\n"); - d->busy = BURN_DRIVE_IDLE; - if (!d->cancel) - d->toc->complete = 1; - return; - } -/* XXX: removal of this line obviously breaks * - end = burn_track_end(d, d->currsession, d->currtrack); */ - - if (drive_lba == end) { - d->currtrack++; - if (d->currtrack > - d->toc->session[d->currsession].lasttrack) { - d->currsession++; - burn_print(12, "session switch to %d\n", - d->currsession); - burn_print(12, "skipping a lead out\n"); - drive_lba = CURRENT_SESSION_START(d); - burn_print(12, "new lba %d\n", drive_lba); -/* XXX more of the same - end = burn_track_end(d, d->currsession, - d->currtrack); -*/ } - burn_print(12, "track switch to %d\n", d->currtrack); - } - - page.sectors = 0; - page.bytes = 0; - - maxsects = BUFFER_SIZE / seclen; - finish = end - drive_lba; - - d->track_end = finish; - - page.sectors = (finish < maxsects) ? finish : maxsects; - printf("reading %d sectors from %d\n", page.sectors, - drive_lba); - - /* >>> ts A61009 : ensure page.sectors >= 0 before calling */ - d->r ead_sectors(d, drive_lba, page.sectors, o, &page); - - printf("Read %d\n", page.sectors); - } -#endif -} -int burn_sector_length_read(struct burn_drive *d, - const struct burn_read_opts *o) -{ - int dlen = 2352; - int data; - -/*XXX how do we handle this crap now?*/ -/* data = d->toc->track[d->currtrack].toc_entry->control & 4;*/ - data = 1; - if (o->report_recovered_errors) - dlen += 294; - if ((o->subcodes_data) && data) - dlen += 96; - if ((o->subcodes_audio) && !data) - dlen += 96; - return dlen; -} - -static int bitcount(unsigned char *data, int n) -{ - int i, j, count = 0; - unsigned char tem; - - for (i = 0; i < n; i++) { - tem = data[i]; - for (j = 0; j < 8; j++) { - count += tem & 1; - tem >>= 1; - } - } - return count; -} - -void burn_packet_process(struct burn_drive *d, unsigned char *data, - const struct burn_read_opts *o) -{ - unsigned char sub[96]; - unsigned short crc; - int ptr = 2352, i, j, code, fb; - int audio = 1; - - if (o->c2errors) { - fb = bitcount(data + ptr, 294); - if (fb) { - burn_print(1, "%d damaged bits\n", - bitcount(data + ptr, 294)); - burn_print(1, "sending error on %s %s\n", - d->idata->vendor, d->idata->product); - /* XXX send a burn_message! burn_message_error(d, - something); */ - } - ptr += 294; - } -/* - if (d->toc->track[d->currtrack].mode == BURN_MODE_UNINITIALIZED) { - if ((d->toc->track[d->currtrack].toc_entry->control & 4) == 0) - d->toc->track[d->currtrack].mode = BURN_MODE_AUDIO; - else - switch (data[15]) { - case 0: - d->toc->track[d->currtrack].mode = BURN_MODE0; - break; - case 1: - d->toc->track[d->currtrack].mode = BURN_MODE1; - break; - case 2: - d->toc->track[d->currtrack].mode = - BURN_MODE2_FORMLESS; - break; - } - } -*/ - if ((audio && o->subcodes_audio) - || (!audio && o->subcodes_data)) { - memset(sub, 0, sizeof(sub)); - for (i = 0; i < 12; i++) { - for (j = 0; j < 8; j++) { - for (code = 0; code < 8; code++) { - sub[code * 12 + i] <<= 1; - if (data[ptr + j + i * 8] & - (1 << (7 - code))) - sub[code * 12 + i]++; - } - } - } - crc = (*(sub + 22) << 8) + *(sub + 23); - if (crc != crc_ccitt(sub + 12, 10)) { - burn_print(1, "sending error on %s %s\n", - d->idata->vendor, d->idata->product); -/* e = burn_error(); - e->drive = d; -*/ - burn_print(1, "crc mismatch in Q\n"); - } - /* else process_q(d, sub + 12); */ - /* - if (o->subfd != -1) write(o->subfd, sub, 96); */ - } -/* - if ((d->track_end <= 150) - && (drive_lba + 150 < CURRENT_SESSION_END(d)) - && (TOC_ENTRY(d->toc, d->currtrack).control == 4) - && (TOC_ENTRY(d->toc, d->currtrack + 1).control == 0)) { - burn_print(12, "pregap : %d\n", d->track_end); - write(o->binfd, zeros, 2352); - -#warning XXX WHERE ARE MY SUBCODES - } else -*//* write(o->datafd, data, 2352); */ -} - -/* so yeah, when you uncomment these, make them write zeros insted of crap -static void write_empty_sector(int fd) -{ - char sec[2352]; - - burn_print(1, "writing an 'empty' sector\n"); - write(fd, sec, 2352); -} - -static void write_empty_subcode(int fd) -{ - char sub[96]; - - write(fd, sub, 96); -} - -static void flipq(unsigned char *sub) -{ - *(sub + 12 + 10) = ~*(sub + 12 + 10); - *(sub + 12 + 11) = ~*(sub + 12 + 11); -} -*/ diff --git a/libburn/read.h b/libburn/read.h deleted file mode 100644 index fc07958..0000000 --- a/libburn/read.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __LIBBURN_READ -#define __LIBBURN_READ - -struct burn_drive; -struct burn_read_opts; - -int burn_sector_length_read(struct burn_drive *d, - const struct burn_read_opts *o); -void burn_packet_process(struct burn_drive *d, unsigned char *data, - const struct burn_read_opts *o); - -#endif /* __LIBBURN_READ */ diff --git a/libburn/sbc.c b/libburn/sbc.c deleted file mode 100644 index 4be928d..0000000 --- a/libburn/sbc.c +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* scsi block commands */ - -#include - -#include "transport.h" -#include "sbc.h" -#include "options.h" - -/* spc command set */ -static char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 }; -static char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 }; - -void sbc_load(struct burn_drive *d) -{ - struct command c; - - memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD)); - c.retry = 1; - c.oplen = sizeof(SBC_LOAD); - c.dir = NO_TRANSFER; - c.page = NULL; - d->issue_command(d, &c); -} - -void sbc_eject(struct burn_drive *d) -{ - struct command c; - - c.page = NULL; - memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD)); - c.oplen = 1; - c.oplen = sizeof(SBC_UNLOAD); - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -/* ts A61021 : the sbc specific part of sg.c:enumerate_common() -*/ -int sbc_setup_drive(struct burn_drive *d) -{ - d->eject = sbc_eject; - d->load = sbc_load; - return 1; -} - diff --git a/libburn/sbc.h b/libburn/sbc.h deleted file mode 100644 index 7fc82e3..0000000 --- a/libburn/sbc.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __SBC -#define __SBC - -struct burn_drive; - -void sbc_load(struct burn_drive *); -void sbc_eject(struct burn_drive *); - -/* ts A61021 : the sbc specific part of sg.c:enumerate_common() -*/ -int sbc_setup_drive(struct burn_drive *d); - -#endif /* __SBC */ diff --git a/libburn/sector.c b/libburn/sector.c deleted file mode 100644 index 4920c01..0000000 --- a/libburn/sector.c +++ /dev/null @@ -1,825 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include - -/* ts A61010 */ -/* #include */ - -#include -#include -#include "error.h" -#include "options.h" -#include "transport.h" -#include "libburn.h" -#include "drive.h" -#include "sector.h" -#include "crc.h" -#include "debug.h" -#include "lec.h" -#include "toc.h" -#include "write.h" - - -#ifdef Libburn_log_in_and_out_streaM -/* <<< ts A61031 */ -#include -#include -#include -#endif /* Libburn_log_in_and_out_streaM */ - - -/*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/ - -#define sector_common(X) d->alba++; d->rlba X; - -static void uncook_subs(unsigned char *dest, unsigned char *source) -{ - int i, j, code; - - memset(dest, 0, 96); - - for (i = 0; i < 12; i++) { - for (j = 0; j < 8; j++) { - for (code = 0; code < 8; code++) { - if (source[code * 12 + i] & 0x80) - dest[j + i * 8] |= (1 << (7 - code)); - source[code * 12 + i] <<= 1; - } - } - } -} - -/* @return >=0 : valid , <0 invalid */ -int sector_get_outmode(enum burn_write_types write_type, - enum burn_block_types block_type) -{ - /* ts A61103 : extended SAO condition to TAO */ - if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO) - return 0; - else - switch (block_type) { - case BURN_BLOCK_RAW0: - return BURN_MODE_RAW; - case BURN_BLOCK_RAW16: - return BURN_MODE_RAW | BURN_SUBCODE_P16; - case BURN_BLOCK_RAW96P: - return BURN_MODE_RAW | BURN_SUBCODE_P96; - case BURN_BLOCK_RAW96R: - return BURN_MODE_RAW | BURN_SUBCODE_R96; - case BURN_BLOCK_MODE1: - return BURN_MODE1; - default: - return -1; - } - - /* ts A61007 : now handled in burn_write_opts_set_write_type() */ - /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */ -} - -/* 0 means "same as inmode" */ -static int get_outmode(struct burn_write_opts *o) -{ - /* ts A61007 */ - return sector_get_outmode(o->write_type, o->block_type); - - /* -1 is prevented by check in burn_write_opts_set_write_type() */ - /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */ -} - - -static void get_bytes(struct burn_track *track, int count, unsigned char *data) -{ - int valid, shortage, curr, i, tr; - -#ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ - static int tee_fd= -1; - if(tee_fd==-1) - tee_fd= open("/tmp/libburn_sg_readin", - O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); -#endif /* Libburn_log_in_and_out_streaM */ - - -/* no track pointer means we're just generating 0s */ - if (!track) { - memset(data, 0, count); - return; - } - -/* first we use up any offset */ - valid = track->offset - track->offsetcount; - if (valid > count) - valid = count; - - if (valid) { - track->offsetcount += valid; - memset(data, 0, valid); - } - shortage = count - valid; - - if (!shortage) - goto ex; - -/* Next we use source data */ - curr = valid; - if (!track->eos) { - valid = track->source->read(track->source, data + curr, count - curr); - } else valid = 0; - - if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */ - track->eos = 1; - valid = 0; - } - track->sourcecount += valid; - -#ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ - if(tee_fd!=-1 && valid>0) { - write(tee_fd, data + curr, valid); - } -#endif /* Libburn_log_in_and_out_streaM */ - - curr += valid; - shortage = count - curr; - - if (!shortage) - goto ex; - -/* Before going to the next track, we run through any tail */ - - valid = track->tail - track->tailcount; - if (valid > count - curr) - valid = count - curr; - - if (valid) { - track->tailcount += valid; - memset(data + curr, 0, valid); - } - curr += valid; - shortage -= valid; - - if (!shortage) - goto ex; - - /* ts A61031 */ - if (shortage >= count) - track->track_data_done = 1; - if (track->open_ended) - goto ex; - -/* If we're still short, and there's a "next" pointer, we pull from that. - if that depletes, we'll just fill with 0s. -*/ - if (track->source->next) { - struct burn_source *src; - printf("pulling from next track\n"); - src = track->source->next; - valid = src->read(src, data + curr, shortage); - if (valid > 0) { - shortage -= valid; - curr += valid; - } - } -ex:; - /* ts A61024 : general finalizing processing */ - if(shortage) - memset(data + curr, 0, shortage); /* this is old icculus.org */ - if (track->swap_source_bytes == 1) { - for (i = 1; i < count; i += 2) { - tr = data[i]; - data[i] = data[i-1]; - data[i-1] = tr; - } - } -} - -/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer - and to count hand outs as well as reserved bytes */ -/* ts A61101 : added parameter track for counting written bytes */ -static unsigned char *get_sector(struct burn_write_opts *opts, - struct burn_track *track, int inmode) -{ - struct burn_drive *d = opts->drive; - struct buffer *out = d->buffer; - int outmode; - int seclen; - unsigned char *ret; - - outmode = get_outmode(opts); - if (outmode == 0) - outmode = inmode; - - /* ts A61009 : react on eventual failure of burn_sector_length() - (should not happen if API tested properly). - Ensures out->bytes >= out->sectors */ - seclen = burn_sector_length(outmode); - if (seclen <= 0) - return NULL; - seclen += burn_subcode_length(outmode); - - if (out->bytes + (seclen) >= BUFFER_SIZE) { - int err; - err = d->write(d, d->nwa, out); - if (err == BE_CANCELLED) - return NULL; - - /* ts A61101 */ - if(track != NULL) { - track->writecount += out->bytes; - track->written_sectors += out->sectors; - } - - d->nwa += out->sectors; - out->bytes = 0; - out->sectors = 0; - } - - ret = out->data + out->bytes; - out->bytes += seclen; - out->sectors++; - - return ret; -} - -/* ts A61031 */ -/* Revoke the counting of the most recent sector handed out by get_sector() */ -static void unget_sector(struct burn_write_opts *opts, int inmode) -{ - struct burn_drive *d = opts->drive; - struct buffer *out = d->buffer; - int outmode; - int seclen; - - outmode = get_outmode(opts); - if (outmode == 0) - outmode = inmode; - - /* ts A61009 : react on eventual failure of burn_sector_length() - (should not happen if API tested properly). - Ensures out->bytes >= out->sectors */ - seclen = burn_sector_length(outmode); - if (seclen <= 0) - return; - seclen += burn_subcode_length(outmode); - - out->bytes -= seclen; - out->sectors--; -} - - -/* either inmode == outmode, or outmode == raw. anything else is bad news */ -/* ts A61010 : changed type to int in order to propagate said bad news */ -/** @return 1 is ok, <= 0 is failure */ -static int convert_data(struct burn_write_opts *o, struct burn_track *track, - int inmode, unsigned char *data) -{ - int outlen, inlen; - int offset = -1; - int outmode; - - outmode = get_outmode(o); - if (outmode == 0) - outmode = inmode; - - outlen = burn_sector_length(outmode); - inlen = burn_sector_length(inmode); - - /* ts A61010 */ - /* a ssert(outlen >= inlen); */ - if (outlen < inlen) - return 0; - - if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) { - get_bytes(track, inlen, data); - return 1; - } - - /* ts A61010 */ - /* a ssert(outmode & BURN_MODE_RAW); */ - if (!(outmode & BURN_MODE_RAW)) - return 0; - - if (inmode & BURN_MODE1) - offset = 16; - if (inmode & BURN_MODE_RAW) - offset = 0; - if (inmode & BURN_AUDIO) - offset = 0; - - /* ts A61010 */ - /* a ssert(offset != -1); */ - if (offset == -1) - return 0; - - get_bytes(track, inlen, data + offset); - return 1; -} - -static void convert_subs(struct burn_write_opts *o, int inmode, - unsigned char *subs, unsigned char *sector) -{ - unsigned char *out; - int outmode; - - outmode = get_outmode(o); - if (outmode == 0) - outmode = inmode; - sector += burn_sector_length(outmode); -/* XXX for sao with subs, we'd need something else... */ - - switch (o->block_type) { - case BURN_BLOCK_RAW96R: - uncook_subs(sector, subs); - break; - - case BURN_BLOCK_RAW16: - memcpy(sector, subs + 12, 12); - out = sector + 12; - out[0] = 0; - out[1] = 0; - out[2] = 0; -/*XXX find a better way to deal with partially damaged P channels*/ - if (subs[2] != 0) - out[3] = 0x80; - else - out[3] = 0; - out = sector + 10; - - out[0] = ~out[0]; - out[1] = ~out[1]; - break; - } -} - -static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data) -{ - unsigned char *q; - int track; - int crc; - int min, sec, frame; - - track = d->toc_temp / 3; - memset(data, 0, 96); - q = data + 12; - - burn_lba_to_msf(d->rlba, &min, &sec, &frame); -/*XXX track numbers are BCD -a0 - 1st track ctrl -a1 - last track ctrl -a2 - lout ctrl -*/ - q[0] = (d->toc_entry[track].control << 4) + 1; - q[1] = 0; - if (d->toc_entry[track].point < 100) - q[2] = dec_to_bcd(d->toc_entry[track].point); - else - q[2] = d->toc_entry[track].point; - q[3] = dec_to_bcd(min); - q[4] = dec_to_bcd(sec); - q[5] = dec_to_bcd(frame); - q[6] = 0; - q[7] = dec_to_bcd(d->toc_entry[track].pmin); - q[8] = dec_to_bcd(d->toc_entry[track].psec); - q[9] = dec_to_bcd(d->toc_entry[track].pframe); - crc = crc_ccitt(q, 10); - q[10] = crc >> 8; - q[11] = crc & 0xFF; - d->toc_temp++; - d->toc_temp %= (d->toc_entries * 3); -} - -int sector_toc(struct burn_write_opts *o, int mode) -{ - struct burn_drive *d = o->drive; - unsigned char *data; - unsigned char subs[96]; - - data = get_sector(o, NULL, mode); - if (data == NULL) - return 0; - /* ts A61010 */ - if (convert_data(o, NULL, mode, data) <= 0) - return 0; - subcode_toc(d, mode, subs); - convert_subs(o, mode, subs, data); - sector_headers(o, data, mode, 1); - sector_common(++) - return 1; -} - -int sector_pregap(struct burn_write_opts *o, - unsigned char tno, unsigned char control, int mode) -{ - struct burn_drive *d = o->drive; - unsigned char *data; - unsigned char subs[96]; - - data = get_sector(o, NULL, mode); - if (data == NULL) - return 0; - /* ts A61010 */ - if (convert_data(o, NULL, mode, data) <= 0) - return 0; - subcode_user(o, subs, tno, control, 0, NULL, 1); - convert_subs(o, mode, subs, data); - sector_headers(o, data, mode, 0); - sector_common(--) - return 1; -} - -int sector_postgap(struct burn_write_opts *o, - unsigned char tno, unsigned char control, int mode) -{ - struct burn_drive *d = o->drive; - unsigned char subs[96]; - unsigned char *data; - - data = get_sector(o, NULL, mode); - if (data == NULL) - return 0; - /* ts A61010 */ - if (convert_data(o, NULL, mode, data) <= 0) - return 0;; -/* use last index in track */ - subcode_user(o, subs, tno, control, 1, NULL, 1); - convert_subs(o, mode, subs, data); - sector_headers(o, data, mode, 0); - sector_common(++) - return 1; -} - -static void subcode_lout(struct burn_write_opts *o, unsigned char control, - unsigned char *data) -{ - struct burn_drive *d = o->drive; - unsigned char *q; - int crc; - int rmin, min, rsec, sec, rframe, frame; - - memset(data, 0, 96); - q = data + 12; - - burn_lba_to_msf(d->alba, &min, &sec, &frame); - burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe); - - if (((rmin == 0) && (rsec == 0) && (rframe == 0)) || - ((rsec >= 2) && !((rframe / 19) % 2))) - memset(data, 0xFF, 12); - q[0] = (control << 4) + 1; - q[1] = 0xAA; - q[2] = 0x01; - q[3] = dec_to_bcd(rmin); - q[4] = dec_to_bcd(rsec); - q[5] = dec_to_bcd(rframe); - q[6] = 0; - q[7] = dec_to_bcd(min); - q[8] = dec_to_bcd(sec); - q[9] = dec_to_bcd(frame); - crc = crc_ccitt(q, 10); - q[10] = crc >> 8; - q[11] = crc & 0xFF; -} - -static char char_to_isrc(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'A' && c <= 'Z') - return 0x11 + (c - 'A'); - if (c >= 'a' && c <= 'z') - return 0x11 + (c - 'a'); - - /* ts A61008 : obsoleted by test in burn_track_set_isrc() */ - /* a ssert(0); */ - return 0; -} - -void subcode_user(struct burn_write_opts *o, unsigned char *subcodes, - unsigned char tno, unsigned char control, - unsigned char indx, struct isrc *isrc, int psub) -{ - struct burn_drive *d = o->drive; - unsigned char *p, *q; - int crc; - int m, s, f, c, qmode; /* 1, 2 or 3 */ - - memset(subcodes, 0, 96); - - p = subcodes; - if ((tno == 1) && (d->rlba == -150)) - memset(p, 0xFF, 12); - - if (psub) - memset(p, 0xFF, 12); - q = subcodes + 12; - - qmode = 1; - /* every 1 in 10 we can do something different */ - if (d->rlba % 10 == 0) { - /* each of these can occur 1 in 100 */ - if ((d->rlba / 10) % 10 == 0) { - if (o->has_mediacatalog) - qmode = 2; - } else if ((d->rlba / 10) % 10 == 1) { - if (isrc && isrc->has_isrc) - qmode = 3; - } - } - - /* ts A61010 : this cannot happen. Assert for fun ? */ - /* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */ - - switch (qmode) { - case 1: - q[1] = dec_to_bcd(tno); /* track number */ - q[2] = dec_to_bcd(indx); /* index XXX read this shit - from the track array */ - burn_lba_to_msf(d->rlba, &m, &s, &f); - q[3] = dec_to_bcd(m); /* rel min */ - q[4] = dec_to_bcd(s); /* rel sec */ - q[5] = dec_to_bcd(f); /* rel frame */ - q[6] = 0; /* zero */ - burn_lba_to_msf(d->alba, &m, &s, &f); - q[7] = dec_to_bcd(m); /* abs min */ - q[8] = dec_to_bcd(s); /* abs sec */ - q[9] = dec_to_bcd(f); /* abs frame */ - break; - case 2: - /* media catalog number */ - q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1]; - q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3]; - q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5]; - q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7]; - q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9]; - q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11]; - q[7] = o->mediacatalog[12] << 4; - - q[8] = 0; - burn_lba_to_msf(d->alba, &m, &s, &f); - q[9] = dec_to_bcd(f); /* abs frame */ - break; - case 3: - c = char_to_isrc(isrc->country[0]); - /* top 6 bits of [1] is the first country code */ - q[1] = c << 2; - c = char_to_isrc(isrc->country[1]); - /* bottom 2 bits of [1] is part of the second country code */ - q[1] += (c >> 4); - /* top 4 bits if [2] is the rest of the second country code */ - q[2] = c << 4; - - c = char_to_isrc(isrc->owner[0]); - /* bottom 4 bits of [2] is part of the first owner code */ - q[2] += (c >> 2); - /* top 2 bits of [3] is the rest of the first owner code */ - q[3] = c << 6; - c = char_to_isrc(isrc->owner[1]); - /* bottom 6 bits of [3] is the entire second owner code */ - q[3] += c; - c = char_to_isrc(isrc->owner[2]); - /* top 6 bits of [4] are the third owner code */ - q[4] = c << 2; - - /* [5] is the year in 2 BCD numbers */ - q[5] = dec_to_bcd(isrc->year % 100); - /* [6] is the first 2 digits in the serial */ - q[6] = dec_to_bcd(isrc->serial % 100); - /* [7] is the next 2 digits in the serial */ - q[7] = dec_to_bcd((isrc->serial / 100) % 100); - /* the top 4 bits of [8] is the last serial digit, the rest is - zeros */ - q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4; - burn_lba_to_msf(d->alba, &m, &s, &f); - q[9] = dec_to_bcd(f); /* abs frame */ - break; - } - q[0] = (control << 4) + qmode; - - crc = crc_ccitt(q, 10); - q[10] = crc >> 8; - q[11] = crc & 0xff; -} - -int sector_lout(struct burn_write_opts *o, unsigned char control, int mode) -{ - struct burn_drive *d = o->drive; - unsigned char subs[96]; - unsigned char *data; - - data = get_sector(o, NULL, mode); - if (!data) - return 0; - /* ts A61010 */ - if (convert_data(o, NULL, mode, data) <= 0) - return 0; - subcode_lout(o, control, subs); - convert_subs(o, mode, subs, data); - sector_headers(o, data, mode, 0); - sector_common(++) - return 1; -} - -int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub) -{ - struct burn_drive *d = o->drive; - unsigned char subs[96]; - unsigned char *data; - - data = get_sector(o, t, t->mode); - if (!data) - return 0; - /* ts A61010 */ - if (convert_data(o, t, t->mode, data) <= 0) - return 0; - - /* ts A61031 */ - if (t->open_ended && t->track_data_done) { - unget_sector(o, t->mode); - return 2; - } - - if (!t->source->read_sub) - subcode_user(o, subs, t->entry->point, - t->entry->control, 1, &t->isrc, psub); - else if (!t->source->read_sub(t->source, subs, 96)) - subcode_user(o, subs, t->entry->point, - t->entry->control, 1, &t->isrc, psub); - convert_subs(o, t->mode, subs, data); - - sector_headers(o, data, t->mode, 0); - sector_common(++) - return 1; -} - -int burn_msf_to_lba(int m, int s, int f) -{ - if (m < 90) - return (m * 60 + s) * 75 + f - 150; - else - return (m * 60 + s) * 75 + f - 450150; -} - -void burn_lba_to_msf(int lba, int *m, int *s, int *f) -{ - if (lba >= -150) { - *m = (lba + 150) / (60 * 75); - *s = (lba + 150 - *m * 60 * 75) / 75; - *f = lba + 150 - *m * 60 * 75 - *s * 75; - } else { - *m = (lba + 450150) / (60 * 75); - *s = (lba + 450150 - *m * 60 * 75) / 75; - *f = lba + 450150 - *m * 60 * 75 - *s * 75; - } -} - -int dec_to_bcd(int d) -{ - int top, bottom; - - top = d / 10; - bottom = d - (top * 10); - return (top << 4) + bottom; -} - -int sector_headers_is_ok(struct burn_write_opts *o, int mode) -{ - if (mode & BURN_AUDIO) /* no headers for "audio" */ - return 1; - if (o->write_type == BURN_WRITE_SAO) - return 1; - - /* ts A61031 */ - if (o->write_type == BURN_WRITE_TAO) - return 1; - - if (mode & BURN_MODE1) - return 2; - return 0; -} - -void sector_headers(struct burn_write_opts *o, unsigned char *out, - int mode, int leadin) -{ - struct burn_drive *d = o->drive; - unsigned int crc; - int min, sec, frame; - int modebyte = -1; - - /* ts A61009 */ -#if 1 - int ret; - - ret = sector_headers_is_ok(o, mode); - if (ret != 2) - return; - modebyte = 1; - -#else - - if (mode & BURN_AUDIO) /* no headers for "audio" */ - return; - if (o->write_type == BURN_WRITE_SAO) - return; - - /* ts A61031 */ - if (o->write_type == BURN_WRITE_TAO) - return; - - if (mode & BURN_MODE1) - modebyte = 1; - -#endif - - /* ts A61009 : now ensured by burn_disc_write_is_ok() */ - /* a ssert(modebyte == 1); */ - - out[0] = 0; - memset(out + 1, 0xFF, 10); /* sync */ - out[11] = 0; - - if (leadin) { - burn_lba_to_msf(d->rlba, &min, &sec, &frame); - out[12] = dec_to_bcd(min) + 0xA0; - out[13] = dec_to_bcd(sec); - out[14] = dec_to_bcd(frame); - out[15] = modebyte; - } else { - burn_lba_to_msf(d->alba, &min, &sec, &frame); - out[12] = dec_to_bcd(min); - out[13] = dec_to_bcd(sec); - out[14] = dec_to_bcd(frame); - out[15] = modebyte; - } - if (mode & BURN_MODE1) { - crc = crc_32(out, 2064); - out[2064] = crc & 0xFF; - crc >>= 8; - out[2065] = crc & 0xFF; - crc >>= 8; - out[2066] = crc & 0xFF; - crc >>= 8; - out[2067] = crc & 0xFF; - } - if (mode & BURN_MODE1) { - memset(out + 2068, 0, 8); - parity_p(out); - parity_q(out); - } - scramble(out); -} - -#if 0 -void process_q(struct burn_drive *d, unsigned char *q) -{ - unsigned char i[5]; - int mode; - - mode = q[0] & 0xF; -/* burn_print(12, "mode: %d : ", mode);*/ - switch (mode) { - case 1: -/* burn_print(12, "tno = %d : ", q[1]); - burn_print(12, "index = %d\n", q[2]); -*/ - /* q[1] is the track number (starting at 1) q[2] is the index - number (starting at 0) */ -#warning this is totally bogus - if (q[1] - 1 > 99) - break; - if (q[2] > d->toc->track[q[1] - 1].indices) { - burn_print(12, "new index at %d\n", d->alba); - d->toc->track[q[1] - 1].index[q[2]] = d->alba; - d->toc->track[q[1] - 1].indices++; - } - break; - case 2: - /* XXX dont ignore these */ - break; - case 3: -/* burn_print(12, "ISRC data in mode 3 q\n");*/ - i[0] = isrc[(q[1] << 2) >> 2]; -/* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]); - burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]); -*/ - break; - default: - - /* ts A61009 : if reactivated then witout Assert */ - a ssert(0); - } -} -#endif - -/* this needs more info. subs in the data? control/adr? */ -#warning sector_identify needs to be written -int sector_identify(unsigned char *data) -{ - scramble(data); -/* -check mode byte for 1 or 2 -test parity to see if it's a valid sector -if invalid, return BURN_MODE_AUDIO; -else return mode byte (what about mode 2 formless? heh) -*/ - return BURN_MODE1; -} diff --git a/libburn/sector.h b/libburn/sector.h deleted file mode 100644 index ecb609a..0000000 --- a/libburn/sector.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __SECTOR -#define __SECTOR - -#include "libburn.h" -#include "transport.h" - -struct burn_drive; -struct isrc; - -int dec_to_bcd(int); - -int sector_toc(struct burn_write_opts *, int mode); -int sector_pregap(struct burn_write_opts *, unsigned char tno, - unsigned char control, int mode); -int sector_postgap(struct burn_write_opts *, unsigned char tno, - unsigned char control, int mode); -int sector_lout(struct burn_write_opts *, unsigned char control, int mode); -int sector_data(struct burn_write_opts *, struct burn_track *t, int psub); - -/* ts A61009 */ -int sector_headers_is_ok(struct burn_write_opts *o, int mode); - -void sector_headers(struct burn_write_opts *, unsigned char *, - int mode, int leadin); -void subcode_user(struct burn_write_opts *, unsigned char *s, - unsigned char tno, unsigned char control, - unsigned char index, struct isrc *isrc, int psub); - -int sector_identify(unsigned char *); - -void process_q(struct burn_drive *d, unsigned char *q); - -#endif /* __SECTOR */ diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c deleted file mode 100644 index c2d92ef..0000000 --- a/libburn/sg-freebsd.c +++ /dev/null @@ -1,769 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - - -/* >>> ts A61021 : for testing the new arrangement of code - please outcomment these defines : */ - -/* Keeps alive old enumerate_common(). New version delegates much work - to methods in drive, mmc, spc, and sbc . -*/ -#define Scsi_freebsd_make_own_enumeratE 1 - - -/* Keeps alive old sg_enumerate(). New version delegates most work to - sg_give_next_adr(). -*/ -#define Scsi_freebsd_old_sg_enumeratE 1 - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* XXX */ - - -#include "transport.h" -#include "drive.h" -#include "sg.h" -#include "spc.h" -#include "mmc.h" -#include "sbc.h" -#include "debug.h" -#include "toc.h" -#include "util.h" - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - -static void enumerate_common(char *fname, int bus_no, int host_no, - int channel_no, int target_no, int lun_no); - -/* ts A51221 */ -int burn_drive_is_banned(char *device_address); - - -/* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ -int mmc_function_spy(char * text); - - -#ifdef Scsi_freebsd_old_sg_enumeratE - -int sg_give_next_adr(burn_drive_enumerator_t *idx, - char adr[], int adr_size, int initialize) -{ - return (0); -} - -int sg_is_enumerable_adr(char* adr) -{ - return (0); -} - -int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, - int *target_no, int *lun_no) -{ - return (0); -} - -#else /* Scsi_freebsd_old_sg_enumeratE */ - -/* ts A61021 : Moved most code from sg_enumerate under sg_give_next_adr() */ -/* Some helper functions for sg_give_next_adr() */ - -static int sg_init_enumerator(burn_drive_enumerator_t *idx) -{ - idx->skip_device = 0; - - if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) { - warn("couldn't open %s", XPT_DEVICE); - return -1; - } - - bzero(&(idx->ccb), sizeof(union ccb)); - - idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID; - idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; - idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; - - idx->ccb.ccb_h.func_code = XPT_DEV_MATCH; - idx->bufsize = sizeof(struct dev_match_result) * 100; - idx->ccb.cdm.match_buf_len = idx->bufsize; - idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize); - if (idx->ccb.cdm.matches == NULL) { - warnx("can't malloc memory for matches"); - close(idx->fd); - return -1; - } - idx->ccb.cdm.num_matches = 0; - idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */ - - /* - * We fetch all nodes, since we display most of them in the default - * case, and all in the verbose case. - */ - idx->ccb.cdm.num_patterns = 0; - idx->ccb.cdm.pattern_buf_len = 0; - - return 1; -} - - -static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx) -{ - /* - * We do the ioctl multiple times if necessary, in case there are - * more than 100 nodes in the EDT. - */ - if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) { - warn("error sending CAMIOCOMMAND ioctl"); - return -1; - } - - if ((idx->ccb.ccb_h.status != CAM_REQ_CMP) - || ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST) - && (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) { - warnx("got CAM error %#x, CDM error %d\n", - idx->ccb.ccb_h.status, idx->ccb.cdm.status); - return -1; - } - return 1; -} - - -/** Returns the next index number and the next enumerated drive address. - @param idx An opaque handle. Make no own theories about it. - @param adr Takes the reply - @param adr_size Gives maximum size of reply including final 0 - @param initialize 1 = start new, - 0 = continue, use no other values for now - -1 = finish - @return 1 = reply is a valid address , 0 = no further address available - -1 = severe error (e.g. adr_size too small) -*/ -int sg_give_next_adr(burn_drive_enumerator_t *idx, - char adr[], int adr_size, int initialize) -{ - int ret; - - if (initialize == 1) { - ret = sg_init_enumerator(idx); - if (ret<=0) - return ret; - } else if (initialize == -1) { - if(idx->fd != -1) - close(idx->fd); - idx->fd = -1; - return 0; - } - - -try_item:; /* This spaghetti loop keeps the number of tabs small */ - - /* Loop content from old sg_enumerate() */ - - while (idx->i >= idx->ccb.cdm.num_matches) { - ret = sg_next_enumeration_buffer(idx); - if (ret<=0) - return -1; - if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP) - && (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) ) - return 0; - idx->i = 0; - } - - switch (idx->ccb.cdm.matches[idx->i].type) { - case DEV_MATCH_BUS: - break; - case DEV_MATCH_DEVICE: { - struct device_match_result* result; - - result = &(idx->ccb.cdm.matches[i].result.device_result); - if (result->flags & DEV_RESULT_UNCONFIGURED) - idx->skip_device = 1; - else - idx->skip_device = 0; - break; - } - case DEV_MATCH_PERIPH: { - struct periph_match_result* result; - char buf[64]; - - result = &(idx->ccb.cdm.matches[i].result.periph_result); - if (idx->skip_device || - strcmp(result->periph_name, "pass") == 0) - break; - snprintf(buf, sizeof (buf), "/dev/%s%d", - result->periph_name, result->unit_number); - if(adr_size <= strlen(buf) - return -1; - strcpy(adr, buf); - - /* Found next enumerable address */ - return 1; - - } - default: - /* printf(stderr, "unknown match type\n"); */ - break; - } - - (idx->i)++; - goto try_item; /* Regular function exit is return 1 above */ -} - - -int sg_is_enumerable_adr(char* adr) -{ - burn_drive_enumerator_t idx; - int initialize = 1; - char buf[64]; - - while(1) { - ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize); - initialize = 0; - if (ret <= 0) - break; - if (strcmp(adr, buf) == 0) { - sg_give_next_adr(&idx, buf, sizeof(buf), -1); - return 1; - } - } - sg_give_next_adr(&idx, buf, sizeof(buf), -1); - return (0); -} - - -/** Try to obtain SCSI address parameters. - @return 1 is success , 0 is failure -*/ -int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, - int *target_no, int *lun_no) -{ - burn_drive_enumerator_t idx; - int initialize = 1; - char buf[64]; - struct periph_match_result* result; - - while(1) { - ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize); - initialize = 0; - if (ret <= 0) - break; - if (strcmp(adr, buf) != 0) - continue; - result = &(idx->ccb.cdm.matches[i].result.periph_result); - *bus_no = result->path_id; - *host_no = result->path_id; - *channel_no = 0; - *target_no = result->target_id - *lun_no = result->target_lun; - sg_give_next_adr(&idx, buf, sizeof(buf), -1); - return 1; - } - sg_give_next_adr(&idx, buf, sizeof(buf), -1); - return (0); -} - -#endif /* ! Scsi_freebsd_old_sg_enumeratE */ - - -int sg_close_drive(struct burn_drive * d) -{ - if (d->cam != NULL) { - cam_close_device(d->cam); - d->cam = NULL; - } - return 0; -} - -int sg_drive_is_open(struct burn_drive * d) -{ - return (d->cam != NULL); -} - - -void ata_enumerate(void) -{ - /* ts A61021: Only a dummy function is needed in FreeBSD */ - /* The difference between sg and ata should be encapsulated - in sg-linux.c */ - ; -} - - -void sg_enumerate(void) -{ - -#ifdef Scsi_freebsd_old_sg_enumeratE - - union ccb ccb; - int bufsize, fd; - unsigned int i; - int skip_device = 0; - - if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { - warn("couldn't open %s", XPT_DEVICE); - return; - } - - bzero(&ccb, sizeof(union ccb)); - - ccb.ccb_h.path_id = CAM_XPT_PATH_ID; - ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; - ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; - - ccb.ccb_h.func_code = XPT_DEV_MATCH; - bufsize = sizeof(struct dev_match_result) * 100; - ccb.cdm.match_buf_len = bufsize; - ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); - if (ccb.cdm.matches == NULL) { - warnx("can't malloc memory for matches"); - close(fd); - return; - } - ccb.cdm.num_matches = 0; - - /* - * We fetch all nodes, since we display most of them in the default - * case, and all in the verbose case. - */ - ccb.cdm.num_patterns = 0; - ccb.cdm.pattern_buf_len = 0; - - /* - * We do the ioctl multiple times if necessary, in case there are - * more than 100 nodes in the EDT. - */ - do { - if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { - warn("error sending CAMIOCOMMAND ioctl"); - break; - } - - if ((ccb.ccb_h.status != CAM_REQ_CMP) - || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) - && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { - warnx("got CAM error %#x, CDM error %d\n", - ccb.ccb_h.status, ccb.cdm.status); - break; - } - - for (i = 0; i < ccb.cdm.num_matches; i++) { - switch (ccb.cdm.matches[i].type) { - case DEV_MATCH_BUS: - break; - case DEV_MATCH_DEVICE: { - struct device_match_result* result; - - result = &ccb.cdm.matches[i].result.device_result; - - if (result->flags & DEV_RESULT_UNCONFIGURED) - skip_device = 1; - else - skip_device = 0; - - break; - } - case DEV_MATCH_PERIPH: { - struct periph_match_result* result; - char buf[64]; - - result = &ccb.cdm.matches[i].result.periph_result; - if (skip_device || strcmp(result->periph_name, "pass") == 0) - break; - snprintf(buf, sizeof (buf), "/dev/%s%d", result->periph_name, result->unit_number); - /* ts A51221 */ - if (burn_drive_is_banned(buf)) - break; - - enumerate_common(buf, result->path_id, result->path_id, 0, - result->target_id, result->target_lun); - break; - } - default: - fprintf(stdout, "unknown match type\n"); - break; - } - } - - } while ((ccb.ccb_h.status == CAM_REQ_CMP) - && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); - - close(fd); - -#else /* Scsi_freebsd_old_sg_enumeratE */ - - burn_drive_enumerator_t idx; - int initialize = 1; - char buf[64]; - - while(1) { - ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize); - initialize = 0; - if (ret <= 0) - break; - if (burn_drive_is_banned(buf)) - continue; - enumerate_common(buf, idx.result->path_id, idx.result->path_id, - 0, idx.result->target_id, - idx.result->target_lun); - } - sg_give_next_adr(&idx, buf, sizeof(buf), -1); - -#endif /* ! Scsi_freebsd_old_sg_enumeratE */ - -} - - -#ifdef Scsi_freebsd_make_own_enumeratE - -/* ts A61021: The old version which mixes SCSI and operating system adapter -*/ -static void enumerate_common(char *fname, int bus_no, int host_no, - int channel_no, int target_no, int lun_no) -{ - struct burn_drive *t; - struct burn_drive out; - - /* ts A60923 */ - out.bus_no = bus_no; - out.host = host_no; - out.id = target_no; - out.channel = channel_no; - out.lun = lun_no; - - out.devname = burn_strdup(fname); - out.cam = NULL; - - out.start_lba= -2000000000; - out.end_lba= -2000000000; - out.read_atip = mmc_read_atip; - - out.grab = sg_grab; - out.release = sg_release; - out.drive_is_open= sg_drive_is_open; - out.issue_command = sg_issue_command; - out.getcaps = spc_getcaps; - out.released = 1; - out.status = BURN_DISC_UNREADY; - - out.eject = sbc_eject; - out.load = sbc_load; - out.lock = spc_prevent; - out.unlock = spc_allow; - out.read_disc_info = spc_sense_write_params; - out.get_erase_progress = spc_get_erase_progress; - out.test_unit_ready = spc_test_unit_ready; - out.probe_write_modes = spc_probe_write_modes; - out.read_toc = mmc_read_toc; - out.write = mmc_write; - out.erase = mmc_erase; - out.read_sectors = mmc_read_sectors; - out.perform_opc = mmc_perform_opc; - out.set_speed = mmc_set_speed; - out.send_parameters = spc_select_error_params; - out.send_write_parameters = spc_select_write_params; - out.send_cue_sheet = mmc_send_cue_sheet; - out.sync_cache = mmc_sync_cache; - out.get_nwa = mmc_get_nwa; - out.close_disc = mmc_close_disc; - out.close_session = mmc_close_session; - out.close_track_session = mmc_close; - out.read_buffer_capacity = mmc_read_buffer_capacity; - out.idata = malloc(sizeof(struct burn_scsi_inquiry_data)); - out.idata->valid = 0; - out.mdata = malloc(sizeof(struct scsi_mode_data)); - out.mdata->valid = 0; - if (out.idata == NULL || out.mdata == NULL) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020108, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Could not allocate new drive object", 0, 0); - return; - } - memset(&out.params, 0, sizeof(struct params)); - t = burn_drive_register(&out); - -/* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("enumerate_common : -------- doing grab"); - -/* try to get the drive info */ - if (t->grab(t)) { - burn_print(2, "getting drive info\n"); - t->getcaps(t); - t->unlock(t); - t->released = 1; - } else { - burn_print(2, "unable to grab new located drive\n"); - } - -/* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("enumerate_common : ----- would release "); - -} - -#else /* Scsi_freebsd_make_own_enumeratE */ - -/* The new, more concise version of enumerate_common */ -static void enumerate_common(char *fname, int bus_no, int host_no, - int channel_no, int target_no, int lun_no) -{ - int ret; - struct burn_drive out; - - /* General libburn drive setup */ - burn_setup_drive(&out, fname); - - /* This transport adapter uses SCSI-family commands and models - (seems the adapter would know better than its boss, if ever) */ - ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, - target_no, lun_no, 0); - if (ret<=0) - return; - - /* Operating system adapter is CAM */ - /* Adapter specific handles and data */ - out.cam = NULL; - /* Adapter specific functions */ - out.grab = sg_grab; - out.release = sg_release; - out.drive_is_open = sg_drive_is_open; - out.issue_command = sg_issue_command; - - /* Finally register drive and inquire drive information */ - burn_drive_finish_enum(&out); -} - -#endif /* ! Scsi_freebsd_make_own_enumeratE */ - -/* ts A61021: do not believe this: - we use the sg reference count to decide whether we can use the - drive or not. - if refcount is not one, drive is open somewhere else. -*/ -int sg_grab(struct burn_drive *d) -{ - int count; - struct cam_device *cam; - - mmc_function_spy("sg_grab"); - - assert(d->cam == NULL); - - cam = cam_open_device(d->devname, O_RDWR); - if (cam == NULL) { - libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Could not grab drive", 0/*os_errno*/, 0); - return 0; - } -/* er = ioctl(fd, SG_GET_ACCESS_COUNT, &count);*/ - count = 1; - if (1 == count) { - d->cam = cam; - fcntl(cam->fd, F_SETOWN, getpid()); - d->released = 0; - return 1; - } - burn_print(1, "could not acquire drive - already open\n"); - sg_close_drive(d); - return 0; -} - - -/* - non zero return means you still have the drive and it's not - in a state to be released? (is that even possible?) -*/ - -int sg_release(struct burn_drive *d) -{ - mmc_function_spy("sg_release"); - - if (d->cam == NULL) { - burn_print(1, "release an ungrabbed drive. die\n"); - return 0; - } - - mmc_function_spy("sg_release ----------- closing."); - - sg_close_drive(d); - return 0; -} - -int sg_issue_command(struct burn_drive *d, struct command *c) -{ - int done = 0; - int err; - union ccb *ccb; - - char buf[161]; - snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d", - (void*)d->cam, d->released); - mmc_function_spy(buf); - - if (d->cam == NULL) { - c->error = 0; - return 0; - } - - c->error = 0; - - ccb = cam_getccb(d->cam); - cam_fill_csio(&ccb->csio, - 1, /* retries */ - NULL, /* cbfncp */ - CAM_DEV_QFRZDIS, /* flags */ - MSG_SIMPLE_Q_TAG, /* tag_action */ - NULL, /* data_ptr */ - 0, /* dxfer_len */ - sizeof (ccb->csio.sense_data), /* sense_len */ - 0, /* cdb_len */ - 30*1000); /* timeout */ - switch (c->dir) { - case TO_DRIVE: - ccb->csio.ccb_h.flags |= CAM_DIR_OUT; - break; - case FROM_DRIVE: - ccb->csio.ccb_h.flags |= CAM_DIR_IN; - break; - case NO_TRANSFER: - ccb->csio.ccb_h.flags |= CAM_DIR_NONE; - break; - } - - ccb->csio.cdb_len = c->oplen; - memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen); - - memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data)); - - if (c->page) { - ccb->csio.data_ptr = c->page->data; - if (c->dir == FROM_DRIVE) { - ccb->csio.dxfer_len = BUFFER_SIZE; -/* touch page so we can use valgrind */ - memset(c->page->data, 0, BUFFER_SIZE); - } else { - assert(c->page->bytes > 0); - ccb->csio.dxfer_len = c->page->bytes; - } - } else { - ccb->csio.data_ptr = NULL; - ccb->csio.dxfer_len = 0; - } - - do { - err = cam_send_ccb(d->cam, ccb); - if (err == -1) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x0002010c, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Failed to transfer command to drive", - errno, 0); - cam_freeccb(ccb); - sg_close_drive(d); - d->released = 1; - d->busy = BURN_DRIVE_IDLE; - c->error = 1; - return -1; - } - /* XXX */ - memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len); - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - if (!c->retry) { - c->error = 1; - cam_freeccb(ccb); - return 1; - } - switch (scsi_error(d, c->sense, 0)) { - case RETRY: - done = 0; - break; - case FAIL: - done = 1; - c->error = 1; - break; - } - } else { - done = 1; - } - } while (!done); - cam_freeccb(ccb); - return 1; -} - -enum response scsi_error(struct burn_drive *d, unsigned char *sense, - int senselen) -{ - int key, asc, ascq; - - senselen = senselen; - key = sense[2]; - asc = sense[12]; - ascq = sense[13]; - - burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n", - key, asc, ascq, d->idata->vendor, d->idata->product); - - switch (asc) { - case 0: - burn_print(12, "NO ERROR!\n"); - return RETRY; - - case 2: - burn_print(1, "not ready\n"); - return RETRY; - case 4: - burn_print(1, - "logical unit is in the process of becoming ready\n"); - return RETRY; - case 0x20: - if (key == 5) - burn_print(1, "bad opcode\n"); - return FAIL; - case 0x21: - burn_print(1, "invalid address or something\n"); - return FAIL; - case 0x24: - if (key == 5) - burn_print(1, "invalid field in cdb\n"); - else - break; - return FAIL; - case 0x26: - if (key == 5) - burn_print( 1, "invalid field in parameter list\n" ); - return FAIL; - case 0x28: - if (key == 6) - burn_print(1, - "Not ready to ready change, medium may have changed\n"); - else - break; - return RETRY; - case 0x3A: - burn_print(12, "Medium not present in %s %s\n", - d->idata->vendor, d->idata->product); - - d->status = BURN_DISC_EMPTY; - return FAIL; - } - burn_print(1, "unknown failure\n"); - burn_print(1, "key:0x%x, asc:0x%x, ascq:0x%x\n", key, asc, ascq); - return FAIL; -} - diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c deleted file mode 100644 index 794b84e..0000000 --- a/libburn/sg-linux.c +++ /dev/null @@ -1,870 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* ts A61010 */ -/* #include */ - -#include -#include -#include -#include -#include -#include -#include - -/* #include ts A61013 : not in Linux man 3 malloc */ - -#include -#include -#include -#include -#include -#include - -#include "transport.h" -#include "drive.h" -#include "sg.h" -#include "spc.h" -#include "mmc.h" -#include "sbc.h" -#include "debug.h" -#include "toc.h" -#include "util.h" - -/* kludge! glibc headers don't define all the SCSI stuff that we use! */ -#ifndef SG_GET_ACCESS_COUNT -# define SG_GET_ACCESS_COUNT 0x2289 -#endif - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - -static void enumerate_common(char *fname, int bus_no, int host_no, - int channel_no, int target_no, int lun_no); - -/* ts A51221 */ -int burn_drive_is_banned(char *device_address); - -/* ts A60813 : storage objects are in libburn/init.c - wether to use O_EXCL - wether to use O_NOBLOCK with open(2) on devices - wether to take O_EXCL rejection as fatal error */ -extern int burn_sg_open_o_excl; -extern int burn_sg_open_o_nonblock; -extern int burn_sg_open_abort_busy; - - -/* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ -int mmc_function_spy(char * text); - - -static int sgio_test(int fd) -{ - unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 }; - sg_io_hdr_t s; - - memset(&s, 0, sizeof(sg_io_hdr_t)); - s.interface_id = 'S'; - s.dxfer_direction = SG_DXFER_NONE; - s.cmd_len = 6; - s.cmdp = test_ops; - s.timeout = 12345; - return ioctl(fd, SG_IO, &s); -} - - -/* ts A60925 : ticket 74 */ -int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry) -{ - int ret, os_errno, sevno= LIBDAX_MSGS_SEV_DEBUG; - char msg[4096+100]; - - if(*fd < 0) - return(0); - ret = close(*fd); - *fd = -1337; - if(ret != -1) - return 1; - os_errno= errno; - - if (fname != NULL) - sprintf(msg, "Encountered error when closing drive '%s'", - fname); - else - sprintf(msg, "Encountered error when closing drive"); - - if (sorry) - sevno = LIBDAX_MSGS_SEV_SORRY; - libdax_msgs_submit(libdax_messenger, driveno, 0x00020002, - sevno, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); - return 0; -} - -int sg_drive_is_open(struct burn_drive * d) -{ - /* a bit more detailed case distinction than needed */ - if (d->fd == -1337) - return 0; - if (d->fd < 0) - return 0; - return 1; -} - -/* ts A60924 */ -int sg_handle_busy_device(char *fname, int os_errno) -{ - char msg[4096]; - - /* ts A60814 : i saw no way to do this more nicely */ - if (burn_sg_open_abort_busy) { - fprintf(stderr, - "\nlibburn: FATAL : Application triggered abort on busy device '%s'\n", - fname); - - /* ts A61007 */ - abort(); - /* a ssert("drive busy" == "non fatal"); */ - } - - /* ts A60924 : now reporting to libdax_msgs */ - sprintf(msg, "Cannot open busy device '%s'", fname); - libdax_msgs_submit(libdax_messenger, -1, 0x00020001, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW, - msg, os_errno, 0); - return 1; -} - - -/* ts A60922 ticket 33 */ -/** Returns the next index number and the next enumerated drive address. - @param idx An opaque handle. Make no own theories about it. - @param adr Takes the reply - @param adr_size Gives maximum size of reply including final 0 - @param initialize 1 = start new, - 0 = continue, use no other values for now - -1 = finish - @return 1 = reply is a valid address , 0 = no further address available - -1 = severe error (e.g. adr_size too small) -*/ -int sg_give_next_adr(burn_drive_enumerator_t *idx, - char adr[], int adr_size, int initialize) -{ - /* sg.h : typedef int burn_drive_enumerator_t; */ - static int sg_limit = 32, ata_limit = 26; - int baseno = 0; - - if (initialize == -1) - return 0; - - if (initialize == 1) - *idx = -1; - (*idx)++; - if (*idx >= sg_limit) - goto next_ata; - if (adr_size < 10) - return -1; - sprintf(adr, "/dev/sg%d", *idx); - return 1; -next_ata:; - baseno += sg_limit; - if (*idx - baseno >= ata_limit) - goto next_nothing; - if (adr_size < 9) - return -1; - sprintf(adr, "/dev/hd%c", 'a' + (*idx - baseno)); - return 1; -next_nothing:; - baseno += ata_limit; - return 0; -} - -int sg_is_enumerable_adr(char *adr) -{ - char fname[4096]; - int i, ret = 0, first = 1; - - while (1) { - ret= sg_give_next_adr(&i, fname, sizeof(fname), first); - if(ret <= 0) - break; - first = 0; - if (strcmp(adr, fname) == 0) - return 1; - - } - return(0); -} - - -/* ts A60926 */ -int sg_release_siblings(int sibling_fds[], int *sibling_count) -{ - int i; - char msg[81]; - - for(i= 0; i < *sibling_count; i++) - sg_close_drive_fd(NULL, -1, &(sibling_fds[i]), 0); - if(*sibling_count > 0) { - sprintf(msg, "Closed %d O_EXCL scsi siblings", *sibling_count); - libdax_msgs_submit(libdax_messenger, -1, 0x00020007, - LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); - } - *sibling_count = 0; - return 1; -} - - -/* ts A60926 */ -int sg_open_drive_fd(char *fname, int scan_mode) -{ - int open_mode = O_RDWR, fd; - char msg[81]; - - /* ts A60813 - A60927 - O_EXCL with devices is a non-POSIX feature - of Linux kernels. Possibly introduced 2002. - Mentioned in "The Linux SCSI Generic (sg) HOWTO" */ - if(burn_sg_open_o_excl) - open_mode |= O_EXCL; - /* ts A60813 - O_NONBLOCK was already hardcoded in ata_ but not in sg_. - There must be some reason for this. So O_NONBLOCK is - default mode for both now. Disable on own risk. */ - if(burn_sg_open_o_nonblock) - open_mode |= O_NONBLOCK; - -/* <<< debugging - fprintf(stderr, - "\nlibburn: experimental: o_excl= %d , o_nonblock= %d, abort_on_busy= %d\n", - burn_sg_open_o_excl,burn_sg_open_o_nonblock,burn_sg_open_abort_busy); - fprintf(stderr, - "libburn: experimental: O_EXCL= %d , O_NONBLOCK= %d\n", - !!(open_mode&O_EXCL),!!(open_mode&O_NONBLOCK)); -*/ - - fd = open(fname, open_mode); - if (fd == -1) { -/* <<< debugging - fprintf(stderr, - "\nlibburn: experimental: fname= %s , errno= %d\n", - fname,errno); -*/ - if (errno == EBUSY) { - sg_handle_busy_device(fname, errno); - return -1; - - } - if (scan_mode) - return -1; - sprintf(msg, "Failed to open device '%s'",fname); - libdax_msgs_submit(libdax_messenger, -1, 0x00020005, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - msg, errno, 0); - return -1; - } - return fd; -} - - -/* ts A60926 */ -int sg_open_scsi_siblings(char *path, int driveno, - int sibling_fds[], int *sibling_count, - int host_no, int channel_no, int id_no, int lun_no) -{ - int tld, i, ret, fd, i_bus_no = -1; - int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; - char msg[161], fname[81]; - - static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d", ""}; - - if(host_no < 0 || id_no < 0 || channel_no < 0 || lun_no < 0) - return(2); - if(*sibling_count > 0) - sg_release_siblings(sibling_fds, sibling_count); - - for (tld = 0; tldev[tld][0] != 0; tld++) { - for (i = 0; i < 32; i++) { - sprintf(fname, tldev[tld], i); - ret = sg_obtain_scsi_adr(fname, &i_bus_no, &i_host_no, - &i_channel_no, &i_target_no, &i_lun_no); - if (ret <= 0) - continue; - if (i_host_no != host_no || i_channel_no != channel_no) - continue; - if (i_target_no != id_no || i_lun_no != lun_no) - continue; - - fd = sg_open_drive_fd(fname, 0); - if (fd < 0) - goto failed; - - if (*sibling_count>=LIBBURN_SG_MAX_SIBLINGS) { - sprintf(msg, "Too many scsi siblings of '%s'", - path); - libdax_msgs_submit(libdax_messenger, - driveno, 0x00020006, - LIBDAX_MSGS_SEV_FATAL, - LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); - goto failed; - } - sprintf(msg, "Opened O_EXCL scsi sibling '%s' of '%s'", - fname, path); - libdax_msgs_submit(libdax_messenger, driveno, - 0x00020004, - LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); - sibling_fds[*sibling_count] = fd; - (*sibling_count)++; - } - } - return(1); -failed:; - sg_release_siblings(sibling_fds, sibling_count); - return 0; -} - - -/* ts A60926 */ -int sg_close_drive(struct burn_drive *d) -{ - int ret; - - if (!burn_drive_is_open(d)) - return 0; - sg_release_siblings(d->sibling_fds, &(d->sibling_count)); - ret = sg_close_drive_fd(d->devname, d->global_index, &(d->fd), 0); - return ret; -} - -void ata_enumerate(void) -{ - struct hd_driveid tm; - int i, fd; - char fname[10]; - - for (i = 0; i < 26; i++) { - sprintf(fname, "/dev/hd%c", 'a' + i); - /* ts A51221 */ - if (burn_drive_is_banned(fname)) - continue; - fd = sg_open_drive_fd(fname, 1); - if (fd == -1) - continue; - - /* found a drive */ - ioctl(fd, HDIO_GET_IDENTITY, &tm); - - /* not atapi */ - if (!(tm.config & 0x8000) || (tm.config & 0x4000)) { - sg_close_drive_fd(fname, -1, &fd, 0); - continue; - } - - /* if SG_IO fails on an atapi device, we should stop trying to - use hd* devices */ - if (sgio_test(fd) == -1) { - sg_close_drive_fd(fname, -1, &fd, 0); - return; - } - if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) - continue; - enumerate_common(fname, -1, -1, -1, -1, -1); - } -} - -void sg_enumerate(void) -{ - struct sg_scsi_id sid; - int i, fd, sibling_fds[LIBBURN_SG_MAX_SIBLINGS], sibling_count= 0, ret; - int bus_no = -1; - char fname[10]; - - for (i = 0; i < 32; i++) { - sprintf(fname, "/dev/sg%d", i); - /* ts A51221 */ - if (burn_drive_is_banned(fname)) - continue; - /* ts A60927 */ - fd = sg_open_drive_fd(fname, 1); - if (fd == -1) - continue; - - /* found a drive */ - ioctl(fd, SG_GET_SCSI_ID, &sid); - -#ifdef SCSI_IOCTL_GET_BUS_NUMBER - /* Hearsay A61005 */ - if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &bus_no) == -1) - bus_no = -1; -#endif - - if (sg_close_drive_fd(fname, -1, &fd, - sid.scsi_type == TYPE_ROM ) <= 0) - continue; - if (sid.scsi_type != TYPE_ROM) - continue; - - /* ts A60927 : trying to do locking with growisofs */ - if(burn_sg_open_o_excl>1) { - ret = sg_open_scsi_siblings( - fname, -1, sibling_fds, &sibling_count, - sid.host_no, sid.channel, - sid.scsi_id, sid.lun); - if (ret<=0) { - sg_handle_busy_device(fname, 0); - continue; - } - /* the final occupation will be done in sg_grab() */ - sg_release_siblings(sibling_fds, &sibling_count); - } -#ifdef SCSI_IOCTL_GET_BUS_NUMBER - if(bus_no == -1) - bus_no = 1000 * (sid.host_no + 1) + sid.channel; -#else - bus_no = sid.host_no; -#endif - enumerate_common(fname, bus_no, sid.host_no, sid.channel, - sid.scsi_id, sid.lun); - } -} - -/* ts A60923 - A61005 : introduced new SCSI parameters */ -/* ts A61021 : moved non os-specific code to spc,sbc,mmc,drive */ -static void enumerate_common(char *fname, int bus_no, int host_no, - int channel_no, int target_no, int lun_no) -{ - int ret, i; - struct burn_drive out; - - /* General libburn drive setup */ - burn_setup_drive(&out, fname); - - /* This transport adapter uses SCSI-family commands and models - (seems the adapter would know better than its boss, if ever) */ - ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, - target_no, lun_no, 0); - if (ret<=0) - return; - - /* Operating system adapter is Linux Generic SCSI (sg) */ - /* Adapter specific handles and data */ - out.fd = -1337; - out.sibling_count = 0; - for(i= 0; ifd == -1337) { */ - if(! burn_drive_is_open(d)) { - - /* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_grab ----------- opening"); - - /* ts A60926 */ - if(burn_sg_open_o_excl>1) { - fd = -1; - ret = sg_open_scsi_siblings(d->devname, - d->global_index,d->sibling_fds, - &(d->sibling_count), - d->host, d->channel, d->id, d->lun); - if(ret <= 0) - goto drive_is_in_use; - } - - fd = open(d->devname, open_mode); - os_errno = errno; - } else - fd= d->fd; - - /* ts A61007 : this is redundant */ - /* a ssert(fd != -1337); */ - - if (fd >= 0) { - - /* ts A60814: - according to my experiments this test would work now ! */ - - /* ts A60926 : this was disabled */ - /* Tests with growisofs on kernel 2.4.21 yielded that this - does not help against blocking on busy drives. - */ -/* <<< the old dummy */ -/* er = ioctl(fd, SG_GET_ACCESS_COUNT, &count);*/ - count = 1; - - if (1 == count) { - d->fd = fd; - fcntl(fd, F_SETOWN, getpid()); - d->released = 0; - return 1; - } - -drive_is_in_use:; - libdax_msgs_submit(libdax_messenger, d->global_index, - 0x00020003, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Could not grab drive - already in use", 0, 0); - sg_close_drive(d); - d->fd = -1337; - return 0; - } - libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Could not grab drive", os_errno, 0); - return 0; -} - -/* - non zero return means you still have the drive and it's not - in a state to be released? (is that even possible?) -*/ - -int sg_release(struct burn_drive *d) -{ - /* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_release"); - - if (d->fd < 1) { - burn_print(1, "release an ungrabbed drive. die\n"); - return 0; - } - - /* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_release ----------- closing"); - - sg_close_drive(d); - return 0; -} - - -int sg_issue_command(struct burn_drive *d, struct command *c) -{ - int done = 0, no_c_page = 0; - int err; - sg_io_hdr_t s; - -#ifdef Libburn_log_sg_commandS - /* <<< ts A61030 */ - static FILE *fp= NULL; - static int fpcount= 0; - int i; -#endif /* Libburn_log_sg_commandS */ - - /* <<< ts A60821 - debug: for tracing calls which might use open drive fds */ - char buf[161]; - sprintf(buf,"sg_issue_command d->fd= %d d->released= %d\n", - d->fd,d->released); - mmc_function_spy(buf); - -#ifdef Libburn_log_sg_commandS - /* <<< ts A61030 */ - if(fp==NULL) { - fp= fopen("/tmp/libburn_sg_command_log","a"); - fprintf(fp,"\n-----------------------------------------\n"); - } - for(i=0;i<10;i++) - fprintf(fp,"%2.2x ", c->opcode[i]); - fprintf(fp,"\n"); - fpcount++; -#endif /* Libburn_log_sg_commandS */ - - - /* ts A61010 : with no fd there is no chance to send an ioctl */ - if (d->fd < 0) { - c->error = 1; - return 0; - } - - c->error = 0; - memset(&s, 0, sizeof(sg_io_hdr_t)); - - s.interface_id = 'S'; - - if (c->dir == TO_DRIVE) - s.dxfer_direction = SG_DXFER_TO_DEV; - else if (c->dir == FROM_DRIVE) - s.dxfer_direction = SG_DXFER_FROM_DEV; - else if (c->dir == NO_TRANSFER) { - s.dxfer_direction = SG_DXFER_NONE; - - /* ts A61007 */ - /* a ssert(!c->page); */ - no_c_page = 1; - } - s.cmd_len = c->oplen; - s.cmdp = c->opcode; - s.mx_sb_len = 32; - s.sbp = c->sense; - memset(c->sense, 0, sizeof(c->sense)); - s.timeout = 200000; - if (c->page && !no_c_page) { - s.dxferp = c->page->data; - if (c->dir == FROM_DRIVE) { - s.dxfer_len = BUFFER_SIZE; -/* touch page so we can use valgrind */ - memset(c->page->data, 0, BUFFER_SIZE); - } else { - - /* ts A61010 */ - /* a ssert(c->page->bytes > 0); */ - if (c->page->bytes <= 0) { - c->error = 1; - return 0; - } - - s.dxfer_len = c->page->bytes; - } - } else { - s.dxferp = NULL; - s.dxfer_len = 0; - } - s.usr_ptr = c; - - do { - err = ioctl(d->fd, SG_IO, &s); - - /* ts A61010 */ - /* a ssert(err != -1); */ - if (err == -1) { - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x0002010c, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Failed to transfer command to drive", - errno, 0); - sg_close_drive(d); - d->released = 1; - d->busy = BURN_DRIVE_IDLE; - c->error = 1; - return -1; - } - - if (s.sb_len_wr) { - if (!c->retry) { - c->error = 1; - - /* A61106: rather than : return 1 */ - goto ex; - } - switch (scsi_error(d, s.sbp, s.sb_len_wr)) { - case RETRY: - done = 0; - break; - case FAIL: - done = 1; - c->error = 1; - break; - } - } else { - done = 1; - } - } while (!done); - - /* ts A61106 */ -ex:; - if (c->error) { - /* >>> to become d->notify_error() */ - scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0); - } - return 1; -} - - -/* ts A61030 - A61109 */ -/* @param flag bit0=do report conditions which are considered not an error */ -int scsi_notify_error(struct burn_drive *d, struct command *c, - unsigned char *sense, int senselen, int flag) -{ - int key= -1, asc= -1, ascq= -1, ret; - char msg[160]; - - if (d->silent_on_scsi_error) - return 1; - - if (senselen > 2) - key = sense[2]; - if (senselen > 13) { - asc = sense[12]; - ascq = sense[13]; - } - - if(!(flag & 1)) { - /* SPC : TEST UNIT READY command */ - if (c->opcode[0] == 0) - return 1; - /* MMC : READ DISC INFORMATION command */ - if (c->opcode[0] == 0x51) - if (key == 0x2 && asc == 0x3A && - ascq>=0 && ascq <= 0x02) /* MEDIUM NOT PRESENT */ - return 1; - } - - sprintf(msg,"SCSI error condition on command %2.2Xh :", c->opcode[0]); - if (key>=0) - sprintf(msg+strlen(msg), " key=%Xh", key); - if (asc>=0) - sprintf(msg+strlen(msg), " asc=%2.2Xh", asc); - if (ascq>=0) - sprintf(msg+strlen(msg), " ascq=%2.2Xh", ascq); - ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); - return ret; -} - - -enum response scsi_error(struct burn_drive *d, unsigned char *sense, - int senselen) -{ - int key, asc, ascq; - - senselen = senselen; - key = sense[2]; - asc = sense[12]; - ascq = sense[13]; - - burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n", - key, asc, ascq, d->idata->vendor, d->idata->product); - - switch (asc) { - case 0: - burn_print(12, "NO ERROR!\n"); - return RETRY; - - case 2: - burn_print(1, "not ready\n"); - return RETRY; - case 4: - burn_print(1, - "logical unit is in the process of becoming ready\n"); - return RETRY; - case 0x20: - if (key == 5) - burn_print(1, "bad opcode\n"); - return FAIL; - case 0x21: - burn_print(1, "invalid address or something\n"); - return FAIL; - case 0x24: - if (key == 5) - burn_print(1, "invalid field in cdb\n"); - else - break; - return FAIL; - case 0x26: - if ( key == 5 ) - burn_print( 1, "invalid field in parameter list\n" ); - return FAIL; - case 0x28: - if (key == 6) - burn_print(1, - "Not ready to ready change, medium may have changed\n"); - else - break; - return RETRY; - case 0x3A: - burn_print(12, "Medium not present in %s %s\n", - d->idata->vendor, d->idata->product); - - d->status = BURN_DISC_EMPTY; - return FAIL; - } - burn_print(1, "unknown failure\n"); - burn_print(1, "key:0x%x, asc:0x%x, ascq:0x%x\n", key, asc, ascq); - return FAIL; -} - -/* ts A60922 */ -/** Try to obtain SCSI address parameters. - @return 1 is success , 0 is failure -*/ -int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, - int *target_no, int *lun_no) -{ - int fd, ret; - struct my_scsi_idlun { - int x; - int host_unique_id; - }; - struct my_scsi_idlun idlun; - - if (strncmp(path, "/dev/hd", 7) == 0 - && path[7] >= 'a' && path[7] <= 'z' && path[8] == 0) - return 0; /* on RIP 14 all hdx return SCSI adr 0,0,0,0 */ - - fd = open(path, O_RDONLY | O_NONBLOCK); - if(fd < 0) - return 0; - -#ifdef SCSI_IOCTL_GET_BUS_NUMBER - /* Hearsay A61005 */ - if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1) - *bus_no = -1; -#endif - - /* http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html */ - ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun); - - sg_close_drive_fd(path, -1, &fd, 0); - if (ret == -1) - return(0); - *host_no= (idlun.x>>24)&255; - *channel_no= (idlun.x>>16)&255; - *target_no= (idlun.x)&255; - *lun_no= (idlun.x>>8)&255; -#ifdef SCSI_IOCTL_GET_BUS_NUMBER - if(*bus_no == -1) - *bus_no = 1000 * (*host_no + 1) + *channel_no; -#else - *bus_no= *host_no; -#endif - return 1; -} diff --git a/libburn/sg.c b/libburn/sg.c deleted file mode 100644 index 23c90c4..0000000 --- a/libburn/sg.c +++ /dev/null @@ -1,13 +0,0 @@ - -/* ts A61013 : It would be nice if autotools could do that job */ - -#ifdef __FreeBSD__ - -#include "sg-freebsd.c" - -#else - -#include "sg-linux.c" - -#endif - diff --git a/libburn/sg.h b/libburn/sg.h deleted file mode 100644 index 1501d65..0000000 --- a/libburn/sg.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __SG -#define __SG - -#ifdef __FreeBSD__ - -/* >>> To hold all state information of BSD device enumeration - which are now local in sg_enumerate() . So that sg_give_next_adr() - can work in BSD and sg_enumerate() can use it. */ -struct burn_drive_enumeration_state { - -#ifdef Scsi_freebsd_old_sg_enumeratE - int dummy; -#else - union ccb ccb; - int bufsize, fd; - unsigned int i; - int skip_device; -#endif /* ! Scsi_freebsd_old_sg_enumeratE */ - -}; -typedef struct burn_drive_enumeration_state burn_drive_enumerator_t; - -#else /* __FreeBSD__ */ - -/* <<< just for testing the C syntax */ -struct burn_drive_enumeration_state { - int dummy; -}; -typedef struct burn_drive_enumeration_state burn_drive_enumerator_tX; - -typedef int burn_drive_enumerator_t; - -#endif /* ! __FreeBSD__ */ - -struct burn_drive; -struct command; - -enum response -{ RETRY, FAIL }; - -/* ts A60925 : ticket 74 */ -int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry); - -/* ts A60922 ticket 33 */ -int sg_give_next_adr(burn_drive_enumerator_t *enm_context, - char adr[], int adr_size, int initialize); -int sg_is_enumerable_adr(char *adr); -int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, - int *target_no, int *lun_no); - -/* ts A60926 : ticket 33 ++ */ -int sg_open_scsi_siblings(char *fname, int driveno, - int sibling_fds[], int *sibling_count, - int host_no, int channel_no, int id_no, int lun_no); -int sg_release_siblings(int sibling_fds[], int *sibling_count); -int sg_close_drive(struct burn_drive *d); - -void sg_enumerate(void); -void ata_enumerate(void); -int sg_grab(struct burn_drive *); -int sg_release(struct burn_drive *); -int sg_issue_command(struct burn_drive *, struct command *); -enum response scsi_error(struct burn_drive *, unsigned char *, int); - -/* ts A61030 */ -/* @param flag bit0=do also report TEST UNIT READY failures */ -int scsi_notify_error(struct burn_drive *, struct command *c, - unsigned char *sense, int senselen, int flag); - -#endif /* __SG */ diff --git a/libburn/source.c b/libburn/source.c deleted file mode 100644 index a5ec152..0000000 --- a/libburn/source.c +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include -#include -#include "libburn.h" -#include "source.h" -#include "structure.h" - -void burn_source_free(struct burn_source *src) -{ - if (--src->refcount < 1) { - if (src->free_data) - src->free_data(src); - free(src); - } -} - -enum burn_source_status burn_track_set_source(struct burn_track *t, - struct burn_source *s) -{ - if (!s->read) - return BURN_SOURCE_FAILED; - s->refcount++; - t->source = s; - - /* ts A61031 */ - t->open_ended = (s->get_size(s) <= 0); - - return BURN_SOURCE_OK; -} - -struct burn_source *burn_source_new(void) -{ - struct burn_source *out; - - out = calloc(1, sizeof(struct burn_source)); - out->refcount = 1; - return out; -} diff --git a/libburn/source.h b/libburn/source.h deleted file mode 100644 index e0a69aa..0000000 --- a/libburn/source.h +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __SOURCE -#define __SOURCE - -struct burn_source *burn_source_new(void); - -#endif /*__SOURCE*/ diff --git a/libburn/spc.c b/libburn/spc.c deleted file mode 100644 index aa761ed..0000000 --- a/libburn/spc.c +++ /dev/null @@ -1,525 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* scsi primary commands */ - -#include -#include -#include -#include -#include -#include -#include - -/* ts A61008 */ -/* #include */ - -#include - -#include "transport.h" -#include "spc.h" -#include "mmc.h" -#include "sbc.h" -#include "drive.h" -#include "debug.h" -#include "options.h" - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - - -/* spc command set */ -static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 255, 0 }; - -/*static char SPC_TEST[]={0,0,0,0,0,0};*/ -static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 }; -static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 }; -static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; -static unsigned char SPC_MODE_SELECT[] = - { 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 }; -static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 }; - -int spc_test_unit_ready(struct burn_drive *d) -{ - struct command c; - - c.retry = 0; - c.oplen = sizeof(SPC_TEST_UNIT_READY); - memcpy(c.opcode, SPC_TEST_UNIT_READY, sizeof(SPC_TEST_UNIT_READY)); - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); - if (c.error) - return (c.sense[2] & 0xF) == 0; - return 1; -} - -void spc_request_sense(struct burn_drive *d, struct buffer *buf) -{ - struct command c; - - c.retry = 0; - c.oplen = sizeof(SPC_REQUEST_SENSE); - memcpy(c.opcode, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE)); - c.page = buf; - c.page->sectors = 0; - c.page->bytes = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); -} - -int spc_get_erase_progress(struct burn_drive *d) -{ - struct buffer b; - - spc_request_sense(d, &b); - return (b.data[16] << 8) | b.data[17]; -} - -void spc_inquiry(struct burn_drive *d) -{ - struct buffer buf; - struct burn_scsi_inquiry_data *id; - struct command c; - - memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY)); - c.retry = 1; - c.oplen = sizeof(SPC_INQUIRY); - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - id = (struct burn_scsi_inquiry_data *)d->idata; - id->vendor[8] = 0; - id->product[16] = 0; - id->revision[4] = 0; - - memcpy(id->vendor, c.page->data + 8, 8); - memcpy(id->product, c.page->data + 16, 16); - memcpy(id->revision, c.page->data + 32, 4); - - id->valid = 1; - return; -} - -void spc_prevent(struct burn_drive *d) -{ - struct command c; - - memcpy(c.opcode, SPC_PREVENT, sizeof(SPC_PREVENT)); - c.retry = 1; - c.oplen = sizeof(SPC_PREVENT); - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -void spc_allow(struct burn_drive *d) -{ - struct command c; - - memcpy(c.opcode, SPC_ALLOW, sizeof(SPC_ALLOW)); - c.retry = 1; - c.oplen = sizeof(SPC_ALLOW); - c.page = NULL; - c.dir = NO_TRANSFER; - d->issue_command(d, &c); -} - -void spc_sense_caps(struct burn_drive *d) -{ - struct buffer buf; - struct scsi_mode_data *m; - int size; - unsigned char *page; - struct command c; - - memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); - c.retry = 1; - c.oplen = sizeof(SPC_MODE_SENSE); - c.opcode[2] = 0x2A; - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - size = c.page->data[0] * 256 + c.page->data[1]; - m = d->mdata; - page = c.page->data + 8; - - m->buffer_size = page[12] * 256 + page[13]; - m->dvdram_read = page[2] & 32; - m->dvdram_write = page[3] & 32; - m->dvdr_read = page[2] & 16; - m->dvdr_write = page[3] & 16; - m->dvdrom_read = page[2] & 8; - m->simulate = page[3] & 4; - m->cdrw_read = page[2] & 2; - m->cdrw_write = page[3] & 2; - m->cdr_read = page[2] & 1; - m->cdr_write = page[3] & 1; - - /* ts A61021 : these fields are marked obsolete in MMC 3 */ - m->max_read_speed = page[8] * 256 + page[9]; - m->cur_read_speed = page[14] * 256 + page[15]; - - /* in MMC-3 : see [30-31] and blocks beginning at [32] */ - m->max_write_speed = page[18] * 256 + page[19]; - /* New field to be set by atip */ - m->min_write_speed = m->max_write_speed; - - /* in MMC-3 : [28-29] */ - m->cur_write_speed = page[20] * 256 + page[21]; - - /* >>> ts A61021 : iterate over all speeds : - data[30-31]: number of speed performance descriptor blocks - data[32-35]: block 0 : [+2-3] speed in kbytes/sec - */ - - m->c2_pointers = page[5] & 16; - m->valid = 1; - m->underrun_proof = page[4] & 128; -} - -void spc_sense_error_params(struct burn_drive *d) -{ - struct buffer buf; - struct scsi_mode_data *m; - int size; - unsigned char *page; - struct command c; - - memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); - c.retry = 1; - c.oplen = sizeof(SPC_MODE_SENSE); - c.opcode[2] = 0x01; - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - size = c.page->data[0] * 256 + c.page->data[1]; - m = d->mdata; - page = c.page->data + 8; - d->params.retries = page[3]; - m->retry_page_length = page[1]; - m->retry_page_valid = 1; -} - -void spc_select_error_params(struct burn_drive *d, - const struct burn_read_opts *o) -{ - struct buffer buf; - struct command c; - - memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); - c.retry = 1; - c.oplen = sizeof(SPC_MODE_SELECT); - c.opcode[8] = 8 + 2 + d->mdata->retry_page_length; - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - - /* ts A61007 : moved up to only caller burn_disc_read() */ - /* a ssert(d->mdata->valid); */ - - memset(c.page->data, 0, 8 + 2 + d->mdata->retry_page_length); - c.page->bytes = 8 + 2 + d->mdata->retry_page_length; - c.page->data[8] = 1; - c.page->data[9] = d->mdata->retry_page_length; - if (o->transfer_damaged_blocks) - c.page->data[10] |= 32; - if (o->report_recovered_errors) - c.page->data[10] |= 4; - if (!o->hardware_error_recovery) - c.page->data[10] |= 1; -/*burn_print(1, "error parameter 0x%x\n", c->page->data[10]);*/ - c.page->data[11] = d->params.retries; - c.dir = TO_DRIVE; - d->issue_command(d, &c); -} - -void spc_sense_write_params(struct burn_drive *d) -{ - struct buffer buf; - struct scsi_mode_data *m; - int size; - unsigned char *page; - struct command c; - - /* ts A61007 : Done in soft at only caller burn_drive_grab() */ - /* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write || - d->mdata->dvdr_write || d->mdata->dvdram_write); */ - - memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); - c.retry = 1; - c.oplen = sizeof(SPC_MODE_SENSE); - c.opcode[2] = 0x05; - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - - size = c.page->data[0] * 256 + c.page->data[1]; - m = d->mdata; - page = c.page->data + 8; - burn_print(1, "write page length 0x%x\n", page[1]); - m->write_page_length = page[1]; - m->write_page_valid = 1; - mmc_read_disc_info(d); -} - -/* remark ts A61104 : -Although command MODE SELECT is SPC, the content of the -Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1). -Thus the filling of the mode page should be done by a mmc_ function. -*/ -void spc_select_write_params(struct burn_drive *d, - const struct burn_write_opts *o) -{ - struct buffer buf; - struct command c; - int bufe, sim; - - /* ts A61007 : All current callers are safe. */ - /* a ssert(o->drive == d); */ - - /* <<< A61030 - fprintf(stderr,"libburn_debug: write_type=%d multi=%d control=%d\n", - o->write_type,o->multi,o->control); - fprintf(stderr,"libburn_debug: block_type=%d spc_block_type=%d\n", - o->block_type,spc_block_type(o->block_type)); - */ - - memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); - c.retry = 1; - c.oplen = sizeof(SPC_MODE_SELECT); - c.opcode[8] = 8 + 2 + d->mdata->write_page_length; - c.page = &buf; - c.page->bytes = 0; - c.page->sectors = 0; - - /* ts A61007 : moved up to burn_disc_write() */ - /* a ssert(d->mdata->valid); */ - - memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length); - c.page->bytes = 8 + 2 + d->mdata->write_page_length; - c.page->data[8] = 5; - c.page->data[9] = d->mdata->write_page_length; - - burn_print(12, "using write page length %d (valid %d)\n", - d->mdata->write_page_length, d->mdata->write_page_valid); - bufe = o->underrun_proof; - sim = o->simulate; - c.page->data[10] = (bufe << 6) - + (sim << 4) - + o->write_type; - - /* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */ - c.page->data[11] = ((3 * !!o->multi) << 6) | o->control; - - c.page->data[12] = spc_block_type(o->block_type); - - /* ts A61104 */ - if(!(o->control&4)) /* audio (MMC-1 table 61) */ - if(o->write_type == BURN_WRITE_TAO) /* ??? for others too ? */ - c.page->data[12] = 0; /* Data Block Type: Raw Data */ - - c.page->data[22] = 0; - c.page->data[23] = 150; /* audio pause length */ -/*XXX need session format! */ - c.dir = TO_DRIVE; - d->issue_command(d, &c); -} - -void spc_getcaps(struct burn_drive *d) -{ - spc_inquiry(d); - spc_sense_caps(d); - spc_sense_error_params(d); -} - -/* -only called when a blank is present, so we set type to blank -(on the last pass) - -don't check totally stupid modes (raw/raw0) -some drives say they're ok, and they're not. -*/ - -void spc_probe_write_modes(struct burn_drive *d) -{ - struct buffer buf; - int try_write_type = 1; - int try_block_type = 0; - int key, asc, ascq; - struct command c; - - while (try_write_type != 4) { - burn_print(9, "trying %d, %d\n", try_write_type, - try_block_type); - memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); - c.retry = 1; - c.oplen = sizeof(SPC_MODE_SELECT); - c.opcode[8] = 8 + 2 + 0x32; - c.page = &buf; - - memset(c.page->data, 0, 8 + 2 + 0x32); - c.page->bytes = 8 + 2 + 0x32; - - c.page->data[8] = 5; - c.page->data[9] = 0x32; - c.page->data[10] = try_write_type; - if (try_block_type > 4) - c.page->data[11] = 4; - else - c.page->data[11] = 0; - c.page->data[12] = try_block_type; - c.page->data[23] = 150; - c.dir = TO_DRIVE; - - d->silent_on_scsi_error = 1; - d->issue_command(d, &c); - d->silent_on_scsi_error = 0; - - key = c.sense[2]; - asc = c.sense[12]; - ascq = c.sense[13]; - - if (key) - burn_print(7, "%d not supported\n", try_block_type); - else { - burn_print(7, "%d:%d SUPPORTED MODE!\n", - try_write_type, try_block_type); - if (try_write_type == 2) /* sao */ - d->block_types[try_write_type] = - BURN_BLOCK_SAO; - else - d->block_types[try_write_type] |= - 1 << try_block_type; - } - switch (try_block_type) { - case 0: - case 1: - case 2: - try_block_type++; - break; - case 3: - try_block_type = 8; - break; - case 8: - case 9: - case 10: - case 11: - case 12: - try_block_type++; - break; - case 13: - try_block_type = 0; - try_write_type++; - break; - default: - return; - } - } -} - -/** @return -1 = error */ -int spc_block_type(enum burn_block_types b) -{ - switch (b) { - case BURN_BLOCK_SAO: - return 0; /* ignored bitz */ - case BURN_BLOCK_RAW0: - return 0; - case BURN_BLOCK_RAW16: - return 1; - case BURN_BLOCK_RAW96P: - return 2; - case BURN_BLOCK_RAW96R: - return 3; - case BURN_BLOCK_MODE1: - return 8; - case BURN_BLOCK_MODE2R: - return 9; - case BURN_BLOCK_MODE2_PATHETIC: - return 10; - case BURN_BLOCK_MODE2_LAME: - return 11; - case BURN_BLOCK_MODE2_OBSCURE: - return 12; - case BURN_BLOCK_MODE2_OK: - return 13; - default: - return -1; - } - /* ts A61007 : already prevented in burn_write_opts_set_write_type() */ - /* a ssert(0); */; -} - -/* ts A61021 : the spc specific part of sg.c:enumerate_common() -*/ -int spc_setup_drive(struct burn_drive *d) -{ - d->getcaps = spc_getcaps; - d->lock = spc_prevent; - d->unlock = spc_allow; - d->read_disc_info = spc_sense_write_params; - d->get_erase_progress = spc_get_erase_progress; - d->test_unit_ready = spc_test_unit_ready; - d->probe_write_modes = spc_probe_write_modes; - d->send_parameters = spc_select_error_params; - d->send_write_parameters = spc_select_write_params; - return 1; -} - -/* ts A61021 : the general SCSI specific part of sg.c:enumerate_common() - @param flag Bitfiled for control purposes - bit0= do not setup spc/sbc/mmc -*/ -int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no, - int channel_no, int target_no, int lun_no, int flag) -{ - int ret; - - /* ts A60923 */ - d->bus_no = bus_no; - d->host = host_no; - d->id = target_no; - d->channel = channel_no; - d->lun = lun_no; - - /* ts A61106 */ - d->silent_on_scsi_error = 0; - - - d->idata = malloc(sizeof(struct burn_scsi_inquiry_data)); - d->idata->valid = 0; - d->mdata = malloc(sizeof(struct scsi_mode_data)); - d->mdata->valid = 0; - - /* ts A61007 : obsolete Assert in drive_getcaps() */ - if(d->idata == NULL || d->mdata == NULL) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020108, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Could not allocate new drive object", 0, 0); - return -1; - } - if(!(flag & 1)) { - ret = spc_setup_drive(d); - if (ret<=0) - return ret; - ret = sbc_setup_drive(d); - if (ret<=0) - return ret; - ret = mmc_setup_drive(d); - if (ret<=0) - return ret; - } - return 1; -} diff --git a/libburn/spc.h b/libburn/spc.h deleted file mode 100644 index d19254a..0000000 --- a/libburn/spc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __SPC -#define __SPC - -#include "libburn.h" - -void spc_inquiry(struct burn_drive *); -void spc_prevent(struct burn_drive *); -void spc_allow(struct burn_drive *); -void spc_sense_caps(struct burn_drive *); -void spc_sense_error_params(struct burn_drive *); -void spc_select_error_params(struct burn_drive *, - const struct burn_read_opts *); -void spc_getcaps(struct burn_drive *d); -void spc_sense_write_params(struct burn_drive *); -void spc_select_write_params(struct burn_drive *, - const struct burn_write_opts *); -void spc_probe_write_modes(struct burn_drive *); -void spc_request_sense(struct burn_drive *d, struct buffer *buf); -int spc_block_type(enum burn_block_types b); -int spc_get_erase_progress(struct burn_drive *d); -int spc_test_unit_ready(struct burn_drive *d); - -/* ts A61021 : the spc specific part of sg.c:enumerate_common() -*/ -int spc_setup_drive(struct burn_drive *d); - -/* ts A61021 : the general SCSI specific part of sg.c:enumerate_common() - @param flag Bitfield for control purposes - bit0= do not setup spc/sbc/mmc -*/ -int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no, - int channel_no, int target_no, int lun_no, int flag); - - -#endif /*__SPC*/ diff --git a/libburn/structure.c b/libburn/structure.c deleted file mode 100644 index 181c6f8..0000000 --- a/libburn/structure.c +++ /dev/null @@ -1,418 +0,0 @@ - -/* ts A61008 */ -/* #include */ - -#include -#include -#include -#include "libburn.h" -#include "structure.h" -#include "write.h" -#include "debug.h" - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - - -/* ts A61008 : replaced Assert by if and return 0 */ -/* a ssert(!(pos > BURN_POS_END)); */ - -#define RESIZE(TO, NEW, pos) {\ - void *tmp;\ -\ - if (pos > BURN_POS_END)\ - return 0;\ - if (pos == BURN_POS_END)\ - pos = TO->NEW##s;\ - if (pos > TO->NEW##s)\ - return 0;\ -\ - tmp = realloc(TO->NEW, sizeof(struct NEW *) * (TO->NEW##s + 1));\ - if (!tmp)\ - return 0;\ - TO->NEW = tmp;\ - memmove(TO->NEW + pos + 1, TO->NEW + pos,\ - sizeof(struct NEW *) * (TO->NEW##s - pos));\ - TO->NEW##s++;\ -} - -struct burn_disc *burn_disc_create(void) -{ - struct burn_disc *d; - d = calloc(1, sizeof(struct burn_disc)); - d->refcnt = 1; - d->sessions = 0; - d->session = NULL; - return d; -} - -void burn_disc_free(struct burn_disc *d) -{ - d->refcnt--; - if (d->refcnt == 0) { - /* dec refs on all elements */ - int i; - - for (i = 0; i < d->sessions; i++) - burn_session_free(d->session[i]); - free(d->session); - free(d); - } -} - -struct burn_session *burn_session_create(void) -{ - struct burn_session *s; - s = calloc(1, sizeof(struct burn_session)); - s->refcnt = 1; - s->tracks = 0; - s->track = NULL; - s->hidefirst = 0; - return s; -} - -void burn_session_hide_first_track(struct burn_session *s, int onoff) -{ - s->hidefirst = onoff; -} - -void burn_session_free(struct burn_session *s) -{ - s->refcnt--; - if (s->refcnt == 0) { - /* dec refs on all elements */ - int i; - - for (i = 0; i < s->tracks; i++) - burn_track_free(s->track[i]); - free(s->track); - free(s); - } - -} - -int burn_disc_add_session(struct burn_disc *d, struct burn_session *s, - unsigned int pos) -{ - RESIZE(d, session, pos); - d->session[pos] = s; - s->refcnt++; - return 1; -} - -struct burn_track *burn_track_create(void) -{ - struct burn_track *t; - t = calloc(1, sizeof(struct burn_track)); - t->refcnt = 1; - t->indices = 0; - t->offset = 0; - t->offsetcount = 0; - t->tail = 0; - t->tailcount = 0; - t->mode = BURN_MODE1; - t->isrc.has_isrc = 0; - t->pad = 1; - t->entry = NULL; - t->source = NULL; - t->eos = 0; - - /* ts A61101 */ - t->sourcecount = 0; - t->writecount = 0; - t->written_sectors = 0; - - /* ts A61031 */ - t->open_ended = 0; - t->track_data_done = 0; - - t->postgap = 0; - t->pregap1 = 0; - t->pregap2 = 0; - - /* ts A61024 */ - t->swap_source_bytes = 0; - return t; -} - -void burn_track_free(struct burn_track *t) -{ - t->refcnt--; - if (t->refcnt == 0) { - /* dec refs on all elements */ - if (t->source) - burn_source_free(t->source); - free(t); - } -} - -int burn_session_add_track(struct burn_session *s, struct burn_track *t, - unsigned int pos) -{ - RESIZE(s, track, pos); - s->track[pos] = t; - t->refcnt++; - return 1; -} - -int burn_session_remove_track(struct burn_session *s, struct burn_track *t) -{ - struct burn_track **tmp; - int i, pos = -1; - - /* ts A61008 */ - /* a ssert(s->track != NULL); */ - if (s->track == NULL) - return 0; - - burn_track_free(t); - - /* Find the position */ - for (i = 0; i < s->tracks; i++) { - if (t == s->track[i]) { - pos = i; - break; - } - } - - if (pos == -1) - return 0; - - /* Is it the last track? */ - if (pos != s->tracks - 1) { - memmove(&s->track[pos], &s->track[pos + 1], - sizeof(struct burn_track *) * (s->tracks - (pos + 1))); - } - - s->tracks--; - tmp = realloc(s->track, sizeof(struct burn_track *) * s->tracks); - if (tmp) - s->track = tmp; - return 1; -} - -void burn_structure_print_disc(struct burn_disc *d) -{ - int i; - - burn_print(12, "This disc has %d sessions\n", d->sessions); - for (i = 0; i < d->sessions; i++) { - burn_structure_print_session(d->session[i]); - } -} -void burn_structure_print_session(struct burn_session *s) -{ - int i; - - burn_print(12, " Session has %d tracks\n", s->tracks); - for (i = 0; i < s->tracks; i++) { - burn_structure_print_track(s->track[i]); - } -} -void burn_structure_print_track(struct burn_track *t) -{ - burn_print(12, "(%p) track size %d sectors\n", t, - burn_track_get_sectors(t)); -} - -void burn_track_define_data(struct burn_track *t, int offset, int tail, - int pad, int mode) -{ - int type_to_form(int mode, unsigned char *ctladr, int *form); - int burn_sector_length(int tracktype); - unsigned char ctladr; - int form = -1; /* unchanged form will be considered an error too */ - - type_to_form(mode, &ctladr, &form); - if (form == -1 || burn_sector_length(mode) <= 0) { - char msg[160]; - - sprintf(msg, "Attempt to set track mode to unusable value %d", - mode); - libdax_msgs_submit(libdax_messenger, -1, 0x00020115, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); - return; - } - - t->offset = offset; - t->pad = pad; - t->mode = mode; - t->tail = tail; -} - - -/* ts A61024 */ -int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes) -{ - if(swap_source_bytes!=0 && swap_source_bytes!=1) - return 0; - t->swap_source_bytes = swap_source_bytes; - return 1; -} - - -void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, - unsigned char year, unsigned int serial) -{ - int i; - - for (i = 0; i < 2; ++i) { - - /* ts A61008 : This is always true */ - /* a ssert((country[i] >= '0' || country[i] < '9') && - (country[i] >= 'a' || country[i] < 'z') && - (country[i] >= 'A' || country[i] < 'Z')); */ - /* ts A61008 : now coordinated with sector.c: char_to_isrc() */ - if (! ((country[i] >= '0' && country[i] <= '9') || - (country[i] >= 'a' && country[i] <= 'z') || - (country[i] >= 'A' && country[i] <= 'Z') ) ) - goto is_not_allowed; - - t->isrc.country[i] = country[i]; - } - for (i = 0; i < 3; ++i) { - - /* ts A61008 : This is always true */ - /* a ssert((owner[i] >= '0' || owner[i] < '9') && - (owner[i] >= 'a' || owner[i] < 'z') && - (owner[i] >= 'A' || owner[i] < 'Z')); */ - /* ts A61008 : now coordinated with sector.c: char_to_isrc() */ - if (! ((owner[i] >= '0' && owner[i] <= '9') || - (owner[i] >= 'a' && owner[i] <= 'z') || - (owner[i] >= 'A' && owner[i] <= 'Z') ) ) - goto is_not_allowed; - - t->isrc.owner[i] = owner[i]; - } - - /* ts A61008 */ - /* a ssert(year <= 99); */ - if (year > 99) - goto is_not_allowed; - - t->isrc.year = year; - - /* ts A61008 */ - /* a ssert(serial <= 99999); */ - if (serial > 99999) - goto is_not_allowed; - - t->isrc.serial = serial; - - /* ts A61008 */ - t->isrc.has_isrc = 1; - return; -is_not_allowed:; - libdax_msgs_submit(libdax_messenger, -1, 0x00020114, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Attempt to set ISRC with bad data", 0, 0); - return; -} - -void burn_track_clear_isrc(struct burn_track *t) -{ - t->isrc.has_isrc = 0; -} - -int burn_track_get_sectors(struct burn_track *t) -{ - int size; - int sectors, seclen; - - seclen = burn_sector_length(t->mode); - size = t->offset + t->source->get_size(t->source) + t->tail; - sectors = size / seclen; - if (size % seclen) - sectors++; - burn_print(1, "%d sectors of %d length\n", sectors, seclen); - return sectors; -} - -/* ts A61031 */ -int burn_track_is_open_ended(struct burn_track *t) -{ - return !!t->open_ended; -} - -/* ts A61101 : API function */ -int burn_track_get_counters(struct burn_track *t, - off_t *read_bytes, off_t *written_bytes) -{ -/* - fprintf(stderr, "libburn_experimental: sizeof(off_t)=%d\n", - sizeof(off_t)); -*/ - *read_bytes = t->sourcecount; - *written_bytes = t->writecount; - return 1; -} - -/* ts A61031 */ -int burn_track_is_data_done(struct burn_track *t) -{ - return !!t->track_data_done; -} - -int burn_track_get_shortage(struct burn_track *t) -{ - int size; - int seclen; - - seclen = burn_sector_length(t->mode); - size = t->offset + t->source->get_size(t->source) + t->tail; - if (size % seclen) - return seclen - size % seclen; - return 0; -} - -int burn_session_get_sectors(struct burn_session *s) -{ - int sectors = 0, i; - - for (i = 0; i < s->tracks; i++) - sectors += burn_track_get_sectors(s->track[i]); - return sectors; -} - -int burn_disc_get_sectors(struct burn_disc *d) -{ - int sectors = 0, i; - - for (i = 0; i < d->sessions; i++) - sectors += burn_session_get_sectors(d->session[i]); - return sectors; -} - -void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry) -{ - memcpy(entry, t->entry, sizeof(struct burn_toc_entry)); -} - -void burn_session_get_leadout_entry(struct burn_session *s, - struct burn_toc_entry *entry) -{ - memcpy(entry, s->leadout_entry, sizeof(struct burn_toc_entry)); -} - -struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num) -{ - *num = d->sessions; - return d->session; -} - -struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num) -{ - *num = s->tracks; - return s->track; -} - -int burn_track_get_mode(struct burn_track *track) -{ - return track->mode; -} - -int burn_session_get_hidefirst(struct burn_session *session) -{ - return session->hidefirst; -} diff --git a/libburn/structure.h b/libburn/structure.h deleted file mode 100644 index 0eb3b8c..0000000 --- a/libburn/structure.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef BURN__STRUCTURE_H -#define BURN__STRUCTURE_H - -struct isrc -{ - int has_isrc; - char country[2]; /* each must be 0-9, A-Z */ - char owner[3]; /* each must be 0-9, A-Z */ - unsigned char year; /* must be 0-99 */ - unsigned int serial; /* must be 0-99999 */ -}; - -struct burn_track -{ - int refcnt; - struct burn_toc_entry *entry; - unsigned char indices; - /* lba address of the index */ - unsigned int index[99]; - /** number of 0 bytes to write before data */ - int offset; - /** how much offset has been used */ - int offsetcount; - /** Number of zeros to write after data */ - int tail; - /** how much tail has been used */ - int tailcount; - /** 1 means Pad with zeros, 0 means start reading the next track */ - int pad; - /** Data source */ - struct burn_source *source; - /** End of Source flag */ - int eos; - - /* ts A61101 */ - off_t sourcecount; - off_t writecount; - off_t written_sectors; - - /* ts A61031 */ - /** Source is of undefined length */ - int open_ended; - /** End of open ended track flag : offset+payload+tail are delivered */ - int track_data_done; - - /** The audio/data mode for the entry. Derived from control and - possibly from reading the track's first sector. */ - int mode; - /** The track contains interval one of a pregap */ - int pregap1; - /** The track contains interval two of a pregap */ - int pregap2; - /** The track contains a postgap */ - int postgap; - struct isrc isrc; - - /* ts A61024 */ - /** Byte swapping on source data stream : 0=none , 1=pairwise */ - int swap_source_bytes; -}; - -struct burn_session -{ - unsigned char firsttrack; - unsigned char lasttrack; - int hidefirst; - unsigned char start_m; - unsigned char start_s; - unsigned char start_f; - struct burn_toc_entry *leadout_entry; - - int tracks; - struct burn_track **track; - int refcnt; -}; - -struct burn_disc -{ - int sessions; - struct burn_session **session; - int refcnt; -}; - -int burn_track_get_shortage(struct burn_track *t); - - -/* ts A61031 : might go to libburn.h */ -int burn_track_is_open_ended(struct burn_track *t); -int burn_track_is_data_done(struct burn_track *t); - - -#endif /* BURN__STRUCTURE_H */ diff --git a/libburn/toc.c b/libburn/toc.c deleted file mode 100644 index c1c198c..0000000 --- a/libburn/toc.c +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -/* ts A61008 */ -/* #include */ - -#include -#include -#include -#include "toc.h" -#include "transport.h" -#include "libburn.h" -#include "sector.h" -#include "options.h" - -#if 0 -static void write_clonecd2(volatile struct toc *toc, int f); - -static void write_clonecd2(volatile struct toc *toc, int f) -{ - int i; - - /* header */ - dprintf(f, "[CloneCD]\r\n"); - dprintf(f, "Version=2\r\n"); - dprintf(f, "\r\n"); - - /* disc data */ - dprintf(f, "[Disc]\r\n"); - - dprintf(f, "TocEntries=%d\r\n", toc->toc_entries); - dprintf(f, "Sessions=%d\r\n", toc->sessions); - dprintf(f, "DataTracksScrambled=%d\r\n", toc->datatracksscrambled); - dprintf(f, "CDTextLength=%d\r\n", toc->cdtextlength); - dprintf(f, "\r\n"); - - /* session data */ - for (i = 0; i < toc->sessions; ++i) { - dprintf(f, "[Session %d]\r\n", i + 1); - - { - int m; - - switch (toc->session[i].track[0]->mode) { - case BURN_MODE_RAW_DATA: - case BURN_MODE_AUDIO: - m = 0; - break; - case BURN_MODE0: - m = 1; - break; - case BURN_MODE1: - case BURN_MODE2_FORMLESS: - case BURN_MODE2_FORM1: - case BURN_MODE2_FORM2: - case BURN_MODE_UNINITIALIZED: - - /* ts A61008 : do this softly without Assert */ - - a ssert(0); /* unhandled! find out ccd's - value for these modes! */ - } - dprintf(f, "PreGapMode=%d\r\n", m); - } - dprintf(f, "\r\n"); - } - - for (i = 0; i < toc->toc_entries; ++i) { - dprintf(f, "[Entry %d]\r\n", i); - - dprintf(f, "Session=%d\r\n", toc->toc_entry[i].session); - dprintf(f, "Point=0x%02x\r\n", toc->toc_entry[i].point); - dprintf(f, "ADR=0x%02x\r\n", toc->toc_entry[i].adr); - dprintf(f, "Control=0x%02x\r\n", toc->toc_entry[i].control); - dprintf(f, "TrackNo=%d\r\n", toc->toc_entry[i].tno); - dprintf(f, "AMin=%d\r\n", toc->toc_entry[i].min); - dprintf(f, "ASec=%d\r\n", toc->toc_entry[i].sec); - dprintf(f, "AFrame=%d\r\n", toc->toc_entry[i].frame); - dprintf(f, "ALBA=%d\r\n", - burn_msf_to_lba(toc->toc_entry[i].min, - toc->toc_entry[i].sec, - toc->toc_entry[i].frame)); - dprintf(f, "Zero=%d\r\n", toc->toc_entry[i].zero); - dprintf(f, "PMin=%d\r\n", toc->toc_entry[i].pmin); - dprintf(f, "PSec=%d\r\n", toc->toc_entry[i].psec); - dprintf(f, "PFrame=%d\r\n", toc->toc_entry[i].pframe); - dprintf(f, "PLBA=%d\r\n", - burn_msf_to_lba(toc->toc_entry[i].pmin, - toc->toc_entry[i].psec, - toc->toc_entry[i].pframe)); - dprintf(f, "\r\n"); - } -} -#endif - -void toc_find_modes(struct burn_drive *d) -{ - struct burn_read_opts o; - int lba; - int i, j; - struct buffer mem; - struct burn_toc_entry *e; - - /* ts A61008 : to be prevented on the higher levels */ - /* a ssert(d->busy); */ - - mem.bytes = 0; - mem.sectors = 1; - o.raw = 1; - o.c2errors = 0; - o.subcodes_audio = 1; - o.subcodes_data = 1; - o.hardware_error_recovery = 1; - o.report_recovered_errors = 0; - o.transfer_damaged_blocks = 1; - o.hardware_error_retries = 1; - - for (i = 0; i < d->disc->sessions; i++) - for (j = 0; j < d->disc->session[i]->tracks; j++) { - struct burn_track *t = d->disc->session[i]->track[j]; - - e = t->entry; - if (!e) - lba = 0; - else - lba = burn_msf_to_lba(e->pmin, e->psec, - e->pframe); -/* XXX | in the subcodes if appropriate! */ - if (e && !(e->control & 4)) { - t->mode = BURN_AUDIO; - } else { - mem.sectors = 1; - d->read_sectors(d, lba, mem.sectors, &o, &mem); - t->mode = sector_identify(mem.data); - } - } -} diff --git a/libburn/toc.h b/libburn/toc.h deleted file mode 100644 index 1d804e7..0000000 --- a/libburn/toc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __TOC_H -#define __TOC_H - -struct command; - -#include "libburn.h" -#include "structure.h" - -/* return if a given entry refers to a track position */ -#define TOC_ENTRY_IS_TRACK(drive, entrynum) \ - ((drive)->toc_entry[entrynum].point < 100) - -/* return if a given entry is in audio or data format */ -#define TOC_ENTRY_IS_AUDIO(drive, entrynum) \ - (~(drive)->toc_entry[entrynum].control & 4) - -/* return the point value for a given entry number */ -#define TOC_POINT(drive, entrynum) ((drive)->toc_entry[entrynum].point) - -/* return the track struct for a given entry number */ -#define TOC_TRACK(drive, entrynum) \ - ((drive)->track[TOC_POINT(drive, entrynum) - 1]) - -/* return the lba of a toc entry */ -#define TOC_ENTRY_PLBA(drive, entrynum) \ - burn_msf_to_lba((drive)->toc_entry[(entrynum)].pmin, \ - (drive)->toc_entry[(entrynum)].psec, \ - (drive)->toc_entry[(entrynum)].pframe) - -/* flags for the q subchannel control field */ -#define TOC_CONTROL_AUDIO (0) -#define TOC_CONTROL_DATA (1 << 2) -#define TOC_CONTROL_AUDIO_TWO_CHANNELS (0) -#define TOC_CONTROL_AUDIO_FOUR_CHANNELS (1 << 3) -#define TOC_CONTROL_AUDIO_PRE_EMPHASIS (1 << 0) -#define TOC_CONTROL_DATA_RECORDED_UNINTERRUPTED (0) -#define TOC_CONTROL_DATA_RECORDED_INCREMENT (1 << 0) -#define TOC_CONTROL_COPY_PROHIBITED (0) -#define TOC_CONTROL_COPY_PERMITTED (1 << 1) - -/** read a sector from each track on disc to determine modes - @param d The drive. -*/ -void toc_find_modes(struct burn_drive *d); - -#endif /*__TOC_H*/ diff --git a/libburn/transport.h b/libburn/transport.h deleted file mode 100644 index 6f73217..0000000 --- a/libburn/transport.h +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef __TRANSPORT -#define __TRANSPORT - -#include "libburn.h" - -#include -/* sg data structures */ -#include - -#ifdef __FreeBSD__ - -#define BUFFER_SIZE 65536/2 - -#else /* __FreeBSD__ */ - -#define BUFFER_SIZE 65536 - -#endif /* ! __FreeBSD__ */ - -enum transfer_direction -{ TO_DRIVE, FROM_DRIVE, NO_TRANSFER }; - -/* end of sg data structures */ - -/* generic 'drive' data structures */ - -struct cue_sheet -{ - int count; - unsigned char *data; -}; - -struct params -{ - int speed; - int retries; -}; - -struct buffer -{ - unsigned char data[BUFFER_SIZE]; - int sectors; - int bytes; -}; - -struct command -{ - unsigned char opcode[16]; - int oplen; - int dir; - unsigned char sense[128]; - int error; - int retry; - struct buffer *page; -}; - -struct burn_scsi_inquiry_data -{ - char vendor[9]; - char product[17]; - char revision[5]; - int valid; -}; - -struct scsi_mode_data -{ - int buffer_size; - int dvdram_read; - int dvdram_write; - int dvdr_read; - int dvdr_write; - int dvdrom_read; - int cdrw_read; - int cdrw_write; - int cdr_read; - int cdr_write; - int simulate; - int max_read_speed; - int max_write_speed; - - /* ts A61021 */ - int min_write_speed; - - int cur_read_speed; - int cur_write_speed; - int retry_page_length; - int retry_page_valid; - int write_page_length; - int write_page_valid; - int c2_pointers; - int valid; - int underrun_proof; -}; - - -#define LIBBURN_SG_MAX_SIBLINGS 16 - -/** Gets initialized in enumerate_common() and burn_drive_register() */ -struct burn_drive -{ - int bus_no; - int host; - int id; - int channel; - int lun; - char *devname; - -#if defined(__FreeBSD__) - struct cam_device* cam; -#else - int fd; - - /* ts A60926 : trying to lock against growisofs /dev/srN, /dev/scdN */ - int sibling_count; - int sibling_fds[LIBBURN_SG_MAX_SIBLINGS]; -#endif - - /* ts A60904 : ticket 62, contribution by elmom */ - /** - Tells the index in scanned burn_drive_info array. - -1 if fallen victim to burn_drive_info_forget() - */ - int global_index; - - pthread_mutex_t access_lock; - - enum burn_disc_status status; - int erasable; - volatile int released; - - /* ts A61106 */ - int silent_on_scsi_error; - - int nwa; /* next writeable address */ - int alba; /* absolute lba */ - int rlba; /* relative lba in section */ - int start_lba; - int end_lba; - int toc_temp; - struct burn_disc *disc; /* disc structure */ - int block_types[4]; - struct buffer *buffer; - struct burn_progress progress; - - volatile int cancel; - volatile enum burn_drive_status busy; -/* transport functions */ - int (*grab) (struct burn_drive *); - int (*release) (struct burn_drive *); - - /* ts A61021 */ - int (*drive_is_open) (struct burn_drive *); - - int (*issue_command) (struct burn_drive *, struct command *); - -/* lower level functions */ - void (*erase) (struct burn_drive *, int); - void (*getcaps) (struct burn_drive *); - - /* ts A61021 */ - void (*read_atip) (struct burn_drive *); - - int (*write) (struct burn_drive *, int, struct buffer *); - void (*read_toc) (struct burn_drive *); - void (*lock) (struct burn_drive *); - void (*unlock) (struct burn_drive *); - void (*eject) (struct burn_drive *); - void (*load) (struct burn_drive *); - void (*read_disc_info) (struct burn_drive *); - void (*read_sectors) (struct burn_drive *, - int start, - int len, - const struct burn_read_opts *, struct buffer *); - void (*perform_opc) (struct burn_drive *); - void (*set_speed) (struct burn_drive *, int, int); - void (*send_parameters) (struct burn_drive *, - const struct burn_read_opts *); - void (*send_write_parameters) (struct burn_drive *, - const struct burn_write_opts *); - void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *); - void (*sync_cache) (struct burn_drive *); - int (*get_erase_progress) (struct burn_drive *); - int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa); - - /* ts A61009 : removed d in favor of o->drive */ - /* void (*close_disc) (struct burn_drive * d, - struct burn_write_opts * o); - void (*close_session) (struct burn_drive * d, - struct burn_write_opts * o); - */ - void (*close_disc) (struct burn_write_opts * o); - void (*close_session) ( struct burn_write_opts * o); - - /* ts A61029 */ - void (*close_track_session) ( struct burn_drive *d, - int session, int track); - - int (*test_unit_ready) (struct burn_drive * d); - void (*probe_write_modes) (struct burn_drive * d); - struct params params; - struct burn_scsi_inquiry_data *idata; - struct scsi_mode_data *mdata; - int toc_entries; - struct burn_toc_entry *toc_entry; - - /* ts A61023 : get size and free space of drive buffer */ - int (*read_buffer_capacity) (struct burn_drive *d); - -}; - -/* end of generic 'drive' data structures */ - -#endif /* __TRANSPORT */ diff --git a/libburn/util.c b/libburn/util.c deleted file mode 100644 index b759dc3..0000000 --- a/libburn/util.c +++ /dev/null @@ -1,53 +0,0 @@ -#include - -/* ts A61008 */ -/* #include */ - -#include -#include "../version.h" -#include "util.h" -#include "libburn.h" - -char *burn_strdup(char *s) -{ - char *ret; - int l; - - /* ts A61008 */ - /* a ssert(s); */ - if (s == NULL) - return NULL; - - l = strlen(s) + 1; - ret = malloc(l); - memcpy(ret, s, l); - - return ret; -} - -char *burn_strndup(char *s, int n) -{ - char *ret; - int l; - - /* ts A61008 */ - /* a ssert(s); */ - /* a ssert(n > 0); */ - if (s == NULL || n <= 0) - return NULL; - - l = strlen(s); - ret = malloc(l < n ? l : n); - - memcpy(ret, s, l < n - 1 ? l : n - 1); - ret[n - 1] = '\0'; - - return ret; -} - -void burn_version(int *major, int *minor, int *micro) -{ - *major = BURN_MAJOR_VERSION; - *minor = BURN_MINOR_VERSION; - *micro = BURN_MICRO_VERSION; -} diff --git a/libburn/util.h b/libburn/util.h deleted file mode 100644 index 4e74895..0000000 --- a/libburn/util.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __UTIL -#define __UTIL - -char *burn_strdup(char *s); - -char *burn_strndup(char *s, int n); - -#endif diff --git a/libburn/write.c b/libburn/write.c deleted file mode 100644 index 479619d..0000000 --- a/libburn/write.c +++ /dev/null @@ -1,897 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include -#include - -/* ts A61009 */ -/* #include */ - - -/* ts A61106 : Deliberate defect provocation macros - DO NOT DEFINE THESE IF YOU WANT SUCCESSFUL TAO ! -#define Libburn_experimental_no_close_tracK 1 -#define Libburn_experimental_no_close_sessioN 1 -*/ - - -#include -#include -#include -#include -#include "error.h" -#include "sector.h" -#include "libburn.h" -#include "drive.h" -#include "transport.h" -#include "crc.h" -#include "debug.h" -#include "init.h" -#include "lec.h" -#include "toc.h" -#include "util.h" -#include "sg.h" -#include "write.h" -#include "options.h" - -#include "libdax_msgs.h" -extern struct libdax_msgs *libdax_messenger; - - -static int type_to_ctrl(int mode) -{ - int ctrl = 0; - - int data = BURN_MODE2 | BURN_MODE1 | BURN_MODE0; - - if (mode & data) { - ctrl |= 4; - } else if (mode & BURN_AUDIO) { - if (mode & BURN_4CH) - ctrl |= 8; - if (mode & BURN_PREEMPHASIS) - ctrl |= 1; - } else - /* ts A61008 */ - /* a ssert(0); */ - return -1; - - if (mode & BURN_COPY) - ctrl |= 2; - - return ctrl; -} - -/* only the ctrl nibble is set here (not adr) */ -/* ts A61009 : removed "static" , reacted on type_to_ctrl() == -1 - preserved ignorance towards unknown modes (for now) */ -void type_to_form(int mode, unsigned char *ctladr, int *form) -{ - int ret; - - ret = type_to_ctrl(mode) << 4; - if (ret == -1) { - *ctladr = 0xff; - *form = -1; - return; - } - *ctladr = ret; - - if (mode & BURN_AUDIO) - *form = 0; - if (mode & BURN_MODE0) { - - /* ts A61009 */ - /* a ssert(0); */ - *form = -1; - return; - } - - if (mode & BURN_MODE1) - *form = 0x10; - if (mode & BURN_MODE2) { - - /* ts A61009 */ - /* a ssert(0); */ /* XXX someone's gonna want this sometime */ - *form = -1; - return; - } - - if (mode & BURN_MODE_RAW) - *form = 0; - if (mode & BURN_SUBCODE_P16) /* must be expanded to R96 */ - *form |= 0x40; - if (mode & BURN_SUBCODE_P96) - *form |= 0xC0; - if (mode & BURN_SUBCODE_R96) - *form |= 0x40; -} - -int burn_write_flush(struct burn_write_opts *o, struct burn_track *track) -{ - struct burn_drive *d = o->drive; - - if (d->buffer->bytes && !d->cancel) { - int err; - err = d->write(d, d->nwa, d->buffer); - if (err == BE_CANCELLED) - return 0; - /* A61101 */ - if(track != NULL) { - track->writecount += d->buffer->bytes; - track->written_sectors += d->buffer->sectors; - } - - d->nwa += d->buffer->sectors; - d->buffer->bytes = 0; - d->buffer->sectors = 0; - } - d->sync_cache(d); - return 1; -} - - -/* ts A61030 */ -int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s, - int tnum) -{ - char msg[81]; - struct burn_drive *d; - struct burn_track *t; - int todo, step, cancelled, seclen; - - /* ts A61106 */ -#ifdef Libburn_experimental_no_close_tracK - return 1; -#endif - - d = o->drive; - t = s->track[tnum]; - - /* ts A61103 : pad up track to minimum size of 600 sectors */ - if (t->written_sectors < 300) { - todo = 300 - t->written_sectors; - sprintf(msg,"Padding up track to minimum size (+ %d sectors)", - todo); - libdax_msgs_submit(libdax_messenger, o->drive->global_index, - 0x0002011a, - LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); - step = BUFFER_SIZE / 4096; /* shall fit any sector size */ - if (step <= 0) - step = 1; - seclen = burn_sector_length(t->mode); - if (seclen <= 0) - seclen = 2048; - memset(d->buffer, 0, sizeof(struct buffer)); - cancelled = d->cancel; - for (; todo > 0; todo -= step) { - if (step > todo) - step = todo; - d->buffer->bytes = step*seclen; - d->buffer->sectors = step; - d->cancel = 0; - d->write(d, d->nwa, d->buffer); - d->nwa += d->buffer->sectors; - t->writecount += d->buffer->bytes; - t->written_sectors += d->buffer->sectors; - } - d->cancel = cancelled; - } - - /* ts A61102 */ - d->busy = BURN_DRIVE_CLOSING_TRACK; - - sprintf(msg, "Closing track %2.2d", tnum+1); - libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); - - /* MMC-1 mentions track number 0xFF for "the incomplete track", - MMC-3 does not. I tried both. 0xFF was in effect when other - bugs finally gave up and made way for readable tracks. */ - d->close_track_session(o->drive, 0, 0xff); /* tnum+1); */ - - /* ts A61102 */ - d->busy = BURN_DRIVE_WRITING; - - return 1; -} - - -/* ts A61030 */ -int burn_write_close_session(struct burn_write_opts *o, struct burn_session *s) -{ - - /* ts A61106 */ -#ifdef Libburn_experimental_no_close_sessioN - return 1; -#endif - - libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, - "Closing session", 0, 0); - - /* ts A61102 */ - o->drive->busy = BURN_DRIVE_CLOSING_SESSION; - - o->drive->close_track_session(o->drive, 1, 0); - - /* ts A61102 */ - o->drive->busy = BURN_DRIVE_WRITING; - - return 1; -} - - -/* ts A60819: - This is unused since about Feb 2006, icculus.org/burn CVS. - The compiler complains. We shall please our compiler. -*/ -#ifdef Libburn_write_with_function_print_cuE - -static void print_cue(struct cue_sheet *sheet) -{ - int i; - unsigned char *unit; - - printf("\n"); - printf("ctladr|trno|indx|form|scms| msf\n"); - printf("------+----+----+----+----+--------\n"); - for (i = 0; i < sheet->count; i++) { - unit = sheet->data + 8 * i; - printf(" %1X %1X | %02X | %02X | %02X | %02X |", - (unit[0] & 0xf0) >> 4, unit[0] & 0xf, unit[1], unit[2], - unit[3], unit[4]); - printf("%02X:%02X:%02X\n", unit[5], unit[6], unit[7]); - } -} - -#endif /* Libburn_write_with_print_cuE */ - - -/* ts A61009 : changed type from void to int */ -/** @return 1 = success , <=0 failure */ -static int add_cue(struct cue_sheet *sheet, unsigned char ctladr, - unsigned char tno, unsigned char indx, - unsigned char form, unsigned char scms, int lba) -{ - unsigned char *unit; - unsigned char *ptr; - int m, s, f; - - burn_lba_to_msf(lba, &m, &s, &f); - - sheet->count++; - ptr = realloc(sheet->data, sheet->count * 8); - - /* ts A61009 */ - /* a ssert(ptr); */ - if (ptr == NULL) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020111, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Could not allocate new auxiliary object (cue_sheet->data)", - 0, 0); - return -1; - } - - sheet->data = ptr; - unit = sheet->data + (sheet->count - 1) * 8; - unit[0] = ctladr; - unit[1] = tno; - unit[2] = indx; - unit[3] = form; - unit[4] = scms; - unit[5] = m; - unit[6] = s; - unit[7] = f; - return 1; -} - -struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o, - struct burn_session *session) -{ - int i, m, s, f, form, pform, runtime = -150, ret; - unsigned char ctladr; - struct burn_drive *d; - struct burn_toc_entry *e; - struct cue_sheet *sheet; - struct burn_track **tar = session->track; - int ntr = session->tracks; - int rem = 0; - - d = o->drive; - - sheet = malloc(sizeof(struct cue_sheet)); - - /* ts A61009 : react on failures of malloc(), add_cue_sheet() - type_to_form() */ - if (sheet == NULL) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020111, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Could not allocate new auxiliary object (cue_sheet)", - 0, 0); - return NULL; - } - - sheet->data = NULL; - sheet->count = 0; - type_to_form(tar[0]->mode, &ctladr, &form); - if (form == -1) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020116, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Track mode has unusable value", 0, 0); - goto failed; - } - ret = add_cue(sheet, ctladr | 1, 0, 0, 1, 0, runtime); - if (ret <= 0) - goto failed; - ret = add_cue(sheet, ctladr | 1, 1, 0, form, 0, runtime); - if (ret <= 0) - goto failed; - runtime += 150; - - burn_print(1, "toc for %d tracks:\n", ntr); - d->toc_entries = ntr + 3; - - /* ts A61009 */ - /* a ssert(d->toc_entry == NULL); */ - if (d->toc_entry != NULL) { - - /* ts A61109 : this happens with appendable CDs - >>> Open question: is the existing TOC needed ? */ - - /* ts A61109 : for non-SAO, this sheet is thrown away later */ - free((char *) d->toc_entry); - - /* - libdax_msgs_submit(libdax_messenger, - d->global_index, 0x00020117, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "toc_entry of drive is already in use", 0, 0); - goto failed; - */ - } - - d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry)); - e = d->toc_entry; - e[0].point = 0xA0; - if (tar[0]->mode & BURN_AUDIO) - e[0].control = TOC_CONTROL_AUDIO; - else - e[0].control = TOC_CONTROL_DATA; - e[0].pmin = 1; - e[0].psec = o->format; - e[0].adr = 1; - e[1].point = 0xA1; - e[1].pmin = ntr; - e[1].adr = 1; - if (tar[ntr - 1]->mode & BURN_AUDIO) - e[1].control = TOC_CONTROL_AUDIO; - else - e[1].control = TOC_CONTROL_DATA; - e[2].point = 0xA2; - e[2].control = e[1].control; - e[2].adr = 1; - - tar[0]->pregap2 = 1; - pform = form; - for (i = 0; i < ntr; i++) { - type_to_form(tar[i]->mode, &ctladr, &form); - if (pform != form) { - - ret = add_cue(sheet, ctladr | 1, i + 1, 0, form, 0, - runtime); - if (ret <= 0) - goto failed; - - runtime += 150; -/* XXX fix pregap interval 1 for data tracks */ -/* ts A60813 silence righteous compiler warning about C++ style comments - This is possibly not a comment but rather a trace of Derek Foreman - experiments. Thus not to be beautified - but to be preserved rectified. -/ / if (!(form & BURN_AUDIO)) -/ / tar[i]->pregap1 = 1; -*/ - tar[i]->pregap2 = 1; - } -/* XXX HERE IS WHERE WE DO INDICES IN THE CUE SHEET */ -/* XXX and we should make sure the gaps conform to ecma-130... */ - tar[i]->entry = &e[3 + i]; - e[3 + i].point = i + 1; - burn_lba_to_msf(runtime, &m, &s, &f); - e[3 + i].pmin = m; - e[3 + i].psec = s; - e[3 + i].pframe = f; - e[3 + i].adr = 1; - e[3 + i].control = type_to_ctrl(tar[i]->mode); - burn_print(1, "track %d control %d\n", tar[i]->mode, - e[3 + i].control); - - ret = add_cue(sheet, ctladr | 1, i + 1, 1, form, 0, runtime); - if (ret <= 0) - goto failed; - - runtime += burn_track_get_sectors(tar[i]); -/* if we're padding, we'll clear any current shortage. - if we're not, we'll slip toc entries by a sector every time our - shortage is more than a sector -XXX this is untested :) -*/ - if (!tar[i]->pad) { - rem += burn_track_get_shortage(tar[i]); - - /* ts A61101 : I doubt that linking would yield a - desireable effect. With TAO it is - counterproductive in any way. - */ - if (o->write_type == BURN_WRITE_TAO) - tar[i]->source->next = NULL; - else - - if (i +1 != ntr) - tar[i]->source->next = tar[i+1]->source; - } else if (rem) { - rem = 0; - runtime++; - } - if (rem > burn_sector_length(tar[i]->mode)) { - rem -= burn_sector_length(tar[i]->mode); - runtime--; - } - pform = form; - } - burn_lba_to_msf(runtime, &m, &s, &f); - e[2].pmin = m; - e[2].psec = s; - e[2].pframe = f; - burn_print(1, "run time is %d (%d:%d:%d)\n", runtime, m, s, f); - for (i = 0; i < d->toc_entries; i++) - burn_print(1, "point %d (%02d:%02d:%02d)\n", - d->toc_entry[i].point, d->toc_entry[i].pmin, - d->toc_entry[i].psec, d->toc_entry[i].pframe); - ret = add_cue(sheet, ctladr | 1, 0xAA, 1, 1, 0, runtime); - if (ret <= 0) - goto failed; - return sheet; - -failed:; - if (sheet != NULL) - free((char *) sheet); - return NULL; -} - -int burn_sector_length(int tracktype) -{ - if (tracktype & BURN_AUDIO) - return 2352; - if (tracktype & BURN_MODE_RAW) - return 2352; - if (tracktype & BURN_MODE1) - return 2048; - /* ts A61009 */ - /* a ssert(0); */ - return -1; -} - -int burn_subcode_length(int tracktype) -{ - if (tracktype & BURN_SUBCODE_P16) - return 16; - if ((tracktype & BURN_SUBCODE_P96) || (tracktype & BURN_SUBCODE_R96)) - return 96; - return 0; -} - -int burn_write_leadin(struct burn_write_opts *o, - struct burn_session *s, int first) -{ - struct burn_drive *d = o->drive; - int count; - - d->busy = BURN_DRIVE_WRITING_LEADIN; - - burn_print(5, first ? " first leadin\n" : " leadin\n"); - - if (first) - count = 0 - d->alba - 150; - else - count = 4500; - - d->progress.start_sector = d->alba; - d->progress.sectors = count; - d->progress.sector = 0; - - while (count != 0) { - if (!sector_toc(o, s->track[0]->mode)) - return 0; - count--; - d->progress.sector++; - } - d->busy = BURN_DRIVE_WRITING; - return 1; -} - -int burn_write_leadout(struct burn_write_opts *o, - int first, unsigned char control, int mode) -{ - struct burn_drive *d = o->drive; - int count; - - d->busy = BURN_DRIVE_WRITING_LEADOUT; - - d->rlba = -150; - burn_print(5, first ? " first leadout\n" : " leadout\n"); - if (first) - count = 6750; - else - count = 2250; - d->progress.start_sector = d->alba; - d->progress.sectors = count; - d->progress.sector = 0; - - while (count != 0) { - if (!sector_lout(o, control, mode)) - return 0; - count--; - d->progress.sector++; - } - d->busy = BURN_DRIVE_WRITING; - return 1; -} - -int burn_write_session(struct burn_write_opts *o, struct burn_session *s) -{ - struct burn_drive *d = o->drive; - struct burn_track *prev = NULL, *next = NULL; - int i, ret; - - d->rlba = 0; - burn_print(1, " writing a session\n"); - for (i = 0; i < s->tracks; i++) { - if (i > 0) - prev = s->track[i - 1]; - if (i + 1 < s->tracks) - next = s->track[i + 1]; - else - next = NULL; - - if (!burn_write_track(o, s, i)) - { ret = 0; goto ex; } - } - - /* ts A61103 */ - ret = 1; -ex:; - if (o->write_type == BURN_WRITE_TAO) - burn_write_close_session(o, s); - return ret; -} - -int burn_write_track(struct burn_write_opts *o, struct burn_session *s, - int tnum) -{ - struct burn_track *t = s->track[tnum]; - struct burn_drive *d = o->drive; - int i, tmp = 0, open_ended = 0, ret, nwa, lba; - int sectors; - char msg[80]; - - d->rlba = -150; - -/* XXX for tao, we don't want the pregaps but still want post? */ - if (o->write_type != BURN_WRITE_TAO) { - - /* ts A61102 */ - d->busy = BURN_DRIVE_WRITING_PREGAP; - - if (t->pregap1) - d->rlba += 75; - if (t->pregap2) - d->rlba += 150; - - if (t->pregap1) { - struct burn_track *pt = s->track[tnum - 1]; - - if (tnum == 0) { - printf("first track should not have a pregap1\n"); - pt = t; - } - for (i = 0; i < 75; i++) - if (!sector_pregap(o, t->entry->point, - pt->entry->control, pt->mode)) - { ret = 0; goto ex; } - } - if (t->pregap2) - for (i = 0; i < 150; i++) - if (!sector_pregap(o, t->entry->point, - t->entry->control, t->mode)) - { ret = 0; goto ex; } - } else { - o->control = t->entry->control; - d->send_write_parameters(d, o); - - /* ts A61103 */ - ret = d->get_nwa(d, -1, &lba, &nwa); - sprintf(msg, - "pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d\n", - tnum+1, nwa, ret, d->nwa); - libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - msg,0,0); - if (nwa > d->nwa) - d->nwa = nwa; - } - -/* user data */ - - /* ts A61102 */ - d->busy = BURN_DRIVE_WRITING; - - sectors = burn_track_get_sectors(t); - open_ended = burn_track_is_open_ended(t); - - /* Update progress */ - d->progress.start_sector = d->nwa; - d->progress.sectors = sectors; - d->progress.sector = 0; - - /* ts A60831: added tnum-line, extended print message on proposal - by bonfire-app@wanadoo.fr in http://libburn.pykix.org/ticket/58 */ - d->progress.track = tnum; - - burn_print(12, "track %d is %d sectors long\n", tnum, sectors); - - /* ts A61030 : this cannot happen. tnum is alsways < s-tracks */ - if (tnum == s->tracks) - tmp = sectors > 150 ? 150 : sectors; - - for (i = 0; open_ended || i < sectors - tmp; i++) { - - /* ts A61023 : http://libburn.pykix.org/ticket/14 - From time to time inquire drive buffer */ - if ((i%64)==0) - d->read_buffer_capacity(d); - - if (!sector_data(o, t, 0)) - { ret = 0; goto ex; } - - /* ts A61031 */ - if (open_ended) { - d->progress.sectors = sectors = i; - if (burn_track_is_data_done(t)) - break; - } - - /* update current progress */ - d->progress.sector++; - } - for (; i < sectors; i++) { - - /* ts A61030: program execution never gets to this point */ - fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n", - tnum, s->tracks, tmp); - - burn_print(1, "last track, leadout prep\n"); - - /* ts A61023 */ - if ((i%64)==0) - d->read_buffer_capacity(d); - - if (!sector_data(o, t, 1)) - { ret = 0; goto ex; } - - /* update progress */ - d->progress.sector++; - } - - if (t->postgap) - for (i = 0; i < 150; i++) - if (!sector_postgap(o, t->entry->point, t->entry->control, - t->mode)) - { ret = 0; goto ex; } - i = t->offset; - if (o->write_type == BURN_WRITE_SAO) { - if (d->buffer->bytes) { - int err; - err = d->write(d, d->nwa, d->buffer); - if (err == BE_CANCELLED) - { ret = 0; goto ex; } - - /* A61101 : probably this is not all payload data */ - /* A61108 : but audio count is short without this */ - t->writecount += d->buffer->bytes; - - d->nwa += d->buffer->sectors; - d->buffer->bytes = 0; - d->buffer->sectors = 0; - } - } - - /* ts A61103 */ - ret = 1; -ex:; - if (o->write_type == BURN_WRITE_TAO) { - - /* ts A61103 */ - /* >>> if cancelled: ensure that at least 600 kB get written */ - - if (!burn_write_flush(o, t)) - ret = 0; - - /* ts A61030 */ - if (burn_write_close_track(o, s, tnum) <= 0) - ret = 0; - } - return ret; -} - -/* ts A61009 */ -int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc) -{ - int i, t; - char msg[80]; - - for (i = 0; i < disc->sessions; i++) - for (t = 0; t < disc->session[i]->tracks; t++) - if (!sector_headers_is_ok( - o, disc->session[i]->track[t]->mode)) - goto bad_track_mode_found; - return 1; -bad_track_mode_found:; - sprintf(msg, "Unsuitable track mode 0x%x in track %d of session %d", - disc->session[i]->track[t]->mode, i+1, t+1); - libdax_msgs_submit(libdax_messenger, -1, 0x0002010a, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - msg, 0, 0); - return 0; -} - -void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc) -{ - struct cue_sheet *sheet; - struct burn_drive *d = o->drive; - struct buffer buf; - struct burn_track *lt; - int first = 1, i, ret, lba, nwa; - char msg[80]; - -/* ts A60924 : libburn/message.c gets obsoleted - burn_message_clear_queue(); -*/ - - burn_print(1, "sync write of %d sessions\n", disc->sessions); - d->buffer = &buf; - memset(d->buffer, 0, sizeof(struct buffer)); - - d->rlba = -150; - - d->toc_temp = 9; - -/* Apparently some drives require this command to be sent, and a few drives -return crap. so we send the command, then ignore the result. -*/ - /* ts A61107 : moved up send_write_parameters because LG GSA-4082B - seems to dislike get_nwa() in advance */ - d->alba = d->start_lba; - d->nwa = d->alba; - if (o->write_type == BURN_WRITE_TAO) { - nwa = 0; /* get_nwa() will be called in burn_track() */ - } else { - - d->send_write_parameters(d, o); - - ret = d->get_nwa(d, -1, &lba, &nwa); - sprintf(msg, "Inquired nwa: %d (ret=%d)", nwa, ret); - libdax_msgs_submit(libdax_messenger, d->global_index, - 0x00000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - msg,0,0); - } - - /* init progress before showing the state */ - d->progress.session = 0; - d->progress.sessions = disc->sessions; - d->progress.track = 0; - d->progress.tracks = disc->session[0]->tracks; - /* TODO: handle indices */ - d->progress.index = 0; - d->progress.indices = disc->session[0]->track[0]->indices; - /* TODO: handle multissession discs */ - /* XXX: sectors are only set during write track */ - d->progress.start_sector = 0; - d->progress.sectors = 0; - d->progress.sector = 0; - - /* ts A61023 */ - d->progress.buffer_capacity = 0; - d->progress.buffer_available = 0; - - d->busy = BURN_DRIVE_WRITING; - - for (i = 0; i < disc->sessions; i++) { - /* update progress */ - d->progress.session = i; - d->progress.tracks = disc->session[i]->tracks; - - sheet = burn_create_toc_entries(o, disc->session[i]); - - /* ts A61009 */ - if (sheet == NULL) - goto fail; - -/* print_cue(sheet);*/ - if (o->write_type == BURN_WRITE_SAO) - d->send_cue_sheet(d, sheet); - free(sheet); - - if (o->write_type == BURN_WRITE_RAW) { - if (!burn_write_leadin(o, disc->session[i], first)) - goto fail; - } else { - if (first) { - - /* ts A61030 : 0 made the burner take data. */ - /* ts A61103 : Meanwhile d->nwa is updated in - burn_write_track() */ - if(o->write_type == BURN_WRITE_TAO) { - d->nwa= d->alba = 0; - } else { - - d->nwa = -150; - d->alba = -150; - - } - - } else { - d->nwa += 4500; - d->alba += 4500; - } - } - if (!burn_write_session(o, disc->session[i])) - goto fail; - - lt = disc->session[i]->track[disc->session[i]->tracks - 1]; - if (o->write_type == BURN_WRITE_RAW) { - if (!burn_write_leadout(o, first, lt->entry->control, - lt->mode)) - goto fail; - } else { - - /* ts A61030 */ - if (o->write_type != BURN_WRITE_TAO) - - if (!burn_write_flush(o, NULL)) - goto fail; - - d->nwa += first ? 6750 : 2250; - d->alba += first ? 6750 : 2250; - } - if (first) - first = 0; - - /* XXX: currently signs an end of session */ - d->progress.sector = 0; - d->progress.start_sector = 0; - d->progress.sectors = 0; - } - - /* ts A61030: extended skipping of flush to TAO: session is closed */ - if (o->write_type != BURN_WRITE_SAO && o->write_type != BURN_WRITE_TAO) - if (!burn_write_flush(o, NULL)) - goto fail; - - sleep(1); - - burn_print(1, "done\n"); - d->busy = BURN_DRIVE_IDLE; - - /* ts A61012 : This return was traditionally missing. I suspect this - to have caused Cdrskin_eject() failures */ - return; - -fail: - d->sync_cache(d); - burn_print(1, "done - failed\n"); - libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Burn run failed", 0, 0); - d->busy = BURN_DRIVE_IDLE; -} diff --git a/libburn/write.h b/libburn/write.h deleted file mode 100644 index 8ef9562..0000000 --- a/libburn/write.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#ifndef BURN__WRITE_H -#define BURN__WRITE_H - -struct cue_sheet; -struct burn_session; -struct burn_write_opts; -struct burn_disc; - -struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o, - struct burn_session *session); -int burn_sector_length(int trackmode); -int burn_subcode_length(int trackmode); - -/* ts A61009 */ -int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc); - -void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc); -int burn_write_leadin(struct burn_write_opts *o, - struct burn_session *s, int first); -int burn_write_leadout(struct burn_write_opts *o, - int first, unsigned char control, int mode); -int burn_write_session(struct burn_write_opts *o, struct burn_session *s); -int burn_write_track(struct burn_write_opts *o, struct burn_session *s, - int tnum); -int burn_write_flush(struct burn_write_opts *o, struct burn_track *track); - -/* ts A61030 : necessary for TAO */ -int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s, - int tnum); -int burn_write_close_session(struct burn_write_opts *o,struct burn_session *s); - -#endif /* BURN__WRITE_H */ diff --git a/test/burn.c b/test/burn.c deleted file mode 100644 index a46866d..0000000 --- a/test/burn.c +++ /dev/null @@ -1,4 +0,0 @@ -int main() -{ - return 0; -} diff --git a/test/dewav.c b/test/dewav.c deleted file mode 100644 index 6166bc3..0000000 --- a/test/dewav.c +++ /dev/null @@ -1,215 +0,0 @@ - -/* dewav - Demo of libburn extension libdax_audioxtr - Audio track data extraction facility of libdax and libburn. - Copyright (C) 2006 Thomas Schmitt , provided under GPL -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* libdax_audioxtr is quite independent of libburn. It only needs - the messaging facility libdax_msgs. So we got two build variations: -*/ -#ifdef Dewav_without_libburN - -/* This build environment is standalone relying only on libdax components */ -#include "../libburn/libdax_msgs.h" -struct libdax_msgs *libdax_messenger= NULL; - -#else /* Dewav_without_libburN */ - -/* This build environment uses libdax_msgs via libburn */ -/* Thus the API header of libburn */ -#include "../libburn/libburn.h" - -#endif /* ! Dewav_without_libburN */ - - -/* The API for .wav extraction */ -#include "../libburn/libdax_audioxtr.h" - - -int main(int argc, char **argv) -{ - /* This program acts as filter from in_path to out_path */ - char *in_path= "", *out_path= "-"; - - /* The read-and-extract object for use with in_path */ - struct libdax_audioxtr *xtr= NULL; - /* The file descriptor eventually detached from xtr */ - int xtr_fd= -2; - - /* Default output is stdout */ - int out_fd= 1; - - /* Inquired source parameters */ - char *fmt, *fmt_info; - int num_channels, sample_rate, bits_per_sample, msb_first; - off_t data_size; - - /* Auxiliary variables */ - int ret, i, be_strict= 1, buf_count, detach_fd= 0, extract_all= 0; - char buf[2048]; - - if(argc < 2) - goto help; - for(i= 1; i=argc-1) { - fprintf(stderr,"%s: option -o needs a file address as argument.\n", - argv[0]); - exit(1); - } - i++; - out_path= argv[i]; - } else if(strcmp(argv[i],"--lax")==0) { - be_strict= 0; - } else if(strcmp(argv[i],"--strict")==0) { - be_strict= 1; - } else if(strcmp(argv[i],"--detach_fd")==0) { - /* Test the dirty detach method. Always --extract_all */ - detach_fd= 1; - } else if(strcmp(argv[i],"--extract_all")==0) { - /* Dirty : read all available bytes regardless of data_size */ - extract_all= 1; - } else if(strcmp(argv[i],"--help")==0) { -help:; - fprintf(stderr, - "usage: %s [-o output_path|\"-\"] [--lax|--strict] [source_path|\"-\"]\n", - argv[0]); - exit(0); - } else { - if(in_path[0]!=0) { - fprintf(stderr,"%s: only one input file is allowed.\n", argv[0]); - exit(2); - } - in_path= argv[i]; - } - } - if(in_path[0] == 0) - in_path= "-"; - - -/* Depending on wether this was built standalone or with full libburn : -*/ -#ifdef Dewav_without_libburN - - /* Initialize and set up libdax messaging system */ - ret= libdax_msgs_new(&libdax_messenger,0); - if(ret<=0) { - fprintf(stderr,"Failed to create libdax_messenger object.\n"); - exit(3); - } - libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER, - LIBDAX_MSGS_SEV_NOTE, "", 0); - fprintf(stderr, "dewav on libdax\n"); - -#else /* Dewav_without_libburN */ - - /* Initialize libburn and set up its messaging system */ - if(burn_initialize() == 0) { - fprintf(stderr,"Failed to initialize libburn.\n"); - exit(3); - } - /* Print messages of severity NOTE or more directly to stderr */ - burn_msgs_set_severities("NEVER", "NOTE", ""); - fprintf(stderr, "dewav on libburn\n"); - -#endif /* ! Dewav_without_libburN */ - - - /* Open audio source and create extractor object */ - ret= libdax_audioxtr_new(&xtr, in_path, 0); - if(ret<=0) - exit(4); - if(strcmp(out_path,"-")!=0) { - out_fd= open(out_path, O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - if(out_fd == -1) { - fprintf(stderr, "Cannot open file: %s\n", out_path); - fprintf(stderr, "Error reported: '%s' (%d)\n",strerror(errno), errno); - exit(5); - } - } - /* Obtain and print parameters of audio source */ - libdax_audioxtr_get_id(xtr, &fmt, &fmt_info, - &num_channels, &sample_rate, &bits_per_sample, &msb_first, 0); - fprintf(stderr, "Detected format: %s\n", fmt_info); - libdax_audioxtr_get_size(xtr, &data_size, 0); - fprintf(stderr, "Data size : %.f bytes\n", (double) data_size); - if((strcmp(fmt,".wav")!=0 && strcmp(fmt,".au")!=0) || - num_channels!=2 || sample_rate!=44100 || bits_per_sample!=16) { - fprintf(stderr, - "%sAudio source parameters do not comply to cdrskin/README specs\n", - (be_strict ? "" : "WARNING: ")); - if(be_strict) - exit(6); - } - if(msb_first==0) - fprintf(stderr, - "NOTE: Extracted data to be written with cdrskin option -swab\n"); - - if(detach_fd) { - /* Take over fd from xtr */; - ret= libdax_audioxtr_detach_fd(xtr, &xtr_fd, 0); - if(ret<=0) { - fprintf(stderr, "Cannot detach file descriptor from extractor\n"); - exit(8); - } - /* not needed any more */ - libdax_audioxtr_destroy(&xtr, 0); - fprintf(stderr, "Note: detached fd and freed extractor object.\n"); - } - - /* Extract and put out raw audio data */; - while(1) { - if(detach_fd) { - buf_count= read(xtr_fd, buf, sizeof(buf)); - if(buf_count==-1) - fprintf(stderr,"Error while reading from detached fd\n(%d) '%s'\n", - errno, strerror(errno)); - } else { - buf_count= libdax_audioxtr_read(xtr, buf, sizeof(buf), !!extract_all); - } - if(buf_count < 0) - exit(7); - if(buf_count == 0) - break; - - ret= write(out_fd, buf, buf_count); - if(ret == -1) { - fprintf(stderr, "Failed to write buffer of %d bytes to: %s\n", - buf_count, out_path); - fprintf(stderr, "Error reported: '%s' (%d)\n", strerror(errno), errno); - exit(5); - } - - } - - /* Shutdown */ - if(out_fd>2) - close(out_fd); - /* ( It is permissible to do this with xtr==NULL ) */ - libdax_audioxtr_destroy(&xtr, 0); - -#ifdef Dewav_without_libburN - - libdax_msgs_destroy(&libdax_messenger,0); - -#else /* Dewav_without_libburN */ - - burn_finish(); - -#endif /* ! Dewav_without_libburN */ - - exit(0); -} diff --git a/test/fake_au.c b/test/fake_au.c deleted file mode 100644 index 01d7a41..0000000 --- a/test/fake_au.c +++ /dev/null @@ -1,164 +0,0 @@ - -/* fake_au - Fakes a file in SUN .au format from a raw little-endian PCM audio file - (e.g. a file extracted from .wav by test/dewav). The input data are assumed - to be 16 bit, stereo, 44100 Hz. - Copyright (C) 2006 Thomas Schmitt , provided under GPL - - Info used: http://www.opengroup.org/public/pubs/external/auformat.html -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int fake_write(unsigned char *buf, size_t size, FILE *fp) -{ - int ret; - - ret= fwrite(buf,size,1,fp); - if(ret==1) - return(1); - fprintf(stderr,"Error %d while writing: '%s'\n",errno,strerror(errno)); - return(0); -} - - -int main(int argc, char **argv) -{ - int ret, i; - unsigned data_size= 0,byte_count,exit_value= 0; - FILE *fp_out= stdout,*fp_in= stdin; - unsigned char buf[4]; - char out_path[4096],in_path[4096]; - struct stat stbuf; - - strcpy(out_path,"-"); - strcpy(in_path,""); - if(argc < 2) { - exit_value= 1; - goto help; - } - for(i= 1; i=argc-1) { - fprintf(stderr,"%s: option -o needs a file address as argument.\n", - argv[0]); - exit(1); - } - i++; - strcpy(out_path, argv[i]); - } else if(strcmp(argv[i],"--stdin_size")==0) { - if(i>=argc-1) { - fprintf(stderr,"%s: option --stdin_size needs a number as argument.\n", - argv[0]); - exit(1); - } - i++; - sscanf(argv[i],"%u",&data_size); - } else if(strcmp(argv[i],"--help")==0) { - exit_value= 0; -help:; - fprintf(stderr,"usage: %s \\\n", argv[0]); - fprintf(stderr," [-o output_path|\"-\"] [source_path | --stdin_size size]\n"); - fprintf(stderr, - "Disguises an extracted .wav stream as .au stereo, 16bit, 44100Hz\n"); - fprintf(stderr, - "stdin gets byte-swapped and appended up to the announced data_size.\n"); - exit(exit_value); - } else { - if(in_path[0]!=0) { - fprintf(stderr,"%s: only one input file is allowed.\n", argv[0]); - exit(1); - } - strcpy(in_path, argv[i]); - } - } - - if(strcmp(in_path,"-")==0 || in_path[0]==0) { - if(data_size==0) { - fprintf(stderr,"%s: input from stdin needs option --stdin_size.\n", - argv[0]); - exit(6); - } - fp_in= stdin; - } else { - fp_in= fopen(in_path,"r"); - if(stat(in_path,&stbuf)!=-1) - data_size= stbuf.st_size; - } - if(fp_in==NULL) { - fprintf(stderr,"Error %d while fopen(\"%s\",\"r\") : '%s'\n", - errno,in_path,strerror(errno)); - exit(2); - } - - if(strcmp(out_path,"-")==0) { - fp_out= stdout; - } else { - if(stat(out_path,&stbuf)!=-1) { - fprintf(stderr,"%s: file '%s' already existing\n",argv[0],out_path); - exit(4); - } - fp_out= fopen(out_path,"w"); - } - if(fp_out==NULL) { - fprintf(stderr,"Error %d while fopen(\"%s\",\"w\") : '%s'\n", - errno,out_path,strerror(errno)); - exit(2); - } - - fake_write((unsigned char *) ".snd",4,fp_out); /* magic number */ - buf[0]= buf[1]= buf[2]= 0; - buf[3]= 32; - fake_write(buf,4,fp_out); /* data_location */ - buf[0]= (data_size>>24)&0xff; - buf[1]= (data_size>>16)&0xff; - buf[2]= (data_size>>8)&0xff; - buf[3]= (data_size)&0xff; - fake_write(buf,4,fp_out); /* data_size */ - buf[0]= buf[1]= buf[2]= 0; - buf[3]= 3; - fake_write(buf,4,fp_out); /* encoding 16 Bit PCM */ - buf[0]= buf[1]= 0; - buf[2]= 172; - buf[3]= 68; - fake_write(buf,4,fp_out); /* sample rate 44100 Hz */ - buf[0]= buf[1]= buf[2]= 0; - buf[3]= 2; - fake_write(buf,4,fp_out); /* number of channels */ - buf[0]= buf[1]= buf[2]= buf[3]= 0; - fake_write(buf,4,fp_out); /* padding */ - fake_write(buf,4,fp_out); /* padding */ - - for(byte_count= 0; byte_count */ -/* Provided under GPL, see also "License and copyright aspects" at file end */ - - -/** Overview - - libburner is a minimal demo application for the library libburn as provided - on http://libburn.pykix.org . It can list the available devices, can - blank a CD-RW and can burn to CD-R or CD-RW. - It's main purpose, nevertheless, is to show you how to use libburn and also - to serve the libburn team as reference application. libburner.c does indeed - define the standard way how above three gestures can be implemented and - stay upward compatible for a good while. - - Before you can do anything, you have to initialize libburn by - burn_initialize() - and provide some signal and abort handling, e.g. by the builtin handler, by - burn_set_signal_handling() - as it is done in main() at the end of this file. Then you aquire a - drive in an appropriate way conforming to the API. The two main - approaches are shown here in application functions: - libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions - libburner_aquire_by_driveno() demonstrates a scan-and-choose approach - With that aquired drive you can blank a CD-RW - libburner_blank_disc() - Between blanking and burning one eventually has to reload the drive status - libburner_regrab() - With the aquired drive you can burn to CD-R or blank CD-RW - libburner_payload() - When everything is done, main() releases the drive and shuts down libburn: - burn_drive_release(); - burn_finish() - -*/ - -/** See this for the decisive API specs . libburn.h is The Original */ -/* For using the installed header file : #include */ -/* This program insists in the own headerfile. */ -#include "../libburn/libburn.h" - -/* libburn is intended for Linux systems with kernel 2.4 or 2.6 for now */ -#include -#include -#include -#include -#include -#include -#include -#include - - -/** For simplicity i use global variables to represent the drives. - Drives are systemwide global, so we do not give away much of good style. -*/ - -/** This list will hold the drives known to libburn. This might be all CD - drives of the system and thus might impose severe impact on the system. -*/ -static struct burn_drive_info *drive_list; - -/** If you start a long lasting operation with drive_count > 1 then you are - not friendly to the users of other drives on those systems. Beware. */ -static unsigned int drive_count; - -/** This variable indicates wether the drive is grabbed and must be - finally released */ -static int drive_is_grabbed = 0; - - -/* Some in-advance definitions to allow a more comprehensive ordering - of the functions and their explanations in here */ -int libburner_aquire_by_adr(char *drive_adr); -int libburner_aquire_by_driveno(int *drive_no); - - -/* ------------------------------- API gestures ---------------------------- */ - -/** You need to aquire a drive before burning. The API offers this as one - compact call and alternatively as application controllable gestures of - whitelisting, scanning for drives and finally grabbing one of them. - - If you have a persistent address of the drive, then the compact call is - to prefer because it only touches one drive. On modern Linux kernels, - there should be no fatal disturbance of ongoing burns of other libburn - instances with any of our approaches. We use open(O_EXCL) by default. - On /dev/hdX it should cooperate with growisofs and some cdrecord variants. - On /dev/sgN versus /dev/scdM expect it not to respect other programs. -*/ -int libburner_aquire_drive(char *drive_adr, int *driveno) -{ - int ret; - - if(drive_adr != NULL && drive_adr[0] != 0) - ret = libburner_aquire_by_adr(drive_adr); - else - ret = libburner_aquire_by_driveno(driveno); - return ret; -} - - -/** If the persistent drive address is known, then this approach is much - more un-obtrusive to the systemwide livestock of drives. Only the - given drive device will be opened during this procedure. -*/ -int libburner_aquire_by_adr(char *drive_adr) -{ - int ret; - - printf("Aquiring drive '%s' ...\n",drive_adr); - ret = burn_drive_scan_and_grab(&drive_list,drive_adr,1); - if (ret <= 0) { - fprintf(stderr,"FAILURE with persistent drive address '%s'\n", - drive_adr); - if (strncmp(drive_adr,"/dev/sg",7) != 0 && - strncmp(drive_adr,"/dev/hd",7) != 0) - fprintf(stderr,"\nHINT: Consider addresses like '/dev/hdc' or '/dev/sg0'\n"); - } else { - printf("Done\n"); - drive_is_grabbed = 1; - } - return ret; -} - - -/** This method demonstrates how to use libburn without knowing a persistent - drive address in advance. It has to make sure that after assessing the list - of available drives, all unwanted drives get closed again. As long as they - are open, no other libburn instance can see them. This is an intended - locking feature. The application is responsible for giving up the locks - by either burn_drive_release() (only after burn_drive_grab() !), - burn_drive_info_forget(), burn_drive_info_free(), or burn_finish(). - @param driveno the index number in libburn's drive list. This will get - set to 0 on success and will then be the drive index to - use in the further dourse of processing. - @return 1 success , <= 0 failure -*/ -int libburner_aquire_by_driveno(int *driveno) -{ - char adr[BURN_DRIVE_ADR_LEN]; - int ret, i; - - printf("Beginning to scan for devices ...\n"); - while (!burn_drive_scan(&drive_list, &drive_count)) - usleep(1002); - if (drive_count <= 0 && *driveno >= 0) { - printf("FAILED (no drives found)\n"); - return 0; - } - printf("Done\n"); - - /* - Interactive programs may choose the drive number at this moment. - - drive[0] to drive[drive_count-1] are struct burn_drive_info - as defined in libburn/libburn.h . This structure is part of API - and thus will strive for future compatibility on source level. - Have a look at the info offered. - Caution: do not take .location for drive address. Always use - burn_drive_get_adr() or you might become incompatible - in future. - Note: bugs with struct burn_drive_info - if any - will not be - easy to fix. Please report them but also strive for - workarounds on application level. - */ - printf("\nOverview of accessible drives (%d found) :\n", - drive_count); - printf("-----------------------------------------------------------------------------\n"); - for (i = 0; i < drive_count; i++) { - if (burn_drive_get_adr(&(drive_list[i]), adr) <=0) - strcpy(adr, "-get_adr_failed-"); - printf("%d --drive '%s' : '%s' '%s'\n", - i,adr,drive_list[i].vendor,drive_list[i].product); - } - printf("-----------------------------------------------------------------------------\n\n"); - - - /* - On multi-drive systems save yourself from sysadmins' revenge. - - Be aware that you hold reserved all available drives at this point. - So either make your choice quick enough not to annoy other system - users, or set free the drives for a while. - - The tested way of setting free all drives is to shutdown the library - and to restart when the choice has been made. The list of selectable - drives should also hold persistent drive addresses as obtained - above by burn_drive_get_adr(). By such an address one may use - burn_drive_scan_and_grab() to finally aquire exactly one drive. - - A not yet tested shortcut should be to call burn_drive_info_free() - and to call either burn_drive_scan() or burn_drive_scan_and_grab() - before accessing any drives again. - - In both cases you have to be aware that the desired drive might get - aquired in the meantime by another user resp. libburn process. - */ - - /* We already made our choice via command line. (default is 0) - So we just have to keep our desired drive and drop all others. - No other libburn instance will have a chance to steal our drive. - */ - if (*driveno < 0) { - printf("Pseudo-drive \"-\" given : bus scanning done.\n"); - return 2; /* the program will end after this */ - } - if (drive_count <= *driveno) { - fprintf(stderr, - "Found only %d drives. Number %d not available.\n", - drive_count, *driveno); - return 0; /* the program will end after this */ - } - - /* Drop all drives which we do not want to use */ - for (i = 0; i < drive_count; i++) { - if (i == *driveno) /* the one drive we want to keep */ - continue; - ret = burn_drive_info_forget(&(drive_list[i]),0); - if (ret != 1) - fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n", - i, ret); - else - printf("Dropped unwanted drive %d\n",i); - } - /* Make the one we want ready for blanking or burning */ - ret= burn_drive_grab(drive_list[*driveno].drive, 1); - if (ret != 1) - return 0; - drive_is_grabbed = 1; - return 1; -} - - -/** Makes a previously used CD-RW ready for thorough re-usal. - - To our knowledge it is hardly possible to abort an ongoing blank operation - because after start it is entirely handled by the drive. - So expect signal handling to wait the normal blanking timespan until it - can allow the process to end. External kill -9 will not help the drive. -*/ -int libburner_blank_disc(struct burn_drive *drive, int blank_fast) -{ - enum burn_disc_status disc_state; - struct burn_progress p; - int percent = 1; - - while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE) - usleep(1001); - - while ((disc_state = burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(1001); - printf( - "Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n", - disc_state); - if (disc_state == BURN_DISC_BLANK) { - fprintf(stderr, - "IDLE: Blank CD media detected. Will leave it untouched\n"); - return 2; - } else if (disc_state == BURN_DISC_FULL || - disc_state == BURN_DISC_APPENDABLE) { - ; /* this is what libburn is willing to blank */ - } else if (disc_state == BURN_DISC_EMPTY) { - fprintf(stderr,"FATAL: No media detected in drive\n"); - return 0; - } else { - fprintf(stderr, - "FATAL: Cannot recognize drive and media state\n"); - return 0; - } - if(!burn_disc_erasable(drive)) { - fprintf(stderr, - "FATAL : Media is not of erasable type\n"); - return 0; - } - printf( - "Beginning to %s-blank CD media.\n", (blank_fast?"fast":"full")); - burn_disc_erase(drive, blank_fast); - sleep(1); - while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { - if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ - percent = 1.0 + ((double) p.sector+1.0) - / ((double) p.sectors) * 98.0; - printf("Blanking ( %d%% done )\n", percent); - sleep(1); - } - printf("Done\n"); - return 1; -} - - -/** This gesture is necessary to get the drive info after blanking. - It opens a small gap for losing the drive to another libburn instance. - We will work on closing this gap. -*/ -int libburner_regrab(struct burn_drive *drive) { - int ret; - - printf("Releasing and regrabbing drive ...\n"); - if (drive_is_grabbed) - burn_drive_release(drive, 0); - drive_is_grabbed = 0; - ret = burn_drive_grab(drive, 0); - if (ret != 0) { - drive_is_grabbed = 1; - printf("Done\n"); - } else - printf("FAILED\n"); - return !!ret; -} - - -/** Brings preformatted track images (ISO 9660, audio, ...) onto media. - To make sure a data image is fully readable on any Linux machine, this - function adds 300 kB of padding to the (usualy single) track. - Audio tracks get padded to complete their last sector. - - In case of external signals expect abort handling of an ongoing burn to - last up to a minute. Wait the normal burning timespan before any kill -9. -*/ -int libburner_payload(struct burn_drive *drive, - char source_adr[][4096], int source_adr_count, - off_t stdin_size, int simulate_burn, int all_tracks_type) -{ - struct burn_source *data_src; - struct burn_disc *target_disc; - struct burn_session *session; - struct burn_write_opts *burn_options; - enum burn_disc_status disc_state; - struct burn_track *track, *tracklist[99]; - struct burn_progress progress; - time_t start_time; - int last_sector = 0, padding = 0, trackno; - char *adr; - - if (all_tracks_type != BURN_AUDIO) { - all_tracks_type = BURN_MODE1; - /* a padding of 300 kB helps to avoid the read-ahead bug */ - padding = 300*1024; - } - - target_disc = burn_disc_create(); - session = burn_session_create(); - burn_disc_add_session(target_disc, session, BURN_POS_END); - - for (trackno = 0 ; trackno < source_adr_count; trackno++) { - tracklist[trackno] = track = burn_track_create(); - burn_track_define_data(track, 0, padding, 1, all_tracks_type); - - adr = source_adr[trackno]; - if (adr[0] == '-' && adr[1] == 0) { - data_src = burn_fd_source_new(0, -1, stdin_size); - printf("Note: using standard input as source with %.f bytes\n", - (double) stdin_size); - } else - data_src = burn_file_source_new(adr, NULL); - if (data_src == NULL) { - fprintf(stderr, - "FATAL: Could not open data source '%s'.\n",adr); - if(errno!=0) - fprintf(stderr,"(Most recent system error: %s )\n", - strerror(errno)); - return 0; - } - if (burn_track_set_source(track, data_src) != BURN_SOURCE_OK) { - printf("FATAL: Cannot attach source object to track object\n"); - return 0; - } - - burn_session_add_track(session, track, BURN_POS_END); - printf("Track %d : source is '%s'\n", trackno, adr); - burn_source_free(data_src); - } /* trackno loop end */ - - while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE) - usleep(100001); - - /* Evaluate drive and media */ - while ((disc_state = burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(100001); - if (disc_state != BURN_DISC_BLANK) { - if (disc_state == BURN_DISC_FULL || - disc_state == BURN_DISC_APPENDABLE) { - fprintf(stderr, - "FATAL: Media with data detected. Need blank media.\n"); - if (burn_disc_erasable(drive)) - fprintf(stderr, "HINT: Try --blank_fast\n\n"); - } else if (disc_state == BURN_DISC_EMPTY) - fprintf(stderr,"FATAL: No media detected in drive\n"); - else - fprintf(stderr, - "FATAL: Cannot recognize drive and media state\n"); - return 0; - } - - burn_options = burn_write_opts_new(drive); - burn_write_opts_set_perform_opc(burn_options, 0); - -#ifdef Libburner_raw_mode_which_i_do_not_likE - /* This yields higher CD capacity but hampers my IDE controller - with burning on one drive and reading on another simultaneously. - My burner does not obey the order --try_to_simulate in this mode. - */ - burn_write_opts_set_write_type(burn_options, - BURN_WRITE_RAW, BURN_BLOCK_RAW96R); -#else - - /* This is by what cdrskin competes with cdrecord -sao which - i understand is the mode preferrably advised by Joerg Schilling */ - burn_write_opts_set_write_type(burn_options, - BURN_WRITE_SAO, BURN_BLOCK_SAO); - -#endif - if(simulate_burn) - printf("\n*** Will TRY to SIMULATE burning ***\n\n"); - burn_write_opts_set_simulate(burn_options, simulate_burn); - burn_structure_print_disc(target_disc); - burn_drive_set_speed(drive, 0, 0); - burn_write_opts_set_underrun_proof(burn_options, 1); - - printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n"); - start_time = time(0); - burn_disc_write(burn_options, target_disc); - - burn_write_opts_free(burn_options); - while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) - usleep(1002); - while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { - if( progress.sectors <= 0 || progress.sector == last_sector) - printf( - "Thank you for being patient since %d seconds.\n", - (int) (time(0) - start_time)); - else - printf("Track %d : sector %d of %d\n", progress.track, - progress.sector, progress.sectors); - last_sector = progress.sector; - sleep(1); - } - printf("\n"); - - for (trackno = 0 ; trackno < source_adr_count; trackno++) - burn_track_free(tracklist[trackno]); - burn_session_free(session); - burn_disc_free(target_disc); - if(simulate_burn) - printf("\n*** Did TRY to SIMULATE burning ***\n\n"); - return 0; -} - - -/** The setup parameters of libburn */ -static char drive_adr[BURN_DRIVE_ADR_LEN]= {""}; -static int driveno= 0; -static int do_blank= 0; -static char source_adr[99][4096]; -static int source_adr_count= 0; -static off_t stdin_size= 650*1024*1024; -static int simulate_burn = 0; -static int all_tracks_type = BURN_MODE1; - - -/** Converts command line arguments into above setup parameters. - drive_adr[] must provide at least BURN_DRIVE_ADR_LEN bytes. - source_adr[] must provide at least 4096 bytes. -*/ -int libburner_setup(int argc, char **argv) -{ - int i, insuffient_parameters = 0, print_help = 0; - - for (i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--audio")) { - all_tracks_type = BURN_AUDIO; - - } else if (!strcmp(argv[i], "--blank_fast")) { - do_blank = 1; - - } else if (!strcmp(argv[i], "--blank_full")) { - do_blank = 2; - - } else if (!strcmp(argv[i], "--burn_for_real")) { - simulate_burn = 0; - - } else if (!strcmp(argv[i], "--drive")) { - ++i; - if (i >= argc) { - fprintf(stderr,"--drive requires an argument\n"); - return 1; - } else if (strcmp(argv[i], "-") == 0) { - drive_adr[0] = 0; - driveno = -1; - } else if (isdigit(argv[i][0])) { - drive_adr[0] = 0; - driveno = atoi(argv[i]); - } else { - if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) { - fprintf(stderr,"--drive address too long (max. %d)\n", - BURN_DRIVE_ADR_LEN-1); - return 2; - } - strcpy(drive_adr, argv[i]); - } - } else if (!strcmp(argv[i], "--stdin_size")) { - ++i; - if (i >= argc) { - fprintf(stderr,"--stdin_size requires an argument\n"); - return 3; - } else - stdin_size = atoi(argv[i]); - if (stdin_size < 600*1024) /* minimum readable track size */ - stdin_size = 600*1024; - } else if (!strcmp(argv[i], "--try_to_simulate")) { - simulate_burn = 1; - - } else if (!strcmp(argv[i], "--help")) { - print_help = 1; - - } else if (!strncmp(argv[i], "--",2)) { - fprintf(stderr, "Unidentified option: %s\n", argv[i]); - return 7; - } else { - if(strlen(argv[i]) >= 4096) { - fprintf(stderr, "Source address too long (max. %d)\n", 4096-1); - return 5; - } - if(source_adr_count >= 99) { - fprintf(stderr, "Too many tracks (max. 99)\n"); - return 6; - } - strcpy(source_adr[source_adr_count], argv[i]); - source_adr_count++; - } - } - insuffient_parameters = 1; - if (driveno < 0) - insuffient_parameters = 0; - if (source_adr_count > 0) - insuffient_parameters = 0; - if (do_blank) - insuffient_parameters = 0; - if (print_help || insuffient_parameters ) { - printf("Usage: %s\n", argv[0]); - printf(" [--drive
||\"-\"]\n"); - printf(" [--blank_fast|--blank_full] [--audio]\n"); - printf(" [--try_to_simulate] [--stdin_size ]\n"); - printf(" [|\"-\"]\n"); - printf("Examples\n"); - printf("A bus scan (needs rw-permissions to see a drive):\n"); - printf(" %s --drive -\n",argv[0]); - printf("Burn a file to drive chosen by number:\n"); - printf(" %s --drive 0 my_image_file\n", - argv[0]); - printf("Burn a file to drive chosen by persistent address:\n"); - printf(" %s --drive /dev/hdc my_image_file\n", argv[0]); - printf("Blank a used CD-RW (is combinable with burning in one run):\n"); - printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]); - printf("Burn two audio tracks\n"); - printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n"); - printf(" test/dewav /path/to/track2.wav -o track2.cd\n"); - printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]); - printf("Burn a compressed afio archive on-the-fly, pad up to 700 MB:\n"); - printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n"); - printf(" %s --drive /dev/hdc --stdin_size 734003200 -\n", argv[0]); - printf("To be read from *not mounted* CD via: afio -tvZ /dev/hdc\n"); - printf("Program tar would need a clean EOF which our padded CD cannot deliver.\n"); - if (insuffient_parameters) - return 6; - } - return 0; -} - - -int main(int argc, char **argv) -{ - int ret; - - ret = libburner_setup(argc, argv); - if (ret) - exit(ret); - - printf("Initializing libburn.pykix.org ...\n"); - if (burn_initialize()) - printf("Done\n"); - else { - printf("FAILED\n"); - fprintf(stderr,"\nFATAL: Failed to initialize.\n"); - exit(33); - } - - /* Print messages of severity SORRY or more directly to stderr */ - burn_msgs_set_severities("NEVER", "SORRY", "libburner : "); - - /* Activate the default signal handler which eventually will try to - properly shutdown drive and library on aborting events. */ - burn_set_signal_handling("libburner : ", NULL, 0); - - /** Note: driveno might change its value in this call */ - ret = libburner_aquire_drive(drive_adr, &driveno); - if (ret<=0) { - fprintf(stderr,"\nFATAL: Failed to aquire drive.\n"); - { ret = 34; goto finish_libburn; } - } - if (ret == 2) - { ret = 0; goto release_drive; } - if (do_blank) { - ret = libburner_blank_disc(drive_list[driveno].drive, - do_blank == 1); - if (ret<=0) - { ret = 36; goto release_drive; } - if (ret != 2 && source_adr_count > 0) - ret = libburner_regrab(drive_list[driveno].drive); - if (ret<=0) { - fprintf(stderr, - "FATAL: Cannot release and grab again drive after blanking\n"); - { ret = 37; goto finish_libburn; } - } - } - if (source_adr_count > 0) { - ret = libburner_payload(drive_list[driveno].drive, - source_adr, source_adr_count, stdin_size, - simulate_burn, all_tracks_type); - if (ret<=0) - { ret = 38; goto release_drive; } - } - ret = 0; -release_drive:; - if (drive_is_grabbed) - burn_drive_release(drive_list[driveno].drive, 0); - -finish_libburn:; - /* This app does not bother to know about exact scan state. - Better to accept a memory leak here. We are done anyway. */ - /* burn_drive_info_free(drive_list); */ - - burn_finish(); - exit(ret); -} - - -/* License and copyright aspects: - -This all is provided under GPL. -Read. Try. Think. Play. Write yourself some code. Be free of my copyright. - -Be also invited to study the code of cdrskin/cdrskin.c et al. - - -Clarification in my name and in the name of Mario Danic, copyright holder -on toplevel of libburn. To be fully in effect after the remaining other -copyrighted code has been replaced by ours and by copyright-free contributions -of our friends: - -We, the copyright holders, agree on the interpretation that -dynamical linking of our libraries constitutes "use of" and -not "derivation from" our work in the sense of GPL, provided -those libraries are compiled from our unaltered code. - -Thus you may link our libraries dynamically with applications -which are not under GPL. You may distribute our libraries and -application tools in binary form, if you fulfill the usual -condition of GPL to offer a copy of the source code -altered -or unaltered- under GPL. - -We ask you politely to use our work in open source spirit -and with the due reference to the entire open source community. - -If there should really arise the case where above clarification -does not suffice to fulfill a clear and neat request in open source -spirit that would otherwise be declined for mere formal reasons, -only in that case we will duely consider to issue a special license -covering only that special case. -It is the open source idea of responsible freedom which will be -decisive and you will have to prove that you exhausted all own -means to qualify for GPL. - -For now we are firmly committed to maintain one single license: GPL. - -History: -libburner is a compilation of my own contributions to test/burniso.c and -fresh code which replaced the remaining parts under copyright of -Derek Foreman. -My respect and my thanks to Derek for providing me a start back in 2005. - -*/ - diff --git a/test/master.c b/test/master.c deleted file mode 100644 index 7c0acb4..0000000 --- a/test/master.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct burn_drive_info *drives; -static unsigned int n_drives; - -void burn_files(struct burn_drive *drive, struct burn_disc *disc) -{ - struct burn_write_opts *o; - enum burn_disc_status s; - - if (!burn_drive_grab(drive, 1)) { - printf("Unable to open the drive!\n"); - return; - } - while (burn_drive_get_status(drive, NULL)) - usleep(1000); - - while ((s = burn_disc_get_status(drive)) == BURN_DISC_UNREADY) - usleep(1000); - - if (s != BURN_DISC_BLANK) { - burn_drive_release(drive, 0); - printf("Please insert blank media in the drive\n"); - return; - } - o = burn_write_opts_new(drive); - burn_drive_set_speed(drive, 0, 2816); - burn_write_opts_set_perform_opc(o, 0); - burn_write_opts_set_write_type(o, BURN_WRITE_TAO, BURN_BLOCK_MODE1); - burn_write_opts_set_simulate(o, 1); -/* want failure on seggy while debugging :) */ - burn_write_opts_set_underrun_proof(o, 0); - burn_structure_print_disc(disc); - burn_disc_write(o, disc); - burn_write_opts_free(o); - - while (burn_drive_get_status(drive, NULL)) { - sleep(1); - } - printf("\n"); - burn_drive_release(drive, 0); - burn_disc_free(disc); -} - -void parse_args(int argc, char **argv, int *drive, struct burn_disc **disc) -{ - int i, tmode = BURN_AUDIO; - int help = 1; - struct burn_session *session; - struct burn_track *tr; - struct burn_source *src; - - *disc = burn_disc_create(); - session = burn_session_create(); - burn_disc_add_session(*disc, session, BURN_POS_END); - for (i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--drive")) { - ++i; - if (i >= argc) - printf("--drive requires an argument\n"); - else - *drive = atoi(argv[i]); - } else if (!strcmp(argv[i], "--audio")) { - tmode = BURN_AUDIO; - } else if (!strcmp(argv[i], "--data")) { - tmode = BURN_MODE1; - } else if (!strcmp(argv[i], "--verbose")) { - ++i; - if (i >= argc) - printf("--verbose requires an argument\n"); - else - burn_set_verbosity(atoi(argv[i])); - } else if (!strcmp(argv[i], "--help")) { - help = 1; /* who cares */ - } else { - help = 0; - printf("%s is a track\n", argv[i]); - - tr = burn_track_create(); - src = burn_file_source_new(argv[i], NULL); - burn_track_set_source(tr, src); - burn_source_free(src); - burn_track_define_data(tr, 0, 0, 1, tmode); - burn_session_add_track(session, tr, BURN_POS_END); - } - } - if (help) { - printf("Usage: %s [--drive ] [--verbose ] files\n", - argv[0]); - exit(EXIT_FAILURE); - } -} - -int main(int argc, char **argv) -{ - int drive = 0; - struct burn_disc *disc; - - parse_args(argc, argv, &drive, &disc); - printf("Initializing library..."); - if (burn_initialize()) - printf("Success\n"); - else { - printf("Failed\n"); - return 1; - } - - printf("Scanning for devices..."); - while (!burn_drive_scan(&drives, &n_drives)) ; - printf("Done\n"); - - burn_files(drives[drive].drive, disc); - burn_drive_info_free(drives); - burn_finish(); - return 0; -} diff --git a/test/poll.c b/test/poll.c deleted file mode 100644 index cd22f15..0000000 --- a/test/poll.c +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include "libburn/libburn.h" -#include "libburn/toc.h" -#include "libburn/mmc.h" - -#include -#include -#include -#include - -static struct burn_drive_info *drives; -static unsigned int n_drives; -int NEXT; - -static void catch_int () -{ - NEXT = 1; -} - -static void poll_drive(int d) -{ - enum burn_disc_status s; - - fprintf(stderr, "polling disc in %s - %s:\n", - drives[d].vendor, drives[d].product); - - if (!burn_drive_grab(drives[d].drive, 1)) { - fprintf(stderr, "Unable to open the drive!\n"); - return; - } - - while (burn_drive_get_status(drives[d].drive, NULL)) - usleep(1000); - - while ((s = burn_disc_get_status(drives[d].drive)) - == BURN_DISC_UNREADY) - usleep(1000); - - while (NEXT == 0) { - sleep(2); - mmc_get_event(drives[d].drive); - } - burn_drive_release(drives[d].drive, 0); -} - -int main() -{ - int i; - struct sigaction newact; - struct sigaction oldact; - fprintf(stderr, "Initializing library..."); - if (burn_initialize()) - fprintf(stderr, "Success\n"); - else { - printf("Failed\n"); - return 1; - } - - fprintf(stderr, "Scanning for devices..."); - while (!burn_drive_scan(&drives, &n_drives)) ; - fprintf(stderr, "Done\n"); - if (!drives) { - printf("No burner found\n"); - return 1; - } - - newact.sa_handler = catch_int; - sigaction(SIGINT, &newact, &oldact); - for (i = 0; i < n_drives; i++) { - NEXT=0; - poll_drive(i); - } - sigaction(SIGINT, &oldact, NULL); - burn_drive_info_free(drives); - burn_finish(); - return 0; -} diff --git a/test/rip.c b/test/rip.c deleted file mode 100644 index 0606cf4..0000000 --- a/test/rip.c +++ /dev/null @@ -1,54 +0,0 @@ -/* THIS IS NOT A PROPER EXAMPLE */ -#include -#include -#include -#include -#include -#include - -#include - -static struct burn_drive_info *drives; -static unsigned int n_drives; - -#warning this example is totally fried -int main() -{ -#if 0 - struct burn_drive *drive; - struct burn_read_opts o; - - burn_initialize(); - o.datafd = - open("/xp/burn/blah.data", O_CREAT | O_WRONLY, - S_IRUSR | S_IWUSR); - o.subfd = - open("/xp/burn/blah.sub", O_CREAT | O_WRONLY, - S_IRUSR | S_IWUSR); - o.raw = 1; - o.c2errors = 0; - o.subcodes_audio = 1; - o.subcodes_data = 1; - o.hardware_error_recovery = 1; - o.report_recovered_errors = 0; - o.transfer_damaged_blocks = 1; - o.hardware_error_retries = 1; - - printf("Scanning for devices..."); - while (!burn_drive_scan(&drives, &n_drives)) ; - printf("Done\n"); - drive = drives[0].drive; - burn_drive_set_speed(drive, 0, 0); - - if (!burn_drive_grab(drive, 1)) { - printf("Unable to open the drive!\n"); - return EXIT_FAILURE; - } - - while (burn_drive_get_status(drive, NULL)) - usleep(1000); - - burn_disc_read(drive, &o); -#endif - return EXIT_SUCCESS; -} diff --git a/test/structest.c b/test/structest.c deleted file mode 100644 index defa274..0000000 --- a/test/structest.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int i; - const char *path; - struct burn_track *track; - struct burn_disc *disc; - struct burn_session *session; - struct burn_source *src; - - disc = burn_disc_create(); - session = burn_session_create(); - burn_disc_add_session(disc, session, BURN_POS_END); - - /* Define a source for all of the tracks */ - path = strdup("/etc/hosts"); - src = burn_file_source_new(path, NULL); - - /* Add ten tracks to a session */ - for (i = 0; i < 10; i++) { - track = burn_track_create(); - burn_session_add_track(session, track, 0); - if (burn_track_set_source(track, src) != BURN_SOURCE_OK) { - printf("problem with the source\n"); - return 0; - } - } - - /* Add ten tracks to a session */ - for (i = 0; i < 10; i++) { - track = burn_track_create(); - burn_session_add_track(session, track, 0); - if (burn_track_set_source(track, src) != BURN_SOURCE_OK) { - printf("problem with the source\n"); - return 0; - } - } - - /* Delete a session */ - burn_session_remove_track(session, track); - - burn_structure_print_disc(disc); - return EXIT_SUCCESS; -} diff --git a/test/toc.c b/test/toc.c deleted file mode 100644 index 1ec7bcf..0000000 --- a/test/toc.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ - -#include -#include -#include -#include -#include - -static struct burn_drive_info *drives; -static unsigned int n_drives; - -static void show_tocs() -{ - struct burn_session **sessions; - struct burn_track **tracks; - struct burn_disc *disc; - int nses, ntracks, hidefirst; - unsigned int i, j, k; - struct burn_toc_entry e; - enum burn_disc_status s; - - for (i = 0; i < n_drives; ++i) { - fprintf(stderr, "TOC for disc in %s - %s:\n", - drives[i].vendor, drives[i].product); - - if (!burn_drive_grab(drives[i].drive, 1)) { - fprintf(stderr, "Unable to open the drive!\n"); - continue; - } - - while (burn_drive_get_status(drives[i].drive, NULL)) - usleep(1000); - - while ((s = burn_disc_get_status(drives[i].drive)) - == BURN_DISC_UNREADY) - usleep(1000); - if (s != BURN_DISC_FULL) { - burn_drive_release(drives[i].drive, 0); - fprintf(stderr, "No disc found!\n"); - continue; - } - - disc = burn_drive_get_disc(drives[i].drive); - - sessions = burn_disc_get_sessions(disc, &nses); - for (k = 0; k < nses; ++k) { - tracks = burn_session_get_tracks(sessions[k], - &ntracks); - hidefirst = burn_session_get_hidefirst(sessions[k]); - if (hidefirst) - fprintf(stderr, - "track: GAP (%2d) lba: %9d (%9d) %02d:%02d:%02d adr: X control: X mode: %d\n", - k + 1, 0, 0, 0, 2, 0, - burn_track_get_mode(tracks[0])); - - for (j = !!hidefirst; j < ntracks; ++j) { - burn_track_get_entry(tracks[j], &e); - fprintf(stderr, - "track: %3d (%2d) lba: %9d (%9d) %02d:%02d:%02d " - "adr: %d control: %d mode: %d\n", - e.point, e.session, - burn_msf_to_lba(e.pmin, e.psec, - e.pframe), - burn_msf_to_lba(e.pmin, e.psec, - e.pframe) * 4, - e.pmin, e.psec, e.pframe, e.adr, - e.control, - burn_track_get_mode(tracks[j])); - } - burn_session_get_leadout_entry(sessions[k], &e); - fprintf(stderr, - "track:lout (%2d) lba: %9d (%9d) %02d:%02d:%02d " - "adr: %d control: %d mode: %d\n", - k + 1, burn_msf_to_lba(e.pmin, e.psec, - e.pframe), - burn_msf_to_lba(e.pmin, e.psec, - e.pframe) * 4, e.pmin, - e.psec, e.pframe, e.adr, e.control, -1); - } - burn_disc_free(disc); - burn_drive_release(drives[i].drive, 0); - } -} - -int main() -{ - fprintf(stderr, "Initializing library..."); - if (burn_initialize()) - fprintf(stderr, "Success\n"); - else { - printf("Failed\n"); - return 1; - } - - fprintf(stderr, "Scanning for devices..."); - while (!burn_drive_scan(&drives, &n_drives)) ; - fprintf(stderr, "Done\n"); - - show_tocs(); - burn_drive_info_free(drives); - burn_finish(); - return 0; -}