Compare commits

..

1 Commits

Author SHA1 Message Date
8c82e3c437 Tagged libburn point release 2006-11-24 01:23:21 +00:00
53 changed files with 1765 additions and 11341 deletions

View File

@ -1,5 +1,2 @@
Joe Neeman
Philippe Rouquier
Gabriel Craciunescu
George Danchev
Jean-Francois Wauthy
Philippe Rouquier

View File

@ -1,7 +1,7 @@
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-2007 Mario Danic, Thomas Schmitt
Copyright (C) 2006 Mario Danic, Thomas Schmitt
This program is free software; you can redistribute it and/or modify

View File

@ -1 +0,0 @@
nothing here now

234
INSTALL
View File

@ -1,234 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -101,9 +101,9 @@ test_structest_CPPFLAGS = -Ilibburn
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - A70312
## cdrskin construction site - ts A60816
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_3_4
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_2_6
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
##
@ -165,9 +165,6 @@ indent: $(indent_files)
nodist_pkgconfig_DATA = \
libburn-1.pc
# http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages
man_MANS = cdrskin/cdrskin.1
EXTRA_DIST = \
libburn-1.pc.in \
version.h.in \
@ -180,7 +177,6 @@ EXTRA_DIST = \
cdrskin/README \
cdrskin/cdrecord_spy.sh \
cdrskin/compile_cdrskin.sh \
cdrskin/convert_man_to_html.sh \
cdrskin/changelog.txt \
cdrskin/cdrskin_eng.html \
cdrskin/wiki_plain.txt \
@ -190,9 +186,5 @@ EXTRA_DIST = \
libburn/os-linux.h \
libburn/sg-freebsd.c \
libburn/sg-linux.c \
COPYING \
NEWS \
ChangeLog \
INSTALL \
$(man_MANS)
COPYING

1
NEWS
View File

@ -1 +0,0 @@
nothing here now

79
README
View File

@ -1,25 +1,25 @@
------------------------------------------------------------------------------
libburnia.pykix.org
libburn.pykix.org
------------------------------------------------------------------------------
This all is under GPL.
(See GPL reference, our clarification and commitment at the end of this text)
------------------------------------------------------------------------------
libburnia.pykix.org
libburn.pykix.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
Copyright (C) 2006 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
These parts are to be replaced by own code of above libburnia.pykix.org
copyright holders and then libburnia.pykix.org is to be their sole copyright.
These parts are to be replaced by own code of above libburn.pykix.org-copyright
holders and then libburn.pykix.org is to be their sole copyright.
This is done to achieve the right to issue the clarification and the
commitment as written at the end of this text.
The rights and merits of the Libburn-copyright holders Derek Foreman and
Ben Jansens will be duely respected.
This libburnia.pykix.org toplevel README (C) 2006-2007 Thomas Schmitt
This libburn.pykix.org toplevel README (C) 2006 Thomas Schmitt
------------------------------------------------------------------------------
Build and Installation
@ -27,14 +27,14 @@ This libburnia.pykix.org toplevel README (C) 2006-2007 Thomas Schmitt
Our build system is based on autotools. For preparing the build of a SVN
snapshot you will need autotools of at least version 1.7.
Check out from SVN by
svn co http://libburnia-svn.pykix.org/libburn/trunk libburn_pykix
svn co http://libburn-svn.pykix.org/libburn/trunk libburn_pykix
go into directory libburn_pykix and apply autotools by
./bootstrap
Alternatively you may unpack a release tarball for which you do not need
autotools installed.
To build a libburnia.pykix.org subproject it should be sufficient to go
To build libburn.pykix.org and its subprojects it should be sufficient to go
into its toplevel directory (here: "libburn_pykix") and execute
./configure
make
@ -43,19 +43,18 @@ To make the libraries accessible for running resp. developing applications
make install
The other half of the project, libisofs, is hosted in the libburnia SVN, too:
svn co http://libburnia-svn.pykix.org/libisofs/trunk libisofs_pykix
The other half of the project, libisofs, is hosted in the libburn SVN, too:
svn co http://libburn-svn.pykix.org/libisofs/trunk libisofs_pykix
See README file there.
------------------------------------------------------------------------------
Overview of libburnia.pykix.org
Overview of libburn.pykix.org
libburnia.pykix.org is an open-source software project for reading, mastering
and writing optical discs.
For now this means only CD media and all single layer DVD media except DVD+R.
libburn.pykix.org is an open-source software project for reading, mastering and
writing optical discs. For now this means only CD-R and CD-RW.
The project comprises of several more or less interdependent parts which
together strive to be a usable foundation for application development.
@ -67,11 +66,11 @@ we would need : login on a development machine resp. a live OS on CD or DVD,
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
volunteers for testing of realistic use cases.
We have a workable code base for burning CD and most single layer DVD.
The burn API is quite comprehensively documented and can be used to build a
presentable application.
We have a functional binary which emulates parts of cdrecord in order to
prove that usability, and in order to allow you to explore libburnia's scope
We do have a workable code base for burning data CDs, though. The burn API is
quite comprehensively documented and can be used to build a presentable
application.
We do have a functional binary which emulates parts of cdrecord in order to
prove that usability, and in order to allow you to explore libburn's scope
by help of existing cdrecord frontends.
The project components (list subject to growth, hopefully):
@ -79,25 +78,20 @@ The project components (list subject to growth, hopefully):
- libburn is the library by which preformatted data get onto optical media.
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
/dev/hdX (e.g. on kernel 2.6).
libburn is the foundation of our cdrecord emulation. Its code is
independent of cdrecord. Its DVD capabilities are learned from
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
libburn is the foundation of our cdrecord emulation.
- libisofs is the library to pack up hard disk files and directories into a
ISO 9660 disk image. This may then be brought to media via libburn.
ISO 9660 disk image. This may then be brought to CD via libburn.
libisofs is to be the foundation of our upcoming mkisofs emulation.
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
Cdrecord is a powerful GPL'ed burn program included in Joerg
Schilling's cdrtools. cdrskin strives to be a second source for
the services traditionally provided by cdrecord. Additionally it
provides libburn's DVD capabilities, where only -sao is compatible
with cdrecord.
the services traditionally provided by cdrecord.
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
runs, though.
See cdrskin/README and man cdrskin/cdrskin.1 for more.
See cdrskin/README for more.
- test is a collection of application gestures and examples given by the
authors of the library features. The main API example for libburn
@ -175,29 +169,6 @@ Project history as far as known to me:
- 13th November 2006 splitting releases of libburn+cdrskin from libisofs.
- 24th November 2006 release of libburn-0.2.6 and cdrskin-0.2.6 . cdrskin has
become suitable for unaware frontends as long as they perform only the core
of cdrecord use cases (including open-ended input streams, audio, and
multi-session).
- 28th November 2006 the umbrella project which encloses both, libisofs and
libburn, is now called libburnia. For the origin of this name, see
http://en.wikipedia.org/wiki/Liburnians .
- 16th January 2007 release of libburn-0.3.0 and cdrskin-0.3.0 . Now the scope
is widened to a first class of DVD media: overwriteable single layer types
DVD-RAM, DVD+RW, DVD-RW. This is not a cdrecord emulation but rather inspired
by dvd+rw-tools' "poor man" writing facility for this class of media.
Taking a bow towards Andy Polyakov.
- 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with
multi-session and with DAO.
- 12th March 2007 version 0.3.4 supports DVD+R and thus covers all single layer
DVD media. Code for double layer DVD+/-R is implemented but awaits a tester
yet.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
@ -216,9 +187,9 @@ Project history as far as known to me:
------------------------------------------------------------------------------
Clarification in my name and in the name of Mario Danic, upcoming copyright
holders 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:
holders on toplevel of libburn. To be fully in effect after the remaining other
copyrighted code has been replaced by ours and by copyright-free contributions
of our friends:
------------------------------------------------------------------------------
We, the copyright holders, agree on the interpretation that

View File

@ -1,5 +1,5 @@
------------------------------------------------------------------------------
libburnia.pykix.org scdbackup.sourceforge.net/cdrskin_eng.html
libburn.pykix.org scdbackup.sourceforge.net/cdrskin_eng.html
------------------------------------------------------------------------------
Installation instructions at about line 60. First the legal stuff:
------------------------------------------------------------------------------
@ -7,31 +7,31 @@ This all is under GPL.
(See GPL reference, our clarification and commitment at the end of this text)
------------------------------------------------------------------------------
Based on and sub project of:
libburnia.pykix.org
libburn.pykix.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
Copyright (C) 2006 Mario Danic, Thomas Schmitt
libburnia.pykix.org is inspired by and in other components still containing
libburn.pykix.org is inspired by and in other components 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
See toplevel README for an overview of the current copyright situation in
libburnia.pykix.org.
libburn.pykix.org.
------------------------------------------------------------------------------
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 libburnia.pykix.org but also published via:
Integrated sub project of libburn.pykix.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-0.3.4.pl00.tar.gz
Copyright (C) 2006-2007 Thomas Schmitt
http://scdbackup.sourceforge.net/cdrskin-0.2.6.pl01.tar.gz
Copyright (C) 2006 Thomas Schmitt
------------------------------------------------------------------------------
On top of libburn there is implemented cdrskin 0.3.4, a limited cdrecord
On top of libburn there is implemented cdrskin 0.2.6, 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
@ -59,16 +59,16 @@ systems, including 64 bit systems. (Further reports are welcome.)
Compilation, First Glimpse, Installation
Obtain cdrskin-0.3.4.pl00.tar.gz, take it to a directory of your choice and do:
Obtain cdrskin-0.2.6.pl01.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-0.3.4.pl00.tar.gz
cd cdrskin-0.3.4
tar xzf cdrskin-0.2.6.pl01.tar.gz
cd cdrskin-0.2.6
Or obtain a libburnia.pykix.org SVN snapshot,
Or obtain a libburn.pykix.org SVN snapshot,
go into the toplevel directory of the snapshot (e.g. cd libburn_pykix ),
and execute the autotools script ./bootstrap . Use autools version >= 1.7 .
Within that toplevel directory of either cdrskin-0.3.4 or libburn then execute:
Within that toplevel directory of either cdrskin-0.2.6 or libburn then execute:
./configure
make
@ -90,7 +90,6 @@ Version identification and help texts available afterwards:
cdrskin/cdrskin -version
cdrskin/cdrskin --help
cdrskin/cdrskin -help
man cdrskin/cdrskin.1
Install (eventually as superuser) cdrskin to a directory where it can be found:
If cdrskin was already installed by a previous version, or by "make install"
@ -109,10 +108,6 @@ 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.)
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:
cp cdrskin/cdrskin.1 /usr/share/man/man1/cdrskin.1
Usage
@ -143,52 +138,41 @@ It is not checked for the necessary degree of hacker safety.
Usage examples
For options and recordable media classes see
man 1 cdrskin
Get an overview of cdrecord style addresses of available devices
cdrskin -scanbus
cdrskin dev=ATA -scanbus
cdrskin --devices
Adresses reported with dev=ATA need prefix "ATA:". Address examples:
dev=0,1,0 dev=ATA:1,0,0 dev=/dev/sg1 dev=/dev/hdc
See also "Drive Addressing" below.
Note: Adresses reported with dev=ATA are to be used with prefix "ATA:". You may
well use device file addresses as reported with --devices. Examples:
dev=0,1,0 dev=/dev/sg1 dev=ATA:1,0,0 dev=/dev/hdc
See also "Drive Addressing".
Note: Address numbers have changed since cdrskin-0.2.2 in order to become
compatible with cdrecord numbers. To get the old number scheme, use
option --old_pseudo_scsi_adr . See also "Pseudo-SCSI Adresses".
Sorry for any inconvenience.
Obtain some info about the drive
cdrskin dev=0,1,0 -checkdrive
Obtain some info about the drive and the inserted media
cdrskin dev=0,1,0 -atip -v
cdrskin dev=0,1,0 -atip
Make used CD-RW or used unformatted DVD-RW writeable again
Thoroughly blank a CD-RW
cdrskin -v dev=0,1,0 blank=all -eject
Blank CD-RW sufficiently for making it ready for overwrite
cdrskin -v dev=0,1,0 blank=fast -eject
Format DVD-RW to avoid need for blanking before re-use
cdrskin -v dev=0,1,0 blank=format_overwrite
De-format DVD-RW to make it capable of multi-session again
cdrskin -v dev=/dev/sr0 blank=deformat_sequential
Burn image file my_image.iso to media
cdrskin -v dev=0,1,0 speed=12 fs=8m driveropts=burnfree padsize=300k \
Burn image file my_image.iso to CD
cdrskin -v dev=0,1,0 speed=12 fs=8m -sao driveropts=burnfree padsize=300k \
-eject my_image.iso
Write multi-session to the same CD , DVD-R[W] or DVD+R
cdrskin dev=/dev/hdc padsize=300k -multi 1.iso
cdrskin dev=/dev/hdc padsize=300k -multi -tao 2.iso
cdrskin dev=/dev/hdc padsize=300k -multi -tao 3.iso
cdrskin dev=/dev/hdc padsize=300k -tao 4.iso
Get multi-session info for option -C of program mkisofs:
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
mkisofs ... -C "$c_values" ...
Burn a compressed afio archive to media on-the-fly
Burn a compressed afio archive to CD on-the-fly
find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 -tao \
driveropts=burnfree padsize=300k -
Burn 6 audio tracks from files with different formats to CD (not to any DVD).
Burn 6 audio tracks from files with different formats to CD.
Anything except .wav or .au files has to be converted into raw format first.
See below "Audio CD" for specifications.
ogg123 -d raw -f track01.cd /path/to/track1.ogg
@ -223,11 +207,10 @@ Run a backup :
Restrictions
Many cdrecord options are still unsupported.
If you have use cases for them, please report your wishes and expectations.
The major restrictions are lifted now: audio, TAO, multi-session do work.
Many cdrecord options are still unsupported, though.
DVD support is restricted to single layer DVD for now. Double layer media
are implemented but untested.
If you have use cases for them, please report your wishes and expectations.
@ -242,11 +225,10 @@ Do not bother Joerg Schilling with any cdrskin problems.
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.
I have the hope that Joerg feels more flattered than annoyed by cdrskin.
Many thanks to Andy Polyakov for his dvd+rw-tools
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
which provide me with examples and pointers into MMC specs for DVD writing.
Actually i, Thomas Schmitt, am a devoted user of cdrecord via my project
scdbackup which still runs a bit better with cdrecord than with cdrskin. TAO.
I have the hope that Joerg feels more flattered than annoyed by cdrskin.
Drive Addressing
@ -343,7 +325,6 @@ If not --no_rc is the first argument then cdrskin attempts on startup to read
arguments from the following three files:
/etc/default/cdrskin
/etc/opt/cdrskin/rc
/etc/cdrskin/cdrskin.conf
$HOME/.cdrskinrc
The files are read in the sequence given above.
Each readable line is treated as one single argument. No extra blanks.
@ -356,7 +337,7 @@ dev=0,1,0
dev_translation=+1,0,0+0,1,0
# Some more options
fifo_start_at=0
--fifo_start_empty
fs=16m
@ -386,97 +367,6 @@ I myself am not into audio. So libburn-hackers@pykix.org might be the
best address for suggestions, requests and bug reports.
DVD+RW and DVD-RAM
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
hold data or not. Options -audio and -multi are not allowed. Only one track
is allowed. -toc does not return information about the media content.
Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second). Currently
there is no difference between -sao and -tao. If ever, then -tao will be the
mode which preserves the current behavior.
For these media, -msinfo alone would not be enough to perform appending of an
ISO filesystem. The filesystem driver will need a hint to find the start of the
most recent session. For example put an ISO filesystem at address 1 GB:
mkisofs -C 0,524288 ... | \
cdrskin dev=/dev/sr0 -v fs=32m -eject speed=4 write_start_address=524288s -
The superuser may then do:
mount -t iso9660 -o ro,sbsector=524288 /dev/sr0 /mnt
Note: On my linux-2.4.21-215 mount works only with sbsector <= 337920 (660 MB).
To extend a filesystem already existing at address 0
mkisofs -C 0,524288 -M /dev/sr0 ... | cdrskin dev=/dev/sr0 ...
Record the number 524288 for usage as first number with -C at the next
extension:
mkisofs -C 524288,1000000 ... | cdrskin write_start_address=1000000s ...
Program growisofs can append to an ISO filesystem on DVD+RW by additionally
manipulating the first session. cdrskin does not want to get involved so deep
into the format of the burned data. Be advised to use growisofs for the
task of maintaining extendable ISO-Filesystems on DVD+RW.
DVD-RW and DVD-R
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
"Sequential Recording". DVD-R are always in sequential state.
"Sequential" is the state of unused media and of media previously blanked
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
The according cdrskin option is blank=deformat_sequential .
If "Incremental Streaming" is available, then sequential media are capable
of multi-session like CD-R[W]. (But not capable of -audio recording.)
This means they need option -multi to stay appendable, need to be blanked
to be writeable from start, return useable info with -toc and -msinfo,
eventually perform appending automatically.
Without "Incremental Streaming" offered by the drive, only write mode DAO is
available with sequential DVD-R[W]. It only works with blank media, allows only
one single track, no -multi, and demands a fixely predicted track size.
(growisofs uses it with DVD-R[W] if option -dvd-compat is given.)
Overwriteable DVD-RW behave much like DVD+RW. "Restricted" refers only to the
granularity of random access and block size which have always to be aligned to
full 32 kB. Sequential DVD-RW are converted into overwriteable DVD-RW by
cdrskin dev=... -v blank=format_overwrite
(Command dvd+rw-format -force can achieve "Restricted Overwrite", too.)
Formatting or first use of freshly formatted DVD-RW can produce unusual noises
from the drive and last several minutes. Depending on mutual compatibility of
drive and media, formatting can yield unusable media. It seems that those die
too on blanking by cdrecord, dvd+rw-format or cdrskin. Perils of DVD-RW.
There are three DVD-RW formatting variants with cdrskin currently:
blank=format_overwrite uses "DVD-RW Quick" formatting (MMC-type 15h)
and writes a first session of 128 MB. This leads to media which are expandable
and random addressable by cdrskin.
blank=format_overwrite_quickest uses "DVD-RW Quick" formatting (type 15h) too,
but leaves the media in "intermediate" state. In the first session of writing
one may only write sequentially to such a DVD. After that, it gets random
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
blank=format_overwrite_full uses preferrably "Full Format" (type 00h).
This formatting lasts as long as writing a full DVD. It includes writing of
lead-out which is said to be good for DVD ROM compatibility.
De-formatting options are available to make overwriteable DVD-RW sequential:
blank=deformat_sequential performs thorough blanking of all states of DVD-RW.
blank=all and blank=fast perform the same thorough blanking, but refuse to do
this with overwriteable DVD-RW, thus preserving their formatting. The specs
allow minimal blanking but the resulting media on my drives offer no
Incremental Streaming afterwards. So blank=fast will do full blanking.
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
DVD+R
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
into an own session, though.
------------------------------------------------------------------------------
Special compilation variations
You may get a (super fat) statically linked binary by :

View File

@ -20,28 +20,27 @@ set -x
# The script is to be run in the directory above the toplevel
# directory of libburn resp. cdrskin development.
#
# The top level directory in the SVN snapshot is named
intermediate="./libburn_pykix"
# libburn source used: http://libburnia.pykix.org
# libburn version used: http://libburn.pykix.org
# Downloaded by:
# $ svn co http://libburnia-svn.pykix.org/libburn/tags/... $intermediate
# $ svn co http://libburn-svn.pykix.org/trunk libburn_pykix
# packed up in a tarball just to save it from inadverted changes by
# $ tar czf libburn_svn.tgz $intermediate
# $ tar czf libburn_svn.tgz libburn_pykix
original="./libburn_svn.tgz"
# Historic moments:
# original="./libburn_svn_A60815.tgz"
# original="./libburn_cdrskin_A60819.tgz"
# The top level directory in that snapshot is named
intermediate="./libburn_pykix"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin
skin_release="0.3.5"
patch_level=""
changes="./libburn-0.2.3.ts.develop"
skin_release="0.2.6"
patch_level=".pl01"
skin_rev="$skin_release""$patch_level"
# The result directory and the name of the result tarballs
target="./cdrskin-${skin_release}"
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
@ -55,9 +54,6 @@ compile_cmd="./cdrskin/compile_cdrskin.sh"
compile_static_opts="-static"
compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
bintarget_static="$bintarget_dynamic"-static
@ -126,8 +122,6 @@ do
rm "$cdrskin_target"/cdrskin_"$i"
fi
done
# Remove eventual SVN stuff from cdrskin directory
for i in .deps .dirstamp .libs
do
if test -e "$cdrskin_target"/"$i"
@ -136,23 +130,6 @@ do
fi
done
# Remove GIFs of cdrskin_eng.html
rm "$cdrskin_target"/doener_*.gif
# Remove automatically generated HTML man page
rm "$cdrskin_target"/man_1_cdrskin.html
# Remove all add_ts_changes_to_libburn besides this one
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
do
if test $(basename "$0") = $(basename "$i")
then
dummy=dummy
else
rm $i
fi
done
# Remove unwanted SVN stuff (TODO: avoid downloading it)
for i in "$target"/.svn "$target"/*/.svn
do
@ -167,6 +144,12 @@ do
fi
done
## No more : Add own libburn-README in toplevel
# cp -a "$changes"/README "$target"
## No more : Add modified Makefile.am
# cp -a "$changes"/Makefile.am "$target"
# Make SVN state tarball for the libburn team
tar czf "$cdrskin_tarball_svn" "$target"
@ -196,20 +179,18 @@ done
# Pack it up to the new libburn+cdrskin-tarball
tar czf "$cdrskin_tarball" "$target"
# Produce a static and a dynamic binary, and a HTML man page
# Produce a static and a dynamic binary
(
cd "$compile_dir" || exit 1
./configure
make
"$compile_cmd" -O2 -do_strip
$compile_cmd -do_strip
cp "$compile_result" "../$bintarget_dynamic"
if test -n "$compile_static_opts"
then
"$compile_cmd" $compile_static_opts -O2 -do_strip
$compile_cmd $compile_static_opts -do_strip
cp "$compile_result" "../$bintarget_static"
fi
"$man_to_html_cmd"
mv "$man_page_html" ..
)
# Remove the build area
@ -222,5 +203,4 @@ rm -rf "$target"
ls -l "$cdrskin_tarball"
ls -l "$bintarget_dynamic"
ls -l "$bintarget_static"
ls -l $(basename "$man_page_html")

View File

@ -20,30 +20,26 @@ set -x
# The script is to be run in the directory above the toplevel
# directory of libburn resp. cdrskin development.
#
# The top level directory in the SVN snapshot is named
intermediate="./libburn_pykix"
# libburn source used: http://libburnia.pykix.org
# libburn version used: http://libburn.pykix.org
# Downloaded by:
# $ svn co http://libburnia-svn.pykix.org/libburn/tags/... $intermediate
# $ svn co http://libburn-svn.pykix.org/libburn/trunk libburn_pykix
# packed up in a tarball just to save it from inadverted changes by
# $ tar czf libburn_svn.tgz $intermediate
original="./libburn_svn_release.tgz"
# $ tar czf libburn_svn.tgz libburn_pykix
original="./libburn_svn.tgz"
# Historic moments:
# original="./libburn_svn_A60815.tgz"
# original="./libburn_cdrskin_A60819.tgz"
# The top level directory in that snapshot is named
intermediate="./libburn_pykix"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin
skin_release="0.3.4"
patch_level=".pl00"
skin_rev="$skin_release""$patch_level"
changes="./libburn-0.2.3.ts.develop"
skin_rev="0.2.7"
# The result directory and the name of the result tarballs
target="./cdrskin-${skin_release}"
target="./cdrskin-${skin_rev}"
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz"
@ -55,9 +51,6 @@ compile_cmd="./cdrskin/compile_cdrskin.sh"
compile_static_opts="-static"
compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
bintarget_static="$bintarget_dynamic"-static
@ -126,8 +119,6 @@ do
rm "$cdrskin_target"/cdrskin_"$i"
fi
done
# Remove eventual SVN stuff from cdrskin directory
for i in .deps .dirstamp .libs
do
if test -e "$cdrskin_target"/"$i"
@ -136,23 +127,6 @@ do
fi
done
# Remove GIFs of cdrskin_eng.html
rm "$cdrskin_target"/doener_*.gif
# Remove automatically generated HTML man page
rm "$cdrskin_target"/man_1_cdrskin.html
# Remove all add_ts_changes_to_libburn besides this one
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
do
if test $(basename "$0") = $(basename "$i")
then
dummy=dummy
else
rm $i
fi
done
# Remove unwanted SVN stuff (TODO: avoid downloading it)
for i in "$target"/.svn "$target"/*/.svn
do
@ -167,6 +141,12 @@ do
fi
done
## No more : Add own libburn-README in toplevel
# cp -a "$changes"/README "$target"
## No more : Add modified Makefile.am
# cp -a "$changes"/Makefile.am "$target"
# Make SVN state tarball for the libburn team
tar czf "$cdrskin_tarball_svn" "$target"
@ -196,20 +176,18 @@ done
# Pack it up to the new libburn+cdrskin-tarball
tar czf "$cdrskin_tarball" "$target"
# Produce a static and a dynamic binary, and a HTML man page
# Produce a static and a dynamic binary
(
cd "$compile_dir" || exit 1
./configure
make
"$compile_cmd" -O2 -do_strip
$compile_cmd -do_strip
cp "$compile_result" "../$bintarget_dynamic"
if test -n "$compile_static_opts"
then
"$compile_cmd" $compile_static_opts -O2 -do_strip
$compile_cmd $compile_static_opts -do_strip
cp "$compile_result" "../$bintarget_static"
fi
"$man_to_html_cmd"
mv "$man_page_html" ..
)
# Remove the build area
@ -222,5 +200,4 @@ rm -rf "$target"
ls -l "$cdrskin_tarball"
ls -l "$bintarget_dynamic"
ls -l "$bintarget_static"
ls -l $(basename "$man_page_html")

View File

