10 changed files with 6005 additions and 0 deletions
@ -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.' |
Loading…
Reference in new issue