Compare commits

..

8 Commits

50 changed files with 630 additions and 5914 deletions

View File

@ -1,12 +1,12 @@
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or later
as published by the Free Software Foundation.
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -12,9 +12,6 @@ lib_LTLIBRARIES = libburn/libburn.la
# Build libraries
libburn_libburn_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
# This causes undesired .o names
# configure.ac appends -D options to variable CFLAG
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
libburn_libburn_la_SOURCES = \
libburn/async.c \
@ -28,8 +25,6 @@ libburn_libburn_la_SOURCES = \
libburn/debug.h \
libburn/drive.c \
libburn/drive.h \
libburn/ecma130ab.c \
libburn/ecma130ab.h \
libburn/error.h \
libburn/file.c \
libburn/file.h \
@ -70,6 +65,9 @@ libburn_libburn_la_SOURCES = \
libburn/write.h \
version.h
## libburn/lec.c \
## libburn/lec.h \
## libburn/sg-@ARCH@.c \
libinclude_HEADERS = \
@ -110,9 +108,9 @@ test_structest_CPPFLAGS = -Ilibburn
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - B00122
## cdrskin construction site - ts A60816 - A91012
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_6
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_2
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
@ -199,14 +197,10 @@ EXTRA_DIST = \
cdrskin/wiki_plain.txt \
cdrskin/cleanup.h \
cdrskin/cleanup.c \
libburn/os-dummy.h \
libburn/os-freebsd.h \
libburn/os-linux.h \
libburn/os-libcdio.h \
libburn/sg-dummy.c \
libburn/sg-freebsd.c \
libburn/sg-linux.c \
libburn/sg-libcdio.c \
COPYING \
NEWS \
ChangeLog \

91
README
View File

@ -6,12 +6,12 @@ This all is under GPL.
------------------------------------------------------------------------------
libburn-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
http://files.libburnia-project.org/releases/libburn-0.7.6.pl00.tar.gz
http://files.libburnia-project.org/releases/libburn-0.7.2.pl00.tar.gz
------------------------------------------------------------------------------
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
From tarball
Obtain libburn-0.7.6.pl00.tar.gz, take it to a directory of your choice and do:
Obtain libburn-0.7.2.pl00.tar.gz, take it to a directory of your choice and do:
tar xzf libburn-0.7.6.pl00.tar.gz
cd libburn-0.7.6
tar xzf libburn-0.7.2.pl00.tar.gz
cd libburn-0.7.2
./configure --prefix=/usr
make
@ -57,30 +57,6 @@ Do in a directory of your choice:
Warning: The trunk might contain experimental features which might not
persist until next release.
Special ./configure options
In some situations Linux may deliver a better write performance to drives if
the track input is read with O_DIRECT (see man 2 open). The API call
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
can be told to use this peculiar read mode by:
--enable-track-src-odirect
But often libburn call burn_write_opts_set_dvd_obs(opts, 64*1024) will yield
even better performance in such a situation. 64k can be made default at
configure time by:
--enable-dvd-obs-64k
This may be combined with above --enable-track-src-odirect .
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
You may install it and re-run libburn's ./configure with option
--enable-libcdio
Make sure to re-compile all source files after running ./configure
make clean ; make
make install
------------------------------------------------------------------------------
An important part of the project, libisofs, is hosted in a bzr repository at
@ -161,8 +137,7 @@ The project components (list subject to growth, hopefully):
Rock Ridge extensions. Manipulation is not only adding or
overwriting of files but also deleting, renaming, attribute
changing, incremental backups, activating boot images, and
extracting of files from ISO images to disk. An own ISO 9660
extension stores ACLs, xattr, and MD5 of file content.
extracting of files from ISO images to disk.
See xorriso/README for more.
- "test" is a collection of application gestures and examples given by the
@ -189,8 +164,8 @@ Applications must use 64 bit off_t. E.g. by defining
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
or take special precautions to interface with the libraries by 64 bit integers
where the .h files prescribe off_t. To reduce libburn's off_t size to 32 bit
will keep it from processing tracks of more than 2 GB size.
where the .h files prescribe off_t. Not to use 64 bit file i/o will keep the
application from producing and processing ISO images of more than 2 GB size.
------------------------------------------------------------------------------
@ -468,39 +443,12 @@ Project history as far as known to me:
It can retrieve media product info and can process track input which was
prepared for CD-ROM XA Mode 2 Form 1. cdrskin now performs option -minfo.
- 28 Oct 2009 libisoburn-0.4.4 fixes a bug with cdrecord emulation and
introduces new information options about media type and ISO image id strings.
On Linux it helps with mounting two sessions of the same media
simultaneously.
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
- 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners,
provides throughput enhancements with hampered busses on Linux, and new
API calls to log SCSI commands and to control the libburn fifo.
- 09 Dec 2009 libisoburn-0.4.6 allows performance tuning of output to DVD
drives or disk files.
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
the files of the generic system adapter for X/Open.
- 29 Dec 2009 Our project received a donation for purchasing a fine small
computer which shall serve as OS farm for development and support.
- 20 Jan 2010 Version 0.6.26 of libisofs fixes minor bugs and shall enhance
portability.
- 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD,
fixes bugs about the generic X/Open system adapter, and allows to use
libcdio >= 0.83 as SCSI transport facility.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or later
as published by the Free Software Foundation.
it under the terms of the GNU General Public License as published by
the Free Software Foundation. To be exact: version 2 of that License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -518,16 +466,16 @@ 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 or from altered code published under GPL.
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.
So we will not raise legal protest if you link our libraries dynamically with
applications which are not under GPL, or if you distribute our libraries
and application tools in binary form, as long as you fulfill the usual
condition of GPL to offer a copy of their source code -altered or unaltered-
under GPL.
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.
@ -544,5 +492,4 @@ means to qualify for GPL.
For now we are firmly committed to maintain one single license: GPL.
signed: Mario Danic, Thomas Schmitt
Agreement joined later by: Vreixo Formoso

View File

@ -6,20 +6,16 @@ AC_DEFUN([TARGET_SHIZZLE],
AC_MSG_CHECKING([target operating system])
case $target_os in
linux*)
case $target in
*-*-linux*)
ARCH=linux
LIBBURN_ARCH_LIBS=
;;
freebsd*)
*-*-freebsd*)
ARCH=freebsd
LIBBURN_ARCH_LIBS=-lcam
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
;;
kfreebsd*-gnu)
ARCH=freebsd
LIBBURN_ARCH_LIBS=-lcam
;;
*)
ARCH=
LIBBURN_ARCH_LIBS=

View File

@ -4,18 +4,17 @@
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
Integrated sub project of libburnia-project.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-0.7.6.pl00.tar.gz
http://scdbackup.sourceforge.net/cdrskin-0.7.2.pl00.tar.gz
Copyright (C) 2006-2010 Thomas Schmitt, provided under GPL version 2 or later.
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
------------------------------------------------------------------------------
cdrskin is a limited cdrecord compatibility wrapper which allows to use
most of the libburn features from the command line.
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD.
IDE drives under Linux 2.4. need kernel module ide-scsi.
ATA and SATA drives under FreeBSD need kernel module atapicam.
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
On other X/Open compliant systems there will only be emulated drives, but no
direct MMC operation on real CD/DVD/BD drives.
@ -25,10 +24,10 @@ By using this software you agree to the disclaimer at the end of this text
Compilation, First Glimpse, Installation
Obtain cdrskin-0.7.6.pl00.tar.gz, take it to a directory of your choice and do:
Obtain cdrskin-0.7.2.pl00.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-0.7.6.pl00.tar.gz
cd cdrskin-0.7.6
tar xzf cdrskin-0.7.2.pl00.tar.gz
cd cdrskin-0.7.2
Within that directory execute:
@ -36,7 +35,8 @@ Within that directory execute:
make
This will already produce a cdrskin binary. But it will be necessary to
install libburn in order to use this binary.
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
@ -73,7 +73,7 @@ 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 totally static linked binary.)
below for a way to create a statically linked binary.)
To install the man page, you may do: echo $MANPATH and choose one of the
listed directories to copy the man-page under its ./man1 directory. Like:
@ -398,25 +398,6 @@ drive. See man page section FILES for a way to lift that ban.
Special compilation variations
All following options of ./configure and cdrskin/compile_cdrskin.sh are
combinable.
In some situations Linux may deliver a better write performance to drives if
the track input is read with O_DIRECT (see man 2 open). The API call
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
can be told to use this peculiar read mode by:
--enable-track-src-odirect
But often cdrskin option dvd_obs=64k will yield even better performance in
such a situation. 64k can be made default at compile time by
cdrskin/compile_cdrskin.sh -dvd_obs_64k
It can also be enabled at configure time by
./configure ... --enable-dvd-obs-64k ...
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
You may install it and re-run libburn's ./configure with option
--enable-libcdio
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
@ -460,7 +441,7 @@ contributions in a due way.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or later
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
@ -476,7 +457,7 @@ contributions in a due way.
Based on and sub project of:
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
libburnia-project.org is inspired by and in other components still containing
parts of
@ -487,3 +468,34 @@ See toplevel README for an overview of the current copyright situation in
libburnia-project.org.
------------------------------------------------------------------------------
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

View File

@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="0.7.6"
skin_release="0.7.2"
patch_level=".pl00"
skin_rev="$skin_release""$patch_level"

View File

@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="0.7.7"
skin_release="0.7.3"
patch_level=""
skin_rev="$skin_release""$patch_level"

View File