@ -38,9 +38,7 @@
#define Cdrfifo_ffd_maX 100
/* 1= enable , 0= disable status messages to stderr
2= report each
*/
/* 1= enable , 0= disable status messages to stderr */
static int Cdrfifo_debuG= 0;
@ -84,8 +82,6 @@ struct CdrfifO {
/* index of first byte in buffer which does not belong to predecessor fd */
int follow_up_eop[Cdrfifo_ffd_maX];
/* if follow_up_eop[i]==buffer_size : read_idx was 0 when this was set */
int follow_up_was_full_buffer[Cdrfifo_ffd_maX];
/* index of first byte in buffer which belongs to [this] fd pair */
int follow_up_sod[Cdrfifo_ffd_maX];
@ -103,9 +99,6 @@ struct CdrfifO {
/* (simultaneous) peer chaining */
struct CdrfifO *next;
struct CdrfifO *prev;
/* rank in peer chain */
int chain_idx;
};
@ -162,13 +155,11 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
for(i= 0; i<Cdrfifo_ffd_maX; i++) {
o->follow_up_fds[i][0]= o->follow_up_fds[i][1]= -1;
o->follow_up_eop[i]= o->follow_up_sod[i]= -1;
o->follow_up_was_full_buffer[i]= 0;
o->follow_up_in_limits[i]= -1.0;
}
o->follow_up_fd_counter= 0;
o->follow_up_fd_idx= -1;
o->next= o->prev= NULL;
o->chain_idx= 0;
o->buffer= TSOB_FELD(char,buffer_size);
if(o->buffer==NULL)
goto failed;
@ -308,16 +299,10 @@ int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd,
*/
int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag)
{
int idx;
struct CdrfifO *s;
for(s= o;s->prev!=NULL;s= s->prev); /* determine start of o-chain */
for(;o->next!=NULL;o= o->next); /* determine end of o-chain */
for(;next->prev!=NULL;next= next->prev); /* determine start of next-chain */
next->prev= o;
o->next= next;
for(idx= 0;s!=NULL;s= s->next)
s->chain_idx= idx++;
return(1);
}
@ -423,26 +408,10 @@ int Cdrfifo_eop_adjust(struct CdrfifO *o,int *buffer_fill, int *eop_idx,
for(i=0; i<=o->follow_up_fd_idx; i++) {
if(o->follow_up_eop[i]>=0 && o->follow_up_eop[i]>=o->read_idx) {
eop_is_near= 1;
if(o->follow_up_eop[i]<o->buffer_size || o->read_idx>0) {
valid_fill= o->follow_up_eop[i]-o->read_idx;
o->follow_up_was_full_buffer[i]= 0;
} else {
/*
If an input fd change hit exactly the buffer end then follow_up_eop
points to buffer_size and not to 0. So it is time to switch output
pipes unless this is immediately after follow_up_eop was set and
read_idx was 0 (... if this is possible at all while write_idx is 0).
follow_up_was_full_buffer was set in this case and gets invalid as
soon as a non-0 read_idx is detected (see above).
*/
if(o->follow_up_was_full_buffer[i])
valid_fill= o->buffer_size;
else
valid_fill= 0; /* the current pipe is completely served */
}
valid_fill= o->follow_up_eop[i]-o->read_idx;
if(valid_fill==0)
*eop_idx= i;
else if(valid_fill<o->chunk_size)
else if(valid_fill<=o->chunk_size)
eop_is_near= 2; /* for debugging. to carry a break point */
break;
}
@ -467,7 +436,7 @@ static int Cdrfifo_setup_try(struct CdrfifO *o, struct timeval start_tv,
*/
{
int buffer_space,buffer_fill,eop_reached= -1,eop_is_near= 0,was_closed;
int fd_buffer_fill, eop_reached_counter= 0;
int fd_buffer_fill;
struct timeval current_tv;
struct timezone tz;
double diff_time,diff_counter,limit,min_wait_time;
@ -496,26 +465,21 @@ setup_try:;
if(eop_reached>=0) { /* switch to next output fd */
o->dest_fd= o->follow_up_fds[eop_reached][1];
if(Cdrfifo_debuG)
fprintf(stderr,"\ncdrfifo %d: new fifo destination fd : %d\n",
o->chain_idx,o->dest_fd);
o->read_idx= o->follow_up_sod[eop_reached];
o->follow_up_eop[eop_reached]= -1;
eop_is_near= 0;
eop_reached= -1;
eop_reached_counter= 0;
goto setup_try;
} else {
/* work is really done */
if((!was_closed) && ((flag&1)||Cdrfifo_debuG))
fprintf(stderr,
"\ncdrfifo %d: w=%d r=%d | b=%d s=%d | i=%.f o=%.f (done)\n",
o->chain_idx,o->write_idx,o->read_idx,buffer_fill,buffer_space,
"\ncdrfifo_debug: w=%d r=%d | b=%d s=%d | i=%.f o=%.f (done)\n",
o->write_idx,o->read_idx,buffer_fill,buffer_space,
o->in_counter,o->out_counter);
return(2);
}
} else if(eop_reached>=0)
eop_reached_counter++;
}
if(o->interval_counter>0) {
if(o->total_min_fill>buffer_fill && o->source_fd>=0)
o->total_min_fill= buffer_fill;
@ -617,8 +581,7 @@ return: <0 = error , 0 = idle , 1 = did some work
if(ret==-1) {
/* >>> handle broken pipe */;
fprintf(stderr,"\ncdrfifo %d: on write: errno=%d , \"%s\"\n",
o->chain_idx,errno,
fprintf(stderr,"\ncdrfifo: on write: errno=%d , \"%s\"\n",errno,
errno==0?"-no error code available-":strerror(errno));
if(!(flag&4))
@ -650,31 +613,22 @@ after_write:;
if(ret==-1) {
/* >>> handle input error */;
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
o->chain_idx,errno,
fprintf(stderr,"\ncdrfifo: on read: errno=%d , \"%s\"\n",errno,
errno==0?"-no error code available-":strerror(errno));
o->source_fd= -1;
} else if(ret==0) { /* eof */
/* activate eventual follow-up source fd */
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
o->chain_idx,o->source_fd,can_read);
fprintf(stderr,"\ncdrfifo: on read(%d,buffer,%d): eof\n",
o->source_fd,can_read);
if(o->follow_up_fd_idx+1 < o->follow_up_fd_counter) {
idx= ++(o->follow_up_fd_idx);
o->source_fd= o->follow_up_fds[idx][0];
/* End-Of-Previous */
if(o->write_idx==0) {
if(o->write_idx==0)
o->follow_up_eop[idx]= o->buffer_size;
/* A70304 : can this happen ? */
o->follow_up_was_full_buffer[idx]= (o->read_idx==0);
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: write_idx 0 on eop: read_idx= %d\n",
o->chain_idx,o->read_idx);
} else
else
o->follow_up_eop[idx]= o->write_idx;
/* Start-Of-Data . Try to start at next full chunk */
sod= o->write_idx;
@ -690,8 +644,7 @@ after_write:;
o->fd_in_counter= 0;
o->fd_in_limit= o->follow_up_in_limits[idx];
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: new fifo source fd : %d\n",
o->chain_idx,o->source_fd);
fprintf(stderr,"\ncdrfio: new fifo source fd : %d\n",o->source_fd);
} else {
o->source_fd= -1;
}
@ -824,13 +777,13 @@ ex:;
} else
elapsed= wait_usec;
if(elapsed>=wait_usec) {
if((flag&1)||Cdrfifo_debuG>=2) {
if((flag&1)||Cdrfifo_debuG) {
fprintf(stderr,"\n");
for(ff= o; ff!=NULL; ff= ff->next) {
buffer_space= Cdrfifo_tell_buffer_space(ff,0);
fprintf(stderr,
"cdrfifo %d: w=%d r=%d | b=%d s=%d | i=%.f o=%.f\n",
ff->chain_idx,ff->write_idx,ff->read_idx,
"cdrfifo_debug: w=%d r=%d | b=%d s=%d | i=%.f o=%.f\n",
ff->write_idx,ff->read_idx,
ff->buffer_size-buffer_space,buffer_space,
ff->in_counter,ff->out_counter);
}
@ -922,76 +875,6 @@ double Scanf_io_size(char *text, int flag)
}
/* This is a hardcoded test mock-up for two simultaneous fifos of which the
one runs with block size 2048 and feeds the other which runs with 2352.
Both fifos have the same number of follow_up pipes (tracks) which shall
be connected 1-to-1.
*/
int Test_mixed_bs(char **paths, int path_count,
int fs_size, double speed_limit, double interval, int flag)
/*
bit0= debugging verbousity
*/
{
int fd_in[100],fd_out[100],ret,pipe_fds[100][2],real_out[100];
int i,iv,stall_counter= 0,cycle_counter= 0.0;
char buf[10240], target_path[80];
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
struct CdrfifO *ff_in= NULL, *ff_out= NULL;
if(path_count<1)
return(2);
Cdrfifo_new(&ff_in,fd_in[0],fd_out[0],2048,fs_size,0);
for(i= 0; i<path_count; i++) {
fd_in[2*i]= open(paths[i],O_RDONLY);
if(fd_in[2*i]==-1)
return(0);
if(pipe(pipe_fds[2*i])==-1)
return(-1);
fd_out[2*i]= pipe_fds[2*i][1];
if(i==0)
ret= Cdrfifo_new(&ff_in,fd_in[2*i],fd_out[2*i],2048,fs_size,0);
else
ret= Cdrfifo_attach_follow_up_fds(ff_in,fd_in[2*i],fd_out[2*i],0);
if(ret<=0)
return(ret);
fd_in[2*i+1]= pipe_fds[2*i][0];
sprintf(target_path,"/dvdbuffer/fifo_mixed_bs_test_%d",i);
fd_out[2*i+1]= open(target_path,O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if(i==0)
ret= Cdrfifo_new(&ff_out,fd_in[2*i+1],fd_out[2*i+1],2352,fs_size,0);
else
ret= Cdrfifo_attach_follow_up_fds(ff_out,fd_in[2*i+1],fd_out[2*i+1],0);
if(ret<=0)
return(ret);
fprintf(stderr,"test_mixed_bs: %d : %2d fifo %2d pipe %2d fifo %2d : %s\n",
i, fd_in[2*i],fd_out[2*i],fd_in[2*i+1],fd_out[2*i+1], target_path);
}
Cdrfifo_attach_peer(ff_in,ff_out,0);
/* Let the fifos work */
iv= interval*1e6;
while(1) {
ret= Cdrfifo_try_to_work(ff_in,iv,NULL,NULL,flag&1);
if(ret<0 || ret==2) { /* <0 = error , 2 = work is done */
fprintf(stderr,"\ncdrfifo %d: fifo ended work with ret=%d\n",
ff_in->chain_idx,ret);
if(ret<0)
return(-7);
break;
}
cycle_counter++;
Cdrfifo_get_counters(ff_in, &in_counter, &out_counter, 0);
if(prev_in == in_counter && prev_out == out_counter)
stall_counter++;
prev_in= in_counter;
prev_out= out_counter;
}
return(1);
}
/* This is a hardcoded test mock-up for two simultaneous fifos of which the
first one simulates the cdrskin fifo feeding libburn and the second one
simulates libburn and the burner at given speed. Both have two fd pairs
@ -1050,8 +933,7 @@ int Test_multi(int fs_size, double speed_limit, double interval, int flag)
while(1) {
ret= Cdrfifo_try_to_work(ff1,iv,NULL,NULL,flag&1);
if(ret<0 || ret==2) { /* <0 = error , 2 = work is done */
fprintf(stderr,"\ncdrfifo %d: fifo ended work with ret=%d\n",
ff1->chain_idx,ret);
fprintf(stderr,"\ncdrfifo: fifo ended work with ret=%d\n",ret);
if(ret<0)
return(-7);
break;
@ -1110,13 +992,6 @@ int main(int argc, char **argv)
} else if(strncmp(argv[i],"vb=",3)==0) {
sscanf(argv[i]+3,"%d",&verbous);
} else if(strcmp(argv[i],"-mixed_bs_test")==0) {
ret= Test_mixed_bs(argv+i+1,argc-i-1,
(int) fs_value,speed_limit,interval,(verbous>=2));
fprintf(stderr,"Test_mixed_bs(): ret= %d\n",ret);
exit(ret<0);
} else if(strcmp(argv[i],"-multi_test")==0) {
if(speed_limit==0.0)
@ -1160,7 +1035,7 @@ int main(int argc, char **argv)
if(speed_limit!=0.0)
Cdrfifo_set_speed_limit(ff,speed_limit,0);
if(fill_buffer) {
ret= Cdrfifo_fill(ff,0,0);
ret= Cdrfifo_fill(ff,0);
if(ret<=0) {
fprintf(stderr,
"cdrfifo: FATAL : initial filling of fifo buffer failed\n");

View File

@ -1,925 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.\" 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 "March 6, 2007"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
cdrskin \- burns preformatted data to CD-R[W], DVD-R[W], DVD+R[W], DVD-RAM
via libburn.
.SH SYNOPSIS
.B cdrskin
.RI [ options | track_source_addresses ]
.br
.SH DESCRIPTION
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
.\" respectively.
.PP
\fBcdrskin\fP is a program that provides some of cdrecord's options
in a compatible way for CD media. With DVD it has its own ways.
You do not need to be superuser for its daily usage.
.PP
.B Overview of features:
.br
Blanking of CD-RW and DVD-RW.
.br
Burning of data or audio tracks to CD,
.br
either in versatile Track at Once mode (TAO)
.br
or in Session at Once mode for seamless tracks.
.br
Multi session on CD (follow-up sessions in TAO only)
.br
or on DVD-R[W] (in Incremental mode) or on DVD+R.
.br
Single session on DVD-RW or DVD-R (Disk-at-once)
.br
or on overwriteable DVD+RW, DVD-RW, DVD-RAM.
.br
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
.br
See section EXAMPLES at the end of this text.
.PP
.B General information paragraphs:
.br
Track recording model
.br
Write mode selection
.br
Recordable CD Media
.br
Sequentially Recordable DVD Media
.br
Overwriteable DVD Media
.br
Drive preparation and addressing
.PP
.B Track recording model:
.br
The input-output entities which get processed are called tracks.
A \fBtrack\fP stores a stream of bytes.
.br
Each track is initiated by one track source address argument, which may either
be "-" for standard input or the address of a readable file. If no write mode
is given explicitely then one will be chosen which matches the peculiarities
of track sources and the state of the output media.
.PP
More than one track can be burned by a single run of cdrskin.
In the terms of the MMC standard all tracks written by the same run constitute
a \fBsession\fP.
.br
Some media types can be kept appendable so that further tracks can
be written to them in subsequent runs of cdrskin (see option -multi).
Info about the addresses of burned tracks is kept in a table of
content (TOC) on media and can be retrieved via cdrskin option -toc.
These informations are also used by the operating systems' CD-ROM read drivers.
.PP
In general there are two types of tracks: data and audio. They differ in
sector size, throughput and readability via the systems' CD-ROM drivers
resp. by music CD players. With DVD there is only type data.
.br
If not explicitely option -audio is given, then any track is burned as type
data, unless the track source is a file with suffix ".wav" or ".au" and has a
header part which identifies it as MS-WAVE resp. SUN Audio with suitable
parameters. Such files are burned as audio tracks by default.
.PP
While audio tracks just contain a given time span of acoustic vibrations,
data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems
are established as a format which can represent a tree of directories and
files on all major operating systems. Such filesystem images can be
produced by programs mkisofs or genisoimage. They can also be extended by
follow-up tracks if prepared properly. See the man pages of said programs.
cdrskin is able to fulfill the needs about their option -C.
.br
Another type of data track content are archive formats which originally
have been developed for magnetic tapes. Only formats which mark a detectable
end-of-archive in their data are suitable, though. Well tested are
the archivers afio and star. Not suitable seems GNU tar.
.PP
.B Write mode selection:
.br
If none of the options -dao, -tao or -sao is given then the program will
try to choose a write mode which matches the defined recording job,
the capabilities of the drive and the state of the present media.
.br
So the mentioning of write modes in the following paragraphs and in the
examples is not so much a demand that the user shall choose one explicitely,
but rather an illustration of what to expect with particular media types.
.PP
.B Recordable CD Media:
.br
CD-R can be initially written only once and eventually extended until they
get closed (or are spoiled because they are overly full). After that they are
read-only. Closing is done automatically unless option
.B -multi
is given which keeps the media appendable.
.br
There are two write modes,
.B -tao
and
.B -sao .
.br
-tao allows to use track source of unpredictable length (like stdin) and allows
to write further sessions to appendable media. -sao produces audio sessions
with seamless tracks but needs predicted track sizes and cannot append sessions
to media.
.br
CD-RW media can be blanked to make them re-usable for another
round of overwriting. Usually
.B blank=fast
is the appropriate option.
Blanking damages the previous content but does not
make it completely unreadable. It is no effective privacy precaution.
Multiple cycles of blanking and overwriting with random numbers might be.
.PP
.B Sequentially Recordable DVD Media:
.br
Currently DVD-RW, DVD-R and DVD+R can be used for the Sequential recording
model.
.br
DVD-RW must be in state "Sequential Recording".
The media must be either blank or appendable.
Newly purchased DVD-RW and DVD-R media are in this state.
Used DVD-RW get into blank sequential state by option
.B blank=deformat_sequential .
.br
With DVD-R[W] two write modes may be available:
.br
Mode DAO has many restrictions. It does not work with
appendable media, allows no -multi and only a single track. The size of the
track needs to be known in advance. So either its source has to be a disk file
of recognizable size or the size has to be announced explicitely by options
.B tsize=
or
.B tao_to_sao_tsize= .
.br
DAO is the only mode for media which do not offer feature 21h Incremental
Streaming. DAO may also be selected explicitely by option
.B -sao .
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
DVD-ROM/-Video compatibility.
.br
The other mode, Incremental Streaming, is the default write mode if
it is available and if the restrictions of DAO would prevent the job.
Incremental Streaming may be selected explicitely by option
.B -tao
as it resembles much CD TAO by allowing track sources of
unpredicted length and to keep media appendable by option
.B -multi .
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
Multiple tracks per session are permissible.
.br
The write modes for DVD+R resemble those with DVD-R except that with DVD+R
each track gets wrapped in an own session. There is no -dummy writing with
DVD+R.
.br
Quite deliberately write mode -sao insists in the tradition of a predicted
track size and blank media, whereas -tao writes the tracks open ended and
allows appendable media.
.br
Currently DVD+R are always kept appendable regardless wether -multi is given
or not. This might change in future so it is strongly advised to already now
use
.B -multi
whenever the disc shall be kept appendable.
.PP
.B Overwriteable DVD Media:
.br
Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
.br
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
hold data or not. They need no special initial formatting.
Options -audio and -multi are not allowed. Only one track is allowed.
-toc does not return information about the media content.
Currently there is no difference between -sao and -tao. If ever, then -tao
will be the mode which preserves the current behavior.
.br
DVD-RW are sold in state "Sequential Recording". To become suitable for the
Overwriteable DVD recording model they need to get formatted to state
"Restricted Overwrite". Then they behave much like DVD+RW. This formatting
can be done by option
.B blank=format_overwrite .
.br
Several programs like dvd+rw-format, cdrecord, wodim, or cdrskin
can bring a DVD-RW out of overwriteable state so
that it has to be formatted again. If in doubt, just give it a try.
.PP
.B Drive preparation and addressing:
.br
The drives, either CD burners or DVD burners, are accessed via addresses which
are specific to libburn and the operating system. Those addresses get listed
by a run of \fBcdrskin --devices\fP.
.br
On Linux, they are device files which traditionally do not offer
w-permissions for normal users. Because libburn needs rw-permission,
it might be only the
.B superuser
who is able to get this list without further
precautions.
.br
It is consensus that \fBchmod a+rw /dev/sg0\fP or \fBchmod a+rw /dev/hdc\fP
is less security sensitive than chmod u+s /usr/bin/cdrskin. The risk for the
drive is somewhat higher but the overall system is much less at stake.
.br
.PP
If you only got one CD capable drive then you may leave out cdrskin option
\fBdev=\fP. Else you should use this option to address the drive you want.
.br
cdrskin option dev= not only accepts the listed addresses but also
traditional cdrecord SCSI addresses which on Linux consist of three
numbers: Bus,Target,Lun. There is also a related address family "ATA" which
accesses IDE drives not under control of Linux SCSI drivers:
ATA:Bus,Target,Lun.
.br
See option -scanbus for getting a list of cdrecord style addresses.
.br
Further are accepted on Linux: links to libburn-suitable device files,
device files which have the same major and minor device number,
and device files which have the same SCSI address parameters (e.g. /dev/sr0).
.br
.SH OPTIONS
.TP
.BI \-\-help
Show non-cdrecord compatible options.
.TP
.BI \-help
Show cdrecord compatible options.
.TP
.BI \-version
Print cdrskin id line, compatibility lure line, libburn version, cdrskin
version, version timestamp, build timestamp (if available), and then exit.
.PP
Alphabetical list of options which are intended to be compatible with
original cdrecord by Joerg Schilling:
.TP
.BI \-atip
Retrieve some info about media state. With CD-RW print "Is erasable".
With DVD media print "book type:" and a media type text.
.TP
.BI \-audio
Announces that the subsequent tracks are to be burned as audio.
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
stereo. For little-endian byte order (which is usual on PCs) use option
-swab. Unless marked explicitely by option -data, input files with suffix
.wav are examined wether they have a header in MS-WAVE format confirming
those parameters and eventually raw audio data get extracted and burned as
audio track. Same is done for suffix .au and SUN Audio.
.br
Option -audio may be used only with CD media and not with DVD.
.TP
.BI blank= type
Blank a CD-RW, a DVD-RW, or format a DVD+/-RW.
This is combinable with burning in the same run of cdrskin.
The type given with blank= selects the particular behavior:
.RS
.TP
help
Print this list of blanking types.
.TP
all
Blank an entire CD-RW or an unformatted DVD-RW.
(See also --prodvd_cli_compatible)
.TP
fast
Minimally blank an entire CD-RW or blank an unformatted DVD-RW.
(See also --prodvd_cli_compatible)
.TP
format_overwrite
Format a DVD-RW to "Restricted Overwrite". The user should bring some patience.
.br
(Note: blank=format_overwrite* are not original cdrecord options.)
.TP
format_overwrite_quickest
Like format_overwrite without creating a 128 MB trailblazer session.
Leads to "intermediate" state which only allows sequential write
beginning from address 0.
The "intermediate" state ends after the first session of writing data.
.TP
format_overwrite_full
For DVD-RW this is like format_overwrite but claims full media size
rather than just 128 MB.
Most traditional formatting is attempted. No data get written.
Much patience is required.
.br
This option treats already formatted media even if not option -force is given.
.br
For DVD+RW this is the only supported explicit formatting type. It provides
complete "de-icing" so no reader slips on unwritten data areas.
.TP
deformat_sequential
Like blank=all but with the additional ability to blank overwriteable DVD-RW.
This will destroy their formatting and make them sequentially recordable.
Another peculiarity is the ability to blank media which appear already blank.
This is similar to option -force but does not try to blank media other than
recognizable CD-RW and DVD-RW.
.br
(Note: blank=deformat_sequential* are not original cdrecord options.)
.TP
deformat_sequential_quickest
Like blank=deformat_sequential but blanking DVD-RW only minimally.
This is faster than full blanking but may yield media incapable of
Incremental Streaming (-tao).
.RE
.TP
.BI \-checkdrive
Retrieve some info about the addressed drive.
Exits with non-zero value if the drive cannot be found and opened.
.TP
.BI \-dao
Alias for option -sao. Write CD in Session at Once mode
or DVD-R[W] in Disc-at-once mode.
.TP
.BI \-data
Subsequent tracks are data tracks. This option is default and only needed
to mark the end of the range of an eventual option -audio.
.TP
.BI dev= target
Set the address of the drive to use. Valid are at least the
addresses listed with option --devices,
X,Y,Z addresses listed with option -scanbus,
ATA:X,Y,Z addresses listed with options dev=ATA -scanbus,
and volatile libburn drive numbers (numbering starts at "0").
Other device file addresses which lead to the same drive might work too.
.br
If no dev= is given, volatile address "dev=0" is assumed. That is the first
drive found being available. Better avoid this ambiguity on systems with more
than one drive.
.br
The special target "help" lists hints about available addressing formats.
Be aware that deprecated option --old_pseudo_scsi_adr may change the meaning
of Bus,Target,Lun addresses.
.TP
.BI driveropts= opt
Set "driveropts=noburnfree" to disable the drive's eventual protection
mechanism against temporary lack of source data (i.e. buffer underrun).
A drive that announces no such capabilities will not get them enabled anyway,
even if attempted explicitely via "driveropts=burnfree".
.TP
.BI \-dummy
Try to perform the drive operations without actually affecting the inserted
media. There is no guarantee that this will work with a particular combination
of drive, media, and write mode. Blanking is prevented reliably, though.
.TP
.BI \-eject
Eject the disc after work is done.
.TP
.BI \-force
Assume that the user knows better in situations when cdrskin or libburn are
insecure about drive or media state. This includes the attempt to blank
media which are classified as unknown or unsuitable, and the attempt to use
write modes which libburn believes they are not supported by the drive.
.br
Another application is to enforce blanking or re-formatting of media
which appear to be in the desired blank or format state already.
.br
.B Caution:
Use this only when in urgent need.
.TP
.BI fs= size
Set the fifo size to the given value. The value may have appended letters which
multiply the preceding number:
.br
"k" or "K" = 1024 , "m" or "M" = 1024k , "g" or "G" = 1024m , "s" or "S" = 2048
.br
Set size to 0 in order to disable the fifo (default is "4m").
.br
The fifo buffers an eventual temporary surplus of track source data in order to
provide the drive with a steady stream during times of temporary lack of track
source supply.
The larger the fifo, the longer periods of poor source supply can be
compensated.
But a large fifo needs substantial time to fill up if not curbed via
option fifo_start_at=size.
.TP
.BI gracetime= seconds
Set the grace time before starting to write. (Default is 0)
.TP
.BI msifile= path
Run option -msinfo and copy the result line into the file given by path.
Unlike -msinfo this option does not redirect all normal output away from
standard output. But it may be combined with -msinfo to achieve this.
.br
Note: msifile=path is actually an option of wodim and not of cdrecord.
.TP
.BI \-msinfo
Retrieve multi-session info for preparing a follow-up session by option -C
of programs mkisofs or genisoimage. Print result to standard output.
This option redirects to stderr all message output except the one of option
--tell_media_space and its own result string, which consists of two numbers.
The result string shall be used as argument of option -C with said programs.
It gives the start address of the most recent session and the predicted
start address of the next session to be appended. The string is empty if
the most recent session was not written with option -multi.
.TP
.BI \-multi
This option keeps the CD or unformatted DVD-R[W] appendable after the current
session has been written.
Without it the disc gets closed and may not be written any more - unless it
is a -RW and gets blanked which causes loss of its content.
.br
The following sessions can only be written in -tao mode. -multi is prohibited
with overwriteable DVD media and with DVD-R[W] DAO write mode.
Option --prodvd_cli_compatible eventually makes -multi tolerable but cannot
make it work.
.br
In order to have all filesystem content accessible, the eventual ISO-9660
filesystem of a follow-up
session needs to be prepared in a special way by the filesystem formatter
program. mkisofs and genisoimage expect particular info about the situation
which can be retrieved by cdrskin option -msinfo.
.br
To retrieve an archive file which was written as follow-up session,
you may use option -toc to learn about the "lba" of the desired track number.
.TP
.BI \-nopad
Do not add trailing zeros to the data stream. Nevertheless, since there seems
to be no use for audio tracks with incomplete last sector, this option applies
only to data tracks. There it is default.
.TP
.BI \-pad
Add 30 kB of trailing zeros to each data track. (This is not sufficient to
avoid problems with various CD-ROM read drivers.)
.TP
.BI padsize= size
Add the given amount of trailing zeros to the next data track. This option
gets reset to padsize=0 after that next track is written. It may be set
again before the next track argument. About size specifiers, see option fs=.
.TP
.BI \-raw96r
Write CD in RAW/RAW96R mode. This mode allows to put more payload bytes
into a CD sector but obviously at the cost of error correction. It can only
be used for tracks of fixely predicted size. Some drives allow this mode but
then behave strange or even go bad for the next few attempts to burn a CD.
One should use it only if inavoidable.
.TP
.BI \-sao
Write CD in Session At Once mode, a sequential DVD-R[W] in Disc-at-once
(DAO) mode, or a DVD+R.
.br
With CD this mode is able to put several audio tracks on media without
producing audible gaps between them.
.br
With DVD-R[W] this mode can only write a single track.
No -multi is allowed with DVD-R[W] -sao.
.br
-sao is permissible with overwriteable DVD and with DVD+R but actually only
imposes restrictions without providing known advantages.
.br
-sao can only be used for tracks of fixely predicted size. This implies that
track arguments which depict stdin or named pipes need to be preceeded by
option tsize= or by option tao_to_sao_tsize=.
.br
-sao cannot be used on appendable media.
.TP
.BI \-scanbus
Scan the system for drives. On Linux the drives at /dev/s* and at /dev/hd*
are to be scanned by two separate runs. One without dev= for /dev/s* and
one with dev=ATA for /dev/hd* devices. (Option --drives lists all available
drives in a single run.)
.br
Drives which are busy or which offer no rw-permission to the user of cdrskin
are not listed. Busy drives get reported in form of warning messages.
.br
The useful fields in a result line are:
.br
Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
.TP
.BI speed= number
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
It is not an error to set a speed higher than is suitable for drive
and media. One should stay within a realistic speed range, though.
.TP
.BI \-swab
Announce that the raw audio data source of subsequent tracks is byte swapped
versus the expectations of cdrecord. This option is suitable for audio where
the least significant byte of a 16 bit word is first (little-endian, Intel).
Most raw audio data on PC systems are available in this byte order.
Less guesswork is needed if track sources are in format MS-WAVE in a file with
suffix ".wav".
.TP
.BI \-tao
Write CD in Track At Once (TAO) mode, sequential DVD-R[W] in Incremental
Streaming mode, or DVD+R without traditional -sao restrictions.
This mode also applies pro-forma to overwriteable DVD media.
.br
Mode -tao can be used with track sources of unpredictable size, like standard
input or named pipes. It is also the only mode that can be used for writing
to appendable media which already hold data. With unformatted DVD-R[W] it is
the only mode which allows -multi.
.TP
.BI \-toc
Print the table of content (TOC) which describes the tracks recorded on disc.
The output contains all info from option -atip plus lines which begin with
"track:", the track number, the word "lba:" and a number which gives the
start address of the track. Addresses are counted in CD sectors which with
SAO or TAO data tracks hold 2048 bytes each.
.RS
.TP
Example. Retrieve an afio archive from track number 2:
.br
tracknumber=2
.br
lba=$(cdrskin dev=/dev/cdrom -toc 2>&1 | \\
.br
grep '^track:[ ]*[ 0-9][0-9]' | \\
.br
tail +"$tracknumber" | head -1 | \\
.br
awk '{ print $4}' )
.br
dd if=/dev/cdrom bs=2048 skip="$lba" | \\
.br
afio -t - | less
.RE
.TP
.BI tsize= size
Announces the exact size of the next track source. This is necessary with any
write mode other than -tao if the track source is not a regular disk file, but
e.g. "-" (standard input) or a named pipe.
About size specifiers, see option fs=.
.br
If the track source does not deliver the predicted amount of bytes, the
remainder of the track is padded with zeros. This is not considered an error.
If on the other hand the track source delivers more than the announced bytes
then the track on media gets truncated to the predicted size and cdrskin exits
with non-zero value.
.TP
.BI \-v
Increment verbose level by one. Startlevel is 0 with only few messages.
Level 1 prints progress report with long running operations and also causes
some extra lines to be put out with info retrieval options.
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.
.PP
Alphabetical list of options which are genuine to cdrskin and intended for
normal use:
.TP
.BI \--allow_setuid
Disable the loud warning about insecure discrepance between login user and
effective user which indicates application of chmod u+s to the program binary.
One should not do this chmod u+s , but it is an old cdrecord tradition.
.TP
.BI \--any_track
Allow source_addresses to begin with "-" (plus further characters) or to
contain a "=" character.
By default such arguments are seen as misspelled options. It is nevertheless
not possible to use one of the options listed with --list_ignored_options.
.TP
.BI assert_write_lba= block_number | byte_address
Abort if the write address given with this option is not the same as predicted
immediately before the write session starts. This option can ensure that a
start address which was presumed by a formatter like mkisofs -C is really used
by the drive for writing.
assert_write_lba=0 effectively demands blank media and excludes appendables.
.br
Block numbering is peculiar: If the last character of the option string is
a letter [a-zA-Z] then the usual unit scaling by "s", "k", "m", etc. applies
and the result is divided by 2048. Else the number value of the string is
taken as plain block number with block size 2048 byte.
(E.g ...=1000 or ...=1000s means block 1000, ...=1m means block
512, ...=4096b means block number 2)
.TP
.BI \--demand_a_drive
Exit with a nonzero value if no drive can be found during a bus scan.
.TP
.BI \--devices
List the device file addresses of all accessible CD drives. In order to get
listed, a drive has to offer rw-permission for the cdrskin user and it may
not be busy. The superuser should be able to see all idle drives listed and
busy drives reported as "SORRY" messages.
.br
Each available drive gets listed by a line containing the following fields:
.br
Number dev='Devicefile' rw-Permissions : 'Vendor' 'Model'
.br
Number and Devicefile can both be used with option dev=, but number is
volatile (numbering changes if drives become busy).
.TP
.BI fifo_start_at= size
Do not wait for full fifo but start burning as soon as the given number
of bytes is read. This option may be helpful to bring the average throughput
near to the maximum throughput of a drive. A large fs= and a small
fifo_start_at= combine a quick burn start and a large savings buffer to
compensate for temporary lack of source data. At the beginning of burning,
the software protection against buffer underun is as weak as the size of
fifo_start_at= . So it is best if the drive offers hardware protection which
is enabled automatically if not driveropts=noburnfree is given.
.TP
.BI \--list_ignored_options
List all ignored cdrecord options. The "-" options cannot be used as addresses
of track sources. No track source address may begin with a text equal to an
option which ends by "=". The list is ended by an empty line.
.TP
.BI \--no_rc
Only if used as first command line argument this option prevents reading and
interpretation of eventual startup files. See section FILES below.
.TP
.BI \--prodvd_cli_compatible
Activates behavior modifications with some DVD situations which bring cdrskin
nearer to the behavior of cdrecord-ProDVD:
.br
Option -multi with unsuitable media is not an error but simply has no effect.
.br
Options blank=fast and blank=all deformat overwriteable DVD-RW media.
.br
Option blank=fast does indeed minmal blanking with DVD-RW. This may yield media
which can only do DAO but not Incremental Streaming.
.TP
.BI \--single_track
Accept only the last argument of the command line as track source address.
.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
exact track size prediction is demanded by the write mode.
.br
This was the fallback from bad old times when cdrskin was unable to burn
in mode -tao . It came back with minimally blanked DVD-RW which allow no
Incremental Streaming (-tao) resp. with explicitly selected write mode -sao
for best DVD-ROM compatibility.
.br
If the track source delivers less bytes than announced then the missing ones
will be filled with zeros.
.TP
.BI --tell_media_space
Prepare a recording session, do not perform it but rather inquire the
maximum number of 2048 byte data blocks which may be written in
the current state of media with the prepared setup. So this option disables
recording of data. It does allow blanking, though, and will measure space
afterwards.
.br
It is not mandatory to give track sources but their nature may influence
the available capacity. So for most realistic results one may set up
the full burn session and add --tell_media_space. But if one has to expect
a cdrskin version prior to 0.3.3 no track source should be given in order
not to start an involuntary burn session.
In this case set at least -sao or -tao explicitely.
.br
The result gets printed to standard output. It is 0 or empty if no writing
is possible with the given options.
This option redirects to stderr all message output except its own result
string and eventual output of -msinfo.
.TP
.BI write_start_address= byte_offset
Set the address on media where to start writing the track. With DVD+RW or
DVD-RAM byte_offset must be aligned to 2 KB blocks, but better is 32 kB.
With DVD-RW 32 kB alignment is mandatory.
.br
Other media are not suitable for this option yet.
.PP
Alphabetical list of options which are only intended for very special
situations and not for normal use:
.TP
.BI \--abort_handler
Establish default signal handling not to leave a drive in busy state
but rather to shut it down and to wait until it has ended the final operations.
This option is only needed for revoking eventual --ignore_signals or
--no_abort_handler.
.TP
.BI \--allow_untested_media
Enable the use of media profiles which have been implemented but not yet
tested. Currently this applies to :
.br
Profile 0015h , DVD-R/DL Sequential (will not allow -multi).
.br
Profile 002Bh , DVD+R/DL.
.br
If you really test such media, then please report the outcome on
libburn-hackers@pykix.org
.TP
.BI dev_translation= <sep><from><sep><to>
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
translate cdrecord addresses into cdrskin addresses.
.br
<sep> is a single character which may not occur in the address string
<from>. <from> is an address as expected to be given by the user via option
dev=. <to> is the address to be used instead whenever <from> is given.
More than one translation instruction can be given in one cdrskin run.
.br
E.g.: dev_translation=+ATA:1,0,0+/dev/sg1 dev_translation=+ATA:1,1,0+/dev/sg2
.TP
.BI \--drive_abort_on_busy
Linux specific: Abort process if a busy drive is encountered.
.TP
.BI \--drive_blocking
Linux specific: Try to wait for a busy drive to become free.
This is not guaranteed to work with all drivers. Some need nonblocking i/o.
.TP
.BI \--drive_not_exclusive
Linux specific: Do not ask the operating system to prevent opening busy drives.
Wether this leads to senseful behavior depends on operating system and kernel.
.TP
.BI \--drive_scsi_exclusive
Linux specific:
Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/stK of drive.
this would be helpful to protect against collisions with program growisofs.
Regrettably on Linux kernel 2.4 with ide-scsi emulation this seems not to
work. Wether it becomes helpful with new Linux systems has to be evaluated.
.TP
.BI \--fifo_disable
Disable fifo despite any fs=.
.TP
.BI \--fifo_per_track
Use a separate fifo for each track.
.TP
.BI \--fill_up_media
Expand the last track of the session to occupy all remaining free space on
the media.
.br
This option overrides option -multi. It will not fill up media if option -sao
is given with CD media.
.br
.B Caution:
This option might increase read compatibility with DVD-ROM drives but
with some DVD recorders and media types it might also fail to produce readable
media at all. "Your mileage may vary".
.TP
.BI grab_drive_and_wait= seconds
Open the addressed drive, wait the given number of seconds, release the drive,
and do normal work as indicated by the other options used. This option helps
to explore the program behavior when faced with busy drives. Just start a
second cdrskin with option --devices while grab_drive_and_wait= is still
active.
.TP
.BI \--ignore_signals
Try to ignore any signals rather than to abort the program. This is not a
very good idea. You might end up waiting a very long time for cdrskin
to finish.
.TP
.BI \--no_abort_handler
On signals exit even if the drive is in busy state. This is not a very good
idea. You might end up with a stuck drive that refuses to hand out the media.
.TP
.BI \--no_blank_appendable
Refuse to blank appendable CD-RW or DVD-RW. This is a feature that was once
builtin with libburn. No information available for what use case it was needed.
.TP
.BI \--no_convert_fs_adr
Do only literal translations of dev=. This prevents cdrskin from test-opening
device files in order to find one that matches the given dev= specifier.
.br
Partly Linux specific:
Such opening is needed for Bus,Target,Lun addresses unless option
--old_pseudo_scsi_adr is given. It is also needed to resolve device file
addresses which are not listed with cdrskin --devices but nevertheless point
to a usable drive. (Like /dev/sr0 using the same SCSI address as /dev/sg0.)
.TP
.BI \--old_pseudo_scsi_adr
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.
.br
.SH EXAMPLES
.SS
.B Get an overview of drives and their addresses:
.br
cdrskin -scanbus
.br
cdrskin dev=ATA -scanbus
.br
cdrskin --devices
.SS
.B Get info about a particular drive or loaded media:
.br
cdrskin dev=0,1,0 -checkdrive
.br
cdrskin dev=ATA:1,0,0 -v -atip
.br
cdrskin dev=/dev/hdc -toc
.SS
.B Make used CD-RW or used unformatted DVD-RW writable again:
.br
cdrskin -v dev=/dev/sg1 blank=fast -eject
.br
cdrskin -v dev=/dev/dvd blank=all -eject
.SS
.B Format DVD-RW to avoid need for blanking before re-use:
.br
cdrskin -v dev=/dev/sr0 blank=format_overwrite
.SS
.B De-format DVD-RW to make it capable of multi-session again:
.br
cdrskin -v dev=/dev/sr0 blank=deformat_sequential
.SS
.B Write ISO-9660 filesystem image as only one to blank or formatted media:
.br
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
.br
-sao -eject padsize=300k my_image.iso
.SS
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW):
.br
find . | afio -oZ - | \\
.br
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
.br
-tao padsize=300k -
.SS
.B Write multi-session to the same CD, DVD-R[W] or DVD+R:
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso
.SS
.B Get multi-session info for option -C of program mkisofs:
.br
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
.br
mkisofs ... -C "$c_values" ...
.SS
.B Inquire free space on media for a -tao -multi run:
.br
x=$(cdrskin dev=/dev/sr0 -tao -multi \\
.br
--tell_media_space 2>/dev/null)
.br
echo "Available: $x blocks of 2048 data bytes"
.SS
.B Write audio tracks to CD:
.br
cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
.br
track1.wav track2.au -audio -swab track3.raw
.br
.SH FILES
If not --no_rc is given as the first argument then cdrskin attempts on
startup to read the arguments from the following files:
.PP
.br
.B /etc/default/cdrskin
.br
.B /etc/opt/cdrskin/rc
.br
.B /etc/cdrskin/cdrskin.conf
.br
.B $HOME/.cdrskinrc
.br
.PP
The files are read in the sequence given above, but none of them is
required for cdrskin to function properly. Each readable line is treated
as one single argument. No extra blanks.
A first character '#' marks a comment, empty lines are ignored.
.SS
.B Example content of a startup file:
.br
# This is the default device
.br
dev=0,1,0
.br
# To accomodate to remnant cdrskin-0.2.2 addresses
.br
dev_translation=+1,0,0+0,1,0
.br
# Some more options
.br
fifo_start_at=0
.br
fs=16m
.br
.SH SEE ALSO
.TP
Formatting track sources for cdrskin:
.br
.BR mkisofs (8),
.BR genisoimage (8),
.BR afio (1),
.BR star (1)
.br
.TP
Other CD/DVD burn programs:
.br
.BR cdrecord (1),
.BR wodim (1)
.br
.TP
For DVD burning (also tutor of libburn's DVD capabilities):
.br
.BR growisofs (1)
.br
.SH AUTHOR
cdrskin was written by Thomas Schmitt <scdbackup@gmx.net>.
.PP
This manual page was written by George Danchev <danchev@spnet.net> and
Thomas Schmitt, for the Debian project and for all others.

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
<HEAD>
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW, DVD+R, cdrecord, compatible, scdbackup">
<META NAME="keywords" CONTENT="cdrskin, libburn, burn, CD, linux, CDR, CD-R, CDRW, CD-RW, cdrecord, compatible, scdbackup, burning">
<META NAME="robots" CONTENT="follow">
<TITLE>cdrskin homepage english</TITLE>
</HEAD>
@ -11,12 +11,7 @@
<FONT SIZE=+1>
<CENTER>
<A HREF="http://en.wikipedia.org/wiki/D%C3%B6ner_kebab">
<IMG SRC="doener_150x200_tr_octx.gif" BORDER=0
ALT="cdrskin logo: Doener mit Scharf">
</A>
<P><H2> Homepage of </H2>
<H1> cdrskin </H1>
<P><H2>Homepage of</H2><H1><BR>cdrskin</H1><BR>
<!-- <FONT SIZE=+0><A HREF="cdrskin_ger.html">deutsch (german)</A></FONT> -->
<H2>Limited cdrecord compatibility wrapper for libburn</H2>
@ -24,8 +19,9 @@
<P>
<H2>Purpose:</H2>
Burns preformatted data to CD and single layer DVD media:<BR>
CD-R, DVD-R, DVD+R, CD-RW, DVD-RW, DVD-RAM, DVD+RW
<UL>
<LI>Burns preformatted data to CD-R or CD-RW</LI>
</UL>
</P>
<P>
@ -33,10 +29,9 @@ CD-R, DVD-R, DVD+R, CD-RW, DVD-RW, DVD-RAM, DVD+RW
<P>
<H2>Hardware requirements:</H2>
A CD/DVD recorder suitable for
<A HREF="http://libburnia.pykix.org">libburnia.pykix.org</A> <BR>
(SCSI , ATA , USB , or SATA writers compliant to standard MMC-3 for CD
and to MMC-5 for DVD).
A CD recorder suitable for
<A HREF="http://libburn.pykix.org">libburn.pykix.org</A>
(SCSI or IDE/ATAPI writers compliant to mmc standard).
<BR>
</P>
@ -44,7 +39,7 @@ and to MMC-5 for DVD).
<H2>Software requirements :</H2>
<DL>
<DT>Linux kernel 2.4 or higher</DT>
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.4 the drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
<DT>libpthread</DT>
<DD>is supposed to be a standard system component.</DD>
@ -56,8 +51,8 @@ and to MMC-5 for DVD).
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-0.3.4</DT>
<DD>(by Derek Foreman, Ben Jansens, and team of libburnia.pykix.org)</DD>
<DT>libburn-0.2.6</DT>
<DD>(by Derek Foreman, Ben Jansens, and team of libburn.pykix.org)</DD>
<DD>transfers data to CD</DD>
</DL>
</P>
@ -88,98 +83,70 @@ and for data CD projects of <A HREF="http://www.k3b.org">K3b</A>
(see <A HREF="#examples">examples</A>).
Suitability for audio CD frontends has been improved much and is now being
evaluated.<BR>
Most DVD types are written in pseudo -tao modes which are very different
from the write mode DAO used by cdrecord(-ProDVD). With DVD-R[W] cdrskin
can use this write mode, too.<BR>
Further enhancements depend on people who can describe and discuss their
wishes as well as on the development of libburn.</DT>
<BR><BR>
<DT>Get an overview of drives and their addresses</DT>
<DD>#<KBD>&nbsp;cdrskin -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin dev=ATA -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin --devices</KBD></DD>
<DT>Being superuser avoids permission problems with /dev/sgN resp. /dev/hdX .
</DT>
<DT>Ordinary users should then get granted rw access to the /dev files
as listed by option --devices.</DT>
<DT>&nbsp;</DT>
<DT>Get an overview of drives:</DT>
<DD>$ cdrskin -scanbus</DD>
<DD>$ cdrskin dev=ATA -scanbus</DD>
<DD>$ cdrskin --devices</DD>
<DT>Get info about a particular drive or loaded media:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=0,1,0 -checkdrive</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -toc</KBD></DD>
<DT>Make used CD-RW or used unformatted DVD-RW writable again:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sg1 blank=fast -eject</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/dvd blank=all -eject</KBD></DD>
<DT>Format DVD-RW to avoid need for blanking before re-use:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sr0 blank=format_overwrite</KBD></DD>
<DT>De-format DVD-RW to make it capable of multi-session again:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sr0 blank=deformat_sequential</KBD></DD>
<DT>Write ISO-9660 filesystem image as only one to blank or formatted media:
</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;-sao -eject padsize=300k my_image.iso</KBD></DD>
<DT>Write compressed afio archive on-the-fly:</DT>
<DD>$<KBD>&nbsp;find . | afio -oZ - | \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;-tao padsize=300k -</KBD></DD>
<DT>Write several sessions to the same CD, DVD-R[W] or DVD+R:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso</KBD></DD>
<DT>Get multi-session info for option -C of program mkisofs:</DT>
<DD>$<KBD>&nbsp;c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)</KBD></DD>
<DD>$<KBD>&nbsp;mkisofs ... -C "$c_values" ...</KBD></DD>
<DT>Inquire free space on media for a -tao -multi run:</DT>
<DD>$<KBD>&nbsp;x=$(cdrskin dev=/dev/sr0 -tao -multi \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;--tell_media_space 2>/dev/null)</KBD></DD>
<DD>$<KBD>&nbsp;echo "Available: $x blocks of 2048 data bytes"</KBD></DD>
<DT>Write audio tracks to CD:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;track1.wav track2.au -audio -swab track3.raw</KBD></DD>
<DT>Get overview of the cdrecord compatible options:</DT>
<DD>$<KBD>&nbsp;<A HREF="cdrskin_help">cdrskin -help</A></KBD></DD>
<DT>Get overview of the non-cdrecord options:</DT>
<DD>$<KBD>&nbsp;<A HREF="cdrskin__help">cdrskin --help</A></KBD></DD>
<DT>Read the detailed manual page:</DT>
<DD>$<KBD>&nbsp;<A HREF="man_1_cdrskin.html">man cdrskin</A></KBD></DD>
</DL>
<DL>
<DT>Read about the standard for which cdrskin is striving:</DT>
<DD>$<KBD>&nbsp;
<A HREF="http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html">
man cdrecord</A></KBD></DD>
<DD><B>Do not bother Joerg Schilling with any cdrskin problems.</B>
<DD>$ cdrskin dev=0,1,0 -checkdrive</DD>
<DD>$ cdrskin dev=ATA:1,0,0 -atip</DD>
<DD>$ cdrskin dev=/dev/hdc -toc</DD>
<DT>Make used CD-RW writable again:</DT>
<DD>$ cdrskin -v dev=/dev/sg1 blank=all -eject</DD>
<DD>$ cdrskin -v dev=/dev/dvd blank=fast -eject</DD>
<DT>Write ISO-9660 filesystem image:</DT>
<DD>$ cdrskin -v dev=/dev/hdc speed=12 fs=8m driveropts=burnfree -sao -eject padsize=300k my_image.iso</DD>
<DT>Write compressed afio archive on-the-fly :</DT>
<DD>$ find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree padsize=300k -tao -</DD>
<DT>Write audio tracks:</DT>
<DD>$ cdrskin -v dev=ATA:1,0,0 speed=48 driveropts=burnfree -sao track1.wav track2.au -audio -swab track3.raw
<DD>
<BR>
<DT><A HREF="cdrskin_help">cdrskin -help</A></DT>
<DD>reports the cdrecord compatible options</DD>
<DT><A HREF="cdrskin__help">cdrskin --help</A></DT>
<DD>reports the non-cdrecord options</DD>
<DT><A HREF="http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html">man cdrecord</A></DT>
<DD>documents the standard for which cdrskin is striving.
<B>Do not bother Joerg Schilling with any cdrskin problems.</B>
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding
this "don't bother Joerg" demand.)
</DD>
</DL>
</P>
<P>
<H2>Known deficiencies:</H2>
<UL>
<DT></DT>
<LI>
Appending sessions to unclosed media is restricted to write mode TAO.
</LI>
<LI>
cdrskin -scanbus or --devices hangs for quite a while if there is
a CD drive which does not work properly (e.g. because it has individual
problems with DMA).
So if the superuser gets no result with cdrskin --devices then one should
disable DMA with the problematic CD drives
(like: <KBD>hdparm -d0 /dev/hdd</KBD> )
and try again.<BR>
In severe cases it might be necessary to guess the device name /dev/sgN resp.
/dev/hdX of the non-ill burner if it cannot be found otherwise among its
ill peers. Alternatively one can guess the address of the ill device, remove
rw-permissions and retry the bus scan as non-superuser.
</UL>
</P>
<HR>
<P>
<DL>
<DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-0.3.4.pl00.tar.gz">cdrskin-0.3.4.pl00.tar.gz</A>
(570 KB).
<DD><A HREF="cdrskin-0.2.6.pl01.tar.gz">cdrskin-0.2.6.pl01.tar.gz</A>
(510 KB).
</DD>
<DD>
The "stable" cdrskin tarballs are source code identical with "stable"
@ -189,30 +156,27 @@ cdrskin is part of libburn - full libburn is provided with cdrskin releases.
</DD>
<DD>&nbsp;</DD>
<DT>Download as single x86 binaries (untar and move to /usr/bin/cdrskin):</DT>
<DD><A HREF="cdrskin_0.3.4.pl00-x86-suse9_0.tar.gz">
cdrskin_0.3.4.pl00-x86-suse9_0.tar.gz</A>, (80 KB),
<DD><A HREF="cdrskin_0.2.6.pl01-x86-suse9_0.tar.gz">
cdrskin_0.2.6.pl01-x86-suse9_0.tar.gz</A>, (60 KB),
<DL>
<DD>runs on SuSE 9.0 (2.4.21) , RIP-14.4 (2.6.14) ,
Gentoo (2.6.15 x86_64 Athlon).</DD>
</DL>
<DD><A HREF="cdrskin_0.3.4.pl00-x86-suse9_0-static.tar.gz">
cdrskin_0.3.4.pl00-x86-suse9_0-static.tar.gz</A>, (285 KB), -static compiled,
<DD><A HREF="cdrskin_0.2.6.pl01-x86-suse9_0-static.tar.gz">
cdrskin_0.2.6.pl01-x86-suse9_0-static.tar.gz</A>, (260 KB), -static compiled,
<DL>
<DD>runs on SuSE 7.2 (2.4.4), and on the systems above.</DD>
</DL>
</DD>
</DL>
<DL><DT>Documentation:</DT>
<DD><A HREF="README_cdrskin">README</A> an introduction</DD>
<DD><A HREF="README_cdrskin">README</A> a short introduction</DD>
<DD><A HREF="cdrskin__help">cdrskin --help</A> non-cdrecord options</DD>
<DD><A HREF="cdrskin_help">cdrskin -help</A> cdrecord compatible options</DD>
<DD><A HREF="man_1_cdrskin.html">man cdrskin</A> the manual page</DD>
<DD>&nbsp;</DD>
</DL>
<DL><DT>Contact:</DT>
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
<DD>libburn development mailing list,
<A HREF="mailto:libburn-hackers@pykix.org">libburn-hackers@pykix.org</A></DD>
</DL>
<DL><DT>License:</DT>
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
@ -223,42 +187,42 @@ cdrskin_0.3.4.pl00-x86-suse9_0-static.tar.gz</A>, (285 KB), -static compiled,
<HR>
<P>
Enhancements towards previous stable version cdrskin-0.3.2:
Enhancements towards previous stable version cdrskin-0.2.4:
<UL>
<LI>Multi-session burning to DVD+R</LI>
<LI>New option --tell_media_space tells the maximum size for the next burn</LI>
<LI>New option assert_write_lba= prevents inadverted writing to appendable
<LI>Bug fix: Multi-track runs with fifo could stall in rare cases</LI>
<LI>Option <KBD><B>-tao</B></KBD> is fully enabled.<BR>
SAO is still the preferred default but TAO is default if a track of
unpredicted size is present (stdin, named pipe, ...) or if a follow-up
session is written to an appendable CD.
(This is an intentional deviation from cdrecord defaults which themselves
have changed with the newest cdrecord versions.)
</LI>
<LI>Status report during blank, preparation and finalization improved.</LI>
<LI>Bug fixed: Trailing trash appended to .wav files caused error message
and, if exceeding fifo size, could even stall a burn.
(Workaround: disable fifo by <KBD><B>fs=0</B></KBD>)</LI>
<LI>Bug fixed: False speed with first pacifier cycle. Potential program
abort by floating point exception (NaN).</LI>
<LI>multi-session CDs: <KBD><B>-multi</B></KBD>, <KBD><B>-msinfo</B></KBD>,
writing to appendable CDs (for now restricted to write mode TAO).</LI>
</UL>
<!--
Bug fixes towards cdrskin-0.3.4.pl00:
<UL>
<LI>none yet</LI>
</UL>
-->
</P>
<HR>
<P>
<DL>
<DT><H3>Development snapshot, version 0.3.5 :</H3></DT>
<DD>Enhancements towards stable version 0.3.4.pl00:
<UL>
<LI>none yet</LI>
</UL>
<DT><H3>Development snapshot, version 0.2.7 :</H3></DT>
<DD>Enhancements towards stable version 0.2.6:
(none yet)
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 0.3.5</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.3.5 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.3.5 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.3.5)</A></DD>
<DD><A HREF="README_cdrskin_devel">README 0.2.7</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.2.7 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.2.7 -help</A></DD>
<DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN of
<A HREF="http://libburnia.pykix.org"> libburnia.pykix.org</A></DT>
<DD>Download: <KBD><B>svn co http://libburnia-svn.pykix.org/libburn/trunk libburn_pykix</B>
<A HREF="http://libburn.pykix.org"> libburn.pykix.org</A></DT>
<DD>Download: <KBD><B>svn co http://libburn-svn.pykix.org/libburn/trunk libburn_pykix</B>
</KBD></DD>
<DD>Build: <KBD><B>cd libburn_pykix ; ./bootstrap ; ./configure ; make</B>
</KBD></DD>
@ -270,19 +234,19 @@ vanilla tools like make and gcc are needed.</DD>
<DD>&nbsp;</DD>
<DT>The following downloads are intended for adventurous end users or
admins with full system souvereignty.</DT>
<DD>Source (./bootstrap is already applied, build tested, for more see
<DD>Source (./bootstrap is already applied, build tested, for more see above
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-0.3.5.tar.gz">cdrskin-0.3.5.tar.gz</A>
(570 KB).
<A HREF="cdrskin-0.2.7.tar.gz">cdrskin-0.2.7.tar.gz</A>
(500 KB).
</DD>
<DD>Binary (untar and move to /usr/bin/cdrskin):</DD>
<DD><A HREF="cdrskin_0.3.5-x86-suse9_0.tar.gz">
cdrskin_0.3.5-x86-suse9_0.tar.gz</A>, (80 KB).
<DD><A HREF="cdrskin_0.2.7-x86-suse9_0.tar.gz">
cdrskin_0.2.7-x86-suse9_0.tar.gz</A>, (60 KB).
</DD>
<DD><A HREF="cdrskin_0.3.5-x86-suse9_0-static.tar.gz">
cdrskin_0.3.5-x86-suse9_0-static.tar.gz</A>, (280 KB)
<DD><A HREF="cdrskin_0.2.7-x86-suse9_0-static.tar.gz">
cdrskin_0.2.7-x86-suse9_0-static.tar.gz</A>, (260 KB)
</DD>
</DL>
</P>
@ -298,10 +262,6 @@ Historic versions based on Derek's and Ben's
<A HREF="http://icculus.org/burn">icculus.org/burn</A> :<BR>
<A HREF="cdrskin-0.1.2.0.2.ts.tar.gz">cdrskin-0.1.2.0.2.ts.tar.gz</A><BR>
<A HREF="cdrskin-0.1.3.0.2.ts.tar.gz">cdrskin-0.1.3.0.2.ts.tar.gz</A>
<BR>
Very special thanks to Andy Polyakov whose
<A HREF="http://fy.chalmers.se/~appro/linux/DVD+RW/tools">dvd+rw-tools</A>
provide libburn with invaluable examples on how to deal with DVD media.
</P>
<HR>
@ -344,7 +304,7 @@ is a GUI frontend which uses cdrecord for CD burning.)
<DD><KBD>...</KBD></DD>
<DD><KBD>&nbsp;&nbsp;&nbsp; 1,0,0 &nbsp;&nbsp; 1)&nbsp; 'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM</KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_SCSI_ADR="ATA:1,0,0"</B></KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_CDRECORD="cdrskin -v -v"</B></KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_CDRECORD="cdrskin -v -v tao_to_sao_tsize=650m"</B></KBD></DD>
<DD>$ <KBD><B>scdbackup_home</B></KBD></DD>
</DL>
<DL>
@ -353,7 +313,7 @@ is a GUI frontend which uses cdrecord for CD burning.)
<DD>$ <KBD><B>export SCDBACKUP_USE_CDRSKIN=1</B></KBD></DD>
<DD>$ <KBD><B>./CONFIGURE_CD</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>cdrskin 0.3.4 : limited cdrecord compatibility wrapper for libburn</KBD></DD>
<DD><KBD>cdrskin 0.2.6 : limited cdrecord compatibility wrapper for libburn</KBD></DD>
</DL>
If your system is stricken with some ill CD device then this can stall
and you will have to press <KBD>Ctrl+C</KBD> to abort.
@ -411,11 +371,10 @@ the gestures necessary for their cdrecord applications.
Contact me. Let's see what we can achieve.
<BR>
<BR>
libburn and cdrskin are now mature enough to substitute cdrecord in its
major use cases of CD and DVD burning. It is possible to foist cdrskin on
various software packages if it gets falsely named "cdrecord".
I do not encourage this approach, but of course such a replacement
opportunity is the goal of a cdrecord compatibility wrapper.
I am aware that libburn and cdrskin still have way to go until you can simply
install cdrskin as cdrecord and may expect any application to run with it.
Currently i do not encourage this approach, but of course such a replacement
opportunity is the long term goal of a cdrecord compatibility wrapper.
<BR>
<BR>
It is very important to me that this project is not perceived as hostile
@ -429,10 +388,6 @@ I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
<!-- <A NAME="bottom" HREF="main_ger.html#bottom">deutsch (german)</A>
<BR><BR>
-->
<A HREF="http://en.wikipedia.org/wiki/D%C3%B6ner_kebab">
<IMG SRC="doener_150x200_tr.gif" BORDER=0
ALT="cdrskin logo: Doener mit Scharf"></A>
<BR><BR>
<FONT SIZE=+0>Enjoying free Open Source hosting by <A HREF="http://www.webframe.org">www.webframe.org</A><BR>
<A HREF="http://www.webframe.org">
<IMG SRC="msfree.gif" ALT="100 % Microsoft free" BORDER=0></A><BR>

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.03.12.110001"
#define Cdrskin_timestamP "2006.11.23.102340"

File diff suppressed because it is too large Load Diff

View File

@ -63,9 +63,9 @@ static int signal_list_count= 24;
/* Signals not to be caught */
static int non_signal_list[]= {
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1
};
static int non_signal_list_count= 5;
static int non_signal_list_count= 4;
#endif /* Cleanup_has_no_libburn_os_H */
@ -75,7 +75,6 @@ static int non_signal_list_count= 5;
/* run time dynamic part */
static char cleanup_msg[4096]= {""};
static int cleanup_exiting= 0;
static int cleanup_has_reported= -1234567890;
static void *cleanup_app_handle= NULL;
static Cleanup_app_handler_T cleanup_app_handler= NULL;
@ -86,10 +85,8 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
{
int ret;
if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
if(cleanup_msg[0]!=0)
fprintf(stderr,"\n%s\n",cleanup_msg);
cleanup_has_reported= signum;
}
if(cleanup_perform_app_handler_first)
if(cleanup_app_handler!=NULL) {
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);

View File

@ -7,7 +7,7 @@
debug_opts=
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
libvers="-DCdrskin_libburn_0_3_4"
libvers="-DCdrskin_libburn_0_2_6"
cleanup_src_or_obj="libburn/cleanup.o"
libdax_msgs_o="libburn/libdax_msgs.o"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
@ -33,15 +33,15 @@ do
libdax_audioxtr_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_3_4"
elif test "$i" = "-libburn_0_2_6"
then
libvers="-DCdrskin_libburn_0_3_4"
libvers="-DCdrskin_libburn_0_2_6"
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_3_5"
libvers="-DCdrskin_libburn_0_2_6"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
libdax_msgs_o="libburn/libdax_msgs.o"
cleanup_src_or_obj="libburn/cleanup.o"
@ -79,7 +79,7 @@ do
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006."
echo " -libburn_0_3_4 set macro to match libburn-0.3.4."
echo " -libburn_0_2_6 set macro to match libburn-0.2.6."
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -no_largefile do not use 64 bit off_t (must match libburn)."
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."

View File

@ -1,76 +0,0 @@
#!/bin/sh
#
# convert_man_to_html.sh - ts A61214
#
# Generates a HTML version of man page cdrskin.1
#
# To be executed within the libburn toplevel directory (like ./libburn-0.2.7)
#
# set -x
man_dir=$(pwd)"/cdrskin"
export MANPATH="$man_dir"
manpage="cdrskin"
raw_html=$(pwd)/"cdrskin/raw_man_1_cdrskin.html"
htmlpage=$(pwd)/"cdrskin/man_1_cdrskin.html"
if test -r "$manpage"
then
dummy=dummy
else
echo "Cannot find readable man page source $1" >&2
exit 1
fi
if test -e "$man_dir"/man1
then
dummy=dummy
else
ln -s . "$man_dir"/man1
fi
if test "$1" = "-work_as_filter"
then
# set -x
sed \
-e 's/<meta name="generator" content="groff -Thtml, see www.gnu.org">/<meta name="generator" content="groff -Thtml, via man -H, via cdrskin\/convert_man_to_html.sh">/' \
-e 's/<meta name="Content-Style" content="text\/css">/<meta name="Content-Style" content="text\/css"><META NAME="description" CONTENT="man page of cdrskin"><META NAME="keywords" CONTENT="man cdrskin, manual, cdrskin, CD, CD-RW, CD-R, burning, cdrecord, compatible"><META NAME="robots" CONTENT="follow">/' \
-e 's/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
-e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \
-e 's/<b>Overview of features:<\/b>/\&nbsp;<BR><b>Overview of features:<\/b>/' \
-e 's/<b>General information paragraphs:<\/b>/\&nbsp;<BR><b>General information paragraphs:<\/b>/' \
-e 's/<b>Track recording model:<\/b>/\&nbsp;<BR><b>Track recording model:<\/b>/' \
-e 's/In general there are two types of tracks: data and audio./\&nbsp;<BR>In general there are two types of tracks: data and audio./' \
-e 's/While audio tracks just contain a given/\&nbsp;<BR>While audio tracks just contain a given/' \
-e 's/<b>Write mode selection:<\/b>/\&nbsp;<BR><b>Write mode selection:<\/b>/' \
-e 's/<b>Recordable CD Media:<\/b>/\&nbsp;<BR><b>Recordable CD Media:<\/b>/' \
-e 's/<b>Overwriteable DVD Media:<\/b>/\&nbsp;<BR><b>Overwriteable DVD Media:<\/b>/' \
-e 's/<b>Sequentially Recordable DVD Media:<\/b>/\&nbsp;<BR><b>Sequentially Recordable DVD Media:<\/b>/' \
-e 's/The write modes for DVD+R/\&nbsp;<BR>The write modes for DVD+R/' \
-e 's/<b>Drive preparation and addressing:<\/b>/\&nbsp;<BR><b>Drive preparation and addressing:<\/b>/' \
-e 's/If you only got one CD capable drive/\&nbsp;<BR>If you only got one CD capable drive/' \
-e 's/^Alphabetical list of options/\&nbsp;<BR>Alphabetical list of options/' \
-e 's/and for all others\.<\/td><\/table>/and for all others.<\/td><\/table> <BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT>/' \
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
<"$2" >"$htmlpage"
set +x
chmod u+rw,go+r,go-w "$htmlpage"
echo "Emerged file:"
ls -lL "$htmlpage"
else
export BROWSER='cp "%s" '"$raw_html"
man -H "$manpage"
"$0" -work_as_filter "$raw_html"
rm "$raw_html"
rm "$man_dir"/man1
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,39 +1,35 @@
--------------------------------------------------------------------------
cdrskin Wiki - plain text copy
--------------------------------------------------------------------------
[[Image(source:/libburn/trunk/cdrskin/doener_150x200_tr.gif)]] [http://en.wikipedia.org/wiki/D%C3%B6ner_kebab Doener]
'''cdrskin is the cdrecord compatibility middleware of libburn.'''
cdrskin is the cdrecord compatibility middleware of libburn.
Its paragon, cdrecord, is a powerful GPL'ed burn program included in Joerg
Schilling's cdrtools. cdrskin strives to be a second source for the services
traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way.
Overwriteable media DVD-RAM, DVD+RW and DVD-RW are handled differently than
with cdrecord-ProDVD in order to offer TAO-like single track recording.
Sequential DVD-R[W] and DVD+R are handled like CD-R[W] with TAO and
multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
with DVD-R[W].
traditionally provided by cdrecord. Currently it does CD-R and CD-RW.
Its future ability to burn DVD media depends on the development of libburn.
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
runs, though. The most comprehensive technical overview of cdrskin
can be found in [http://libburnia.pykix.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
can be found in cdrskin/README . Online available as :
http://libburn.pykix.org/browser/trunk/cdrskin/README?format=raw
About libburn API for burning CD: http://libburnia-api.pykix.org
About libburn API for burning CD: http://libburn-api.pykix.org
--------------------------------------------------------------------------
For dual layer DVD types and for appending sessions to ISO filesystems on
DVD other than DVD-RW, DVD-R, DVD+R see the advise to use dvd+rw-tools at
the end of this text.
Appending sessions to an unclosed CD is restricted to write mode TAO.
(Users who have a burner which succeeds with a follow-up session via
cdrecord -sao : please contact us.)
cdrskin does not provide DVD burning yet. See advise to use dvd+rw-tools
at the end of this text.
--------------------------------------------------------------------------
About the command line options of cdrskin:
They are described in detail in [http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html#OPTIONS section OPTIONS] of
[http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html man cdrskin]
There are two families of options: cdrecord-compatible ones and options
which are specific to cdrskin. The latter are mostly used to configure
cdrskin for its task to emulate cdrecord. There are some, nevertheless,
@ -43,10 +39,9 @@ The cdrecord-compatible options are listed in the output of
{{{
cdrskin -help
}}}
where the option "help" has *one* dash. Online: [http://scdbackup.sourceforge.net/cdrskin_help_devel cdrskin -help]
where the option "help" has *one* dash.
For these options you may expect program behavior that is roughly the
same as described in original man cdrecord .
same as described in original man 1 cdrecord .
Online: http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html
@ -54,10 +49,10 @@ The cdrskin-specific options are listed by
{{{
cdrskin --help
}}}
where the option "help" has *two* dashes. Online: [http://scdbackup.sourceforge.net/cdrskin__help_devel cdrskin --help]
where the option "help" has *two* dashes.
Some are very experimental and should only be
used in coordination with the libburnia developer team.
Those have no man page yet. Some are very experimental and should only be
used in coordination with the libburn developer team.
Some are of general user interest, though:
--------------------------------------------------------------------------
@ -82,66 +77,6 @@ has to offer both, r- and w-permission.
--------------------------------------------------------------------------
The DVD capabilities of cdrskin differ from those of cdrecord-ProDVD. cdrskin
offers TAO-like multi-session with DVD-R[W], DVD+R and TAO-like single session
with overwriteable DVD media. It also offers DAO on DVD-R[W] which is probably
the same as the traditional cdrecord-ProDVD write mode.
Non-cdrecord blank mode blank=format_overwrite brings a DVD-RW
disc from its initial profile "Sequential Recording" into profile state
"Restricted Overwrite".
{{{
cdrskin dev=/dev/sr0 -v blank=format_overwrite
}}}
DVD-RAM, DVD+RW and overwriteable DVD-RW appear to cdrskin as blank media
which are capable of taking only a single track. This track may be positioned
on a 32KiB aligned address, though.
{{{
cdrskin ... write_start_address=2412m ...
}}}
Non-cdrecord blank mode blank=deformat_sequential brings an overwriteable
DVD-RW back into state "Sequential Recording" with the capability of doing
multi-session, if the drive is capable of "Incremental Streaming"
(MMC feature 21h).
Used sequential DVD-RW media may be blanked by blank=fast or blank=all which
normally both do full blanking.
blank=deformat_sequential does minimal blanking of DVD-RW which usually yields
media incapable of "Incremental Streaming".
Option --prodvd_cli_compatible activates blank=fast and blank=all for
overwriteable DVD-RW which normally ignore those two options. It also makes
option -multi tolerable with media and write modes which are not suitable for
multi-session. (The default behavior of cdrskin deems me to be preferrable.)
--------------------------------------------------------------------------
assert_write_lba=<lba> allows to ensure that the start block address which
was used with the formatter program (e.g. mkisofs -C) matches the start block
address which will be used by the upcoming burn.
E.g. cdrskin aborts with an error message if
{{{
assert_write_lba=0
}}}
is given but an appendable media is to be burned which would start ati
block 68432.
An ISO-9660 file system image must be prepared according to a particular
block address on media. If the prepared address and the real address on media
do not match then the filesystem will not be mountable or may even cause system
trouble.
A sequential archive format like afio or star will not necessarily need such
a coordination of addresses. It might nevertheless be confusing to a reader
if the archive does not start at block 0.
--------------------------------------------------------------------------
fifo_start_at=<num> is a throughput enhancer for unsteady data streams
like they are produced by a compressing archiver program when piping to
CD on-the-fly. It makes better use of the general property of a FIFO
@ -191,12 +126,25 @@ default settings of cdrskin. Possible locations for such settings:
/etc/opt/cdrskin/rc
/etc/cdrskin/cdrskin.conf
$HOME/.cdrskinrc
--------------------------------------------------------------------------
tao_to_sao_tsize=<num> allows the - actually unsupported - cdrecord option
-tao and defines a default track size to be used if - as custom with -tao -
no option tsize=# is given.
Since -tao is supported in cdrskin-0.2.6 the TAO-to-SAO workaround has become
quite obsolete. Nevertheless, tao_to_sao_tsize= allows to preset a default
size for SAO mode which is in effect only if no track size is available.
As in general with cdrskin tsize=# the data source does not have to provide
the full annouced amount of data. Missing data will be padded up by 0-bytes.
Surplus data is supposed to cause an error, though. The burn will then
be a failure in any way.
--------------------------------------------------------------------------
dev_translation=<sep><from><sep><to> may be needed to foist cdrskin to
frontend programs of cdrecord which do *not* ask cdrecord -scanbus but
which make own assumptions and guesses about cdrecord's device addresses.
@ -228,10 +176,9 @@ for an illustrated example with K3b 0.10 .
DVD advise:
For burning of DVD media other than DVD-RAM, DVD+RW, DVD+R, DVD-RW, DVD-R,
the cdrskin project currently advises to use Andy Polyakov's dvd+rw-tools
which despite their historic name are capable of all the media above
and also do dual layer and even BD discs.
For burning of DVD media the cdrskin project currently advises to use
Andy Polyakov's dvd+rw-tools which despite their historic name burn
for me on above burner: DVD+RW, DVD+R, DVD-RW, DVD-R .
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
@ -239,19 +186,24 @@ They are not compatible or related to cdrecord resp. cdrecord-ProDVD
(now obsoleted by original source cdrtools cdrecord with identical
capabilities besides the license key).
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
overwriteable media. This is not the same as multi-session writing of cdrskin
with CD media, but retrieves additional information from the existing ISO
image and finally manipulates the start sectors of this existing image.
So for growable ISO filesystems on DVD-RAM or DVD+RW growisofs is the only
choice, currently.
If there is sincere and well motivated interest, the cdrskin project could try
to employ growisofs as DVD burning engine. The cdrskin project would prefer to
wait for DVD support being included in libburn, though.
A very limited and specialized cdrecord-compatibility wrapper for growisofs
serves in my project scdbackup. It is not overly hard to make one that serves
some very few fixed use cases.
To my knowledge, Linux kernels 2.6 do write to DVD+RW via block devices as
they would write to a traditional tape device. Try old tape archiver
commands with addresses like /dev/sr0 or /dev/hdc rather than /dev/mt0 .
I have heard rumors that DVD-RW in mode "restricted overwrite" would be
block device ready, too. My burner is not a real friend of DVD-RW and
in an experiment the burn worked fine - but the result was not identical
to the stream sent to the device. I had similar failure with DVD-RAM, too.
cdrskin can offer DVD multi-session only with sequential DVD-R[W] and with
DVD+R.
Associated options blank=, -multi, -msinfo and -toc are available in this case.
Thus sequential DVD-RW behave much like large CD-RW with possibly more than 99
tracks.
Beware of the impact of a slow block device on overall system i/o buffering.
It is wise to curb its input to a speed which it is able to deliver to media.
Else your i/o dedicated RAM might buffer a big amount of stream data.
--------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [0.3.4], [http://libburnia.pykix.org])
AC_INIT([libburn], [0.2.6], [http://libburn.pykix.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -7,6 +7,12 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects])
dnl A61101 This breaks Linux build (makes 32 bit off_t)
dnl http://sourceware.org/autobook/autobook/autobook_96.html says
dnl one must include some config.h and this was a pitfall.
dnl So why dig the pit at all ?
dnl AM_CONFIG_HEADER(config.h)
dnl Making releases:
dnl BURN_MICRO_VERSION += 1;
dnl BURN_INTERFACE_AGE += 1;
@ -18,8 +24,8 @@ dnl
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
dnl
BURN_MAJOR_VERSION=0
BURN_MINOR_VERSION=3
BURN_MICRO_VERSION=4
BURN_MINOR_VERSION=2
BURN_MICRO_VERSION=6
BURN_INTERFACE_AGE=0
BURN_BINARY_AGE=0
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
@ -57,7 +63,6 @@ AC_C_BIGENDIAN
dnl Large file support
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
AC_CHECK_FUNC([fseeko])
if test ! $ac_cv_func_fseeko; then
AC_ERROR([Libburn requires largefile support.])
fi
@ -70,6 +75,12 @@ AC_PROG_INSTALL
AC_CHECK_HEADERS()
AC_CHECK_MEMBER([struct tm.tm_gmtoff],
[AC_DEFINE(HAVE_TM_GMTOFF, 1,
[Define this if tm structure includes a tm_gmtoff entry.])],
,
[#include <time.h>])
THREAD_LIBS=-lpthread
AC_SUBST(THREAD_LIBS)

View File

@ -1,16 +1,12 @@
/**
@author Mario Danic, Thomas Schmitt
@mainpage Libburnia Documentation Index
@mainpage Libburn Documentation Index
@section intro Introduction
Libburnia is an open-source project for reading, mastering and writing
optical discs.
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD-RW, DVD-R.
Not supported yet are dual layer media, HD-DVD, BD (blue ray). Testers for
dual layer DVD+/-R are wanted, though.
Libburn is an open-source library for reading, mastering and writing
optical discs. For now this means only CD-R and CD-RW.
The project comprises of several more or less interdependent parts which
together strive to be a usable foundation for application development.
@ -22,22 +18,19 @@ we would need : login on a development machine resp. a live OS on CD or DVD,
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
volunteers for testing of realistic use cases.
We have a workable code base for burning data and audio CDs and many DVD types.
The burn API is quite comprehensively documented and can be used to build a
presentable application.
We have a functional binary which emulates the core use cases of cdrecord in
order to prove that usability, and in order to allow you to explore libburn's
scope by help of existing cdrecord frontends.
We do have a workable code base for burning data CDs, though. The burn API is
quite comprehensively documented and can be used to build a presentable
application.
We do have a functional binary which emulates parts of cdrecord in order to
prove that usability, and in order to allow you to explore libburn's scope
by help of existing cdrecord frontends.
@subsection components The project components (list subject to growth, hopefully):
- libburn is the library by which preformatted data get onto optical media.
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
/dev/hdX (e.g. on kernel 2.6).
libburn is the foundation of our cdrecord emulation. Its code is
independent of cdrecord. Its DVD capabilities are learned from
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
libburn is the foundation of our cdrecord emulation.
- libisofs is the library to pack up hard disk files and directories into a
ISO 9660 disk image. This may then be brought to CD via libburn.
@ -46,18 +39,15 @@ scope by help of existing cdrecord frontends.
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
cdrecord is a powerful GPL'ed burn program included in Joerg
Schilling's cdrtools. cdrskin strives to be a second source for
the services traditionally provided by cdrecord. Additionally it
provides libburn's DVD capabilities, where only -sao is compatible
with cdrecord.
the services traditionally provided by cdrecord.
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
runs, though.
See cdrskin/README for more.
- "test" is a collection of application gestures and examples given by the
authors of the library features. The burn API example of libburn
is named test/libburner.c . The API for media information inquiry is
demonstrated in test/telltoc.c .
authors of the library features. The main API example of libburn
is named test/libburner.c .
Explore these examples if you look for inspiration.
We plan to be a responsive upstream. Bear with us.
@ -90,11 +80,11 @@ languages and development tools.
libburner is a minimal demo application for the library libburn
(see: libburn/libburn.h) as provided on http://libburn.pykix.org .
It can list the available devices, can blank a CD-RW or DVD-RW and
can burn to recordable CD and recordable single layer DVD.
It can list the available devices, can blank a CD-RW and
can burn to CD-R or CD-RW.
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburnia team as reference application. libburner does indeed
to serve the libburn team as reference application. libburner does indeed
define the standard way how above three gestures can be implemented and
stay upward compatible for a good while.
@ -102,43 +92,27 @@ stay upward compatible for a good while.
<pre>
Usage: test/libburner
[--drive <address>|<driveno>|"-"] [--audio]
[--blank_fast|--blank_full|--format_overwrite]
[--try_to_simulate]
[--multi] [<one or more imagefiles>|"-"]
[--blank_fast|--blank_full] [--try_to_simulate]
[<one or more imagefiles>|"-"]
Examples
A bus scan (needs rw-permissions to see a drive):
test/libburner --drive -
Burn a file to drive chosen by number, leave appendable:
test/libburner --drive 0 --multi my_image_file
Burn a file to drive chosen by persistent address, close:
Burn a file to drive chosen by number:
test/libburner --drive 0 my_image_file
Burn a file to drive chosen by persistent address:
test/libburner --drive /dev/hdc my_image_file
Blank a used CD-RW (is combinable with burning in one run):
test/libburner --drive /dev/hdc --blank_fast
Blank a used DVD-RW (is combinable with burning in one run):
test/libburner --drive /dev/hdc --blank_full
Format a DVD-RW to avoid need for blanking before re-use:
test/libburner --drive /dev/hdc --format_overwrite
Burn two audio tracks (to CD only):
Burn two audio tracks
lame --decode -t /path/to/track1.mp3 track1.cd
test/dewav /path/to/track2.wav -o track2.cd
test/libburner --drive /dev/hdc --audio track1.cd track2.cd
Burn a compressed afio archive on-the-fly:
Burn a compressed afio archive on-the-fly, pad up to 700 MB:
( cd my_directory ; find . -print | afio -oZ - ) | \
test/libburner --drive /dev/hdc -
To be read from *not mounted* media via: afio -tvZ /dev/hdc
To be read from *not mounted* CD via: afio -tvZ /dev/hdc
Program tar would need a clean EOF which our padded CD cannot deliver.
</pre>
libburner has two companions, telltoc and dewav, which help to perform some
peripheral tasks of burning.
telltoc prints a table of content (sessions, tracks and leadouts), it tells
about type and state of media, and also is able to provide the necessary
multi-session information for program mkisofs option -C. Especially helpful
are its predictions with "Write multi" and "Write modes" where availability
of "TAO" indicates that tracks of unpredicted length can be written.
See: test/telltoc --help.
dewav extracts raw byte-swapped audio data from files of format .wav (MS WAVE)
or .au (SUN Audio). See example in libburner --help.
@subsection libburner-source Sourceode of libburner

121
doc/comments_test_ts Normal file
View File

@ -0,0 +1,121 @@
/**
@author Mario Danic, Thomas Schmitt
@mainpage Libburn Documentation Index
@section intro Introduction
Libburn is an open-source library for reading, mastering and writing
optical discs. For now this means only CD-R and CD-RW.
The project comprises of several more or less interdependent parts which
together strive to be a usable foundation for application development.
These are libraries, language bindings, and middleware binaries which emulate
classical (and valuable) Linux tools.
Our scope is currently Linux 2.4 and 2.6 and we will have a hard time to widen
this for now, because of our history. The project could need advise from or
membership of skilled kernel people and people who know how to talk CD/DVD
drives into doing things.
We do have a workable code base for burning data CDs, though. The burn API is
quite comprehensively documented and can be used to build a presentable
application.
We do have a functional binary which emulates parts of cdrecord in order to
prove that usability, and in order to allow you to explore libburn's scope
by help of existing cdrecord frontends.
@subsection components The project components (list subject to growth, hopefully):
- libburn is the library by which preformatted data get onto optical media.
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
/dev/hdX (e.g. on kernel 2.6).
libburn is the foundation of our cdrecord emulation.
- libisofs is the library to pack up hard disk files and directories into a
ISO 9660 disk image. This may then be brought to CD via libburn.
libisofs is to be the foundation of our upcoming mkisofs emulation.
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
cdrecord is a powerful GPL'ed burn program included in Joerg
Schilling's cdrtools. cdrskin strives to be a second source for
the services traditionally provided by cdrecord.
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
runs, though.
See cdrskin/README for more.
- "test" is a collection of application gestures and examples given by the
authors of the library features. The main API example of libburn
is named test/libburner.c .
Explore these examples if you look for inspiration.
We plan to be a responsive upstream. Bear with us.
@section using Using the libraries
Our build system is based on autotools.
User experience tells us that you will need at least autotools version 1.7.
To build libburn and its subprojects it should be sufficient to go into
its toplevel directory and execute
- ./bootstrap (needed if you downloaded from SVN)
- ./configure
- make
To make the libraries accessible for running resp. developing applications
- make install
Both libraries are written in C language and get built by autotools.
Thus we expect them to be useable by a wide range of Linux-implemented
languages and development tools.
@section libburner Libburner
libburner is a minimal demo application for the library libburn
(see: libburn/libburn.h) as provided on http://libburn.pykix.org .
It can list the available devices, can blank a CD-RW and
can burn to CD-R or CD-RW.
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburn team as reference application. libburner does indeed
define the standard way how above three gestures can be implemented and
stay upward compatible for a good while.
@subsection libburner-help Libburner --help
<pre>
Usage: test/libburner
[--drive <address>|<driveno>|"-"]
[--verbose <level>] [--blank_fast|--blank_full]
[--burn_for_real|--try_to_simulate] [--stdin_size <bytes>]
[<imagefile>|"-"]
Examples
A bus scan (needs rw-permissions to see a drive):
test/libburner --drive -
Burn a file to drive chosen by number:
test/libburner --drive 0 --burn_for_real my_image_file
Burn a file to drive chosen by persistent address:
test/libburner --drive /dev/hdc --burn_for_real my_image_file
Blank a used CD-RW (is combinable with burning in one run):
test/libburner --drive 0 --blank_fast
Burn a compressed afio archive on-the-fly, pad up to 700 MB:
( cd my_directory ; find . -print | afio -oZ - ) | \
test/libburner --drive /dev/hdc --burn_for_real --stdin_size 734003200 -
To be read from *not mounted* CD via:
afio -tvZ /dev/hdc
Program tar would need a clean EOF which our padded CD cannot deliver.
</pre>
@subsection libburner-source Sourceode of libburner
Click on blue names of functions, structures, variables, etc in oder to
get to the according specs of libburn API or libburner sourcecode.
@include libburner.c
*/

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,9 @@
#include "options.h"
#include "async.h"
#include "init.h"
#include "back_hacks.h"
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
#include <a ssert.h>
@ -38,14 +35,6 @@ struct erase_opts
int fast;
};
/* ts A61230 */
struct format_opts
{
struct burn_drive *drive;
off_t size;
int flag;
};
struct write_opts
{
struct burn_drive *drive;
@ -53,7 +42,6 @@ struct write_opts
struct burn_disc *disc;
};
struct w_list
{
struct burn_drive *drive;
@ -65,7 +53,6 @@ struct w_list
{
struct scan_opts scan;
struct erase_opts erase;
struct format_opts format;
struct write_opts write;
} u;
};
@ -211,9 +198,6 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
{
struct erase_opts o;
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
drive->cancel = 1;
/* ts A61006 */
/* a ssert(drive); */
/* a ssert(!SCAN_GOING()); */
@ -234,90 +218,11 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
return;
}
/* ts A70103 moved up from burn_disc_erase_sync() */
/* ts A60825 : allow on parole to blank appendable CDs */
/* ts A70131 : allow blanking of overwriteable DVD-RW (profile 0x13) */
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
and of any kind of full media */
if ((drive->current_profile != 0x0a &&
drive->current_profile != 0x13 &&
drive->current_profile != 0x14 &&
drive->status != BURN_DISC_FULL)
||
(drive->status != BURN_DISC_FULL &&
drive->status != BURN_DISC_APPENDABLE &&
drive->status != BURN_DISC_BLANK)
) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020130,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive and media state unsuitable for blanking",
0, 0);
return;
}
o.drive = drive;
o.fast = fast;
add_worker(drive, (WorkerFunc) erase_worker_func, &o);
}
/* ts A61230 */
static void *format_worker_func(struct w_list *w)
{
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
w->u.format.flag);
remove_worker(pthread_self());
return NULL;
}
/* ts A61230 */
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
{
struct format_opts o;
int ok = 0;
char msg[160];
if ((SCAN_GOING()) || find_worker(drive)) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"A drive operation is still going on (want to format)",
0, 0);
return;
}
if (flag & 128) /* application prescribed format type */
flag |= 16; /* enforce re-format */
if (drive->current_profile == 0x14)
ok = 1; /* DVD-RW sequential */
else if (drive->current_profile == 0x13 && (flag & 16))
ok = 1; /* DVD-RW Restricted Overwrite with force bit */
else if (drive->current_profile == 0x1a) {
ok = 1; /* DVD+RW */
size = 0;
flag &= ~(2|8); /* no insisting in size 0, no expansion */
flag |= 4; /* format up to maximum size */
}
if (!ok) {
sprintf(msg,"Will not format media type %4.4Xh",
drive->current_profile);
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020129,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
drive->cancel = 1;
return;
}
o.drive = drive;
o.size = size;
o.flag = flag;
add_worker(drive, (WorkerFunc) format_worker_func, &o);
}
static void *write_disc_worker_func(struct w_list *w)
{
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
@ -333,18 +238,6 @@ static void *write_disc_worker_func(struct w_list *w)
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{
struct write_opts o;
char reasons[BURN_REASONS_LEN+80];
#ifndef Libburn_precheck_write_ruleS
int i, j, mode, mixed_mode = 0;
#endif
/* For the next lines any return indicates failure */
opts->drive->cancel = 1;
/* ts A70203 : people have been warned in API specs */
if (opts->write_type == BURN_WRITE_NONE)
return;
/* ts A61006 */
/* a ssert(!SCAN_GOING()); */
@ -365,57 +258,10 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
"Drive capabilities not inquired yet", 0, 0);
return;
}
/* ts A70219 : intended to replace all further tests here and many
tests in burn_*_write_sync()
*/
strcpy(reasons, "Write job parameters are unsuitable:\n");
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
== BURN_WRITE_NONE) {
#ifndef Libburn_precheck_write_ruleS
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
#else
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
return;
#endif /* Libburn_precheck_write_ruleS */
}
#ifndef Libburn_precheck_write_ruleS
/* <<< covered burn_precheck_write() */
/* ts A61009 : obsolete Assert in sector_headers() */
if (! burn_disc_write_is_ok(opts, disc, 0)) /* issues own msgs */
if (! burn_disc_write_is_ok(opts, disc)) /* issues own msgs */
return;
/* <<< covered burn_precheck_write() */
/* ts A70122 : libburn SAO code mishandles mode changes */
for (i = 0; i < disc->sessions; i++) {
if (disc->session[i]->tracks <= 0)
continue;
mode = disc->session[i]->track[0]->mode;
for (j = 1; j < disc->session[i]->tracks; j++)
if (mode != disc->session[i]->track[j]->mode)
mixed_mode = 1;
}
if (mixed_mode && opts->write_type == BURN_WRITE_SAO) {
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020133,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot mix data and audio in SAO mode", 0, 0);
return;
}
#endif /* ! Libburn_precheck_write_ruleS */
opts->drive->cancel = 0; /* End of the return = failure area */
o.drive = opts->drive;
o.opts = opts;
o.disc = disc;

View File

@ -63,9 +63,9 @@ static int signal_list_count= 24;
/* Signals not to be caught */
static int non_signal_list[]= {
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1
};
static int non_signal_list_count= 5;
static int non_signal_list_count= 4;
#endif /* Cleanup_has_no_libburn_os_H */
@ -75,7 +75,6 @@ static int non_signal_list_count= 5;
/* run time dynamic part */
static char cleanup_msg[4096]= {""};
static int cleanup_exiting= 0;
static int cleanup_has_reported= -1234567890;
static void *cleanup_app_handle= NULL;
static Cleanup_app_handler_T cleanup_app_handler= NULL;
@ -86,10 +85,8 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
{
int ret;
if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
if(cleanup_msg[0]!=0)
fprintf(stderr,"\n%s\n",cleanup_msg);
cleanup_has_reported= signum;
}
if(cleanup_perform_app_handler_first)
if(cleanup_app_handler!=NULL) {
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);

View File

@ -25,15 +25,7 @@
#include "util.h"
#include "sg.h"
#include "structure.h"
/* ts A70107 : to get BE_CANCELLED */
#include "error.h"
/* ts A70219 : for burn_disc_get_write_mode_demands() */
#include "options.h"
/* A70225 : to learn about eventual Libburn_dvd_r_dl_multi_no_close_sessioN */
#include "write.h"
#include "back_hacks.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -62,7 +54,6 @@ void burn_drive_free(struct burn_drive *d)
if (burn_drive_is_open(d))
d->release(d);
free((void *) d->idata);
burn_mdata_free_subs(d->mdata);
free((void *) d->mdata);
if(d->toc_entry != NULL)
free((void *) d->toc_entry);
@ -144,39 +135,54 @@ unsigned int burn_drive_count(void)
return drivetop + 1;
}
/* ts A61125 : media status aspects of burn_drive_grab() */
int burn_drive_inquire_media(struct burn_drive *d)
int burn_drive_grab(struct burn_drive *d, int le)
{
int errcode;
int was_equal = 0, must_equal = 3, max_loop = 20;
/* ts A61225 : after loading the tray, mode page 2Ah can change */
d->getcaps(d);
/* ts A60907 */
int loop_count, old_speed = -1234567890, new_speed = -987654321;
int old_erasable = -1234567890, new_erasable = -987654321;
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
if (!d->released) {
burn_print(1, "can't grab - already grabbed\n");
return 0;
}
errcode = d->grab(d);
if (errcode == 0) {
burn_print(1, "low level drive grab failed\n");
return 0;
}
d->busy = BURN_DRIVE_GRABBING;
if (le)
d->load(d);
d->lock(d);
d->start_unit(d);
/* ts A61020 : this was BURN_DISC_BLANK as pure guess */
d->status = BURN_DISC_UNREADY;
if (d->mdata->cdr_write || d->mdata->cdrw_write ||
d->mdata->dvdr_write || d->mdata->dvdram_write) {
#define Libburn_knows_correct_state_after_loaD 1
#ifdef Libburn_knows_correct_state_after_loaD
#ifdef Libburn_grab_release_and_grab_agaiN
d->read_disc_info(d);
#else
/* ts A61227 : This repeated read_disc_info seems
to be obsoleted by above d->getcaps(d).
*/
/* ts A60908 */
/* Trying to stabilize the disc status after eventual load
without closing and re-opening the drive */
/* This seems to work for burn_disc_erasable() .
Speed values on RIP-14 and LITE-ON 48125S are stable
and false, nevertheless. */
int was_equal = 0, must_equal = 3, max_loop = 20;
int loop_count, old_speed = -1234567890, new_speed= -987654321;
int old_erasable = -1234567890, new_erasable = -987654321;
fprintf(stderr,"LIBBURN_DEBUG: read_disc_info()\n");
and false, nevertheless. So cdrskin -atip is still
forced to finish-initialize. */
/*
fprintf(stderr,"libburn: experimental: read_disc_info()\n");
*/
for (loop_count = 0; loop_count < max_loop; loop_count++){
old_speed = new_speed;
old_erasable = new_erasable;
@ -196,57 +202,18 @@ int burn_drive_inquire_media(struct burn_drive *d)
was_equal = 0;
/*
if (loop_count >= 1 && was_equal == 0)
*/
fprintf(stderr,"LIBBURN_DEBUG: %d : speed %d:%d erasable %d:%d\n",
fprintf(stderr,"libburn: experimental: %d : speed %d:%d erasable %d:%d\n",
loop_count,old_speed,new_speed,old_erasable,new_erasable);
*/
usleep(100000);
}
#endif /* ! Libburn_knows_correct_state_after_loaD */
#endif /* ! Libburn_grab_release_and_grab_agaiN */
} else {
if (d->current_profile == -1 || d->current_is_cd_profile)
d->read_toc(d);
d->read_toc(d);
}
return 1;
}
int burn_drive_grab(struct burn_drive *d, int le)
{
int errcode;
/* ts A61125 - A61202 */
int ret, sose;
if (!d->released) {
burn_print(1, "can't grab - already grabbed\n");
return 0;
}
d->status = BURN_DISC_UNREADY;
errcode = d->grab(d);
if (errcode == 0) {
burn_print(1, "low level drive grab failed\n");
return 0;
}
d->busy = BURN_DRIVE_GRABBING;
if (le)
d->load(d);
d->lock(d);
/* ts A61118 */
d->start_unit(d);
/* ts A61202 : gave bit1 of le a meaning */
sose = d->silent_on_scsi_error;
if (!le)
d->silent_on_scsi_error = 1;
/* ts A61125 : outsourced media state inquiry aspects */
ret = burn_drive_inquire_media(d);
d->silent_on_scsi_error = sose;
d->busy = BURN_DRIVE_IDLE;
return ret;
return 1;
}
struct burn_drive *burn_drive_register(struct burn_drive *d)
@ -344,31 +311,6 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
}
/* ts A61125 : model aspects of burn_drive_release */
int burn_drive_mark_unready(struct burn_drive *d)
{
/* ts A61020 : mark media info as invalid */
d->start_lba= -2000000000;
d->end_lba= -2000000000;
/* ts A61202 */
d->current_profile = -1;
d->current_has_feat21h = 0;
d->current_feat2fh_byte4 = -1;
d->status = BURN_DISC_UNREADY;
if (d->toc_entry != NULL)
free(d->toc_entry);
d->toc_entry = NULL;
d->toc_entries = 0;
if (d->disc != NULL) {
burn_disc_free(d->disc);
d->disc = NULL;
}
return 1;
}
void burn_drive_release(struct burn_drive *d, int le)
{
if (d->released) {
@ -392,14 +334,26 @@ void burn_drive_release(struct burn_drive *d, int le)
return;
}
/* ts A61020 : mark media info as invalid */
d->start_lba= -2000000000;
d->end_lba= -2000000000;
d->unlock(d);
if (le)
d->eject(d);
d->release(d);
d->released = 1;
/* ts A61125 : outsourced model aspects */
burn_drive_mark_unready(d);
d->release(d);
d->status = BURN_DISC_UNREADY;
d->released = 1;
if (d->toc_entry != NULL)
free(d->toc_entry);
d->toc_entry = NULL;
d->toc_entries = 0;
if (d->disc != NULL) {
burn_disc_free(d->disc);
d->disc = NULL;
}
}
@ -455,6 +409,11 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
burn_print(1, "erasing drive %s %s\n", d->idata->vendor,
d->idata->product);
/* ts A60825 : allow on parole to blank appendable CDs */
if ( ! (d->status == BURN_DISC_FULL ||
(d->status == BURN_DISC_APPENDABLE &&
! libburn_back_hack_42) ) )
return;
d->cancel = 0;
d->busy = BURN_DRIVE_ERASING;
d->erase(d, fast);
@ -472,147 +431,12 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1);
while ((d->progress.sector = d->get_erase_progress(d)) > 0 ||
!d->test_unit_ready(d))
!d->test_unit_ready(d))
sleep(1);
d->progress.sector = 0x10000;
/* ts A61125 : update media state records */
burn_drive_mark_unready(d);
burn_drive_inquire_media(d);
d->busy = BURN_DRIVE_IDLE;
}
/*
@param flag: bit0 = fill formatted size with zeros
bit1, bit2 , bit4, bit7 - bit15 are for d->format_unit()
*/
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
{
int ret, buf_secs, err, i, stages = 1, pbase, pfill, pseudo_sector;
off_t num_bufs;
char msg[80];
struct buffer buf;
/* reset the progress */
d->progress.session = 0;
d->progress.sessions = 1;
d->progress.track = 0;
d->progress.tracks = 1;
d->progress.index = 0;
d->progress.indices = 1;
d->progress.start_sector = 0;
d->progress.sectors = 0x10000;
d->progress.sector = 0;
stages = 1 + ((flag & 1) && size > 1024 * 1024);
d->cancel = 0;
d->busy = BURN_DRIVE_FORMATTING;
ret = d->format_unit(d, size, flag & 0xff96); /* forward bits */
if (ret <= 0)
d->cancel = 1;
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1);
while ((pseudo_sector = d->get_erase_progress(d)) > 0 ||
!d->test_unit_ready(d)) {
d->progress.sector = pseudo_sector / stages;
sleep(1);
}
d->sync_cache(d);
if (size <= 0)
goto ex;
/* update media state records */
burn_drive_mark_unready(d);
burn_drive_inquire_media(d);
if (flag & 1) {
/* write size in zeros */;
pbase = 0x8000 + 0x7fff * (stages == 1);
pfill = 0xffff - pbase;
buf_secs = 16; /* Must not be more than 16 */
num_bufs = size / buf_secs / 2048;
if (num_bufs > 0x7fffffff) {
d->cancel = 1;
goto ex;
}
/* <<< */
sprintf(msg,
"Writing %.f sectors of zeros to formatted media",
(double) num_bufs * (double) buf_secs);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
d->buffer = &buf;
memset(d->buffer, 0, sizeof(struct buffer));
d->buffer->bytes = buf_secs * 2048;
d->buffer->sectors = buf_secs;
d->busy = BURN_DRIVE_WRITING;
for (i = 0; i < num_bufs; i++) {
d->nwa = i * buf_secs;
err = d->write(d, d->nwa, d->buffer);
if (err == BE_CANCELLED || d->cancel) {
d->cancel = 1;
break;
}
d->progress.sector = pbase
+ pfill * ((double) i / (double) num_bufs);
}
d->sync_cache(d);
if (d->current_profile == 0x13 || d->current_profile == 0x1a) {
/* DVD-RW or DVD+RW */
d->busy = BURN_DRIVE_CLOSING_SESSION;
/* CLOSE SESSION, 010b */
d->close_track_session(d, 1, 0);
d->busy = BURN_DRIVE_WRITING;
}
}
ex:;
d->progress.sector = 0x10000;
d->busy = BURN_DRIVE_IDLE;
d->buffer = NULL;
}
/* ts A70112 API */
int burn_disc_get_formats(struct burn_drive *d, int *status, off_t *size,
unsigned *bl_sas, int *num_formats)
{
int ret;
*status = 0;
*size = 0;
*bl_sas = 0;
*num_formats = 0;
ret = d->read_format_capacities(d, 0x00);
if (ret <= 0)
return 0;
*status = d->format_descr_type;
*size = d->format_curr_max_size;
*bl_sas = d->format_curr_blsas;
*num_formats = d->num_format_descr;
return 1;
}
/* ts A70112 API */
int burn_disc_get_format_descr(struct burn_drive *d, int index,
int *type, off_t *size, unsigned *tdp)
{
*type = 0;
*size = 0;
*tdp = 0;
if (index < 0 || index >= d->num_format_descr)
return 0;
*type = d->format_descriptors[index].type;
*size = d->format_descriptors[index].size;
*tdp = d->format_descriptors[index].tdp;
return 1;
}
enum burn_disc_status burn_disc_get_status(struct burn_drive *d)
{
/* ts A61007 */
@ -1191,7 +1015,7 @@ int burn_drive_find_scsi_equiv(char *path, char adr[])
ret = burn_drive_obtain_scsi_adr(path, &bus_no, &host_no, &channel_no,
&target_no, &lun_no);
if(ret <= 0) {
sprintf(msg,"burn_drive_obtain_scsi_adr( %s ) returns %d",
sprintf(msg,"burn_drive_obtain_scsi_adr( %s ) returns %d\n",
path, ret);
burn_drive_adr_debug_msg(msg, NULL);
return 0;
@ -1278,7 +1102,7 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed)
}
/** Abort any running drive operation and finish libburn.
/** Abort any running drive operation and finis libburn.
@param patience Maximum number of seconds to wait for drives to finish
@param pacifier_func Function to produce appeasing messages. See
burn_abort_pacifier() for an example.
@ -1376,13 +1200,8 @@ int burn_disc_read_atip(struct burn_drive *d)
0, 0);
return -1;
}
if (d->current_profile == -1 || d->current_is_cd_profile) {
d->read_atip(d);
/* >>> some control of success would be nice :) */
} else {
/* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD */;
return 0;
}
d->read_atip(d);
/* >>> some control of success would be nice :) */
return 1;
}
@ -1408,382 +1227,9 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
0, 0);
return -1;
}
if (o != NULL)
if (o!=NULL)
d->send_write_parameters(d, o);
ret = d->get_nwa(d, trackno, lba, nwa);
return ret;
}
/* ts A70131 : new API function */
int burn_disc_get_msc1(struct burn_drive *d, int *start)
{
int ret, trackno;
if (burn_drive_is_released(d)) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002011b,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Attempt to read track info from ungrabbed drive",
0, 0);
return -1;
}
if (d->busy != BURN_DRIVE_IDLE) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002011c,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Attempt to read track info from busy drive",
0, 0);
return -1;
}
ret = d->read_multi_session_c1(d, &trackno, start);
return ret;
}
/* ts A70213 : new API function */
off_t burn_disc_available_space(struct burn_drive *d,
struct burn_write_opts *o)
{
int lba, nwa;
if (burn_drive_is_released(d))
goto ex;
if (d->busy != BURN_DRIVE_IDLE)
goto ex;
if (o != NULL)
d->send_write_parameters(d, o);
d->get_nwa(d, -1, &lba, &nwa);
ex:;
if (o->start_byte > 0) {
if (o->start_byte > d->media_capacity_remaining)
return 0;
return d->media_capacity_remaining - o->start_byte;
}
return d->media_capacity_remaining;
}
/* ts A61202 : New API function */
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
{
*pno = d->current_profile;
strcpy(name,d->current_profile_text);
return *pno >= 0;
}
/* ts A61223 : New API function */
int burn_drive_wrote_well(struct burn_drive *d)
{
return !d->cancel;
}
/* ts A61226 */
int burn_speed_descriptor_new(struct burn_speed_descriptor **s,
struct burn_speed_descriptor *prev,
struct burn_speed_descriptor *next, int flag)
{
struct burn_speed_descriptor *o;
(*s) = o = malloc(sizeof(struct burn_speed_descriptor));
if (o == NULL)
return -1;
o->source = 0;
o->profile_loaded = -2;
o->profile_name[0] = 0;
o->wrc = 0;
o->exact = 0;
o->mrw = 0;
o->end_lba = -1;
o->write_speed = 0;
o->read_speed = 0;
o->prev = prev;
if (prev != NULL) {
next = prev->next;
prev->next = o;
}
o->next = next;
if (next != NULL)
next->prev = o;
return 1;
}
/* ts A61226 */
/* @param flag bit0= destroy whole next-chain of descriptors */
int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag)
{
struct burn_speed_descriptor *next, *o;
if ((*s) == NULL)
return 0;
if (flag&1)
for (o = (*s); o->prev != NULL; o = o->prev);
else
o = (*s);
next = o->next;
if (next != NULL)
next->prev = o->prev;
if (o->prev != NULL)
o->prev->next = next;
free((char *) (*s));
(*s) = NULL;
if (flag&1)
return burn_speed_descriptor_destroy(&next, flag&1);
return 1;
}
/* ts A61226 */
int burn_speed_descriptor_copy(struct burn_speed_descriptor *from,
struct burn_speed_descriptor *to, int flag)
{
to->source = from->source;
to->profile_loaded = from->profile_loaded;
strcpy(to->profile_name, from->profile_name);
to->wrc = from->wrc;
to->exact = from->exact;
to->mrw = from->mrw;
to->end_lba = from->end_lba;
to->write_speed = from->write_speed;
to->read_speed = from->read_speed;
return 1;
}
/* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */
int burn_mdata_free_subs(struct scsi_mode_data *m)
{
burn_speed_descriptor_destroy(&(m->speed_descriptors), 1);
return 1;
}
/* ts A61226 : API function */
int burn_drive_get_speedlist(struct burn_drive *d,
struct burn_speed_descriptor **speed_list)
{
int ret;
struct burn_speed_descriptor *sd, *csd = NULL;
(*speed_list) = NULL;
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
ret = burn_speed_descriptor_new(&csd, NULL, csd, 0);
if (ret <= 0)
return -1;
burn_speed_descriptor_copy(sd, csd, 0);
}
(*speed_list) = csd;
return (csd != NULL);
}
/* ts A61226 : API function */
int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list)
{
return burn_speed_descriptor_destroy(speed_list, 1);
}
/* ts A70203 : API function */
int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
struct burn_multi_caps **caps, int flag)
{
enum burn_disc_status s;
struct burn_multi_caps *o;
int status, num_formats, ret, type, i;
off_t size;
unsigned dummy;
*caps = NULL;
s = burn_disc_get_status(d);
if(s == BURN_DISC_UNGRABBED)
return -1;
*caps = o = (struct burn_multi_caps *)
malloc(sizeof(struct burn_multi_caps));
if(*caps == NULL)
return -1;
/* Default says nothing is available */
o->multi_session = o->multi_track = 0;
o-> start_adr = 0;
o->start_alignment = o->start_range_low = o->start_range_high = 0;
o->might_do_tao = o->might_do_sao = o->might_do_raw = 0;
o->advised_write_mode = BURN_WRITE_NONE;
o->selected_write_mode = wt;
o->current_profile = d->current_profile;
o->current_is_cd_profile = d->current_is_cd_profile;
if (s != BURN_DISC_BLANK && s != BURN_DISC_APPENDABLE) {
return 0;
} else if (s == BURN_DISC_APPENDABLE &&
(wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) {
return 0;
} else if (wt == BURN_WRITE_RAW && !d->current_is_cd_profile) {
return 0;
} else if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
/* CD-R , CD-RW */
if (d->block_types[BURN_WRITE_TAO]) {
o->multi_session = o->multi_track = 1;
o->might_do_tao = 2;
if (o->advised_write_mode == BURN_WRITE_NONE)
o->advised_write_mode = BURN_WRITE_TAO;
}
if (d->block_types[BURN_WRITE_SAO]) {
o->multi_session = o->multi_track = 1;
o->might_do_sao = 1;
if (o->advised_write_mode == BURN_WRITE_NONE)
o->advised_write_mode = BURN_WRITE_SAO;
}
if (d->block_types[BURN_WRITE_RAW]) {
o->might_do_raw = 1;
if (o->advised_write_mode == BURN_WRITE_NONE)
o->advised_write_mode = BURN_WRITE_RAW;
}
if (wt == BURN_WRITE_RAW)
o->multi_session = o->multi_track = 0;
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , sequential DVD-RW , DVD-R/DL Sequential */
if (s == BURN_DISC_BLANK) {
o->might_do_sao = 1;
o->advised_write_mode = BURN_WRITE_SAO;
}
if (d->current_has_feat21h) {
#ifndef Libburn_dvd_r_dl_multi_no_close_sessioN
if (d->current_profile != 0x15)
#endif
o->multi_session = 1;
o->multi_track = 1;
o->might_do_tao = 2;
o->advised_write_mode = BURN_WRITE_TAO;
}
if (wt == BURN_WRITE_SAO)
o->multi_session = o->multi_track = 0;
} else if (d->current_profile == 0x12 || d->current_profile == 0x13 ||
d->current_profile == 0x1a) {
/* DVD-RAM, overwriteable DVD-RW, DVD+RW */
o->start_adr = 1;
ret = burn_disc_get_formats(d, &status, &size, &dummy,
&num_formats);
if (ret == 1) {
if (status == BURN_FORMAT_IS_FORMATTED)
o->start_range_high = size;
if (d->current_profile == 0x13) {
o->start_alignment = 32 * 1024;
for (i = 0; i < num_formats; i++) {
ret = burn_disc_get_format_descr(d, i,
&type, &size, &dummy);
if (ret <= 0)
continue;
if (type == 0x13) /* expandable */
break;
}
if (i >= num_formats) /* not expandable */
o->start_range_high -= 32 * 1024;
} else {
o->start_alignment = 2 * 1024;
if (d->best_format_size - 2048 >
o->start_range_high)
o->start_range_high =
d->best_format_size - 2048;
}
}
o->might_do_sao = 4;
o->might_do_tao = 2;
o->advised_write_mode = BURN_WRITE_TAO;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
o->multi_session = o->multi_track = 1;
o->might_do_tao = 2;
o->might_do_sao = 1;
o->advised_write_mode = BURN_WRITE_TAO;
} else /* unknown media */
return 0;
if (s == BURN_DISC_APPENDABLE)
o->might_do_sao = o->might_do_raw = 0;
if (wt == BURN_WRITE_TAO && !o->might_do_tao)
return 0;
else if (wt == BURN_WRITE_SAO && !o->might_do_sao)
return 0;
else if (wt == BURN_WRITE_RAW && !o->might_do_raw)
return 0;
return 1;
}
/* ts A70203 : API function */
int burn_disc_free_multi_caps(struct burn_multi_caps **caps)
{
if (*caps == NULL)
return 0;
free((char *) *caps);
*caps = NULL;
return 1;
}
/* ts A70207 : evaluate write mode related peculiarities of a disc
@param flag bit0= fill_up_media is active
*/
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag)
{
struct burn_session *session;
struct burn_track *track;
int i, j, mode, unknown_track_sizes = 0, last_track_is_unknown = 0;
enum burn_disc_status s;
memset((char *) result, 0, sizeof(struct burn_disc_mode_demands));
if (disc == NULL)
return 2;
s = burn_disc_get_status(opts->drive);
if (s == BURN_DISC_APPENDABLE || disc->sessions > 1)
result->will_append = 1;
if (disc->sessions > 1)
result->multi_session = 1;
for (i = 0; i < disc->sessions; i++) {
session = disc->session[i];
if (session->tracks <= 0)
continue;
mode = session->track[0]->mode;
if (session->tracks > 1)
result->multi_track = 1;
for (j = 0; j < session->tracks; j++) {
track = session->track[j];
if (burn_track_is_open_ended(track)) {
if (burn_track_get_default_size(track) > 0) {
if (result->unknown_track_size == 0)
result->unknown_track_size = 2;
} else
result->unknown_track_size = 1;
unknown_track_sizes++;
last_track_is_unknown = 1;
} else
last_track_is_unknown = 0;
if (mode != track->mode)
result->mixed_mode = 1;
if (track->mode == BURN_MODE1) {
result->block_types |= BURN_BLOCK_MODE1;
} else if (track->mode == BURN_AUDIO) {
result->audio = 1;
result->block_types |= BURN_BLOCK_RAW0;
result->exotic_track = 1;
} else {
result->block_types |= opts->block_type;
result->exotic_track = 1;
}
}
}
if (flag&1) {/* fill_up_media will define the size of the last track */
if (unknown_track_sizes == 1 && last_track_is_unknown)
result->unknown_track_size = 0;
}
return (disc->sessions > 0);
}

