@ -0,0 +1,317 @@ | |||
------------------------------------------------------------------------------ | |||
libburn.pykix.org scdbackup.sourceforge.net/cdrskin | |||
------------------------------------------------------------------------------ | |||
This all is under GPL. Wether it can become LGPL is currently very unclear. | |||
(So for now see explanation and GPL reference at the end of this text) | |||
------------------------------------------------------------------------------ | |||
Libburn. By 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>, Luke Biddell <luke.biddell@gmail.com>, | |||
Anant Narayanan <anant@kix.in> , Thomas Schmitt <scdbackup@gmx.net> | |||
Copyright (C) 2006 Mario Danic, Luke Biddell, Anant Narayanan, Thomas Schmitt | |||
------------------------------------------------------------------------------ | |||
My thanks to the above authors (except myself, of course) for making the | |||
following possible. | |||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net> | |||
Integrated sub project of libburn.pykix.org but also published via: | |||
http://scdbackup.sourceforge.net/cdrskin_eng.html | |||
http://scdbackup.sourceforge.net/cdrskin-0.1.4.tar.gz | |||
Copyright (C) 2006 Thomas Schmitt | |||
------------------------------------------------------------------------------ | |||
On top of libburn there is implemented cdrskin 0.1.4, a limited cdrecord | |||
compatibility wrapper which allows to use some libburn features from | |||
the command line. | |||
Interested users of cdrecord are invited to participate in the development | |||
of cdrskin. Contact: scdbackup@gmx.net | |||
Important : | |||
This software is provided as is. There is no warranty implied and no | |||
protection against possible damages. You use this on your own risk. | |||
Don't blame me or other authors of libburn if anything goes wrong. | |||
I used it on my own risk with : | |||
SuSE 7.2, kernel 2.4.4, ide-scsi emulation, LITE-ON LTR48125S CD burner | |||
SuSE 9.0, kernel 2.4.21, ide-scsi emulation, LG GSA-4082B CD/DVD burner | |||
RIP-14.4, kernel 2.6.14, no ide-scsi, with both above burners | |||
It fails to compile or run on SuSE 6.4 (kernel 2.2.14). | |||
It does not find the IDE CD burner on SuSE 7.2 without ide-scsi. | |||
Other people sucessfully tested cdrskin on several kernel 2.6 based x86 Linux | |||
systems, including 64 bit systems. (Further reports are welcome.) | |||
Compilation, First Glimpse, Installation | |||
Obtain cdrskin-0.1.4.tar.gz , go to a directory of your choice and do: | |||
tar xzf cdrskin-0.1.4.tar.gz | |||
cd cdrskin-0.1.4 | |||
Or obtain a libburn.pykix.org SVN snapshot, go into toplevel directory libburn, | |||
and execute the autotools command ./bootstrap | |||
Within that toplevel directory of either cdrskin-0.1.4 or libburn then execute: | |||
./configure | |||
make | |||
(Note: there are next-level directories "libburn" and "cdrskin". Those | |||
would be the wrong ones. Meant is the highest directory of tarball resp. | |||
SVN download. Among others containing files "AUTHORS", "configure", | |||
"Makefile.am", as well as directories "libburn" and "cdrskin".) | |||
This will already produce a cdrskin binary. But it might be necessary to | |||
install libburn in order to use this binary. Installation of libburn is | |||
beyond the scope of cdrskin. For this, see included libburn docs. | |||
In order to surely get a standalone binary, execute | |||
cdrskin/compile_cdrskin.sh | |||
Help texts : | |||
cdrskin/cdrskin --help | |||
cdrskin/cdrskin -help | |||
Install (eventually as superuser) cdrskin to a directory where it can be found: | |||
cp cdrskin/cdrskin /usr/bin | |||
It is not necessary for the standalone cdrskin binary to have libburn | |||
installed, since it incorporates the necessary libburn parts at compile time. | |||
It will not collide with an installed version of libburn either. | |||
But libpthread must be installed on the system and glibc has to match. (See | |||
below for a way to create a statically linked binary.) | |||
Up to now i discourage to install the emerging libraries and to use them | |||
with other programs. Unless you need my patches, better use vanilla libburn | |||
for that. | |||
Usage | |||
The user of cdrskin needs rw-permission for the CD burner device. | |||
A list of rw-accessible drives can be obtained by | |||
cdrskin --devices | |||
CD devices which offer no rw-permission are invisible to normal users. | |||
The superuser should be able to see any usable drive and then set the | |||
permissions as needed. If this hangs then there is a drive with | |||
unexpected problems (locked, busy, broken, whatever). You might have to | |||
guess the address of your (non-broken) burner by other means, then. | |||
On Linux 2.4 this would be some /dev/sgN and on 2.6. some /dev/hdX. | |||
The output of cdrskin --devices might look like | |||
0 dev='/dev/sg0' rwrwr- : 'TEAC' 'CD-ROM CD-532S' | |||
1 dev='/dev/sg1' rwrw-- : 'LITE-ON' 'LTR-48125S' | |||
So full and insecure enabling of both for everybody would look like | |||
chmod a+rw /dev/sg0 /dev/sg1 | |||
(The CD-ROM is in these examples only for demonstrating the presence of another | |||
SCSI device. This /dev/sg0 may be left as it is and stay invisible for normal | |||
users.) | |||
I strongly discourage to run cdrskin with setuid root or via sudo ! | |||
It is not checked for the necessary degree of hacker safety. | |||
Usage examples | |||
Get an overview of cdrecord style addresses of available devices | |||
cdrskin -scanbus | |||
Obtain some info about the drive | |||
cdrskin dev=1,1,0 -checkdrive | |||
Obtain some info about the drive and the inserted media | |||
cdrskin dev=1,1,0 -atip | |||
Thoroughly blank a CD-RW | |||
cdrskin -v dev=1,1,0 blank=all eject_device=/dev/cdrom -eject | |||
Blank CD-RW sufficiently for making it ready for overwrite | |||
cdrskin -v dev=1,1,0 blank=fast eject_device=/dev/cdrom -eject | |||
Burn image file my_image.iso to CD | |||
cdrskin -v dev=1,1,0 speed=12 fs=8m -sao driveropts=burnfree padsize=300k \ | |||
eject_device=/dev/cdrom -eject my_image.iso | |||
Burn a compressed afio archive to CD on-the-fly | |||
find . | afio -oZ - | cdrskin -v dev=1,1,0 fs=32m speed=8 -sao \ | |||
driveropts=burnfree padsize=300k tsize=650m - | |||
Usage example with http://scdbackup.sourceforge.net | |||
Address may be a cdrecord-style "scsibus,target,lun" as listed with | |||
cdrskin -scanbus (but not as listed with cdrecord -scanbus) : | |||
export SCDBACKUP_SCSI_ADR="1,1,0" | |||
or a device file address as listed by --devices with an accessible drive : | |||
export SCDBACKUP_SCSI_ADR="/dev/sg1" | |||
Set usage of cdrskin with appropriate options rather than cdrecord : | |||
export SCDBACKUP_CDRECORD="cdrskin -v -v tao_to_sao_tsize=650m eject_device=/dev/cdrw" | |||
Run a backup : | |||
scdbackup_home | |||
Restrictions | |||
The convenient burn mode TAO is not available with libburn yet. | |||
Therefore it has to be defaulted to mode SAO which needs to know the track | |||
size in advance. non-cdrecord option tao_to_sao_tsize=650m causes each CD | |||
to get burned up to 650 MB regardless of the payload size. | |||
Command eject does not work with /dev/sgX and there is no easy way to determine | |||
a drive's device file address which is suitable for eject. | |||
So this address has to be supplied by eject_device=... unless your drive is | |||
/dev/sg0 which is guessed as eject_device=/dev/sr0 . | |||
No audio features, no multi session ... Please report your wishes. | |||
Inspiration and Standard | |||
For the original meaning of cdrecord options see : | |||
man cdrecord | |||
(http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html) | |||
Do not bother Joerg Schilling with any cdrskin problems. | |||
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding | |||
this "don't bother Joerg" demand.) | |||
cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes | |||
have been copied from the message output of cdrecord runs, though. I am | |||
thankful to Joerg Schilling for every single one of them. | |||
Actually i, Thomas Schmitt, am a devoted user of cdrecord via my project | |||
scdbackup which still runs a bit better with cdrecord than with cdrskin. TAO. | |||
I have the hope that Joerg feels more flattered than annoyed by cdrskin. | |||
Pseudo-SCSI Adresses | |||
cdrecord and cdrskin share only some syntax of addresses but not the meaning | |||
of the components. A cdrecord-style address for cdrskin | |||
[[prefix:]scsibus,]target,lun | |||
corresponds either to a device file address or to a libburn drive number. | |||
Component "scsibus" indicates the translation method. Defined busses are: | |||
0 target is the libburn drivenumber as listed with --devices | |||
1 associated to device file /dev/sgN , target chooses N | |||
2 associated to device file /dev/hdX , target 0='a', 1='b' ..., 25='z' | |||
So "1,1,0" is /dev/sg1, "2,3,0" is /dev/hdd, "0,2,0" is libburn drive #2 at | |||
some unspecified device file. | |||
This scheme shall help to keep cdrecord-style addresses stable and exchangeable | |||
between users without excluding drives with unexpected device addresses. | |||
The numbering on bus 0 is prone to arbitrary changes caused by changes in | |||
drive accessability. | |||
Further busses may emerge as libburn evolves. "prefix" and "lun" may get | |||
a meaning. To stay upward compatible, use addresses as printed by -scanbus. | |||
Some programs or users have their own ideas about the address of their burner. | |||
K3b 0.10 for example derives cdrecord addresses by own examination of the | |||
devices and not by calling cdrecord -scanbus. | |||
To direct such callers to the appropriate drives, cdrskin allows to define | |||
device address aliases. Like | |||
cdrskin dev_translation=+1,0,0+/dev/sg1 \ | |||
dev_translation=+ATA:1,0,0+/dev/sg1 \ | |||
dev_translation=-"cd+dvd"-1,1,0 \ | |||
... | |||
Any of the addresses dev=1,0,0, dev=ATA:1,0,0, dev=cd+dvd will be mapped to | |||
/dev/sg1 resp. to its standard alias 1,1,0. | |||
The first character after "dev_translation=" defines the character which | |||
separates the two parts of the translation pair. (Above: "+" and "-".) | |||
In K3b 0.10 it is possible to employ alternative writer programs by setting | |||
their full path (e.g. /usr/bin/cdrskin) in menu | |||
Settings:Configure K3b...:Programs:Search Path | |||
and to make them default in menu | |||
Settings:Configure K3b...:Programs:Programs: | |||
A suitable setting for "cdrecord" in menu | |||
Settings:Configure K3b...:Programs:User Parameters | |||
would then probably be | |||
-v dev_translation=+1,0,0+/dev/sg1 | |||
You will learn from button "Show Debugging Output" after a failed burn run | |||
what cdrecord command was used with what address "dev=...". This address "..." | |||
will be the right one to replace "1,0,0" in above example. | |||
Startup Files | |||
If not --no_rc is the first argument then cdrskin attempts on startup to read | |||
arguments from the following three files: | |||
/etc/defaults/cdrskin | |||
/etc/opt/cdrskin/rc | |||
$HOME/.cdrskinrc | |||
The files are read in the sequence given above. | |||
Each readable line is treated as one single argument. No extra blanks, | |||
no comments, no empty lines are permitted. | |||
Example content of a startup file: | |||
dev=1,1,0 | |||
dev_translation=+1,0,0+1,1,0 | |||
--fifo_start_empty | |||
fs=16m | |||
Special compilation variations | |||
You may get a (super fat) statically linked binary by : | |||
cdrskin/compile_cdrskin.sh -static | |||
if your system supports static linking, at all. This will not help with kernels | |||
which do not properly support the necessary low-level interfaces chosen by | |||
your compile-time libraries. | |||
A size reduced but fully functional binary may be produced by | |||
cdrskin/compile_cdrskin.sh -do_strip | |||
An extra lean binary with reduced capabilities is created by | |||
cdrskin/compile_cdrskin.sh -do_diet -do_strip | |||
It will not read startup files, will abort on option dev_translation= , | |||
will not have a fifo buffer, and will not be able to put out help texts or | |||
debugging messages. | |||
------------------------------------------------------------------------------ | |||
It is my understanding that you may put a binary of unchanged cdrskin on any | |||
suitable system if you only tell the user that the source is available for | |||
free in the internet. Search engines will find it. Better than any URL here. | |||
If you link to the libraries or if you make changes in our source, you will | |||
currently have to release your own programs under GPL and nothing else, i fear. | |||
As it looks no single one of us currently has the right to issue any other | |||
license. | |||
You may submit source changes which affect our standalone binaries and if | |||
they get included you may distribute binaries derived from our new code base. | |||
signed: Thomas Schmitt (and his understanding of GPL), author of this README. | |||
------------------------------------------------------------------------------ | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
@ -0,0 +1,163 @@ | |||
#!/bin/sh | |||
set -x | |||
# This script documents how this cdrskin version was derived from | |||
# a vanilla libburn version. It is not intended nor needed for any | |||
# use of cdrskin but included here only to show the technical | |||
# relationship between both projects - which are close friends | |||
# and issue roughly the same software. | |||
# | |||
# Package maintainers are advised to cover rather libburn than | |||
# cdrskin unless they put only emphasis on the cdrecord emulation | |||
# provided by cdrskin. libburn contains cdrskin - cdrskin is an | |||
# oscillating, friendly and coordinated fork of libburn. | |||
# | |||
# Script results are a source tarball and two binaries | |||
# one dynamic and one static in respect to system libs. | |||
# Both binaries are static in respect to libburn. | |||
# | |||
# The script is to be run in the directory above the toplevel | |||
# directory of libburn resp. cdrskin development. | |||
# | |||
# libburn version used: http://libburn.pykix.org SVN of Aug 15 2006 | |||
# packed up in a tarball just to save it from inadverted changes. | |||
original="./libburn_svn_A60815.tgz" | |||
# The top level directory in that snapshot is named | |||
intermediate="./libburn" | |||
# My changes are in libburn-0.2.1.ts.develop , mainly in ./cdrskin | |||
changes="./libburn-0.2.1.ts.develop" | |||
skin_rev="0.1.4" | |||
# The result directory and the name of the result tarballs | |||
target="./cdrskin-${skin_rev}" | |||
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz" | |||
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz" | |||
# (This once earned me an embarrassingly blooping source tarball) | |||
# compile_dir="$changes" | |||
compile_dir="$target" | |||
compile_cmd="./cdrskin/compile_cdrskin.sh" | |||
compile_static_opts="-static" | |||
compile_result="cdrskin/cdrskin" | |||
# addresses relative to compile_dir : | |||
bintarget_dynamic="../cdrskin_${skin_rev}-x86-suse9_0" | |||
bintarget_static="$bintarget_dynamic"-static | |||
if test -d "$changes" | |||
then | |||
dummy=dummy | |||
else | |||
echo "$0 : FATAL : no directory $changes" >&2 | |||
exit 1 | |||
fi | |||
for i in "$target" "$intermediate" | |||
do | |||
if test -e "$i" | |||
then | |||
echo "$0 : FATAL : already existing $i" >&2 | |||
exit 2 | |||
fi | |||
done | |||
if test -f "$original" | |||
then | |||
dummy=dummy | |||
else | |||
echo "$0 : FATAL : no file $original" >&2 | |||
fi | |||
# Unpack SVN snapshot. | |||
tar xzf "$original" | |||
# Rename the directory to the cdrskin name | |||
mv "$intermediate" "$target" | |||
# Copy the changes from the development tree | |||
# | |||
cdrskin_dir="$changes"/cdrskin | |||
libburn_dir="$changes"/libburn | |||
cdrskin_target="$target"/cdrskin | |||
libburn_target="$target"/libburn | |||
# Create version timestamp | |||
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" | |||
echo "$timestamp" | |||
echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h | |||
# Add the cdrskin files | |||
if test -e "$cdrskin_target" | |||
then | |||
rm -rf "$cdrskin_target" | |||
fi | |||
cp -a "$cdrskin_dir" "$cdrskin_target" | |||
# Remove copied binaries | |||
rm "$cdrskin_target"/cdrfifo | |||
rm "$cdrskin_target"/cdrskin | |||
rm "$cdrskin_target"/cleanup | |||
# Remove unwanted SVN stuff (TODO: avoid downloading it) | |||
for i in "$target"/.svn "$target"/*/.svn | |||
do | |||
if test "$i" = "$target"'/*/.svn' | |||
then | |||
dummy=dummy | |||
else | |||
if test -e "$i" | |||
then | |||
rm -rf "$i" | |||
fi | |||
fi | |||
done | |||
# For now: Add own libburn-README in toplevel | |||
cp -a "$changes"/README "$target" | |||
# Add modified Makefile.am | |||
cp -a "$changes"/Makefile.am "$target" | |||
# Make SVN state tarball for the libburn team | |||
# TODO: will probably be obsoleted after sucessful merge | |||
tar czf "$cdrskin_tarball_svn" "$target" | |||
# Get over dependecy on autotools. Rely only on cc, make et. al. | |||
# This is not the same as "make dist" but i can do it without | |||
# having to evaluate the quality of said "make dist" | |||
# | |||
( cd "$target" ; ./bootstrap ) | |||
# Pack it up to the new libburn+cdrskin-tarball | |||
tar czf "$cdrskin_tarball" "$target" | |||
# Produce a static and a dynamic binary | |||
( | |||
cd "$compile_dir" || exit 1 | |||
./configure | |||
make | |||
$compile_cmd -do_strip | |||
cp "$compile_result" "$bintarget_dynamic" | |||
if test -n "$compile_static_opts" | |||
then | |||
$compile_cmd $compile_static_opts -do_strip | |||
cp "$compile_result" "$bintarget_static" | |||
fi | |||
) | |||
# Disable this for debugging the merge process | |||
rm -rf "$target" | |||
@ -0,0 +1,37 @@ | |||
#!/bin/sh | |||
# | |||
# Spying on the call to cdrecord. | |||
# | |||
# Move $(which cdrecord) to $(dirname $(which cdrecord))/real_cdrecord . | |||
# Install this sript instead. (Do not forget to revoke this after the test.) | |||
# | |||
# The report target is set in variable rt. | |||
# The default is this file : | |||
rt=/tmp/cdrecord_spy_log | |||
# To use a bystanding xterm as target i find out the pty address by | |||
# executing in that terminal | |||
# sleep 12345 | |||
# and then running in another terminal | |||
# ps -ef | grep 'sleep 12345' | |||
# which answers something like | |||
# thomas 21303 30518 0 14:02 pts/23 00:00:00 sleep 12345 | |||
# thomas 21421 30523 0 14:02 pts/24 00:00:00 grep sleep 12345 | |||
# from which i learn that pts/23 is sleeping 12345. Now sleep can be aborted. | |||
# | |||
# rt=/dev/pts/23 | |||
echo '------------------------------------- cdrecord_spy 0.1.0 -------' >>"$rt" | |||
date >>"$rt" | |||
echo '----------------------------------------------------------------' >>"$rt" | |||
echo "$0" >>"$rt" | |||
for i in "$@" | |||
do | |||
echo "$i" >>"$rt" | |||
done | |||
echo '------------------------------------- cdrecord_spy 0.1.0 - end -' >>"$rt" | |||
real_cdrecord "$@" | |||
@ -0,0 +1,144 @@ | |||
/* | |||
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net> | |||
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently. | |||
By chaining of fifo objects, several fifos can be run simultaneously | |||
in fd-to-fd mode. Modes are controlled by parameter flag of | |||
Cdrfifo_try_to_work(). | |||
Provided under GPL license within cdrskin and under BSD license elsewise. | |||
*/ | |||
#ifndef Cdrfifo_headerfile_includeD | |||
#define Cdrfifo_headerfile_includeD | |||
/** The fifo buffer which will smoothen the data stream from data provider | |||
to data consumer. Although this is not a mandatory lifesavier for modern | |||
burners any more, a fifo can speed up burning of data which is delivered | |||
with varying bandwidths (e.g. compressed archives created on the fly | |||
or mkisofs running at its speed limit.). | |||
This structure is opaque to applications and may only be used via | |||
the Cdrfifo*() methods described in cdrfifo.h . | |||
*/ | |||
struct CdrfifO; | |||
/** Create a fifo object. | |||
@param ff Returns the address of the new object. | |||
@param source_fd Filedescriptor opened to a readable data stream. | |||
@param dest_fd Filedescriptor opened to a writable data stream. | |||
To work with libburn, it needs to be attached to a | |||
struct burn_source object. | |||
@param chunk_size Size of buffer block for a single transaction (0=default) | |||
@param buffer_size Size of fifo buffer | |||
@param flag unused yet | |||
@return 1 on success, <=0 on failure | |||
*/ | |||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd, | |||
int chunk_size, int buffer_size, int flag); | |||
/** Release from memory a fifo object previously created by Cdrfifo_new(). | |||
@param ff The victim (gets returned as NULL, call can stand *ff==NULL) | |||
@param flag Bitfield for control purposes: | |||
bit0= do not close destination fd | |||
*/ | |||
int Cdrfifo_destroy(struct CdrfifO **ff, int flag); | |||
/** Close any output fds */ | |||
int Cdrfifo_close(struct CdrfifO *o, int flag); | |||
/** Close any output fds of o and its chain peers */ | |||
int Cdrfifo_close_all(struct CdrfifO *o, int flag); | |||
int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size, | |||
int flag); | |||
/** Set a speed limit for buffer output. | |||
@param o The fifo object | |||
@param bytes_per_second >0 catch up slowdowns over the whole run time | |||
<0 catch up slowdowns only over one interval | |||
=0 disable speed limit | |||
*/ | |||
int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second, | |||
int flag); | |||
int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag); | |||
int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag); | |||
/** Attach a further pair of input and output fd which will use the same | |||
fifo buffer when its predecessors are exhausted. Reading will start as | |||
soon as reading of the predecessor encounters EOF. Writing will start | |||
as soon as all pending predecessor data are written. | |||
*/ | |||
int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd, | |||
int flag); | |||
/** Attach a further fifo which shall be processed simultaneously with this | |||
one by Cdrfifo_try_to_work() in fd-to-fd mode. | |||
*/ | |||
int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag); | |||
/** Obtain buffer state. | |||
@param o The buffer object | |||
@param fill Returns the number of pending payload bytes in the buffer | |||
@param space Returns the number of unused buffer bytes | |||
@param flag unused yet | |||
@return -1=error , 0=inactive , 1=reading and writing , | |||
2=reading ended (but still writing) | |||
*/ | |||
int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag); | |||
int Cdrfifo_get_counters(struct CdrfifO *o, | |||
double *in_counter, double *out_counter, int flag); | |||
/** reads min_fill and begins measurement interval for next min_fill */ | |||
int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag); | |||
int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill, | |||
int *interval_min_fill, int flag); | |||
int Cdrfifo_get_cdr_counters(struct CdrfifO *o, | |||
double *put_counter, double *get_counter, | |||
double *empty_counter, double *full_counter, | |||
int flag); | |||
/** Check for pending data at the fifo's source file descriptor and wether the | |||
fifo is ready to take them. Simultaneously check the buffer for existing | |||
data and the destination fd for readiness to accept some. If so, a small | |||
chunk of data is transfered to and/or from the fifo. | |||
This is done for the given fifo object and all members of its next-chain. | |||
The check and transactions are repeated until a given timespan has elapsed. | |||
libburn applications call this function in the burn loop instead of sleep(). | |||
It may also be used instead of read(). Then it returns as soon as an output | |||
transaction would be performed. See flag:bit2. | |||
@param o The fifo object | |||
@param wait_usec The time in microseconds after which the function shall | |||
return. | |||
@param reply_buffer with bit2: Returns write-ready buffer chunk and must | |||
be able to take at least chunk_size bytes | |||
@param reply_count with bit2: Returns number of writeable bytes in reply_pt | |||
@param flag Bitfield for control purposes: | |||
bit0= Enable debug pacifier (same with Cdrfifo_debuG) | |||
bit1= Do not write, just fill buffer | |||
bit2= fd-to-memory mode (else fd-to-fd mode): | |||
Rather than writing a chunk return it and its size. | |||
No simultaneous processing of chained fifos. | |||
bit3= With bit2: do not check destination fd for readiness | |||
@return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done | |||
*/ | |||
int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec, | |||
char *reply_buffer, int *reply_count, int flag); | |||
/** Fill the fifo as far as possible without writing to destination fd | |||
@return 1 on success, <=0 on failure | |||
*/ | |||
int Cdrfifo_fill(struct CdrfifO *o, int flag); | |||
#endif /* Cdrfifo_headerfile_includeD */ | |||
@ -0,0 +1 @@ | |||
#define Cdrskin_timestamP "2006.08.17.171327" |
@ -0,0 +1,184 @@ | |||
/* | |||
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net> | |||
A signal handler which cleans up an application and exits. | |||
Provided under GPL license within cdrskin and under BSD license elsewise. | |||
*/ | |||
/* | |||
cc -g -o cleanup -DCleanup_standalonE cleanup.c | |||
*/ | |||
#include <sys/types.h> | |||
#include <stdlib.h> | |||
#include <unistd.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <errno.h> | |||
#include <signal.h> | |||
typedef void (*sighandler_t)(int); | |||
#include "cleanup.h" | |||
/* Signals to be caught */ | |||
static int signal_list[]= { | |||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, | |||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, | |||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, | |||
SIGTTOU, | |||
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, | |||
SIGVTALRM, SIGXCPU, SIGXFSZ, -1 | |||
}; | |||
static char *signal_name_list[]= { | |||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", | |||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", | |||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", | |||
"SIGTTOU", | |||
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", | |||
"SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" | |||
}; | |||
static int signal_list_count= 24; | |||
/* Signals not to be caught */ | |||
static int non_signal_list[]= { | |||
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1 | |||
}; | |||
static int non_signal_list_count= 4; | |||
/* run time dynamic part */ | |||
static char cleanup_msg[4096]= {""}; | |||
static int cleanup_exiting= 0; | |||
static void *cleanup_app_handle= NULL; | |||
static Cleanup_app_handler_T cleanup_app_handler= NULL; | |||
static int cleanup_perform_app_handler_first= 0; | |||
static int Cleanup_handler_exit(int exit_value, int signum, int flag) | |||
{ | |||
int ret; | |||
if(cleanup_perform_app_handler_first) | |||
if(cleanup_app_handler!=NULL) { | |||
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); | |||
if(ret==2) | |||
return(2); | |||
} | |||
if(cleanup_exiting) { | |||
if(cleanup_msg[0]!=0) | |||
fprintf(stderr,"%s\n",cleanup_msg); | |||
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n", | |||
getpid(),signum); | |||
return(0); | |||
} | |||
cleanup_exiting= 1; | |||
if(cleanup_msg[0]!=0) | |||
fprintf(stderr,"%s\n",cleanup_msg); | |||
alarm(0); | |||
if(!cleanup_perform_app_handler_first) | |||
if(cleanup_app_handler!=NULL) | |||
(*cleanup_app_handler)(cleanup_app_handle,signum,0); | |||
exit(exit_value); | |||
} | |||
static void Cleanup_handler_generic(int signum) | |||
{ | |||
int i; | |||
sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno); | |||
for(i= 0; i<signal_list_count; i++) | |||
if(signum==signal_list[i]) { | |||
sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d", | |||
signal_name_list[i],errno); | |||
break; | |||
} | |||
Cleanup_handler_exit(1,signum,0); | |||
} | |||
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag) | |||
/* | |||
bit0= set to default handlers | |||
bit1= set to ignore | |||
bit2= set cleanup_perform_app_handler_first | |||
bit3= set SIGABRT to handler (makes sense with bits 0 or 1) | |||
*/ | |||
{ | |||
int i,j,max_sig= -1,min_sig= 0x7fffffff; | |||
sighandler_t sig_handler; | |||
cleanup_msg[0]= 0; | |||
cleanup_app_handle= handle; | |||
cleanup_app_handler= handler; | |||
if(flag&4) | |||
cleanup_perform_app_handler_first= 1; | |||
if(flag&1) | |||
sig_handler= SIG_DFL; | |||
else if(flag&2) | |||
sig_handler= SIG_IGN; | |||
else | |||
sig_handler= Cleanup_handler_generic; | |||
/* set all signal numbers between the lowest and highest in the list | |||
except those in the non-signal list */ | |||
for(i= 0; i<signal_list_count; i++) { | |||
if(signal_list[i]>max_sig) | |||
max_sig= signal_list[i]; | |||
if(signal_list[i]<min_sig) | |||
min_sig= signal_list[i]; | |||
} | |||
for(i= min_sig; i<=max_sig; i++) { | |||
for(j= 0; j<non_signal_list_count; j++) | |||
if(i==non_signal_list[j]) | |||
break; | |||
if(j>=non_signal_list_count) { | |||
if(i==SIGABRT && (flag&8)) | |||
signal(i,Cleanup_handler_generic); | |||
else | |||
signal(i,sig_handler); | |||
} | |||
} | |||
return(1); | |||
} | |||
#ifdef Cleanup_standalonE | |||
struct Demo_apP { | |||
char *msg; | |||
}; | |||
int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag) | |||
{ | |||
printf("Handling exit of demo application on signal %d. msg=\"%s\"\n", | |||
signum,demoapp->msg); | |||
return(1); | |||
} | |||
main() | |||
{ | |||
struct Demo_apP demoapp; | |||
demoapp.msg= "Good Bye"; | |||
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); | |||
if(1) { /* change to 0 in order to wait for external signals */ | |||
char *cpt= NULL,c; | |||
printf("Intentionally provoking SIGSEGV ...\n"); | |||
c= *cpt; | |||
} else { | |||
printf("killme: %d\n",getpid()); | |||
sleep(3600); | |||
} | |||
Cleanup_set_handlers(NULL,NULL,1); | |||
exit(0); | |||
} | |||
#endif /* Cleanup_standalonE */ |
@ -0,0 +1,34 @@ | |||
/* | |||
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net> | |||
A signal handler which cleans up an application and exits. | |||
Provided under GPL license within cdrskin and under BSD license elsewise. | |||
*/ | |||
#ifndef Cleanup_includeD | |||
#define Cleanup_includeD 1 | |||
/** Layout of an application provided cleanup function using an application | |||
provided handle as first argument and the signal number as second | |||
argument. The third argument is a flag bit field with no defined bits yet. | |||
If the handler returns 2 then it has delegated exit() to some other | |||
instance and the Cleanup handler shall return rather than exit. | |||
*/ | |||
typedef int (*Cleanup_app_handler_T)(void *, int, int); | |||
/** Establish exiting signal handlers on (hopefully) all signals that are | |||
not ignored by default or non-catchable. | |||
@param handle Opaque object which knows how to cleanup application | |||
@param handler Function which uses handle to perform application cleanup | |||
@param flag Control Bitfield | |||
bit0= reset to default signal handling | |||
*/ | |||
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, | |||
int flag); | |||
#endif /* ! Cleanup_includeD */ | |||
@ -0,0 +1,133 @@ | |||
#!/bin/sh | |||
# compile_cdrskin.sh | |||
# Copyright 2005 - 2006 Thomas Schmitt, scdbackup@gmx.net, GPL | |||
# to be executed within ./libburn-0.2.1 resp ./cdrskin-0.1.4 | |||
debug_opts= | |||
def_opts= | |||
libvers="-DCdrskin_libburn_0_2_1" | |||
do_strip=0 | |||
static_opts= | |||
warn_opts="-Wall" | |||
fifo_source="cdrskin/cdrfifo.c" | |||
compile_cdrskin=1 | |||
compile_cdrfifo=0 | |||
for i in "$@" | |||
do | |||
if test "$i" = "-compile_cdrfifo" | |||
then | |||
compile_cdrfifo=1 | |||
elif test "$i" = "-tarball_0_2" | |||
then | |||
libvers= | |||
elif test "$i" = "-cvs_A51208" | |||
then | |||
libvers="-DCdrskin_libburn_cvs_A51208_tS" | |||
elif test "$i" = "-cvs_A60220" | |||
then | |||
libvers="-DCdrskin_libburn_cvs_A60220_tS" | |||
elif test "$i" = "-do_not_compile_cdrskin" | |||
then | |||
compile_cdrskin=0 | |||
elif test "$i" = "-do_diet" | |||
then | |||
fifo_source= | |||
def_opts="$def_opts -DCdrskin_extra_leaN" | |||
warn_opts= | |||
elif test "$i" = "-do_strip" | |||
then | |||
do_strip=1 | |||
elif test "$i" = "-g" | |||
then | |||
debug_opts="$debug_opts -g" | |||
elif test "$i" = "-O2" | |||
then | |||
debug_opts="$debug_opts -O2" | |||
elif test "$i" = "-help" -o "$i" = "--help" -o "$i" = "-h" | |||
then | |||
echo "cdrskin/compile_cdrskin.sh : to be executed within ./cdrskin-0.1.3.0.2.ts" | |||
echo "Options:" | |||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo." | |||
echo " -tarball_0_2 set macro to match libburn-0.2.ts.tar.gz" | |||
echo " -cvs_A51208 set macro to match libburn-CVS of 8 Dec 2005." | |||
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006." | |||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin." | |||
echo " -do_diet produce capability reduced lean version." | |||
echo " -do_strip apply program strip to compiled programs." | |||
echo " -g compile with cc option -g." | |||
echo " -O2 compile with cc option -O2." | |||
echo " -static compile with cc option -static." | |||
exit 0 | |||
elif test "$i" = "-static" | |||
then | |||
static_opts="-static" | |||
fi | |||
done | |||
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" | |||
echo "Version timestamp : $(sed -e 's/#define Cdrskin_timestamP "//' -e 's/"$//' cdrskin/cdrskin_timestamp.h)" | |||
echo "Build timestamp : $timestamp" | |||
if test "$compile_cdrskin" | |||
then | |||
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts" | |||
cc $warn_opts -I. $static_opts $debug_opts $libvers $def_opts \ | |||
-DCdrskin_build_timestamP='"'"$timestamp"'"' \ | |||
\ | |||
-o cdrskin/cdrskin \ | |||
\ | |||
cdrskin/cdrskin.c \ | |||
$fifo_source \ | |||
cdrskin/cleanup.c \ | |||
\ | |||
libburn/async.o \ | |||
libburn/debug.o \ | |||
libburn/drive.o \ | |||
libburn/file.o \ | |||
libburn/init.o \ | |||
libburn/options.o \ | |||
libburn/source.o \ | |||
libburn/structure.o \ | |||
\ | |||
libburn/message.o \ | |||
libburn/sg.o \ | |||
libburn/write.o \ | |||
\ | |||
libburn/mmc.o \ | |||
libburn/sbc.o \ | |||
libburn/spc.o \ | |||
libburn/util.o \ | |||
\ | |||
libburn/sector.o \ | |||
libburn/toc.o \ | |||
\ | |||
libburn/crc.o \ | |||
libburn/lec.o \ | |||
\ | |||
-lpthread | |||
fi | |||
if test "$compile_cdrfifo" = 1 | |||
then | |||
echo "compiling program cdrskin/cdrfifo.c $static_opts $debug_opts" | |||
cc $static_opts $debug_opts \ | |||
-DCdrfifo_standalonE \ | |||
-o cdrskin/cdrfifo \ | |||
cdrskin/cdrfifo.c | |||
fi | |||
if test "$do_strip" = 1 | |||
then | |||
echo "stripping result cdrskin/cdrskin" | |||
strip cdrskin/cdrskin | |||
if test "$compile_cdrfifo" = 1 | |||
then | |||
echo "stripping result cdrskin/cdrfifo" | |||
strip cdrskin/cdrfifo | |||
fi | |||
fi | |||
echo 'done.' |