@ -25,11 +25,6 @@
#include <sys/time.h>
#include <sys/select.h>
#ifndef Cdrfifo_standalonE
/* <<< until release of 0.7.4 : for Libburn_has_open_trac_srC */
#include "../libburn/libburn.h"
#endif
#include "cdrfifo.h"
@ -125,7 +120,7 @@ struct CdrfifO {
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 bit0= Debugging verbosity
@param flag Unused yet
@return 1 on success, <=0 on failure
*/
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
@ -179,13 +174,7 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
o->follow_up_fd_idx= -1;
o->next= o->prev= NULL;
o->chain_idx= 0;
#ifdef Libburn_has_open_trac_srC
o->buffer= burn_os_alloc_buffer((size_t) buffer_size, 0);
#else
o->buffer= TSOB_FELD(char,buffer_size);
#endif /* ! Libburn_has_open_trac_srC */
if(o->buffer==NULL)
goto failed;
return(1);
@ -237,14 +226,8 @@ int Cdrfifo_destroy(struct CdrfifO **ff, int flag)
if(o->iso_fs_descr!=NULL)
free((char *) o->iso_fs_descr);
if(o->buffer!=NULL)
#ifdef Libburn_has_open_trac_srC
burn_os_free_buffer(o->buffer, o->buffer_size, 0);
#else
free((char *) o->buffer);
#endif /* Libburn_has_open_trac_srC */
free((char *) o);
(*ff)= NULL;
return(1);
@ -633,7 +616,7 @@ return: <0 = error , 0 = idle , 1 = did some work
*/
{
double buffer_space;
int can_read,can_write= 0,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
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)) {
@ -676,46 +659,6 @@ return: <0 = error , 0 = idle , 1 = did some work
after_write:;
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
can_read= o->buffer_size - o->write_idx;
#ifdef Libburn_has_open_trac_srC
/* ts A91115
This chunksize must be aligned to filesystem blocksize.
*/
#define Cdrfifo_o_direct_chunK 32768
if(o->write_idx < o->read_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;
/* Make sure to read with properly aligned size */
if(can_read > Cdrfifo_o_direct_chunK)
can_read= Cdrfifo_o_direct_chunK;
else if(can_read < Cdrfifo_o_direct_chunK)
can_read= -1;
ret= 0;
if(can_read>0)
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
if(can_read < 0) {
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
if(can_write <= 0 && o->dest_fd >= 0) {
fd_set rds,wts,exs;
struct timeval wt;
FD_ZERO(&rds);
FD_ZERO(&wts);
FD_ZERO(&exs);
FD_SET((o->dest_fd),&wts);
wt.tv_sec= 0;
wt.tv_usec= 10000;
select(o->dest_fd + 1,&rds, &wts, &exs, &wt);
}
} else
#else /* Libburn_has_open_trac_srC */
if(can_read>o->chunk_size)
can_read= o->chunk_size;
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
@ -726,9 +669,6 @@ after_write:;
ret= 0;
if(can_read>0)
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
#endif /* ! Libburn_has_open_trac_srC */
if(ret==-1) {
/* >>> handle input error */;

View File

@ -33,7 +33,7 @@ struct CdrfifO;
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 bit0= Debugging verbosity
@param flag unused yet
@return 1 on success, <=0 on failure
*/
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Jan 19, 2010"
.TH CDRSKIN 1 "Sep 10, 2009"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -796,11 +796,6 @@ Level 2 additionally reports about option settings derived from arguments or
startup files. Level 3 is for debugging and useful mainly in conjunction with
somebody who had a look into the program sourcecode.
.TP
.BI \-V
Enable logging of SCSI commands to stderr. This allows expert examination
of the interaction between libburn and the drive. The commands are specified
in SCSI-3 standards SPC, SBC, MMC.
.TP
.BI \-waiti
Wait until input data is available at stdin or EOF occurs at stdin.
Only then begin to access any drives.
@ -899,14 +894,6 @@ Both, write_start_address and direct_write_amount size must be aligned to a
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
overwriteable DVD-RW it is 32k.
.TP
.BI dvd_obs= default|32k|64k
Linux specific:
Set the number of bytes to be transmitted with each write operation to DVD
or BD media. Tracks get padded up to the next multiple of this write
size. A number of 64 KB may improve throughput with bus systems which
show latency problems. The default depends on media type, option
stream_recording=, and on compile time options.
.TP
.BI fallback_program= command
Set a command name to be executed if cdrskin encounters a known cdrecord
option which it does not yet support. If a non-empty command is given with
@ -1021,22 +1008,6 @@ which can only do DAO but not Incremental Streaming.
.BI \--single_track
Accept only the last argument of the command line as track source address.
.TP
.BI stdio_sync= on|off|number
Set the number of bytes after which to force output to drives with prefix
"stdio:". This forcing keeps the memory from being clogged with lots of
pending data for slow devices. Default "on" is the same as "16m".
Forced output can be disabled by "off".
.TP
.BI stream_recording= on|off|number
By setting "on" request that compliance to the desired speed setting is
preferred over management of write errors. With DVD-RAM and BD this can
bring effective write speed near to the nominal write speed of the media.
But it will also disable the automatic use of replacement blocks
if write errors occur. It might as well be disliked or ignored by the drive.
.br
If a number is given, then error management stays enabled for all byte
addresses below that number. Any number below 16s is the same as "off".
.TP
.BI tao_to_sao_tsize= size
Set an exact fixed size for the next track to be in effect only if the track
source cannot deliver a size prediction and no tsize= was specified and an
@ -1223,6 +1194,17 @@ Linux specific:
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
pseudo ATA addresses. This method is outdated and was never compatible with
original cdrecord.
.TP
.BI stream_recording="on"|"off"|number
By setting "on" request that compliance to the desired speed setting is
preferred over management of write errors. With DVD-RAM and BD this can
bring effective write speed near to the nominal write speed of the media.
But it will also disable the automatic use of replacement blocks
if write errors occur. It might as well be disliked or ignored by the drive.
.br
If a number is given, then error management stays enabled for all byte
addresses below that number. Any number below 16s is the same as "off".
.TP
.BI --xa1-ignore
Silently interpret option -xa1 as -data. This may be necessary if a frontent
does not prepare -xa1 block headers but insists in using option -xa1.
@ -1242,7 +1224,7 @@ cdrskin dev=0,1,0 -checkdrive
.br
cdrskin dev=ATA:1,0,0 -v -atip
.br
cdrskin dev=/dev/hdc -minfo
cdrskin dev=/dev/hdc -toc
.SS
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
.br

View File

@ -1,7 +1,7 @@
/*
cdrskin.c , Copyright 2006-2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. See future commitment below.
cdrskin.c , Copyright 2006-2009 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2. See future commitment below.
A cdrecord compatible command line interface for libburn.
@ -88,7 +88,7 @@ or
/** The official program version */
#ifndef Cdrskin_prog_versioN
#define Cdrskin_prog_versioN "0.7.6"
#define Cdrskin_prog_versioN "0.7.2"
#endif
/** The official libburn interface revision to use.
@ -101,7 +101,7 @@ or
#define Cdrskin_libburn_minoR 7
#endif
#ifndef Cdrskin_libburn_micrO
#define Cdrskin_libburn_micrO 6
#define Cdrskin_libburn_micrO 2
#endif
@ -135,43 +135,42 @@ or
#endif /* Cdrskin_libburn_cvs_A60220_tS */
#ifdef Cdrskin_libburn_0_7_6
#define Cdrskin_libburn_versioN "0.7.6"
#ifdef Cdrskin_libburn_0_7_2
#define Cdrskin_libburn_versioN "0.7.2"
#define Cdrskin_libburn_from_pykix_svN 1
#endif /* Cdrskin_libburn_0_7_6 */
#endif /* Cdrskin_libburn_0_7_2 */
#ifdef Cdrskin_libburn_0_7_7
#define Cdrskin_libburn_versioN "0.7.7"
#ifdef Cdrskin_libburn_0_7_3
#define Cdrskin_libburn_versioN "0.7.3"
#define Cdrskin_libburn_from_pykix_svN 1
/* Place novelty switch macros here.
Move them down to Cdrskin_libburn_from_pykix_svN on version leap
*/
#endif /* Cdrskin_libburn_0_7_7 */
#endif /* Cdrskin_libburn_0_7_3 */
#ifndef Cdrskin_libburn_versioN
#define Cdrskin_libburn_0_7_6
#define Cdrskin_libburn_versioN "0.7.6"
#define Cdrskin_libburn_0_7_2
#define Cdrskin_libburn_versioN "0.7.2"
#define Cdrskin_libburn_from_pykix_svN 1
#endif
#ifdef Cdrskin_libburn_0_7_6
#ifdef Cdrskin_libburn_0_7_2
#undef Cdrskin_libburn_majoR
#undef Cdrskin_libburn_minoR
#undef Cdrskin_libburn_micrO
#define Cdrskin_libburn_majoR 0
#define Cdrskin_libburn_minoR 7
#define Cdrskin_libburn_micrO 6
#define Cdrskin_libburn_micrO 2
#endif
#ifdef Cdrskin_libburn_0_7_7
#ifdef Cdrskin_libburn_0_7_3
#undef Cdrskin_libburn_majoR
#undef Cdrskin_libburn_minoR
#undef Cdrskin_libburn_micrO
#define Cdrskin_libburn_majoR 0
#define Cdrskin_libburn_minoR 7
#define Cdrskin_libburn_micrO 7
#define Cdrskin_libburn_micrO 3
#endif
@ -323,16 +322,11 @@ or
/** A macro which is able to eat up a function call like printf() */
#ifdef Cdrskin_extra_leaN
#define ClN(x)
#define Cdrskin_no_cdrfifO 1
#else
#define ClN(x) x
#ifdef Cdrskin_use_libburn_fifO
/*
# define Cdrskin_no_cdrfifO 1
*/
#endif
#endif
/** Verbosity level for pacifying progress messages */
#define Cdrskin_verbose_progresS 1
@ -871,12 +865,12 @@ backward:;
/* --------------------------------------------------------------------- */
#ifndef Cdrskin_no_cdrfifO
#ifndef Cdrskin_extra_leaN
/* Program is to be linked with cdrfifo.c */
#include "cdrfifo.h"
#else /* ! Cdrskin_no_cdrfifO */
#else /* ! Cdrskin_extra_leaN */
/* Dummy */
@ -884,7 +878,7 @@ struct CdrfifO {
int dummy;
};
#endif /* Cdrskin_no_cdrfifO */
#endif /* Cdrskin_extra_leaN */
/* --------------------------------------------------------------------- */
@ -947,10 +941,6 @@ struct CdrtracK {
struct burn_track *libburn_track;
#ifdef Cdrskin_use_libburn_fifO
struct burn_source *libburn_fifo;
#endif /* Cdrskin_use_libburn_fifO */
};
int Cdrtrack_destroy(struct CdrtracK **o, int flag);
@ -1008,9 +998,6 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss,
o->ff_fifo= NULL;
o->ff_idx= -1;
o->libburn_track= NULL;
#ifdef Cdrskin_use_libburn_fifO
o->libburn_fifo= NULL;
#endif /* Cdrskin_use_libburn_fifO */
ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size),
&(o->tao_to_sao_tsize),&(o->use_data_image_size),
@ -1047,7 +1034,7 @@ int Cdrtrack_destroy(struct CdrtracK **o, int flag)
if(track==NULL)
return(0);
#ifndef Cdrskin_no_cdrfifO
#ifndef Cdrskin_extra_leaN
Cdrfifo_destroy(&(track->fifo),0);
#endif
@ -1133,61 +1120,6 @@ int Cdrtrack_get_source_path(struct CdrtracK *track,
}
#ifdef Cdrskin_use_libburn_fifO
int Cdrtrack_get_libburn_fifo(struct CdrtracK *track,
struct burn_source **fifo, int flag)
{
*fifo= track->libburn_fifo;
return(1);
}
int Cdrtrack_report_fifo(struct CdrtracK *track, int flag)
{
int size, free_bytes, ret;
int total_min_fill, interval_min_fill, put_counter, get_counter;
int empty_counter, full_counter;
double fifo_percent;
char *status_text;
if(track->libburn_fifo == NULL)
return(0);
/* Check for open input or leftover bytes in liburn fifo */
ret = burn_fifo_inquire_status(track->libburn_fifo, &size, &free_bytes,
&status_text);
if(ret >= 0 && size - free_bytes > 1) {
/* not clear why free_bytes is reduced by 1 */
fprintf(stderr,
"cdrskin: FATAL : Fifo still contains data after burning has ended.\n");
fprintf(stderr,
"cdrskin: FATAL : %d bytes left.\n", size - free_bytes - 1);
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");
return(-1);
}
burn_fifo_get_statistics(track->libburn_fifo, &total_min_fill,
&interval_min_fill, &put_counter, &get_counter,
&empty_counter, &full_counter);
fifo_percent= 100.0*((double) total_min_fill)/(double) size;
if(fifo_percent==0 && total_min_fill>0)
fifo_percent= 1;
fflush(stdout);
fprintf(stderr,"Cdrskin: fifo had %d puts and %d gets.\n",
put_counter,get_counter);
fprintf(stderr,
"Cdrskin: fifo was %d times empty and %d times full, min fill was %.f%%.\n",
empty_counter, full_counter, fifo_percent);
return(1);
}
#endif /* Cdrskin_use_libburn_fifO */
int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag)
{
*fifo= track->fifo;
@ -1302,7 +1234,7 @@ int Cdrtrack_activate_image_size(struct CdrtracK *track, double *size_used,
}
track->extracting_container= 1;
#ifndef Cdrskin_no_cdrfifO
#ifndef Cdrskin_extra_leaN
if(track->ff_fifo!=NULL)
Cdrfifo_set_fd_in_limit(track->ff_fifo,track->fixed_size,track->ff_idx,0);
#endif
@ -1366,7 +1298,6 @@ int Cdrtrack_seek_isosize(struct CdrtracK *track, int fd, int flag)
bit0=debugging verbosity
bit1=open as source for direct write:
no audio extract, no minimum track size
bit2=permission to use burn_os_open_track_src() (evtl O_DIRECT)
@return <=0 error, 1 success
*/
int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
@ -1456,15 +1387,8 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
return(-1);
if(is_wav==-3)
return(0);
if(is_wav==0) {
if(track->track_type != BURN_MODE1 ||
(track->cdxa_conversion & 0x7fffffff))
flag&= ~4; /* Better avoid O_DIRECT with odd sectors */
if(flag & 4)
*fd= burn_os_open_track_src(track->source_path, O_RDONLY, 0);
else
*fd= open(track->source_path, O_RDONLY);
}
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);
@ -1528,7 +1452,7 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
}
#ifndef Cdrskin_no_cdrfifO
#ifndef Cdrskin_extra_leaN
/** Install a fifo object between data source and libburn.
Its parameters are known to track.
@ -1550,8 +1474,7 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
*outlet_fd= -1;
if(track->fifo_size<=0)
return(2);
ret= Cdrtrack_open_source_path(track,&source_fd,
(flag&1) | (4 * (track->fifo_size >= 256 * 1024)));
ret= Cdrtrack_open_source_path(track,&source_fd,flag&1);
if(ret<=0)
return(ret);
if(pipe(pipe_fds)==-1)
@ -1568,7 +1491,7 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
/* >>> ??? obtain track sector size and use instead of 2048 ? */
ret= Cdrfifo_new(&ff,source_fd,pipe_fds[1],2048,track->fifo_size, flag & 1);
ret= Cdrfifo_new(&ff,source_fd,pipe_fds[1],2048,track->fifo_size,0);
if(ret<=0)
return(ret);
if(previous_fifo!=NULL)
@ -1591,100 +1514,18 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
return(1);
}
#endif /* ! Cdrskin_no_cdrfifO */
#ifndef Cdrskin_extra_leaN
#ifdef Cdrskin_use_libburn_fifO
/** Read data into the eventual libburn fifo until either fifo_start_at bytes
are read (-1 = no limit), it is full or or the data source is exhausted.
/** Read data into the fifo until either it is full or the data source is
exhausted.
@return <=0 error, 1 success
*/
int Cdrtrack_fill_libburn_fifo(struct CdrtracK *track, int fifo_start_at,
int flag)
{
int ret, bs= 32 * 1024;
int buffer_size, buffer_free;
double data_image_size;
char buf[64 * 1024], *buffer_text;
if(fifo_start_at == 0)
return(2);
if(track->libburn_fifo == NULL)
return(2);
if(fifo_start_at>0 && fifo_start_at<track->fifo_size)
printf(
"cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n",
fifo_start_at);
printf("Waiting for reader process to fill input buffer ... ");
fflush(stdout);
ret= burn_fifo_fill(track->libburn_fifo, fifo_start_at,
(fifo_start_at == -1));
if(ret < 0)
return(0);
/** Ticket 55: check fifos for input, throw error on 0-bytes from stdin
@return <=0 abort run, 1 go on with burning
*/
ret= burn_fifo_inquire_status(track->libburn_fifo, &buffer_size,
&buffer_free, &buffer_text);
if(track->is_from_stdin) {
if(ret<0 || buffer_size <= buffer_free) {
fprintf(stderr,"\ncdrskin: FATAL : (First track) fifo did not read a single byte from stdin\n");
return(0);
}
}
/* Try to obtain ISO 9660 Volume Descriptors and size from fifo.
Not an error if there is no ISO 9660. */
if(track->iso_fs_descr != NULL)
free(track->iso_fs_descr);
track->iso_fs_descr = NULL;
if(buffer_size - buffer_free >= 64 * 1024) {
ret= burn_fifo_peek_data(track->libburn_fifo, buf, 64 * 1024, 0);
if(ret == 1) {
track->iso_fs_descr = calloc(1, bs);
if(track->iso_fs_descr == NULL)
return(-1);
memcpy(track->iso_fs_descr, buf + bs, bs);
ret= Scan_for_iso_size((unsigned char *) buf + bs, &data_image_size, 0);
if(ret > 0)
track->data_image_size= data_image_size;
}
}
return(1);
}
#endif /* Cdrskin_use_libburn_fifO */
#ifdef Cdrskin_no_cdrfifO
int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
{
return(Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0));
}
#else /* Cdrskin_no_cdrfifO */
int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
{
int ret,buffer_fill,buffer_space;
double data_image_size;
if(fifo_start_at==0)
if(track->fifo==NULL || fifo_start_at==0)
return(2);
if(track->fifo==NULL) {
#ifdef Cdrskin_use_libburn_fifO
ret= Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0);
return(ret);
#else
return(2);
#endif
}
if(fifo_start_at>0 && fifo_start_at<track->fifo_size)
printf(
"cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n",
@ -1714,7 +1555,6 @@ int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
return(1);
}
#endif /* ! Cdrskin_no_cdrfifO */
#endif /* ! Cdrskin_extra_leaN */
@ -1726,11 +1566,10 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
/*
bit0= debugging verbosity
bit1= apply padding hack (<<< should be unused for now)
bit2= permission to use O_DIRECT (if enabled at compile time)
*/
{
struct burn_track *tr;
struct burn_source *src= NULL, *fd_src= NULL;
struct burn_source *src= NULL;
double padding,lib_padding;
int ret,sector_pad_up;
double fixed_size;
@ -1742,7 +1581,7 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
/* Note: track->track_type may get set in here */
if(track->source_fd==-1) {
ret= Cdrtrack_open_source_path(track, &source_fd, flag & (4 | 1));
ret= Cdrtrack_open_source_path(track,&source_fd,(flag&1));
if(ret<=0)
goto ex;
}
@ -1787,41 +1626,6 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
}
src= burn_fd_source_new(track->source_fd,-1,(off_t) fixed_size);
#ifdef Cdrskin_use_libburn_fifO
if(src != NULL && track->fifo == NULL) {
int fifo_enabled, fifo_size, fifo_start_at, chunksize, chunks;
int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled,
int *fifo_size, int *fifo_start_at, int flag);
Cdrskin_get_fifo_par(track->boss, &fifo_enabled, &fifo_size, &fifo_start_at,
0);
fd_src= src;
if(track->track_type == BURN_AUDIO)
chunksize= 2352;
else if (track->cdxa_conversion == 1)
chunksize= 2056;
else
chunksize= 2048;
chunks= fifo_size / chunksize;
if(chunks > 1 && fifo_enabled) {
src= burn_fifo_source_new(fd_src, chunksize, chunks,
(chunksize * chunks >= 128 * 1024));
if((flag & 1) || src == NULL)
fprintf(stderr, "cdrskin_DEBUG: %s libburn fifo of %d bytes\n",
src != NULL ? "installed" : "failed to install",
chunksize * chunks);
track->libburn_fifo= src;
if(src == NULL) {
src= fd_src;
fd_src= NULL;
}
}
}
#endif /* Cdrskin_use_libburn_fifO */
if(src==NULL) {
fprintf(stderr,
"cdrskin: FATAL : Could not create libburn data source object\n");
@ -1834,8 +1638,6 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
burn_session_add_track(session,tr,BURN_POS_END);
ret= 1;
ex:
if(fd_src!=NULL)
burn_source_free(fd_src);
if(src!=NULL)
burn_source_free(src);
return(ret);
@ -1886,7 +1688,7 @@ int Cdrtrack_get_sectors(struct CdrtracK *track, int flag)
}
#ifndef Cdrskin_no_cdrfifO
#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.
@ -1907,7 +1709,7 @@ int Cdrtrack_has_input_left(struct CdrtracK *track, int flag)
return(0);
}
#endif /* ! Cdrskin_no_cdrfifO */
#endif /* ! Cdrskin_extra_leaN */
/* --------------------------------------------------------------------- */
@ -2334,8 +2136,6 @@ int Cdrpreskin_fallback(struct CdrpreskiN *preskin, int argc, char **argv,
int i, wp= 1;
char *ept, *upt;
if(preskin->fallback_program[0] == 0)
return(1);
if(getuid()!=geteuid() && !preskin->allow_setuid) {
fprintf(stderr,
"cdrskin: SORRY : uid and euid differ. Will not start external fallback program.\n");
@ -2872,9 +2672,6 @@ set_dev:;
printf(
" --drive_scsi_exclusive try to exclusively reserve device files\n");
printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n");
printf(" dvd_obs=\"default\"|number\n");
printf(
" set number of bytes per DVD/BD write: 32k or 64k\n");
#ifdef Cdrskin_burn_drive_eject_brokeN
printf(
" eject_device=<path> set the device address for command eject\n");
@ -2925,11 +2722,6 @@ set_dev:;
printf(
" byte addresses below that number.\n");
#endif
printf(" stdio_sync=\"default\"|\"off\"|number\n");
printf(
" set number of bytes after which to force output\n");
printf(
" to drives with prefix \"stdio:\".\n");
#ifdef Cdrskin_allow_libburn_taO
printf(
@ -2995,9 +2787,7 @@ see_cdrskin_eng_html:;
"\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 general verbose level by one\n");
fprintf(stderr,
"\t-V\t\tincrement SCSI command transport verbose level by one\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,
@ -3124,16 +2914,12 @@ see_cdrskin_eng_html:;
} 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) {
burn_set_scsi_logging(2 | 4); /* log SCSI to stderr */
} else if(strcmp(argv[i],"-v")==0 || strcmp(argv[i],"-verbose")==0) {
(o->verbosity)++;
ClN(printf("cdrskin: verbosity level : %d\n",o->verbosity));
set_severities:;
if(o->verbosity>=Cdrskin_verbose_debuG)
Cdrpreskin_set_severities(o,"NEVER","DEBUG",0);
} else if(strcmp(argv[i],"-vv")==0 || strcmp(argv[i],"-vvv")==0 ||
strcmp(argv[i],"-vvvv")==0) {
(o->verbosity)+= strlen(argv[i])-1;
@ -3143,17 +2929,7 @@ set_severities:;
int major, minor, micro;
printf(
"Cdrecord 2.01-Emulation Copyright (C) 2006-2010, see libburnia-project.org\n");
if(o->fallback_program[0]) {
char *hargv[2];
printf("Fallback program : %s\n",o->fallback_program);
printf("Fallback version :\n");
hargv[0]= argv[0];
hargv[1]= "-version";
Cdrpreskin_fallback(o,2,hargv,1); /* dirty never come back */
}
printf("System adapter : %s\n", burn_scsi_transport_id(0));
"Cdrecord 2.01-Emulation Copyright (C) 2006-2009, see libburnia-project.org\n");
printf("libburn interface : %d.%d.%d\n",
burn_header_version_major, burn_header_version_minor,
burn_header_version_micro);
@ -3169,6 +2945,15 @@ set_severities:;
printf("Version timestamp : %s\n",Cdrskin_timestamP);
printf("Build timestamp : %s\n",Cdrskin_build_timestamP);
if(o->fallback_program[0]) {
char *hargv[2];
printf("Fallback program : %s\n",o->fallback_program);
printf("Fallback version :\n");
hargv[0]= argv[0];
hargv[1]= "-version";
Cdrpreskin_fallback(o,2,hargv,1); /* dirty never come back */
}
{ret= 2; goto ex;}
} else if(strcmp(argv[i],"-waiti")==0) {
@ -3185,9 +2970,7 @@ set_severities:;
final_checks:;
if(flag&1)
goto ex;
if(o->verbosity >= Cdrskin_verbose_debuG)
ClN(fprintf(stderr,
"cdrskin: DEBUG : Using %s\n", burn_scsi_transport_id(0)));
if(o->do_waiti) {
fprintf(stderr,
"cdrskin: Option -waiti pauses program until input appears at stdin\n");
@ -3318,10 +3101,19 @@ ex:;
/** 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
*/
/** <<< Hopefully obsolete:
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
*/
#define Cdrskin_tracksize_maX 1024.0*1024.0*1024.0*1024.0
@ -3370,8 +3162,6 @@ struct CdrskiN {
int dummy_mode;
int force_is_set;
int stream_recording_is_set; /* see burn_write_opts_set_stream_recording() */
int dvd_obs; /* DVD write chunk size: 0, 32k or 64k */
int stdio_sync; /* stdio fsync interval: -1, 0, >=32 */
int single_track;
int prodvd_cli_compatible;
@ -3590,8 +3380,6 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->dummy_mode= 0;
o->force_is_set= 0;
o->stream_recording_is_set= 0;
o->dvd_obs= 0;
o->stdio_sync= 0;
o->single_track= 0;
o->prodvd_cli_compatible= 0;
o->do_devices= 0;
@ -3766,8 +3554,6 @@ int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled,
}
#ifndef Cdrskin_no_cdrfifO
/** Create and install fifo objects between track data sources and libburn.
The sources and parameters are known to skin.
@return <=0 error, 1 success
@ -3777,20 +3563,6 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
struct CdrfifO *ff= NULL;
int ret,i,hflag;
#ifdef Cdrskin_use_libburn_fifO
int profile_number;
char profile_name[80];
/* Refuse here and thus use libburn fifo only with single track, non-CD */
ret= burn_disc_get_profile(skin->drives[skin->driveno].drive,
&profile_number, profile_name);
if(profile_number != 0x09 && profile_number != 0x0a &&
skin->track_counter == 1)
return(1);
#endif /* Cdrskin_use_libburn_fifO */
skin->fifo= NULL;
for(i=0;i<skin->track_counter;i++) {
hflag= (skin->verbosity>=Cdrskin_verbose_debuG);
@ -3822,8 +3594,6 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
return(1);
}
#endif /* ! Cdrskin_no_cdrfifO */
/** Read data into the track fifos until either #1 is full or its data source
is exhausted.
@ -4166,7 +3936,7 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
if(skin->preskin->abort_handler==3)
fprintf(stderr,"cdrskin: ABORT : Trying to ignore any further signals\n");
#ifndef Cdrskin_no_cdrfifO
#ifndef Cdrskin_extra_leaN
if(skin->fifo!=NULL)
Cdrfifo_close_all(skin->fifo,0);
#endif
@ -6061,28 +5831,16 @@ int Cdrskin_burn_pacifier(struct CdrskiN *skin,
bit0= growisofs style
*/
{
double bytes_to_write= 0.0;
double written_bytes= 0.0,written_total_bytes= 0.0;
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,advance_interval=0,new_mb,old_mb,time_to_tell;
int old_track_idx,buffer_fill,formatting= 0,use_data_image_size;
char fifo_text[80],mb_text[40], pending[40];
int ret,fifo_percent,fill,space,advance_interval=0,new_mb,old_mb,time_to_tell;
int fs,bs,old_track_idx,buffer_fill,formatting= 0,use_data_image_size;
char fifo_text[80],mb_text[40];
char *debug_mark= ""; /* use this to prepend a marker text for experiments */
#ifndef Cdrskin_no_cdrfifO
double buffer_size;
int fs, bs, space;
#endif
#ifdef Cdrskin_use_libburn_fifO
struct burn_source *current_fifo= NULL;
int size, free_space;
char *status_text= "";
#endif /* Cdrskin_use_libburn_fifO */
/* for debugging */
static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out;
@ -6186,14 +5944,9 @@ thank_you_for_patience:;
if(skin->verbosity>=Cdrskin_verbose_progresS) {
if(skin->is_writing)
fprintf(stderr,"\n");
pending[0]= 0;
/*
if(bytes_to_write > 0 && skin->verbosity >= Cdrskin_verbose_debuG)
sprintf(pending, " pnd %.f", bytes_to_write - written_total_bytes);
*/
fprintf(stderr,
"\rcdrskin: thank you for being patient for %.f seconds%21.21s",
elapsed_total_time, pending);
"\rcdrskin: thank you for being patient for %.f seconds ",
elapsed_total_time);
}
advance_interval= 1;
}
@ -6258,37 +6011,6 @@ thank_you_for_patience:;
fifo_text[0]= 0;
curr_fifo_in= last_fifo_in;
curr_fifo_out= last_fifo_out;
#ifdef Cdrskin_use_libburn_fifO
/* Inquire fifo fill and format fifo pacifier text */
if(skin->fifo == NULL && skin->supposed_track_idx >= 0 &&
skin->supposed_track_idx < skin->track_counter &&
skin->fifo_size > 0) {
Cdrtrack_get_libburn_fifo(skin->tracklist[skin->supposed_track_idx],
&current_fifo, 0);
if(current_fifo != NULL) {
ret= burn_fifo_inquire_status(current_fifo, &size, &free_space,
&status_text);
if(ret <= 0 || ret >= 4) {
strcpy(fifo_text, "(fifo 0%) ");
} else if(ret == 1) {
burn_fifo_next_interval(current_fifo, &fill);
fifo_percent= 100.0 * ((double) fill) / (double) size;
if(fifo_percent<100 && fill>0)
fifo_percent++;
sprintf(fifo_text, "(fifo %3d%%) ", fifo_percent);
} else
strcpy(fifo_text, "(fifo 100%) ");
} else if(skin->fifo_size > 0) {
strcpy(fifo_text, "(fifo 100%) ");
}
}
#endif /* Cdrskin_use_libburn_fifO */
#ifndef Cdrskin_no_cdrfifO
if(skin->fifo!=NULL) {
ret= Cdrfifo_get_buffer_state(skin->fifo,&fill,&space,0);
buffer_size= fill+space;
@ -6317,9 +6039,6 @@ thank_you_for_patience:;
}
}
}
#endif /* ! Cdrskin_no_cdrfifO */
if(skin->supposed_track_idx >= 0 &&
skin->supposed_track_idx < skin->track_counter) {
/* fixed_size,padding are fetched above via Cdrtrack_get_size() */;
@ -6830,8 +6549,7 @@ int Cdrskin_direct_write(struct CdrskiN *skin, int flag)
&source_path,&source_fd,&is_from_stdin,0);
if(source_fd==-1) {
ret= Cdrtrack_open_source_path(skin->tracklist[0],&source_fd,
2 | (skin->verbosity >= Cdrskin_verbose_debuG) |
(4 * (skin->fifo_size >= 256 * 1024)));
2|(skin->verbosity>=Cdrskin_verbose_debuG));
if(ret<=0)
goto ex;
}
@ -6998,19 +6716,15 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
struct burn_progress p;
struct burn_drive *drive;
int ret,loop_counter= 0,max_track= -1,i,hflag,nwa,num, wrote_well= 2;
int fifo_disabled= 0, min_buffer_fill= 101;
int fifo_disabled= 0,fifo_percent,total_min_fill,min_buffer_fill= 101;
int use_data_image_size, needs_early_fifo_fill= 0,iso_size= -1;
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;
char *doing;
char *source_path;
int source_fd, is_from_stdin;
#ifndef Cdrskin_no_cdrfifO
double put_counter, get_counter, empty_counter, full_counter;
int total_min_fill, fifo_percent;
#endif
if(skin->tell_media_space)
doing= "estimating";
else
@ -7069,11 +6783,6 @@ burn_failed:;
hflag= (skin->verbosity>=Cdrskin_verbose_debuG);
if(i==skin->track_counter-1)
Cdrtrack_ensure_padding(skin->tracklist[i],hflag&1);
/* if(skin->fifo_size >= 256 * 1024) */
hflag|= 4;
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);
@ -7209,13 +6918,6 @@ burn_failed:;
#ifdef Cdrskin_libburn_has_stream_recordinG
burn_write_opts_set_stream_recording(o, skin->stream_recording_is_set);
#endif
#ifdef Cdrskin_dvd_obs_default_64K
if(skin->dvd_obs == 0)
burn_write_opts_set_dvd_obs(o, 64 * 1024);
else
#endif
burn_write_opts_set_dvd_obs(o, skin->dvd_obs);
burn_write_opts_set_stdio_fsync(o, skin->stdio_sync);
if(skin->dummy_mode) {
fprintf(stderr,
@ -7339,14 +7041,6 @@ fifo_filling_failed:;
if(skin->fifo==NULL || fifo_disabled) {
usleep(20000);
} else {
#ifdef Cdrskin_no_cdrfifO
/* Should never happen as skin->fifo should be NULL */
usleep(20000);
#else /* Cdrskin_no_cdrfifO */
ret= Cdrfifo_try_to_work(skin->fifo,20000,NULL,NULL,0);
if(ret<0) {
int abh;
@ -7372,11 +7066,7 @@ fifo_filling_failed:;
fprintf(stderr,"\ncdrskin_debug: fifo ended work with ret=%d\n",ret);
fifo_disabled= 1;
}
#endif /* ! Cdrskin_no_cdrfifO */
}
#else /* ! Cdrskin_extra_leaN */
usleep(20000);
#endif /* Cdrskin_extra_leaN */
@ -7416,19 +7106,6 @@ fifo_filling_failed:;
#ifndef Cdrskin_extra_leaN
#ifdef Cdrskin_use_libburn_fifO
if(skin->fifo == NULL && skin->verbosity>=Cdrskin_verbose_progresS) {
/* >>> this should rather be done for each track
(for now this libburn_fifo should only be used with single track)
*/
Cdrtrack_report_fifo(skin->tracklist[skin->track_counter - 1], 0);
}
#endif /* Cdrskin_use_libburn_fifO */
#ifndef Cdrskin_no_cdrfifO
if(skin->fifo!=NULL && skin->fifo_size>0 && wrote_well) {
int dummy,final_fill;
Cdrfifo_get_buffer_state(skin->fifo,&final_fill,&dummy,0);
@ -7476,11 +7153,6 @@ fifo_full_at_end:;
"Cdrskin: fifo was %.f times empty and %.f times full, min fill was %d%%.\n",
empty_counter,full_counter,fifo_percent);
}
}
#endif /* ! Cdrskin_no_cdrfifO */
if(skin->verbosity>=Cdrskin_verbose_progresS) {
drive_status= burn_drive_get_status(drive, &p);
#ifdef Cdrskin_libburn_has_buffer_min_filL
@ -7778,7 +7450,7 @@ int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag)
""
};
static char ignored_full_options[][41]= {
"-d", "-silent", "-s", "-setdropts", "-prcap",
"-d", "-Verbose", "-V", "-silent", "-s", "-setdropts", "-prcap",
"-reset", "-abort", "-overburn", "-ignsize", "-useinfo",
"-fix", "-nofix",
"-raw", "-raw96p", "-raw16", "-raw96r",
@ -8120,22 +7792,6 @@ set_driveropts:;
} else if(strcmp(argv[i],"-dummy")==0) {
skin->dummy_mode= 1;
} else if(strncmp(argv[i], "-dvd_obs=", 9)==0) {
value_pt= argv[i] + 9;
goto dvd_obs;
} else if(strncmp(argv[i], "dvd_obs=", 8)==0) {
value_pt= argv[i] + 8;
dvd_obs:;
if(strcmp(value_pt, "default") == 0)
num= 0;
else
num = Scanf_io_size(value_pt,0);
if(num != 0 && num != 32768 && num != 65536) {
fprintf(stderr,
"cdrskin: SORRY : Option dvd_obs= accepts only sizes 0, 32k, 64k\n");
} else
skin->dvd_obs= num;
} else if(strcmp(argv[i],"-eject")==0) {
skin->do_eject= 1;
if(skin->verbosity>=Cdrskin_verbose_cmD)
@ -8526,26 +8182,6 @@ set_speed:;
if(skin->verbosity>=Cdrskin_verbose_cmD)
ClN(printf("cdrskin: speed : %f\n",skin->x_speed));
} else if(strncmp(argv[i], "-stdio_sync=", 12)==0) {
value_pt= argv[i] + 12;
goto stdio_sync;
} else if(strncmp(argv[i], "stdio_sync=", 11)==0) {
value_pt= argv[i] + 11;
stdio_sync:;
if(strcmp(value_pt, "default") == 0 || strcmp(value_pt, "on") == 0)
num= 0;
else if(strcmp(value_pt, "off") == 0)
num= -1;
else
num = Scanf_io_size(value_pt,0);
if(num > 0)
num/= 2048;
if(num != -1 && num != 0 && (num < 32 || num > 512 * 1024)) {
fprintf(stderr,
"cdrskin: SORRY : Option stdio_sync= accepts only sizes -1, 0, 32k ... 1g\n");
} else
skin->stdio_sync= num;
} else if(strncmp(argv[i],"-stream_recording=",18)==0) {
value_pt= argv[i]+18;
goto set_stream_recording;
@ -8625,8 +8261,6 @@ track_too_large:;
if(skin->smallest_tsize<0 || skin->smallest_tsize>skin->fixed_size)
skin->smallest_tsize= skin->fixed_size;
} else if(strcmp(argv[i],"-V")==0 || strcmp(argv[i],"-Verbose")==0) {
/* is handled in Cdrpreskin_setup() */;
} else if(strcmp(argv[i],"-v")==0 || strcmp(argv[i],"-verbose")==0) {
/* is handled in Cdrpreskin_setup() */;
} else if(strcmp(argv[i],"-vv")==0 || strcmp(argv[i],"-vvv")==0 ||
@ -8817,13 +8451,13 @@ ignore_unknown:;
if(skin->track_counter>0) {
skin->do_burn= 1;
#ifndef Cdrskin_no_cdrfifO
#ifndef Cdrskin_extra_leaN
if(!skin->do_direct_write) {
ret= Cdrskin_attach_fifo(skin,0);
if(ret<=0)
return(ret);
}
#endif /* ! Cdrskin_no_cdrfifO */
#endif /* ! Cdrskin_extra_leaN */
}
return(1);

View File

@ -50,8 +50,7 @@ via SCSI, PATA (aka IDE, ATA), USB, or SATA.
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
<DT>or FreeBSD (with libc, of course) :</DT>
<DD>ATA and SATA drives need atapicam running.</DD>
<DD>libcam has to be installed.</DD>
<DD>ATAPI/CAM support has to be enabled in the kernel, see atapicam(4).</DD>
<DT>libpthread</DT>
<DD>is supposed to be a standard system component.</DD>
</DL>
@ -62,7 +61,7 @@ via SCSI, PATA (aka IDE, ATA), USB, or SATA.
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-0.7.6</DT>
<DT>libburn-0.7.2</DT>
<DD>(founded by Derek Foreman and Ben Jansens,
developed and maintained since August 2006 by
Thomas Schmitt from team of libburnia-project.org)
@ -194,8 +193,8 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
<P>
<DL>
<DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-0.7.6.pl00.tar.gz">cdrskin-0.7.6.pl00.tar.gz</A>
(810 KB).
<DD><A HREF="cdrskin-0.7.2.pl00.tar.gz">cdrskin-0.7.2.pl00.tar.gz</A>
(780 KB).
</DD>
<DD>
The cdrskin tarballs are source code identical with libburn releases
@ -244,22 +243,22 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
<HR>
<P>
Enhancements towards previous stable version cdrskin-0.7.4.pl00:
Enhancements towards previous stable version cdrskin-0.7.0.pl00:
<UL>
<LI>
Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
</LI>
<LI>Experimental system adapter via GNU libcdio on X/Open systems</LI>
<LI>Experimentally using FreeBSD system adapter for Debian kfreebsd</LI>
<LI>Better interpretation of options -mode2, -xa, -xa1, -xa2</LI>
<LI>New option --xa1-ignore</LI>
<LI>New -atip report lines "Product Id:" and "Producer:"</LI>
<LI>Emulation of some -minfo output</LI>
<!--
<LI>none</LI>
-->
</UL>
Bug fixes towards cdrskin-0.7.4.pl00:
Bug fixes towards cdrskin-0.7.0.pl00:
<UL>
<LI>none</LI>
<LI>CD TAO sessions with multiple tracks did not work in -dummy mode</LI>
<!--
<LI>none</LI>
-->
</UL>
@ -267,8 +266,8 @@ Bug fixes towards cdrskin-0.7.4.pl00:
<P>
<DL>
<DT><H3>Development snapshot, version 0.7.7 :</H3></DT>
<DD>Enhancements towards current stable version 0.7.6.pl00:
<DT><H3>Development snapshot, version 0.7.3 :</H3></DT>
<DD>Enhancements towards current stable version 0.7.2.pl00:
<UL>
<LI>none yet</LI>
<!--
@ -277,7 +276,7 @@ Bug fixes towards cdrskin-0.7.4.pl00:
</UL>
</DD>
<DD>Bug fixes towards cdrskin-0.7.6.pl00:
<DD>Bug fixes towards cdrskin-0.7.2.pl00:
<UL>
<LI>none yet</LI>
<!--
@ -286,10 +285,10 @@ Bug fixes towards cdrskin-0.7.4.pl00:
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 0.7.7</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.7 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.7 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.7)</A></DD>
<DD><A HREF="README_cdrskin_devel">README 0.7.3</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.3 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.3 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.3)</A></DD>
<DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN of
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
@ -309,8 +308,8 @@ admins with full system souvereignty.</DT>
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-0.7.7.tar.gz">cdrskin-0.7.7.tar.gz</A>
(810 KB).
<A HREF="cdrskin-0.7.3.tar.gz">cdrskin-0.7.3.tar.gz</A>
(780 KB).
</DD>
<!-- This is not offered any more since spring 2008

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2010.01.22.130001"
#define Cdrskin_timestamP "2009.10.12.080001"

View File