View File

@ -10,8 +10,6 @@
struct burn_drive;
struct command;
struct mempage;
struct scsi_mode_data;
struct burn_speed_descriptor;
#define LEAD_IN 1
#define GAP 2
@ -71,44 +69,5 @@ int burn_setup_drive(struct burn_drive *d, char *fname);
*/
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
/* ts A61125 : media status aspects of burn_drive_grab() */
int burn_drive_inquire_media(struct burn_drive *d);
/* ts A61125 : model aspects of burn_drive_release */
int burn_drive_mark_unready(struct burn_drive *d);
/* ts A61226 */
int burn_speed_descriptor_new(struct burn_speed_descriptor **s,
struct burn_speed_descriptor *prev,
struct burn_speed_descriptor *next, int flag);
/* ts A61226 */
/* @param flag bit0= destroy whole next-chain of descriptors */
int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag);
/* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */
int burn_mdata_free_subs(struct scsi_mode_data *m);
/* ts A61230 */
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag);
/* ts A70207 : evaluate write mode related peculiarities of a disc */
struct burn_disc_mode_demands {
int multi_session;
int multi_track;
int unknown_track_size; /* 0=known, 1=unknown, 2=unknown+defaulted */
int mixed_mode;
int audio;
int exotic_track;
int block_types;
int will_append; /* because of media state or multi session disc */
};
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag);
#endif /* __DRIVE */

View File

@ -42,7 +42,7 @@ static int file_read(struct burn_source *source,
unsigned char *buffer,
int size)
{
struct burn_source_file *fs = source->data;
struct burn_source_fd *fs = source->data;
return read_full_buffer(fs->datafd, buffer, size);
}
@ -71,24 +71,14 @@ static off_t file_size(struct burn_source *source)
struct stat buf;
struct burn_source_file *fs = source->data;
if (fs->fixed_size > 0)
return fs->fixed_size;
if (fstat(fs->datafd, &buf) == -1)
return (off_t) 0;
/* for now we keep it compatible to the old (int) return value */
if(buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */
return (off_t) 1308622848;
return (off_t) buf.st_size;
}
/* ts A70125 */
static int file_set_size(struct burn_source *source, off_t size)
{
struct burn_source_file *fs = source->data;
fs->fixed_size = size;
return 1;
}
struct burn_source *burn_file_source_new(const char *path, const char *subpath)
{
struct burn_source_file *fs;
@ -113,43 +103,84 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
if (subpath)
fs->subfd = fd2;
/* ts A70125 */
fs->fixed_size = 0;
src = burn_source_new();
src->read = file_read;
if (subpath)
src->read_sub = file_read_sub;
src->get_size = file_size;
src->set_size = file_set_size;
src->free_data = file_free;
src->data = fs;
return src;
}
/* ts A70126 : removed class burn_source_fd in favor of burn_source_file */
/* ------ provisory location for the new source subclass fd --------- */
static off_t fd_get_size(struct burn_source *source)
{
struct stat buf;
struct burn_source_fd *fs = source->data;
if (fs->fixed_size > 0)
return fs->fixed_size;
if (fstat(fs->datafd, &buf) == -1)
return (off_t) 0;
/* for now we keep it compatible to the old (int) return value */
if (buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */
return (off_t) 1308622848;
return buf.st_size;
}
static int fd_read(struct burn_source *source,
unsigned char *buffer,
int size)
{
struct burn_source_fd *fs = source->data;
return read_full_buffer(fs->datafd, buffer, size);
}
static int fd_read_sub(struct burn_source *source,
unsigned char *buffer,
int size)
{
struct burn_source_fd *fs = source->data;
return read_full_buffer(fs->subfd, buffer, size);
}
static void fd_free_data(struct burn_source *source)
{
struct burn_source_fd *fs = source->data;
close(fs->datafd);
if (source->read_sub)
close(fs->subfd);
free(fs);
}
struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
{
struct burn_source_file *fs;
struct burn_source_fd *fs;
struct burn_source *src;
if (datafd == -1)
return NULL;
fs = malloc(sizeof(struct burn_source_file));
fs = malloc(sizeof(struct burn_source_fd));
fs->datafd = datafd;
fs->subfd = subfd;
fs->fixed_size = size;
src = burn_source_new();
src->read = file_read;
src->read = fd_read;
if(subfd != -1)
src->read = file_read_sub;
src->get_size = file_size;
src->set_size = file_set_size;
src->free_data = file_free;
src->read = fd_read_sub;
src->get_size = fd_get_size;
src->free_data = fd_free_data;
src->data = fs;
return src;
}

View File

@ -7,11 +7,16 @@ struct burn_source_file
{
int datafd;
int subfd;
off_t fixed_size;
};
/* ts A70126 : burn_source_file obsoleted burn_source_fd */
/* ------ provisory location for the new source subclass fd --------- */
struct burn_source_fd
{
int datafd;
int subfd;
off_t fixed_size;
};
#endif /* LIBBURN__FILE_H */

View File

@ -50,10 +50,6 @@ static char abort_message_prefix[81] = {"libburn : "};
static pid_t abort_control_pid= 0;
/* ts A70223 : wether implemented untested profiles are supported */
int burn_support_untested_profiles = 0;
/* ts A60925 : ticket 74 */
/** Create the messenger object for libburn. */
int burn_msgs_initialize(void)
@ -77,7 +73,6 @@ int burn_initialize(void)
if (burn_running)
return 1;
burn_support_untested_profiles = 0;
ret = burn_msgs_initialize();
if (ret <= 0)
return 0;
@ -214,38 +209,8 @@ ex:
int burn_builtin_abort_handler(void *handle, int signum, int flag)
{
if(getpid() != abort_control_pid) {
#ifdef Not_yeT
pthread_t thread_id;
/* >>> need better handling of self-induced SIGs
like SIGSEGV or SIGFPE.
Like bonking the control thread if it did not show up
after a short while.
*/
/* >>> if this is a non-fatal signal : return -2 */
thread_id = pthread_self();
/* >>> find thread_id in worker list of async.c */
/* >>> if owning a drive : mark idle and canceled
(can't do anything more) */
usleep(1000000); /* calm down */
/* forward signal to control thread */
if (abort_control_pid>1)
kill(abort_control_pid, signum);
/* >>> ??? end thread */;
#else
usleep(1000000); /* calm down */
if(getpid() != abort_control_pid)
return -2;
#endif /* ! Not_yeT */
}
Cleanup_set_handlers(NULL, NULL, 2);
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
abort_message_prefix);
@ -279,10 +244,3 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
}
/* ts A70223 : API */
void burn_allow_untested_profiles(int yes)
{
burn_support_untested_profiles = !!yes;
}