@ -7143,10 +7143,11 @@ Made number transition and activated development documentation
+ cdrskin/add_ts_changes_to_libburn_0_7_3
Updated cdrskin tarball generator
12 Oct 2009 [2867]
[]
cdrskin/changelog.txt
Documented changes and release timestamp
------------------------------ release - cdrskin-0.7.2.pl00 - 2009.10.12.080001
* Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode
* Better interpretation of options -mode2, -xa, -xa1, -xa2
@ -7158,867 +7159,15 @@ Documented changes and release timestamp
* New API call burn_disc_get_cd_info()
* New API call burn_track_set_cdxa_conv()
2009.10.12.103503 [2858]
Makefile.am
configure.ac
README
libburn/libburn.h
cdrskin/cdrskin.c
cdrskin/README
cdrskin/compile_cdrskin.sh
cdrskin/cdrskin_timestamp.h
cdrskin/cdrskin_eng.html
Made number transition to 0.7.3
12 Oct 2009 [2859]
- cdrskin/add_ts_changes_to_libburn_0_7_0
- cdrskin/add_ts_changes_to_libburn_0_7_1
+ cdrskin/add_ts_changes_to_libburn_0_7_2
+ cdrskin/add_ts_changes_to_libburn_0_7_3
Updated cdrskin tarball generator
12 Oct 2009 [2860]
cdrskin/changelog.txt
Documented changes and release timestamp
12 Oct 2009 [2861]
svn move -m "libburn release 0.7.2 is ready" \
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwo \
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo
------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.12.105750
2009.10.17.131852 [2865] [2864]
Makefile.am
libburn/libburn.h
libburn/sector.c
+ libburn/ecma130ab.h
+ libburn/ecma130ab.c
cdrskin/compile_cdrskin.sh
Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
------------------------------------ cycle - cdrskin-0.7.3 -
------------------------------------ cycle - cdrskin-0.7.3 -
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
2009.10.19.115722 [2867]
libburn/ecma130ab.c
Optimizations with parity computation, clarification about nature of logarithms
2009.10.20.160131 [2868]
libburn/libburn.h
libburn/ecma130ab.c
More optimizations with parity computation
------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.20.160131
2009.10.27.100637 [2871]
libburn/mmc.c
Bug fix: burn_drive->disc_id or burn_drive->disc_app_code altered by stray 0. Thanks to George Danchev.
2009.10.27.101031 [2872]
libburn/sg-freebsd.c
Bug fix: Closed memory leak with failure to open device file under FreeBSD. Thanks to George Danchev.
2009.10.30.134640 [2880]
libburn/libburn.h
libburn/spc.c
libburn/mmc.c
libburn/sg-linux.c
Test macros for finding reason of stall problem with Pioneer DVD-216D on DVD-R
------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.30.134640
2009.11.03.184626 [2881]
libburn/libburn.h
libburn/mmc.c
Test macro for SL_V in mode page 05
2009.11.04.084506 [2882]
libburn/libburn.h
libburn/write.c
Test macro for SEND OPC INFORMATION before DVD-R track
2009.11.05.170409 [2883]
libburn/libburn.h
libburn/transport.h
libburn/write.c
libburn/sbc.c
libburn/mmc.c
Test macros for double START UNIT and SET CD SPEED
2009.11.08.120917 [2884]
libburn/mmc.c
Corrected allocation length with GET CONFIGURATION
2009.11.08.121334 [2885]
libburn/spc.h
libburn/spc.c
libburn/mmc.h
libburn/sg-linux.c
Made SCSI command log more complete and more readable
2009.11.10.132154 [2886]
libburn/mmc.c
Avoiding START UNIT before the drive gets released
2009.11.10.203412 [2887]
libburn/libburn.h
libburn/write.c
libburn/spc.c
libburn/sbc.c
libburn/mmc.c
libburn/sg-linux.c
Hopefully solved the endless burn problem with Pioneer DVR-216D
2009.11.11.100714 [2888]
libburn/write.c
Increased stdio flush interval from 1 MB to 16 MB
2009.11.11.100822 [2889]
cdrskin/cdrskin.c
Reporting number of pending bytes while thanking for patience in -vvv mode
2009.11.11.105028 [2890]
cdrskin/cdrskin.c
Silenced a compiler warning about potentially uninitialized variable
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.11.105159
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns
11 Nov 2009 [2891]
cdrskin/cdrskin_eng.html
Updated cdrskin home page about DVR-216D workaround
2009.11.12.175514 [2892]
libburn/libburn.h
libburn/init.c
libburn/write.c
libburn/sg-linux.c
Made SCSI logger permanent and controllable via API call
2009.11.12.175735 [2893]
libburn/spc.c
libburn/sbc.c
libburn/mmc.c
Workaround for Pioneer DVR-216D refusal to eject
2009.11.12.180048 [2894]
libburn/drive.c
Macro Libburn_pioneer_dvr_216d_dummy_probe_wM for omitting write mode probe
2009.11.12.180241 [2895]
cdrskin/cdrskin.c
Implemented option -V for logging of SCSI commands
2009.11.12.193617 [2896]
cdrskin/cdrskin.c
cdrskin/cdrskin.1
Man page entry and help text for option -V
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.12.194644
* Implemented option -V for logging of SCSI commands
* Workaround for Pioneer DVR-216D refusal to eject
13 Nov 2009 [2898]
svn copy -m Branching for libburn bugfix release 0.7.2.pl01 \
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo \
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01
2009.11.12.230001 [2899]
README
libburn/write.c
libburn/sbc.c
cdrskin/README
cdrskin/cdrskin_eng.html
cdrskin/cdrskin_timestamp.h
libburn-0.7.2.pl01 : Workarounds for Pioneer DVR-216D rev 1.09
13 Nov 2009 [2900]
svn move -m libburn bugfix release 0.7.2.pl01 is ready \
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01 \
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwoPl01
-------------------------------- patch - cdrskin-0.7.2.pl01 - 2009.11.12.230001
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns
* Workaround for Pioneer DVR-216D refusal to eject
2009.11.15.115923 [2901]
libburn/file.c
Corrected an outdated remark
2009.11.15.152541 [2902]
cdrskin/cdrskin.c
cdrskin/cdrfifo.c
cdrskin/compile_cdrskin.sh
New compile_cdrskin.sh option -o_direct (Linux only)
2009.11.15.153140 [2903]
libburn/libburn.h
libburn/options.h
libburn/options.c
libburn/write.c
New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
2009.11.15.165016 [2904]
cdrskin/cdrskin.c
cdrskin/cdrskin.1
New options dvd_obs= and stdio_fsync=
2009.11.16.165420 [2905]
configure.ac
Makefile.am
libburn/write.c
cdrskin/cdrskin.c
cdrskin/cdrfifo.h
cdrskin/cdrfifo.c
cdrskin/cdrskin.1
Configure options --enable-cdrskin-fifo-odirect, --enable-dvd-obs-64k
16 Nov 2009 [2906]
cdrskin/compile_cdrskin.sh
New compile_cdrskin.sh option -dvd_obs_64k, adapted to new .o names of libburn
16 Nov 2009 [2907]
README
cdrskin/README
cdrskin/cdrskin_eng.html
Updated build instructions of libburn and cdrskin
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.16.180334
* New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
* New options dvd_obs= and stdio_fsync=
* Configure option --enable-dvd-obs-64k
* New compile_cdrskin.sh option -dvd_obs_64k
2009.11.17.093602 [2908]
configure.ac
Makefile.am
cdrskin/compile_cdrskin.sh
Revoked usage of libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.17.100248
17 Nov 2009 [2912]
cdrskin/compile_cdrskin.sh
Corrected help text of cdrskin static compile script
2009.11.18.122713 [2913]
libburn/drive.c
libburn/spc.c
libburn/mmc.h
libburn/mmc.c
Split automatic drive start function from mmc_function_spy()
2009.11.18.185733 [2914]
libburn/write.c
Reserving enough track space for 64 kB write chunks
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.18.190403
2009.11.20.134952 [2915]
libburn/libburn.h
libburn/write.c
libburn/sg-linux.c
Experiment about SG_FLAG_DIRECT_IO
2009.11.20.175854 [2916]
cdrskin/cdrfifo.c
Avoided use of uninitialized variable
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.21.122202
2009.11.21.191516 [2917]
libburn/write.c
Longer READ BUFFER CAPACITY interval with DVD/BD writing
2009.11.21.191717 [2918]
cdrskin/cdrskin.c
Enabled cdrskin O_DIRECT with fs=0
2009.11.22.115227 [2919]
libburn/write.c
Bug fix: DVD DAO track size was rounded up much too generously
2009.11.23.185725 [2920]
configure.ac
Makefile.am
README
libburn/libburn.h
libburn/file.h
libburn/file.c
libburn/async.c
libburn/write.c
libburn/sg-linux.c
libburn/sg-freebsd.c
libburn/sg-freebsd-port.c
libburn/sg-dummy.c
New API calls burn_os_open_track_src() , burn_os_alloc_buffer()
2009.11.23.193252 [2921]
cdrskin/cdrskin.c
cdrskin/cdrfifo.c
cdrskin/compile_cdrskin.sh
cdrskin/README
Gave up cdrskin specific O_DIRECT compile option
2009.11.25.122233 [2920]
libburn/libburn.h
libburn/sg-linux.c
libburn/sg-freebsd.c
libburn/sg-freebsd-port.c
libburn/sg-dummy.c
Gave up call burn_os_close_track_src() introduced by rev 2920
2009.11.25.160153 [2923]
libburn/libburn.h
libburn/file.c
libburn/libdax_msgs.h
New API call burn_fifo_fill()
2009.11.26.144452 [2924]
libburn/libburn.h
libburn/file.h
libburn/file.c
New API calls burn_fifo_get_statistics(), burn_fifo_next_interval()
2009.11.26.211418 [2925]
cdrskin/cdrskin.c
cdrskin/compile_cdrskin.sh
Compiler option -use_libburn_fifo to switch non-CD from cdrfifo to libburn fifo
2009.11.28.122436 [2926]
libburn/sg-linux.c
Using mmap() by default for allocating read buffers
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.28.165658
* Bug fix: DVD DAO track size was rounded up much too generously
* New API call burn_fifo_fill()
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval()
* Configure option --enable-track-src-odirect
2009.11.30.100152 [2929]
libburn/sbc.c
Documented meaning of START/STOP UNIT bits
2009.12.02.103036 [2930]
libburn/write.c
Gave up CLOSE TRACK with CD TAO burn runs
2009.12.05.111822 [2931]
libburn/mmc.c
Bug fix: SIGSEGV with LG GH22LS30 when inquiring media product id
------------------------------------ cycle - cdrskin-0.7.3 - 2009.12.05.112623
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30
2009.12.05.142309 [2932]
libburn/libburn.h
libburn/write.c
Made effect of macro Libburn_pioneer_dvr_216d_read_buf_caP unconditional
2009.12.05.143707 [2933]
libburn/mmc.c
libburn/sg-linux.c
Converted stderr experiment messages to DEBUG messages
2009.12.06.073404 [2934]
libburn/mmc.c
Some clarifications about the GH22LS30 problem
2009.12.06.074622 [2935]
libburn/write.c
Some clarifications about the Linux throughput problem
2009.12.06.093847 [2936]
cdrskin/compile_cdrskin.sh
Now default in cdrskin: use of libburn fifo with DVD and BD single track
06 Dec 2009 [2937]
svn copy -m Branching for libburn release 0.7.4
http://svn.libburnia-project.org/libburn/trunk
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFour
2009.12.06.160001 [2938]
Makefile.am
configure.ac
README
libburn/libburn.h
cdrskin/cdrskin.c
cdrskin/README
cdrskin/compile_cdrskin.sh
cdrskin/cdrskin_timestamp.h
cdrskin/cdrskin_eng.html
Made number transition to 0.7.4
06 Dec 2009 [2939]
- cdrskin/add_ts_changes_to_libburn_0_7_2
- cdrskin/add_ts_changes_to_libburn_0_7_3
+ cdrskin/add_ts_changes_to_libburn_0_7_4
+ cdrskin/add_ts_changes_to_libburn_0_7_5
Updated cdrskin tarball generator
06 Dec 2009 [2940]
cdrskin/changelog.txt
Documented changes and release timestamp
------------------------------ release - cdrskin-0.7.4.pl00 - 2009.12.06.160001
* Configure options --enable-dvd-obs-64k, --enable-track-src-odirect
* New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
* New API call burn_set_scsi_logging()
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(), burn_fifo_fill()
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns
* Workaround for Pioneer DVR-216D refusal to eject
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30
* Bug fix: DVD DAO track size was rounded up much too generously
* cdrskin option -V for logging of SCSI commands
* New cdrskin options dvd_obs= and stdio_fsync=
* New compile_cdrskin.sh option -dvd_obs_64k
2009.12.07.070029 [2941]
Makefile.am
configure.ac
README
libburn/libburn.h
cdrskin/cdrskin.c
cdrskin/README
cdrskin/compile_cdrskin.sh
cdrskin/cdrskin_timestamp.h
cdrskin/cdrskin_eng.html
Made number transition to 0.7.5
07 Dec 2009 [2942]
- cdrskin/add_ts_changes_to_libburn_0_7_2
- cdrskin/add_ts_changes_to_libburn_0_7_3
+ cdrskin/add_ts_changes_to_libburn_0_7_4
+ cdrskin/add_ts_changes_to_libburn_0_7_5
Updated cdrskin tarball generator
07 Dec 2009 [2943]
cdrskin/changelog.txt
Documented changes and release timestamp
07 Dec 2009 [2946]
svn move -m libburn release 0.7.4 is ready
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFour
http://svn.libburnia-project.org/libburn/tags/ZeroSevenFour
------------------------------------ cycle - cdrskin-0.7.5 - 2009.12.07.083850
16 Dec 2009 [2955]
doc/cookbook.txt
Mentioned in cookbook the change about TAO close track
2009.12.19.140015 [2957]
libburn/spc.c
Corrected CDB length of command 55h MODE SELECT from 12 to 10
2009.12.19.142456 [2958]
libburn/spc.h
libburn/sg-linux.c
Moved sg_log_cmd() to spc.c scsi_log_cmd()
2009.12.19.142456 [2959]
configure.ac
Makefile.am
libburn/os.h
libburn/sg.c
libburn/sg-freebsd-port.c
+ libburn/os-libcdio.h
+ libburn/sg-libcdio.c
Experimental SCSI transport adapter via GNU libcdio
2009.12.24.170601 [2960]
configure.ac
libburn/spc.h
libburn/spc.c
libburn/sg-linux.c
libburn/sg-libcdio.c
Making use of libcdio function mmc_get_cmd_scsi_sense()
25 Dec 2009 [2961]
cdrskin/compile_cdrskin.sh
Option -use_libcdio for cdrskin development compile script
2009.12.25.101433 [2962]
libburn/libdax_msgs.h
Commited file forgotten with rev 2960
2009.12.25.143326 [2963]
libburn/sg-libcdio.c
Resolving symbolic links in libcdio drive list
2009.12.25.144122 [2964]
configure.ac
Added PKG_CHECK_MODULES for libcdio-0.82 (must become 0.83 when released)
2009.12.25.205704 [2965]
configure.ac
libburn/sg-libcdio.c
Adapted to libcdio-0.83 and its runtime version telling
2009.12.25.223915 [2966]
libburn/init.c
libburn/sg.h
libburn/sg-freebsd.c
libburn/sg-freebsd-port.c
libburn/sg-libcdio.c
libburn/sg-linux.c
New internal sg-API function sg_initialize()
2009.12.26.080301 [2967]
libburn/init.c
libburn/sg-dummy.c
libburn/sg-freebsd.c
libburn/sg-freebsd-port.c
libburn/sg-libcdio.c
libburn/sg-linux.c
New API function burn_scsi_transport_id()
26 Dec 2009 [2968]
Makefile.am
Added os-dummy.h and sg-dummy.h to libburn tarball
26 Dec 2009 [2969]
svn copy -m Branching for libburn bugfix release 0.7.4.pl01
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01
26 Dec 2009 [2970]
svn mv -m Branching for libburn bugfix release 0.7.4.pl01
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01
26 Dec 2009 [2971]
svn rm -m Branching for libburn bugfix release 0.7.4.pl01
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01
26 Dec 2009 [2972]
svn copy -m Branching for libburn bugfix release 0.7.4.pl01
http://svn.libburnia-project.org/libburn/tags/ZeroSevenFour
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01
2009.12.26.110001 [2973]
README
Makefile.am
cdrskin/cdrskin_timestamp.h
Bug fix: Added missing system adapter for generic X/Open to libburn release tarball
26 Dec 2009 [2974]
svn move -m libburn bugfix release 0.7.4.pl01 is ready
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01
http://svn.libburnia-project.org/libburn/tags/ZeroSevenFourPl01
2009.12.26.193707 [2975]
cdrskin/cdrskin.c
Reporting burn_scsi_transport_id() in cdrskin as debug message
2009.12.26.222656 [2976]
libburn/libburn.h
doc/comments
Reacted on some doxygen warnings of Debian hurd build
2009.12.27.092057 [2979]
libburn/os-libcdio.h
libburn/sg-libcdio.c
Showing libburn users drive name link targets, using in libcdio its own names
2009.12.27.102342 [2981]
libburn/sg-libcdio.c
Shorter sg_initialize message with sg-libcdio
2009.12.27.144620 [2982]
libburn/init.c
libburn/drive.c
libburn/sg.h
libburn/os-libcdio.h
libburn/sg-dummy.c
libburn/sg-freebsd.c
libburn/sg-freebsd-port.c
libburn/sg-libcdio.c
libburn/sg-linux.c
Extended sg-API by sg_shutdown(), sg_dispose_drive(), sg_id_string()
2009.12.27.144733 [2983]
cdrskin/cdrskin.c
Reporting system adapter id with cdrskin -version
2009.12.29.115717 [2984]
configure.ac
Incremented middle .so number
2009.12.29.115854 [2985]
libburn/spc.c
Corrected a mode page size computation error which for now had no bad effect
2009.12.29.132537 [2986]
acinclude.m4
libburn/os.h
libburn/sg.c
Experimentally enabled FreeBSD system adapter for Debian kfreebsd
------------------------------------ cycle - cdrskin-0.7.5 - 2009.12.29.134637
* Experimental SCSI transport adapter via GNU libcdio
* Experimentally using FreeBSD system adapter for Debian kfreebsd
* Bug fix: System adapter for generic X/Open was missing in libburn release tarball
2009.12.29.224506 [2987]
acinclude.m4
Adaptions for Debian kfreebsd requested by Petr Salinger
2009.12.30.154140 [2988]
libburn/drive.c
libburn/sg-libcdio.c
Making use of new libcdio capability to obtain SCSI address tuple on Linux
2009.12.30.201025 [2990]
libburn/sg-libcdio.c
Silenced libcdio warnings
2010.01.01.124042 [2994]
libburn/drive.c
Bug fix: with non-Linux adapters there were 0 readable bytes on block devices
2010.01.01.124415 [2995]
libburn/sg-libcdio.c
Enabled block device size recognition with sg-libcdio on Linux
------------------------------------ cycle - cdrskin-0.7.5 - 2010.01.01.143104
* Bug fix: with non-Linux adapters there were 0 readable bytes on block devices
2010.01.04.134949 [3001]
libburn/write.c
libburn/libdax_msgs.h
Avoiding stream recording on BD if not 64 kB buffer
2010.01.04.135427 [3002]
libburn/os-libcdio.h
Enlarged buffer size of libcdio adapter on Linux to 64k
2010.01.09.142027 [3004]
libburn/sg-libcdio.c
Forgot to forward sense reply to higher levels
2010.01.09.142642 [3005]
libburn/spc.c
Better error message with unknown SCSI error codes
2010.01.09.143428 [3006]
libburn/spc.c
libburn/sbc.c
Revoked asynchronous eject, as we cannot distinguish out from unready
2010.01.12.165214 [3009]
libburn/sg-dummy.c
libburn/sg-freebsd-port.c
libburn/sg-libcdio.c
libburn/sg-linux.c
Corrected free capacity measurement of stdio: drives in regular files
12 Jan 2010 [3010]
doc/cookbook.txt
Fixed typos in MMC cookbook
2010.01.13.074028 [3011]
libburn/drive.c
Experimentally regard FreeBSD /dev/da[0-9] and /dev/cd[0-9] as block device
2010.01.13.074640 [3012]
libburn/sg-freebsd.c
Adaptions after encounter with FreeBSD 8.0
2010.01.13.171546 [3013]
libburn/libburn.h
Carified that apps must use 64 bit off_t or the lib must be tweaked.
14 Jan 2010 [3014]
14 Jan 2010 [3015]
test/libburner.c
Carified in libburner.c that apps must use 64 bit off_t.
2010.01.14.160633 [3016]
libburn/libburn.h
libburn/drive.c
Giving up drive probing by mode page sending
2010.01.14.160748 [3017]
libburn/sg-libcdio.c
Provisory rejection of FreeBSD ATAPI drives in sg-libcdio
2010.01.15.182615 [3018]
libburn/os-freebsd.h
libburn/sg-freebsd.c
Implemented adivisory FreeBSD drive locking via flock(2)
2010.01.16.125258 [3019]
libburn/drive.c
libburn/sg.h
libburn/sg-dummy.c
libburn/sg-freebsd.c
libburn/sg-freebsd-port.c
libburn/sg-libcdio.c
libburn/sg-linux.c
New OS adapter burn_os_is_2k_seekrw() replaces S_ISBLK() with pseudo-drives
2010.01.18.103410 [3023]
libburn/sg-linux.c
Changed a comment in sg-linux.c
------------------------------------ cycle - cdrskin-0.7.5 - 2010.01.18.104011
* Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
21 Jan 2010 [3028]
cdrskin/cdrskin.1
Changed man page example from -toc to -minfo
2010.01.21.104741 [3029]
libburn/sg-freebsd.c
libburn/sg-libcdio.c
Learned how to inquire size of disk-like FreeBSD devices
22 Jan 2010 [3030]
svn copy -m "Branching for libburn release 0.7.6" \
http://svn.libburnia-project.org/libburn/trunk \
http://svn.libburnia-project.org/libburn/branches/ZeroSevenSix
2010.01.22.130001 []
Makefile.am
configure.ac
README
libburn/libburn.h
cdrskin/cdrskin.c
cdrskin/README
cdrskin/compile_cdrskin.sh
cdrskin/cdrskin_timestamp.h
cdrskin/cdrskin_eng.html
Made number transition to 0.7.6
22 Jan 2010 [3032]
COPYRIGHT
cdrskin/cdrskin.c
doc/cookbook.txt
libburn/libdax_msgs.h
libburn/libdax_msgs.c
test/libburner.c
test/telltoc.c
Lifted ban to derive GPLv3, extended copyright range to 2010
22 Jan 2009 [3033]
- cdrskin/add_ts_changes_to_libburn_0_7_4
- cdrskin/add_ts_changes_to_libburn_0_7_5
+ cdrskin/add_ts_changes_to_libburn_0_7_6
+ cdrskin/add_ts_changes_to_libburn_0_7_7
Updated cdrskin tarball generator
22 Jan 2009 []
cdrskin/changelog.txt
Documented changes and release timestamp
------------------------------ release - cdrskin-0.7.6.pl00 - 2010.01.22.130001
* Bug fix: System adapter for generic X/Open was missing in libburn release tarball
* Bug fix: with non-Linux adapters there were 0 readable bytes on block devices
* Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
* Enabled FreeBSD system adapter for Debian kfreebsd
* Experimental SCSI transport adapter via GNU libcdio 0.83git
------------------------------------ cycle - cdrskin-0.7.7 -
------------------------------------ cycle - cdrskin-0.7.7 -
------------------------------------ cycle - cdrskin-0.7.7 -
------------------------------------ cycle - cdrskin-0.7.3 -
===============================================================================
TODO
===============================================================================
- After writing first session and reload:
Drive current: -dev '/dev/cd0'
Drive type : vendor 'TSSTcorp' product 'CDDVDW SH-S223C' revision 'SB02'
Media current: DVD-RW sequential recording
Media product: RITEKW01 , Ritek Corp
Media status : is written , is appendable
TOC layout : Idx , sbsector , Size , Volume Id
ISO session : 1 , 0 , 232357s , ISOIMAGE
Other session: 2 , 261200 , 2036688s ,
Media summary: 2 sessions, 2269200 data blocks, 4432m data, 3978m free
Media nwa : 261200s
dvd+rw-mediainfo shows 3 sessions with 2 tracks.
Firmware bug.
- USB stick and drive on FreeBSD
- how to detect random-read-write device ?
--- libcdio ---
24 Dec 2009 [29de1d8bcb614a8360b519c5843c5852f78101db]
include/cdio/mmc.h
lib/driver/generic.h
lib/driver/mmc.c
lib/driver/libcdio.sym ( - cdio_version)
New API function mmc_last_cmd_sense()
24 Dec 2009 [890b5610a8ec01609df8997f8031324af5bb4219]
lib/driver/gnu_linux.c
Linux driver makes available the sense reply of the most recent MMC command
(Is there a place to register access modes MMC_RDWR and MMC_RDWR_EXCL ?)
24 Dec 2009 [20f762c3c12c06b52a47b401eb913c69c72ddcf8]
include/cdio/version.h.in
lib/driver/util.c
lib/driver/libcdio.sym ( + cdio_version)
New API function cdio_version() tell libcdio version at runtime
24 Dec 2009 [7cc7484a0b93268260c02ec35c46e1456f0fb38a]
lib/driver/gnu_linux.c
lib/driver/util.c
Small repairs to the previous two changees
30 Dec 2009 07_cdio_get_arg_scsi_tuple_linux.tgz [cf882cfd20912fed94d1a4a2e057bbcf68c496a1]
lib/driver/generic.h
lib/driver/_cdio_generic.c
lib/driver/gnu_linux.c
New cdio_get_arg() key "scsi-tuple-linux"
15 Jan 2010 10_add_mmc_rdwr_excl_on_freebsd.tgz [bd096b3eca0644044a872c1f0d31a75395d420a4]
NEWS
test/test_mmc_rdwr.c
lib/driver/FreeBSD/freebsd.h
lib/driver/FreeBSD/freebsd.c
lib/driver/FreeBSD/freebsd_cam.c
lib/driver/FreeBSD/freebsd_ioctl.c
FreeBSD driver augmented by MMC_RDWR_EXCL
Todo:
Driver-Todo:
- implement MMC_RDWR and MMC_RDWR_EXCL
- record SCSI sense reply in generic_img_private_t.scsi_mmc_sense
- rectify return values to DRIVER_OP_*
(- obtain SCSI address tuple)
- test concurrent drive access attempts resp. exclusivity of drive access
--------------------------------- bugs -------------------------------------
@ -8045,8 +7194,6 @@ READ TRACK INFORMATION[#5]:
------------------------------ end of bugs ---------------------------------
- xorriso -as tar (Rocky wants me to begin with -x)
Support for BD-R SRM+POW
? Provide an option to open track source file O_DIRECT ?

View File

@ -1,26 +1,19 @@
#!/bin/sh
# compile_cdrskin.sh
# Copyright 2005 - 2010 Thomas Schmitt, scdbackup@gmx.net, GPL
# Copyright 2005 - 2009 Thomas Schmitt, scdbackup@gmx.net, GPL version 2
# to be executed within ./libburn-* resp ./cdrskin-*
debug_opts="-O2"
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
fifo_opts="-DCdrskin_use_libburn_fifO"
libvers="-DCdrskin_libburn_0_7_6"
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
# burn="libburn/libburn_libburn_la-"
burn="libburn/"
cleanup_src_or_obj="$burn"cleanup.o
libdax_msgs_o="$burn"libdax_msgs.o
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libvers="-DCdrskin_libburn_0_7_2"
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"
libcdio=
fifo_source="cdrskin/cdrfifo.c"
compile_cdrskin=1
compile_cdrfifo=0
@ -38,20 +31,20 @@ do
then
libvers="-DCdrskin_libburn_cvs_A60220_tS"
libdax_audioxtr_o=
libdax_msgs_o="$burn"message.o
libdax_msgs_o="libburn/message.o"
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
elif test "$i" = "-libburn_0_7_6"
elif test "$i" = "-libburn_0_7_2"
then
libvers="-DCdrskin_libburn_0_7_6"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
libvers="-DCdrskin_libburn_0_7_2"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
libdax_msgs_o="libburn/libdax_msgs.o"
cleanup_src_or_obj="libburn/cleanup.o"
elif test "$i" = "-libburn_svn"
then
libvers="-DCdrskin_libburn_0_7_7"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
libvers="-DCdrskin_libburn_0_7_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"
@ -62,9 +55,6 @@ do
elif test "$i" = "-no_largefile"
then
largefile_opts=
elif test "$i" = "-dvd_obs_64k"
then
def_opts="$def_opts -DCdrskin_dvd_obs_default_64K"
elif test "$i" = "-do_not_compile_cdrskin"
then
compile_cdrskin=0
@ -76,19 +66,6 @@ do
elif test "$i" = "-do_strip"
then
do_strip=1
elif test "$i" = "-use_libburn_fifo"
then
fifo_opts="-DCdrskin_use_libburn_fifO"
elif test "$i" = "-use_no_libburn_fifo"
then
fifo_opts=""
elif test "$i" = "-use_no_cdrfifo"
then
fifo_source=
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
elif test "$i" = "-use_libcdio"
then
libcdio="-lcdio"
elif test "$i" = "-g"
then
debug_opts="-g"
@ -98,13 +75,9 @@ do
echo "Options:"
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -libburn_0_7_6 set macro to match libburn-0.7.6"
echo " -libburn_0_7_2 set macro to match libburn-0.7.2"
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
echo " -use_libcdio link with -lcdio because libburn uses it."
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
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."
@ -125,14 +98,13 @@ echo "Build timestamp : $timestamp"
if test "$compile_cdrskin"
then
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj $libcdio"
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 \
$fifo_opts \
$def_opts \
\
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
@ -144,33 +116,31 @@ then
\
$cleanup_src_or_obj \
\
"$burn"async.o \
"$burn"debug.o \
"$burn"drive.o \
"$burn"file.o \
"$burn"init.o \
"$burn"options.o \
"$burn"source.o \
"$burn"structure.o \
libburn/async.o \
libburn/debug.o \
libburn/drive.o \
libburn/file.o \
libburn/init.o \
libburn/options.o \
libburn/source.o \
libburn/structure.o \
\
"$burn"sg.o \
"$burn"write.o \
"$burn"read.o \
libburn/sg.o \
libburn/write.o \
libburn/read.o \
$libdax_audioxtr_o \
$libdax_msgs_o \
\
"$burn"mmc.o \
"$burn"sbc.o \
"$burn"spc.o \
"$burn"util.o \
libburn/mmc.o \
libburn/sbc.o \
libburn/spc.o \
libburn/util.o \
\
"$burn"sector.o \
"$burn"toc.o \
libburn/sector.o \
libburn/toc.o \
\
"$burn"crc.o \
"$burn"ecma130ab.o \
libburn/crc.o \
\
$libcdio \
-lpthread
ret=$?
@ -212,8 +182,8 @@ then
-DDewav_without_libburN \
-o test/dewav \
test/dewav.c \
"$burn"libdax_audioxtr.o \
"$burn"libdax_msgs.o \
libburn/libdax_audioxtr.o \
libburn/libdax_msgs.o \
\
-lpthread

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [0.7.6], [http://libburnia-project.org])
AC_INIT([libburn], [0.7.2], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -7,7 +7,7 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects])
dnl Notes by ts A71207 - B00122 :
dnl Notes by ts A71207 - A91012 :
dnl
dnl Regrettably the meaning of the various version types was misunderstood
dnl before version 0.4.1.
@ -75,8 +75,6 @@ dnl 0.6.6 = libburn.so.4.31.0
dnl 0.6.8 = libburn.so.4.33.0
dnl 0.7.0 = libburn.so.4.35.0
dnl 0.7.2 = libburn.so.4.37.0
dnl 0.7.4 = libburn.so.4.39.0
dnl 0.7.6 = libburn.so.4.41.0
dnl
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
@ -102,7 +100,7 @@ dnl
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
BURN_MAJOR_VERSION=0
BURN_MINOR_VERSION=7
BURN_MICRO_VERSION=6
BURN_MICRO_VERSION=2
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
AC_SUBST(BURN_MAJOR_VERSION)
@ -113,15 +111,15 @@ AC_SUBST(BURN_VERSION)
dnl Libtool versioning
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
dnl
dnl ts B00122
dnl This is the release version libburn-0.7.6 = libburn.so.4.41.0
dnl ### This is the development version after above release version
dnl ts A91012
dnl ### This is the release version libburn-0.7.2 = libburn.so.4.37.0
dnl This is the development version after above release version
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
dnl
dnl SONAME = 45 - 41 = 4 . Linux library name = libburn.so.4.41.0
LT_CURRENT=45
LT_AGE=41
dnl SONAME = 41 - 37 = 4 . Linux library name = libburn.so.4.37.0
LT_CURRENT=41
LT_AGE=37
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -181,63 +179,6 @@ dnl If this would be done more specifically in Makefile.am
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
CFLAGS="$CFLAGS $STATVFS_DEF"
dnl ts A91122
AC_ARG_ENABLE(track-src-odirect,
[ --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no],
, enable_track_src_odirect=no)
if test x$enable_track_src_odirect = xyes; then
LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
echo "enabled use of O_DIRECT with track input"
else
LIBBURN_O_DIRECT_DEF=
echo "disabled use of O_DIRECT with track input"
fi
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
dnl ### AC_SUBST(LIBBURN_O_DIRECT_DEF)
CFLAGS="$CFLAGS $LIBBURN_O_DIRECT_DEF"
dnl ts A91116
AC_ARG_ENABLE(dvd-obs-64k,
[ --enable-dvd-obs-64k 64 KB default size for DVD/BD writing, default=no],
, enable_fifo_odirect=no)
if test x$enable_dvd_obs_64k = xyes; then
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
echo "enabled write size default 64 KB on DVD and BD"
else
LIBBURN_DVD_OBS_64K=
echo "disabled write size default 64 KB on DVD and BD"
fi
CFLAGS="$CFLAGS $LIBBURN_DVD_OBS_64K"
dnl ts A91218
AC_ARG_ENABLE(libcdio,
[ --enable-libcdio Enable EXPERIMENTAL use of libcdio as system adapter, default=no],
, enable_libcdio=no)
if test x$enable_libcdio = xyes; then
dnl Check whether there is libcdio-devel and libcdio-runtime.
dnl If not, erase this macro
LIBCDIO_DEF="-DLibburn_use_libcdiO"
dnl The empty yes case obviously causes -lcdio to be linked
AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= )
else
LIBCDIO_DEF=
fi
if test x$LIBCDIO_DEF = x
then
if test x$enable_libcdio = xyes
then
echo "WARNING: could not enable use of libcdio as system adapter"
fi
else
echo "enabled EXPERIMENTAL use of libcdio as system adapter"
CFLAGS="$CFLAGS $LIBCDIO_DEF"
LIBCDIO_REQUIRED=0.83
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
fi
dnl Add compiler-specific flags
dnl See if the user wants aggressive optimizations of the code
@ -257,6 +198,7 @@ else
CFLAGS="$CFLAGS -DDEBUG"
fi
dnl Determine target directory for libburn-*.pc
dnl Important: Must be performed _after_ TARGET_SHIZZLE
dnl

View File