View File

@ -107,40 +107,22 @@ struct burn_write_opts;
enum burn_write_types
{
/** Packet writing.
currently unsupported, (for DVD Incremental Streaming use TAO)
currently unsupported
*/
BURN_WRITE_PACKET,
/** With CD: Track At Once recording
2s gaps between tracks, no fonky lead-ins
With sequential DVD-R[W]: Incremental Streaming
With DVD-RAM/+RW: Random Writeable (used sequentially)
With overwriteable DVD-RW: Rigid Restricted Overwrite
/** Track At Once recording.
2s gaps between tracks, no fonky lead-ins
*/
BURN_WRITE_TAO,
/** With CD: Session At Once
Block type MUST be BURN_BLOCK_SAO
ts A70122: Currently not capable of mixing data and audio tracks.
With sequential DVD-R[W]: Disc-at-once, DAO
Single session, single track, fixed size mandatory, (-dvd-compat)
/** Session At Once.
block type MUST be BURN_BLOCK_SAO
*/
BURN_WRITE_SAO,
/** With CD: Raw disc at once recording.
all subcodes must be provided by lib or user
only raw block types are supported
/** Raw disc at once recording.
all subcodes must be provided by lib or user
only raw block types are supported
*/
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 won't work.
*/
BURN_WRITE_NONE
BURN_WRITE_RAW
};
/** Data format to send to the drive */
@ -247,26 +229,13 @@ enum burn_drive_status
/** The drive is told to close a track (TAO only) */
BURN_DRIVE_CLOSING_TRACK,
/** The drive is told to close a session (TAO only) */
BURN_DRIVE_CLOSING_SESSION,
/* ts A61223 */
/** The drive is formatting media */
BURN_DRIVE_FORMATTING
BURN_DRIVE_CLOSING_SESSION
};
/** Information about a track on a disc - this is from the q sub channel of the
lead-in area of a disc. The documentation here is very terse.
See a document such as mmc3 for proper information.
CAUTION : This structure is prone to future extension !
Do not restrict your application to unsigned char with any counter like
"session", "point", "pmin", ...
Do not rely on the current size of a burn_toc_entry.
ts A70201 : DVD extension, see below
*/
struct burn_toc_entry
{
@ -290,23 +259,6 @@ struct burn_toc_entry
unsigned char psec;
/** Track start time frames for normal tracks */
unsigned char pframe;
/* Indicates wether extension data are valid and eventually override
older elements in this structure:
bit0= DVD extension is valid
*/
unsigned char extensions_valid;
/* ts A70201 : DVD extension.
If invalid the members are guaranteed to be 0. */
/* Tracks and session numbers are 16 bit. Here are the high bytes. */
unsigned char session_msb;
unsigned char point_msb;
/* pmin, psec, and pframe may be too small if DVD extension is valid */
int start_lba;
/* min, sec, and frame may be too small if DVD extension is valid */
int track_blocks;
};
@ -330,9 +282,6 @@ struct burn_source {
/** Get the size of the source's data */
off_t (*get_size)(struct burn_source *);
/** Set the size of the source's data */
int (*set_size)(struct burn_source *source, off_t size);
/** Clean up the source specific data */
void (*free_data)(struct burn_source *);
@ -461,55 +410,6 @@ struct burn_progress {
unsigned buffer_min_fill;
};
/* ts A61226 */
/** Description of a speed capability as reported by the drive in conjunction
with eventually loaded media. There can be more than one such object per
drive. So they are chained via .next and .prev , where NULL marks the end
of the chain. This list is set up by burn_drive_scan() and gets updated
by burn_drive_grab().
A copy may be obtained by burn_drive_get_speedlist() and disposed by
burn_drive_free_speedlist().
For technical background info see SCSI specs MMC and SPC:
mode page 2Ah (from SPC 5Ah MODE SENSE) , mmc3r10g.pdf , 6.3.11 Table 364
ACh GET PERFORMANCE, Type 03h , mmc5r03c.pdf , 6.8.5.3 Table 312
*/
struct burn_speed_descriptor {
/** Where this info comes from :
0 = misc , 1 = mode page 2Ah , 2 = ACh GET PERFORMANCE */
int source;
/** The media type that was current at the time of report
-2 = state unknown, -1 = no media was loaded , else see
burn_disc_get_profile() */
int profile_loaded;
char profile_name[80];
/** The attributed capacity of appropriate media in logical block units
i.e. 2352 raw bytes or 2048 data bytes. -1 = capacity unknown. */
int end_lba;
/** Speed is given in 1000 bytes/s , 0 = invalid. The numbers
are supposed to be usable with burn_drive_set_speed() */
int write_speed;
int read_speed;
/** Expert info from ACh GET PERFORMANCE and/or mode page 2Ah.
Expect values other than 0 or 1 to get a meaning in future.*/
/* Rotational control: 0 = CLV/default , 1 = CAV */
int wrc;
/* 1 = drive promises reported performance over full media */
int exact;
/* 1 = suitable for mixture of read and write */
int mrw;
/** List chaining. Use .next until NULL to iterate over the list */
struct burn_speed_descriptor *prev;
struct burn_speed_descriptor *next;
};
/** Initialize the library.
This must be called before using any other functions in the library. It
may be called more than once with no effect.
@ -541,7 +441,6 @@ void burn_finish(void);
@param patience Maximum number of seconds to wait for drives to finish
@param pacifier_func If not NULL: a function to produce appeasing messages.
See burn_abort_pacifier() for an example.
@param handle Opaque handle to be used with pacifier_func
@return 1 ok, all went well
0 had to leave a drive in unclean state
<0 severe error, do no use libburn again
@ -589,19 +488,6 @@ void burn_set_verbosity(int level);
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
/* ts A70223 */
/** Allows the use of media types which are implemented in libburn but not yet
tested. The list of those untested profiles is subject to change.
Currently it contains: 0x15 "DVD-R/DL Sequential".
If you really test such media, then please report the outcome on
libburn-hackers@pykix.org
If ever then this call should be done soon after burn_initialize() before
any drive scanning.
@param yes 1=allow all implemented profiles, 0=only tested media (default)
*/
void burn_allow_untested_profiles(int yes);
/* ts A60823 */
/** Aquire a drive with known persistent address.This is the sysadmin friendly
way to open one drive and to leave all others untouched. It bundles
@ -687,9 +573,7 @@ int burn_drive_scan(struct burn_drive_info *drive_infos[],
int burn_drive_info_forget(struct burn_drive_info *drive_info, int force);
/** When no longer needed, free a whole burn_drive_info array which was
returned by burn_drive_scan().
For freeing single drive array elements use burn_drive_info_forget().
/** Free a burn_drive_info array returned by burn_drive_scan
*/
void burn_drive_info_free(struct burn_drive_info drive_infos[]);
@ -731,11 +615,6 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
then it is not decisive and the first enumerated address which matches
the >= 0 parameters is taken as result.
Note: bus and (host,channel) are supposed to be redundant.
@param bus_no "Bus Number" (something like a virtual controller)
@param host_no "Host Number" (something like half a virtual controller)
@param channel_no "Channel Number" (other half of "Host Number")
@param target_no "Target Number" or "SCSI Id" (a device)
@param lun_no "Logical Unit Number" (a sub device)
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
characters size. The persistent address gets copied to it.
@return 1 = success , 0 = failure , -1 = severe error
@ -836,55 +715,11 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive,
@param d The drive to query.
@param o If not NULL: write parameters to be set on drive before query
@param trackno 0=next track to come, >0 number of existing track
@param lba return value: start lba
@param nwa return value: Next Writeable Address
@return 1=nwa is valid , 0=nwa is not valid , -1=error
*/
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
int trackno, int *lba, int *nwa);
/* ts A70131 */
/** Read start lba of the first track in the last complete session.
This is the first parameter of mkisofs option -C. The second parameter
is nwa as obtained by burn_disc_track_lba_nwa() with trackno 0.
@param d The drive to query.
@param start_lba returns the start address of that track
@return <= 0 : failure, 1 = ok
*/
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
/* ts A70213 */
/** Return the best possible estimation of the currently available capacity of
the media. This might depend on particular write option settings. For
inquiring the space with such a set of options, the drive has to be
grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value
from the most recent automatic inquiry (e.g. during last drive grabbing).
An eventual start address from burn_write_opts_set_start_byte() will be
subtracted from the obtained capacity estimation. Negative results get
defaulted to 0.
@param d The drive to query.
@param o If not NULL: write parameters to be set on drive before query
@return number of most probably available free bytes
*/
off_t burn_disc_available_space(struct burn_drive *d,
struct burn_write_opts *o);
/* ts A61202 */
/** Tells the MMC Profile identifier of the loaded media. The drive must be
grabbed in order to get a non-zero result.
libburn currently writes only to profiles 0x09 "CD-R", 0x0a "CD-RW",
0x11 "DVD-R", 0x12 "DVD-RAM", 0x13 "DVD-RW restricted overwrite",
0x14 "DVD-RW Sequential Recording" or 0x1a "DVD+RW".
If enabled by burn_allow_untested_profiles() it also writes to profile
0x15 "DVD-R/DL Sequential Recording".
@param d The drive where the media is inserted.
@param pno Profile Number as of mmc5r03c.pdf, table 89
@param name Profile Name (e.g "CD-RW", unknown profiles have empty name)
@return 1 profile is valid, 0 no profile info available
*/
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]);
/** Tells whether a disc can be erased or not
@return Non-zero means erasable
@ -912,7 +747,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive);
void burn_write_opts_free(struct burn_write_opts *opts);
/** Creates a read_opts struct for reading from the specified drive
must be freed with burn_read_opts_free
must be freed with burn_write_opts_free
@param drive The drive to read from
@return The read_opts
*/
@ -931,83 +766,10 @@ void burn_read_opts_free(struct burn_read_opts *opts);
@param drive The drive with which to erase a disc.
@param fast Nonzero to do a fast erase, where only the disc's headers are
erased; zero to erase the entire disc.
With DVD-RW, fast blanking yields media capable only of DAO.
*/
void burn_disc_erase(struct burn_drive *drive, int fast);
/* ts A70101 - A70112 */
/** Format media for use with libburn. This currently applies to DVD-RW
in state "Sequential Recording" (profile 0014h) which get formatted to
state "Restricted Overwrite" (profile 0013h). DVD+RW can be "de-iced"
by setting bit2 of flag. Other media cannot be formatted yet.
@param drive The drive with the disc to format.
@param size The size in bytes to be used with the format command. It should
be divisible by 32*1024. The effect of this parameter may
depend on the media profile.
@param flag Bitfield for control purposes:
bit0= after formatting, write the given number of zero-bytes
to the media and eventually perform preliminary closing.
bit1= insist in size 0 even if there is a better default known
bit2= format to maximum available size
bit3= -reserved-
bit4= enforce re-format of (partly) formatted media
bit7= MMC expert application mode (else libburn tries to
choose a suitable format type):
bit8 to bit15 contain the index of the format to use. See
burn_disc_get_formats(), burn_disc_get_format_descr().
Acceptable types are: 0x00, 0x10, 0x11, 0x13, 0x15, 0x26.
If bit7 is set, bit4 is set automatically.
*/
void burn_disc_format(struct burn_drive *drive, off_t size, int flag);
/* ts A70112 */
/** Possible formatting status values */
#define BURN_FORMAT_IS_UNFORMATTED 1
#define BURN_FORMAT_IS_FORMATTED 2
#define BURN_FORMAT_IS_UNKNOWN 3
/** Inquire the formatting status, the associated sizes and the number of
available formats. The info is media specific and stems from MMC command
23h READ FORMAT CAPACITY. See mmc5r03c.pdf 6.24 for background details.
Media type can be determined via burn_disc_get_profile().
@param drive The drive with the disc to format.
@param status The current formatting status of the inserted media.
See BURN_FORMAT_IS_* macros. Note: "unknown" is the
legal status for quick formatted, yet unwritten DVD-RW.
@param size The size in bytes associated with status.
unformatted: the maximum achievable size of the media
formatted: the currently formatted capacity
unknown: maximum capacity of drive or of media
@param bl_sas Additional info "Block Length/Spare Area Size".
Expected to be constantly 2048 for non-BD media.
@param num_formats The number of available formats. To be used with
burn_disc_get_format_descr() to obtain such a format
and eventually with burn_disc_format() to select one.
@return 1 reply is valid , <=0 failure
*/
int burn_disc_get_formats(struct burn_drive *drive, int *status, off_t *size,
unsigned *bl_sas, int *num_formats);
/** Inquire parameters of an available media format.
@param drive The drive with the disc to format.
@param index The index of the format item. Beginning with 0 up to reply
parameter from burn_disc_get_formats() : num_formats - 1
@param type The format type. See mmc5r03c.pdf, 6.5, 04h FORMAT UNIT.
0x00=full, 0x10=CD-RW/DVD-RW full, 0x11=CD-RW/DVD-RW grow,
0x15=DVD-RW quick, 0x13=DVD-RW quick grow,
0x26=DVD+RW background
@param size The maximum size in bytes achievable with this format.
@param tdp Type Dependent Parameter. See mmc5r03c.pdf.
@return 1 reply is valid , <=0 failure
*/
int burn_disc_get_format_descr(struct burn_drive *drive, int index,
int *type, off_t *size, unsigned *tdp);
/* ts A61109 : this was and is defunct */
/* ts A61109 : this is defunct */
/** Read a disc from the drive and write it to an fd pair. The drive must be
grabbed successfully BEFORE calling this function. Always ensure that the
drive reports a status of BURN_DISC_FULL before calling this function.
@ -1016,38 +778,9 @@ int burn_disc_get_format_descr(struct burn_drive *drive, int index,
*/
void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
/* ts A70222 */
/** The length of a rejection reasons string for burn_precheck_write() and
burn_write_opts_auto_write_type() .
*/
#define BURN_REASONS_LEN 4096
/* ts A70219 */
/** Examines a completed setup for burn_disc_write() wether it is permissible
with drive and media. This function is called by burn_disc_write() but
an application might be interested in this check in advance.
@param o The options for the writing operation.
@param disc The descrition of the disc to be created
@param reasons Eventually returns a list of rejection reason statements
@param silent 1= do not issue error messages , 0= report problems
@return 1 ok, -1= no recordable media detected, 0= other failure
*/
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int silent);
/* <<< enabling switch for internal usage and trust in this function */
#define Libburn_precheck_write_ruleS 1
/** Write a disc in the drive. The drive must be grabbed successfully before
calling this function. Always ensure that the drive reports a status of
BURN_DISC_BLANK ot BURN_DISC_APPENDABLE before calling this function.
Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
To be set by burn_write_opts_set_write_type().
BURN_DISC_BLANK before calling this function.
@param o The options for the writing operation.
@param disc The struct burn_disc * that described the disc to be created
*/
@ -1060,17 +793,6 @@ void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc);
*/
void burn_drive_cancel(struct burn_drive *drive);
/* ts A61223 */
/** Inquire wether 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
*/
int burn_drive_wrote_well(struct burn_drive *d);
/** Convert a minute-second-frame (MSF) value to sector count
@param m Minute component
@param s Second component
@ -1103,7 +825,7 @@ int burn_msf_to_lba(int m, int s, int f);
*/
void burn_lba_to_msf(int lba, int *m, int *s, int *f);
/** Create a new disc */
/** Create a new disc (for DAO recording)*/
struct burn_disc *burn_disc_create(void);
/** Delete disc and decrease the reference count on all its sessions
@ -1111,7 +833,9 @@ struct burn_disc *burn_disc_create(void);
*/
void burn_disc_free(struct burn_disc *d);
/** Create a new session */
/** Create a new session (For SAO at once recording, or to be added to a
disc for DAO)
*/
struct burn_session *burn_session_create(void);
/** Free a session (and decrease reference count on all tracks inside)
@ -1222,20 +946,6 @@ struct burn_disc *burn_drive_get_disc(struct burn_drive *d);
enum burn_source_status burn_track_set_source(struct burn_track *t,
struct burn_source *s);
/* ts A70218 */
/** Set a default track size to be used only if the track turns out to be of
unpredictable length and if the effective write type demands a fixed size.
This can be useful to enable write types CD SAO or DVD DAO together with
a track source like stdin. If the track source delivers fewer bytes than
announced then the track will be padded up with zeros.
@param t The track to change
@param size The size to set
@return 0=failure 1=sucess
*/
int burn_track_set_default_size(struct burn_track *t, off_t size);
/** Free a burn_source (decrease its refcount and maybe free it)
@param s Source to free
*/
@ -1255,7 +965,6 @@ struct burn_source *burn_file_source_new(const char *path,
*/
struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
/** Tells how long a track will be on disc
>>> NOTE: Not reliable with tracks of undefined length
*/
@ -1281,9 +990,7 @@ void burn_structure_print_disc(struct burn_disc *d);
void burn_structure_print_session(struct burn_session *s);
void burn_structure_print_track(struct burn_track *t);
/** Sets the write type for the write_opts struct.
Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
/** Sets the write type for the write_opts struct
@param opts The write opts to change
@param write_type The write type to use
@param block_type The block type to use
@ -1293,26 +1000,6 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts,
enum burn_write_types write_type,
int block_type);
/* ts A70207 */
/** As an alternative to burn_write_opts_set_write_type() this function tries
to find a suitable write type and block type for a given write job
described by opts and disc. To be used after all other setups have been
made, i.e. immediately before burn_disc_write().
@param opts The nearly complete write opts to change
@param disc The already composed session and track model
@param reasons This text string collects reasons for decision resp. failure
@param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
(is automatically set with bit0)
@return Chosen write type. BURN_WRITE_NONE on failure.
*/
enum burn_write_types burn_write_opts_auto_write_type(
struct burn_write_opts *opts, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int flag);
/** Supplies toc entries for writing - not normally required for cd mastering
@param opts The write opts to change
@param count The number of entries
@ -1357,48 +1044,13 @@ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned cha
/* ts A61106 */
/** Sets the multi flag which eventually marks the emerging session as not
being the last one and thus creating a BURN_DISC_APPENDABLE media.
@param multi 1=media will be appendable, 0=media will be closed (default)
/* Sets the multi flag which eventually marks the emerging session as not being
the last one and thus creating a BURN_DISC_APPENDABLE media.
@param multi 1=media will be appendable, 0=media will be closed (default)
*/
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts A61222 */
/** Sets a start address for writing to media and write modes which allow to
choose this address at all (DVD+RW, DVD-RAM, formatted DVD-RW only for
now). The address is given in bytes. If it is not -1 then a write run
will fail if choice of start address is not supported or if the block
alignment of the address is not suitable for media and write mode.
(Alignment to 32 kB blocks is advised with DVD media.)
@param opts The write opts to change
@param value The address in bytes (-1 = start at default address)
*/
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value);
/* ts A70213 */
/** Caution: still immature and likely to change. Problems arose with
sequential DVD-RW on one drive.
Controls wether the whole available space of the media shall be filled up
by the last track of the last session.
@param opts The write opts to change
@param fill_up_media If 1 : fill up by last track, if 0 = do not fill up
*/
void burn_write_opts_set_fillup(struct burn_write_opts *opts,
int fill_up_media);
/* ts A70303 */
/** Eventually makes libburn ignore the failure of some conformance checks:
- the check wether CD write+block type is supported by the drive
@param opts The write opts to change
@param use_force 1=ignore above checks, 0=refuse work on failed check
*/
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force);
/** Sets whether to read in raw mode or not
@param opts The read opts to change
@param raw_mode If non-zero, reading will be done in raw mode, so that everything in the data tracks on the
@ -1454,9 +1106,7 @@ void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts,
void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts,
unsigned char hardware_error_retries);
/** Gets the maximum write speed for a drive and eventually loaded media.
The return value might change by the media type of already loaded media,
again by call burn_drive_grab() and again by call burn_disc_read_atip().
/** Gets the maximum write speed for a drive
@param d Drive to query
@return Maximum write speed in K/s
*/
@ -1464,9 +1114,8 @@ int burn_drive_get_write_speed(struct burn_drive *d);
/* ts A61021 */
/** Gets the minimum write speed for a drive and eventually loaded media.
The return value might change by the media type of already loaded media,
again by call burn_drive_grab() and again by call burn_disc_read_atip().
/** Gets the minimum write speed for a drive. This might differ from
burn_drive_get_write_speed() only after burn_disc_read_atip()
@param d Drive to query
@return Minimum write speed in K/s
*/
@ -1479,134 +1128,6 @@ int burn_drive_get_min_write_speed(struct burn_drive *d);
*/
int burn_drive_get_read_speed(struct burn_drive *d);
/* ts A61226 */
/** Obtain a copy of the current speed descriptor list. The drive's list gets
updated on various occasions such as burn_drive_grab() but the copy
obtained here stays untouched. It has to be disposed via
burn_drive_free_speedlist() when it is not longer needed. Speeds
may appear several times in the list. The list content depends much on
drive and media type. It seems that .source == 1 applies mostly to CD media
whereas .source == 2 applies to any media.
@param d Drive to query
@param speed_list The copy. If empty, *speed_list gets returned as NULL.
@return 1=success , 0=list empty , <0 severe error
*/
int burn_drive_get_speedlist(struct burn_drive *d,
struct burn_speed_descriptor **speed_list);
/* ts A61226 */
/** Dispose a speed descriptor list copy which was obtained by
burn_drive_get_speedlist().
@param speed_list The list copy. *speed_list gets set to NULL.
@return 1=list disposed , 0= *speedlist was already NULL
*/
int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list);
/* ts A70203 */
/** The reply structure for burn_disc_get_multi_caps()
*/
struct burn_multi_caps {
/* Multi-session capability allows to keep the media appendable after
writing a session. It also guarantees that the drive will be able
to predict and use the appropriate Next Writeable Address to place
the next session on the media without overwriting the existing ones.
It does not guarantee that the selected write type is able to do
an appending session after the next session. (E.g. CD SAO is capable
of multi-session by keeping a disc appendable. But .might_do_sao
will be 0 afterwards, when checking the appendable media.)
1= media may be kept appendable by burn_write_opts_set_multi(o,1)
0= media will not be appendable
*/
int multi_session;
/* Multi-track capability allows to write more than one track source
during a single session. The written tracks can later be found in
libburn's TOC model with their start addresses and sizes.
1= multiple tracks per session are allowed
0= only one track per session allowed
*/
int multi_track;
/* Start-address capability allows to set a non-zero address with
burn_write_opts_set_start_byte(). Eventually this has to respect
.start_alignment and .start_range_low, .start_range_high in this
structure.
1= non-zero start address is allowed
0= only start address 0 is allowed (to depict the drive's own idea
about the appropriate write start)
*/
int start_adr;
/** The alignment for start addresses.
( start_address % start_alignment ) must be 0.
*/
off_t start_alignment;
/** The lowest permissible start address.
*/
off_t start_range_low;
/** The highest addressable start address.
*/
off_t start_range_high;
/** Potential availability of write modes
4= needs no size prediction, not to be chosen automatically
3= needs size prediction, not to be chosen automatically
2= available, no size prediction necessary
1= available, needs exact size prediction
0= not available
With CD media (profiles 0x09 and 0x0a) check also the elements
*_block_types of the according write mode.
*/
int might_do_tao;
int might_do_sao;
int might_do_raw;
/** Generally advised write mode.
Not necessarily the one chosen by burn_write_opts_auto_write_type()
because the burn_disc structure might impose particular demands.
*/
enum burn_write_types advised_write_mode;
/** Write mode as given by parameter wt of burn_disc_get_multi_caps().
*/
enum burn_write_types selected_write_mode;
/** Profile number which was current when the reply was generated */
int current_profile;
/** Wether the current profile indicates CD media. 1=yes, 0=no */
int current_is_cd_profile;
};
/** Allocates a struct burn_multi_caps (see above) and fills it with values
which are appropriate for the drive and the loaded media. The drive
must be grabbed for this call. The returned structure has to be disposed
via burn_disc_free_multi_caps() when no longer needed.
@param d The drive to inquire
@param wt With BURN_WRITE_NONE the best capabilities of all write modes
get returned. If set to a write mode like BURN_WRITE_SAO the
capabilities with that particular mode are returned and the
return value is 0 if the desired mode is not possible.
@param caps returns the info structure
@param flag Bitfield for control purposes (unused yet, submit 0)
@return < 0 : error , 0 : writing seems impossible , 1 : writing possible
*/
int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
struct burn_multi_caps **caps, int flag);
/** Removes from memory a multi session info structure which was returned by
burn_disc_get_multi_caps(). The pointer *caps gets set to NULL.
@param caps the info structure to dispose (note: pointer to pointer)
@return 0 : *caps was already NULL, 1 : memory object was disposed
*/
int burn_disc_free_multi_caps(struct burn_multi_caps **caps);
/** Gets a copy of the toc_entry structure associated with a track
@param t Track to get the entry from
@param entry Struct for the library to fill out
@ -1684,10 +1205,9 @@ int burn_msgs_set_severities(char *queue_severity,
/** Obtain the oldest pending libburn message from the queue which has at
least the given minimum_severity. This message and any older message of
lower severity will get discarded from the queue and is then lost forever.
@param minimum_severity may be one of "NEVER", "FATAL", "SORRY",
"WARNING", "HINT", "NOTE", "UPDATE", "DEBUG", "ALL".
To call with minimum_severity "NEVER" will discard the
whole queue.
Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT",
"NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER"
will discard the whole queue.
@param error_code Will become a unique error code as liste in
libburn/libdax_msgs.h
@param msg_text Must provide at least BURN_MSGS_MESSAGE_LEN bytes.

View File

@ -1,8 +1,7 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006-2007 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
*/
@ -335,36 +334,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002011a (NOTE,HIGH) = Padding up track to minimum size
0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive
0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive
0x0002011d (FATAL,HIGH) = SCSI error on write
0x0002011e (SORRY,HIGH) = Unsuitable media detected
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
0x00020121 (FATAL,HIGH) = Write preparation setup failed
0x00020122 (FATAL,HIGH) = SCSI error on format_unit
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
0x00020125 (SORRY,HIGH) = Write start address not supported
0x00020126 (SORRY,HIGH) = Write start address not properly aligned
0x00020127 (NOTE,HIGH) = Write start address is ...
0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance
0x00020129 (SORRY,HIGH) = Will not format media type
0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities
0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job
0x0002012c (SORRY,HIGH) = Too many logical tracks recorded
0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses
0x0002012e (NOTE,HIGH) = Activated track default size
0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session
0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking
0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive
0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn
0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode
0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO
0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO
0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track
0x00020137 (HINT,HIGH) = TAO would be possible
0x00020138 (FATAL,HIGH) = Cannot reserve track
0x00020139 (SORRY,HIGH) = Write job parameters are unsuitable
0x0002013a (FATAL,HIGH) = No suitable media detected
0x0002011d (FATAL,HIGH) = SCSI error condition on write
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