@ -73,9 +73,9 @@ compatible for a good while.
@subsection libburner-help Libburner --help
<pre>
Usage: test/libburner
[--drive address|driveno|"-"] [--audio]
[--drive <address>|<driveno>|"-"] [--audio]
[--blank_fast|--blank_full|--format] [--try_to_simulate]
[--multi] [one or more imagefiles|"-"]
[--multi] [<one or more imagefiles>|"-"]
Examples
A bus scan (needs rw-permissions to see a drive):
test/libburner --drive -

View File

@ -1,4 +1,4 @@
libburnia-project.org Optical Media Rotisserie Recipes as of January 2010
libburnia-project.org Optical Media Rotisserie Recipes as of January 2009
Content:
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
@ -86,7 +86,7 @@ parameters:
BUFE Buffer Underrun protection 0=off, 1=on
Test Write -dummy mode for writing 0=off, 1=on
Write Type Packet/TAO/SAO/RAW 01h = TAO
Multi-session Whether to keep appendable 00b = finalize
Multi-session Wether to keep appendable 00b = finalize
11b = keep appendable
Track Mode Describes frame type 4 for data , 0 for audio
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
@ -119,22 +119,19 @@ A track must at least contain 300 payload blocks: 4 seconds of audio or
600 KiB of data.
(mmc5r03c.pdf 6.3.3.1.2)
Up to december 2009 the track was closed by 5Bh CLOSE TRACK SESSION Close
Function 001b. Older MMC specifies a valid Logical Track Number FFh to depict
the open track. MMC-5 is quite silent about this. FFh worked for my drives.
The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b.
Older MMC specifies a valid Logical Track Number FFh to depict the open track.
MMC-5 is quite silent about this. FFh works for my drives.
(mmc5r03c.pdf 6.3.3.1.2)
This is omitted since libburn-0.7.4, relying entirely on 35h SYNCHRONIZE CACHE.
First appeared a drive where CLOSE TRACK fails in simulation mode, later
another one produced error replies even with real burning.
After that, a new track may be written beginning with sending the mode page 05h
again. It is not tested whether 05h can be omitted if Track Mode and Data Block
again. It is not tested wether 05h can be omitted if Track Mode and Data Block
Type are the same as with the previous track.
The new track will be added to the session which was opened by the first track.
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
with Logical Track Number 0 closes the session. It depends on the Multi-Session
value in mode page 05h whether the disc is finalized or stays appendable.
value in mode page 05h wether the disc is finalized or stays appendable.
(mmc5r03c.pdf 6.3.3.1.3)
@ -205,7 +202,7 @@ for finalized disc.
In libburn the address of the first track in the last session is obtained from
the last session's POINT = A0h and from the track descriptor with the POINT
value matching the PMIN value of the A0h descriptor.
Untested is whether POINT = B0h and 52h READ TRACK INFORMATION are always in
Untested is wether POINT = B0h and 52h READ TRACK INFORMATION are always in
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
@ -311,7 +308,7 @@ A Write Parameters mode page 05h has to be composed and transmitted via
BUFE Buffer Underrun protection 0=off, 1=on
Test Write -dummy mode for writing 0=off, 1=on
Write Type Packet/TAO/SAO/RAW 02h = SAO
Multi-session Whether to keep appendable 00b = finalize
Multi-session Wether to keep appendable 00b = finalize
11b = keep appendable
Track Mode Describes frame type 0 (is ignored)
Data Block Type Layout of payload blocks 0 (is ignored)
@ -352,7 +349,7 @@ There is no separator between the tracks of a pure mode SAO session.
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
between data mode tracks and audio mode tracks.)
(libburn sends its own buffer to the drive at the end of each track but does
not sync the drive's chache. It is unclear whether this separation of tracks
not sync the drive's chache. It is unclear wether this separation of tracks
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
harm in any case and would probably be unavoidable if audio and data tracks
were mixed.)
@ -758,8 +755,7 @@ The only known way to get full speed from DVD-RAM or BD-RE with enabled defect
management is the use of AAh WRITE12 with Streaming Bit set to 1.
(mmc5r03c.pdf 6.45)
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
With the tested BD-RE one must write full 64 kB buffers, or else writing
might not get into effect at all.
With the tested BD-RE one has to write full 64 kB buffers.
Although it seems not optimal, this is specified not only to disable the
cumbersome checkread but also to ignore known defects and to write data
@ -773,8 +769,7 @@ MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
None of the features of profiles 0012h and 0043h promises the existence of
AAh WRITE12.
(mmc5r03c.pdf 5.4.13, 6.45)
Nevertheless it worked on all tested drives if proper alignment and block
size was observed.
Nevertheless it worked on all tested drives if proper alignment was observed.
-------------------------------------------------------------------------------
@ -846,8 +841,6 @@ This chain gives the start addresses of sessions. The sector count minus start
address gives the size of a particular session. ECMA-119 explains how to
retrieve more info from the PVD (e.g. the volume id).
See also the multi-session example in libisofs/doc/checksums.txt.
-------------------------------------------------------------------------------
@ -940,7 +933,7 @@ Multi-Session by the application.
LS_V Link size valid 1=true
Test Write -dummy mode for writing 0=off, 1=on
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
Multi-session Whether to keep appendable 00b = finalize
Multi-session Wether to keep appendable 00b = finalize
11b = keep appendable
Track Mode Describes frame type 5 [*1]
Data Block Type Layout of payload blocks 8 [*2]
@ -987,7 +980,7 @@ from the reply of 51h READ DISC INFORMATION requesting Data Type 000b
Multiple tracks are permissible in a single session. After all of them have
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
Number 0 closes the session. It depends on the Multi-Session value in mode
page 05h whether the disc is finalized or stays appendable.
page 05h wether the disc is finalized or stays appendable.
(mmc5r03c.pdf 6.3.3.2.3)
@ -1012,7 +1005,7 @@ The mode page 05h to be sent :
LS_V Link size valid 0=false [*3]
Test Write -dummy mode for writing 0=off, 1=on
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
Multi-session Whether to keep appendable 00b = finalize
Multi-session Wether to keep appendable 00b = finalize
Track Mode Describes frame type 5 [*1]
Data Block Type Layout of payload blocks 8 [*2]
Link Size ??? 0 [*3]
@ -1229,7 +1222,7 @@ No mode page 05h is to be sent.
growisofs sends a page but the specs clearly state that one shall not do.
(mmc5r03c.pdf 7.5.3)
It is optional whether a track size is reserved in advance or not. Eventually
It is optional wether a track size is reserved in advance or not. Eventually
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
already be aligned to 32 KiB.
(mmc5r03c.pdf 6.31)

View File

@ -627,8 +627,7 @@ int burn_fifo_start(struct burn_source *source, int flag)
fs->is_started = -1;
/* create and set up ring buffer */;
fs->buf = burn_os_alloc_buffer(
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
fs->buf = calloc(fs->chunksize, fs->chunks);
if (fs->buf == NULL) {
/* >>> could not start ring buffer */;
return -1;

View File

@ -90,7 +90,6 @@ void burn_drive_free_subs(struct burn_drive *d)
if (d->stdio_fd >= 0)
close (d->stdio_fd);
d->stdio_fd = -1;
sg_dispose_drive(d, 0);
}
@ -425,6 +424,10 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
char msg[BURN_DRIVE_ADR_LEN + 160];
int ret;
/* ts A60821
<<< debug: for tracing calls which might use open drive fds */
int mmc_function_spy(struct burn_drive *d, char * text);
d->drive_role = 1; /* MMC drive */
t = burn_drive_register(d);
@ -907,29 +910,6 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
out->write_simulate = !!d->mdata->simulate;
out->c2_errors = !!d->mdata->c2_pointers;
out->drive = d;
#ifdef Libburn_dummy_probe_write_modeS
/* ts A91112 */
/* Set default block types. The call d->probe_write_modes() is quite
obtrusive. It may be performed explicitely by new API call
burn_drive_probe_cd_write_modes().
*/
if (out->write_dvdram || out->write_dvdr ||
out->write_cdrw || out->write_cdr) {
out->tao_block_types = d->block_types[BURN_WRITE_TAO] =
BURN_BLOCK_MODE1 | BURN_BLOCK_RAW0;
out->sao_block_types = d->block_types[BURN_WRITE_SAO] =
BURN_BLOCK_SAO;
} else {
out->tao_block_types = d->block_types[BURN_WRITE_TAO] = 0;
out->sao_block_types = d->block_types[BURN_WRITE_SAO] = 0;
}
out->raw_block_types = d->block_types[BURN_WRITE_RAW] = 0;
out->packet_block_types = 0;
#else /* Libburn_dummy_probe_write_modeS */
/* update available block types for burners */
if (out->write_dvdram || out->write_dvdr ||
out->write_cdrw || out->write_cdr)
@ -938,30 +918,6 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
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];
#endif /* ! Libburn_dummy_probe_write_modeS */
return 1;
}
/* ts A91112 - B00114 API */
/* Probe available CD write modes and block types.
*/
int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo)
{
struct burn_drive *d = dinfo->drive;
if (d == NULL)
return 0;
if (dinfo->write_dvdram || dinfo->write_dvdr ||
dinfo->write_cdrw || dinfo->write_cdr)
d->probe_write_modes(d);
dinfo->tao_block_types = d->block_types[BURN_WRITE_TAO];
dinfo->sao_block_types = d->block_types[BURN_WRITE_SAO];
dinfo->raw_block_types = d->block_types[BURN_WRITE_RAW];
dinfo->packet_block_types = d->block_types[BURN_WRITE_PACKET];
return 1;
}
@ -1322,7 +1278,6 @@ int burn_drive__fd_from_special_adr(char *adr)
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
{
int ret = -1, fd = -1, role = 0;
int is_block_dev = 0;
/* divided by 512 it needs to fit into a signed long integer */
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
off_t read_size = -1;
@ -1339,18 +1294,17 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
else
ret = stat(fname, &stbuf);
if (ret != -1) {
is_block_dev = burn_os_is_2k_seekrw(fname, 0);
if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size;
else if (is_block_dev) {
else if (S_ISBLK(stbuf.st_mode)) {
ret = burn_os_stdio_capacity(fname,
&read_size);
if (ret <= 0)
read_size = (off_t) 0x7ffffff0 *
(off_t) 2048;
read_size = -1;
}
}
if (ret == -1 || is_block_dev || S_ISREG(stbuf.st_mode)) {
if (ret == -1 || S_ISBLK(stbuf.st_mode) ||
S_ISREG(stbuf.st_mode)) {
ret = burn_os_stdio_capacity(fname, &size);
if (ret == -1) {
libdax_msgs_submit(libdax_messenger, -1,
@ -1566,23 +1520,14 @@ int burn_drive_is_enumerable_adr(char *adr)
#define BURN_DRIVE_MAX_LINK_DEPTH 20
/* ts A60922 ticket 33 */
/* @param flag bit0= no debug messages
bit1= resolve only links,
do not rely on drive list for resolving via st_rdev
*/
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
int flag)
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;
struct stat stbuf;
if (flag & 1)
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )",
path);
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )", path);
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
if (flag & 1)
burn_drive_adr_debug_msg(
burn_drive_adr_debug_msg(
"burn_drive_resolve_link aborts because link too deep",
NULL);
return 0;
@ -1590,15 +1535,12 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
(*recursion_count)++;
ret = readlink(path, link_target, sizeof(link_target));
if (ret == -1) {
if (flag & 1)
burn_drive_adr_debug_msg("readlink( %s ) returns -1",
path);
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);
if (flag & 1)
burn_drive_adr_debug_msg(msg, NULL);
burn_drive_adr_debug_msg(msg, NULL);
return -1;
}
link_target[ret] = 0;
@ -1611,25 +1553,10 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
} else
adrpt = link_target;
}
if (flag & 2) {
/* Link-only recursion */
if (lstat(adrpt, &stbuf) == -1) {
;
} else if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
ret = burn_drive_resolve_link(adrpt, adr,
recursion_count, flag);
} else {
strcpy(adr, adrpt);
}
} else {
/* Link and device number recursion */
ret = burn_drive_convert_fs_adr_sub(adrpt, adr,
recursion_count);
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
link_target, ret);
}
if (flag & 1)
burn_drive_adr_debug_msg(msg, NULL);
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;
}
@ -1803,7 +1730,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
return 0;
}
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
ret = burn_drive_resolve_link(path, adr, rec_count, 0);
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);
@ -2642,9 +2569,6 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
if (S_ISBLK(stbuf1.st_mode) && S_ISBLK(stbuf2.st_mode) &&
stbuf1.st_rdev == stbuf2.st_rdev)
return 1; /* same major,minor device number */
if (S_ISCHR(stbuf1.st_mode) && S_ISCHR(stbuf2.st_mode) &&
stbuf1.st_rdev == stbuf2.st_rdev)
return 1; /* same major,minor device number */
/* Are both filesystem objects related to the same MMC drive */
if (conv_ret2 <= 0)

View File