File diff suppressed because it is too large Load Diff

View File

@ -51,25 +51,4 @@ int mmc_read_buffer_capacity(struct burn_drive *d);
*/
int mmc_setup_drive(struct burn_drive *d);
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format()
and mmc5r03c.pdf, 6.5 FORMAT UNIT */
int mmc_format_unit(struct burn_drive *d, off_t size, int flag);
/* ts A61225 : obtain write speed descriptors via ACh GET PERFORMANCE */
int mmc_get_write_performance(struct burn_drive *d);
/* ts A61229 : outsourced from spc_select_write_params() */
/* Note: Page data is not zeroed here to allow preset defaults. Thus
memset(pd, 0, 2 + d->mdata->write_page_length);
is the eventual duty of the caller.
*/
int mmc_compose_mode_page_5(struct burn_drive *d,
const struct burn_write_opts *o,
unsigned char *pd);
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
#endif /*__MMC*/

View File

@ -21,10 +21,6 @@ struct burn_source *burn_null_source_new(void)
src->read_sub = NULL;
src->get_size = 0;
/* ts A70126 */
src->set_size = NULL;
src->free_data = NULL;
src->data = NULL;
return src;

View File

@ -1,6 +1,5 @@
#include "libburn.h"
#include "options.h"
#include "drive.h"
#include "transport.h"
/* ts A61007 */
@ -33,11 +32,6 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->simulate = 0;
opts->underrun_proof = drive->mdata->underrun_proof;
opts->perform_opc = 1;
opts->obs = -1;
opts->obs_pad = 0;
opts->start_byte = -1;
opts->fill_up_media = 0;
opts->force_is_set = 0;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
@ -158,7 +152,6 @@ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
memcpy(opts->mediacatalog, &mediacatalog, 13);
}
/* ts A61106 */
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
{
@ -166,197 +159,6 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
}
/* ts A61222 */
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
{
opts->start_byte = value;
}
/* ts A70207 API */
/** @param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
*/
enum burn_write_types burn_write_opts_auto_write_type(
struct burn_write_opts *opts, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int flag)
{
struct burn_multi_caps *caps = NULL;
struct burn_drive *d = opts->drive;
struct burn_disc_mode_demands demands;
enum burn_write_types wt;
int ret, would_do_sao = 0;
char *reason_pt;
reasons[0] = 0;
if (d->status != BURN_DISC_BLANK &&
d->status != BURN_DISC_APPENDABLE){
if (d->status == BURN_DISC_FULL)
strcat(reasons, "MEDIA: closed or not recordable, ");
else
strcat(reasons,"MEDIA: no writeable media detected, ");
if (!(flag & 3))
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002013a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"No suitable media detected", 0, 0);
return BURN_WRITE_NONE;
}
ret = burn_disc_get_write_mode_demands(disc, opts, &demands,
!!opts->fill_up_media);
if (ret <= 0) {
strcat(reasons, "cannot recognize job demands, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if (demands.exotic_track && !d->current_is_cd_profile) {
if (demands.audio)
strcat(reasons, "audio track prohibited by non-CD, ");
else
strcat(reasons, "exotic track prohibited by non-CD, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if ((flag & 1) && opts->write_type != BURN_WRITE_SAO)
goto try_tao;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "SAO: ");
if (d->status != BURN_DISC_BLANK) {
strcat(reasons, "write type SAO works only on blank media, ");
goto try_tao;
}
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_SAO, &caps, 0);
if (ret < 0) {
no_caps:;
strcat(reasons, "cannot inquire write mode capabilities, ");
{wt = BURN_WRITE_NONE; goto ex;}
} else if (ret == 0) {
strcat(reasons, "no SAO offered by drive and media, ");
goto no_sao;
}
if ((opts->multi || demands.multi_session) &&
!caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.will_append)
strcat(reasons, "appended session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.unknown_track_size == 1 &&
(caps->might_do_sao == 1 || caps->might_do_sao == 3))
strcat(reasons, "track size unpredictable, ");
if (demands.mixed_mode)
strcat(reasons, "tracks of different modes mixed, ");
if (demands.exotic_track && !d->current_is_cd_profile)
strcat(reasons, "non-data track on non-cd, ");
else if (d->current_is_cd_profile)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (d->current_is_cd_profile && opts->fill_up_media)
strcat(reasons, "cd sao cannot do media fill up yet, ");
if (strcmp(reason_pt, "SAO: ") != 0)
goto no_sao;
would_do_sao = 1;
if (demands.unknown_track_size == 2 && (!(flag & 1)) &&
(caps->might_do_sao == 1 || caps->might_do_sao == 3)) {
strcat(reasons, "would have to use default track sizes, ");
goto no_sao;
} else if (caps->might_do_sao >= 3 && !(flag & 1))
goto try_tao;
do_sao:;
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_SAO, BURN_BLOCK_SAO);
{wt = BURN_WRITE_SAO; goto ex;}
no_sao:;
try_tao:;
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
goto try_raw;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "TAO: ");
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0);
if (ret < 0)
goto no_caps;
if (ret == 0) {
strcat(reasons, "no TAO offered by drive and media, ");
goto no_tao;
}
if ((opts->multi || demands.multi_session) && !caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.exotic_track && !d->current_is_cd_profile)
strcat(reasons, "non-data track on non-cd, ");
if (d->current_is_cd_profile && !opts->force_is_set)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "TAO: ") != 0)
goto no_tao;
/* ( TAO data/audio block size will be handled automatically ) */
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1);
{wt = BURN_WRITE_TAO; goto ex;}
no_tao:;
if (would_do_sao && !(flag & 1))
goto do_sao;
if (!d->current_is_cd_profile)
goto no_write_mode;
try_raw:;
if ((flag & 1) && opts->write_type != BURN_WRITE_RAW)
goto no_write_mode;
if (!(flag & 1)) /* For now: no automatic raw write modes */
goto no_write_mode;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "RAW: ");
if (!d->current_is_cd_profile)
strcat(reasons, "write type RAW prohibited by non-cd, ");
else if (d->status != BURN_DISC_BLANK)
strcat(reasons, "write type RAW works only on blank media, ");
else if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "RAW: ") != 0)
goto no_write_mode;
/* For now: no setting of raw write modes */
{wt = BURN_WRITE_RAW; goto ex;}
no_write_mode:;
wt = BURN_WRITE_NONE;
ex:;
burn_disc_free_multi_caps(&caps);
if (wt == BURN_WRITE_NONE && !(flag & 3)) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012b,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive offers no suitable write mode with this job",
0, 0);
}
return wt;
}
/* ts A70213 : new API function */
void burn_write_opts_set_fillup(struct burn_write_opts *opts,int fill_up_media)
{
opts->fill_up_media = !!fill_up_media;
return;
}
/* ts A70303: API */
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
{
opts->force_is_set = !!use_force;
}
void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw)
{

View File

@ -32,23 +32,6 @@ struct burn_write_opts
/** Perform calibration of the drive's laser before beginning the
write. */
unsigned int perform_opc:1;
/* ts A61219 : Output block size to trigger buffer flush if hit.
-1 with CD, 32 kB with DVD */
int obs;
int obs_pad; /* 1=pad up last block to obs */
/* ts A61222 : Start address for media which allow a choice */
off_t start_byte;
/* ts A70213 : Wether to fill up the available space on media */
int fill_up_media;
/* ts A70303 : Wether to override conformance checks:
- the check wether CD write+block type is supported by the drive
*/
int force_is_set;
/** A disc can have a media catalog number */
int has_mediacatalog;
unsigned char mediacatalog[13];

View File

@ -7,6 +7,10 @@
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
*/
#ifndef BURN_OS_H_INCLUDED
#define BURN_OS_H_INCLUDED 1
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man 7 signal.)
*/
@ -33,24 +37,28 @@
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
SIGKILL, SIGCHLD, SIGSTOP, SIGURG
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 5
#define BURN_OS_NON_SIGNAL_COUNT 4
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536/2
/** To hold all state information of BSD device enumeration
which are now local in sg_enumerate() . So that sg_give_next_adr()
can work in BSD and sg_enumerate() can use it.
*/
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
struct burn_drive_enumeration_state; \
typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
struct burn_drive_enumeration_state { \
union ccb ccb; \
int bufsize, fd; \
unsigned int i; \
int skip_device; \
}; \
typedef struct burn_drive_enumeration_state burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
@ -59,3 +67,6 @@ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
struct cam_device* cam;
#endif /* ! BURN_OS_H_INCLUDED */

View File

@ -34,14 +34,13 @@
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
SIGKILL, SIGCHLD, SIGSTOP, SIGURG
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 5
#define BURN_OS_NON_SIGNAL_COUNT 4
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536

View File