@ -1,850 +0,0 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
This code module implements the production of RSPC parity bytes (P- and Q-
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf
The following statements about Galois Fields have been learned mostly from
http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.pdf
by James S. Plank after an e-mail exchange with Norbert Preining.
The output has been compared with the output of the old code of libburn
which was labeled "borrowed HEAVILY from cdrdao" and claimed by Joerg
Schilling to stem from code by Heiko Eissfeldt.
-------------------------------------------------------------------------
Note: In this text, "^" denotes exponentiation and not the binary exor
operation. Confusingly in the C code "^" is said exor.
Note: This is not C1, C2 which is rather mentioned in ECMA-130 Annex C and
always performed inside the drive.
-------------------------------------------------------------------------
RSPC resp. P- and Q-Parity
ECMA-130 Annex A prescribes to compute the parity bytes for P-columns and
Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating
polynomials x^8+x^4+x^3+x^2+1 (i.e. 0x11d) and x^1 (i.e. 0x02).
Bytes 12 to 2075 of a audio-sized sector get ordered in two byte words
as 24 rows and 43 columns. Then this matrix is split into a LSB matrix
and a MSB matrix of the same layout. Parity bytes are to be computed
from these 8-bit values.
2 P-bytes cover each column of 24 bytes. They get appended to the matrix
as rows 24 and 25.
2 Q-bytes cover each the 26 diagonals of the extended matrix.
Both parity byte pairs have to be computed so that extended rows or
diagonals match this linear equation:
H x V = (0,0)
H is a 2-row matrix of size n matching the length of the V ectors
[ 1 1 ... 1 1 ]
[ x^(n-1) x^(n-2) x^1 1 ]
Vp represents a P-row. It is a byte vector consisting of row bytes at
position 0 to 23 and the two parity bytes which shall be determined
at position 24 and 25. So Hp has 26 columns.
Vq represents a Q-diagonal. It is a byte vector consisting of diagonal
bytes at position 0 to 42 and the two parity bytes at position 43 and 44.
So Hq has 45 columns. The Q-diagonals cover P-parity bytes.
By applying some high school algebra one gets the parity bytes b0, b1 of
vector V = (n_payload_bytes, b0 , b1) as
b0 = ( H[n] * SUM(n_payload_bytes) - H[0..(n-1)] x n_payload_bytes )
/ (H[n+1] - H[n])
b1 = - SUM(n_payload_bytes) - b0
H[i] is the i-the element of the second row of matrix H. E.g. H[0] = x^(n-1)
The result has to be computed by Galois field arithmetics. See below.
The P-parity bytes of each column get reunited as LSB and MSB of two words.
word1 gets written to positions 1032 to 1074, word0 to 1075 to 1117.
The Q-parity bytes of each diagonal get reunited too. word1 goes to 1118
to 1143, word0 to 1144 to 1169.
>>> I do not read this swap of word1 and word0 from ECMA-130 Annex A.
>>> But the new output matches the old output only if it is done that way.
>>> See correctness reservation below.
Algebra on Galois fields is the same as on Rational Numbers.
But arithmetics is defined by operations on polynomials rather than the
usual integer arithmetics on binary numbers.
Addition and subtraction are identical with the binary exor operator.
Multiplication and division would demand polynomial division, e.g. by the
euclidian algorithm. The computing path over logarithms and powers follows
algebra and allows to reduce the arithmetic task to table lookups, additions
modulo 255, and exor operations. Note that the logarithms are natural
numbers, not polynomials. They get added or subtracted by the usual addition
(not by exor) and their polynomial power depends on their value modulo 255.
Needed are a logarithm table and a power table (or inverse logarithm table)
for Galois Field GF(2^8) which will serve to perform the peculiar
multiplication and division operation of Galois fields.
The power table is simply an enumeration of x^n accorting to
GF-multiplication. It also serves as second line of matrix H for the parity
equations:
Hp[i] = gfpow[25-i] , i out of {0,..,25}
Hq[i] = gfpow[44-i] , i out of {0,..,44}
The logarithm table is the inverse permutation of the power table.
Some simplifications apply to the implementation:
In the world of Galois fields there is no difference between - and +.
The term (H[n+1] - H[n]) is constant: 3.
-------------------------------------------------------------------------
Scrambling
ECMA-130 Annex B prescribes to exor the byte stream of an audio-sized sector
with a sequence of pseudo random bytes. It mentions polynomial x^15+x+1 and
a 15-bit register.
It shows a diagram of a Feedback Shift Register with 16 bit boxes, though.
Comparing this with explanations in
http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm
one can recognize the diagram as a Fibonacci Implementation. But there seems
really to be one bit box too many.
The difference of both lengths is expressed in function next_bit() by
the constants 0x3fff,0x4000 for 15 bit versus 0x7fff,0x8000 for 16 bits.
Comparing the output of both alternatives with the old scrambler output
lets 15 bit win for now.
So the prescription is to start with 15 bit value 1, to use the lowest bit
as output, to shift the bits down by one, to exor the output bit with the
next lowest bit, and to put that exor result into bit 14 of the register.
-------------------------------------------------------------------------
Correctness Reservation
In both cases, parity and scrambling, the goal for now is to replicate the
output of the dismissed old lec.c by output which is based on published
specs and own implementation code. Whether they comply to ECMA-130 is a
different question which can only be answered by real test cases for
raw CD recording.
Of course this implementation will be corrected so that it really complies
to ECMA-130 as soon as evidence emerges that it does not yet.
*/
/* ------------------------------------------------------------------------- */
/* Power and logarithm tables for GF(2^8), parity matrices for ECMA-130.
Generated by burn_rspc_setup_tables() and burn_rspc_print_tables().
The highest possible sum of gflog[] values is is 508. So the table gfpow[]
with period 255 was manually unrolled to 509 elements to avoid one modulo
255 operation in burn_rspc_mult().
Proposed by D. Hugh Redelmeier.
*/
static unsigned char gfpow[509] = {
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,
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,
};
static unsigned char gflog[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
};
#define Libburn_use_h_matriceS 1
#ifdef Libburn_use_h_matriceS
/* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time
than using gfpow[25-i] resp. gfpow[44-1]. I blame this on the more
condensed data representation which slightly increases the rate of cache
hits.
Nevertheless this effect is very likely depending on the exact cache
size and architecture. In general, using h[] saves more than 8000
subtractions per sector.
*/
/* Parity matrices H as prescribed by ECMA-130 Annex A.
Actually just reverted order start pieces of gfpow[].
*/
static unsigned char h26[26] = {
3, 143, 201, 234, 117, 180, 90, 45, 152, 76,
38, 19, 135, 205, 232, 116, 58, 29, 128, 64,
32, 16, 8, 4, 2, 1,
};
static unsigned char h45[45] = {
238, 119, 181, 212, 106, 53, 148, 74, 37, 156,
78, 39, 157, 192, 96, 48, 24, 12, 6, 3,
143, 201, 234, 117, 180, 90, 45, 152, 76, 38,
19, 135, 205, 232, 116, 58, 29, 128, 64, 32,
16, 8, 4, 2, 1,
};
#endif /* Libburn_use_h_matriceS */
/* Pseudo-random bytes which of course are exactly the same as with the
previously used code.
Generated by function print_ecma_130_scrambler().
*/
static unsigned char ecma_130_annex_b[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
};
/* ------------------------------------------------------------------------- */
/* This is the new implementation of P- and Q-parity generation.
It needs about the same computing time as the old implementation (both
with gcc -O2 on AMD 64 bit). Measurements indicate that about 280 MIPS
are needed for 48x CD speed (7.1 MB/s).
*/
static unsigned char burn_rspc_mult(unsigned char a, unsigned char b)
{
if (a == 0 || b == 0)
return 0;
/* Optimization of (a == 0 || b == 0) by D. Hugh Redelmeier
if((((int)a - 1) | ((int)b - 1)) < 0)
return 0;
*/
return gfpow[gflog[a] + gflog[b]];
/* % 255 not necessary because gfpow is unrolled up to index 510 */
}
/* Divide by polynomial 0x03. Derived from burn_rspc_div() and using the
unrolled size of the gfpow[] array.
*/
static unsigned char burn_rspc_div_3(unsigned char a)
{
if (a == 0)
return 0;
return gfpow[230 + gflog[a]];
}
static void burn_rspc_p0p1(unsigned char *sector, int col,
unsigned char *p0_lsb, unsigned char *p0_msb,
unsigned char *p1_lsb, unsigned char *p1_msb)
{
unsigned char *start, b;
unsigned int i, sum_v_lsb = 0, sum_v_msb = 0;
unsigned int hxv_lsb = 0, hxv_msb = 0;
start = sector + 12 + 2 * col;
for(i = 0; i < 24; i++) {
b = *start;
sum_v_lsb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_lsb ^= burn_rspc_mult(b, h26[i]);
#else
hxv_lsb ^= burn_rspc_mult(b, gfpow[25 - i]);
#endif
b = *(start + 1);
sum_v_msb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_msb ^= burn_rspc_mult(b, h26[i]);
#else
hxv_msb ^= burn_rspc_mult(b, gfpow[25 - i]);
#endif
start += 86;
}
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
*p0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
*p0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
*p1_lsb = sum_v_lsb ^ *p0_lsb;
*p1_msb = sum_v_msb ^ *p0_msb;
}
void burn_rspc_parity_p(unsigned char *sector)
{
int i;
unsigned char p0_lsb, p0_msb, p1_lsb, p1_msb;
/* Loop over P columns */
for(i = 0; i < 43; i++) {
burn_rspc_p0p1(sector, i, &p0_lsb, &p0_msb, &p1_lsb, &p1_msb);
sector[2162 + 2 * i] = p0_lsb;
sector[2162 + 2 * i + 1] = p0_msb;
sector[2076 + 2 * i] = p1_lsb;
sector[2076 + 2 * i + 1] = p1_msb;
#ifdef Libburn_with_lec_generatoR
if(verbous) {
printf("p %2d : %2.2X %2.2X ", i,
(unsigned int) p0_lsb, (unsigned int) p0_msb);
printf("%2.2X %2.2X ",
(unsigned int) p1_lsb, (unsigned int) p1_msb);
printf("-> %d,%d\n", 2162 + 2 * i, 2076 + 2 * i);
}
#endif /* Libburn_with_lec_generatoR */
}
}
static void burn_rspc_q0q1(unsigned char *sector, int diag,
unsigned char *q0_lsb, unsigned char *q0_msb,
unsigned char *q1_lsb, unsigned char *q1_msb)
{
unsigned char *start, b;
unsigned int i, idx, sum_v_lsb = 0, sum_v_msb = 0;
unsigned int hxv_lsb = 0, hxv_msb = 0;
start = sector + 12;
idx = 2 * 43 * diag;
for(i = 0; i < 43; i++) {
if (idx >= 2236)
idx -= 2236;
b = start[idx];
sum_v_lsb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_lsb ^= burn_rspc_mult(b, h45[i]);
#else
hxv_lsb ^= burn_rspc_mult(b, gfpow[44 - i]);
#endif
b = start[idx + 1];
sum_v_msb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_msb ^= burn_rspc_mult(b, h45[i]);
#else
hxv_msb ^= burn_rspc_mult(b, gfpow[44 - i]);
#endif
idx += 88;
}
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
*q0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
*q0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
*q1_lsb = sum_v_lsb ^ *q0_lsb;
*q1_msb = sum_v_msb ^ *q0_msb;
}
void burn_rspc_parity_q(unsigned char *sector)
{
int i;
unsigned char q0_lsb, q0_msb, q1_lsb, q1_msb;
/* Loop over Q diagonals */
for(i = 0; i < 26; i++) {
burn_rspc_q0q1(sector, i, &q0_lsb, &q0_msb, &q1_lsb, &q1_msb);
sector[2300 + 2 * i] = q0_lsb;
sector[2300 + 2 * i + 1] = q0_msb;
sector[2248 + 2 * i] = q1_lsb;
sector[2248 + 2 * i + 1] = q1_msb;
#ifdef Libburn_with_lec_generatoR
if(verbous) {
printf("q %2d : %2.2X %2.2X ", i,
(unsigned int) q0_lsb, (unsigned int) q0_msb);
printf("%2.2X %2.2X ",
(unsigned int) q1_lsb, (unsigned int) q1_msb);
printf("-> %d,%d\n", 2300 + 2 * i, 2248 + 2 * i);
}
#endif /* Libburn_with_lec_generatoR */
}
}
/* ------------------------------------------------------------------------- */
/* The new implementation of the ECMA-130 Annex B scrambler.
It is totally unoptimized. One should make use of larger word operations.
Measurements indicate that about 50 MIPS are needed for 48x CD speed.
*/
void burn_ecma130_scramble(unsigned char *sector)
{
int i;
unsigned char *s;
s = sector + 12;
for (i = 0; i < 2340; i++)
s[i] ^= ecma_130_annex_b[i];
}
/* ------------------------------------------------------------------------- */
/* The following code is not needed for libburn but rather documents the
origin of the tables above. In libburn it will not be compiled.
*/
#ifdef Libburn_with_lec_generatoR
/* This function produced the content of gflog[] and gfpow[]
*/
static int burn_rspc_setup_tables(void)
{
unsigned int b, l;
memset(gflog, 0, sizeof(gflog));
memset(gfpow, 0, sizeof(gfpow));
b = 1;
for (l = 0; l < 255; l++) {
gfpow[l] = (unsigned char) b;
gflog[b] = (unsigned char) l;
b = b << 1;
if (b & 256)
b = b ^ 0x11d;
}
return 0;
}
/* This function printed the content of gflog[] and gfpow[] as C code
and compared the content with the tables of the old implementation.
h26[] and h45[] are reverted order copies of gfpow[]
*/
static int burn_rspc_print_tables(void)
{
int i;
printf("static unsigned char gfpow[255] = {");
printf("\n\t");
for(i= 0; i < 255; i++) {
printf("%3u, ", gfpow[i]);
#ifdef Libburn_with_old_lec_comparisoN
if(gfpow[i] != gf8_ilog[i])
fprintf(stderr, "*** ILOG %d : %d != %d ***\n", i, gfpow[i], gf8_ilog[i]);
#endif
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
printf("static unsigned char gflog[256] = {");
printf("\n\t");
for(i= 0; i < 256; i++) {
printf(" %3u,", gflog[i]);
#ifdef Libburn_with_old_lec_comparisoN
if(gflog[i] != gf8_log[i])
fprintf(stderr, "*** LOG %d : %d != %d ***\n", i, gflog[i], gf8_log[i]);
#endif
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
printf("static unsigned char h26[26] = {");
printf("\n\t");
for(i= 0; i < 26; i++) {
printf(" %3u,", gfpow[25 - i]);
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
printf("static unsigned char h45[45] = {");
printf("\n\t");
for(i= 0; i < 45; i++) {
printf(" %3u,",gfpow[44 - i]);
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
return 0;
}
/* This code was used to generate the content of array ecma_130_annex_b[].
*/
static unsigned short ecma_130_fsr = 1;
static int next_bit(void)
{
int ret;
ret = ecma_130_fsr & 1;
ecma_130_fsr = (ecma_130_fsr >> 1) & 0x3fff;
if (ret ^ (ecma_130_fsr & 1))
ecma_130_fsr |= 0x4000;
return ret;
}
static int print_ecma_130_scrambler(void)
{
int i, j, b;
ecma_130_fsr = 1;
printf("static unsigned char ecma_130_annex_b[2340] = {");
printf("\n\t");
for (i = 0; i < 2340; i++) {
b = 0;
for (j = 0; j < 8; j++)
b |= next_bit() << j;
printf("%3u, ", b);
if ((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n");
return 1;
}
#ifdef Libburn_with_general_rspc_diV
/* This is a general polynomial division function.
burn_rspc_div_3() has been derived from this by setting b to constant 3.
*/
static unsigned char burn_rspc_div(unsigned char a, unsigned char b)
{
int d;
if (a == 0)
return 0;
if (b == 0)
return -1;
d = gflog[a] - gflog[b];
if (d < 0)
d += 255;
return gfpow[d];
}
#endif /* Libburn_with_general_rspc_diV */
#endif /* Libburn_with_lec_generatoR */

View File

@ -1,23 +0,0 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
This code module implements the computations prescribed in ECMA-130 Annex A
and B. For explanations of the underlying mathematics see ecma130ab.c .
*/
#ifndef Libburn_ecma130ab_includeD
#define Libburn_ecma130ab_includeD 1
void burn_rspc_parity_p(unsigned char *sector);
void burn_rspc_parity_q(unsigned char *sector);
void burn_ecma130_scramble(unsigned char *sector);
#endif /* ! Libburn_ecma130ab_includeD */

View File

@ -1,6 +1,5 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
@ -28,6 +27,8 @@ 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)
{
@ -210,7 +211,7 @@ static int fifo_read(struct burn_source *source,
int size)
{
struct burn_source_fifo *fs = source->data;
int ret, todo, rpos, bufsize, diff, counted = 0;
int ret, todo, rpos, bufsize, diff;
if (fs->end_of_consumption) {
/* ??? msg: reading has been ended already */;
@ -255,9 +256,6 @@ static int fifo_read(struct burn_source *source,
"Forwarded input error ends output", 0, 0);
return -1;
}
if (!counted)
fs->empty_counter++;
counted = 1;
fifo_sleep(0);
}
diff = fs->buf_writepos - rpos; /* read volatile only once */
@ -287,7 +285,6 @@ static int fifo_read(struct burn_source *source,
(size - todo), fs->buf_readpos, (double) fs->out_counter);
*/
fs->get_counter++;
return (size - todo);
}
@ -315,10 +312,8 @@ static void fifo_free(struct burn_source *source)
burn_fifo_abort(fs, 0);
if (fs->inp != NULL)
burn_source_free(fs->inp);
if (fs->buf != NULL)
burn_os_free_buffer(fs->buf,
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
free(fs->buf);
free((char *) fs);
}
@ -326,8 +321,7 @@ static void fifo_free(struct burn_source *source)
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
{
struct burn_source_fifo *fs = source->data;
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes, fill;
int counted;
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
char *bufpt;
pthread_t thread_handle_storage;
@ -341,7 +335,6 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
/* wait for enough buffer space available */
wpos = fs->buf_writepos;
counted = 0;
while (1) {
rpos = fs->buf_readpos;
diff = rpos - wpos;
@ -352,28 +345,18 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
free_bytes = diff - 1;
else {
free_bytes = (bufsize - wpos) + rpos - 1;
if (bufsize - wpos < fs->inp_read_size)
if (bufsize - wpos < fs->chunksize)
trans_end = 1;
}
if (free_bytes >= fs->inp_read_size)
if (free_bytes >= fs->chunksize)
break;
if (!counted)
fs->full_counter++;
counted = 1;
fifo_sleep(0);
}
fill = bufsize - free_bytes - 1;
if (fill < fs->total_min_fill)
fs->total_min_fill = fill;
if (fill < fs->interval_min_fill)
fs->interval_min_fill = fill;
/* prepare the receiving memory */
bufpt = fs->buf + wpos;
if (trans_end) {
bufpt = burn_os_alloc_buffer(
(size_t) fs->inp_read_size, 0);
bufpt = calloc(fs->chunksize, 1);
if (bufpt == NULL) {
libdax_msgs_submit(libdax_messenger, -1,
0x00000003,
@ -387,13 +370,15 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
/* Obtain next chunk */
if (fs->inp->read != NULL)
ret = fs->inp->read(fs->inp,
(unsigned char *) bufpt, fs->inp_read_size);
(unsigned char *) bufpt, fs->chunksize);
else
ret = fs->inp->read_xt( fs->inp,
(unsigned char *) bufpt, fs->inp_read_size);
if (ret == 0)
(unsigned char *) bufpt, fs->chunksize);
if (ret > 0)
fs->in_counter += ret;
else if (ret == 0)
break; /* EOF */
else if (ret < 0) {
else {
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Read error on fifo input", errno, 0);
@ -402,21 +387,17 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->input_error = EIO;
break;
}
fs->in_counter += ret;
fs->put_counter++;
/* activate read chunk */
if (ret > fs->inp_read_size)
/* beware of ill custom burn_source */
ret = fs->inp_read_size;
if (ret > fs->chunksize) /* beware of ill custom burn_source */
ret = fs->chunksize;
if (trans_end) {
/* copy to end of buffer */
memcpy(fs->buf + wpos, bufpt, bufsize - wpos);
/* copy to start of buffer */
memcpy(fs->buf, bufpt + (bufsize - wpos),
fs->inp_read_size - (bufsize - wpos));
burn_os_free_buffer(bufpt, (size_t) fs->inp_read_size,
0);
fs->chunksize - (bufsize - wpos));
free(bufpt);
if (ret >= bufsize - wpos)
fs->buf_writepos = ret - (bufsize - wpos);
else
@ -452,9 +433,7 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
So in both cases the consumer is aware that reading is futile
or even fatal.
*/
if(fs->buf != NULL)
burn_os_free_buffer(fs->buf,
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
fs->buf = NULL;
fs->thread_handle= NULL;
@ -471,9 +450,7 @@ int burn_fifo_cancel(struct burn_source *source)
return(1);
}
/*
@param flag bit0= allow larger read chunks
*/
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
int chunksize, int chunks, int flag)
{
@ -500,10 +477,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
fs->thread_pid = 0;
fs->thread_is_valid = 0;
fs->inp = NULL; /* set later */
if (flag & 1)
fs->inp_read_size = 32 * 1024;
else
fs->inp_read_size = chunksize;
fs->chunksize = chunksize;
fs->chunks = chunks;
fs->buf = NULL;
@ -512,9 +485,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
fs->input_error = 0;
fs->end_of_consumption = 0;
fs->in_counter = fs->out_counter = 0;
fs->total_min_fill = fs->interval_min_fill = 0;
fs->put_counter = fs->get_counter = 0;
fs->empty_counter = fs->full_counter = 0;
src = burn_source_new();
if (src == NULL) {
@ -580,89 +550,34 @@ int burn_fifo_inquire_status(struct burn_source *source,
}
/* ts A91125 : API */
void burn_fifo_get_statistics(struct burn_source *source,
int *total_min_fill, int *interval_min_fill,
int *put_counter, int *get_counter,
int *empty_counter, int *full_counter)
{
struct burn_source_fifo *fs = source->data;
*total_min_fill = fs->total_min_fill;
*interval_min_fill = fs->interval_min_fill;
*put_counter = fs->put_counter;
*get_counter = fs->get_counter;
*empty_counter = fs->empty_counter;
*full_counter = fs->full_counter;
}
/* ts A91125 : API */
void burn_fifo_next_interval(struct burn_source *source,
int *interval_min_fill)
{
struct burn_source_fifo *fs = source->data;
int size, free_bytes, ret;
char *status_text;
*interval_min_fill = fs->interval_min_fill;
ret = burn_fifo_inquire_status(source,
&size, &free_bytes, &status_text);
fs->interval_min_fill = size - free_bytes - 1;
}
/* @param flag bit0= do not copy to buf but only wait until the fifo has read
bufsize or input ended.
The same happens if buf is NULL.
bit1= fill to max fifo size
*/
int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
int flag)
{
int size, free_bytes, ret, wait_count= 0;
char *status_text;
struct burn_source_fifo *fs = source->data;
if (buf == NULL)
flag |= 1;
/* Eventually start fifo thread by reading 0 bytes */
ret = fifo_read(source, (unsigned char *) NULL, 0);
if (ret<0)
{ret = 0; goto ex;}
return 0;
/* wait for at least bufsize bytes being ready */
while (1) {
ret= burn_fifo_inquire_status(source,
&size, &free_bytes, &status_text);
if (flag & 2) {
bufsize = size - (size % fs->inp_read_size) -
fs->inp_read_size;
if (bufsize <= 0)
{ret = 0; goto ex;}
}
if (size - fs->inp_read_size < bufsize) {
if (flag & 1) {
bufsize = size - (size % fs->inp_read_size) -
fs->inp_read_size;
if (bufsize <= 0)
{ret = 0; goto ex;}
} else {
libdax_msgs_submit(libdax_messenger, -1,
0x0002015c, LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH,
"Fifo size too small for desired peek buffer",
0, 0);
{ret = -1; goto ex;}
}
if (size < bufsize) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002015c,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Fifo size is smaller than desired peek buffer", 0, 0);
return -1;
}
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Fifo is already under consumption when peeking is desired",
0, 0);
{ret = -1; goto ex;}
return -1;
}
if(size - free_bytes >= bufsize) {
@ -671,33 +586,17 @@ int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
wait_count, status_text, size - free_bytes);
*/
if(!(flag & 1))
memcpy(buf, fs->buf, bufsize);
{ret = 1; goto ex;}
}
if (ret & 2) {
/* input has ended, not enough data arrived */
if (flag & 1)
{ret = 0; goto ex;}
memcpy(buf, fs->buf, bufsize);
return 1;
}
if (ret&2) { /* input has ended, not enough data arrived */
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Fifo input ended short of desired peek buffer size",
0, 0);
{ret = 0; goto ex;}
return 0;
}
if (free_bytes < fs->inp_read_size) {
/* Usable fifo size filled, not enough data arrived */
if (flag & 1)
{ret = 0; goto ex;}
libdax_msgs_submit(libdax_messenger, -1, 0x00020174,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Fifo alignment does not allow desired read size",
0, 0);
{ret = 0; goto ex;}
}
usleep(100000);
wait_count++;
@ -709,25 +608,5 @@ int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
*/
}
ret = 0;
ex:;
fs->total_min_fill = fs->interval_min_fill = fs->buf_writepos;
return(ret);
return(0);
}
/* ts A80713 : API */
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
int flag)
{
return burn_fifo_fill_data(source, buf, bufsize, 0);
}
/* ts A91125 : API */
int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
{
return burn_fifo_fill_data(source, NULL, bufsize,
1 | ((flag & 1) << 1));
}

View File

@ -35,7 +35,6 @@ struct burn_source_fifo {
/* the burn_source for which this fifo is acting as proxy */
struct burn_source *inp;
int inp_read_size;
/* <<< up to now it was only a pipe. This is on its way out. */
int outlet[2];
@ -52,14 +51,6 @@ struct burn_source_fifo {
off_t in_counter;
off_t out_counter;
int total_min_fill;
int interval_min_fill;
int put_counter;
int get_counter;
int empty_counter;
int full_counter;
};

View File

@ -59,12 +59,6 @@ int burn_sg_open_o_nonblock = 1;
to unconditional abort of the process */
int burn_sg_open_abort_busy = 0;
/* The message returned from sg_id_string() and/or sg_initialize()
*/
static char sg_initialize_msg[1024] = {""};
/* ts A61002 */
#include "cleanup.h"
@ -81,13 +75,6 @@ burn_abort_handler_t burn_global_signal_handler = NULL;
/* ts A70223 : wether implemented untested profiles are supported */
int burn_support_untested_profiles = 0;
/* ts A91111 :
whether to log SCSI commands (to be implemented in sg-*.c)
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
int burn_sg_log_scsi = 0;
/* ts A60925 : ticket 74 */
/** Create the messenger object for libburn. */
@ -116,14 +103,6 @@ int burn_initialize(void)
ret = burn_msgs_initialize();
if (ret <= 0)
return 0;
ret = sg_initialize(sg_initialize_msg, 0);
if (ret <= 0) {
libdax_msgs_submit(libdax_messenger, -1,
0x00020175,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
sg_initialize_msg, 0, 0);
return 0;
}
burn_running = 1;
return 1;
}
@ -151,22 +130,10 @@ void burn_finish(void)
/* ts A60924 : ticket 74 */
libdax_msgs_destroy(&libdax_messenger,0);
sg_shutdown(0);
burn_running = 0;
}
/* ts A91226 */
/** API function. See libburn.h */
char *burn_scsi_transport_id(int flag)
{
if (!burn_running)
sg_id_string(sg_initialize_msg, 0);
return sg_initialize_msg;
}
/* ts A60813 */
/** API function. See libburn.h */
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
@ -447,9 +414,3 @@ int burn_set_messenger(void *messenger)
return 1;
}
/* ts A91111 API */
void burn_set_scsi_logging(int flag)
{
burn_sg_log_scsi = flag & 7;
}

View File

@ -9,10 +9,8 @@ Applications must use 64 bit off_t. E.g. by defining
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
or take special precautions to interface with the library by 64 bit integers
where this .h files prescribe off_t.
To prevent 64 bit file i/o in the library would keep the application from
processing tracks of more than 2 GB size.
where this .h files prescribe off_t. Not to use 64 bit file i/o will keep the
application from producing and processing ISO images of more than 2 GB size.
*/
#include <sys/types.h>
@ -143,22 +141,19 @@ enum burn_write_types
only raw block types are supported
With DVD and BD media: not supported.
ts A90901: This had been disabled because its implementation
ts A90901: THIS HAS BEEN DISABLED because its implementation
relied on code from cdrdao which is not understood
currently.
A burn run will abort with "FATAL" error message
if this mode is attempted.
@since 0.7.2
ts A91016: Re-implemented according to ECMA-130 Annex A and B.
Now understood, explained and not stemming from cdrdao.
@since 0.7.4
*/
BURN_WRITE_RAW,
/** In replies this indicates that not any writing will work.
As parameter for inquiries it indicates that no particular write
mode shall is specified.
Do not use for setting a write mode for burning. It will not work.
Do not use for setting a write mode for burning. It won't work.
*/
BURN_WRITE_NONE
};
@ -764,19 +759,6 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed);
*/
void burn_set_verbosity(int level);
/* ts A91111 */
/** Enable resp. disable logging of SCSI commands (currently Linux only).
This call can be made at any time - even before burn_initialize().
It is in effect for all active drives and currently not very thread
safe for multiple drives.
@param flag Bitfield for control purposes. The default is 0.
bit0= log to file /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush output after each line
@since 0.7.4
*/
void burn_set_scsi_logging(int flag);
/* 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.
@ -867,12 +849,12 @@ void burn_allow_untested_profiles(int yes);
If the path leads to an existing file of any type other than directory,
then the result is a sequential write-only stdio-drive = drive role 3.
The special address form "stdio:/dev/fd/{number}" is interpreted literally
as reference to open file descriptor {number}. This address form coincides
The special address form "stdio:/dev/fd/<number>" is interpreted literally
as reference to open file descriptor <number>. This address form coincides
with real files on some systems, but it is in fact hardcoded in libburn.
Special address "stdio:-" means stdout = "stdio:/dev/fd/1".
The role of such a drive is determined by the file type obtained via
fstat({number}).
fstat(<number>).
Roles 2 and 3 perform all their eventual data transfer activities on a file
via standard i/o functions open(2), lseek(2), read(2), write(2), close(2).
@ -1064,19 +1046,6 @@ int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no,
*/
int burn_drive_grab(struct burn_drive *drive, int load);
/* ts B00114 */
/* Probe available CD write modes and block types. In earlier versions this
was done unconditionally on drive examination or aquiration. But it is
lengthy and obtrusive, up to spoiling burn runs on the examined drives.
So now this probing is omitted by default. All drives which announce to be
capable of CD or DVD writing, get blindly attributed the capability for
SAO and TAO. Applications which are interested in RAW modes or want to
rely on the traditional write mode information, may use this call.
@param drive_info drive object to be inquired
@return >0 indicates success, <=0 means failure
@since 0.7.6
*/
int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info);
/* ts A90824 */
/** Calm down or alert a drive. Some drives stay alert after reading for
@ -1085,7 +1054,7 @@ int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info);
sense to calm down the drive if no read operation is expected for the
next few seconds. The drive will get alert automatically if operations
are required.
@param d The drive to influence.
@param drive The drive to influence.
@param flag Bitfield for control purposes
bit0= become alert (else start snoozing)
This is not mandatory to allow further drive operations
@ -1109,7 +1078,7 @@ void burn_drive_release(struct burn_drive *drive, int eject);
eject button disabled. This physically locked drive state will last until
the drive is grabbed again and released via burn_drive_release().
Programs like eject, cdrecord, growisofs will break that ban too.
@param d The drive to release and leave locked.
@param drive The drive to release and leave locked.
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 means success, <=0 means failure
@since 0.4.0
@ -1202,7 +1171,7 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
/* ts A90909 */
/** Retrieve some media information which is mainly specific to CD. For other
media only the bits in reply parameter valid are supposed to be meaningful.
@param d The drive to query.
@param drive The drive to query.
@param disc_type A string saying either "CD-DA or CD-ROM", or "CD-I",
or ""CD-ROM XA", or "undefined".
@param disc_id A 32 bit number read from the media. (Meaning unclear yet)
@ -1593,11 +1562,9 @@ void burn_drive_cancel(struct burn_drive *drive);
/* ts A61223 */
/** Inquire whether the most recent asynchronous media job was successful.
This applies to burn_disc_erase(), burn_disc_format(), burn_disc_write().
Reasons for non-success may be: rejection of burn parameters, abort due to
fatal errors during write, blank or format, a call to burn_drive_cancel()
by the application thread.
/** Inquire whether the most recent write run was successful. Reasons for
non-success may be: rejection of burn parameters, abort during fatal errors
during write, a call to burn_drive_cancel() by the application thread.
@param d The drive to inquire.
@return 1=burn seems to have went well, 0=burn failed
@since 0.2.6
@ -1805,58 +1772,6 @@ void burn_source_free(struct burn_source *s);
struct burn_source *burn_file_source_new(const char *path,
const char *subpath);
/* ts A91122 : An interface to open(O_DIRECT) or similar OS tricks. */
/** Opens a file with eventual acceleration preparations which may depend
on the operating system and on compile time options of libburn.
You may use this call instead of open(2) for opening file descriptors
which shall be handed to burn_fd_source_new().
This should only be done for tracks with BURN_BLOCK_MODE1 (2048 bytes
per block).
If you use this call then you MUST allocate the buffers which you use
with read(2) by call burn_os_alloc_buffer(). Read sizes MUST be a multiple
of a safe buffer amount. Else you risk that track data get altered during
transmission.
burn_disk_write() will allocate a suitable read/write buffer for its own
operations. A fifo created by burn_fifo_source_new() will allocate
suitable memory for its buffer if called with flag bit0 and a multiple
of a safe buffer amount.
@param path The file address to open
@param open_flags The flags as of man 2 open. Normally just O_RDONLY.
@param flag Bitfield for control purposes (unused yet, submit 0).
@return A file descriptor as of open(2). Finally to be disposed
by close(2).
-1 indicates failure.
@since 0.7.4
*/
int burn_os_open_track_src(char *path, int open_flags, int flag);
/** Allocate a memory area that is suitable for reading with a file descriptor
opened by burn_os_open_track_src().
@param amount Number of bytes to allocate. This should be a multiple
of the operating system's i/o block size. 32 KB is
guaranteed by libburn to be safe.
@param flag Bitfield for control purposes (unused yet, submit 0).
@return The address of the allocated memory, or NULL on failure.
A non-NULL return value has finally to be disposed via
burn_os_free_buffer().
@since 0.7.4
*/
void *burn_os_alloc_buffer(size_t amount, int flag);
/** Dispose a memory area which was obtained by burn_os_alloc_buffer(),
@param buffer Memory address to be freed.
@param amount The number of bytes which was allocated at that
address.
@param flag Bitfield for control purposes (unused yet, submit 0).
@return 1 success , <=0 failure
@since 0.7.4
*/
int burn_os_free_buffer(void *buffer, size_t amount, int flag);
/** 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.
@ -1895,17 +1810,7 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
a particular chunksize. E.g. libisofs demands 2048.
@param chunks The number of chunks to be allocated in ring buffer.
This value must be >= 2.
@param flag Bitfield for control purposes:
bit0= The read method of inp is capable of delivering
arbitrary amounts of data per call. Not only one
sector.
Suitable for inp from burn_file_source_new()
and burn_fd_source_new() if not the fd has
exotic limitations on read size.
You MUST use this on inp which uses an fd opened
with burn_os_open_track_src().
Better do not use with other inp types.
@since 0.7.4
@param flag Bitfield for control purposes (unused yet, submit 0).
@return A pointer to the newly created burn_source.
Later both burn_sources, inp and the returned fifo, have
to be disposed by calling burn_source_free() for each.
@ -1938,42 +1843,12 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
int *free_bytes, char **status_text);
/* ts A91125 */
/** Inquire various counters which reflect the fifo operation.
@param fifo The fifo object to inquire
@param total_min_fill The minimum number of bytes in the fifo. Beginning
from the moment when fifo consumption is enabled.
@param interval_min_fill The minimum byte number beginning from the moment
when fifo consumption is enabled or from the
most recent moment when burn_fifo_next_interval()
was called.
@param put_counter The number of data transactions into the fifo.
@param get_counter The number of data transactions out of the fifo.
@param empty_counter The number of times the fifo was empty.
@param full_counter The number of times the fifo was full.
@since 0.7.4
*/
void burn_fifo_get_statistics(struct burn_source *fifo,
int *total_min_fill, int *interval_min_fill,
int *put_counter, int *get_counter,
int *empty_counter, int *full_counter);
/* ts A91125 */
/** Inquire the fifo minimum fill counter for intervals and reset that counter.
@param fifo The fifo object to inquire
@param interval_min_fill The minimum number of bytes in the fifo. Beginning
from the moment when fifo consumption is enabled
or from the most recent moment when
burn_fifo_next_interval() was called.
@since 0.7.4
*/
void burn_fifo_next_interval(struct burn_source *fifo, int *interval_min_fill);
/* ts A80713 */
/** Obtain a preview of the first input data of a fifo which was created
by burn_fifo_source_new(). The data will later be delivered normally to
the consumer track of the fifo.
bufsize may not be larger than the fifo size (chunk_size * chunks) - 32k.
bufsize may not be larger than the fifo size (chunk_size * chunks).
This call will succeed only if data consumption by the track has not
started yet, i.e. best before the call to burn_disc_write().
It will start the worker thread of the fifo with the expectable side
@ -1981,33 +1856,17 @@ void burn_fifo_next_interval(struct burn_source *fifo, int *interval_min_fill);
data have arrived or until it becomes clear that this will not happen.
The call may be repeated with increased bufsize. It will always yield
the bytes beginning from the first one in the fifo.
@param fifo The fifo object to inquire resp. start
@param fifo The fifo object to inquire
@param buf Pointer to memory of at least bufsize bytes where to
deliver the peeked data.
deliver the peeked data
@param bufsize Number of bytes to peek from the start of the fifo data
@param flag Bitfield for control purposes (unused yet, submit 0).
@return <0 on severe error, 0 if not enough data, 1 if bufsize bytes read
@since 0.5.0
*/
int burn_fifo_peek_data(struct burn_source *fifo, char *buf, int bufsize,
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
int flag);
/* ts A91125 */
/** Start the fifo worker thread and wait either until the requested number
of bytes have arrived or until it becomes clear that this will not happen.
Filling will go on asynchronously after burn_fifo_fill() returned.
This call and burn_fifo_peek_data() do not disturb each other.
@param fifo The fifo object to start
@param fill Number of bytes desired. Expect to get return 1 if
at least fifo size - 32k were read.
@param flag Bitfield for control purposes.
bit0= fill fifo to maximum size
@return <0 on severe error, 0 if not enough data,
1 if desired amount or fifo full
@since 0.7.4
*/
int burn_fifo_fill(struct burn_source *fifo, int fill, int flag);
/* ts A70328 */
/** Sets a fixed track size after the data source object has already been
@ -2244,32 +2103,6 @@ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force);
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
int value);
/* ts A91115 */
/** Overrides the write chunk size for DVD and BD media which is normally
determined according to media type and setting of stream recording.
A chunk size of 64 KB may improve throughput with bus systems which show
latency problems.
@param opts The write opts to change
@param obs Number of bytes which shall be sent by a single write command.
0 means automatic size, 32768 and 65336 are the only other
accepted sizes for now.
@since 0.7.4
*/
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs);
/* ts A91115 */
/** Sets the rythm by which stdio pseudo drives force their output data to
be consumed by the receiving storage device. This forcing keeps the memory
from being clogged with lots of pending data for slow devices.
@param opts The write opts to change
@param rythm Number of 2KB output blocks after which fsync(2) is
performed. -1 means no fsync(), 0 means default,
elsewise the value must be >= 32.
Default is currently 8192 = 16 MB.
@since 0.7.4
*/
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm);
/** Sets whether to read in raw mode or not
@param opts The read opts to change
@ -2616,7 +2449,7 @@ void burn_version(int *major, int *minor, int *micro);
*/
#define burn_header_version_major 0
#define burn_header_version_minor 7
#define burn_header_version_micro 6
#define burn_header_version_micro 2
/** Note:
Above version numbers are also recorded in configure.ac because libtool
wants them as parameters at build time.
@ -2666,15 +2499,6 @@ These two advises are mutually exclusive.
*/
/* ts A91226 */
/** Obtain the id string of the SCSI transport interface.
This interface may be a system specific adapter module of libburn or
an adapter to a supporting library like libcdio.
@flag Bitfield for control puposes, submit 0 for now
@return A pointer to the id string. Do not alter the string content.
@since 0.7.6
*/
char *burn_scsi_transport_id(int flag);
/* ts A60924 : ticket 74 */
/** Control queueing and stderr printing of messages from libburn.
@ -2922,31 +2746,4 @@ BURN_END_DECLS
#endif
/* ts A91205 */
/* The following experiments may be interesting in future:
*/
/* Perform OPC explicitely.
# define Libburn_pioneer_dvr_216d_with_opC 1
*/
/* Load mode page 5 and modify it rather than composing from scratch.
# define Libburn_pioneer_dvr_216d_load_mode5 1
*/
/* Inquire drive events and react by reading configuration or starting unit.
# define Libburn_pioneer_dvr_216d_get_evenT 1
*/
/* ts A91112 */
/* Do not probe CD modes but declare only data and audio modes supported.
For other modes resp. real probing one has to call
burn_drive_probe_cd_write_modes().
*/
#define Libburn_dummy_probe_write_modeS 1
#endif /*LIBBURN_H*/

View File

@ -1,8 +1,8 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL
Copyright (C) 2006 - 2009 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2
*/
#include <stdio.h>

View File

@ -1,8 +1,8 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006-2010 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL
Copyright (C) 2006-2009 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2
*/
@ -528,7 +528,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
0x0002015a (NOTE,HIGH) = Could not examine busy device
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
0x0002015c (FAILURE,HIGH) = Fifo size too small for desired peek buffer
0x0002015c (FAILURE,HIGH) = Fifo size is smaller than desired peek buffer
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
@ -551,9 +551,6 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
0x00020175 (FATAL,HIGH) = Supporting library is too old
0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer
libdax_audioxtr:

View File