@ -217,8 +217,7 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
return NULL;
seclen += burn_subcode_length(outmode);
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
if (out->bytes + (seclen) > BUFFER_SIZE || out->bytes == opts->obs) {
if (out->bytes + (seclen) >= BUFFER_SIZE) {
int err;
err = d->write(d, d->nwa, out);
if (err == BE_CANCELLED)
@ -643,10 +642,7 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
return 2;
}
/* ts A61219 : allow track without .entry */
if (t->entry == NULL)
;
else if (!t->source->read_sub)
if (!t->source->read_sub)
subcode_user(o, subs, t->entry->point,
t->entry->control, 1, &t->isrc, psub);
else if (!t->source->read_sub(t->source, subs, 96))

View File

@ -1,5 +1,19 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Revives old enumerate_common(). New version delegates much work
to methods in drive, mmc, spc, and sbc .
*/
#define Scsi_freebsd_make_own_enumeratE 1
/* Revives old scsi_enumerate_drives(). New version delegates most work to
sg_give_next_adr().
*/
#define Scsi_freebsd_old_scsi_enumeratE 1
#include <assert.h>
#include <errno.h>
#include <unistd.h>
@ -31,13 +45,6 @@
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
struct burn_drive_enumeration_state {
int fd;
union ccb ccb;
unsigned int i;
int skip_device;
};
static void enumerate_common(char *fname, int bus_no, int host_no,
int channel_no, int target_no, int lun_no);
@ -50,20 +57,33 @@ int burn_drive_is_banned(char *device_address);
int mmc_function_spy(char * text);
#ifdef Scsi_freebsd_old_scsi_enumeratE
int sg_give_next_adr(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
return (0);
}
int sg_is_enumerable_adr(char* adr)
{
return (0);
}
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no)
{
return (0);
}
#else /* Scsi_freebsd_old_scsi_enumeratE */
/* ts A61021 : Moved most code from scsi_enumerate_drives under
sg_give_next_adr() */
/* Some helper functions for scsi_give_next_adr() */
static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
static int sg_init_enumerator(burn_drive_enumerator_t *idx)
{
struct burn_drive_enumeration_state *idx;
int bufsize;
idx = malloc(sizeof(*idx));
if (idx == NULL) {
warnx("can't malloc memory for enumerator");
return -1;
}
idx->skip_device = 0;
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
@ -78,13 +98,12 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
bufsize = sizeof(struct dev_match_result) * 100;
idx->ccb.cdm.match_buf_len = bufsize;
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
idx->bufsize = sizeof(struct dev_match_result) * 100;
idx->ccb.cdm.match_buf_len = idx->bufsize;
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
if (idx->ccb.cdm.matches == NULL) {
warnx("can't malloc memory for matches");
close(idx->fd);
free(idx);
return -1;
}
idx->ccb.cdm.num_matches = 0;
@ -97,28 +116,12 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
idx->ccb.cdm.num_patterns = 0;
idx->ccb.cdm.pattern_buf_len = 0;
*idx_ = idx;
return 1;
}
static void sg_destroy_enumerator(burn_drive_enumerator_t *idx_)
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
{
struct burn_drive_enumeration_state *idx = *idx_;
if(idx->fd != -1)
close(idx->fd);
free(idx->ccb.cdm.matches);
free(idx);
*idx_ = NULL;
}
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
{
struct burn_drive_enumeration_state *idx = *idx_;
/*
* We do the ioctl multiple times if necessary, in case there are
* more than 100 nodes in the EDT.
@ -149,94 +152,95 @@ static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
@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_,
int sg_give_next_adr(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
struct burn_drive_enumeration_state *idx;
int ret;
if (initialize == 1) {
ret = sg_init_enumerator(idx_);
ret = sg_init_enumerator(idx);
if (ret<=0)
return ret;
} else if (initialize == -1) {
sg_destroy_enumerator(idx_);
if(idx->fd != -1)
close(idx->fd);
idx->fd = -1;
return 0;
}
idx = *idx_;
do {
if (idx->i >= idx->ccb.cdm.num_matches) {
ret = sg_next_enumeration_buffer(idx_);
if (ret<=0)
return -1;
idx->i = 0;
} else
(idx->i)++;
try_item:; /* This spaghetti loop keeps the number of tabs small */
while (idx->i < idx->ccb.cdm.num_matches) {
switch (idx->ccb.cdm.matches[idx->i].type) {
case DEV_MATCH_BUS:
break;
case DEV_MATCH_DEVICE: {
struct device_match_result* result;
/* Loop content from old scsi_enumerate_drives() */
result = &(idx->ccb.cdm.matches[idx->i].result.device_result);
if (result->flags & DEV_RESULT_UNCONFIGURED)
idx->skip_device = 1;
else
idx->skip_device = 0;
break;
}
case DEV_MATCH_PERIPH: {
struct periph_match_result* result;
while (idx->i >= idx->ccb.cdm.num_matches) {
ret = sg_next_enumeration_buffer(idx);
if (ret<=0)
return -1;
if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP)
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) )
return 0;
idx->i = 0;
}
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
if (idx->skip_device ||
strcmp(result->periph_name, "pass") == 0)
break;
ret = snprintf(adr, adr_size, "/dev/%s%d",
result->periph_name, result->unit_number);
if(ret >= adr_size)
return -1;
switch (idx->ccb.cdm.matches[idx->i].type) {
case DEV_MATCH_BUS:
break;
case DEV_MATCH_DEVICE: {
struct device_match_result* result;
/* Found next enumerable address */
return 1;
result = &(idx->ccb.cdm.matches[i].result.device_result);
if (result->flags & DEV_RESULT_UNCONFIGURED)
idx->skip_device = 1;
else
idx->skip_device = 0;
break;
}
case DEV_MATCH_PERIPH: {
struct periph_match_result* result;
char buf[64];
}
default:
/* printf(stderr, "unknown match type\n"); */
break;
}
(idx->i)++;
}
} while ((idx->ccb.ccb_h.status == CAM_REQ_CMP)
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE));
result = &(idx->ccb.cdm.matches[i].result.periph_result);
if (idx->skip_device ||
strcmp(result->periph_name, "pass") == 0)
break;
snprintf(buf, sizeof (buf), "/dev/%s%d",
result->periph_name, result->unit_number);
if(adr_size <= strlen(buf)
return -1;
strcpy(adr, buf);
return 0;
/* Found next enumerable address */
return 1;
}
default:
/* printf(stderr, "unknown match type\n"); */
break;
}
(idx->i)++;
goto try_item; /* Regular function exit is return 1 above */
}
int sg_is_enumerable_adr(char* adr)
{
burn_drive_enumerator_t idx;
int ret;
int initialize = 1;
char buf[64];
ret = sg_init_enumerator(&idx);
if (ret <= 0)
return 0;
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
break;
if (strcmp(adr, buf) == 0) {
sg_destroy_enumerator(&idx);
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
}
sg_destroy_enumerator(&idx);
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return (0);
}
@ -248,32 +252,32 @@ 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 ret;
int initialize = 1;
char buf[64];
struct periph_match_result* result;
ret = sg_init_enumerator(&idx);
if (ret <= 0)
return 0;
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (strcmp(path, buf) == 0) {
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
*bus_no = result->path_id;
*host_no = result->path_id;
*channel_no = 0;
*target_no = result->target_id;
*lun_no = result->target_lun;
sg_destroy_enumerator(&idx);
return 1;
}
break;
if (strcmp(adr, buf) != 0)
continue;
result = &(idx->ccb.cdm.matches[i].result.periph_result);
*bus_no = result->path_id;
*host_no = result->path_id;
*channel_no = 0;
*target_no = result->target_id
*lun_no = result->target_lun;
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
sg_destroy_enumerator(&idx);
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return (0);
}
#endif /* ! Scsi_freebsd_old_scsi_enumeratE */
int sg_close_drive(struct burn_drive * d)
{
@ -291,28 +295,125 @@ int sg_drive_is_open(struct burn_drive * d)
int scsi_enumerate_drives(void)
{
burn_drive_enumerator_t idx;
int ret;
char buf[64];
struct periph_match_result* result;
ret = sg_init_enumerator(&idx);
if (ret <= 0)
return 0;
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
if (ret <= 0)
break;
if (burn_drive_is_banned(buf))
continue;
result = &idx->ccb.cdm.matches[idx->i].result.periph_result;
enumerate_common(buf, result->path_id, result->path_id,
0, result->target_id,
result->target_lun);
#ifdef Scsi_freebsd_old_scsi_enumeratE
union ccb ccb;
int bufsize, fd;
unsigned int i;
int skip_device = 0;
if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
warn("couldn't open %s", XPT_DEVICE);
return;
}
sg_destroy_enumerator(&idx);
return 1;
bzero(&ccb, sizeof(union ccb));
ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
ccb.ccb_h.func_code = XPT_DEV_MATCH;
bufsize = sizeof(struct dev_match_result) * 100;
ccb.cdm.match_buf_len = bufsize;
ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
if (ccb.cdm.matches == NULL) {
warnx("can't malloc memory for matches");
close(fd);
return;
}
ccb.cdm.num_matches = 0;
/*
* We fetch all nodes, since we display most of them in the default
* case, and all in the verbose case.
*/
ccb.cdm.num_patterns = 0;
ccb.cdm.pattern_buf_len = 0;
/*
* We do the ioctl multiple times if necessary, in case there are
* more than 100 nodes in the EDT.
*/
do {
if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
warn("error sending CAMIOCOMMAND ioctl");
break;
}
if ((ccb.ccb_h.status != CAM_REQ_CMP)
|| ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
&& (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
warnx("got CAM error %#x, CDM error %d\n",
ccb.ccb_h.status, ccb.cdm.status);
break;
}
for (i = 0; i < ccb.cdm.num_matches; i++) {
switch (ccb.cdm.matches[i].type) {
case DEV_MATCH_BUS:
break;
case DEV_MATCH_DEVICE: {
struct device_match_result* result;
result = &ccb.cdm.matches[i].result.device_result;
if (result->flags & DEV_RESULT_UNCONFIGURED)
skip_device = 1;
else
skip_device = 0;
break;
}
case DEV_MATCH_PERIPH: {
struct periph_match_result* result;
char buf[64];
result = &ccb.cdm.matches[i].result.periph_result;
if (skip_device || strcmp(result->periph_name, "pass") == 0)
break;
snprintf(buf, sizeof (buf), "/dev/%s%d", result->periph_name, result->unit_number);
/* ts A51221 */
if (burn_drive_is_banned(buf))
break;
enumerate_common(buf, result->path_id, result->path_id, 0,
result->target_id, result->target_lun);
break;
}
default:
fprintf(stdout, "unknown match type\n");
break;
}
}
} while ((ccb.ccb_h.status == CAM_REQ_CMP)
&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
close(fd);
#else /* Scsi_freebsd_old_scsi_enumeratE */
burn_drive_enumerator_t idx;
int initialize = 1;
char buf[64];
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (burn_drive_is_banned(buf))
continue;
enumerate_common(buf, idx.result->path_id, idx.result->path_id,
0, idx.result->target_id,
idx.result->target_lun);
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
#endif /* ! Scsi_freebsd_old_scsi_enumeratE */
}
@ -450,10 +551,7 @@ int sg_grab(struct burn_drive *d)
mmc_function_spy("sg_grab");
if (burn_drive_is_open(d)) {
d->released = 0;
return 1;
}
assert(d->cam == NULL);
cam = cam_open_device(d->devname, O_RDWR);
if (cam == NULL) {
@ -493,7 +591,6 @@ int sg_release(struct burn_drive *d)
mmc_function_spy("sg_release ----------- closing.");
sg_close_drive(d);
d->released = 1;
return 0;
}

View File

@ -74,70 +74,6 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
#include <scsi/sg.h>
#include <scsi/scsi.h>
/* ts A61211 : to recognize CD devices on /dev/sr* */
#include <linux/cdrom.h>
/* ts A61211 : preparing for exploration of recent Linux ATA adventures */
/** PORTING : Device file families for bus scanning and drive access.
Both device families must support the following ioctls:
SG_IO,
SG_GET_SCSI_ID
SCSI_IOCTL_GET_BUS_NUMBER
SCSI_IOCTL_GET_IDLUN
as well as mutual exclusively locking with open(O_EXCL).
If a device family is left empty, then it will not be used.
To avoid misunderstandings: both families are used via identical
transport methods as soon as a device file is accepted as CD drive
by the family specific function <family>_enumerate().
One difference remains throughout usage: Host,Channel,Id,Lun and Bus
address parameters of ATA devices are considered invalid.
*/
/* Set this to 1 in order to get on stderr messages from sg_enumerate() */
static int linux_sg_enumerate_debug = 0;
/* The device file family to use for (emulated) generic SCSI transport.
This must be a printf formatter with one single placeholder for int
in the range of 0 to 31 . The resulting addresses must provide SCSI
address parameters Host, Channel, Id, Lun and also Bus.
E.g.: "/dev/sg%d"
*/
/* NEW INFO: If hard disks at /dev/sr allow ioctl(CDROM_DRIVE_STATUS), they
are in danger.
If you want it less dangerous:
#undef CDROM_DRIVE_STATUS
but then you might need linux_sg_accept_any_type = 1 which
is _more dangerous_.
*/
/* !!! DO NOT SET TO sr%d UNLESS YOU PROTECTED ALL INDISPENSIBLE DEVICES
by chmod -rw . A test wether non-CD devices are properly excluded would
be well needed though. Heroic disks, scanners, etc. wanted !!! */
static char linux_sg_device_family[80] = {"/dev/sg%d"};
/* Set this to 1 in order to accept any TYPE_* (see scsi/scsi.h) */
/* NEW INFO: Try with 0 first. There is hope via CDROM_DRIVE_STATUS. */
/* !!! DO NOT SET TO 1 UNLESS YOU PROTECTED ALL INDISPENSIBLE DEVICES
chmod -rw !!! */
static int linux_sg_accept_any_type = 0;
/* The device file family to use for SCSI transport over ATA.
This must be a printf formatter with one single placeholder for a
_single_ char in the range of 'a' to 'z'. This placeholder _must_ be
at the end of the formatter string.
E.g. "/dev/hd%c"
*/
static char linux_ata_device_family[80] = {"/dev/hd%c"};
/* Set this to 1 in order to get on stderr messages from ata_enumerate()
*/
static int linux_ata_enumerate_verbous = 0;
/** PORTING : ------ libburn portable headers and definitions ----- */
@ -349,11 +285,7 @@ static int sg_open_scsi_siblings(char *path, int driveno,
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
char msg[161], fname[81];
static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d",
"/dev/sg%d", ""};
if (linux_sg_device_family[0] == 0)
return 1;
static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d", ""};
if(host_no < 0 || id_no < 0 || channel_no < 0 || lun_no < 0)
return(2);
@ -361,8 +293,6 @@ static int sg_open_scsi_siblings(char *path, int driveno,
sg_release_siblings(sibling_fds, sibling_count);
for (tld = 0; tldev[tld][0] != 0; tld++) {
if (strcmp(tldev[tld], linux_sg_device_family)==0)
continue;
for (i = 0; i < 32; i++) {
sprintf(fname, tldev[tld], i);
ret = sg_obtain_scsi_adr(fname, &i_bus_no, &i_host_no,
@ -397,7 +327,7 @@ static int sg_open_scsi_siblings(char *path, int driveno,
(*sibling_count)++;
}
}
return 1;
return(1);
failed:;
sg_release_siblings(sibling_fds, sibling_count);
return 0;
@ -412,39 +342,20 @@ static void ata_enumerate(void)
int i, fd;
char fname[10];
if (linux_ata_enumerate_verbous)
fprintf(stderr, "libburn_debug: linux_ata_device_family = %s\n",
linux_ata_device_family);
if (linux_ata_device_family[0] == 0)
return;
for (i = 0; i < 26; i++) {
sprintf(fname, linux_ata_device_family, 'a' + i);
if (linux_ata_enumerate_verbous)
fprintf(stderr, "libburn_debug: %s : ", fname);
sprintf(fname, "/dev/hd%c", 'a' + i);
/* ts A51221 */
if (burn_drive_is_banned(fname)) {
if (linux_ata_enumerate_verbous)
fprintf(stderr, "not in whitelist\n");
if (burn_drive_is_banned(fname))
continue;
}
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) {
if (linux_ata_enumerate_verbous)
fprintf(stderr,"open failed, errno=%d '%s'\n",
errno, strerror(errno));
if (fd == -1)
continue;
}
/* found a drive */
ioctl(fd, HDIO_GET_IDENTITY, &tm);
/* not atapi */
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
if (linux_ata_enumerate_verbous)
fprintf(stderr, "not marked as ATAPI\n");
sg_close_drive_fd(fname, -1, &fd, 0);
continue;
}
@ -452,22 +363,11 @@ static void ata_enumerate(void)
/* if SG_IO fails on an atapi device, we should stop trying to
use hd* devices */
if (sgio_test(fd) == -1) {
if (linux_ata_enumerate_verbous)
fprintf(stderr,
"FATAL: sgio_test() failed: errno=%d '%s'\n",
errno, strerror(errno));
sg_close_drive_fd(fname, -1, &fd, 0);
return;
}
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
if (linux_ata_enumerate_verbous)
fprintf(stderr,
"cannot close properly, errno=%d '%s'\n",
errno, strerror(errno));
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0)
continue;
}
if (linux_ata_enumerate_verbous)
fprintf(stderr, "accepting as drive without SCSI address\n");
enumerate_common(fname, -1, -1, -1, -1, -1);
}
}
@ -478,66 +378,21 @@ static void sg_enumerate(void)
{
struct sg_scsi_id sid;
int i, fd, sibling_fds[LIBBURN_SG_MAX_SIBLINGS], sibling_count= 0, ret;
int sid_ret = 0;
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
int bus_no = -1;
char fname[10];
if (linux_sg_enumerate_debug)
fprintf(stderr, "libburn_debug: linux_sg_device_family = %s\n",
linux_sg_device_family);
if (linux_sg_device_family[0] == 0)
return;
for (i = 0; i < 32; i++) {
sprintf(fname, linux_sg_device_family, i);
if (linux_sg_enumerate_debug)
fprintf(stderr, "libburn_debug: %s : ", fname);
sprintf(fname, "/dev/sg%d", i);
/* ts A51221 */
if (burn_drive_is_banned(fname)) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "not in whitelist\n");
if (burn_drive_is_banned(fname))
continue;
}
/* ts A60927 */
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "open failed, errno=%d '%s'\n",
errno, strerror(errno));
if (fd == -1)
continue;
}
/* found a drive */
sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid);
if (sid_ret == -1) {
sid.scsi_id = -1; /* mark SCSI address as invalid */
if(linux_sg_enumerate_debug)
fprintf(stderr,
"ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ",
errno, strerror(errno));
#ifdef CDROM_DRIVE_STATUS
/* ts A61211 : not widening old acceptance range */
if (strcmp(linux_sg_device_family,"/dev/sg%d") != 0) {
/* http://developer.osdl.org/dev/robustmutexes/
src/fusyn.hg/Documentation/ioctl/cdrom.txt */
sid_ret = ioctl(fd, CDROM_DRIVE_STATUS, 0);
if(linux_sg_enumerate_debug)
fprintf(stderr,
"ioctl(CDROM_DRIVE_STATUS) = %d , ",
sid_ret);
if (sid_ret != -1 && sid_ret != CDS_NO_INFO)
sid.scsi_type = TYPE_ROM;
else
sid_ret = -1;
}
#endif /* CDROM_DRIVE_STATUS */
}
ioctl(fd, SG_GET_SCSI_ID, &sid);
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
/* Hearsay A61005 */
@ -546,37 +401,10 @@ static void sg_enumerate(void)
#endif
if (sg_close_drive_fd(fname, -1, &fd,
sid.scsi_type == TYPE_ROM ) <= 0) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"cannot close properly, errno=%d '%s'\n",
errno, strerror(errno));
sid.scsi_type == TYPE_ROM ) <= 0)
continue;
}
if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM)
&& !linux_sg_accept_any_type) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "sid.scsi_type = %d (!= TYPE_ROM)\n",
sid.scsi_type);
if (sid.scsi_type != TYPE_ROM)
continue;
}
if (sid_ret == -1 || sid.scsi_id < 0) {
/* ts A61211 : employ a more general ioctl */
ret = sg_obtain_scsi_adr(fname, &bus_no, &host_no,
&channel_no, &target_no, &lun_no);
if (ret>0) {
sid.host_no = host_no;
sid.channel = channel_no;
sid.scsi_id = target_no;
sid.lun = lun_no;
} else {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"sg_obtain_scsi_adr() failed\n");
continue;
}
}
/* ts A60927 : trying to do locking with growisofs */
if(burn_sg_open_o_excl>1) {
@ -585,8 +413,6 @@ static void sg_enumerate(void)
sid.host_no, sid.channel,
sid.scsi_id, sid.lun);
if (ret<=0) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "cannot lock siblings\n");
sg_handle_busy_device(fname, 0);
continue;
}
@ -599,10 +425,6 @@ static void sg_enumerate(void)
#else
bus_no = sid.host_no;
#endif
if (linux_sg_enumerate_debug)
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
sid.host_no, sid.channel, sid.scsi_id, sid.lun,
bus_no);
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
sid.scsi_id, sid.lun);
}
@ -691,18 +513,13 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
int sg_give_next_adr(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
/* os-linux.h : typedef int burn_drive_enumerator_t; */
/* sg.h : typedef int burn_drive_enumerator_t; */
static int sg_limit = 32, ata_limit = 26;
int baseno = 0;
if (initialize == -1)
return 0;
if (linux_sg_device_family[0] == 0)
sg_limit = 0;
if (linux_ata_device_family[0] == 0)
ata_limit = 0;
if (initialize == 1)
*idx = -1;
(*idx)++;
@ -710,7 +527,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
goto next_ata;
if (adr_size < 10)
return -1;
sprintf(adr, linux_sg_device_family, *idx);
sprintf(adr, "/dev/sg%d", *idx);
return 1;
next_ata:;
baseno += sg_limit;
@ -718,7 +535,7 @@ next_ata:;
goto next_nothing;
if (adr_size < 9)
return -1;
sprintf(adr, linux_ata_device_family, 'a' + (*idx - baseno));
sprintf(adr, "/dev/hd%c", 'a' + (*idx - baseno));
return 1;
next_nothing:;
baseno += ata_limit;
@ -1034,15 +851,14 @@ ex:;
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no)
{
int fd, ret, l;
int fd, ret;
struct my_scsi_idlun {
int x;
int host_unique_id;
};
struct my_scsi_idlun idlun;
l = strlen(linux_ata_device_family) - 2;
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
if (strncmp(path, "/dev/hd", 7) == 0
&& path[7] >= 'a' && path[7] <= 'z' && path[8] == 0)
return 0; /* on RIP 14 all hdx return SCSI adr 0,0,0,0 */

View File

@ -15,7 +15,6 @@
#include <stdlib.h>
#include "libburn.h"
#include "transport.h"
#include "spc.h"
#include "mmc.h"
@ -133,13 +132,9 @@ void spc_sense_caps(struct burn_drive *d)
{
struct buffer buf;
struct scsi_mode_data *m;
int size, page_length, num_write_speeds = 0, i, speed, ret;
int size;
unsigned char *page;
struct command c;
struct burn_speed_descriptor *sd;
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
static int speed_debug = 0;
memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c.retry = 1;
@ -155,17 +150,6 @@ void spc_sense_caps(struct burn_drive *d)
m = d->mdata;
page = c.page->data + 8;
/* ts A61225 :
Although MODE SENSE indeed belongs to SPC, the returned code page
2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes,
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
*/
page_length = page[1];
m->valid = 0;
burn_mdata_free_subs(m);
m->buffer_size = page[12] * 256 + page[13];
m->dvdram_read = page[2] & 32;
m->dvdram_write = page[3] & 32;
@ -178,83 +162,28 @@ void spc_sense_caps(struct burn_drive *d)
m->cdr_read = page[2] & 1;
m->cdr_write = page[3] & 1;
m->c2_pointers = page[5] & 16;
m->underrun_proof = page[4] & 128;
/* ts A61021 : these fields are marked obsolete in MMC 3 */
m->max_read_speed = page[8] * 256 + page[9];
m->cur_read_speed = page[14] * 256 + page[15];
/* in MMC-3 : see [30-31] and blocks beginning at [32] */
m->max_write_speed = page[18] * 256 + page[19];
m->cur_write_speed = page[20] * 256 + page[21];
/* ts A61021 : New field to be set by atip (or following MMC-3 info) */
/* New field to be set by atip */
m->min_write_speed = m->max_write_speed;
/* ts A61225 : for ACh GET PERFORMANCE, Type 03h */
m->min_end_lba = 0x7fffffff;
m->max_end_lba = 0;
/* in MMC-3 : [28-29] */
m->cur_write_speed = page[20] * 256 + page[21];
/* >>> ts A61021 : iterate over all speeds :
data[30-31]: number of speed performance descriptor blocks
data[32-35]: block 0 : [+2-3] speed in kbytes/sec
*/
m->c2_pointers = page[5] & 16;
m->valid = 1;
mmc_get_configuration(d);
/* ts A61225 : end of MMC-1 , begin of MMC-3 */
if (page_length < 32) /* no write speed descriptors ? */
goto try_mmc_get_performance;
m->cur_write_speed = page[28] * 256 + page[29];
if (speed_debug)
fprintf(stderr, "LIBBURN_DEBUG: cur_write_speed = %d\n",
m->cur_write_speed);
num_write_speeds = page[30] * 256 + page[31];
m->max_write_speed = m->min_write_speed = m->cur_write_speed;
for (i = 0; i < num_write_speeds; i++) {
speed = page[32 + 4*i + 2] * 256 + page[32 + 4*i + 3];
if (speed_debug)
fprintf(stderr,
"LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n",
i, speed, page[32 + 4*i +1] & 7);
/* ts A61226 */
ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
NULL, d->mdata->speed_descriptors, 0);
if (ret > 0) {
sd = d->mdata->speed_descriptors;
sd->source = 1;
if (d->current_profile > 0) {
sd->profile_loaded = d->current_profile;
strcpy(sd->profile_name,
d->current_profile_text);
}
sd->wrc = (( page[32 + 4*i +1] & 7 ) == 1 );
sd->write_speed = speed;
}
if (speed > m->max_write_speed)
m->max_write_speed = speed;
if (speed < m->min_write_speed)
m->min_write_speed = speed;
}
if (speed_debug)
fprintf(stderr,
"LIBBURN_DEBUG: 5Ah,2Ah min_write_speed = %d , max_write_speed = %d\n",
m->min_write_speed, m->max_write_speed);
try_mmc_get_performance:;
ret = mmc_get_write_performance(d);
if (ret > 0 && speed_debug)
fprintf(stderr,
"LIBBURN_DEBUG: ACh min_write_speed = %d , max_write_speed = %d\n",
m->min_write_speed, m->max_write_speed);
m->underrun_proof = page[4] & 128;
}
void spc_sense_error_params(struct burn_drive *d)
{
struct buffer buf;
@ -318,7 +247,7 @@ void spc_sense_write_params(struct burn_drive *d)
{
struct buffer buf;
struct scsi_mode_data *m;
int size, dummy;
int size;
unsigned char *page;
struct command c;
@ -343,35 +272,19 @@ void spc_sense_write_params(struct burn_drive *d)
m->write_page_length = page[1];
m->write_page_valid = 1;
mmc_read_disc_info(d);
/* ts A70212 : try to setup d->media_capacity_remaining */
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12)
d->read_format_capacities(d, -1);
else if (d->status == BURN_DISC_BLANK ||
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
d->get_nwa(d, -1, &dummy, &dummy);
}
/* others are hopefully up to date from mmc_read_disc_info() */
/*
fprintf(stderr, "LIBBURN_DEBUG: media_capacity_remaining = %.f\n",
(double) d->media_capacity_remaining);
*/
}
/* remark ts A61104 :
Although command MODE SELECT is SPC, the content of the
Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1).
Thus the filling of the mode page is done by mmc_compose_mode_page_5().
Thus the filling of the mode page should be done by a mmc_ function.
*/
void spc_select_write_params(struct burn_drive *d,
const struct burn_write_opts *o)
{
struct buffer buf;
struct command c;
int bufe, sim;
/* ts A61007 : All current callers are safe. */
/* a ssert(o->drive == d); */
@ -396,14 +309,30 @@ void spc_select_write_params(struct burn_drive *d,
memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length);
c.page->bytes = 8 + 2 + d->mdata->write_page_length;
c.page->data[8] = 5;
c.page->data[9] = d->mdata->write_page_length;
burn_print(12, "using write page length %d (valid %d)\n",
d->mdata->write_page_length, d->mdata->write_page_valid);
bufe = o->underrun_proof;
sim = o->simulate;
c.page->data[10] = (bufe << 6)
+ (sim << 4)
+ o->write_type;
/* ts A61229 */
if (mmc_compose_mode_page_5(d, o, c.page->data + 8) <= 0)
return;
/* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */
c.page->data[11] = ((3 * !!o->multi) << 6) | o->control;
c.page->data[12] = spc_block_type(o->block_type);
/* ts A61104 */
if(!(o->control&4)) /* audio (MMC-1 table 61) */
if(o->write_type == BURN_WRITE_TAO) /* ??? for others too ? */
c.page->data[12] = 0; /* Data Block Type: Raw Data */
c.page->data[22] = 0;
c.page->data[23] = 150; /* audio pause length */
/*XXX need session format! */
c.dir = TO_DRIVE;
d->issue_command(d, &c);
}
@ -416,6 +345,9 @@ void spc_getcaps(struct burn_drive *d)
}
/*
only called when a blank is present, so we set type to blank
(on the last pass)
don't check totally stupid modes (raw/raw0)
some drives say they're ok, and they're not.
*/
@ -425,24 +357,12 @@ void spc_probe_write_modes(struct burn_drive *d)
struct buffer buf;
int try_write_type = 1;
int try_block_type = 0;
int key, asc, ascq, useable_write_type = -1, useable_block_type = -1;
int last_try = 0;
int key, asc, ascq;
struct command c;
/* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */
while (try_write_type != 5) {
while (try_write_type != 4) {
burn_print(9, "trying %d, %d\n", try_write_type,
try_block_type);
/* ts A70213 */
if (try_write_type == 4) {
/* Pseudo write type NONE . Set a useable write mode */
if (useable_write_type == -1)
break;
try_write_type = useable_write_type;
try_block_type = useable_block_type;
last_try= 1;
}
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c.retry = 1;
c.oplen = sizeof(SPC_MODE_SELECT);
@ -467,9 +387,6 @@ void spc_probe_write_modes(struct burn_drive *d)
d->issue_command(d, &c);
d->silent_on_scsi_error = 0;
if (last_try)
break;
key = c.sense[2];
asc = c.sense[12];
ascq = c.sense[13];
@ -485,15 +402,6 @@ void spc_probe_write_modes(struct burn_drive *d)
else
d->block_types[try_write_type] |=
1 << try_block_type;
/* ts A70213 */
if ((useable_write_type < 0 && try_write_type > 0) ||
(try_write_type == 1 && try_block_type == 8)) {
/* Packet is not supported yet.
Prefer TAO MODE_1. */
useable_write_type = try_write_type;
useable_block_type = try_block_type;
}
}
switch (try_block_type) {
case 0:
@ -521,8 +429,6 @@ void spc_probe_write_modes(struct burn_drive *d)
}
}
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
/** @return -1 = error */
int spc_block_type(enum burn_block_types b)
{
@ -596,7 +502,6 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
d->idata->valid = 0;
d->mdata = malloc(sizeof(struct scsi_mode_data));
d->mdata->valid = 0;
d->mdata->speed_descriptors = NULL;
/* ts A61007 : obsolete Assert in drive_getcaps() */
if(d->idata == NULL || d->mdata == NULL) {

View File

@ -113,12 +113,6 @@ struct burn_track *burn_track_create(void)
t->mode = BURN_MODE1;
t->isrc.has_isrc = 0;
t->pad = 1;
/* ts A70213 */
t->fill_up_media = 0;
/* ts A70218 */
t->default_size = 0;
t->entry = NULL;
t->source = NULL;
t->eos = 0;
@ -323,8 +317,7 @@ void burn_track_clear_isrc(struct burn_track *t)
int burn_track_get_sectors(struct burn_track *t)
{
/* ts A70125 : was int */
off_t size;
int size;
int sectors, seclen;
seclen = burn_sector_length(t->mode);
@ -336,88 +329,12 @@ int burn_track_get_sectors(struct burn_track *t)
return sectors;
}
/* ts A70125 */
int burn_track_set_sectors(struct burn_track *t, int sectors)
{
off_t size, seclen;
int ret;
seclen = burn_sector_length(t->mode);
size = seclen * (off_t) sectors - (off_t) t->offset - (off_t) t->tail;
if (size < 0)
return 0;
ret = t->source->set_size(t->source, size);
t->open_ended = (t->source->get_size(t->source) <= 0);
return ret;
}
/* ts A70218 */
int burn_track_set_size(struct burn_track *t, off_t size)
{
t->open_ended = (size <= 0);
return t->source->set_size(t->source, size);
}
/* ts A70213 */
int burn_track_set_fillup(struct burn_track *t, int fill_up_media)
{
t->fill_up_media = fill_up_media;
if (fill_up_media)
t->open_ended = 0;
return 1;
}
/* ts A70213 */
/**
@param flag bit0= force new size even if existing track size is larger
*/
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag)
{
int max_sectors, ret = 2;
char msg[160];
if (t->fill_up_media <= 0)
return 2;
max_sectors = max_size / 2048;
if (burn_track_get_sectors(t) < max_sectors || (flag & 1)) {
sprintf(msg, "Setting total track size to %ds (payload %ds)\n",
max_sectors, (int) (t->source->get_size(t->source)/2048));
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
ret = burn_track_set_sectors(t, max_sectors);
t->open_ended = 0;
}
return ret;
}
/* ts A61031 */
int burn_track_is_open_ended(struct burn_track *t)
{
return !!t->open_ended;
}
/* ts A70218 : API */
int burn_track_set_default_size(struct burn_track *t, off_t size)
{
t->default_size = size;
return 1;
}
/* ts A70218 */
off_t burn_track_get_default_size(struct burn_track *t)
{
return t->default_size;
}
/* ts A61101 : API function */
int burn_track_get_counters(struct burn_track *t,
off_t *read_bytes, off_t *written_bytes)
@ -469,19 +386,13 @@ int burn_disc_get_sectors(struct burn_disc *d)
void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry)
{
if (t->entry == NULL)
memset(entry, 0, sizeof(struct burn_toc_entry));
else
memcpy(entry, t->entry, sizeof(struct burn_toc_entry));
memcpy(entry, t->entry, sizeof(struct burn_toc_entry));
}
void burn_session_get_leadout_entry(struct burn_session *s,
struct burn_toc_entry *entry)
{
if (s->leadout_entry == NULL)
memset(entry, 0, sizeof(struct burn_toc_entry));
else
memcpy(entry, s->leadout_entry, sizeof(struct burn_toc_entry));
memcpy(entry, s->leadout_entry, sizeof(struct burn_toc_entry));
}
struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num)

View File

@ -27,13 +27,6 @@ struct burn_track
int tailcount;
/** 1 means Pad with zeros, 0 means start reading the next track */
int pad;
/* ts A70213 : wether to expand this track to full available media */
int fill_up_media;
/* ts A70218 : a track size to use if it is mandarory to have some */
off_t default_size;
/** Data source */
struct burn_source *source;
/** End of Source flag */
@ -95,18 +88,5 @@ int burn_track_get_shortage(struct burn_track *t);
int burn_track_is_open_ended(struct burn_track *t);
int burn_track_is_data_done(struct burn_track *t);
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
int burn_track_set_sectors(struct burn_track *t, int sectors);
/* ts A70218 : sets the payload size alone */
int burn_track_set_size(struct burn_track *t, off_t size);
/* ts A70213 */
int burn_track_set_fillup(struct burn_track *t, int fill_up_media);
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag);
/* ts A70218 */
off_t burn_track_get_default_size(struct burn_track *t);
#endif /* BURN__STRUCTURE_H */

View File

@ -36,12 +36,7 @@ struct params
struct buffer
{
/* ts A61219:
Added 4096 bytes reserve against possible buffer overflows.
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
This can at most cause a 1 sector overlap. Sometimes an offset
of 16 byte is applied to the output data (in some RAW mode). ) */
unsigned char data[BUFFER_SIZE + 4096];
unsigned char data[BUFFER_SIZE];
int sectors;
int bytes;
};
@ -65,7 +60,6 @@ struct burn_scsi_inquiry_data
int valid;
};
struct scsi_mode_data
{
int buffer_size;
@ -85,12 +79,6 @@ struct scsi_mode_data
/* ts A61021 */
int min_write_speed;
/* ts A61225 : Results from ACh GET PERFORMANCE, Type 03h
Speed values go into *_*_speed */
int min_end_lba;
int max_end_lba;
struct burn_speed_descriptor *speed_descriptors;
int cur_read_speed;
int cur_write_speed;
int retry_page_length;
@ -103,20 +91,6 @@ struct scsi_mode_data
};
/* ts A70112 : represents a single Formattable Capacity Descriptor as of
mmc5r03c.pdf 6.24.3.3 . There can at most be 32 of them. */
struct burn_format_descr {
/* format type: e.g 0x00 is "Full", 0x15 is "Quick" */
int type;
/* the size in bytes derived from Number of Blocks */
off_t size;
/* the Type Dependent Parameter (usually the write alignment size) */
unsigned tdp;
};
#define LIBBURN_SG_MAX_SIBLINGS 16
/** Gets initialized in enumerate_common() and burn_drive_register() */
@ -129,9 +103,6 @@ struct burn_drive
int lun;
char *devname;
/* ts A70302: mmc5r03c.pdf 5.3.2 Physical Interface Standard */
int phys_if_std; /* 1=SCSI, 2=ATAPI, 3,4,6=FireWire, 7=SATA, 8=USB */
char phys_if_name[80]; /* MMC-5 5.3.2 table 91 , e.g. "SCSI Family" */
/* see os.h for name of particular os-*.h where this is defined */
BURN_OS_TRANSPORT_DRIVE_ELEMENTS
@ -148,50 +119,6 @@ struct burn_drive
enum burn_disc_status status;
int erasable;
/* ts A61201 from 46h GET CONFIGURATION */
int current_profile;
char current_profile_text[80];
int current_is_cd_profile;
int current_is_supported_profile;
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
Quite internal. Regard as opaque :)
*/
/* 1 = incremental recording available, 0 = not available */
int current_has_feat21h;
/* Link Size item number 0 from feature 0021h descriptor */
int current_feat21h_link_size;
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
bit1= DVD-RW supported
bit2= Test Write available
bit3= DVD-R DL supported
bit6= Buffer Under-run Free recording available (page 05h BUFE)
Value -1 indicates that no 002Fh was current in the features list.
*/
int current_feat2fh_byte4;
/* ts A70114 : wether a DVD-RW media holds an incomplete session
(which could need closing after write) */
int needs_close_session;
/* ts A61218 from 51h READ DISC INFORMATION */
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */
off_t format_curr_max_size; /* meaning depends on format_descr_type */
unsigned format_curr_blsas; /* meaning depends on format_descr_type */
int best_format_type;
off_t best_format_size;
/* The complete list of format descriptors as read with 23h */
int num_format_descr;
struct burn_format_descr format_descriptors[32];
volatile int released;
/* ts A61106 */
@ -202,23 +129,6 @@ struct burn_drive
int rlba; /* relative lba in section */
int start_lba;
int end_lba;
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
int complete_sessions;
/* ts A70129 :
from 51h READ DISC INFORMATION Last Track Number in Last Session */
int last_track_no;
/* ts A70212 : from various sources : free space on media (in bytes)
With CD this might change after particular write
parameters have been set and nwa has been inquired.
(e.g. by d->send_write_parameters() ; d->get_nwa()).
*/
off_t media_capacity_remaining;
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
int media_lba_limit;
int toc_temp;
struct burn_disc *disc; /* disc structure */
int block_types[4];
@ -262,19 +172,10 @@ struct burn_drive
void (*send_write_parameters) (struct burn_drive *,
const struct burn_write_opts *);
void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
int (*reserve_track) (struct burn_drive *d, off_t size);
void (*sync_cache) (struct burn_drive *);
int (*get_erase_progress) (struct burn_drive *);
int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa);
/* ts A70131 : obtain (possibly fake) TOC number and start lba of
first track in last complete session */
int (*read_multi_session_c1)(struct burn_drive *d,
int *trackno, int *start);
/* ts A61009 : removed d in favor of o->drive */
/* void (*close_disc) (struct burn_drive * d,
struct burn_write_opts * o);
@ -299,13 +200,6 @@ struct burn_drive
/* ts A61023 : get size and free space of drive buffer */
int (*read_buffer_capacity) (struct burn_drive *d);
/* ts A61220 : format media (e.g. DVD+RW) */
int (*format_unit) (struct burn_drive *d, off_t size, int flag);
/* ts A70108 */
/* mmc5r03c.pdf 6.24 : get list of available formats */
int (*read_format_capacities) (struct burn_drive *d, int top_wanted);
};
/* end of generic 'drive' data structures */

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,7 @@ int burn_sector_length(int trackmode);
int burn_subcode_length(int trackmode);
/* ts A61009 */
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc,
int flag);
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc);
void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc);
int burn_write_leadin(struct burn_write_opts *o,
@ -33,16 +32,4 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
int tnum);
int burn_write_close_session(struct burn_write_opts *o,struct burn_session *s);
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session
"When the recording mode is Incremental Recording,
the disc is single session."
Enable this macro to get away from growisofs which uses Close Session
but also states "// DVD-R DL Seq has no notion of multi-session".
#define Libburn_dvd_r_dl_multi_no_close_sessioN 1
*/
#endif /* BURN__WRITE_H */