@ -28,8 +28,6 @@
/* ts A70223 : in init.c */
extern int burn_support_untested_profiles;
static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len);
#ifdef Libburn_log_in_and_out_streaM
/* <<< ts A61031 */
@ -179,7 +177,7 @@ static unsigned char MMC_GET_CONFIGURATION[] =
{ 0x46, 0, 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, 0x7e, 0, 0, 0, 8, 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 };
@ -245,6 +243,11 @@ int mmc_function_spy(struct burn_drive *d, char * text)
d->cancel = 1;
return 0;
}
if (d->is_stopped && strcmp(text, "stop_unit") != 0 &&
strcmp(text, "start_unit") != 0) {
d->start_unit(d);
d->is_stopped = 0;
}
return 1;
}
@ -273,29 +276,12 @@ int mmc_int_to_four_char(unsigned char *data, int num)
}
static int mmc_start_for_bit0 = 0;
/* @param flag bit0= the calling function should need no START UNIT.
(Handling depends on mmc_start_for_bit0)
*/
int mmc_start_if_needed(struct burn_drive *d, int flag)
{
if (!d->is_stopped)
return 2;
if ((flag & 1) && !mmc_start_for_bit0)
return 2;
d->start_unit(d);
d->is_stopped = 0;
return 1;
}
void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
{
struct buffer buf;
struct command c;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
return;
@ -327,7 +313,6 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
int lba;
char msg[80];
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_reserve_track") <= 0)
return 0;
@ -362,7 +347,6 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
{
struct command c;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_track_info") <= 0)
return 0;
@ -415,7 +399,6 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
int ret, num, alloc_len = 20;
unsigned char *data;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_get_nwa") <= 0)
return -1;
@ -426,11 +409,6 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
*lba = mmc_four_char_to_int(data + 8);
*nwa = mmc_four_char_to_int(data + 12);
num = mmc_four_char_to_int(data + 16);
#ifdef Libburn_pioneer_dvr_216d_load_mode5
/* >>> memorize track mode : data[6] & 0xf */;
#endif
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12 || d->current_profile == 0x43) {
/* overwriteable */
@ -541,19 +519,17 @@ void mmc_get_event(struct burn_drive *d)
{
struct buffer buf;
struct command c;
int alloc_len = 8, len, evt_code, loops = 0;
unsigned char *evt;
int alloc_len= 8;
if (mmc_function_spy(d, "mmc_get_event") <= 0)
return;
again:;
scsi_init_command(&c, MMC_GET_EVENT, sizeof(MMC_GET_EVENT));
c.dxfer_len = 8;
/* >>> have a burn_drive element for Notification Class */;
c.opcode[4] = 0x7e;
/*
c.oplen = sizeof(MMC_GET_EVENT);
memcpy(c.opcode, MMC_GET_EVENT, sizeof(MMC_GET_EVENT));
*/
c.dxfer_len = alloc_len;
c.opcode[7] = (c.dxfer_len >> 8) & 0xff;
c.opcode[8] = c.dxfer_len & 0xff;
c.retry = 1;
@ -562,66 +538,11 @@ again:;
c.page->sectors = 0;
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
if (c.error)
return;
evt = c.page->data;
len = ((evt[0] << 8) | evt[1]) + 2;
if (len < 8)
return;
/* >>> memorize evt[3] in burn_drive element for Notification Class */;
if (evt[3] == 0) /* No event */
return;
evt_code = evt[4] & 0xf;
if (evt_code == 0) /* No change */
return;
switch (evt[2] & 7) {
case 0: /* no events supported */
return;
case 1: /* Operational change */
if (((evt[6] << 8) | evt[7])) {
alloc_len = 8;
mmc_get_configuration_al(d, &alloc_len);
}
break;
case 2: /* Power Management */
if (evt[5] >= 2)
d->start_unit(d);
break;
case 3: /* External request */
/* >>> report about external request */;
break;
case 4: /* Media */
if (evt_code == 2) {
d->start_unit(d);
alloc_len = 8;
mmc_get_configuration_al(d, &alloc_len);
}
break;
case 5: /* Multiple Host Events */
/* >>> report about foreign host interference */;
break;
case 6: /* Device busy */
if (evt_code == 1 && evt[5]) {
/* >>> wait the time announced in evt[6],[7]
as 100ms units */;
}
break;
default: /* reserved */
break;
}
loops++;
if (loops < 100)
goto again;
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]);
}
@ -766,7 +687,6 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
struct command c;
int len;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_write_12") <= 0)
return;
@ -809,7 +729,6 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
#endif /* Libburn_log_in_and_out_streaM */
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_write") <= 0)
return BE_CANCELLED;
@ -1103,7 +1022,6 @@ static int mmc_read_toc_fmt0(struct burn_drive *d)
{
int alloc_len = 4, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_toc_fmt0") <= 0)
return -1;
ret = mmc_read_toc_fmt0_al(d, &alloc_len);
@ -1486,7 +1404,6 @@ void mmc_read_toc(struct burn_drive *d)
{
int alloc_len = 4, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_toc") <= 0)
return;
@ -1517,7 +1434,6 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
struct burn_track **tracks;
struct burn_toc_entry toc_entry;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_multi_session_c1") <= 0)
return 0;
@ -1715,7 +1631,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
d->disc_info_valid |= (!!(data[7] & 128)) << 1;
if (len + 2 > 31 && (data[7] & 64)) {
memcpy(d->disc_bar_code, data + 24, 8);
d->disc_bar_code[8] = 0;
d->disc_bar_code[9] = 0;
d->disc_info_valid |= 4;
}
if (len + 2 > 32 && (data[7] & 16)) {
@ -1850,16 +1766,11 @@ regard_as_blank:;
return 0;
}
/* ts A61217 :
/* ts A61217 : Note for future
growisofs performs OPC if (data[0]<<8)|data[1]<=32
which indicates no OPC entries are attached to the
reply from the drive.
ts A91104 :
Actually growisofs performs OPC only on DVD-R[W].
*/
d->num_opc_tables = 0;
if(((data[0] << 8) | data[1]) > 32) /* i.e. > 34 bytes are available */
d->num_opc_tables = data[33];
/* ts A61219 : mmc5r03c.pdf 6.22.3.1.13 BG Format Status
0=blank (not yet started)
@ -1907,7 +1818,6 @@ void mmc_read_disc_info(struct burn_drive *d)
{
int alloc_len = 34, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_disc_info") <= 0)
return;
@ -1939,7 +1849,6 @@ void mmc_read_atip(struct burn_drive *d)
4234, 5646, 7056, 8468, -12, -13, -14, -15};
/* 24, 32, 40, 48, -, -, -, - */
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_atip") <= 0)
return;
@ -2097,7 +2006,6 @@ void mmc_read_sectors(struct burn_drive *d,
int errorblock, req;
struct command c;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_read_sectors") <= 0)
return;
@ -2168,7 +2076,6 @@ void mmc_erase(struct burn_drive *d, int fast)
{
struct command c;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_erase") <= 0)
return;
@ -2190,7 +2097,6 @@ void mmc_read_lead_in(struct burn_drive *d, struct buffer *buf)
int len;
struct command c;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_read_lead_in") <= 0)
return;
@ -2219,7 +2125,6 @@ void mmc_perform_opc(struct burn_drive *d)
{
struct command c;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_perform_opc") <= 0)
return;
@ -2252,11 +2157,14 @@ int mmc_set_streaming(struct burn_drive *d,
unsigned char *pd;
int key, asc, ascq;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_set_streaming") <= 0)
return 0;
scsi_init_command(&c, MMC_SET_STREAMING, sizeof(MMC_SET_STREAMING));
/*
c.oplen = sizeof(MMC_SET_STREAMING);
memcpy(c.opcode, MMC_SET_STREAMING, sizeof(MMC_SET_STREAMING));
*/
c.retry = 1;
c.page = &buf;
c.page->bytes = 28;
@ -2310,10 +2218,26 @@ int mmc_set_streaming(struct burn_drive *d,
d->issue_command(d, &c);
if (c.error) {
if (c.sense[2]!=0 && !d->silent_on_scsi_error) {
#ifdef NIX
sprintf(msg,
"SCSI error on set_streaming(%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
w_speed,
c.sense[2],c.sense[12],c.sense[13]);
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00020124,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
#else /* NIX */
sprintf(msg,
"SCSI error on set_streaming(%d): ", w_speed);
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
&key, &asc, &ascq);
#endif /* !NIX */
}
return 0;
}
@ -2327,7 +2251,6 @@ void mmc_set_speed(struct burn_drive *d, int r, int w)
int ret, end_lba = 0;
struct burn_speed_descriptor *best_sd = NULL;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_set_speed") <= 0)
return;
@ -2441,7 +2364,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
return 0;
}
old_alloc_len = *alloc_len;
*alloc_len = len = mmc_four_char_to_int(c.page->data) + 4;
*alloc_len = len = mmc_four_char_to_int(c.page->data);
if (len > old_alloc_len)
len = old_alloc_len;
if (len < 8 || len > 4096)
@ -2668,7 +2591,6 @@ void mmc_get_configuration(struct burn_drive *d)
{
int alloc_len = 8, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_get_configuration") <= 0)
return;
@ -2872,7 +2794,6 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
{
int alloc_len = 4, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_format_capacities") <= 0)
return 0;
@ -2901,7 +2822,9 @@ void mmc_sync_cache(struct burn_drive *d)
c.oplen = sizeof(MMC_SYNC_CACHE);
*/
c.retry = 1;
c.opcode[1] |= 2; /* ts A70918 : Immed */
c.page = NULL;
c.dir = NO_TRANSFER;
@ -2929,7 +2852,6 @@ void mmc_sync_cache(struct burn_drive *d)
d->cancel = 1;
return;
}
if (spc_wait_unit_attention(d, 3600, "SYNCHRONIZE CACHE", 0) <= 0)
d->cancel = 1;
else
@ -2952,6 +2874,11 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
scsi_init_command(&c, MMC_READ_BUFFER_CAPACITY,
sizeof(MMC_READ_BUFFER_CAPACITY));
/*
memcpy(c.opcode, MMC_READ_BUFFER_CAPACITY,
sizeof(MMC_READ_BUFFER_CAPACITY));
c.oplen = sizeof(MMC_READ_BUFFER_CAPACITY);
*/
c.dxfer_len = alloc_len;
c.opcode[7] = (c.dxfer_len >> 8) & 0xff;
c.opcode[8] = c.dxfer_len & 0xff;
@ -3019,7 +2946,6 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
int key, asc, ascq;
int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_format_unit") <= 0)
return 0;
size_mode = (flag >> 1) & 3;
@ -3761,7 +3687,6 @@ int mmc_get_write_performance(struct burn_drive *d)
{
int alloc_len = 8, max_descr = 0, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_get_write_performance") <= 0)
return 0;
@ -3804,9 +3729,10 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
pd[4] = 8;
/* Link size dummy */
pd[5] = 0;
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11 ||
d->current_profile == 0x15)
&& o->write_type == BURN_WRITE_SAO) {
&& o->write_type == BURN_WRITE_SAO) {
/* ts A70205 : DVD-R[W][/DL] : Disc-at-once, DAO */
/* Learned from dvd+rw-tools and mmc5r03c.pdf .
See doc/cookbook.txt for more detailed references. */
@ -3815,17 +3741,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
pd[2] = ((!!o->underrun_proof) << 6)
| ((!!o->simulate) << 4)
| 2;
/* No multi-session , FP = 0 , Copy = 0, Track Mode = 5 */
/* No multi-session , FP = 0 , Track Mode = 5 */
pd[3] = 5;
#ifdef Libburn_pioneer_dvr_216d_load_mode5
/* >>> use track mode from mmc_get_nwa() */
/* >>> pd[3] = (pd[3] & ~0xf) | (d->track_inf[5] & 0xf); */
#endif
/* Data Block Type = 8 */
pd[4] = 8;
@ -3902,7 +3819,6 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
{
struct command c;
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_read_10") <= 0)
return -1;
;
@ -3961,7 +3877,6 @@ int mmc_read_capacity(struct burn_drive *d)
int alloc_len= 8;
d->media_read_capacity = 0x7fffffff;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_capacity") <= 0)
return 0;
@ -4045,9 +3960,7 @@ int mmc_read_disc_structure(struct burn_drive *d,
char **reply, int *reply_len, int flag)
{
int alloc_len = 4, ret;
char msg[80];
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_disc_structure") <= 0)
return 0;
@ -4058,49 +3971,7 @@ int mmc_read_disc_structure(struct burn_drive *d,
fprintf(stderr,"LIBBURN_DEBUG: ADh alloc_len = %d , ret = %d\n",
alloc_len, ret);
*/
if (ret <= 0)
return ret;
if (alloc_len < 12) {
sprintf(msg,
"READ DISC STRUCTURE announces only %d bytes of reply\n",
alloc_len);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
ret = 0;
/* ts A91205
LG GH22LS30 revision 1.00 returns for DVD-R format
code 0x0E an allocation length of 4 (= 0 payload).
A MS-Windows tool can inquire media code "RITEKF1",
though.
This macro causes a try to unconditionally read the
desired payload bytes. The drive then returns 35
bytes as requested and the media id is "RITEKF1".
Nevertheless this is not a generally usable gesture
because older Linux USB dislikes requests to fetch
more bytes than the drive will deliver.
# define Libburn_enforce_structure_code_0x0E 1
*/
#ifdef Libburn_enforce_structure_code_0x0E
if (format == 0x0E) {
alloc_len = min_len + 4;
ret = mmc_read_disc_structure_al(d, &alloc_len,
media_type, layer_number, format, min_len,
reply, reply_len, 0);
if (*reply_len < min_len || *reply == NULL)
ret = 0;
sprintf(msg, "READ DISC STRUCTURE returns %d bytes of required %d\n",
*reply_len + 4, min_len + 4);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
}
#endif
} else
if (alloc_len >= 12 && ret > 0)
ret = mmc_read_disc_structure_al(d, &alloc_len,
media_type, layer_number, format, min_len,
reply, reply_len, 0);
@ -4382,7 +4253,6 @@ int mmc_setup_drive(struct burn_drive *d)
d->needs_close_session = 0;
d->needs_sync_cache = 0;
d->bg_format_status = -1;
d->num_opc_tables = -1;
d->last_lead_in = -2000000000;
d->last_lead_out = -2000000000;
d->disc_type = 0xff;

View File

@ -68,9 +68,6 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
const struct burn_write_opts *o,
unsigned char *pd);
/* ts A70201 */
int mmc_four_char_to_int(unsigned char *data);
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
int mmc_read_10(struct burn_drive *d, int start, int amount,
struct buffer *buf);
@ -93,12 +90,4 @@ int mmc_get_media_product_id(struct burn_drive *d,
char **product_id, char **media_code1, char **media_code2,
char **book_type, int flag);
/* ts A60910 (estimated) */
int mmc_function_spy(struct burn_drive *d, char * text);
/* ts A91118 */
int mmc_start_if_needed(struct burn_drive *d, int flag);
#endif /*__MMC*/

View File

@ -39,8 +39,6 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->fill_up_media = 0;
opts->force_is_set = 0;
opts->do_stream_recording = 0;
opts->dvd_obs_override = 0;
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
@ -391,25 +389,6 @@ void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
}
/* ts A91115: API */
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
{
if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024)
return;
opts->dvd_obs_override = obs;
}
/* ts A91115: API */
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
{
if (rythm == -1)
opts->stdio_fsync_size = 0;
else if (rythm == 0)
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
else if (rythm >= 32)
opts->stdio_fsync_size = rythm;
}
/* ts A70901: API */

View File

@ -51,19 +51,9 @@ struct burn_write_opts
/* ts A80412 : whether to use WRITE12 with Streaming bit set
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
This gets transferred to burn_drive.do_stream_recording
*/
This gets transferred to burn_drive.do_stream_recording */
int do_stream_recording;
/* ts A91115 : override value for .obs on DVD media.
Only values 0, 32K and 64K are allowed for now. */
int dvd_obs_override;
/* ts A91115 : size of the fsync() interval for stdio writing.
Values 0 or >= 32 counted in 2 KB blocks. */
int stdio_fsync_size;
/** A disc can have a media catalog number */
int has_mediacatalog;
unsigned char mediacatalog[13];
@ -74,11 +64,6 @@ struct burn_write_opts
unsigned char multi;
};
/* Default value for burn_write_opts.stdio_flush_size
*/
#define Libburn_stdio_fsync_limiT 8192
/** 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

View File

@ -57,7 +57,5 @@ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
To be initialized and used within sg-*.c .
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
struct cam_device* cam; \
int lock_fd; \
struct cam_device* cam;

View File

@ -1,72 +0,0 @@
/* os-libcdio.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
Unknown X/Open-like systems
with GNU libcdio MMC transport adapter sg-libcdio.c
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man 7 signal.)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
SIGTTOU
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 16
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 3
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
with buffer size 32 kB. So stream recording is allowed only with size 64k.
This makes it worth to have a special case for Linux buffer size here.
*/
#ifdef __linux
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
#else
/* (It might be risky to use 64k. FreeBSD is said to can only 32k.) */
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
#endif
/* To hold the position of the most recently delivered address from
device enumeration.
*/
struct burn_drive_enumerator_struct {
char **ppsz_cd_drives;
char **pos;
};
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
Usually they are initialized in sg-*.c:enumerate_common().
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
void *p_cdio; /* actually a pointer to CdIo_t */ \
char libcdio_name[4096]; /* The drive path as used by libcdio */ \

View File

@ -13,15 +13,6 @@
Operating system case distinction
*/
#ifdef Libburn_use_libcdiO
/* -------------------------- X/Open with GNU libcdio ---------------------- */
#include "os-libcdio.h"
#else
#ifdef __FreeBSD__
@ -29,14 +20,6 @@
#include "os-freebsd.h"
#else
#ifdef __FreeBSD_kernel__
/* ----------------------- FreeBSD with CAM under Debian ------------------- */
#include "os-freebsd.h"
#else
#ifdef __linux
@ -53,9 +36,7 @@
#endif /* ! __linux */
#endif /* ! __FreeBSD__kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libburn_use_libcdiO */
#endif /* ! BURN_OS_H_INCLUDED */

View File

@ -17,27 +17,7 @@
int mmc_function_spy(struct burn_drive *d, char * text);
/* START STOP UNIT as of SBC-1 and SBC-2
0: Opcode 0x1B
1: bit0= Immed
bit1-7= reserved
2: reserved
3: reserved
4: bit0= Start (else Stop unit)
bit1= Load/Eject (according to Start resp. Stop)
bit2-3= reserved
bit4-7= Power Condition
0= Start Valid: process Start and Load/Eject bits
1= assume Active state
2= assume Idle state
3= assume Stanby state
(5= SBC-1 only: assume Sleep state)
7= transfer control of power conditions to logical unit
10= force idle condition timer to 0
11= force standby condition timer to 0
All others are reserved.
5: Control (set to 0)
*/
/* spc command set */
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
@ -51,6 +31,11 @@ void sbc_load(struct burn_drive *d)
return;
scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD));
/*
memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD));
c.oplen = sizeof(SBC_LOAD);
c.page = NULL;
*/
c.retry = 1;
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
@ -74,24 +59,25 @@ void sbc_eject(struct burn_drive *d)
return;
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
/* c.opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
/*
memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD));
c.oplen = sizeof(SBC_UNLOAD);
c.page = NULL;
*/
c.opcode[1] |= 1; /* ts A70918 : Immed */
c.page = NULL;
c.dir = NO_TRANSFER;
d->issue_command(d, &c);
/* ts A70918 : Wait long. A late eject could surprise or hurt user.
ts B00109 : Asynchronous eject revoked, as one cannot reliably
distinguish out from unready.
if (c.error)
return;
/* ts A70918 : Wait long. A late eject could surprise or hurt user. */
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
*/
}
/* ts A91112 : Now with flag */
/* @param flag bit0= asynchronous waiting
*/
int sbc_start_unit_flag(struct burn_drive *d, int flag)
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */
int sbc_start_unit(struct burn_drive *d)
{
struct command c;
int ret;
@ -101,37 +87,17 @@ int sbc_start_unit_flag(struct burn_drive *d, int flag)
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
c.retry = 1;
c.opcode[1] |= (flag & 1); /* ts A70918 : Immed */
c.opcode[1] |= 1; /* ts A70918 : Immed */
c.dir = NO_TRANSFER;
d->issue_command(d, &c);
if (c.error)
return 0;
if (!(flag & 1))
return 1;
/* ts A70918 : asynchronous */
/* ts A70918 : now asynchronous */
d->is_stopped = 0;
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
return ret;
}
int sbc_start_unit(struct burn_drive *d)
{
int ret;
d->is_stopped = 0; /* no endless starting attempts */
/* Asynchronous, not to block controller by waiting */
ret = sbc_start_unit_flag(d, 1);
if (ret <= 0)
return ret;
/* Synchronous to catch Pioneer DVR-216D which is ready too early.
A pending START UNIT can prevent ejecting of the tray.
*/
ret = sbc_start_unit_flag(d, 0);
return ret;
}
/* ts A90824 : Trying to reduce drive noise */
int sbc_stop_unit(struct burn_drive *d)
{

View File

@ -21,8 +21,6 @@
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
#include "ecma130ab.h"
#ifdef Libburn_log_in_and_out_streaM
/* <<< ts A61031 */
@ -736,57 +734,6 @@ int sector_headers_is_ok(struct burn_write_opts *o, int mode)
int sector_headers(struct burn_write_opts *o, unsigned char *out,
int mode, int leadin)
{
#ifdef Libburn_ecma130ab_includeD
struct burn_drive *d = o->drive;
unsigned int crc;
int min, sec, frame;
int modebyte = -1;
int ret;
ret = sector_headers_is_ok(o, mode);
if (ret != 2)
return !!ret;
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);
burn_rspc_parity_p(out);
burn_rspc_parity_q(out);
}
burn_ecma130_scramble(out);
return 1;
#else /* Libburn_ecma130ab_includeD */
int ret;
ret = sector_headers_is_ok(o, mode);
@ -803,52 +750,8 @@ int sector_headers(struct burn_write_opts *o, unsigned char *out,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Raw CD write modes are not supported", 0, 0);
return 0;
#endif /* ! Libburn_ecma130ab_includeD */
}
#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? */
@ -863,7 +766,7 @@ int sector_identify(unsigned char *data)
{
/*
burn_ecma130_scramble(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;

View File

@ -7,8 +7,8 @@ the transport level aspects of SCSI control and command i/o.
Present implementation: default dummy which enables libburn only to work
with stdio: pseudo drive addresses.
For real implementations see sg-linux.c, sg-freebsd.c,
sg-libcdio.c
For real implementations see sg-linux.c or sg-freebsd.c
*/
@ -19,7 +19,6 @@ Present implementation: default dummy which enables libburn only to work
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#ifdef Libburn_os_has_statvfS
#include <sys/statvfs.h>
@ -39,59 +38,6 @@ Present implementation: default dummy which enables libburn only to work
extern struct libdax_msgs *libdax_messenger;
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
strcpy(msg, "internal X/Open adapter sg-dummy");
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** Returns the next index number and the next enumerated drive address.
The enumeration has to cover all available and accessible drives. It is
allowed to return addresses of drives which are not available but under
@ -206,23 +152,6 @@ int sg_is_enumerable_adr(char *adr)
}
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (S_ISBLK(stbuf.st_mode))
return 1;
return 0;
}
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
exist yet, then the directory will be inquired.
@ -285,7 +214,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
if (statvfs(testpath, &vfsbuf) == -1)
return -2;
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
(off_t) vfsbuf.f_bavail;
#else /* Libburn_os_has_statvfS */
@ -298,39 +227,3 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
return 1;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

View File

@ -29,28 +29,12 @@ and of deriving the following system specific files from existing examples:
Said sg-*.c operations are defined by a public function interface, which has
to be implemented in a way that provides libburn with the desired services:
sg_id_string() returns an id string of the SCSI transport adapter.
It may be called before initialization but then may
return only a preliminary id.
sg_initialize() performs global initialization of the SCSI transport
adapter and eventually needed operating system
facilities. Checks for compatibility of supporting
software components.
sg_shutdown() performs global finalizations and releases golbally
aquired resources.
sg_give_next_adr() iterates over the set of potentially useful drive
address strings.
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
accessible drives into libburn's list of drives.
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
on destruction. Releases resources which were aquired
underneath scsi_enumerate_drives().
sg_drive_is_open() tells wether libburn has the given drive in use.
sg_grab() opens the drive for SCSI commands and ensures
@ -64,25 +48,8 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
that can be used in 2 kB granularity by lseek(2),
read(2), and possibly write(2) if not read-only.
E.g. a USB stick or a hard disk.
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
burn_os_alloc_buffer() allocates a memory area that is suitable for file
descriptors issued by burn_os_open_track_src().
The buffer size may be rounded up for alignment
reasons.
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
Porting hints are marked by the text "PORTING:".
Send feedback to libburn-hackers@pykix.org .
@ -263,61 +230,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* ------------------------------------------------------------------------ */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd-port");
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** Returns the next index number and the next enumerated drive address.
The enumeration has to cover all available and accessible drives. It is
allowed to return addresses of drives which are not available but under
@ -387,7 +299,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
break;
snprintf(buf, sizeof (buf), "/dev/%s%d",
result->periph_name, result->unit_number);
if(adr_size <= strlen(buf))
if(adr_size <= strlen(buf)
return -1;
strcpy(adr, buf);
@ -411,7 +323,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
int scsi_enumerate_drives(void)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
int initialize = 1;
char buf[64];
while(1) {
@ -426,7 +338,6 @@ int scsi_enumerate_drives(void)
idx.result->target_lun);
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
@ -449,12 +360,11 @@ int sg_drive_is_open(struct burn_drive * d)
*/
int sg_grab(struct burn_drive *d)
{
int count;
struct cam_device *cam;
if(d->cam != NULL) {
d->released = 0;
return 1;
}
if(d->cam != NULL)
return 0;
cam = cam_open_device(d->devname, O_RDWR);
if (cam == NULL) {
@ -605,7 +515,7 @@ 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, ret;
int initialize = 1;
char buf[64];
struct periph_match_result* result;
@ -614,7 +524,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
initialize = 0;
if (ret <= 0)
break;
if (strcmp(path, buf) != 0)
if (strcmp(adr, buf) != 0)
continue;
result = &(idx->ccb.cdm.matches[i].result.periph_result);
*bus_no = result->path_id;
@ -636,7 +546,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int sg_is_enumerable_adr(char* adr)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
int initialize = 1;
char buf[64];
while(1) {
@ -654,47 +564,6 @@ int sg_is_enumerable_adr(char* adr)
}
/* ts B00115 */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, written, and read with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
char *spt;
int i, e;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (!S_ISCHR(stbuf.st_mode))
return 0;
spt = strrchr(path, '/');
if (spt == NULL)
spt = path;
else
spt++;
e = strlen(spt);
for (i = strlen(spt) - 1; i > 0; i--)
if (spt[i] >= '0' && spt[i] <= '9')
e = i;
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
return 1;
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
return 1;
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
return 1;
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
return 1;
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
return 1;
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
return 1;
return 0;
}
/* ts A70909 */
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
@ -754,45 +623,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
if (testpath[0]) {
if (statvfs(testpath, &vfsbuf) == -1)
return -2;
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
(off_t) vfsbuf.f_bavail;
}
return 1;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

View File

@ -7,7 +7,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
@ -17,12 +16,10 @@
#include <err.h> /* XXX */
/* ts A70909 */
#include <sys/statvfs.h>
/* ts B00121 */
#include <sys/disk.h> /* DIOCGMEDIASIZE */
#include "transport.h"
#include "drive.h"
@ -57,79 +54,6 @@ int burn_drive_is_banned(char *device_address);
int mmc_function_spy(struct burn_drive *d, char * text);
/* ts B00113
Whether to log SCSI commands:
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
extern int burn_sg_log_scsi;
/* ts B00114 */
/* Storage object is in libburn/init.c
whether to strive for exclusive access to the drive
*/
extern int burn_sg_open_o_excl;
/* ts A91227 */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd");
return 1;
}
/* ts A91227 */
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/* ts A91227 */
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/* ts A61021 : Moved most code from scsi_enumerate_drives under
sg_give_next_adr() */
/* Some helper functions for scsi_give_next_adr() */
@ -148,8 +72,6 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
warn("couldn't open %s", XPT_DEVICE);
free(idx);
idx = NULL;
return -1;
}
@ -221,7 +143,7 @@ static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
}
/** Returns the next index object state and the next enumerated drive address.
/** 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
@ -275,15 +197,9 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
struct periph_match_result* result;
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
/* ts B00112 : we really want only "cd" devices.
if (idx->skip_device ||
strcmp(result->periph_name, "pass") == 0)
break;
*/
if (idx->skip_device ||
strcmp(result->periph_name, "cd") != 0)
break;
ret = snprintf(adr, adr_size, "/dev/%s%d",
result->periph_name, result->unit_number);
if(ret >= adr_size)
@ -294,7 +210,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
}
default:
/* fprintf(stderr, "unknown match type\n"); */
/* printf(stderr, "unknown match type\n"); */
break;
}
(idx->i)++;
@ -369,10 +285,6 @@ int sg_close_drive(struct burn_drive * d)
cam_close_device(d->cam);
d->cam = NULL;
}
if (d->lock_fd > 0) {
close(d->lock_fd);
d->lock_fd = -1;
}
return 0;
}
@ -426,9 +338,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
out.lun = lun_no;
out.devname = burn_strdup(fname);
out.cam = NULL;
out.lock_fd = -1;
out.start_lba= -2000000000;
out.end_lba= -2000000000;
@ -520,8 +430,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* Operating system adapter is CAM */
/* Adapter specific handles and data */
out.cam = NULL;
out.lock_fd = -1;
/* Adapter specific functions */
out.grab = sg_grab;
out.release = sg_release;
@ -534,143 +442,14 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
#endif /* ! Scsi_freebsd_make_own_enumeratE */
/* Lock the inode associated to dev_fd and the inode associated to devname.
Return OS errno, number of pass device of dev_fd, locked fd to devname,
error message.
A return value of > 0 means success, <= 0 means failure.
/* 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.
*/
static int freebsd_dev_lock(int dev_fd, char *devname,
int *os_errno, int *pass_dev_no, int *lock_fd, char msg[4096],
int flag)
{
int lock_denied = 0, fd_stbuf_valid, name_stbuf_valid, i, pass_l = 100;
int max_retry = 3, tries = 0;
struct stat fd_stbuf, name_stbuf;
char pass_name[16], *lock_name;
*os_errno = 0;
*pass_dev_no = -1;
*lock_fd = -1;
msg[0] = 0;
fd_stbuf_valid = !fstat(dev_fd, &fd_stbuf);
/* Try to find name of pass device by inode number */
lock_name = (char *) "effective device";
if(fd_stbuf_valid) {
for (i = 0; i < pass_l; i++) {
sprintf(pass_name, "/dev/pass%d", i);
if (stat(pass_name, &name_stbuf) != -1)
if(fd_stbuf.st_ino == name_stbuf.st_ino &&
fd_stbuf.st_dev == name_stbuf.st_dev)
break;
}
if (i < pass_l) {
lock_name = pass_name;
*pass_dev_no = i;
}
}
name_stbuf_valid = !stat(devname, &name_stbuf);
for (tries= 0; tries <= max_retry; tries++) {
lock_denied = flock(dev_fd, LOCK_EX | LOCK_NB);
*os_errno = errno;
if (lock_denied) {
if (errno == EAGAIN && tries < max_retry) {
/* <<< debugging
fprintf(stderr,
"\nlibcdio_DEBUG: EAGAIN pass, tries= %d\n",
tries);
*/
usleep(2000000);
continue;
}
sprintf(msg,
"Device busy. flock(LOCK_EX) failed on %s of %s",
strlen(lock_name) > 2000 || *pass_dev_no < 0 ?
"pass device" : lock_name,
strlen(devname) > 2000 ? "drive" : devname);
return 0;
}
break;
}
/*
fprintf(stderr, "libburn_DEBUG: flock obtained on %s of %s\n",
lock_name, devname);
*/
/* Eventually lock the official device node too */
if (fd_stbuf_valid && name_stbuf_valid &&
(fd_stbuf.st_ino != name_stbuf.st_ino ||
fd_stbuf.st_dev != name_stbuf.st_dev)) {
*lock_fd = open(devname, O_RDONLY);
if (*lock_fd == 0) {
close(*lock_fd);
*lock_fd = -1;
} if (*lock_fd > 0) {
for (tries = 0; tries <= max_retry; tries++) {
lock_denied =
flock(*lock_fd, LOCK_EX | LOCK_NB);
if (lock_denied) {
if (errno == EAGAIN &&
tries < max_retry) {
/* <<< debugging
fprintf(stderr,
"\nlibcdio_DEBUG: EAGAIN dev, tries= %d\n",
tries);
*/
usleep(2000000);
continue;
}
close(*lock_fd);
*lock_fd = -1;
sprintf(msg,
"Device busy. flock(LOCK_EX) failed on %s",
strlen(devname) > 4000 ? "drive" : devname);
return 0;
}
break;
}
}
/*
fprintf(stderr, "libburn_DEBUG: flock obtained on %s\n",
devname);
*/
}
return 1;
}
static int sg_lock(struct burn_drive *d, int flag)
{
int ret, os_errno, pass_dev_no = -1, flock_fd = -1;
char msg[4096];
ret = freebsd_dev_lock(d->cam->fd, d->devname,
&os_errno, &pass_dev_no, &flock_fd, msg, 0);
if (ret <= 0) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020008,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
sg_close_drive(d);
return 0;
}
if (d->lock_fd > 0)
close(d->lock_fd);
d->lock_fd = flock_fd;
return 1;
}
int sg_grab(struct burn_drive *d)
{
int count;
struct cam_device *cam;
if (mmc_function_spy(d, "sg_grab") <= 0)
@ -683,19 +462,22 @@ int sg_grab(struct burn_drive *d)
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", errno, 0);
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;
}
d->cam = cam;
if (burn_sg_open_o_excl & 63)
if (sg_lock(d, 0) <= 0)
return 0;
fcntl(cam->fd, F_SETOWN, getpid());
d->released = 0;
return 1;
/* 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;
}
@ -723,11 +505,11 @@ int sg_release(struct burn_drive *d)
int sg_issue_command(struct burn_drive *d, struct command *c)
{
int done = 0, err, sense_len, ret;
int done = 0;
int err;
union ccb *ccb;
char buf[161];
static FILE *fp = NULL;
char buf[161];
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
(void*)d->cam, d->released);
mmc_function_spy(NULL, buf);
@ -736,15 +518,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->error = 0;
return 0;
}
if (burn_sg_log_scsi & 1) {
if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
fprintf(fp,
"\n-----------------------------------------\n");
}
}
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
c->error = 0;
@ -793,6 +566,12 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
/* touch page so we can use valgrind */
memset(c->page->data, 0, BUFFER_SIZE);
} else {
/* ts A90430 */
/* a ssert(c->page->bytes > 0); */
if (c->page->bytes <= 0) {
c->error = 1;
return 0;
}
ccb->csio.dxfer_len = c->page->bytes;
}
} else {
@ -808,24 +587,20 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
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;
{ret = -1; goto ex;}
return -1;
}
/* XXX */
/* ts B00110 */
/* Better curb sense_len */
sense_len = ccb->csio.sense_len;
if (sense_len > sizeof(c->sense))
sense_len = sizeof(c->sense);
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;
{ret = 1; goto ex;}
cam_freeccb(ccb);
return 1;
}
switch (scsi_error(d, c->sense, 0)) {
case RETRY:
@ -840,58 +615,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
done = 1;
}
} while (!done);
ret = 1;
ex:;
if (c->error)
scsi_notify_error(d, c, c->sense, 18, 0);
if (burn_sg_log_scsi & 3)
/* >>> Need own duration time measurement. Then remove bit1 */
scsi_log_err(c, fp, c->sense, 0, (c->error != 0) | 2);
cam_freeccb(ccb);
return ret;
}
/* ts B00115 */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read and eventually written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
char *spt;
int i, e;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (!S_ISCHR(stbuf.st_mode))
return 0;
spt = strrchr(path, '/');
if (spt == NULL)
spt = path;
else
spt++;
e = strlen(spt);
for (i = strlen(spt) - 1; i > 0; i--)
if (spt[i] >= '0' && spt[i] <= '9')
e = i;
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
return 1;
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
return 1;
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
return 1;
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
return 1;
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
return 1;
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
return 1;
return 0;
return 1;
}
@ -912,7 +637,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
char testpath[4096], *cpt;
long blocks;
off_t add_size = 0;
int fd, ret;
testpath[0] = 0;
blocks = *bytes / 512;
@ -947,15 +671,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#endif /* Libburn_if_this_was_linuX */
} else if(S_ISCHR(stbuf.st_mode)) {
fd = open(path, O_RDONLY);
if (fd == -1)
return -2;
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
close(fd);
if (ret == -1)
return -2;
*bytes = add_size;
} else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
@ -965,45 +680,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
if (testpath[0]) {
if (statvfs(testpath, &vfsbuf) == -1)
return -2;
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
(off_t) vfsbuf.f_bavail;
}
return 1;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

View File

@ -1,928 +0,0 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
This is the main operating system dependent SCSI part of libburn. It implements
the transport level aspects of SCSI control and command i/o.
Present implementation: GNU libcdio , for X/Open compliant operating systems
PORTING:
Porting libburn typically will consist of adding a new operating system case
to the following switcher files:
os.h Operating system specific libburn definitions and declarations.
sg.c Operating system dependent transport level modules.
and of deriving the following system specific files from existing examples:
os-*.h Included by os.h. You will need some general system knowledge
about signals and knowledge about the storage object needs of your
transport level module sg-*.c.
sg-*.c This source module. You will need special system knowledge about
how to detect all potentially available drives, how to open them,
eventually how to exclusively reserve them, how to perform
SCSI transactions, how to inquire the (pseudo-)SCSI driver.
You will not need to care about CD burning, MMC or other high-level
SCSI aspects.
Said sg-*.c operations are defined by a public function interface, which has
to be implemented in a way that provides libburn with the desired services:
sg_id_string() returns an id string of the SCSI transport adapter.
It may be called before initialization but then may
return only a preliminary id.
sg_initialize() performs global initialization of the SCSI transport
adapter and eventually needed operating system
facilities. Checks for compatibility of supporting
software components.
sg_shutdown() performs global finalizations and releases golbally
aquired resources.
sg_give_next_adr() iterates over the set of potentially useful drive
address strings.
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
accessible drives into libburn's list of drives.
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
on destruction. Releases resources which were aquired
underneath scsi_enumerate_drives().
sg_drive_is_open() tells wether libburn has the given drive in use.
sg_grab() opens the drive for SCSI commands and ensures
undisturbed access.
sg_release() closes a drive opened by sg_grab()
sg_issue_command() sends a SCSI command to the drive, receives reply,
and evaluates wether the command succeeded or shall
be retried or finally failed.
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
that can be used in 2 kB granularity by lseek(2),
read(2), and possibly write(2) if not read-only..
E.g. a USB stick or a hard disk.
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
burn_os_alloc_buffer() allocates a memory area that is suitable for file
descriptors issued by burn_os_open_track_src().
The buffer size may be rounded up for alignment
reasons.
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
Porting hints are marked by the text "PORTING:".
Send feedback to libburn-hackers@pykix.org .
*/
/** PORTING : ------- OS dependent headers and definitions ------ */
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#ifdef Libburn_os_has_statvfS
#include <sys/statvfs.h>
#endif /* Libburn_os_has_stavtfS */
#ifdef __linux
/* for ioctl(BLKGETSIZE) */
#include <sys/ioctl.h>
#include <linux/fs.h>
#endif
#ifdef __FreeBSD__
#define Libburn_is_on_freebsD 1
#endif
#ifdef __FreeBSD_kernel__
#define Libburn_is_on_freebsD 1
#endif
#ifdef Libburn_is_on_freebsD
/* To avoid ATAPI devices */
#define Libburn_guess_freebsd_atapi_devicE 1
/* To obtain size of disk-like devices */
#include <sys/disk.h> /* DIOCGMEDIASIZE */
#endif /* Libburn_is_on_freebsD */
#define Libburn_guess_freebsd_atapi_devicE 1
#include <cdio/cdio.h>
#include <cdio/logging.h>
#include <cdio/mmc.h>
/* The waiting time before eventually retrying a failed SCSI command.
Before each retry wait Libburn_sg_linux_retry_incR longer than with
the previous one.
*/
#define Libburn_sg_libcdio_retry_usleeP 100000
#define Libburn_sg_libcdio_retry_incR 100000
/** PORTING : ------ libburn portable headers and definitions ----- */
#include "transport.h"
#include "drive.h"
#include "sg.h"
#include "spc.h"
/* collides with symbols of <cdio/mmc.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;
/* is in portable part of libburn */
int burn_drive_is_banned(char *device_address);
int burn_drive_resolve_link(char *path, char adr[],
int *recursion_count, int flag); /* drive.c */
/* Whether to log SCSI commands:
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
extern int burn_sg_log_scsi;
/* ------------------------------------------------------------------------ */
/* PORTING: Private definitions. Port only if needed by public functions. */
/* (Public functions are listed below) */
/* ------------------------------------------------------------------------ */
/* Storage object is in libburn/init.c
whether to strive for exclusive access to the drive
*/
extern int burn_sg_open_o_excl;
/* ------------------------------------------------------------------------ */
/* PORTING: Private functions. Port only if needed by public functions */
/* (Public functions are listed below) */
/* ------------------------------------------------------------------------ */
static int sg_close_drive(struct burn_drive * d)
{
CdIo_t *p_cdio;
if (d->p_cdio != NULL) {
p_cdio = (CdIo_t *) d->p_cdio;
cdio_destroy(p_cdio);
d->p_cdio = NULL;
}
return 0;
}
static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
char **pos;
int count = 0;
if (initialize == 1) {
idx->pos = idx->ppsz_cd_drives =
cdio_get_devices(DRIVER_DEVICE);
if (idx->ppsz_cd_drives == NULL)
return 0;
for (pos = idx->ppsz_cd_drives ; pos != NULL; pos++) {
if (*pos == NULL)
break;
count++;
}
} else if (initialize == -1) {
if (*(idx->ppsz_cd_drives) != NULL)
cdio_free_device_list(idx->ppsz_cd_drives);
idx->ppsz_cd_drives = NULL;
}
#ifdef Libburn_guess_freebsd_atapi_devicE
try_next:;
#endif
if (idx->pos == NULL)
return 0;
if (*(idx->pos) == NULL)
return 0;
#ifdef Libburn_guess_freebsd_atapi_devicE
if (strncmp(*(idx->pos), "/dev/acd", 8) == 0) {
(idx->pos)++;
goto try_next;
}
#endif
if (strlen(*(idx->pos)) >= adr_size)
return -1;
strcpy(adr, *(idx->pos));
(idx->pos)++;
return 1;
}
/* ----------------------------------------------------------------------- */
/* PORTING: Private functions which contain publicly needed functionality. */
/* Their portable part must be performed. So it is probably best */
/* to replace the non-portable part and to call these functions */
/* in your port, too. */
/* ----------------------------------------------------------------------- */
/** Wraps a detected drive into libburn structures and hands it over to
libburn drive list.
*/
static void enumerate_common(char *fname, char *cdio_name,
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;
/* PORTING: ------------------- non portable part --------------- */
/* Transport adapter is libcdio */
/* Adapter specific handles and data */
out.p_cdio = NULL;
strcpy(out.libcdio_name, fname);
if (strlen(cdio_name) < sizeof(out.libcdio_name))
strcpy(out.libcdio_name, cdio_name);
/* PORTING: ---------------- end of non portable part ------------ */
/* Adapter specific functions with standardized names */
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);
}
/* ------------------------------------------------------------------------ */
/* PORTING: Public functions. These MUST be ported. */
/* ------------------------------------------------------------------------ */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
char *version_text;
sprintf(msg, "sg-libcdio h%d with libcdio ", LIBCDIO_VERSION_NUM);
#if LIBCDIO_VERSION_NUM < 83
LIBBURN_MISCONFIGURATION = 0;
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_cdio_version_dot_h_TOO_OLD__NEED_libcdio_VERSION_NUM_83 = 0;
LIBBURN_MISCONFIGURATION_ = 0;
#endif /* LIBCDIO_VERSION_NUM < 83 */
version_text = (char *) cdio_version_string;
strncat(msg, version_text, 800);
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility of supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
int cdio_ver;
char *msg_pt;
cdio_loglevel_default = CDIO_LOG_ASSERT;
msg[0] = 0;
sg_id_string(msg, 0);
cdio_ver = libcdio_version_num;
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg , 0, 0);
if (cdio_ver < LIBCDIO_VERSION_NUM) {
strcat(msg, " ---> ");
msg_pt = msg + strlen(msg);
sprintf(msg_pt,
"libcdio TOO OLD: numeric version %d , need at least %d",
cdio_ver, LIBCDIO_VERSION_NUM);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg_pt, 0, 0);
return 0;
}
return 1;
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** Returns the next index number and the next enumerated drive address.
The enumeration has to cover all available and accessible drives. It is
allowed to return addresses of drives which are not available but under
some (even exotic) circumstances could be available. It is on the other
hand allowed, only to hand out addresses which can really be used right
in the moment of this call. (This implementation chooses the latter.)
@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, recursion_count = 0;
char path[4096];
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
if (ret <= 0)
return ret;
if (strlen(adr) >= sizeof(path))
return ret;
strcpy(path, adr);
ret = burn_drive_resolve_link(path, adr, &recursion_count, 2);
return (ret >= 0);
}
/** Brings all available, not-whitelist-banned, and accessible drives into
libburn's list of drives.
*/
int scsi_enumerate_drives(void)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret, i_bus_no = -1, recursion_count = 0;
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
char buf[4096], target[4096];
while(1) {
ret = sg_give_next_adr_raw(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
ret = burn_drive_resolve_link(buf, target, &recursion_count,2);
if (ret <= 0)
strcpy(target, buf);
if (burn_drive_is_banned(target))
continue;
sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no,
&i_channel_no, &i_target_no, &i_lun_no);
enumerate_common(target, buf,
i_bus_no, i_host_no, i_channel_no,
i_target_no, i_lun_no);
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
/** Tells whether libburn has the given drive in use or exclusively reserved.
If it is "open" then libburn will eventually call sg_release() on it when
it is time to give up usage resp. reservation.
*/
/** Published as burn_drive.drive_is_open() */
int sg_drive_is_open(struct burn_drive * d)
{
return (d->p_cdio != NULL);
}
/** Opens the drive for SCSI commands and - if burn activities are prone
to external interference on your system - obtains an exclusive access lock
on the drive. (Note: this is not physical tray locking.)
A drive that has been opened with sg_grab() will eventually be handed
over to sg_release() for closing and unreserving.
*/
int sg_grab(struct burn_drive *d)
{
CdIo_t *p_cdio;
char *am_eff, msg[4096], *am_wanted;
int os_errno, second_try = 0;
if (d->p_cdio != NULL) {
d->released = 0;
return 1;
}
if (d->libcdio_name[0] == 0) /* just to be sure it is initialized */
strcpy(d->libcdio_name, d->devname);
am_wanted = (burn_sg_open_o_excl & 63) ? "MMC_RDWR_EXCL" : "MMC_RDWR";
try_to_open:;
p_cdio = cdio_open_am(d->libcdio_name, DRIVER_DEVICE, am_wanted);
if (p_cdio == NULL) {
os_errno = errno;
sprintf(msg, "Could not grab drive '%s'", d->devname);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020003,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
return 0;
}
am_eff = (char *) cdio_get_arg(p_cdio, "access-mode");
if (strncmp(am_eff, "MMC_RDWR", 8) != 0) {
cdio_destroy(p_cdio);
if (!second_try) {
am_wanted = (burn_sg_open_o_excl & 63) ?
"MMC_RDWR" : "MMC_RDWR_EXCL";
second_try = 1;
goto try_to_open;
}
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020003,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"libcdio provides no MMC_RDWR access mode", 0, 0);
return 0;
}
d->p_cdio = p_cdio;
d->released = 0;
return 1;
}
/** PORTING: Is mainly about the call to sg_close_drive() and whether it
implements the demanded functionality.
*/
/** Gives up the drive for SCSI commands and releases eventual access locks.
(Note: this is not physical tray locking.)
*/
int sg_release(struct burn_drive *d)
{
if (d->p_cdio == NULL) {
burn_print(1, "release an ungrabbed drive. die\n");
return 0;
}
sg_close_drive(d);
return 0;
}
/** Sends a SCSI command to the drive, receives reply and evaluates wether
the command succeeded or shall be retried or finally failed.
Returned SCSI errors shall not lead to a return value indicating failure.
The callers get notified by c->error. An SCSI failure which leads not to
a retry shall be notified via scsi_notify_error().
The Libburn_log_sg_commandS facility might be of help when problems with
a drive have to be examined. It shall stay disabled for normal use.
@return: 1 success , <=0 failure
*/
int sg_issue_command(struct burn_drive *d, struct command *c)
{
int sense_valid = 0, i, usleep_time, timeout_ms;
time_t start_time;
driver_return_code_t i_status;
unsigned int dxfer_len;
static FILE *fp = NULL;
mmc_cdb_t cdb = {{0, }};
cdio_mmc_direction_t e_direction;
CdIo_t *p_cdio;
unsigned char *sense_pt = NULL;
c->error = 0;
if (d->p_cdio == NULL) {
return 0;
}
p_cdio = (CdIo_t *) d->p_cdio;
if (burn_sg_log_scsi & 1) {
if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
fprintf(fp,
"\n-----------------------------------------\n");
}
}
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
memcpy(cdb.field, c->opcode, c->oplen);
if (c->dir == TO_DRIVE) {
dxfer_len = c->page->bytes;
e_direction = SCSI_MMC_DATA_WRITE;
} else if (c->dir == FROM_DRIVE) {
if (c->dxfer_len >= 0)
dxfer_len = c->dxfer_len;
else
dxfer_len = BUFFER_SIZE;
e_direction = SCSI_MMC_DATA_READ;
/* touch page so we can use valgrind */
memset(c->page->data, 0, BUFFER_SIZE);
} else {
dxfer_len = 0;
e_direction = SCSI_MMC_DATA_NONE;
}
/* retry-loop */
start_time = time(NULL);
timeout_ms = 200000;
for(i = 0; ; i++) {
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
dxfer_len, c->page->data);
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
if (sense_valid >= 18)
memcpy(c->sense, sense_pt,
sense_valid >= sizeof(c->sense) ?
sizeof(c->sense) : sense_valid );
if (sense_pt != NULL)
free(sense_pt);
/* Regrettably mmc_run_cmd() does not clearly distinguish between transport
failure and SCSI error reply.
This reaction here would be for transport failure:
if (i_status != 0 && i_status != DRIVER_OP_ERROR) {
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 (!sense_valid) {
memset(c->sense, 0, sizeof(c->sense));
if (i_status != 0) { /* set dummy sense */
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
c->sense[2] = 0x02;
c->sense[12] = 0x04;
}
} else
c->sense[2] &= 15;
if (i_status != 0 ||
(c->sense[2] || c->sense[12] || c->sense[13])) {
if (!c->retry) {
c->error = 1;
goto ex;
}
switch (scsi_error(d, c->sense, 18)) {
case RETRY:
break;
case FAIL:
c->error = 1;
goto ex;
}
/*
Calming down retries and breaking up endless cycle
*/
usleep_time = Libburn_sg_libcdio_retry_usleeP +
i * Libburn_sg_libcdio_retry_incR;
if (time(NULL) + usleep_time / 1000000 - start_time >
timeout_ms / 1000 + 1) {
c->error = 1;
goto ex;
}
usleep(usleep_time);
} else
break; /* retry-loop */
} /* end of retry-loop */
ex:;
if (c->error)
scsi_notify_error(d, c, c->sense, 18, 0);
if (burn_sg_log_scsi & 3)
/* >>> Need own duration time measurement. Then remove bit1 */
scsi_log_err(c, fp, c->sense, 0, (c->error != 0) | 2);
return 1;
}
/** Tries 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)
{
CdIo_t *p_cdio;
char *tuple;
*bus_no = *host_no = *channel_no = *target_no = *lun_no = -1;
p_cdio = cdio_open(path, DRIVER_DEVICE);
if (p_cdio == NULL)
return 0;
/* Try whether a bus,host,channel,target,lun address tuple is
available */
tuple = (char *) cdio_get_arg(p_cdio, "scsi-tuple");
if (tuple != NULL) if (tuple[0]) {
sscanf(tuple, "%d,%d,%d,%d,%d",
bus_no, host_no, channel_no, target_no, lun_no);
}
cdio_destroy(p_cdio);
return (*bus_no >= 0);
}
/** Tells wether a text is a persistent address as listed by the enumeration
functions.
*/
int sg_is_enumerable_adr(char* adr)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
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);
}
#ifdef __FreeBSD__
#define Libburn_guess_block_devicE 1
#endif
#ifdef __FreeBSD_kernel__
#define Libburn_guess_block_devicE 1
#endif
#ifdef Libburn_guess_block_devicE
/* ts B00115 */
/* The FreeBSD implementation of burn_os_is_2k_seekrw().
On FreeBSD there are no block devices.
*/
static int freebsd_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
char *spt;
int i, e;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (!S_ISCHR(stbuf.st_mode))
return 0;
spt = strrchr(path, '/');
if (spt == NULL)
spt = path;
else
spt++;
e = strlen(spt);
for (i = strlen(spt) - 1; i > 0; i--)
if (spt[i] >= '0' && spt[i] <= '9')
e = i;
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
return 1;
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
return 1;
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
return 1;
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
return 1;
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
return 1;
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
return 1;
return 0;
}
#endif /* Libburn_guess_block_devicE */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
#ifdef Libburn_guess_block_devicE
return freebsd_is_2k_seekrw(path, flag);
#else
struct stat stbuf;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (S_ISBLK(stbuf.st_mode))
return 1;
return 0;
#endif /* ! Libburn_guess_block_devicE */
}
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
exist yet, then the directory will be inquired.
@param bytes The pointed value gets modified, but only if an estimation is
possible.
@return -2 = cannot perform necessary operations on file object
-1 = neither path nor dirname of path exist
0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set
*/
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
#ifdef Libburn_os_has_statvfS
struct statvfs vfsbuf;
#endif
char testpath[4096], *cpt;
long blocks;
off_t add_size = 0;
testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) {
strcpy(testpath, path);
cpt = strrchr(testpath, '/');
if(cpt == NULL)
strcpy(testpath, ".");
else if(cpt == testpath)
testpath[1] = 0;
else
*cpt = 0;
if (stat(testpath, &stbuf) == -1)
return -1;
#ifdef __linux
/* Linux specific determination of block device size */
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDONLY, fd, ret;
fd = open(path, open_mode);
if (fd == -1)
return -2;
ret = ioctl(fd, BLKGETSIZE, &blocks);
close(fd);
if (ret == -1)
return -2;
*bytes = ((off_t) blocks) * (off_t) 512;
#endif /* __linux */
#ifdef Libburn_is_on_freebsD
} else if(S_ISCHR(stbuf.st_mode)) {
int fd, ret;
fd = open(path, O_RDONLY);
if (fd == -1)
return -2;
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
close(fd);
if (ret == -1)
return -2;
*bytes = add_size;
#endif/* Libburn_is_on_freebsD */
} else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
return 0;
if (testpath[0]) {
#ifdef Libburn_os_has_statvfS
if (statvfs(testpath, &vfsbuf) == -1)
return -2;
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
(off_t) vfsbuf.f_bavail;
#else /* Libburn_os_has_statvfS */
return 0;
#endif /* ! Libburn_os_has_stavtfS */
}
return 1;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

View File

@ -1,11 +1,5 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* <<< ts A91112 : experiments to get better speed with USB
#define Libburn_sgio_as_growisofS 1
*/
/*
This is the main operating system dependent SCSI part of libburn. It implements
@ -35,28 +29,12 @@ and of deriving the following system specific files from existing examples:
Said sg-*.c operations are defined by a public function interface, which has
to be implemented in a way that provides libburn with the desired services:
sg_id_string() returns an id string of the SCSI transport adapter.
It may be called before initialization but then may
return only a preliminary id.
sg_initialize() performs global initialization of the SCSI transport
adapter and eventually needed operating system
facilities. Checks for compatibility of supporting
software components.
sg_shutdown() performs global finalizations and releases golbally
aquired resources.
sg_give_next_adr() iterates over the set of potentially useful drive
address strings.
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
accessible drives into libburn's list of drives.
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
on destruction. Releases resources which were aquired
underneath scsi_enumerate_drives().
sg_drive_is_open() tells wether libburn has the given drive in use.
sg_grab() opens the drive for SCSI commands and ensures
@ -70,25 +48,8 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
that can be used in 2 kB granularity by lseek(2) and
read(2), and possibly write(2) if not read-only.
E.g. a USB stick or a hard disk.
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
burn_os_alloc_buffer() allocates a memory area that is suitable for file
descriptors issued by burn_os_open_track_src().
The buffer size may be rounded up for alignment
reasons.
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
Porting hints are marked by the text "PORTING:".
Send feedback to libburn-hackers@pykix.org .
@ -101,13 +62,6 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
/** PORTING : ------- OS dependent headers and definitions ------ */
#ifdef Libburn_read_o_direcT
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif
#endif /* Libburn_read_o_direcT */
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@ -126,9 +80,6 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
/* for ioctl(BLKGETSIZE) */
#include <linux/fs.h>
/* for mmap() */
#include <sys/mman.h>
#include <scsi/sg.h>
/* Values within sg_io_hdr_t indicating success after ioctl(SG_IO) : */
@ -217,7 +168,6 @@ static int linux_ata_enumerate_verbous = 0;
/** PORTING : ------ libburn portable headers and definitions ----- */
#include "libburn.h"
#include "transport.h"
#include "drive.h"
#include "sg.h"
@ -246,25 +196,17 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* ts A60813 : storage objects are in libburn/init.c
whether to use O_EXCL with open(2) of devices
whether to use fcntl(,F_SETLK,) after open(2) of devices
wether to use O_EXCL with open(2) of devices
wether to use fcntl(,F_SETLK,) after open(2) of devices
what device family to use : 0=default, 1=sr, 2=scd, (3=st), 4=sg
whether to use O_NOBLOCK with open(2) on devices
whether to take O_EXCL rejection as fatal error
*/
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_fcntl_f_setlk;
extern int burn_sg_use_family;
extern int burn_sg_open_o_nonblock;
extern int burn_sg_open_abort_busy;
/* ts A91111 :
whether to log SCSI commands:
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
extern int burn_sg_log_scsi;
/* ts A60821
debug: for tracing calls which might use open drive fds
@ -1428,61 +1370,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* ------------------------------------------------------------------------ */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
strcpy(msg, "internal Linux SG_IO adapter sg-linux");
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** PORTING:
In this Linux implementation, this function mirrors the enumeration
done in sg_enumerate and ata_enumerate(). It would be better to base those
@ -1755,34 +1642,69 @@ int sg_release(struct burn_drive *d)
}
#ifdef NIX
/* <<< now in spc.c as scsi_log_err */
/** ts A70518:
Debugging log facility. Controlled by existence of macros:
Libburn_log_sg_commandS enables logging to file
/tmp/libburn_sg_command_log
Libburn_fflush_log_sg_commandS enables fflush after each output line
Libburn_log_sg_command_stderR enables additional log to stderr
*/
/*
#define Libburn_log_sg_commandS 1
#define Libburn_fflush_log_sg_commandS 1
#define Libburn_log_sg_command_stderR 1
*/
#ifdef Libburn_log_sg_commandS
/** Logs command (before execution) */
static int sg_log_cmd(struct command *c, FILE *fp, int flag)
{
int i;
if (fp != NULL) {
for(i = 0; i < 16 && i < c->oplen; i++)
fprintf(fp,"%2.2x ", c->opcode[i]);
fprintf(fp, "\n");
#ifdef Libburn_fflush_log_sg_commandS
fflush(fp);
#endif
}
if (fp == stderr)
return 1;
#ifdef Libburn_log_sg_command_stderR
sg_log_cmd(c, stderr, flag);
#endif
return 1;
}
/** logs outcome of a sg command. flag&1 causes an error message */
static int sg_log_err(struct command *c, FILE *fp,
sg_io_hdr_t *s,
int flag)
{
if(fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
if(flag & 1) {
if(fp!=NULL) {
if(flag & 1)
fprintf(fp,
"+++ key=%X asc=%2.2Xh ascq=%2.2Xh (%6d ms)\n",
s->sbp[2], s->sbp[12], s->sbp[13],s->duration);
} else {
scsi_show_cmd_reply(c, fp, 0);
else
fprintf(fp,"%6d ms\n", s->duration);
}
if (burn_sg_log_scsi & 4)
fflush(fp);
#ifdef Libburn_fflush_log_sg_commandS
fflush(fp);
#endif
}
if (fp == stderr || !(burn_sg_log_scsi & 2))
if (fp == stderr)
return 1;
#ifdef Libburn_log_sg_command_stderR
sg_log_err(c, stderr, s, flag);
#endif
return 1;
}
#endif /* NIX */
#endif /* Libburn_log_sg_commandS */
/** Sends a SCSI command to the drive, receives reply and evaluates wether
@ -1790,6 +1712,8 @@ static int sg_log_err(struct command *c, FILE *fp,
Returned SCSI errors shall not lead to a return value indicating failure.
The callers get notified by c->error. An SCSI failure which leads not to
a retry shall be notified via scsi_notify_error().
The Libburn_log_sg_commandS facility might be of help when problems with
a drive have to be examined. It shall stay disabled for normal use.
@return: 1 success , <=0 failure
*/
int sg_issue_command(struct burn_drive *d, struct command *c)
@ -1798,8 +1722,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
int err;
time_t start_time;
sg_io_hdr_t s;
#ifdef Libburn_log_sg_commandS
/* ts A61030 */
static FILE *fp= NULL;
#endif /* Libburn_log_sg_commandS */
/* <<< ts A60821
debug: for tracing calls which might use open drive fds */
@ -1808,16 +1735,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
d->fd,d->released);
mmc_function_spy(NULL, buf);
#ifdef Libburn_log_sg_commandS
/* ts A61030 */
if (burn_sg_log_scsi & 1) {
if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
fprintf(fp,
"\n-----------------------------------------\n");
}
if(fp==NULL) {
fp= fopen("/tmp/libburn_sg_command_log","a");
fprintf(fp,"\n-----------------------------------------\n");
}
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
sg_log_cmd(c,fp,0);
#endif /* Libburn_log_sg_commandS */
/* ts A61010 : with no fd there is no chance to send an ioctl */
if (d->fd < 0) {
@ -1830,13 +1756,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
s.interface_id = 'S';
#ifdef Libburn_sgio_as_growisofS
/* ??? ts A91112 : does this speed up USB ? (from growisofs)
--- did not help
*/
s.flags = SG_FLAG_DIRECT_IO;
#endif /* Libburn_sgio_as_growisofS */
if (c->dir == TO_DRIVE)
s.dxfer_direction = SG_DXFER_TO_DEV;
else if (c->dir == FROM_DRIVE)
@ -1957,9 +1876,11 @@ ex:;
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
if (burn_sg_log_scsi & 3)
/* <<< sg_log_err(c, fp, &s, c->error != 0); */
scsi_log_err(c, fp, s.sbp, s.duration, c->error != 0);
#ifdef Libburn_log_sg_commandS
sg_log_err(c, fp, &s, c->error != 0);
#endif /* Libburn_log_sg_commandS */
return 1;
}
@ -2055,24 +1976,6 @@ int sg_is_enumerable_adr(char *adr)
}
/* ts B00115 */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (S_ISBLK(stbuf.st_mode))
return 1;
return 0;
}
/* ts A70909 */
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
@ -2124,86 +2027,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
if (testpath[0]) {
if (statvfs(testpath, &vfsbuf) == -1)
return -2;
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
(off_t) vfsbuf.f_bavail;
}
return 1;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef PROT_READ
#ifdef PROT_WRITE
#ifdef MAP_SHARED
#ifdef MAP_ANONYMOUS
#ifdef MAP_FAILED
#define Libburn_linux_do_mmaP 1
#endif
#endif
#endif
#endif
#endif
#ifdef Libburn_read_o_direcT
#ifdef O_DIRECT
#define Libburn_linux_do_o_direcT 1
#endif
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
#ifdef Libburn_linux_do_o_direcT
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Opening track source with O_DIRECT" , 0, 0);
fd = open(path, open_flags | O_DIRECT);
#else
fd = open(path, open_flags);
#endif
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
#ifdef Libburn_linux_do_mmaP
/* >>> check whether size is suitable */;
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Allocating buffer via mmap()" , 0, 0);
buf = mmap(NULL, amount, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
if (buf == MAP_FAILED)
buf = NULL;
else
memset(buf, 0, amount);
#else
buf = calloc(1, amount);
#endif /* ! Libburn_linux_do_mmaP */
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
int ret = 0;
if (buffer == NULL)
return 0;
#ifdef Libburn_linux_do_mmaP
ret = munmap(buffer, amount);
#else
free(buffer);
#endif
return (ret == 0);
}