View File

@ -7,12 +7,10 @@
/** Overview
libburner is a minimal demo application for the library libburn as provided
on http://libburnia.pykix.org . It can list the available devices, can
blank a CD-RW or DVD-RW, can format a DVD-RW, and can burn to CD-R, CD-RW,
DVD+RW, DVD-RAM or DVD-RW. Not supported yet: DVD+R [DL].
on http://libburn.pykix.org . It can list the available devices, can
blank a CD-RW and can burn to CD-R or CD-RW.
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburnia team as reference application. libburner.c does indeed
to serve the libburn team as reference application. libburner.c does indeed
define the standard way how above three gestures can be implemented and
stay upward compatible for a good while.
@ -27,9 +25,9 @@
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
With that aquired drive you can blank a CD-RW
libburner_blank_disc()
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
libburner_format_row()
With the aquired drive you can burn to CD-R, CD-RW, DVD+RW, DVD-RAM, DVD-RW
Between blanking and burning one eventually has to reload the drive status
libburner_regrab()
With the aquired drive you can burn to CD-R or blank CD-RW
libburner_payload()
When everything is done, main() releases the drive and shuts down libburn:
burn_drive_release();
@ -72,10 +70,6 @@ static unsigned int drive_count;
finally released */
static int drive_is_grabbed = 0;
/** A number and a text describing the type of media in aquired drive */
static int current_profile= -1;
static char current_profile_name[80]= {""};
/* Some in-advance definitions to allow a more comprehensive ordering
of the functions and their explanations in here */
@ -104,13 +98,7 @@ int libburner_aquire_drive(char *drive_adr, int *driveno)
ret = libburner_aquire_by_adr(drive_adr);
else
ret = libburner_aquire_by_driveno(driveno);
if (ret <= 0)
return ret;
burn_disc_get_profile(drive_list[0].drive, &current_profile,
current_profile_name);
if (current_profile_name[0])
printf("Detected media type: %s\n", current_profile_name);
return 1;
return ret;
}
@ -121,21 +109,12 @@ int libburner_aquire_drive(char *drive_adr, int *driveno)
int libburner_aquire_by_adr(char *drive_adr)
{
int ret;
char libburn_drive_adr[BURN_DRIVE_ADR_LEN];
/* This tries to resolve links or alternative device files */
ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
if (ret<=0) {
fprintf(stderr,"Address does not lead to a CD burner: '%s'\n",
drive_adr);
return ret;
}
printf("Aquiring drive '%s' ...\n",libburn_drive_adr);
ret = burn_drive_scan_and_grab(&drive_list,libburn_drive_adr,1);
printf("Aquiring drive '%s' ...\n",drive_adr);
ret = burn_drive_scan_and_grab(&drive_list,drive_adr,1);
if (ret <= 0) {
fprintf(stderr,"FAILURE with persistent drive address '%s'\n",
libburn_drive_adr);
drive_adr);
} else {
printf("Done\n");
drive_is_grabbed = 1;
@ -262,27 +241,29 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
{
enum burn_disc_status disc_state;
struct burn_progress p;
double percent = 1.0;
int percent = 1;
disc_state = burn_disc_get_status(drive);
while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE)
usleep(1001);
while ((disc_state = burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
usleep(1001);
printf(
"Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n",
disc_state);
if (current_profile == 0x13) {
; /* formatted DVD-RW will get blanked to sequential state */
} else if (disc_state == BURN_DISC_BLANK) {
if (disc_state == BURN_DISC_BLANK) {
fprintf(stderr,
"IDLE: Blank media detected. Will leave it untouched\n");
"IDLE: Blank CD media detected. Will leave it untouched\n");
return 2;
} else if (disc_state == BURN_DISC_FULL ||
disc_state == BURN_DISC_APPENDABLE) {
; /* this is what libburner is willing to blank */
; /* this is what libburn is willing to blank */
} else if (disc_state == BURN_DISC_EMPTY) {
fprintf(stderr,"FATAL: No media detected in drive\n");
return 0;
} else {
fprintf(stderr,
"FATAL: Unsuitable drive and media state\n");
"FATAL: Cannot recognize drive and media state\n");
return 0;
}
if(!burn_disc_erasable(drive)) {
@ -291,14 +272,14 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
return 0;
}
printf(
"Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
"Beginning to %s-blank CD media.\n", (blank_fast?"fast":"full"));
burn_disc_erase(drive, blank_fast);
sleep(1);
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
percent = 1.0 + ((double) p.sector+1.0)
/ ((double) p.sectors) * 98.0;
printf("Blanking ( %.1f%% done )\n", percent);
printf("Blanking ( %d%% done )\n", percent);
sleep(1);
}
printf("Done\n");
@ -306,45 +287,24 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
}
/** Persistently changes DVD-RW profile 0014h "Sequential Recording" to
profile 0013h "Restricted Overwrite" which needs no blanking for re-use
but is not capable of multi-session.
Expect a behavior similar to blanking with unusual noises from the drive.
/** This gesture is necessary to get the drive info after blanking.
It opens a small gap for losing the drive to another libburn instance.
We will work on closing this gap.
*/
int libburner_format_row(struct burn_drive *drive)
{
struct burn_progress p;
double percent = 1.0;
int libburner_regrab(struct burn_drive *drive) {
int ret;
if (current_profile == 0x13) {
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
return 2;
} else if (current_profile != 0x14) {
fprintf(stderr, "FATAL: Can only format DVD-RW\n");
return 0;
}
printf("Beginning to format media.\n");
burn_disc_format(drive, (off_t) 0, 0);
sleep(1);
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
percent = 1.0 + ((double) p.sector+1.0)
/ ((double) p.sectors) * 98.0;
printf("Formatting ( %.1f%% done )\n", percent);
sleep(1);
}
burn_disc_get_profile(drive_list[0].drive, &current_profile,
current_profile_name);
printf("Media type now: %4.4xh \"%s\"\n",
current_profile, current_profile_name);
if (current_profile != 0x13) {
fprintf(stderr,
"FATAL: Failed to change media profile to desired value\n");
return 0;
}
return 1;
printf("Releasing and regrabbing drive ...\n");
if (drive_is_grabbed)
burn_drive_release(drive, 0);
drive_is_grabbed = 0;
ret = burn_drive_grab(drive, 0);
if (ret != 0) {
drive_is_grabbed = 1;
printf("Done\n");
} else
printf("FAILED\n");
return !!ret;
}
@ -355,9 +315,6 @@ int libburner_format_row(struct burn_drive *drive)
In case of external signals expect abort handling of an ongoing burn to
last up to a minute. Wait the normal burning timespan before any kill -9.
For simplicity, this function allows memory leaks in case of failure.
In apps which do not abort immediately, one should clean up better.
*/
int libburner_payload(struct burn_drive *drive,
char source_adr[][4096], int source_adr_count,
@ -371,9 +328,9 @@ int libburner_payload(struct burn_drive *drive,
struct burn_track *track, *tracklist[99];
struct burn_progress progress;
time_t start_time;
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
int last_sector = 0, padding = 0, trackno, write_mode_tao = 0, fd;
off_t fixed_size;
char *adr, reasons[BURN_REASONS_LEN];
char *adr;
struct stat stbuf;
if (all_tracks_type != BURN_AUDIO) {
@ -402,7 +359,7 @@ int libburner_payload(struct burn_drive *drive,
fixed_size = stbuf.st_size;
}
if (fixed_size==0)
unpredicted_size = 1;
write_mode_tao = 1;
data_src = NULL;
if (fd>=0)
data_src = burn_fd_source_new(fd, -1, fixed_size);
@ -420,14 +377,19 @@ int libburner_payload(struct burn_drive *drive,
}
burn_session_add_track(session, track, BURN_POS_END);
printf("Track %d : source is '%s'\n", trackno+1, adr);
printf("Track %d : source is '%s'\n", trackno, adr);
burn_source_free(data_src);
} /* trackno loop end */
while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE)
usleep(100001);
/* Evaluate drive and media */
disc_state = burn_disc_get_status(drive);
if (disc_state != BURN_DISC_BLANK &&
disc_state != BURN_DISC_APPENDABLE) {
while ((disc_state = burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
usleep(100001);
if (disc_state == BURN_DISC_APPENDABLE) {
write_mode_tao = 1;
} else if (disc_state != BURN_DISC_BLANK) {
if (disc_state == BURN_DISC_FULL) {
fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n");
if (burn_disc_erasable(drive))
@ -443,17 +405,18 @@ int libburner_payload(struct burn_drive *drive,
burn_options = burn_write_opts_new(drive);
burn_write_opts_set_perform_opc(burn_options, 0);
burn_write_opts_set_multi(burn_options, !!multi);
if (write_mode_tao)
burn_write_opts_set_write_type(burn_options,
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
else
burn_write_opts_set_write_type(burn_options,
BURN_WRITE_SAO, BURN_BLOCK_SAO);
if(simulate_burn)
printf("\n*** Will TRY to SIMULATE burning ***\n\n");
burn_write_opts_set_simulate(burn_options, simulate_burn);
burn_structure_print_disc(target_disc);
burn_drive_set_speed(drive, 0, 0);
burn_write_opts_set_underrun_proof(burn_options, 1);
if (burn_write_opts_auto_write_type(burn_options, target_disc,
reasons, 0) == BURN_WRITE_NONE) {
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
fprintf(stderr, "Reasons given:\n%s\n", reasons);
return 0;
}
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
start_time = time(0);
@ -467,7 +430,7 @@ int libburner_payload(struct burn_drive *drive,
printf(
"Thank you for being patient since %d seconds.\n",
(int) (time(0) - start_time));
else if(unpredicted_size)
else if(write_mode_tao)
printf("Track %d : sector %d\n", progress.track+1,
progress.sector);
else
@ -482,12 +445,11 @@ int libburner_payload(struct burn_drive *drive,
burn_track_free(tracklist[trackno]);
burn_session_free(session);
burn_disc_free(target_disc);
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
current_profile != 0x12) /* not with DVD+RW, DVD-RW, DVD-RAM */
if (multi)
printf("NOTE: Media left appendable.\n");
if (simulate_burn)
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
return 1;
return 0;
}
@ -503,6 +465,8 @@ static int all_tracks_type = BURN_MODE1;
/** Converts command line arguments into above setup parameters.
drive_adr[] must provide at least BURN_DRIVE_ADR_LEN bytes.
source_adr[] must provide at least 4096 bytes.
*/
int libburner_setup(int argc, char **argv)
{
@ -540,9 +504,6 @@ int libburner_setup(int argc, char **argv)
}
strcpy(drive_adr, argv[i]);
}
} else if (!strcmp(argv[i], "--format_overwrite")) {
do_blank = 101;
} else if (!strcmp(argv[i], "--multi")) {
do_multi = 1;
@ -581,8 +542,7 @@ int libburner_setup(int argc, char **argv)
if (print_help || insuffient_parameters ) {
printf("Usage: %s\n", argv[0]);
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
printf(" [--blank_fast|--blank_full|--format_overwrite]\n");
printf(" [--try_to_simulate]\n");
printf(" [--blank_fast|--blank_full] [--try_to_simulate]\n");
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
printf("Examples\n");
printf("A bus scan (needs rw-permissions to see a drive):\n");
@ -593,18 +553,15 @@ int libburner_setup(int argc, char **argv)
printf(" %s --drive /dev/hdc my_image_file\n", argv[0]);
printf("Blank a used CD-RW (is combinable with burning in one run):\n");
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
printf("Blank a used DVD-RW (is combinable with burning in one run):\n");
printf(" %s --drive /dev/hdc --blank_full\n",argv[0]);
printf("Format a DVD-RW to avoid need for blanking before re-use:\n");
printf(" %s --drive /dev/hdc --format_overwrite\n", argv[0]);
printf("Burn two audio tracks (to CD only):\n");
printf("Burn two audio tracks\n");
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]);
printf("Burn a compressed afio archive on-the-fly:\n");
printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n");
printf(" %s --drive /dev/hdc -\n", argv[0]);
printf("To be read from *not mounted* media via: afio -tvZ /dev/hdc\n");
printf("To be read from *not mounted* CD via: afio -tvZ /dev/hdc\n");
printf("Program tar would need a clean EOF which our padded CD cannot deliver.\n");
if (insuffient_parameters)
return 6;
}
@ -620,7 +577,7 @@ int main(int argc, char **argv)
if (ret)
exit(ret);
printf("Initializing libburnia.pykix.org ...\n");
printf("Initializing libburn.pykix.org ...\n");
if (burn_initialize())
printf("Done\n");
else {
@ -645,13 +602,17 @@ int main(int argc, char **argv)
if (ret == 2)
{ ret = 0; goto release_drive; }
if (do_blank) {
if (do_blank > 100)
ret = libburner_format_row(drive_list[driveno].drive);
else
ret = libburner_blank_disc(drive_list[driveno].drive,
do_blank == 1);
ret = libburner_blank_disc(drive_list[driveno].drive,
do_blank == 1);
if (ret<=0)
{ ret = 36; goto release_drive; }
if (ret != 2 && source_adr_count > 0)
ret = libburner_regrab(drive_list[driveno].drive);
if (ret<=0) {
fprintf(stderr,
"FATAL: Cannot release and grab again drive after blanking\n");
{ ret = 37; goto finish_libburn; }
}
}
if (source_adr_count > 0) {
ret = libburner_payload(drive_list[driveno].drive,
@ -684,7 +645,7 @@ 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
on toplevel of libburn. To be fully in effect after the remaining other
copyrighted code has been replaced by ours and by copyright-free contributions
of our friends:

View File

@ -5,9 +5,9 @@
/** Overview
telltoc is a minimal demo application for the library libburn as provided
on http://libburnia.pykix.org . It can list the available devices, can
display some drive properties, the type of media, eventual table of content
and multisession info for mkisofs option -C .
on http://libburn.pykix.org . It can list the available devices, can display
some drive properties, the type of media, eventual table of content and
multisession info for mkisofs option -C .
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburn team as reference application. telltoc.c does indeed
define the standard way how above gestures can be implemented and stay upward
@ -105,20 +105,11 @@ int telltoc_aquire_by_adr(char *drive_adr)
{
int ret;
char libburn_drive_adr[BURN_DRIVE_ADR_LEN];
/* This tries to resolve links or alternative device files */
ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
if (ret<=0) {
fprintf(stderr,"Address does not lead to a CD burner: '%s'\n",
drive_adr);
return ret;
}
fprintf(stderr,"Aquiring drive '%s' ...\n",libburn_drive_adr);
ret = burn_drive_scan_and_grab(&drive_list,libburn_drive_adr,1);
fprintf(stderr,"Aquiring drive '%s' ...\n",drive_adr);
ret = burn_drive_scan_and_grab(&drive_list,drive_adr,1);
if (ret <= 0) {
fprintf(stderr,"FAILURE with persistent drive address '%s'\n",
libburn_drive_adr);
drive_adr);
} else {
fprintf(stderr,"Done\n");
drive_is_grabbed = 1;
@ -200,11 +191,11 @@ int telltoc_aquire_by_driveno(int *driveno, int silent_drive)
}
/** This gesture is necessary to get my NEC DVD_RW ND-4570A out of a state
of noisy overexcitement after its tray was loaded and it then was inquired
for Next Writeable Address.
of noisy overexcitement after it was inquired for Next Writeable Address.
The noise then still lasts 20 seconds. Same with cdrecord -toc, btw.
This opens a small gap for losing the drive to another libburn instance.
It opens a small gap for losing the drive to another libburn instance.
Not a problem in telltoc. This is done as very last drive operation.
Eventually the other libburn instance will have the same sanitizing effect.
*/
@ -224,50 +215,31 @@ int telltoc_regrab(struct burn_drive *drive) {
int telltoc_media(struct burn_drive *drive)
{
int ret, media_found = 0, profile_no = -1;
double max_speed = 0.0, min_speed = 0.0, speed_conv;
off_t available = 0;
int ret, media_found = 0;
double max_speed = 0.0, min_speed = 0.0;
enum burn_disc_status s;
char profile_name[80], speed_unit[40];
struct burn_multi_caps *caps;
struct burn_write_opts *o = NULL;
printf("Media current: ");
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
if (profile_no > 0 && ret >0) {
if (profile_name[0])
printf("%s\n", profile_name);
else
printf("%4.4Xh\n", profile_no);
} else
printf("is not recognizable\n");
speed_conv = 176.4;
strcpy(speed_unit,"176.4 kB/s (CD, data speed 150 KiB/s)");
if (strstr(profile_name, "DVD") == profile_name) {
speed_conv = 1385.0;
strcpy(speed_unit,"1385.0 kB/s (DVD)");
}
/* >>> libburn does not obtain full profile list yet */
while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE)
usleep(100001);
while ((s = burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
usleep(100001);
printf("Media status : ");
s = burn_disc_get_status(drive);
if (s == BURN_DISC_FULL) {
if (s==BURN_DISC_FULL) {
printf("is written , is closed\n");
media_found = 1;
} else if (s == BURN_DISC_APPENDABLE) {
} else if (s==BURN_DISC_APPENDABLE) {
printf("is written , is appendable\n");
media_found = 1;
} else if (s == BURN_DISC_BLANK) {
} else if (s==BURN_DISC_BLANK) {
printf("is blank\n");
media_found = 1;
} else if (s == BURN_DISC_EMPTY)
} else if (s==BURN_DISC_EMPTY)
printf("is not present\n");
else
printf("is not recognizable\n");
printf("Media reuse : ");
printf("Media type : ");
if (media_found) {
if (burn_disc_erasable(drive))
printf("is erasable\n");
@ -276,175 +248,41 @@ int telltoc_media(struct burn_drive *drive)
} else
printf("is not recognizable\n");
ret = burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
if (ret > 0) {
/* Media appears writeable */
printf("Write multi : ");
printf("%s multi-session , ",
caps->multi_session == 1 ? "allows" : "prohibits");
if (caps->multi_track)
printf("allows multiple tracks\n");
else
printf("enforces single track\n");
printf("Write start : ");
if (caps->start_adr == 1)
printf(
"allows addresses [%.f , %.f]s , alignment=%.fs\n",
(double) caps->start_range_low / 2048 ,
(double) caps->start_range_high / 2048 ,
(double) caps->start_alignment / 2048 );
else
printf("prohibits write start addressing\n");
printf("Write modes : ");
if (caps->might_do_tao)
printf("TAO%s",
caps->advised_write_mode == BURN_WRITE_TAO ?
" (advised)" : "");
if (caps->might_do_sao)
printf("%sSAO%s",
caps->might_do_tao ? " , " : "",
caps->advised_write_mode == BURN_WRITE_SAO ?
" (advised)" : "");
if (caps->might_do_raw)
printf("%sRAW%s",
caps->might_do_tao | caps->might_do_sao ?
" , " : "",
caps->advised_write_mode == BURN_WRITE_RAW ?
" (advised)" : "");
printf("\n");
o= burn_write_opts_new(drive);
if (o != NULL) {
burn_write_opts_set_perform_opc(o, 0);
if(caps->advised_write_mode == BURN_WRITE_TAO)
burn_write_opts_set_write_type(o,
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
else if (caps->advised_write_mode == BURN_WRITE_SAO)
burn_write_opts_set_write_type(o,
BURN_WRITE_SAO, BURN_BLOCK_SAO);
else {
burn_write_opts_free(o);
o = NULL;
}
}
available = burn_disc_available_space(drive, o);
printf("Write space : %.1f MiB (%.fs)\n",
((double) available) / 1024.0 / 1024.0,
((double) available) / 2048.0);
burn_disc_free_multi_caps(&caps);
if (o != NULL)
burn_write_opts_free(o);
}
ret = burn_drive_get_write_speed(drive);
max_speed = ((double ) ret) / speed_conv;
ret = burn_drive_get_min_write_speed(drive);
min_speed = ((double ) ret) / speed_conv;
if (!media_found)
printf("Drive speed : max=%.1f , min=%.1f\n",
max_speed, min_speed);
else
printf("Avail. speed : max=%.1f , min=%.1f\n",
max_speed, min_speed);
ret = 0;
if (media_found)
ret = burn_disc_read_atip(drive);
ret= burn_disc_read_atip(drive);
if(ret>0) {
ret = burn_drive_get_min_write_speed(drive);
min_speed = ((double ) ret) / speed_conv;
ret = burn_drive_get_write_speed(drive);
max_speed = ((double ) ret) / speed_conv;
printf("Media speed : max=%.1f , min=%.1f\n",
ret= burn_drive_get_min_write_speed(drive);
min_speed = ((double ) ret) / 176.0;
}
ret= burn_drive_get_write_speed(drive);
max_speed = ((double ) ret) / 176.0;
if (!media_found)
printf("Drive speed : max=%.f\n", max_speed);
else if (min_speed<=0)
printf("Media speed : max=%.f\n", max_speed);
else
printf("Media speed : max=%.f , min=%.f\n",
max_speed, min_speed);
}
printf("Speed unit 1x: %s\n", speed_unit);
return 1;
}
int telltoc_speedlist(struct burn_drive *drive)
{
int ret, has_modern_entries = 0;
struct burn_speed_descriptor *speed_list, *sd;
ret = burn_drive_get_speedlist(drive, &speed_list);
if (ret <= 0) {
fprintf(stderr, "SORRY: Cannot obtain speed list info\n");
return 2;
}
for (sd = speed_list; sd != NULL; sd = sd->next)
if (sd->source == 2)
has_modern_entries = 1;
for (sd = speed_list; sd != NULL; sd = sd->next) {
if (has_modern_entries && sd->source < 2)
continue;
if (sd->write_speed <= 0)
continue;
printf("Speed descr. : %d kB/s", sd->write_speed);
if (sd->end_lba >= 0)
printf(", %.1f MiB", ((double) sd->end_lba) / 512.0);
if (sd->profile_name[0])
printf(", %s", sd->profile_name);
printf("\n");
}
burn_drive_free_speedlist(&speed_list);
return 1;
}
int telltoc_formatlist(struct burn_drive *drive)
{
int ret, i, status, num_formats, profile_no, type;
off_t size;
unsigned dummy;
char status_text[80], profile_name[90];
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
&num_formats);
if (ret <= 0) {
fprintf(stderr, "SORRY: Cannot obtain format list info\n");
return 2;
}
if (status == BURN_FORMAT_IS_UNFORMATTED)
sprintf(status_text, "unformatted, up to %.1f MiB",
((double) size) / 1024.0 / 1024.0);
else if(status == BURN_FORMAT_IS_FORMATTED)
sprintf(status_text, "formatted, with %.1f MiB",
((double) size) / 1024.0 / 1024.0);
else if(status == BURN_FORMAT_IS_UNKNOWN) {
burn_disc_get_profile(drive, &profile_no, profile_name);
if (profile_no > 0)
sprintf(status_text, "intermediate or unknown");
else
sprintf(status_text, "no media or unknown media");
} else
sprintf(status_text, "illegal status according to MMC-5");
printf("Format status: %s\n", status_text);
for (i = 0; i < num_formats; i++) {
ret = burn_disc_get_format_descr(drive, i,
&type, &size, &dummy);
if (ret <= 0)
continue;
printf("Format descr.: %2.2Xh , %.1f MiB (%.fs)\n",
type, ((double) size) / 1024.0 / 1024.0,
((double) size) / 2048.0);
}
return 1;
}
int telltoc_toc(struct burn_drive *drive)
{
int num_sessions = 0 , num_tracks = 0 , lba = 0, pmin, psec, pframe;
int num_sessions = 0 , num_tracks = 0 , lba = 0;
int track_count = 0;
int session_no, track_no;
enum burn_disc_status s;
struct burn_disc *disc= NULL;
struct burn_session **sessions;
struct burn_track **tracks;
struct burn_toc_entry toc_entry;
while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE)
usleep(100001);
while ((s = burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
usleep(100001);
disc = burn_drive_get_disc(drive);
if (disc==NULL) {
fprintf(stderr, "SORRY: Cannot obtain Table Of Content\n");
@ -459,36 +297,27 @@ int telltoc_toc(struct burn_drive *drive)
for(track_no= 0; track_no<num_tracks; track_no++) {
track_count++;
burn_track_get_entry(tracks[track_no], &toc_entry);
if (toc_entry.extensions_valid & 1) {
/* DVD extension valid */
lba = toc_entry.start_lba;
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
} else {
pmin = toc_entry.pmin;
psec = toc_entry.psec;
pframe = toc_entry.pframe;
lba= burn_msf_to_lba(pmin, psec, pframe);
}
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
toc_entry.pframe);
printf("Media content: session %2d ", session_no+1);
printf("track %2d %s lba: %9d %4.2d:%2.2d:%2.2d\n",
printf("track %2d %s lba: %9d %2.2u:%2.2u:%2.2u\n",
track_count,
((toc_entry.control&7)<4?"audio":"data "),
lba, pmin, psec, pframe);
lba,
toc_entry.pmin,
toc_entry.psec,
toc_entry.pframe);
}
burn_session_get_leadout_entry(sessions[session_no],
&toc_entry);
if (toc_entry.extensions_valid & 1) {
lba = toc_entry.start_lba;
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
} else {
pmin = toc_entry.pmin;
psec = toc_entry.psec;
pframe = toc_entry.pframe;
lba= burn_msf_to_lba(pmin, psec, pframe);
}
lba = burn_msf_to_lba(toc_entry.pmin,
toc_entry.psec, toc_entry.pframe);
printf("Media content: session %2d ", session_no+1);
printf("leadout lba: %9d %4.2d:%2.2d:%2.2d\n",
lba, pmin, psec, pframe);
printf("leadout lba: %9d %2.2u:%2.2u:%2.2u\n",
lba,
toc_entry.pmin,
toc_entry.psec,
toc_entry.pframe);
}
if (disc!=NULL)
burn_disc_free(disc);
@ -499,11 +328,19 @@ int telltoc_toc(struct burn_drive *drive)
int telltoc_msinfo(struct burn_drive *drive,
int msinfo_explicit, int msinfo_alone)
{
int ret, lba, nwa = -123456789, aux_lba;
int num_sessions, session_no, ret, num_tracks;
int nwa = -123456789, lba = -123456789, aux_lba, lout_lba;
enum burn_disc_status s;
struct burn_disc *disc= NULL;
struct burn_session **sessions;
struct burn_track **tracks;
struct burn_toc_entry toc_entry;
struct burn_write_opts *o= NULL;
s = burn_disc_get_status(drive);
while (burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE)
usleep(100001);
while ((s = burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
usleep(100001);
if (s!=BURN_DISC_APPENDABLE) {
if (!msinfo_explicit)
return 2;
@ -516,17 +353,34 @@ int telltoc_msinfo(struct burn_drive *drive,
The first number is the sector number of the first sector in
the last session of the disk that should be appended to.
*/
ret = burn_disc_get_msc1(drive, &lba);
if (ret <= 0) {
fprintf(stderr,
"SORRY: Cannot obtain start address of last session\n");
disc = burn_drive_get_disc(drive);
if (disc==NULL) {
fprintf(stderr,"SORRY: Cannot obtain info about CD content\n");
return 2;
}
sessions = burn_disc_get_sessions(disc, &num_sessions);
for (session_no = 0; session_no<num_sessions; session_no++) {
tracks = burn_session_get_tracks(sessions[session_no],
&num_tracks);
if (tracks==NULL || num_tracks<=0)
continue;
burn_track_get_entry(tracks[0], &toc_entry);
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
toc_entry.pframe);
}
if(lba==-123456789) {
fprintf(stderr,"SORRY: Cannot find any track on media\n");
{ ret = 0; goto ex; }
}
/* Prepare a qualified guess as fallback for nwa inquiry */
burn_session_get_leadout_entry(sessions[num_sessions-1], &toc_entry);
lout_lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,
toc_entry.pframe);
/* man mkisofs , option -C :
The second number is the starting sector number of the new session.
*/
/* Set some roughly suitable write opts to be sent to drive. */
/* Set some write opts to be sent to drive. LG GSA-4082B needs it. */
o= burn_write_opts_new(drive);
if(o!=NULL) {
burn_write_opts_set_perform_opc(o, 0);
@ -538,16 +392,22 @@ int telltoc_msinfo(struct burn_drive *drive,
telltoc_regrab(drive); /* necessary to calm down my NEC drive */
if(ret<=0) {
fprintf(stderr,
"SORRY: Cannot obtain next writeable address\n");
{ ret = 0; goto ex; }
"NOTE: Guessing next writeable address from leadout\n");
if(num_sessions>0)
nwa= lout_lba+6900;
else
nwa= lout_lba+11400;
}
if (!msinfo_alone)
printf("Media msinfo : mkisofs ... -C ");
printf("%d,%d\n",lba,nwa);
ret = 1;
ex:;
if (o != NULL)
if (disc!=NULL)
burn_disc_free(disc);
if (o!=NULL)
burn_write_opts_free(o);
return ret;
}
@ -560,7 +420,6 @@ static int do_media = 0;
static int do_toc = 0;
static int do_msinfo = 0;
static int print_help = 0;
static int do_capacities = 0;
/** Converts command line arguments into above setup parameters.
@ -597,9 +456,6 @@ int telltoc_setup(int argc, char **argv)
} else if (!strcmp(argv[i], "--msinfo")) {
do_msinfo = 1;
} else if (!strcmp(argv[i], "--capacities")) {
do_capacities = 1;
} else if (!strcmp(argv[i], "--toc")) {
do_toc = 1;
@ -616,7 +472,7 @@ int telltoc_setup(int argc, char **argv)
if (print_help) {
printf("Usage: %s\n", argv[0]);
printf(" [--drive <address>|<driveno>|\"-\"]\n");
printf(" [--media] [--capacities] [--toc] [--msinfo]\n");
printf(" [--media] [--toc] [--msinfo]\n");
printf("Examples\n");
printf("A bus scan (needs rw-permissions to see a drive):\n");
printf(" %s --drive -\n",argv[0]);
@ -651,14 +507,13 @@ int main(int argc, char **argv)
msinfo_alone = 1;
}
/* Default option is to do everything if possible */
if (do_media==0 && do_msinfo==0 && do_capacities==0 && do_toc==0
&& driveno!=-1) {
if (do_media==0 && do_msinfo==0 && do_toc==0 && driveno!=-1) {
if(print_help)
exit(0);
full_default = do_media = do_msinfo = do_capacities= do_toc = 1;
full_default = do_media = do_msinfo = do_toc = 1;
}
fprintf(stderr, "Initializing libburnia.pykix.org ...\n");
fprintf(stderr, "Initializing libburn.pykix.org ...\n");
if (burn_initialize())
fprintf(stderr, "Done\n");
else {
@ -683,14 +538,6 @@ int main(int argc, char **argv)
if (ret<=0)
{ret = 36; goto release_drive; }
}
if (do_capacities) {
ret = telltoc_speedlist(drive_list[driveno].drive);
if (ret<=0)
{ret = 39; goto release_drive; }
ret = telltoc_formatlist(drive_list[driveno].drive);
if (ret<=0)
{ret = 39; goto release_drive; }
}
if (do_toc) {
ret = telltoc_toc(drive_list[driveno].drive);
if (ret<=0)