View File

@ -5,20 +5,10 @@
*/
#ifdef Libburn_use_libcdiO
#include "sg-libcdio.c"
#else
#ifdef __FreeBSD__
#include "sg-freebsd.c"
#else
#ifdef __FreeBSD_kernel__
#include "sg-freebsd.c"
#else
#ifdef __linux
@ -47,7 +37,5 @@ static int intentional_compiler_warning(void)
#include "sg-dummy.c"
#endif /* ! __linux */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libburn_use_libcdiO */

View File

@ -31,51 +31,6 @@ int scsi_enumerate_drives(void);
int sg_drive_is_open(struct burn_drive * d);
int burn_os_is_2k_seekrw(char *path, int flag);
int burn_os_stdio_capacity(char *path, off_t *bytes);
/* ts A91227 */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag);
/* ts A91225 */
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag);
/* ts A91227 */
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag);
/* ts A91227 */
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag);
#endif /* __SG */

View File

@ -27,13 +27,10 @@
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* ts A91111 :
whether to log SCSI commands:
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
extern int burn_sg_log_scsi;
/* ts A70910
debug: for tracing calls which might use open drive fds
or for catching SCSI usage of emulated drives. */
int mmc_function_spy(struct burn_drive *d, char * text);
/* spc command set */
@ -44,7 +41,8 @@ static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 36, 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 };
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 };
@ -100,9 +98,7 @@ int spc_test_unit_ready(struct burn_drive *d)
/* ts A70315 */
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready
bit1=do not issue success message
*/
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready */
/** Wait until the drive state becomes clear or until max_usec elapsed */
int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
int flag)
@ -116,6 +112,13 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
usleep(100000);
for(i = !(flag & 1); i < max_sec * 10; i++) {
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
/* <<<
fprintf(stderr,
"libburn_EXPERIMENTAL: i= %d ret= %d key= %X asc= %2.2X ascq= %2.2X\n",
i, ret, (unsigned) key, (unsigned) asc, (unsigned) ascq);
*/
if (ret > 0) /* ready */
break;
if (key!=0x2 || asc!=0x4) {
@ -137,14 +140,24 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
/* media change notice = try again */
goto slumber;
#ifdef NIX
sprintf(msg,
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
cmd_text, (unsigned) key, (unsigned) asc,
(unsigned) ascq);
#else
/* ts A90213 */
sprintf(msg,
"Asynchronous SCSI error on %s: ", cmd_text);
"Asynchromous SCSI error on %s: ", cmd_text);
sense[2] = key;
sense[12] = asc;
sense[13] = ascq;
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg),
&key, &asc, &ascq);
#endif /* ! NIX */
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -155,14 +168,11 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
slumber:;
usleep(100000);
}
if (ret <= 0 || !(flag & 2)) {
sprintf(msg, "Async %s %s after %d.%d seconds",
cmd_text, (ret > 0 ? "succeeded" : "failed"),
i / 10, i % 10);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020150, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
}
sprintf(msg, "Async %s %s after %d.%d seconds",
cmd_text, (ret > 0 ? "succeeded" : "failed"), i / 10, i % 10);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020150,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
if (i < max_sec * 10)
return (ret > 0);
@ -252,14 +262,14 @@ void spc_prevent(struct burn_drive *d)
return;
scsi_init_command(&c, SPC_PREVENT, sizeof(SPC_PREVENT));
/*
memcpy(c.opcode, SPC_PREVENT, sizeof(SPC_PREVENT));
c.oplen = sizeof(SPC_PREVENT);
c.page = NULL;
*/
c.retry = 1;
c.dir = NO_TRANSFER;
d->issue_command(d, &c);
#ifdef Libburn_pioneer_dvr_216d_get_evenT
mmc_get_event(d);
#endif
}
void spc_allow(struct burn_drive *d)
@ -328,7 +338,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
was_error = 1;
}
size = c.page->data[0] * 256 + c.page->data[1] + 2;
size = c.page->data[0] * 256 + c.page->data[1];
page = c.page->data + 8;
/* ts A61225 :
@ -479,7 +489,6 @@ void spc_sense_caps(struct burn_drive *d)
{
int alloc_len, start_len = 30, ret;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "sense_caps") <= 0)
return;
@ -504,7 +513,6 @@ void spc_sense_error_params(struct burn_drive *d)
unsigned char *page;
struct command c;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "sense_error_params") <= 0)
return;
@ -524,7 +532,7 @@ void spc_sense_error_params(struct burn_drive *d)
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
size = c.page->data[0] * 256 + c.page->data[1] + 2;
size = c.page->data[0] * 256 + c.page->data[1];
m = d->mdata;
page = c.page->data + 8;
d->params.retries = page[3];
@ -538,7 +546,6 @@ void spc_select_error_params(struct burn_drive *d,
struct buffer buf;
struct command c;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "select_error_params") <= 0)
return;
@ -580,7 +587,6 @@ void spc_sense_write_params(struct burn_drive *d)
unsigned char *page;
struct command c;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "sense_write_params") <= 0)
return;
@ -607,7 +613,7 @@ void spc_sense_write_params(struct burn_drive *d)
/* ts A71128 : do not interpret reply if error */
m = d->mdata;
if (!c.error) {
size = c.page->data[0] * 256 + c.page->data[1] + 2;
size = c.page->data[0] * 256 + c.page->data[1];
page = c.page->data + 8;
burn_print(1, "write page length 0x%x\n", page[1]);
m->write_page_length = page[1];
@ -644,9 +650,7 @@ void spc_select_write_params(struct burn_drive *d,
{
struct buffer buf;
struct command c;
int alloc_len;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "select_write_params") <= 0)
return;
@ -660,33 +664,13 @@ void spc_select_write_params(struct burn_drive *d,
o->block_type,spc_block_type(o->block_type));
*/
alloc_len = 8 + 2 + d->mdata->write_page_length;
memset(&(buf.data), 0, alloc_len);
#ifdef Libburn_pioneer_dvr_216d_load_mode5
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c.dxfer_len = alloc_len;
c.opcode[7] = (alloc_len >> 8) & 0xff;
c.opcode[8] = alloc_len & 0xff;
c.retry = 1;
c.opcode[2] = 0x05;
c.page = &buf;
c.page->bytes = 0;
c.page->sectors = 0;
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
if (c.error)
memset(&(buf.data), 0,
8 + 2 + d->mdata->write_page_length);
#endif /* Libburn_pioneer_dvr_216d_load_mode5 */
scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
/*
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c.oplen = sizeof(SPC_MODE_SELECT);
*/
c.retry = 1;
c.opcode[7] = (alloc_len >> 8) & 0xff;
c.opcode[8] = alloc_len & 0xff;
c.opcode[8] = 8 + 2 + d->mdata->write_page_length;
c.page = &buf;
c.page->bytes = 0;
c.page->sectors = 0;
@ -694,7 +678,8 @@ void spc_select_write_params(struct burn_drive *d,
/* ts A61007 : moved up to burn_disc_write() */
/* a ssert(d->mdata->valid); */
c.page->bytes = alloc_len;
memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length);
c.page->bytes = 8 + 2 + 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);
@ -731,7 +716,6 @@ void spc_probe_write_modes(struct burn_drive *d)
int last_try = 0;
struct command c;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
return;
@ -749,8 +733,11 @@ void spc_probe_write_modes(struct burn_drive *d)
try_block_type = useable_block_type;
last_try= 1;
}
scsi_init_command(&c, SPC_MODE_SELECT,sizeof(SPC_MODE_SELECT));
/*
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c.oplen = sizeof(SPC_MODE_SELECT);
*/
c.retry = 1;
c.opcode[8] = 8 + 2 + 0x32;
c.page = &buf;
@ -779,6 +766,7 @@ void spc_probe_write_modes(struct burn_drive *d)
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 {
@ -824,7 +812,6 @@ void spc_probe_write_modes(struct burn_drive *d)
return;
}
}
}
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
@ -932,24 +919,6 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
int *key, int *asc, int *ascq)
{
char *msg;
static char key_def[16][40] = {
"(no specific error)",
"Recovered error",
"Drive not ready",
"Medium error",
"Drive error",
"Illegal request",
"Drive event",
"Data protected",
"Blank/Nonblank",
"Vendor specific code",
"Copy aborted",
"Command aborted",
"(obsolete error code)",
"Volume overflow",
"Miscompare",
"(reserved error code)",
};
msg= msg_data;
*key= *asc= *ascq= -1;
@ -961,7 +930,7 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
if (senselen<=0 || senselen>13)
*ascq = sense[13];
sprintf(msg, "[%X %2.2X %2.2X] ", (*key) & 0xf, *asc, *ascq);
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
msg= msg + strlen(msg);
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
@ -1173,11 +1142,6 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "Medium not present");
d->status = BURN_DISC_EMPTY;
return FAIL;
case 0x57:
if (*key != 3 || *ascq != 0)
break;
sprintf(msg, "Unable to recover Table-of-Content");
return FAIL;
case 0x63:
if (*key != 5)
break;
@ -1230,8 +1194,8 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
return FAIL;
}
sprintf(msg_data,
"See MMC specs: Sense Key %X \"%s\", ASC %2.2X ASCQ %2.2X",
*key & 0xf, key_def[(*key) & 0xf], *asc, *ascq);
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
*key, *asc, *ascq);
return FAIL;
}
@ -1265,8 +1229,6 @@ static char *scsi_command_name(unsigned int c, int flag)
return "FORMAT UNIT";
case 0x1b:
return "START/STOP UNIT";
case 0x12:
return "INQUIRY";
case 0x1e:
return "PREVENT/ALLOW MEDIA REMOVAL";
case 0x23:
@ -1296,7 +1258,7 @@ static char *scsi_command_name(unsigned int c, int flag)
case 0x55:
return "MODE SELECT";
case 0x5a:
return "MODE SENSE";
return "SEND OPC INFORMATION";
case 0x5b:
return "CLOSE TRACK/SESSION";
case 0x5c:
@ -1374,119 +1336,3 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
return ret;
}
/* ts A91106 */
/* @param flag bit0= do not show eventual data payload sent to the drive
(never with WRITE commands)
bit1= show write length and target LBA in decimal
*/
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
{
int i;
FILE *fp = fp_in;
fprintf(fp, "\n%s\n",
scsi_command_name((unsigned int) c->opcode[0], 0));
for(i = 0; i < 16 && i < c->oplen; i++)
fprintf(fp, "%2.2x ", c->opcode[i]);
if (i > 0)
fprintf(fp, "\n");
if (flag & 1)
return 1;
if (c->opcode[0] == 0x2A) { /* WRITE 10 */
if (flag & 2)
fprintf(fp, "%d -> %d\n",
(c->opcode[7] << 8) | c->opcode[8],
mmc_four_char_to_int(c->opcode + 2));
} else if (c->opcode[0] == 0xAA) { /* WRITE 12 */
if (flag & 2)
fprintf(fp, "%d -> %d\n",
mmc_four_char_to_int(c->opcode + 6),
mmc_four_char_to_int(c->opcode + 2));
} else if (c->dir == TO_DRIVE) {
fprintf(fp, "To drive: %db\n", c->page->bytes);
for (i = 0; i < c->page->bytes; i++)
fprintf(fp, "%2.2x%c", c->page->data[i],
((i % 20) == 19 ? '\n' : ' '));
if (i % 20)
fprintf(fp, "\n");
}
return 1;
}
/* ts A91106 */
int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
{
int i;
FILE *fp = fp_in;
if (c->dir != FROM_DRIVE)
return 2;
if (c->opcode[0] == 0x28 || c->opcode[0] == 0x3C ||
c->opcode[0] == 0xA8 || c->opcode[0] == 0xBE) {
/* READ commands */
/* >>> report amount of data */;
return 2;
}
fprintf(fp, "From drive: %db\n", c->dxfer_len);
for (i = 0; i < c->dxfer_len; i++)
fprintf(fp, "%2.2x%c", c->page->data[i],
((i % 20) == 19 ? '\n' : ' '));
if (i % 20)
fprintf(fp, "\n");
return 1;
}
/* ts A91218 (former sg_log_cmd ts A70518) */
/** Logs command (before execution) */
int scsi_log_cmd(struct command *c, void *fp_in, int flag)
{
FILE *fp = fp_in;
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
scsi_show_cmd_text(c, fp, 0);
if (burn_sg_log_scsi & 4)
fflush(fp);
}
if (fp == stderr || !(burn_sg_log_scsi & 2))
return 1;
scsi_log_cmd(c, stderr, flag);
return 1;
}
/* ts A91221 (former sg_log_err ts A91108) */
/** Logs outcome of a sg command.
@param flag bit0 causes an error message
bit1 do not print duration
*/
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
int duration, int flag)
{
char durtxt[20];
FILE *fp = fp_in;
if(fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
if(flag & 1) {
durtxt[0] = 0;
if (!(flag & 2))
sprintf(durtxt, " (%6d ms)\n",duration);
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
sense[2], sense[12], sense[13], durtxt);
} else {
scsi_show_cmd_reply(c, fp, 0);
if (!(flag & 2))
fprintf(fp,"%6d ms\n", duration);
}
if (burn_sg_log_scsi & 4)
fflush(fp);
}
if (fp == stderr || !(burn_sg_log_scsi & 2))
return 1;
scsi_log_err(c, stderr, sense, duration, flag);
return 1;
}

View File

@ -59,20 +59,4 @@ int scsi_notify_error(struct burn_drive *, struct command *c,
/* ts A70519 */
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
/* ts A91106 */
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
/* ts A91106 */
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
/* ts A91218 (former sg_log_cmd ts A70518) */
/** Logs command (before execution) */
int scsi_log_cmd(struct command *c, void *fp, int flag);
/* ts A91221 (former sg_log_err ts A91108) */
/** Logs outcome of a sg command. */
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
int duration, int flag);
#endif /*__SPC*/

View File

@ -220,7 +220,6 @@ struct burn_drive
/* ts A61218 from 51h READ DISC INFORMATION */
int last_lead_in;
int last_lead_out;
int num_opc_tables; /* ts A91104: -1= not yet known */
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
int disc_type; /* 0="CD-DA or CD-ROM", 0x10="CD-I", 0x20="CD-ROM XA" */
unsigned int disc_id; /* a "32 bit binary integer" */

View File

@ -43,19 +43,11 @@
#include "options.h"
#include "structure.h"
#include "source.h"
#include "mmc.h"
#include "spc.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* ts A91120 : <<< experimental */
#ifdef Libburn_mmap_write_buffeR
#include <sys/mman.h>
#endif
/* The maximum output size to be used with CD media. This is also curbed
by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
*/
@ -890,14 +882,9 @@ ex:;
next track. cdrecord does not use CLOSE TRACK at all but
ends the tracks by SYNCHRONIZE CACHE alone.
*/
/* ts A91202 :
Peng Shao reports that his LG GH22LS30 issues an SCSI error
on CLOSE TRACK even in non-dummy mode. So i better give up
this gesture which seems not be needed by any drive.
if (!o->simulate)
if (burn_write_close_track(o, s, tnum) <= 0)
ret = 0;
*/
if (!o->simulate)
if (burn_write_close_track(o, s, tnum) <= 0)
ret = 0;
}
return ret;
}
@ -1093,25 +1080,11 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
/* ts A70214 : eventually adjust already expanded size of track */
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
#ifdef Libburn_pioneer_dvr_216d_with_opC
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : num_opc_tables = %d\n", d->num_opc_tables);
if (d->num_opc_tables <= 0 && !o->simulate) {
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : performing OPC\n");
d->perform_opc(d);
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : done\n");
}
#endif
#ifdef Libburn_pioneer_dvr_216d_get_evenT
mmc_get_event(d);
#endif
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
/* Round track size up to write chunk size and reserve track */
/* Round track size up to 32 KiB and reserve track */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
* (off_t) 2048;
if (size % o->obs)
size += (off_t) (o->obs - (size % o->obs));
* (off_t) 2048;
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
ret = d->reserve_track(d, size);
if (ret <= 0) {
sprintf(msg, "Cannot reserve track of %.f bytes",
@ -1149,11 +1122,14 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
if (o->write_type == BURN_WRITE_SAO &&
! burn_track_is_open_ended(s->track[tnum])) {
/* Round track size up to write chunk size and reserve track */
/* Round track size up to 32 KiB and reserve track */
/* ts A81208 */
/* >>> ??? round to 64 KiB for BD-R ? (It is not mandatory) */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
* (off_t) 2048;
if (size % o->obs)
size += (off_t) (o->obs - (size % o->obs));
* (off_t) 2048;
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
ret = d->reserve_track(d, size);
if (ret <= 0) {
sprintf(msg, "Cannot reserve track of %.f bytes",
@ -1255,132 +1231,6 @@ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
}
/* <<<
#define Libburn_simplified_dvd_chunk_transactioN 1
*/
#ifdef Libburn_simplified_dvd_chunk_transactioN
/* ts A91114 : EXPERIMENTAL, NOT COMPLETELY IMPLEMENTED
Simplified data transmission for DVD. libburn via Linux USB is 30 % slower
than growisofs or cdrecord when transmitting 32 KB chunks.
With 64 KB chunks it is 20% faster than the competitors.
No heavy CPU load is visible but there might be subtle race conditions in
the USB driver which work better with shorter time gaps between WRITE
commands.
Insight: It is actually about the interference of track source reading
with SCSI writing via USB. growisofs reads with O_DIRECT into a
mmap()ed buffer. When doing the same, libburn with 32 KB chunks
reaches similar write speed.
On the other hand, 64 KB chunks are 20% faster than that and
are not improved by reading O_DIRECT.
O_DIRECT is a property of the input fd of struct burn_source.
It can only be done with properly aligned memory and with aligned
read size. Alignment size is file system system specific.
System call
mmap(NULL, (size_t) buffer_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
is supposed to allocate a properly aligned buffer.
64 KB is supposed to be a safe size.
Actually mmap() seems to be the main cause for a positive effect
of O_DIRECT.
This simplified transmission function did not bring visible benefit.
So for now it is not worth to teach it all applicable details of old
CD sector oriented transmission.
@return 1= ok, go on , 2= no input with track->open_ended = nothing written
<= 0 = error
*/
static int transact_dvd_chunk(struct burn_write_opts *opts,
struct burn_track *track)
{
int curr = 0, valid, err;
struct burn_drive *d = opts->drive;
struct buffer *out = d->buffer;
unsigned char *data = out->data;
#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 */
/* Read a chunk full of data */
/* ??? Do we have offset padding ? >>> First produce offset padding */;
/* <<<< */
if (0 && !track->eos) {
for (curr = 0; curr < opts->obs; curr += 2048) {
if (track->source->read != NULL)
valid = track->source->read(track->source,
data + curr, 2048);
else
valid = track->source->read_xt(track->source,
data + curr, 2048);
if (valid <= 0) {
track->eos = 1;
break;
}
track->sourcecount += valid;
#ifdef Libburn_log_in_and_out_streaM
if(tee_fd!=-1 && valid>0) {
write(tee_fd, data + curr, valid);
}
#endif /* Libburn_log_in_and_out_streaM */
}
} else if (!track->eos){
valid = track->source->read(track->source, data, opts->obs);
if (valid <= 0) {
track->eos = 1;
} else {
track->sourcecount += valid;
curr = valid;
#ifdef Libburn_log_in_and_out_streaM
if(tee_fd!=-1 && valid>0) {
write(tee_fd, data, valid);
}
#endif /* Libburn_log_in_and_out_streaM */
}
}
if (curr == 0 && track->open_ended) {
/* >>> allow tail padding */;
return 2;
}
if (curr < opts->obs)
memset(data + curr , 0, opts->obs - curr);
/* Write chunk */
out->bytes = opts->obs;
out->sectors = out->bytes / 2048;
err = d->write(d, d->nwa, out);
if (err == BE_CANCELLED)
return 0;
track->writecount += out->bytes;
track->written_sectors += out->sectors;
d->progress.buffered_bytes += out->bytes;
d->nwa += out->sectors;
out->bytes = 0;
out->sectors = 0;
return 1;
}
#endif /* Libburn_simplified_dvd_chunk_transactioN */
/* ts A61218 - A81208 */
int burn_dvd_write_track(struct burn_write_opts *o,
struct burn_session *s, int tnum, int is_last_track)
@ -1390,7 +1240,6 @@ int burn_dvd_write_track(struct burn_write_opts *o,
struct buffer *out = d->buffer;
int sectors;
int i, open_ended = 0, ret= 0, is_flushed = 0;
int first_buf_cap = 0, further_cap = 0, buf_cap_step = 1024;
/* ts A70213 : eventually expand size of track to max */
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
@ -1401,11 +1250,6 @@ int burn_dvd_write_track(struct burn_write_opts *o,
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
if (ret <= 0)
goto ex;
/* Pioneer DVR-216D rev 1.09 hates multiple buffer inquiries
before the drive buffer is full.
*/
first_buf_cap = 0;
further_cap = -1;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
@ -1441,30 +1285,12 @@ int burn_dvd_write_track(struct burn_write_opts *o,
for (i = 0; open_ended || i < sectors; i++) {
/* From time to time inquire drive buffer */
/* ts A91110: Eventually avoid to do this more than once
before the drive buffer is full. See above DVD-
*/
if (i == first_buf_cap ||
((i % buf_cap_step) == 0 &&
(i >= further_cap || further_cap < 0))) {
if ((i%256)==0)
d->read_buffer_capacity(d);
if (further_cap < 0)
further_cap =
d->progress.buffer_capacity / 2048 + 128;
}
#ifdef Libburn_simplified_dvd_chunk_transactioN
ret = transact_dvd_chunk(o, t);
if (ret <= 0)
{ret = 0; goto ex;}
i += o->obs / 2048 - 1;
d->progress.sector += o->obs / 2048 - 1;
#else
/* transact a (CD sized) sector */
if (!sector_data(o, t, 0))
{ ret = 0; goto ex; }
#endif
if (open_ended) {
d->progress.sectors = sectors = i;
@ -1923,47 +1749,15 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
}
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
if (d->do_stream_recording) {
if (d->current_profile == 0x41) /* BD-R */
o->obs = Libburn_bd_re_streamed_obS;
}
}
#ifdef Libburn_dvd_obs_default_64K
o->obs = 64 * 1024;
#endif
/* <<< test only : Does this increase effective speed with USB ?
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
128kB: glibc complains about double free
With BURN_OS_TRANSPORT_BUFFER_SIZE
enlarged to 128 MB, the first WRITE fails
with an i/o error.
o->obs = 64 * 1024;
>>> next try is 128 kB
o->obs = 128 * 1024;
*/
if (o->dvd_obs_override >= 32 * 1024)
o->obs = o->dvd_obs_override;
if (o->obs > BUFFER_SIZE) {
sprintf(msg, "Chosen write chunk size %d exceeds system dependent buffer size", o->obs);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
o->obs = 32 * 1024; /* This size is required to work */
}
if (d->do_stream_recording &&
(d->current_profile == 0x43 || d->current_profile == 0x41) &&
o->obs < Libburn_bd_re_streamed_obS) {
/* LG GGW-H20 writes junk with stream recording and obs=32k */
sprintf(msg,
"Stream recording disabled because of small OS buffer");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020176, LIBDAX_MSGS_SEV_NOTE,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
d->do_stream_recording = 0;
}
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
d->current_profile, o->obs, o->obs_pad);
@ -2251,9 +2045,8 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
break;
}
d->progress.sector++;
/* Flush to disk from time to time */
if (d->progress.sector - prev_sync_sector >=
o->stdio_fsync_size && o->stdio_fsync_size > 0) {
/* Flush to disk after each full MB */
if (d->progress.sector - prev_sync_sector >= 512) {
prev_sync_sector = d->progress.sector;
if (!o->simulate)
burn_stdio_sync_cache(d->stdio_fd, d, 1);
@ -2336,7 +2129,6 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
off_t default_size;
char msg[80];
/* ts A60924 : libburn/message.c gets obsoleted
burn_message_clear_queue();
*/
@ -2351,12 +2143,11 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
else
d->stream_recording_start = 0;
/* ts A91122 : Get buffer suitable for sources made by
burn_os_open_track_src() */
d->buffer = burn_os_alloc_buffer(sizeof(struct buffer), 0);
d->buffer = calloc(sizeof(struct buffer), 1);
if (d->buffer == NULL)
goto fail_wo_sync;
/* >>> ts A90321
memset(d->buffer, 0, sizeof(struct buffer));
@ -2577,8 +2368,7 @@ fail_wo_sync:;
ex:;
d->do_stream_recording = 0;
if (d->buffer != NULL)
burn_os_free_buffer((char *) d->buffer,
sizeof(struct buffer), 0);
free((char *) d->buffer);
d->buffer = buffer_mem;
return;
}

View File

@ -1,7 +1,7 @@
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
/* Copyright (C) 2005 - 2010 Thomas Schmitt <scdbackup@gmx.net> */
/* Provided under GPL, see also "License and copyright aspects" at file end */
/* Copyright (C) 2005 - 2009 Thomas Schmitt <scdbackup@gmx.net> */
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
/** Overview
@ -38,16 +38,6 @@
burn_finish()
*/
/*
Applications must use 64 bit off_t. E.g. by defining
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
or take special precautions to interface with the library by 64 bit integers
where libburn/libburn.h prescribes off_t.
This program gets fed with appropriate settings externally by libburn's
autotools generated build system.
*/
/** See this for the decisive API specs . libburn.h is The Original */
/* For using the installed header file : #include <libburn/libburn.h> */
@ -778,6 +768,37 @@ 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 libburnia. 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

View File

@ -1,7 +1,7 @@
/* test/telltoc.c , API illustration of obtaining media status info */
/* Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL */
/* Copyright (C) 2006 - 2007 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 */
/** Overview