Compare commits
253 Commits
ZeroFourZe
...
ZeroSevenZ
Author | SHA1 | Date | |
---|---|---|---|
77eee54ee6 | |||
f143123ae1 | |||
edf242dd39 | |||
7fd995e0e4 | |||
22c187cd61 | |||
b900831914 | |||
654d71ef07 | |||
0571f4dc2e | |||
ff23614200 | |||
c59300b27a | |||
635996a327 | |||
93287896a6 | |||
4da88193fa | |||
3091eeb9c9 | |||
19a668a48e | |||
6ceabaff32 | |||
b65b852c15 | |||
1ccedd5572 | |||
473e205c9e | |||
2522bebfbd | |||
8276611468 | |||
38994b62c0 | |||
474c4cddd7 | |||
b0b4bc57f8 | |||
b97fa7a451 | |||
8aca8e9921 | |||
15b31b121a | |||
e5632de786 | |||
91e3a2f3f7 | |||
0ffc4bd19b | |||
9cb4e4281e | |||
f87747802a | |||
4626304e39 | |||
d19abc1940 | |||
5ef7b4b445 | |||
033107b436 | |||
635405da8f | |||
aafa543391 | |||
8594cd96bc | |||
b07c83ed86 | |||
d74b1a2008 | |||
8c56ca131f | |||
53e4483460 | |||
591c385489 | |||
b0f1f67495 | |||
6139fb32dd | |||
01ed4729bd | |||
350ac05bfd | |||
5f55a436e8 | |||
3baaa886be | |||
d4147e72f0 | |||
116798e081 | |||
7cc43c44e9 | |||
de0b3dd469 | |||
596d5bc5b0 | |||
867093d7d4 | |||
47dd4d8c09 | |||
01a825310e | |||
96043eddf5 | |||
5a65d6fa07 | |||
aca01b88f3 | |||
6d667880e5 | |||
1a667c86bc | |||
7c64d4bc13 | |||
6fea3d0a9b | |||
687bde257c | |||
1de41908a8 | |||
8af33586e8 | |||
3ea5106d68 | |||
0ca643d0a4 | |||
d50c90b7be | |||
1b5ab0834e | |||
147cb430d1 | |||
1cbe3afdcc | |||
817edbaeea | |||
6552c8267c | |||
82fcf62309 | |||
c1572c271f | |||
83ed108298 | |||
0d669b4369 | |||
22554efe4f | |||
eb7e20a02c | |||
a5e2729604 | |||
d52ea49eb6 | |||
96e1cc451c | |||
bfba58b0fa | |||
175061615e | |||
717ad0f412 | |||
f3ea35b9b8 | |||
bb9ef6b988 | |||
aa606552eb | |||
9d99e7874a | |||
d1483a15da | |||
ed60d9a644 | |||
bd5d8e8991 | |||
bf64271c67 | |||
b0c8bbd48d | |||
2fb19dd08e | |||
2ce3199241 | |||
6fe53827da | |||
6053f3a6e3 | |||
de274ddaff | |||
92b0e145d5 | |||
4a5083739d | |||
7a8040fe9f | |||
57df15054f | |||
a57cf121d8 | |||
935239b4f9 | |||
e50cc04374 | |||
89c12404d0 | |||
78642d08ae | |||
c2c2499862 | |||
32252122b8 | |||
63a48571af | |||
006fb98aee | |||
afded80e10 | |||
fb3d2de5df | |||
c640c7954b | |||
bc30c4201a | |||
50b587a22c | |||
cd99716ab5 | |||
13bdbd3555 | |||
711c055730 | |||
f64ed23a98 | |||
730c1555ab | |||
acd7dbc5c6 | |||
6dc9ecbcad | |||
5a99f9c4d8 | |||
ea17318e18 | |||
98d742a4ef | |||
332a92ac78 | |||
6c50416d3c | |||
91d678a503 | |||
76e85e600c | |||
9d48bb6892 | |||
38f0399fff | |||
39198ff8cb | |||
67ca4a251a | |||
b1c6953b61 | |||
eb95d89272 | |||
548051e53f | |||
a72b38c116 | |||
a67aa2ccee | |||
2fb5ea8def | |||
55061cb7cf | |||
4b3ec06cc4 | |||
ad6bd91b21 | |||
0e2aaa2d59 | |||
4244a3c141 | |||
e4d30e4762 | |||
2856e9c984 | |||
6660ef7ece | |||
37092086d9 | |||
35d1394262 | |||
4dec38984d | |||
be0626ae9e | |||
a54113267e | |||
2d9d250471 | |||
ff7520f2f5 | |||
d0d90fc902 | |||
1d41767348 | |||
12b0fbf17c | |||
44368aef6c | |||
43b6ad6008 | |||
f006ee5436 | |||
5e4da147a5 | |||
103b301b09 | |||
0386feabfe | |||
4e949d79fe | |||
422a97a2f2 | |||
a52ea438a5 | |||
62f41452bb | |||
015bc00a91 | |||
d6fde26824 | |||
1cfb29f032 | |||
65cf751a30 | |||
4683386de1 | |||
5d51869c3b | |||
fe8a6c6224 | |||
db5568c03b | |||
a07631c57b | |||
e522db6220 | |||
51ac900de6 | |||
cdea153443 | |||
0ce3f7c224 | |||
8de0a3dc6c | |||
e75e5e04b8 | |||
86d5bdfef8 | |||
c1298d82a6 | |||
5c6366ecbd | |||
616454c737 | |||
ea6957ef68 | |||
f9398c08e6 | |||
b4617c679c | |||
42bb74881a | |||
61671b41d7 | |||
1e74d7a04e | |||
c48244abfc | |||
13492efe4b | |||
bccb39efd8 | |||
6fc60be93c | |||
d69b856b6a | |||
b5e2d60c68 | |||
ff1ad50119 | |||
4cb6706307 | |||
6e74c8bc2e | |||
fdbed06f84 | |||
67e4282b82 | |||
bd8d4bb49f | |||
623edf9d9d | |||
d4fe8c75be | |||
9ebd020847 | |||
a93d18231a | |||
ec8b75217f | |||
99767afe1f | |||
024076ad54 | |||
c39e7d8ce4 | |||
95609061f1 | |||
d498003515 | |||
b1630a3b33 | |||
eddf4e6b13 | |||
654e25d40a | |||
69e1d4a51f | |||
305917fe86 | |||
b3b42ff649 | |||
63d1f5dcbf | |||
77a9a1fc92 | |||
beb1c1d2d1 | |||
e449654c7b | |||
d66a40bc0e | |||
bed900f3f4 | |||
922fc6c90b | |||
adac21d6ee | |||
d9e056c3ac | |||
32a6bd1f82 | |||
9f7be91aba | |||
fec4fd864f | |||
e48014caea | |||
82c6e92da0 | |||
206910da4e | |||
0a27b188a3 | |||
6705389f14 | |||
5c8d6865b5 | |||
2d6d2679a0 | |||
5432612965 | |||
9b1a57d84a | |||
e5ea580e3b | |||
981a1bf5e1 | |||
49925ad2ba | |||
fc5f2a4745 | |||
903a12c90b | |||
0f50c21888 | |||
f3739013fa |
@ -1,13 +1,12 @@
|
||||
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
32
Makefile.am
32
Makefile.am
@ -1,4 +1,8 @@
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
|
||||
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
|
||||
# was: pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
||||
|
||||
libincludedir=$(includedir)/libburn
|
||||
|
||||
lib_LTLIBRARIES = libburn/libburn.la
|
||||
@ -82,29 +86,35 @@ noinst_PROGRAMS = \
|
||||
bin_PROGRAMS = \
|
||||
cdrskin/cdrskin
|
||||
|
||||
LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||
|
||||
test_libburner_CPPFLAGS = -Ilibburn
|
||||
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_libburner_SOURCES = test/libburner.c
|
||||
test_telltoc_CPPFLAGS = -Ilibburn
|
||||
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_telltoc_SOURCES = test/telltoc.c
|
||||
test_dewav_CPPFLAGS = -Ilibburn
|
||||
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_dewav_SOURCES = test/dewav.c
|
||||
test_fake_au_CPPFLAGS =
|
||||
test_fake_au_LDADD =
|
||||
test_fake_au_SOURCES = test/fake_au.c
|
||||
test_poll_CPPFLAGS = -Ilibburn
|
||||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_poll_SOURCES = test/poll.c
|
||||
test_structest_CPPFLAGS = -Ilibburn
|
||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_structest_SOURCES = test/structest.c
|
||||
|
||||
## cdrskin construction site - ts A60816 - A70720
|
||||
## cdrskin construction site - ts A60816 - A90507
|
||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_3_9
|
||||
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_0
|
||||
|
||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||
cdrskin_cdrskin_LDADD = libburn/libburn.la $(LIBBURN_EXTRALIBS)
|
||||
|
||||
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
||||
##
|
||||
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
||||
@ -163,13 +173,13 @@ indent: $(indent_files)
|
||||
|
||||
# Extra things
|
||||
nodist_pkgconfig_DATA = \
|
||||
libburn-5.pc
|
||||
libburn-1.pc
|
||||
|
||||
# http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages
|
||||
man_MANS = cdrskin/cdrskin.1
|
||||
|
||||
EXTRA_DIST = \
|
||||
libburn-5.pc.in \
|
||||
libburn-1.pc.in \
|
||||
version.h.in \
|
||||
doc/comments \
|
||||
doc/doxygen.conf.in \
|
||||
|
311
README
311
README
@ -4,50 +4,70 @@
|
||||
This all is under GPL.
|
||||
(See GPL reference, our clarification and commitment at the end of this text)
|
||||
------------------------------------------------------------------------------
|
||||
libburnia-project.org
|
||||
libburn-project.org
|
||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
|
||||
|
||||
Still containing parts of
|
||||
Libburn. By Derek Foreman <derek@signalmarketing.com> and
|
||||
Ben Jansens <xor@orodu.net>
|
||||
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
||||
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||
and Ben Jansens <xor@orodu.net>
|
||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||
These parts are to be replaced by own code of above libburnia-project.org
|
||||
copyright holders and then libburnia-project.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-project.org toplevel README (C) 2006-2007 Thomas Schmitt
|
||||
http://files.libburnia-project.org/releases/libburn-0.7.0.pl00.tar.gz
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Build and Installation
|
||||
|
||||
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://svn.libburnia-project.org/libburn/trunk libburn
|
||||
go into directory libburn and apply autotools by
|
||||
./bootstrap
|
||||
From tarball
|
||||
|
||||
Alternatively you may unpack a release tarball for which you do not need
|
||||
autotools installed.
|
||||
Obtain libburn-0.7.0.pl00.tar.gz, take it to a directory of your choice and do:
|
||||
|
||||
To build a libburnia-project.org subproject it should be sufficient to go
|
||||
into its toplevel directory (here: "libburn") and execute
|
||||
tar xzf libburn-0.7.0.pl00.tar.gz
|
||||
cd libburn-0.7.0
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
|
||||
To make the libraries accessible for running resp. developing applications
|
||||
To make libburn accessible for running resp. application development,
|
||||
and to install the cdrecord compatibility binary cdrskin, do
|
||||
(as Superuser):
|
||||
|
||||
make install
|
||||
|
||||
This procedure installs libburn.so.4 and cdrskin depending on it.
|
||||
For a standalone cdrskin binary, see cdrskin/README.
|
||||
|
||||
The other half of the project, libisofs, is hosted in the libburnia SVN, too:
|
||||
svn co http://svn.libburnia-project.org/libisofs/trunk libisofs
|
||||
See README file there.
|
||||
A behavioral conflict is known between any burn software and demons like hald
|
||||
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
|
||||
You may have to keep your hald away from the drive. See for example
|
||||
http://www.freebsd.org/gnome/docs/halfaq.html
|
||||
|
||||
|
||||
From SVN
|
||||
|
||||
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.
|
||||
Do in a directory of your choice:
|
||||
|
||||
svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn
|
||||
cd libburn-svn
|
||||
./bootstrap
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
make install
|
||||
|
||||
Warning: The trunk might contain experimental features which might not
|
||||
persist until next release.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||
launchpad.net :
|
||||
bzr branch lp:libisofs
|
||||
|
||||
Another part the project, libisoburn, is hosted in the libburnia SVN, too:
|
||||
svn co http://svn.libburnia-project.org/libisoburn/trunk libisoburn
|
||||
|
||||
See README files there.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -55,41 +75,54 @@ See README file there.
|
||||
|
||||
libburnia-project.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.
|
||||
For now this means CD media, all DVD media except DVD-R DL, all BD media.
|
||||
|
||||
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.
|
||||
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
||||
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
||||
On other X/Open compliant systems there will only be pseudo drives, but no
|
||||
direct MMC operation on real CD/DVD/BD drives.
|
||||
|
||||
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
|
||||
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.
|
||||
For full ports to other systems 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.
|
||||
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
||||
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
|
||||
by help of existing cdrecord frontends.
|
||||
We have a functional application 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.
|
||||
|
||||
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
||||
and manipulated quite freely. This capability together with our burn capability
|
||||
makes possible a single binary application which covers all steps of image
|
||||
composition, updating and writing. Quite unique in the Linux world.
|
||||
|
||||
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).
|
||||
/dev/srM 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.
|
||||
|
||||
- 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.
|
||||
|
||||
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
||||
also allows to grow ISO-9660 filesystem images on multi-session
|
||||
media as well as on overwriteable media via the same API.
|
||||
All media peculiarities are handled automatically.
|
||||
|
||||
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||
Cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||
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
|
||||
@ -97,14 +130,42 @@ The project components (list subject to growth, hopefully):
|
||||
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
|
||||
is test/libburner.c .
|
||||
- xorriso is an application of all three libraries which creates, loads,
|
||||
manipulates and writes ISO 9660 filesystem images with
|
||||
Rock Ridge extensions. Manipulation is not only adding or
|
||||
overwriting of files but also deleting, renaming, attribute
|
||||
changing, incremental backups, activating boot images, and
|
||||
extracting of files from ISO images to disk.
|
||||
See xorriso/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 .
|
||||
Explore these examples if you look for inspiration.
|
||||
|
||||
We plan to be a responsive upstream. Bear with us. We are still practicing.
|
||||
We strive to be a responsive upstream.
|
||||
|
||||
Our libraries are committed to maintain older feature sets in newer versions.
|
||||
This applies to source code headers (API) as well as to linkable objects (ABI).
|
||||
The only exception from this rule is about non-release versions x.y.*[13579]
|
||||
which are allowed to introduce new features, change those new features in
|
||||
any way and even may revoke such new features before the next release of
|
||||
x.y.*[02468]. As soon as it is released, a feature is promised to persist.
|
||||
|
||||
SONAMES:
|
||||
libburn.so.4 (since 0.3.4, March 2007),
|
||||
libisofs.so.6 (since 0.6.2, February 2008),
|
||||
libisoburn.so.1 (since 0.1.0, February 2008).
|
||||
|
||||
Applications must use 64 bit off_t. E.g. by defining
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
or take special precautions to interface with the libraries by 64 bit integers
|
||||
where the .h files prescribe off_t. Not to use 64 bit file i/o will keep the
|
||||
application from producing and processing ISO images of more than 2 GB size.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@ -133,7 +194,7 @@ Project history as far as known to me:
|
||||
discontent.
|
||||
The situation first caused me to publically regret it and then - after i
|
||||
got the opportunity to move in with cdrskin - gave me true reason to
|
||||
personally apologize to Derek Foreman, Ben Jansens and the contibutors at
|
||||
personally apologize to Derek Foreman, Ben Jansens and the contributors at
|
||||
icculus.org/burn. Posted to both projects:
|
||||
http://lists.freedesktop.org/archives/libburn/2006-August/000446.html
|
||||
http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html
|
||||
@ -204,6 +265,166 @@ Project history as far as known to me:
|
||||
We look back on improved stability, a substantially extended list of media
|
||||
and write modes, and better protection against typical user mishaps.
|
||||
|
||||
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
|
||||
and an upcomming integrated application for manipulating and writing
|
||||
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
|
||||
by these enhancements: growing of overwriteable media and disk files.
|
||||
Taking again a bow towards Andy Polyakov.
|
||||
|
||||
- 26th Januar 2008 version 0.4.2 rectifies the version numbering so that we
|
||||
reliably release libburn.so.4 as should have been done since libburn-0.3.2.
|
||||
cdrskin now is by default linked dynamically and does a runtime check
|
||||
to ensure not to be started with a libburn which is older than itself.
|
||||
|
||||
- 3rd Feb 2008 libisofs-0.2.x (.so.5) has been deprecated.
|
||||
|
||||
- 14th Feb 2008 libisofs-0.6.2 permanently replaces the old libisofs-0.2.x.
|
||||
It is the first release of new libisofs.so.6 which will guarantee future
|
||||
API/ABI compatibility for its whole feature set.
|
||||
|
||||
- 15th Feb 2008 libisoburn-0.1.0 (.so.1) coordinates libisofs and libburn for
|
||||
the purpose of ISO image reading and writing. It emulates multi-session on
|
||||
overwriteable media. Application xorriso makes use of all three libraries.
|
||||
|
||||
- 8th Apr 2008 libburn-0.4.4 has proven to be capable of burning to DVD+R/DL
|
||||
and read performance on disk file pseudo-drives has been improved.
|
||||
|
||||
- 27th Apr 2008 libisofs-0.6.4 can now read data file content from images
|
||||
and can map pieces of disk files onto image files. Image directory iteration
|
||||
has been enhanced. Input data streams and extended information have been
|
||||
exposed in the API to allow future development.
|
||||
|
||||
- 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of
|
||||
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
|
||||
xorriso makes use of new libisofs features by performing incremental
|
||||
updates of directory trees and by cutting oversized data files into
|
||||
pieces. A primitive single session emulation of cdrecord and mkisofs is
|
||||
provided.
|
||||
|
||||
- 10th May 2008 libburn-0.4.6 supports formatting and writing of BD-RE,
|
||||
full nominal speed for DVD-RAM and BD-RE. cdrskin has a unified blank
|
||||
type with automatic media state recognition.
|
||||
|
||||
- 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by
|
||||
libburn-0.4.8 to allow libisoburn emulation of multisession on those media.
|
||||
|
||||
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
|
||||
on overwriteble media and disk files.
|
||||
|
||||
- 1st Jun 2008 libisofs-0.6.6 fixes some problems around device files.
|
||||
|
||||
- 3rd Jun 2008 libisoburn-0.1.8 fixes a bug with overwriteable media.
|
||||
|
||||
- 23rd Jun 2008 libisoburn-0.2.0 introduces extraction of files from
|
||||
ISO images.
|
||||
|
||||
- 16th Jul 2008 libburn-0.5.0 handles systems with no /dev/sr* but only
|
||||
/dev/scd*.
|
||||
|
||||
- 19th Jul 2008 libisoburn/xorriso-0.2.2 can do multi-session in mkisofs
|
||||
and cdrecord style. xorriso now can serve underneath growisofs.
|
||||
|
||||
- 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be
|
||||
enumerable in order to be adressable. Enumeration is enhanced by examining
|
||||
/proc/sys/dev/cdrom/info.
|
||||
|
||||
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
|
||||
with data retrieval option.
|
||||
|
||||
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which allows very
|
||||
large data files in the image.
|
||||
|
||||
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
|
||||
capabilities of libisofs.
|
||||
|
||||
- 6th Oct 2008 libburn-0.5.4 adjusts the changes of 0.5.2 to the needs of
|
||||
Linux kernel 2.4 and introduces human readable SCSI error messages.
|
||||
|
||||
- 6th Oct 2008 libisofs-0.6.10 fixes two bugs which prevented adding and
|
||||
manipulation of ISOLINUX boot images.
|
||||
|
||||
- 15th Oct 2008 libisoburn/xorriso-0.2.8 can activate and maintain an
|
||||
ISOLINUX boot image by an EL Torito boot record.
|
||||
|
||||
- 12th Nov 2008 libburn-0.5.6 fixes usage of freed memory by the fifo thread
|
||||
of an aborted burn run.
|
||||
|
||||
- 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly
|
||||
and allows to produce ISO images which resemble old mkisofs images.
|
||||
|
||||
- 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character
|
||||
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
|
||||
signature, and for producing ISO images with MBR which boot from hard disk
|
||||
or USB stick. Three minor bugs were fixed.
|
||||
|
||||
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
|
||||
and improves BD-RE formatting.
|
||||
|
||||
- 9th Dec 2008 Our project received a donation from Thomas Weber.
|
||||
|
||||
- 2nd Jan 2009 libburn-0.6.0 allows to format BD-R and to write to either
|
||||
formatted or unformatted BD-R.
|
||||
|
||||
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
|
||||
mounting older sessions from all kinds of media. Pseudo-drives outside the
|
||||
/dev/ tree can be addressed without prefix "stdio:".
|
||||
|
||||
- 20th Feb 2009 libburn-0.6.2 source release now compiles out of the box
|
||||
on FreeBSD.
|
||||
|
||||
- 28 Feb 2009 libisofs-0.6.14 can record ACLs and Extended Attributes xattr
|
||||
in its ISO images.
|
||||
|
||||
- 01 Mar 2009 libisoburn-0.3.4. xorriso makes use of the ACL and xattr
|
||||
capabilities provided by libisofs for xorriso backup features.
|
||||
|
||||
- 11 Mar 2009 libisofs-0.6.16 of libisofs fixes two bugs which on Solaris
|
||||
prevented to navigate the ISO images by ".." and to recognize the Rock Ridge
|
||||
extensions of ISO images. The ban to build libisofs on operating systems
|
||||
other than Linux and FreeBSD has been lifted.
|
||||
|
||||
- 13 Mar 2009 libburn-0.6.4 got a dummy adapter for SCSI/MMC command transport.
|
||||
It will show no drives and thus libburn will only be able to perform
|
||||
operations on "stdio:" pseudo drives. Nevertheless this allowed to lift the
|
||||
ban to build libburn on operating systems other than Linux and FreeBSD.
|
||||
|
||||
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
|
||||
in order to be mountable where mkisofs images are mountable.
|
||||
|
||||
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
|
||||
Built-in filters allow compression to formats gzip and zisofs. External
|
||||
filter processes allow arbitrary data conversions like encryption.
|
||||
|
||||
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
|
||||
perform content filtering of data files.
|
||||
|
||||
- 08 May 2009 libburn-0.6.6 fixes a bug with aborting on broken output pipe
|
||||
and a bug with device scan on FreeBSD.
|
||||
|
||||
- 31 May 2009 libisofs-0.6.20 can record hard link relations in ISO images
|
||||
and offers support with restoring them to disk. Current Linux kernels will
|
||||
mount images with such hard links but will attribute a unique inode number
|
||||
to each file.
|
||||
|
||||
- 28 Jun 2009 libisoburn-0.4.0: xorriso can record and restore hard link
|
||||
relations of files. Performance of data reading has been improved. Option
|
||||
-find now supports logical operators with its tests.
|
||||
|
||||
- 14 Jul 2009 libburn-0.6.8 fixes bugs and shortcommings with old MMC-1 drives
|
||||
and with large SCSI bus numbers as handed out by Linux for USB drives.
|
||||
|
||||
- 20 Jul 2009 libisoburn-0.4.0.pl01 fixes a regression in xorriso which caused
|
||||
data loss in older sessions if xorriso was used underneath growisofs.
|
||||
Affected are releases since libisoburn-0.3.2 in january 2009.
|
||||
|
||||
- 25 Aug 2009 libisofs-0.6.22 can record MD5 checksums for the whole session
|
||||
and for each single data file. Checksum tags allow to verify superblock and
|
||||
directory tree before importing them.
|
||||
|
||||
- 27 Aug 2009 libburn-0.7.0 allows to calm down a drive and to inquire its
|
||||
supported profiles. It works around some pitfalls with U3 enhanced memory
|
||||
sticks which emulate a CD-ROM.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
59
acinclude.m4
59
acinclude.m4
@ -1,9 +1,11 @@
|
||||
AC_DEFUN([TARGET_SHIZZLE],
|
||||
[
|
||||
ARCH=""
|
||||
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
|
||||
|
||||
AC_MSG_CHECKING([target operating system])
|
||||
|
||||
|
||||
case $target in
|
||||
*-*-linux*)
|
||||
ARCH=linux
|
||||
@ -12,11 +14,66 @@ AC_DEFUN([TARGET_SHIZZLE],
|
||||
*-*-freebsd*)
|
||||
ARCH=freebsd
|
||||
LIBBURN_ARCH_LIBS=-lcam
|
||||
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
||||
;;
|
||||
*)
|
||||
AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||
ARCH=
|
||||
LIBBURN_ARCH_LIBS=
|
||||
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_RESULT([$ARCH])
|
||||
])
|
||||
|
||||
|
||||
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||
dnl
|
||||
AC_DEFUN([LIBBURNIA_SET_PKGCONFIG],
|
||||
[
|
||||
### for testing --enable-libdir-pkgconfig on Linux
|
||||
### LIBBURNIA_PKGCONFDIR="$libdir"data/pkgconfig
|
||||
|
||||
if test "x$LIBBURNIA_PKGCONFDIR" = "x$libdir"/pkgconfig
|
||||
then
|
||||
dummy=dummy
|
||||
else
|
||||
AC_ARG_ENABLE(libdir-pkgconfig,
|
||||
[ --enable-libdir-pkgconfig Install to $libdir/pkgconfig on any OS, default=no],
|
||||
, enable_libdir_pkgconfig="no")
|
||||
AC_MSG_CHECKING([for --enable-libdir-pkgconfig])
|
||||
if test "x$enable_libdir_pkgconfig" = xyes
|
||||
then
|
||||
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_libdir_pkgconfig])
|
||||
fi
|
||||
|
||||
libburnia_pkgconfig_override="no"
|
||||
AC_ARG_ENABLE(pkgconfig-path,
|
||||
[ --enable-pkgconfig-path=DIR Absolute path of directory for libisofs-*.pc],
|
||||
libburnia_pkgconfig_override="yes" , enable_pkgconfig_path="none")
|
||||
AC_MSG_CHECKING([for overridden pkgconfig directory path])
|
||||
if test "x$enable_pkgconfig_path" = xno
|
||||
then
|
||||
libburnia_pkgconfig_override="no"
|
||||
fi
|
||||
if test "x$enable_pkgconfig_path" = x -o "x$enable_pkgconfig_path" = xyes
|
||||
then
|
||||
libburnia_pkgconfig_override="invalid argument"
|
||||
fi
|
||||
if test "x$libburnia_pkgconfig_override" = xyes
|
||||
then
|
||||
LIBBURNIA_PKGCONFDIR="$enable_pkgconfig_path"
|
||||
AC_MSG_RESULT([$LIBBURNIA_PKGCONFDIR])
|
||||
else
|
||||
AC_MSG_RESULT([$libburnia_pkgconfig_override])
|
||||
fi
|
||||
AC_SUBST(LIBBURNIA_PKGCONFDIR)
|
||||
|
||||
dnl For debugging only
|
||||
### AC_MSG_RESULT([LIBBURNIA_PKGCONFDIR = $LIBBURNIA_PKGCONFDIR])
|
||||
|
||||
])
|
||||
|
||||
|
104
cdrskin/README
104
cdrskin/README
@ -4,15 +4,19 @@
|
||||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||
Integrated sub project of libburnia-project.org but also published via:
|
||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||
http://scdbackup.sourceforge.net/cdrskin-0.3.9.tar.gz
|
||||
Copyright (C) 2006-2007 Thomas Schmitt, provided under GPL version 2.
|
||||
http://scdbackup.sourceforge.net/cdrskin-0.7.0.pl00.tar.gz
|
||||
|
||||
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
||||
most of the libburn features from the command line.
|
||||
|
||||
Currently it is only supported on Linux with kernels >= 2.4.
|
||||
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
||||
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
||||
On other X/Open compliant systems there will only be emulated drives, but no
|
||||
direct MMC operation on real CD/DVD/BD drives.
|
||||
|
||||
By using this software you agree to the disclaimer at the end of this text
|
||||
"This software is provided as is. There is no warranty implied and ..."
|
||||
@ -20,17 +24,17 @@ By using this software you agree to the disclaimer at the end of this text
|
||||
|
||||
Compilation, First Glimpse, Installation
|
||||
|
||||
Obtain cdrskin-0.3.9.tar.gz, take it to a directory of your choice and do:
|
||||
Obtain cdrskin-0.7.0.pl00.tar.gz, take it to a directory of your choice and do:
|
||||
|
||||
tar xzf cdrskin-0.3.9.tar.gz
|
||||
cd cdrskin-0.3.9
|
||||
tar xzf cdrskin-0.7.0.pl00.tar.gz
|
||||
cd cdrskin-0.7.0
|
||||
|
||||
Within that directory execute:
|
||||
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
|
||||
This will already produce a cdrskin binary. But it might be necessary to
|
||||
This will already produce a cdrskin binary. But it will be necessary to
|
||||
install libburn in order to use this binary. Installation of libburn is
|
||||
beyond the scope of cdrskin. For this, see included libburn docs.
|
||||
|
||||
@ -44,11 +48,21 @@ Version identification and help texts available afterwards:
|
||||
cdrskin/cdrskin -help
|
||||
man cdrskin/cdrskin.1
|
||||
|
||||
|
||||
Install (eventually as superuser) cdrskin to a directory where it can be found:
|
||||
The command for global installation of both, libburn and cdrskin is
|
||||
make install
|
||||
If the library libburn.so.4 is not found with a test run of cdrskin, then
|
||||
try whether command
|
||||
ldconfig
|
||||
makes it accessible. With the statically linked binary this should not matter.
|
||||
|
||||
With that static binary you may as well do the few necessary actions manually.
|
||||
If cdrskin was already installed by a previous version, or by "make install"
|
||||
in the course of this installation, then find out where:
|
||||
which cdrskin
|
||||
Copy your standalone binary to exactly the address which you get as reply
|
||||
Copy your standalone binary to exactly the address which you get as reply.
|
||||
E.g.:
|
||||
|
||||
cp cdrskin/cdrskin /usr/bin/cdrskin
|
||||
|
||||
@ -108,6 +122,11 @@ as listed device files. This addressing via e.g. /dev/sr0 or /dev/scd1 is
|
||||
compatible with generic read programs like dd and with write program growisofs.
|
||||
For finding /dev/sg1 from /dev/sr0, the program needs rw-access to both files.
|
||||
|
||||
A behavioral conflict is known between any burn software and demons like hald
|
||||
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
|
||||
You may have to keep your hald away from the drive. See for example
|
||||
http://www.freebsd.org/gnome/docs/halfaq.html
|
||||
|
||||
|
||||
Usage examples
|
||||
|
||||
@ -129,8 +148,8 @@ Obtain some info about the drive
|
||||
Obtain some info about the drive and the inserted media
|
||||
cdrskin dev=0,1,0 -atip -v
|
||||
|
||||
Make used CD-RW or used unformatted DVD-RW writeable again
|
||||
cdrskin -v dev=0,1,0 blank=fast -eject
|
||||
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
||||
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
||||
|
||||
Format DVD-RW to avoid need for blanking before re-use
|
||||
cdrskin -v dev=0,1,0 blank=format_overwrite
|
||||
@ -142,18 +161,18 @@ Burn image file my_image.iso to media
|
||||
cdrskin -v dev=0,1,0 speed=12 fs=8m driveropts=burnfree padsize=300k \
|
||||
-eject my_image.iso
|
||||
|
||||
Write multi-session to the same CD , DVD-R[W] or DVD+R
|
||||
Write multi-session to the same CD , DVD-R[W] or DVD+R[/DL]
|
||||
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
|
||||
cdrskin dev=/dev/hdc padsize=300k -multi 2.iso
|
||||
cdrskin dev=/dev/hdc padsize=300k -multi 3.iso
|
||||
cdrskin dev=/dev/hdc padsize=300k 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
|
||||
find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 -tao \
|
||||
find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 \
|
||||
driveropts=burnfree padsize=300k -
|
||||
|
||||
Burn 6 audio tracks from files with different formats to CD (not to any DVD).
|
||||
@ -176,8 +195,6 @@ See output of command
|
||||
cdrskin --list_ignored_options
|
||||
If you have use cases for them, please report your wishes and expectations.
|
||||
|
||||
DVD support is restricted to single layer DVD for now. Double layer media
|
||||
are implemented but untested.
|
||||
On the other hand, the capability of multi-session and of writing streams
|
||||
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
|
||||
|
||||
@ -252,17 +269,30 @@ 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 , DVD-RAM , BD-RE
|
||||
|
||||
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
|
||||
These random access 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.
|
||||
Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second) or BD units
|
||||
(1x = 4,495,625 bytes/second). Currently there is no difference between -sao
|
||||
and -tao. If ever, then -tao will be the mode which preserves the current
|
||||
behavior.
|
||||
|
||||
BD-RE media need formatting before first use. cdrskin option "blank=as_needed"
|
||||
recognizes unformatted BD-RE and applies a lengthy formatting run.
|
||||
|
||||
During write operations DVD-RAM and BD-RE automatically apply Defect
|
||||
Management. This usually slows them down to half nominal speed. If drive
|
||||
and media produce flawless results anyway, then one can try to reach full
|
||||
nominal speed by option "stream_recording=on".
|
||||
In this case bad blocks are not detected during write and not even previously
|
||||
known bad blocks are avoided. So you have to make your own readability tests
|
||||
and go back to half speed as soon as the first read errors show up.
|
||||
Instead of "on" one may also set a start address for stream recording.
|
||||
Like "stream_recording=100m". This will write slowly to the first 100 MB of
|
||||
the media and accelerate when writing to higher addresses.
|
||||
|
||||
Program growisofs can append to an ISO filesystem on DVD+RW by additionally
|
||||
manipulating the first session. Meanwhile cdrskin can do the same.
|
||||
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
|
||||
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
|
||||
on overwriteable media.
|
||||
@ -331,11 +361,24 @@ Incremental Streaming afterwards. So blank=fast will do full blanking.
|
||||
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
|
||||
|
||||
|
||||
DVD+R
|
||||
DVD+R , DVD+R DL , BD-R
|
||||
|
||||
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
|
||||
into an own session, though.
|
||||
|
||||
DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address
|
||||
of the layer break where a reading drive might show some delay while switching
|
||||
between both media layers.
|
||||
|
||||
BD-R are sold unformatted blank. If used without initial formatting then the
|
||||
drive is supposed to format them to maximum payload size with no Defect
|
||||
Management (see also above with BD-RE).
|
||||
If Defect Management is desired then BD-R need to be formatted before the
|
||||
first attempt to write a session to them.
|
||||
blank=format_if_needed will detect the situation and eventually apply
|
||||
default sized Defect Management formatting.
|
||||
blank=format_defectmgt_* will apply non-default parameters to formatting.
|
||||
|
||||
|
||||
Emulated Drives
|
||||
|
||||
@ -384,9 +427,9 @@ Don't blame me or other authors of libburn if anything goes wrong.
|
||||
Actually, in case of severe trouble, nearly always the drive and the media
|
||||
are the cause. Any mistake of the burn program is supposed to be caught
|
||||
by the drive's firmware and to lead to mere misburns.
|
||||
The worst mishaps which hit the author implied the need to reboot the
|
||||
The worst mishaps which hit the author imposed the need to reboot the
|
||||
system because of drives gnawing endlessly on ill media. Permanent hardware
|
||||
damage did not occur in 1.5 years of development.
|
||||
damage did not occur in 3.5 years of development. But one never knows ...
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -398,9 +441,8 @@ contributions in a due way.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -415,7 +457,7 @@ contributions in a due way.
|
||||
Based on and sub project of:
|
||||
libburnia-project.org
|
||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
||||
|
||||
libburnia-project.org is inspired by and in other components still containing
|
||||
parts of
|
||||
|
@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
|
||||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-release"
|
||||
|
||||
skin_release="0.3.8"
|
||||
skin_release="0.7.0"
|
||||
patch_level=".pl00"
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
||||
@ -58,7 +58,8 @@ 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_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
||||
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
||||
bintarget_static="$bintarget_dynamic"-static
|
||||
|
||||
if test -d "$changes"
|
||||
@ -103,9 +104,9 @@ cdrskin_target="$target"/cdrskin
|
||||
libburn_target="$target"/libburn
|
||||
|
||||
# Create version timestamp
|
||||
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||
echo "$timestamp"
|
||||
echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h
|
||||
# timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||
# echo "$timestamp"
|
||||
# echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h
|
||||
|
||||
# Add the cdrskin files
|
||||
if test -e "$cdrskin_target"
|
||||
@ -154,6 +155,10 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove libcevap
|
||||
rm -rf "$target"/libcevap
|
||||
|
||||
|
||||
# Remove unwanted SVN stuff (TODO: avoid downloading it)
|
||||
for i in "$target"/.svn "$target"/*/.svn
|
||||
do
|
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
|
||||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-develop"
|
||||
|
||||
skin_release="0.3.9"
|
||||
skin_release="0.7.1"
|
||||
patch_level=""
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
||||
@ -58,7 +58,7 @@ 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_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
||||
bintarget_static="$bintarget_dynamic"-static
|
||||
|
||||
if test -d "$changes"
|
||||
@ -143,6 +143,9 @@ rm "$cdrskin_target"/doener_*.gif "$cdrskin_target"/doener_*.png
|
||||
# Remove automatically generated HTML man page
|
||||
rm "$cdrskin_target"/man_1_cdrskin.html
|
||||
|
||||
# Remove libcevap
|
||||
rm -rf "$target"/libcevap
|
||||
|
||||
# Remove all add_ts_changes_to_libburn besides this one
|
||||
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
|
||||
do
|
||||
@ -222,6 +225,8 @@ tar czf "$cdrskin_tarball" "$target"
|
||||
"$compile_cmd" $compile_static_opts -libburn_svn -O2 -do_strip
|
||||
cp "$compile_result" "../$bintarget_static"
|
||||
fi
|
||||
# "$compile_cmd" -libburn_svn -O2 -do_diet -do_strip
|
||||
# cp "$compile_result" "../$bintarget_dynamic"_diet
|
||||
"$man_to_html_cmd"
|
||||
mv "$man_page_html" ..
|
||||
)
|
@ -2,7 +2,7 @@
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH CDRSKIN 1 "September 26, 2007"
|
||||
.TH CDRSKIN 1 "May 07, 2009"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@ -16,8 +16,7 @@
|
||||
.\" .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.
|
||||
cdrskin \- burns preformatted data to CD, DVD, and BD via libburn.
|
||||
.SH SYNOPSIS
|
||||
.B cdrskin
|
||||
.RI [ options | track_source_addresses ]
|
||||
@ -29,13 +28,15 @@ via libburn.
|
||||
.\" 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.
|
||||
in a compatible way for CD media. With DVD and BD it has its own ways.
|
||||
You do not need to be superuser for its daily usage.
|
||||
.SS
|
||||
.B Overview of features:
|
||||
.br
|
||||
Blanking of CD-RW and DVD-RW.
|
||||
.br
|
||||
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
|
||||
.br
|
||||
Burning of data or audio tracks to CD,
|
||||
.br
|
||||
either in versatile Track at Once mode (TAO)
|
||||
@ -44,13 +45,13 @@ 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.
|
||||
or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R.
|
||||
.br
|
||||
Single session on DVD-RW or DVD-R (Disk-at-once).
|
||||
.br
|
||||
Single session or emulated ISO-9660 multi-session
|
||||
.br
|
||||
on overwriteable DVD+RW, DVD-RW, DVD-RAM,
|
||||
on overwriteable DVD+RW, DVD-RW, DVD-RAM, BD-RE
|
||||
.br
|
||||
or on data file or block device.
|
||||
.br
|
||||
@ -66,9 +67,9 @@ Write mode selection
|
||||
.br
|
||||
Recordable CD Media
|
||||
.br
|
||||
Sequentially Recordable DVD Media
|
||||
Sequentially Recordable DVD or BD Media
|
||||
.br
|
||||
Overwriteable DVD Media
|
||||
Overwriteable DVD or BD Media
|
||||
.br
|
||||
Drive preparation and addressing
|
||||
.br
|
||||
@ -96,7 +97,7 @@ 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.
|
||||
resp. by music CD players. With DVD and BD 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
|
||||
@ -107,8 +108,9 @@ 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.
|
||||
produced by programs mkisofs or genisoimage or xorriso.
|
||||
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
|
||||
@ -148,8 +150,8 @@ read-only. Closing is done automatically unless option
|
||||
is given which keeps the media appendable.
|
||||
.br
|
||||
Write mode
|
||||
-tao allows to use track source of unpredictable length (like stdin) and allows
|
||||
to write further sessions to appendable media.
|
||||
-tao allows to use track sources 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
|
||||
@ -159,14 +161,16 @@ round of overwriting. Usually
|
||||
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.
|
||||
Multiple cycles of blanking and overwriting with random numbers might be
|
||||
needed.
|
||||
.SS
|
||||
.B Sequentially Recordable DVD Media:
|
||||
.B Sequentially Recordable DVD or BD Media:
|
||||
.br
|
||||
Currently DVD-RW, DVD-R and DVD+R can be used for the Sequential recording
|
||||
model.
|
||||
Currently DVD-RW, DVD-R , DVD+R[/DL], and BD-R can be used for the Sequential
|
||||
recording model. It resembles the model of CD media. Only DVD-RW can be
|
||||
blanked and re-used from scratch.
|
||||
.br
|
||||
DVD-RW must be in state "Sequential Recording".
|
||||
DVD-RW are sequential media if they are 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
|
||||
@ -198,25 +202,27 @@ unpredicted length and to keep media appendable by option
|
||||
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.
|
||||
The write modes for DVD+R[/DL] and BD-R resemble those with DVD-R except that
|
||||
each track gets wrapped in an own session. There is no -dummy writing
|
||||
with DVD+R[/DL] or BD-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
|
||||
BD-R may be formatted before first use to enable the Defect Management which
|
||||
might catch and repair some bad spots at the expense of slow speed
|
||||
even with flawless media.
|
||||
.br
|
||||
.B Note:
|
||||
Option -multi might make DVD media unreadable in some DVD-ROM drives.
|
||||
Best reader compatibility is achieved without it
|
||||
(i.e. by single session media).
|
||||
.SS
|
||||
.B Overwriteable DVD Media:
|
||||
.B Overwriteable DVD or BD Media:
|
||||
.br
|
||||
Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
|
||||
.br
|
||||
DVD+RW and DVD-RAM media need no special initial formatting. They offer a
|
||||
single continuous data area for blockwise random access.
|
||||
Currently types DVD+RW, DVD-RW, DVD-RAM and BD-RE can be overwritten via
|
||||
cdrskin.
|
||||
.br
|
||||
Option -audio is not allowed. Only one track is allowed.
|
||||
Option -multi cannot mark a recognizeable end of overwriteable media.
|
||||
@ -229,6 +235,12 @@ media get treated as blank regardless wether they hold data or not.
|
||||
.br
|
||||
Currently there is no difference between -sao and -tao. If ever, then -tao
|
||||
will be the mode which preserves the current behavior.
|
||||
.PP
|
||||
DVD+RW and DVD-RAM media need no special initial formatting. They offer a
|
||||
single continuous data area for blockwise random access. BD-RE need
|
||||
explicit formatting before use. See
|
||||
.B blank=as_needed
|
||||
or blank=format_defectmgt .
|
||||
.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
|
||||
@ -242,7 +254,7 @@ that it has to be formatted again. If in doubt, just give it a try.
|
||||
.SS
|
||||
.B Drive preparation and addressing:
|
||||
.br
|
||||
The drives, either CD burners or DVD burners, are accessed via addresses which
|
||||
The drives, CD, DVD, or BD 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
|
||||
@ -278,7 +290,9 @@ and device files which have the same SCSI address parameters (e.g. /dev/sg0).
|
||||
.SS
|
||||
.B Emulated drives:
|
||||
.br
|
||||
Option --allow_emulated_drives enables addressing of pseudo-drives
|
||||
Option
|
||||
.B --allow_emulated_drives
|
||||
enables addressing of pseudo-drives
|
||||
which get emulated on top of filesystem objects. Regular data files and
|
||||
block devices result in pseudo-drives which behave much like DVD-RAM.
|
||||
If the given address does not exist yet but its directory exists, then
|
||||
@ -329,7 +343,8 @@ 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.
|
||||
With DVD media print "book type:" and a media type text. With BD media
|
||||
print "Mounted Media:" and media type text.
|
||||
.TP
|
||||
.BI \-audio
|
||||
Announces that the subsequent tracks are to be burned as audio.
|
||||
@ -340,16 +355,26 @@ stereo. For little-endian byte order (which is usual on PCs) use option
|
||||
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.
|
||||
Option -audio may be used only with CD media and not with DVD or BD.
|
||||
.TP
|
||||
.BI blank= type
|
||||
Blank a CD-RW, a DVD-RW, or format a DVD+/-RW.
|
||||
Blank a CD-RW, DVD-RW, or format a DVD-RW, DVD+RW, DVD-RAM, BD.
|
||||
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.
|
||||
as_needed
|
||||
Try to make the media ready for writing from scratch. If it needs formatting,
|
||||
then format it. If it is not blank, then try to apply blank=fast.
|
||||
It is a reason to abort if the media cannot assume thoroughly writeable state,
|
||||
e.g. if it is non-blank write-once.
|
||||
.br
|
||||
This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use
|
||||
blank=format_overwriteable. Blank unformatted BD-R stay unformatted.
|
||||
.br
|
||||
(Note: blank=as_needed is not an original cdrecord option.)
|
||||
.TP
|
||||
The following blank types are specific to particular media familes. Use them if special features are desired.
|
||||
.TP
|
||||
all
|
||||
Blank an entire CD-RW or an unformatted DVD-RW.
|
||||
@ -359,10 +384,36 @@ fast
|
||||
Minimally blank an entire CD-RW or blank an unformatted DVD-RW.
|
||||
(See also --prodvd_cli_compatible, --grow_overwriteable_iso)
|
||||
.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_* 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).
|
||||
.TP
|
||||
format_if_needed
|
||||
Format a media if it is not formatted yet,
|
||||
and if cdrskin supports formatting for the media type,
|
||||
and if formatting will not happen automatically during write.
|
||||
This currently applies to unformatted DVD-RW, DVD-RAM, BD-RE,
|
||||
and blank unformatted BD-R.
|
||||
Eventually the appropriate default formatting is chosen.
|
||||
If other media or states are encountered then nothing happens.
|
||||
.br
|
||||
The following formatting types are more specialized to particular
|
||||
media families.
|
||||
.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.)
|
||||
(Note: blank=format_* are not original cdrecord options.)
|
||||
.TP
|
||||
format_overwrite_quickest
|
||||
Like format_overwrite without creating a 128 MiB trailblazer session.
|
||||
@ -381,19 +432,59 @@ This option treats already formatted media even if not option -force is given.
|
||||
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.
|
||||
format_defectmgt
|
||||
Format DVD-RAM or BD to reserve the default amount of spare blocks for
|
||||
defect management.
|
||||
.br
|
||||
(Note: blank=deformat_sequential* are not original cdrecord options.)
|
||||
The following format_defectmgt_* allow to submit user wishes which
|
||||
nevertheless have to match one of the available formats. These formats are
|
||||
offered by the drive after examining the media.
|
||||
.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).
|
||||
format_defectmgt_cert_off
|
||||
Disable the usual media quality certification in order to save time and
|
||||
format to default size.
|
||||
The certification setting persists even if subsequent blank= options override
|
||||
the size of the format selection.
|
||||
.br
|
||||
Whether formatting without certification works properly depends much on the
|
||||
drive. One should check the "Format status:" from --list_formats afterwards.
|
||||
.TP
|
||||
format_defectmgt_cert_on
|
||||
Re-enable the usual media quality certification and format to default size.
|
||||
The certification setting persists like with format_defectmgt_cert_off.
|
||||
.br
|
||||
Whether there happens certification at all depends much on the media state
|
||||
and the actually selected format descriptor.
|
||||
.TP
|
||||
format_defectmgt_max
|
||||
Format DVD-RAM or BD to reserve a maximum number of spare blocks.
|
||||
.TP
|
||||
format_defectmgt_min
|
||||
Format DVD-RAM or BD to reserve a minimum number of spare blocks.
|
||||
It might be necessary to format format_defectmgt_none first in order to get
|
||||
offered the most minmal spare blocks sizes for format_defectmgt_min.
|
||||
.TP
|
||||
format_defectmgt_none
|
||||
Format DVD-RAM or BD-RE to the largest available payload in the hope to disable
|
||||
defect management at all. This may or may not have a speed increasing effect.
|
||||
Unformatted blank BD-R will be left unformatted.
|
||||
.TP
|
||||
format_defectmgt_payload_<size>
|
||||
Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a
|
||||
number of bytes, eventually with suffixes "s", "k", "m". The largest number
|
||||
of spare blocks will be chosen which allows at least the given payload size.
|
||||
.TP
|
||||
format_by_index_<number>
|
||||
Format DVD-RW, DVD+RW, DVD-RAM or BD.
|
||||
The number after "format_by_index_" is used as index to the list of available
|
||||
format descriptors. This list can be obtained by option --list_formats.
|
||||
The numbers after text "Format idx" are the ones to be used with
|
||||
format_by_index_. Format descriptor lists are volatile. Do neither eject
|
||||
nor write the media between the run of --list_formats and the run of
|
||||
blank=format_by_index_ or else you may get a different format than desired.
|
||||
.TP
|
||||
help
|
||||
Print this list of blanking types.
|
||||
.RE
|
||||
.TP
|
||||
.BI \-checkdrive
|
||||
@ -534,7 +625,8 @@ 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.
|
||||
of programs mkisofs, genisoimage, or xorriso -as mkisofs.
|
||||
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.
|
||||
@ -546,8 +638,8 @@ To have a chance for working on overwriteable media, this option has to be
|
||||
accompanied by option --grow_overwriteable_iso.
|
||||
.TP
|
||||
.BI \-multi
|
||||
This option keeps the CD or unformatted DVD-R[W] appendable after the current
|
||||
session has been written.
|
||||
This option keeps CD, unformatted DVD-R[W], DVD+R, or BD-R 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
|
||||
@ -565,7 +657,7 @@ 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.
|
||||
This lba is the address of the 2048 byte block where the archive begins.
|
||||
.br
|
||||
With overwriteable DVD media, -multi cannot mark the end of the session.
|
||||
With overwriteable DVD or BD media, -multi cannot mark the end of the session.
|
||||
So when adding a new session this end has to be determined from the payload.
|
||||
Currently only ISO-9660 filesystems can be used that way. See option
|
||||
.B \--grow_overwriteable_iso
|
||||
@ -595,8 +687,8 @@ 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.
|
||||
Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once
|
||||
(DAO) mode.
|
||||
.br
|
||||
With CD this mode is able to put several audio tracks on media without
|
||||
producing audible gaps between them.
|
||||
@ -604,8 +696,8 @@ producing audible gaps between them.
|
||||
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.
|
||||
-sao is permissible with overwriteable DVD, or DVD+R[/DL], or BD 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
|
||||
@ -629,6 +721,7 @@ Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
|
||||
.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.
|
||||
With BD 1x = 4,495,625 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.
|
||||
Special speed settings are:
|
||||
@ -645,8 +738,8 @@ 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.
|
||||
Streaming mode, or DVD+R[/DL] without traditional -sao restrictions.
|
||||
This mode also applies pro-forma to overwriteable 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
|
||||
@ -776,8 +869,9 @@ be the only finalization. It is advised to eject the media afterwards because
|
||||
the write operations circumvent the usual system i/o with its caches and
|
||||
buffers. By ejecting, those invalid memory copies get surely discarded.
|
||||
.br
|
||||
Only few media can be written this way: DVD-RAM, RVD+RW and overwriteable
|
||||
DVD-RW. Writing is restricted to the already formatted area of the media.
|
||||
Only few media can be written this way: DVD-RAM, BD-RE, RVD+RW and
|
||||
overwriteable DVD-RW. Writing is restricted to the already formatted
|
||||
area of the media.
|
||||
.br
|
||||
Writing starts at byte 0 of the media or at the address given by option
|
||||
.B write_start_address= .
|
||||
@ -792,7 +886,7 @@ padded up to the necessary size by zeros. Size -1 revokes direct writing
|
||||
and switches back to normal session oriented writing.
|
||||
.br
|
||||
Both, write_start_address and direct_write_amount size must be aligned to a
|
||||
media dependend transaction size. With DVD-RAM and DVD+RW this is 2k, with
|
||||
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
|
||||
overwriteable DVD-RW it is 32k.
|
||||
.TP
|
||||
.BI fallback_program= command
|
||||
@ -872,6 +966,16 @@ With multi-session DVD, blank=fast will act like dvd+rw-format -blank=full .
|
||||
.br
|
||||
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
|
||||
.TP
|
||||
.BI \--list_formats
|
||||
List the available format descriptors as reported by the drive for the
|
||||
loaded media. Each descriptor line begins with "Format idx" and the
|
||||
descriptor's list index, followed by a ":", the format type, the number
|
||||
of payload blocks and that same number converted to MiB.
|
||||
.br
|
||||
The meaning of the format types is defined by the MMC standard
|
||||
with command FORMAT UNIT. A user will more be interested in the
|
||||
sizes than in the types.
|
||||
.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
|
||||
@ -928,8 +1032,8 @@ 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 kiB blocks, but better is 32 kiB.
|
||||
Set the address on media where to start writing the track. With DVD+RW, DVD-RAM
|
||||
or BD-RE byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB.
|
||||
With DVD-RW 32 kiB alignment is mandatory.
|
||||
.br
|
||||
Other media are not suitable for this option yet.
|
||||
@ -949,8 +1053,6 @@ 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
|
||||
@ -987,8 +1089,9 @@ 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_dev_family= sr | scd | sg
|
||||
Linux specific: Select a SCSI device file family to be used for drive command
|
||||
transactions. Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
||||
Linux specific: Select a SCSI device file family to be scanned for by
|
||||
options --devices and -scanbus.
|
||||
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
||||
on kernels >= 2.6 . This option allows to explicitely override that default
|
||||
in order to meet other programs at a common device file for each drive.
|
||||
On kernel 2.4 families sr and scd will find no drives.
|
||||
@ -1082,7 +1185,16 @@ Linux specific:
|
||||
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||
original cdrecord.
|
||||
.TP
|
||||
.BI stream_recording="on"|"off"|number
|
||||
By setting "on" request that compliance to the desired speed setting is
|
||||
preferred over management of write errors. With DVD-RAM and BD this can
|
||||
bring effective write speed near to the nominal write speed of the media.
|
||||
But it will also disable the automatic use of replacement blocks
|
||||
if write errors occur. It might as well be disliked or ignored by the drive.
|
||||
.br
|
||||
If a number is given, then error management stays enabled for all byte
|
||||
addresses below that number. Any number below 16s is the same as "off".
|
||||
.SH EXAMPLES
|
||||
.SS
|
||||
.B Get an overview of drives and their addresses:
|
||||
@ -1101,11 +1213,9 @@ 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:
|
||||
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
|
||||
.br
|
||||
cdrskin -v dev=/dev/sg1 blank=fast -eject
|
||||
.br
|
||||
cdrskin -v dev=/dev/dvd blank=all -eject
|
||||
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
||||
.SS
|
||||
.B Format DVD-RW to avoid need for blanking before re-use:
|
||||
.br
|
||||
@ -1119,7 +1229,7 @@ cdrskin -v dev=/dev/sr0 blank=deformat_sequential
|
||||
.br
|
||||
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
|
||||
.br
|
||||
-sao -eject padsize=300k my_image.iso
|
||||
blank=as_needed -eject padsize=300k my_image.iso
|
||||
.SS
|
||||
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW):
|
||||
.br
|
||||
@ -1127,17 +1237,17 @@ find . | afio -oZ - | \\
|
||||
.br
|
||||
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
|
||||
.br
|
||||
-tao padsize=300k -
|
||||
blank=as_needed padsize=300k -
|
||||
.SS
|
||||
.B Write multi-session to the same CD, DVD-R[W] or DVD+R:
|
||||
.B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R:
|
||||
.br
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso
|
||||
cdrskin dev=/dev/sr0 -v padsize=300k -multi 1.iso
|
||||
.br
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso
|
||||
cdrskin dev=/dev/sr0 -v padsize=300k -multi 2.iso
|
||||
.br
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso
|
||||
cdrskin dev=/dev/sr0 -v padsize=300k -multi 3.iso
|
||||
.br
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso
|
||||
cdrskin dev=/dev/sr0 -v padsize=300k 4.iso
|
||||
.SS
|
||||
.B Get multi-session info for option -C of program mkisofs:
|
||||
.br
|
||||
@ -1145,9 +1255,9 @@ 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:
|
||||
.B Inquire free space on media for a -multi run:
|
||||
.br
|
||||
x=$(cdrskin dev=/dev/sr0 -tao -multi \\
|
||||
x=$(cdrskin dev=/dev/sr0 -multi \\
|
||||
.br
|
||||
--tell_media_space 2>/dev/null)
|
||||
.br
|
||||
@ -1212,23 +1322,25 @@ Formatting data track sources for cdrskin:
|
||||
.br
|
||||
.BR mkisofs (8),
|
||||
.BR genisoimage (8),
|
||||
.BR xorriso (1),
|
||||
.BR afio (1),
|
||||
.BR star (1)
|
||||
.br
|
||||
.TP
|
||||
Other CD/DVD burn programs:
|
||||
Other CD/DVD/BD burn programs:
|
||||
.br
|
||||
.BR cdrecord (1),
|
||||
.BR wodim (1)
|
||||
.BR wodim (1),
|
||||
.BR xorriso (1)
|
||||
.br
|
||||
.TP
|
||||
For DVD burning (also tutor of libburn's DVD capabilities):
|
||||
For DVD/BD burning (also tutor of libburn's DVD/BD 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.
|
||||
This manual page was started by George Danchev <danchev@spnet.net> and
|
||||
is now maintained by Thomas Schmitt.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW, DVD+R, DVD+R/DL, DVD-RAM, BD-RE, BD-R, cdrecord, compatible, scdbackup">
|
||||
<META NAME="robots" CONTENT="follow">
|
||||
<TITLE>cdrskin homepage english</TITLE>
|
||||
</HEAD>
|
||||
@ -17,26 +17,29 @@
|
||||
</A>
|
||||
<P><H2> Homepage of </H2>
|
||||
<H1> cdrskin </H1>
|
||||
<!-- <FONT SIZE=+0><A HREF="cdrskin_ger.html">deutsch (german)</A></FONT> -->
|
||||
|
||||
<H2>Limited cdrecord compatibility wrapper for libburn</H2>
|
||||
</CENTER>
|
||||
|
||||
<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
|
||||
Burns preformatted data to CD, DVD, and BD media:<BR>
|
||||
CD-R, DVD-R, DVD+R, DVD+R/DL, BD-R, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
||||
</P>
|
||||
<P>
|
||||
|
||||
<HR>
|
||||
|
||||
<A HREF="#download">Direct hop to download links -></A>
|
||||
|
||||
<P>
|
||||
<H2>Hardware requirements:</H2>
|
||||
A CD/DVD recorder suitable for
|
||||
<A HREF="http://libburnia-project.org">http://libburnia-project.org</A> <BR>
|
||||
(SCSI , ATA , USB , or SATA writers compliant to standard MMC-3 for CD
|
||||
and to MMC-5 for DVD).
|
||||
About any CD, DVD, or BD recorder produced in the recent ten years.
|
||||
<BR>
|
||||
<A HREF="http://libburnia-project.org">libburn</A>
|
||||
supports recorders which are compliant to standards MMC-1 for CD and
|
||||
MMC-5 for DVD or BD. Linux and FreeBSD allow to access drives connected
|
||||
via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||
<BR>
|
||||
</P>
|
||||
|
||||
@ -46,6 +49,8 @@ and to MMC-5 for DVD).
|
||||
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
|
||||
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
||||
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
|
||||
<DT>or FreeBSD (with libc, of course) :</DT>
|
||||
<DD>ATAPI/CAM support has to be enabled in the kernel, see atapicam(4).</DD>
|
||||
<DT>libpthread</DT>
|
||||
<DD>is supposed to be a standard system component.</DD>
|
||||
</DL>
|
||||
@ -56,14 +61,18 @@ and to MMC-5 for DVD).
|
||||
GPL software included:<BR>
|
||||
</H2>
|
||||
<DL>
|
||||
<DT>libburn-0.3.8</DT>
|
||||
<DD>(by Derek Foreman, Ben Jansens, and team of libburnia-project.org)</DD>
|
||||
<DD>transfers data to CD and DVD</DD>
|
||||
<DT>libburn-0.7.0</DT>
|
||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||
developed and maintained since August 2006 by
|
||||
Thomas Schmitt from team of libburnia-project.org)
|
||||
</DD>
|
||||
<DD>transfers data to CD, DVD, BD</DD>
|
||||
</DL>
|
||||
</P>
|
||||
|
||||
<P>
|
||||
This program system has been tested on Intel/AMD Linux systems only.<BR>
|
||||
This program system has been tested on Intel/AMD Linux and FreeBSD systems
|
||||
only.<BR>
|
||||
Ports to other usable systems are appreciated. Reports are welcome.
|
||||
</P>
|
||||
|
||||
@ -83,10 +92,10 @@ Ports to other usable systems are appreciated. Reports are welcome.
|
||||
<DL>
|
||||
<DT>The most common options of cdrecord for data and audio on CD media
|
||||
are provided in a compatible way.<BR>
|
||||
On single layer DVD media cdrskin is able to perform any recording job
|
||||
On all DVD media except DVD-R DL, cdrskin is able to perform any recording job
|
||||
which is possible with cdrecord.
|
||||
Other than with cdrecord, options -multi and -tao are supported with
|
||||
certain DVD types.
|
||||
Other than with cdrecord, option -multi is supported with many DVD types and
|
||||
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW.
|
||||
</DT>
|
||||
<BR><BR>
|
||||
<DT>Get an overview of drives and their addresses</DT>
|
||||
@ -104,9 +113,8 @@ as listed by option --devices.</DT>
|
||||
<DD>$<KBD> cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -toc</KBD></DD>
|
||||
|
||||
<DT>Make used CD-RW or used unformatted DVD-RW writable again:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=fast -eject</KBD></DD>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/dvd blank=all -eject</KBD></DD>
|
||||
<DT>Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=as_needed -eject</KBD></DD>
|
||||
|
||||
<DT>Format DVD-RW to avoid need for blanking before re-use:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/sr0 blank=format_overwrite</KBD></DD>
|
||||
@ -117,31 +125,34 @@ as listed by option --devices.</DT>
|
||||
<DT>Write ISO-9660 filesystem image as only one to blank or formatted media:
|
||||
</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
|
||||
<DD><KBD> -sao -eject padsize=300k my_image.iso</KBD></DD>
|
||||
<DD><KBD> blank=as_needed -eject padsize=300k my_image.iso</KBD></DD>
|
||||
|
||||
<DT>Write compressed afio archive on-the-fly:</DT>
|
||||
<DD>$<KBD> find . | afio -oZ - | \</KBD></DD>
|
||||
<DD><KBD> cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
|
||||
<DD><KBD> -tao padsize=300k -</KBD></DD>
|
||||
<DD><KBD> blank=as_needed padsize=300k -</KBD></DD>
|
||||
|
||||
<DT>Write several sessions to the same CD, DVD-R[W] or DVD+R:</DT>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso</KBD>
|
||||
<DT>Write several sessions to the same CD, DVD-R[W] or DVD+R[/DL]:</DT>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi 1.iso</KBD>
|
||||
</DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso</KBD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi 2.iso</KBD>
|
||||
</DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso</KBD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi 3.iso</KBD>
|
||||
</DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso</KBD></DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k 4.iso</KBD></DD>
|
||||
|
||||
<DT>Get multi-session info for option -C of program mkisofs:</DT>
|
||||
<DD>$<KBD> c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)</KBD></DD>
|
||||
<DD>$<KBD> mkisofs ... -C "$c_values" ...</KBD></DD>
|
||||
|
||||
<DT>Inquire free space on media for a -tao -multi run:</DT>
|
||||
<DD>$<KBD> x=$(cdrskin dev=/dev/sr0 -tao -multi \</KBD></DD>
|
||||
<DT>Inquire free space on media for a -multi run:</DT>
|
||||
<DD>$<KBD> x=$(cdrskin dev=/dev/sr0 -multi \</KBD></DD>
|
||||
<DD><KBD> --tell_media_space 2>/dev/null)</KBD></DD>
|
||||
<DD>$<KBD> echo "Available: $x blocks of 2048 data bytes"</KBD></DD>
|
||||
|
||||
<DT>Accelerate BD-RE writing to full nominal speed after the first 250 MB</DT>
|
||||
<DD>$<KBD> cdrskin ... stream_recording=250m ...</KBD>
|
||||
|
||||
<DT>Write audio tracks to CD:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
|
||||
<DD><KBD> track1.wav track2.au -audio -swab track3.raw</KBD></DD>
|
||||
@ -165,39 +176,51 @@ man cdrecord</A></KBD></DD>
|
||||
this "don't bother Joerg" demand.)
|
||||
</DD>
|
||||
</DL>
|
||||
|
||||
Testers wanted who are willing to risk some double layer DVD media.
|
||||
<DL>
|
||||
<DT>Learn to know a more versatile way to burn ISO 9660 formatted data</DT>
|
||||
<DD>
|
||||
Standalone ISO 9660 multi-session CD/DVD/BD tool
|
||||
<A HREF="http://scdbackup.sourceforge.net/xorriso_eng.html">xorriso</A>.
|
||||
</DD>
|
||||
</DL>
|
||||
|
||||
</P>
|
||||
|
||||
<HR>
|
||||
|
||||
<A NAME="download"></A>
|
||||
|
||||
<P>
|
||||
<DL>
|
||||
<DT>Download as source code (see README):</DT>
|
||||
<DD><A HREF="cdrskin-0.3.8.pl00.tar.gz">cdrskin-0.3.8.pl00.tar.gz</A>
|
||||
(615 KB).
|
||||
<DD><A HREF="cdrskin-0.7.0.pl00.tar.gz">cdrskin-0.7.0.pl00.tar.gz</A>
|
||||
(820 KB).
|
||||
</DD>
|
||||
<DD>
|
||||
The "stable" cdrskin tarballs are source code identical with "stable"
|
||||
libburn releases or with "stabilized" libburn SVN snapshots. They get
|
||||
produced via a different procedure, though.<BR>
|
||||
The cdrskin tarballs are source code identical with libburn releases
|
||||
of the same version number.
|
||||
They get produced via a different procedure, though.<BR>
|
||||
cdrskin is part of libburn - full libburn is provided with cdrskin releases.
|
||||
</DD>
|
||||
|
||||
<!-- This is not offered any more since spring 2008
|
||||
<DD> </DD>
|
||||
<DT>Download as single x86 binaries (untar and move to /usr/bin/cdrskin):</DT>
|
||||
<DD><A HREF="cdrskin_0.3.8.pl00-x86-suse9_0.tar.gz">
|
||||
cdrskin_0.3.8.pl00-x86-suse9_0.tar.gz</A>, (90 KB),
|
||||
<DD><A HREF="cdrskin_0.4.2.pl00-x86-suse9_0.tar.gz">
|
||||
cdrskin_0.4.2.pl00-x86-suse9_0.tar.gz</A>, (110 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.8.pl00-x86-suse9_0-static.tar.gz">
|
||||
cdrskin_0.3.8.pl00-x86-suse9_0-static.tar.gz</A>, (290 KB), -static compiled,
|
||||
<DD><A HREF="cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz">
|
||||
cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 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>
|
||||
@ -220,53 +243,55 @@ cdrskin_0.3.8.pl00-x86-suse9_0-static.tar.gz</A>, (290 KB), -static compiled,
|
||||
<HR>
|
||||
|
||||
<P>
|
||||
Enhancements towards previous stable version cdrskin-0.3.6:
|
||||
Enhancements towards previous stable version cdrskin-0.6.8.pl00:
|
||||
<UL>
|
||||
<LI>Now able to cope with the peculiarities of Linux 2.4 USB</LI>
|
||||
<LI>Refusal to perform -dummy runs on media which cannot simulate burning</LI>
|
||||
<LI>Precautions against using the burner drive as track source</LI>
|
||||
<LI>New option modesty_on_drive= may help with hda -> hdb burns</LI>
|
||||
<LI>New option minbuf= , cdrecord compatible frontend of modesty_on_drive=</LI>
|
||||
<LI>New option --adjust_speed_to_drive</LI>
|
||||
</UL>
|
||||
|
||||
<LI>Adapted to pitfalls of U3 memory sticks which appear as CD-ROM drives</LI>
|
||||
<LI>Listing all supported profiles with option -atip -v</LI>
|
||||
<!--
|
||||
Bug fixes towards cdrskin-0.3.8.pl00:
|
||||
<UL>
|
||||
<LI>none yet</LI>
|
||||
</UL>
|
||||
<LI>none</LI>
|
||||
-->
|
||||
</UL>
|
||||
|
||||
</P>
|
||||
Bug fixes towards cdrskin-0.6.8.pl00:
|
||||
<UL>
|
||||
<LI>none</LI>
|
||||
<!--
|
||||
-->
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
|
||||
<P>
|
||||
<DL>
|
||||
<DT><H3>Development snapshot, version 0.3.9 :</H3></DT>
|
||||
<DD>Enhancements towards stable version 0.3.8.pl00:
|
||||
<DT><H3>Development snapshot, version 0.7.1 :</H3></DT>
|
||||
<DD>Enhancements towards current stable version 0.7.0.pl00:
|
||||
<UL>
|
||||
<LI>New option direct_write_amount=</LI>
|
||||
<LI>New option --grow_overwriteable_iso</LI>
|
||||
<LI>New option --allow_emulated_drives dev=stdio:<path></LI>
|
||||
<LI>More cdrecord options supported:
|
||||
-format, -inq, -load, -lock, -immed, -waiti</LI>
|
||||
<!--
|
||||
<LI>none yet</LI>
|
||||
<!--
|
||||
-->
|
||||
|
||||
</UL>
|
||||
</DD>
|
||||
|
||||
<DD>Bug fixes towards cdrskin-0.7.0.pl00:
|
||||
<UL>
|
||||
<LI>none yet</LI>
|
||||
<!--
|
||||
-->
|
||||
</UL>
|
||||
</DD>
|
||||
|
||||
<DD> </DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 0.3.9</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.3.9 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.3.9 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.3.9)</A></DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 0.7.1</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.1 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.1 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.1)</A></DD>
|
||||
<DD> </DD>
|
||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||
<DD>Download: <KBD><B>svn co http://svn.libburnia-project.org/libburn/trunk libburn</B>
|
||||
</KBD></DD>
|
||||
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make</B>
|
||||
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
|
||||
</KBD></DD>
|
||||
<DD>Build of SVN versions needs <A HREF="http://sources.redhat.com/autobook/">
|
||||
autotools</A> of at least version 1.7 installed.
|
||||
@ -274,22 +299,29 @@ But after the run of <KBD>./bootstrap</KBD>, only
|
||||
vanilla tools like make and gcc are needed.</DD>
|
||||
</DD>
|
||||
<DD> </DD>
|
||||
<DT>The following downloads are intended for adventurous end users or
|
||||
<DT>The following download is intended for adventurous end users or
|
||||
admins with full system souvereignty.</DT>
|
||||
<DD>Source (./bootstrap is already applied, build tested, for more see
|
||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||
</DD>
|
||||
<DD>
|
||||
<A HREF="cdrskin-0.3.9.tar.gz">cdrskin-0.3.9.tar.gz</A>
|
||||
(640 KB).
|
||||
<A HREF="cdrskin-0.7.1.tar.gz">cdrskin-0.7.1.tar.gz</A>
|
||||
(820 KB).
|
||||
</DD>
|
||||
|
||||
<!-- This is not offered any more since spring 2008
|
||||
|
||||
<DT>The following downloads are intended for adventurous end users or
|
||||
admins with full system souvereignty.</DT>
|
||||
<DD>Binary (untar and move to /usr/bin/cdrskin):</DD>
|
||||
<DD><A HREF="cdrskin_0.3.9-x86-suse9_0.tar.gz">
|
||||
cdrskin_0.3.9-x86-suse9_0.tar.gz</A>, (90 KB).
|
||||
<DD><A HREF="cdrskin_0.4.3-x86-suse9_0.tar.gz">
|
||||
cdrskin_0.4.3-x86-suse9_0.tar.gz</A>, (110 KB).
|
||||
</DD>
|
||||
<DD><A HREF="cdrskin_0.3.9-x86-suse9_0-static.tar.gz">
|
||||
cdrskin_0.3.9-x86-suse9_0-static.tar.gz</A>, (290 KB)
|
||||
<DD><A HREF="cdrskin_0.4.3-x86-suse9_0-static.tar.gz">
|
||||
cdrskin_0.4.3-x86-suse9_0-static.tar.gz</A>, (310 KB)
|
||||
</DD>
|
||||
-->
|
||||
|
||||
</DL>
|
||||
</P>
|
||||
|
||||
@ -307,7 +339,7 @@ Historic versions based on Derek's and Ben's
|
||||
<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.
|
||||
provide libburn with invaluable examples on how to deal with DVD and BD media.
|
||||
</P>
|
||||
|
||||
<HR>
|
||||
@ -315,14 +347,33 @@ provide libburn with invaluable examples on how to deal with DVD media.
|
||||
<A NAME="examples">
|
||||
<P>
|
||||
<DL>
|
||||
<DT>Example for a setup of device permissions. To be done by the superuser:</DT>
|
||||
<DT>(CD devices which offer no rw-permission are invisible to normal users.)
|
||||
<DT>Example for a setup of device permissions.</DT>
|
||||
<DT>
|
||||
Newer Linux distros enable rw-access for the desktop user automatically.
|
||||
So try as normal user whether all your drives are found.
|
||||
CD devices which offer no rw-permission will stay invisible.
|
||||
</DT>
|
||||
<DD>$ <KBD><B>cdrskin --devices</B></KBD></DD>
|
||||
<DT>If not all desired drives show up, become superuser and do again:</DT>
|
||||
</DT>
|
||||
<DD># <KBD><B>cdrskin --devices</B></KBD></DD>
|
||||
<DD><KBD>...</KBD></DD>
|
||||
<DD><KBD>0 dev='/dev/sr0' rwrwr- : 'TEAC' 'CD-ROM CD-532S'</KBD></DD>
|
||||
<DD><KBD>0 dev='/dev/sr0' rwr-r- : 'TEAC' 'CD-ROM CD-532S'</KBD></DD>
|
||||
<DD><KBD>1 dev='/dev/hdc' rwrw-- : 'LITE-ON' 'LTR-48125S'</KBD></DD>
|
||||
<DT>Most simple and most insecure is this equivalent
|
||||
of the usual cdrecord permissions u+s,a+x:</DT>
|
||||
<DD># <KBD><B>chmod a+rw /dev/sr0 /dev/hdc</B></KBD></DD>
|
||||
<DT>
|
||||
More secure is to put the permitted users into a group like
|
||||
"floppy", to assign /dev/sr0 /dev/hdc to this group,
|
||||
and to allow rw-access only to group members.
|
||||
</DT>
|
||||
<DD># <KBD><B>vi /etc/group</B></KBD></DD>
|
||||
<DD><KBD>...</KBD></DD>
|
||||
<DD><KBD>floppy:x:19:thomas,scdbackup</KBD></DD>
|
||||
<DD><KBD>...</KBD></DD>
|
||||
<DD># <KBD><B>chgrp floppy /dev/sr0 /dev/hdc</B></KBD></DD>
|
||||
<DD># <KBD><B>chmod g+rw /dev/sr0 /dev/hdc</B></KBD></DD>
|
||||
</DL>
|
||||
</P>
|
||||
|
||||
@ -337,6 +388,8 @@ Example how to setup K3b to use cdrskin for burning data CD projects.
|
||||
is a GUI frontend which uses cdrecord for CD burning.)
|
||||
</P>
|
||||
|
||||
<!--
|
||||
|
||||
<HR>
|
||||
|
||||
<A NAME="scdbackup">
|
||||
@ -391,6 +444,8 @@ and try again.
|
||||
</DL>
|
||||
</P>
|
||||
|
||||
-->
|
||||
|
||||
<HR>
|
||||
|
||||
<A NAME="cdrecord">
|
||||
@ -403,7 +458,7 @@ cdrecord but not vice versa.
|
||||
I am a long time user of cdrecord and it works fine for me.
|
||||
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
|
||||
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
|
||||
maintained. So for me - there would be not problem with it.
|
||||
maintained. So for me - there would be no problem with it.
|
||||
<BR>
|
||||
But the author of cdrecord and the Linux kernel people foster a very hostile
|
||||
relationship. Ok, that's their business, not mine (or ours if you are with me).
|
||||
@ -446,17 +501,34 @@ and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
|
||||
<A href="http://sourceforge.net">
|
||||
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
||||
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
||||
<P>
|
||||
Enjoying a FreeBSD shell account with the opportunity to
|
||||
build and install cdrskin at<BR>
|
||||
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
|
||||
</P>
|
||||
</FONT></CENTER>
|
||||
<HR>
|
||||
<DL>
|
||||
<DT>Links to my other published software projects :
|
||||
<DD><A HREF="http://scdbackup.webframe.org/xorriso_eng.html">
|
||||
xorriso, a standalone ISO 9660 multi-session CD/DVD/BD burn tool.
|
||||
No mkisofs needed.
|
||||
<DL>
|
||||
<DD>
|
||||
<A HREF="http://scdbackup.sourceforge.net/xorriso_eng.html">
|
||||
(a second source of above)</A>
|
||||
</DD>
|
||||
</DL>
|
||||
</DD>
|
||||
<DD><A HREF=http://scdbackup.webframe.org/main_eng.html>
|
||||
scdbackup, multi volume CD backup</A>
|
||||
<DL><DD><A HREF=http://scdbackup.sourceforge.net/main_eng.html>
|
||||
(a second source of above)</A></DL>
|
||||
(a second source of above)</A></DD></DL></DD>
|
||||
<DD><A HREF=http://stic.sourceforge.net>Some Tools for Image Collectors</A>
|
||||
</DD>
|
||||
<DD><A HREF=http://scdbackup.webframe.org/pppoem>
|
||||
pppoem, a DSL throughput monitor (mainly for Linux kernel 2.4)</A>
|
||||
</DD>
|
||||
</DL>
|
||||
<BR><BR>
|
||||
Legal statement: This website does not serve any commercial purpose.<BR>
|
||||
|
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.10.23.150436"
|
||||
#define Cdrskin_timestamP "2009.08.27.123001"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
# compile_cdrskin.sh
|
||||
# Copyright 2005 - 2007 Thomas Schmitt, scdbackup@gmx.net, GPL
|
||||
# Copyright 2005 - 2009 Thomas Schmitt, scdbackup@gmx.net, GPL version 2
|
||||
# to be executed within ./libburn-* resp ./cdrskin-*
|
||||
|
||||
debug_opts="-O2"
|
||||
def_opts=
|
||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||
libvers="-DCdrskin_libburn_0_3_9"
|
||||
libvers="-DCdrskin_libburn_0_7_0"
|
||||
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_8"
|
||||
elif test "$i" = "-libburn_0_7_0"
|
||||
then
|
||||
libvers="-DCdrskin_libburn_0_3_8"
|
||||
libvers="-DCdrskin_libburn_0_7_0"
|
||||
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_9"
|
||||
libvers="-DCdrskin_libburn_0_7_1"
|
||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||
cleanup_src_or_obj="libburn/cleanup.o"
|
||||
@ -75,10 +75,8 @@ do
|
||||
echo "Options:"
|
||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||
echo " -compile_dewav compile program test/dewav without libburn."
|
||||
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006."
|
||||
echo " -libburn_0_3_8 set macro to match libburn-0.3.8."
|
||||
echo " -libburn_0_7_0 set macro to match libburn-0.7.0"
|
||||
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."
|
||||
echo " -experimental use newly introduced libburn features."
|
||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
||||
|
@ -16,7 +16,7 @@ manpage="cdrskin"
|
||||
raw_html=$(pwd)/"cdrskin/raw_man_1_cdrskin.html"
|
||||
htmlpage=$(pwd)/"cdrskin/man_1_cdrskin.html"
|
||||
|
||||
if test -r "$manpage"
|
||||
if test -r "$man_dir"/"$manpage".1
|
||||
then
|
||||
dummy=dummy
|
||||
else
|
||||
@ -56,7 +56,7 @@ then
|
||||
-e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
||||
-e 's/<b>Emulated drives:<\/b>/\ <BR><b>Emulated drives:<\/b>/' \
|
||||
-e 's/^Alphabetical list of options/\ <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/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
|
||||
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
||||
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
||||
<"$2" >"$htmlpage"
|
||||
|
@ -8,10 +8,10 @@
|
||||
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
|
||||
Overwriteable media DVD-RAM, DVD+RW, DVD-RW, and BD-RE are handled differently
|
||||
than with cdrecord-ProDVD in order to offer TAO-like single track recording.
|
||||
Sequential DVD-R[W], DVD+R, DVD+R DL, BD-R are handled like CD-R[W] with TAO
|
||||
and multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
|
||||
with DVD-R[W].
|
||||
|
||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||
@ -23,8 +23,7 @@ About libburn API for burning CD and DVD: http://api.libburnia-project.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
|
||||
For yet unsupported media types see the advice to use dvd+rw-tools at
|
||||
the end of this text.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
@ -80,12 +79,58 @@ controls drive accessability by rw-permissions of the drive rather than
|
||||
by x-permission of the burn binary. To be usable with cdrskin, the drive
|
||||
has to offer both, r- and w-permission.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
blank=as_needed applies the suitable blanking or formatting to make
|
||||
any supported type of media ready for writing from scratch.
|
||||
If this is not possible, e.g. because the media is written and not
|
||||
re-usable, then the program run fails.
|
||||
|
||||
Option blank= offers several specialized blanking and formatting types,
|
||||
which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE.
|
||||
(See also below: blank=format_overwrite)
|
||||
The drive offers a list of possible formats by cdrskin option --list_formats.
|
||||
One should aquire MMC background information before making use of them.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
cdrskin does not only read from and write to optical drives which comply
|
||||
to the MMC standard but also does the same with regular files or block
|
||||
devices other than optical drives.
|
||||
|
||||
Because the power to alter a disk file might be a bad surprise for a
|
||||
traditional user of cdrecord, it is necessary to give option
|
||||
--allow_emulated_drives before an emulated drive may be addressed.
|
||||
Eventually one of the startup files would be a good place for it.
|
||||
See man page, section FILES.
|
||||
|
||||
The addresses of emulated drives begin with the prefix "stdio:".
|
||||
{{{
|
||||
dev=stdio:/tmp/pseudo_drive
|
||||
dev=stdio:/dev/usbstick
|
||||
}}}
|
||||
|
||||
Regular files and block devices behave much like DVD-RAM.
|
||||
|
||||
Other file types may be valid targets for write-only operations.
|
||||
This includes standard output, named pipes, character devices
|
||||
{{{
|
||||
dev=stdio:/dev/fd/1
|
||||
dev=stdio:/tmp/named_pipe
|
||||
dev=stdio:/dev/ptyxy
|
||||
}}}
|
||||
|
||||
These files behave much like blank DVD-R.
|
||||
|
||||
All files used as pseudo-drives have to offer rw-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.
|
||||
offers TAO-like multi-session with DVD-R[W], DVD+R[ DL] 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
|
||||
@ -94,9 +139,9 @@ disc from its initial profile "Sequential Recording" into profile state
|
||||
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.
|
||||
DVD-RAM, DVD+RW, BD-RE 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 ...
|
||||
}}}
|
||||
@ -107,8 +152,9 @@ 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.
|
||||
|
||||
normally both do full blanking. Thus sequential DVD-RW behave much like large
|
||||
CD-RW with possibly more than 99 tracks.
|
||||
|
||||
blank=deformat_sequential does minimal blanking of DVD-RW which usually yields
|
||||
media incapable of "Incremental Streaming".
|
||||
|
||||
@ -117,6 +163,13 @@ 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.)
|
||||
|
||||
Option --grow_overwriteable_iso gives cdrskin ISO pseudo-multi-session
|
||||
capabilities on DVD-RAM, DVD+RW, BD-RE similar to growisofs.
|
||||
Associated options blank=, -multi, -msinfo and -toc are available in this case.
|
||||
They either pretend a blank media (if there is no ISO 9660 image) or appendable
|
||||
media with a single session and track on it. blank= invalidates ISO images.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
assert_write_lba=<lba> allows to ensure that the start block address which
|
||||
@ -228,10 +281,10 @@ 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/BD media other than DVD-RAM, DVD+RW, DVD+R, DVD+R DL,
|
||||
DVD-RW, DVD-R, BD-RE, 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 more, including BD discs.
|
||||
|
||||
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
|
||||
|
||||
@ -239,19 +292,27 @@ 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).
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Advanced multi-session use cases:
|
||||
|
||||
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.
|
||||
|
||||
So, inspired by growisofs, cdrskin can offer DVD multi-session not only with
|
||||
sequential DVD-R[W] and with DVD+R [DL], but also with DVD-RAM, DVD+RW, BD-RE
|
||||
and even regular disk files or block devices other than CD/DVD writers.
|
||||
This is enabled by option --grow_overwriteable_iso.
|
||||
|
||||
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.
|
||||
The libburnia project provides an integrated ISO-9660 multi-session tool
|
||||
named [wiki:Xorriso xorriso] which tries to go one step beyond
|
||||
growisofs. It uses [wiki:Libburn libburn] , [wiki:Libisofs libisofs]
|
||||
and [wiki:Libisoburn libisoburn].
|
||||
|
||||
See [http://scdbackup.sourceforge.net/man_1_xorriso.html man xorriso].
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
148
configure.ac
148
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libburn], [0.3.9], [http://libburnia-project.org])
|
||||
AC_INIT([libburn], [0.7.0], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -7,35 +7,119 @@ AC_CANONICAL_TARGET
|
||||
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
|
||||
dnl Making releases:
|
||||
dnl BURN_MICRO_VERSION += 1;
|
||||
dnl BURN_INTERFACE_AGE += 1;
|
||||
dnl BURN_BINARY_AGE += 1;
|
||||
dnl if any functions have been added, set BURN_INTERFACE_AGE to 0.
|
||||
dnl if backwards compatibility has been broken,
|
||||
dnl set BURN_BINARY_AGE and BURN_INTERFACE_AGE to 0.
|
||||
dnl Notes by ts A71207 - A90827 :
|
||||
dnl
|
||||
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
||||
dnl Regrettably the meaning of the various version types was misunderstood
|
||||
dnl before version 0.4.1.
|
||||
dnl
|
||||
dnl In the past MAJOR.MINOR.MICRO versions led to the following SONAME numbers:
|
||||
dnl 0.2.2 = 2 , 0.2.3 = 3 , 0.2.6 = 6
|
||||
dnl 0.3.0 = 0 , 0.3.2 = 2 , 0.3.4 = 4 . 0.3.6 = 6 , 0.3.8 = 4
|
||||
dnl 0.4.0 = 0 (also released as SONAME 4)
|
||||
dnl
|
||||
dnl Meanwhile the following schemes are maintained in parallel:
|
||||
dnl
|
||||
dnl BURN_MAJOR_VERSION , BURN_MINOR_VERSION , BURN_MICRO_VERSION
|
||||
dnl are three small non-negative integers which describe the evolution
|
||||
dnl steps of the library.
|
||||
dnl Older applications are able to use younger libraries over
|
||||
dnl quite a long range of such steps. Some day, nevertheless,
|
||||
dnl compatibility might get terminated, after due notice.
|
||||
dnl
|
||||
dnl SONAME (libburn.so.4)
|
||||
dnl is a small positive integer which marks a family of compatible
|
||||
dnl evolution steps. Libraries with a particular SONAME allow a binary
|
||||
dnl with the same SONAME to start up. Any further compatibility check is to
|
||||
dnl be done by own runtime means. Especially *_version() calls in the API
|
||||
dnl which return BURN_MAJOR_VERSION, BURN_MINOR_VERSION, BURN_MICRO_VERSION.
|
||||
dnl See below.
|
||||
dnl
|
||||
dnl CURRENT, AGE, REVISION
|
||||
dnl are three integers used by libtool. CURRENT is positive, the others
|
||||
dnl non-negative. The use at runtime is not known yet. But libtool computes
|
||||
dnl at build time SONAME = CURRENT - AGE.
|
||||
dnl So this is a superspace of the SONAME version space. To avoid
|
||||
dnl ill SONAME, the value of CURRENT must be larger than AGE.
|
||||
dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces
|
||||
dnl
|
||||
dnl On Linux the name of the dynamic library will be
|
||||
dnl libburn.so.$SONAME.$AGE.$REV
|
||||
dnl In the terminology of this file:
|
||||
dnl CURRENT = LT_CURRENT
|
||||
dnl AGE = LT_AGE
|
||||
dnl REVISION= LT_REVISION
|
||||
dnl
|
||||
dnl Beginning with libburn-0.4.1 a rectified counting was introduced as
|
||||
dnl CURRENT=10, REVISION=1, AGE=6
|
||||
dnl This rectification declared that version to be binary compatible up
|
||||
dnl from libburn-0.3.4.
|
||||
dnl Real compatibility was given since libburn-0.3.2.
|
||||
dnl Beware of libburn-0.2.6 which had SONAME=6 and is not binary compatible.
|
||||
dnl Applications for libburn-0.2 to libburn-0.3.1 need recompilation but no
|
||||
dnl source code changes.
|
||||
dnl
|
||||
dnl Neatly versioned stable releases meanwhile:
|
||||
dnl 0.4.2 = libburn.so.4.7.0
|
||||
dnl 0.4.4 = libburn.so.4.9.0
|
||||
dnl 0.4.6 = libburn.so.4.11.0
|
||||
dnl 0.4.8 = libburn.so.4.13.0
|
||||
dnl 0.5.0 = libburn.so.4.15.0
|
||||
dnl 0.5.2 = libburn.so.4.17.0
|
||||
dnl 0.5.4 = libburn.so.4.19.0
|
||||
dnl 0.5.6 = libburn.so.4.21.0
|
||||
dnl 0.5.8 = libburn.so.4.23.0
|
||||
dnl 0.6.0 = libburn.so.4.25.0
|
||||
dnl 0.6.2 = libburn.so.4.27.0
|
||||
dnl 0.6.4 = libburn.so.4.29.0
|
||||
dnl 0.6.6 = libburn.so.4.31.0
|
||||
dnl 0.6.8 = libburn.so.4.33.0
|
||||
dnl 0.7.0 = libburn.so.4.35.0
|
||||
dnl
|
||||
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||
dnl The linker will do no finer checks. Especially no age range check for
|
||||
dnl the application binary. If SONAME matches, then the couple starts.
|
||||
dnl
|
||||
dnl Therefore at run time info is provided by libburn function burn_version().
|
||||
dnl It returns the major, minor and micro revision of the library.
|
||||
dnl Before using any API feature, a program should check for age.
|
||||
dnl
|
||||
dnl The variables BURN_*_VERSION are mere copies for informing libtool.
|
||||
dnl The true values which get issued and should be compared are macros
|
||||
dnl defined in libburn/libburn.h .
|
||||
dnl
|
||||
dnl Normally one can allow a program to run with a library which passed the
|
||||
dnl linker SONAME test and which is not older than the library it was
|
||||
dnl developed for. Library2 is younger than library1 if:
|
||||
dnl major2>major1 || (major2==major1 &&
|
||||
dnl (minor2>minor1 || (minor2==minor1 && micro2 > micro1)))
|
||||
dnl
|
||||
dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||
BURN_MAJOR_VERSION=0
|
||||
BURN_MINOR_VERSION=3
|
||||
BURN_MICRO_VERSION=9
|
||||
BURN_INTERFACE_AGE=0
|
||||
BURN_BINARY_AGE=0
|
||||
BURN_MINOR_VERSION=7
|
||||
BURN_MICRO_VERSION=0
|
||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
|
||||
AC_SUBST(BURN_MAJOR_VERSION)
|
||||
AC_SUBST(BURN_MINOR_VERSION)
|
||||
AC_SUBST(BURN_MICRO_VERSION)
|
||||
AC_SUBST(BURN_INTERFACE_AGE)
|
||||
AC_SUBST(BURN_BINARY_AGE)
|
||||
AC_SUBST(BURN_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION
|
||||
LT_CURRENT=`expr $BURN_MICRO_VERSION - $BURN_INTERFACE_AGE`
|
||||
LT_REVISION=$BURN_INTERFACE_AGE
|
||||
LT_AGE=`expr $BURN_BINARY_AGE - $BURN_INTERFACE_AGE`
|
||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
dnl
|
||||
dnl ts A90827
|
||||
dnl This is the release version libburn-0.7.0 = libburn.so.4.35.0
|
||||
dnl ### This is the development version after above release version
|
||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||
dnl
|
||||
dnl SONAME = 39 - 35 = 4 . Linux library name = libburn.so.4.35.0
|
||||
LT_CURRENT=39
|
||||
LT_AGE=35
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
AC_SUBST(LT_RELEASE)
|
||||
@ -44,6 +128,12 @@ AC_SUBST(LT_REVISION)
|
||||
AC_SUBST(LT_AGE)
|
||||
AC_SUBST(LT_CURRENT_MINUS_AGE)
|
||||
|
||||
dnl ts A71207: This is done only not to break any old components
|
||||
BURN_INTERFACE_AGE=$LT_REVISION
|
||||
BURN_BINARY_AGE=`expr $LT_AGE + $BURN_INTERFACE_AGE`
|
||||
AC_SUBST(BURN_INTERFACE_AGE)
|
||||
AC_SUBST(BURN_BINARY_AGE)
|
||||
|
||||
AC_PREFIX_DEFAULT([/usr/local])
|
||||
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
||||
|
||||
@ -75,8 +165,19 @@ AC_SUBST(THREAD_LIBS)
|
||||
|
||||
TARGET_SHIZZLE
|
||||
AC_SUBST(ARCH)
|
||||
AC_SUBST(LIBBURNIA_PKGCONFDIR)
|
||||
AC_SUBST(LIBBURN_ARCH_LIBS)
|
||||
|
||||
dnl ts A90303
|
||||
dnl Check the preconditions for using statvfs() in sg-dummy
|
||||
dnl (sg-linux and sg-freebsd use statvfs() unconditionally)
|
||||
STATVFS_DEF=-DLibburn_os_has_statvfS
|
||||
AC_CHECK_HEADER(sys/statvfs.h, X=, STATVFS_DEF=)
|
||||
AC_CHECK_FUNC([statvfs], X=, STATVFS_DEF=)
|
||||
dnl If this would be done more specifically in Makefile.am
|
||||
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
|
||||
CFLAGS="$CFLAGS $STATVFS_DEF"
|
||||
|
||||
dnl Add compiler-specific flags
|
||||
|
||||
dnl See if the user wants aggressive optimizations of the code
|
||||
@ -96,10 +197,17 @@ else
|
||||
CFLAGS="$CFLAGS -DDEBUG"
|
||||
fi
|
||||
|
||||
|
||||
dnl Determine target directory for libburn-*.pc
|
||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||
dnl
|
||||
LIBBURNIA_SET_PKGCONFIG
|
||||
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/doxygen.conf
|
||||
version.h
|
||||
libburn-5.pc
|
||||
libburn-1.pc
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
101
doc/comments
101
doc/comments
@ -1,75 +1,51 @@
|
||||
/**
|
||||
@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.
|
||||
optical discs. This page is about its capability to handle optical media.
|
||||
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
||||
DVD-R, BD-R, BD-RE.
|
||||
|
||||
Not supported yet are dual layer media, HD-DVD, BD (blue ray). Testers for
|
||||
dual layer DVD+/-R are wanted, though.
|
||||
Not supported yet are DVD-R/DL. Testers wanted.
|
||||
|
||||
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, or FreeBSD . For ports to other
|
||||
systems 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.
|
||||
|
||||
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
|
||||
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.
|
||||
libburn is the library by which preformatted data get onto optical media.
|
||||
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.
|
||||
|
||||
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.
|
||||
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/BD capabilities,
|
||||
where only -sao is compatible with 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.
|
||||
|
||||
@subsection components The project components (list subject to growth, hopefully):
|
||||
The burn API example of libburn is named test/libburner.c . The API for media
|
||||
information inquiry is demonstrated in test/telltoc.c .
|
||||
Explore these examples if you look for inspiration.
|
||||
|
||||
- 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/srM 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.
|
||||
|
||||
- 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. Additionally it
|
||||
provides libburn's DVD capabilities, where only -sao is compatible
|
||||
with 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 .
|
||||
Explore these examples if you look for inspiration.
|
||||
|
||||
We plan to be a responsive upstream. Bear with us.
|
||||
SONAME:
|
||||
libburn.so.4 (since 0.3.4, March 2007),
|
||||
|
||||
|
||||
@section using Using the libraries
|
||||
@section using Using libburn
|
||||
|
||||
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
|
||||
To build libburn and its companion applications go into its toplevel directory
|
||||
and execute
|
||||
|
||||
- ./bootstrap (needed if you downloaded from SVN)
|
||||
|
||||
@ -81,29 +57,24 @@ 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://libburnia-project.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 burn to recordable CD, DVD, or BD,
|
||||
can blank a CD-RW or DVD-RW, and can format unformatted DVD-RW, BD-R, or BD-RE.
|
||||
|
||||
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
|
||||
define the standard way how above three gestures can be implemented and
|
||||
stay upward compatible for a good while.
|
||||
define the standard way how above gestures can be implemented and stay upward
|
||||
compatible for a good while.
|
||||
|
||||
@subsection libburner-help Libburner --help
|
||||
<pre>
|
||||
Usage: test/libburner
|
||||
[--drive <address>|<driveno>|"-"] [--audio]
|
||||
[--blank_fast|--blank_full|--format_overwrite]
|
||||
[--try_to_simulate]
|
||||
[--blank_fast|--blank_full|--format] [--try_to_simulate]
|
||||
[--multi] [<one or more imagefiles>|"-"]
|
||||
Examples
|
||||
A bus scan (needs rw-permissions to see a drive):
|
||||
@ -116,8 +87,8 @@ 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
|
||||
Format a DVD-RW, BD-RE or BD-R:
|
||||
test/libburner --drive /dev/hdc --format
|
||||
Burn two audio tracks (to CD only):
|
||||
lame --decode -t /path/to/track1.mp3 track1.cd
|
||||
test/dewav /path/to/track2.wav -o track2.cd
|
||||
|
314
doc/cookbook.txt
314
doc/cookbook.txt
@ -1,11 +1,12 @@
|
||||
libburnia-project.org Optical Media Rotisserie Recipes as of August 2007
|
||||
libburnia-project.org Optical Media Rotisserie Recipes as of January 2009
|
||||
|
||||
Content:
|
||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||
- SAO CD Cookbook (CD-R, CD-RW, pure audio or pure data only)
|
||||
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW)
|
||||
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE)
|
||||
- Sequential DVD-R[W] Cookbook
|
||||
- DVD+R Cookbook
|
||||
- DVD+R[/DL] Cookbook
|
||||
- BD-R Cookbook
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
TAO Multi-Session CD Cookbook
|
||||
@ -403,7 +404,8 @@ correctness of Pre-gap and Post-gap would become evident.
|
||||
-------------------------------------------------------------------------------
|
||||
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
and by experiments with drives NEC ND-4570A and LG GSA-4082B.
|
||||
by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L,
|
||||
LG GGW H20L, and by BD-RE experiments done by Giulio Orsero on LG BE06LU10.
|
||||
|
||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||
|
||||
@ -416,18 +418,24 @@ DVD-RAM 0012h
|
||||
DVD-RW Restricted Overwrite 0013h
|
||||
DVD-RW Sequential Recording 0014h (i.e. unformatted)
|
||||
DVD+RW 001Ah
|
||||
BD-RE 0043h
|
||||
|
||||
A short compilation of the write model:
|
||||
- Overwriting in general
|
||||
|
||||
The recipes described here are depending on formatting state:
|
||||
- DVD-RAM, fully formatted DVD+RW or DVD-RW
|
||||
- DVD-RAM, fully formatted DVD+RW, DVD-RW, BD-RE
|
||||
- Unformatted DVD+RW
|
||||
- Partly formatted DVD+RW
|
||||
- Unformatted DVD-RW
|
||||
- Partly formatted DVD-RW
|
||||
- Intermediate state DVD-RW
|
||||
- DVD-RAM and BD-RE formatting
|
||||
- DVD-RAM and BD-RE speed tuning
|
||||
|
||||
Slightly off topic are
|
||||
- ISO 9660 multi-session emulation on overwriteable media
|
||||
- ISO 9660 based TOC emulation on overwriteable media
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Overwriting in general :
|
||||
@ -444,7 +452,7 @@ Optimal performance is promised without any speed setting. But my experiments
|
||||
showed that SET STREAMING values persist after media change.
|
||||
|
||||
In the formatted area of the media, coarse random access is possible.
|
||||
For DVD-RAM and DVD+RW write addresses and data size need to be aligned
|
||||
For DVD-RAM, DVD+RW, BD-RE write addresses and data size need to be aligned
|
||||
to 2 KiB. For DVD-RW alignment has to be 32 KiB. Within these limitations
|
||||
the write address is at the discretion of the sending program.
|
||||
Just use 2Ah WRITE to send data.
|
||||
@ -483,9 +491,12 @@ software did anything wrong.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DVD-RAM, fully formatted DVD+RW or DVD-RW :
|
||||
DVD-RAM, fully formatted DVD+RW, DVD-RW, BD-RE :
|
||||
|
||||
Full format is the natural state of DVD-RAM.
|
||||
Full format is the natural state of DVD-RAM.
|
||||
|
||||
BD-RE are sold unformatted and need to be fully formatted first.
|
||||
See paragraph about DVD-RAM and BD-RE formatting below.
|
||||
|
||||
DVD+RW reaches this state if Background Formatting is allowed to finish without
|
||||
being stopped by 5Bh CLOSE TRACK SESSION.
|
||||
@ -516,7 +527,7 @@ with Close Function 010b despite there is no session open in this scenario.)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Unformatted DVD+RW
|
||||
Unformatted DVD+RW :
|
||||
|
||||
This is the state of previously unused DVD+RW media.
|
||||
|
||||
@ -671,6 +682,166 @@ of Intermediate state by 5Bh CLOSE TRACK SESSION with Close Function 010b.
|
||||
(mmc5r03c.pdf 6.3.3.2.3)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DVD-RAM and BD-RE formatting :
|
||||
|
||||
Although DVD-RAM usually are sold formatted, there may still arise the wish
|
||||
to adjust formatting.
|
||||
BD-RE are sold unformatted and need to be formatted prior to usage.
|
||||
|
||||
Two format types are relevant for DVD-RAM : 00h and 01h.
|
||||
00h offers the default size format and usually a maximum payload size format.
|
||||
Even with that maximum size payload there is hardware defect management.
|
||||
(mmc5r03c.pdf 6.5.4.2.1.2)
|
||||
01h allows to convert payload capacity into spare blocks for defect
|
||||
managment. There is no way to increase payload capacity by format 01h.
|
||||
(mmc5r03c.pdf 6.5.4.2.2.1)
|
||||
|
||||
With BD-RE there are three format types : 00h, 30h and 31h.
|
||||
00h offers the default size format. This may be the only fast formatting
|
||||
mode that is offered by the drive.
|
||||
Feature 0023h tells whether format 31h and certain 30h subtypes are available.
|
||||
(mmc5r03c.pdf 5.3.13)
|
||||
30h offers several sizes with defect management. Usually there are three
|
||||
sizes given: #1: default size, #2: maximum spare area, #3: minimal spare.
|
||||
One may demand any spare size between maximum and minimum. There may be quick
|
||||
certification and full certification. See feature 0023h.
|
||||
31h offers a single size and disables defect management. This has the side
|
||||
effect to speed up writing to nominal speed.
|
||||
(mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472)
|
||||
|
||||
Only format sizes from the list of format descriptors are permissible
|
||||
for DVD-RAM. The format list can be obtained by 23h READ FORMAT CAPACITIES.
|
||||
It also includes a description of the current formatting state.
|
||||
(mmc5r03c.pdf 6.24, 6.24.3.2, 6.24.3.3)
|
||||
|
||||
Formatting is done by command 04h FORMAT UNIT. Its data payload consists
|
||||
of a Format List Header and a Format Descriptor. It is advisable to set
|
||||
the Immed bit and the FOV bit in header byte number 1. The descriptor should
|
||||
be a copy of a descriptor from 23h READ FORMAT CAPACITIES.
|
||||
(mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3)
|
||||
With nearly all formats Sub-type should be set to 0. But with BD-RE formats
|
||||
30h and 31h the Sub-type selects the certification mode.
|
||||
Usable with 30h seem 10b Full Certification and 11b Quick Certification.
|
||||
Usable with 31h seem also 00b Quick Reformat and 01b No Certification.
|
||||
(mmc5r03c.pdf 6.5.4.2.15.1)
|
||||
|
||||
Other format types have their certification intensity controlled by
|
||||
a pair of bits: CmpList and DCRT.
|
||||
CmpList resides in CDB byte 1 as bit 3. DCRT resides in the payload byte 1
|
||||
as bit 5. Both together should request a quick size change without lengthy
|
||||
certification but maintaining the list of known defects.
|
||||
(mmc5r03c.pdf 6.5, table 249, 6.5.3.2)
|
||||
With DVD-RAM on my PHILIPS SPD3300L drive they prevent any format size
|
||||
change though. The TSSTcorp SH-S203B works properly.
|
||||
With BD-RE format 00h, the default is specified to be Quick Reformat,
|
||||
and with 00h in general certification can only be disabled not enabled.
|
||||
(mmc5r03c.pdf 6.5.4.2.1.7)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DVD-RAM and BD-RE tuning :
|
||||
|
||||
A special aspect of DVD-RAM and BD-RE is their low speed with write operations,
|
||||
which usually is only half than the nominal speed of media and drive.
|
||||
This is blamed to the automatic checkreading which happens for managing
|
||||
eventual defects.
|
||||
|
||||
Defect management of BD-RE can be disabled by format type 31h. See above.
|
||||
There is no drive known yet which would apply command 2Ah WRITE10 to DVD-RAM
|
||||
with full speed.
|
||||
|
||||
The only known way to get full speed from DVD-RAM or BD-RE with enabled defect
|
||||
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
||||
(mmc5r03c.pdf 6.45)
|
||||
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
||||
With the tested BD-RE one has to write full 64 kB buffers.
|
||||
|
||||
Although it seems not optimal, this is specified not only to disable the
|
||||
cumbersome checkread but also to ignore known defects and to write data
|
||||
to these defective addresses.
|
||||
(mmc5r03c.pdf 4.8.5)
|
||||
So the speed-up is only advisable as long as the media are free of
|
||||
incorrectable errors.
|
||||
|
||||
Caveat:
|
||||
MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
|
||||
None of the features of profiles 0012h and 0043h promises the existence of
|
||||
AAh WRITE12.
|
||||
(mmc5r03c.pdf 5.4.13, 6.45)
|
||||
Nevertheless it worked on all tested drives if proper alignment was observed.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
ISO 9660 multi-session emulation on overwriteable media :
|
||||
|
||||
Overwriteable media provide a single overwriteable track which may grow up to
|
||||
the full media capacity. There is no builtin table-of-content which records
|
||||
the history of write sessions.
|
||||
mount -t iso9660 will use sbsector=0 as default.
|
||||
The term "superblock" shall depict the first 64 KiB after the sbsector address.
|
||||
|
||||
ISO 9660 multi-session depends on typical TOC information in two ways:
|
||||
It needs the superblock address MSC1 of the most recently recorded session and
|
||||
it needs the Next Writeable Address NWA for which to prepare the adress offset.
|
||||
|
||||
The following is learned from growisofs and from ECMA-119:
|
||||
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
||||
|
||||
ISO 9660 filesystems provide information about the number of sectors which
|
||||
is also the lowest unused block address and thus a suitable NWA.
|
||||
This block address is stored in the Primary Volume Descriptor which is supposed
|
||||
to be stored in block 16 (eventually relative to MSC1).
|
||||
The bytes 0 to 5 of a PVD block are
|
||||
0x01 'C' 'D' '0' '0' '1'
|
||||
The sector count can then be read from byte 80 to 83
|
||||
sectors= pvd[80] | (pvd[81] << 8) | (pvd[82] << 16) | (pvd[83] << 24);
|
||||
(Ecma-119.pdf 8.4)
|
||||
To support CD, DVD and BD media alike, it is advisable to round the NWA
|
||||
to the next multiple of 32 (= 64 KiB).
|
||||
|
||||
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
||||
After writing the session it is necessary to patch the PVD at LBA 16.
|
||||
The minimal change would be to update the number of image sectors.
|
||||
It is stored in both notations LSB and MSB:
|
||||
for(i= 0; i < 4; i++)
|
||||
pvd[87 - i]= pvd[80 + i]= (sectors >> (8 * i)) & 0xff;
|
||||
|
||||
cdrskin --grow_overwriteable_iso not only patches the sector fields of the
|
||||
PVD block but also the blocks up to LBA 31 which begin with
|
||||
0xff 'C' 'D' '0' '0' '1'
|
||||
libisoburn submits 64 KiB data buffer to libisofs before image generation and
|
||||
afterwards writes these 64 KiB as new superblock to LBA 0.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
ISO 9660 based TOC emulation on overwriteable media :
|
||||
|
||||
Above method of multi-session emulation yields a single session image after
|
||||
each add-on session. No reliable session history can be read because the
|
||||
sector size of the existing session gets overwritten by the new one.
|
||||
A TOC with session history is nevertheless desirable with incremental backups
|
||||
in order to access older backup states by mounting older superblocks at the
|
||||
start addresses of older sessions.
|
||||
|
||||
All usual ISO 9660 formatter programs write a complete superblock to the
|
||||
start of each session.
|
||||
With a uniform NWA rounding rule it is possible to compute the address of
|
||||
superblock N+1 as the NWA after session N. The only problem is N=1
|
||||
because it gets overwritten by later sessions.
|
||||
|
||||
libisoburn preserves the information of session 1 by writing the first session
|
||||
to LBA 32 rather than LBA 0. Afterwards it writes the overall superblock to
|
||||
LBA 0 (up to 31).
|
||||
So with all further add-on sessions the superblock at LBA 0 will enclose the
|
||||
overall image, while the superblocks of the sessions form a chain beginning
|
||||
at LBA 32. Each session superblock points to the next one by its sector count
|
||||
rounded up to 32. The chain end is marked by the overall image size.
|
||||
This chain gives the start addresses of sessions. The sector count minus start
|
||||
address gives the size of a particular session. ECMA-119 explains how to
|
||||
retrieve more info from the PVD (e.g. the volume id).
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -990,7 +1161,7 @@ close session if multi-session is demanded.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DVD+R Cookbook
|
||||
DVD+R[/DL] Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
backed by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
||||
@ -1006,7 +1177,7 @@ DVD+R/DL 002bh
|
||||
|
||||
- About empty, appendable and finalized DVD+R
|
||||
- Writing a Pseudo Session to DVD+R
|
||||
- >>> Hearsay about DVD+R/DL (Dual Layer) :
|
||||
- DVD+R/DL (Dual Layer
|
||||
|
||||
The following two chapters of the Sequential DVD-R[W] Cookbook are valid for
|
||||
DVD+R media too:
|
||||
@ -1100,9 +1271,126 @@ by closing them already after the first session.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Hearsay about DVD+R/DL (Dual Layer) :
|
||||
DVD+R/DL (Dual Layer) :
|
||||
|
||||
>>>
|
||||
libburn treats DL media just like their single layer equivalents.
|
||||
This seems to work fine for DVD+R/DL, according to a report by nightmorph
|
||||
in http://libburnia-project.org/ticket/13 .
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
BD-R Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
backed by experiments iwith drive LG GGW H20L.
|
||||
|
||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
|
||||
(mmc5r03c.pdf 6.6.2.1)
|
||||
BD-R 0042h
|
||||
|
||||
There are two basic recording modes defined: Sequential Recording Mode SRM and
|
||||
Random Recording Mode RRM. The latter is optional and for now not topic of this
|
||||
text.
|
||||
(mmc5r03c.pdf 4.5.3.5)
|
||||
|
||||
|
||||
- SRM Formatting
|
||||
- Writing a session in SRM-POW
|
||||
(- Pseudo-OverWrite SRM+POW)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
SRM Formatting:
|
||||
|
||||
Despite being write-once media BD-R can optionally carry some formatting.
|
||||
|
||||
SRM has a disc structure model with tracks and sessions.
|
||||
Several tracks may be open at the same time, each having its own NWA.
|
||||
(mmc5r03c.pdf 4.5.3.5.2.2)
|
||||
This structure is formatted onto blank media automatically as soon as the
|
||||
first serious write attempt occurs.
|
||||
(mmc5r03c.pdf 4.5.3.5)
|
||||
Before such a write attempt, blank media may be explicitely formatted with
|
||||
spares, which provide defect management.
|
||||
(mmc5r03c.pdf 4.5.3.5.3)
|
||||
Tracks get created from other tracks via RESERVE TRACK splitting.
|
||||
(mmc5r03c.pdf 4.5.3.5.2.5)
|
||||
|
||||
On top of defect management there may be Pseudo-OverWrite SRM+POW, a costly
|
||||
way to write several times to the same LBA. See below.
|
||||
Fully sequential states are called SRM-POW.
|
||||
(mmc5r03c.pdf 4.5.3.5.4)
|
||||
|
||||
Explicite formatting is done by 04h FORMAT UNIT. Its data payload consists
|
||||
of a Format List Header and a Format Descriptor. It is advisable to set
|
||||
the Immed bit and the FOV bit in header byte number 1. The descriptor should
|
||||
be a copy of a descriptor from 23h READ FORMAT CAPACITIES but the size may be
|
||||
adjusted within a certain range.
|
||||
(mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3)
|
||||
|
||||
Format type 00h creates SRM layouts with a default number of spares (or
|
||||
eventually RRM) chosen by the format sub-type:
|
||||
00b = SRM with support for POW
|
||||
01b = SRM without POW (but with some spares for defect management)
|
||||
10b = (RRM)
|
||||
(mmc5r03c.pdf 6.5.4.2.1.6)
|
||||
|
||||
Format type 32h uses the same sub-types but allows to allocate non-default
|
||||
amounts of spares. Similar to BD-RE format 31h, three format descriptors are
|
||||
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
|
||||
The size may be chosen within that range.
|
||||
|
||||
The sense behind the Type Dependent Parameters is obscure
|
||||
to me. Best will be to set ISA_V and TDMA_V to 0.
|
||||
(mmc5r03c.pdf 6.5.4.2.1.17)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Writing a session in SRM:
|
||||
|
||||
The procedure and constraints for writing BD-R SRM-POW are very similar to
|
||||
DVD+R. libburn flatly re-uses its DVD+R code except the Close Function for
|
||||
finalizing a disc.
|
||||
|
||||
In short:
|
||||
If all written sessions are closed, then there is exactly one NWA.
|
||||
In the beginning there is an empty session and track. A new track can be
|
||||
written either with pre-announced size (by RESERVE TRACK) or open-end by
|
||||
simply starting to write to the NWA. When done the track gets closed by
|
||||
close function 001b. Then either session or disc gets closed depending on
|
||||
the Close Function used:
|
||||
- Close Function 010b closes the session and keeps the media appendable
|
||||
(same as with DVD+R)
|
||||
- Close Function 110b finalizes the media and makes it read-only.
|
||||
(differs from libburn DVD+R procedure which uses 101b)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Pseudo-OverWrite POW: (no used yet by libburn)
|
||||
|
||||
This enhancement of SRM emulates overwriting of existing data blocks.
|
||||
(mmc5r03c.pdf 4.5.3.5.4)
|
||||
|
||||
POW establishes a virtual vLBA space on top of the real address space rLBA.
|
||||
All read and write commands deal with vLBA. It seems that track NWAs are
|
||||
assumed to be identical in vLBA space and in rLBA space.
|
||||
It is not clear whether one may write to vLBA blocks which are neither written
|
||||
yet nor at one of the track NWAs. Probably not, or else one could make NWAs run
|
||||
into vLBAs which are associated with older rLBAs.
|
||||
|
||||
Replacing invalidated blocks consumes addresses in rLBA space at the NWA of
|
||||
some track. I.e. no spares are consumed by POW. Nevertheless it is costly by
|
||||
a special map called Orphanage. It covers rLBA which have been consumed
|
||||
by differing vLBAs. It never shrinks and can grow with each write to remapped
|
||||
addresses.
|
||||
To avoid heavy Orphanage growth it is advised to write mostly to vLBA which
|
||||
still coincide with their rLBA. E.g. those addresses which have neither been
|
||||
written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
|
||||
at the NWA of a sufficiently sized track.
|
||||
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -38,7 +38,7 @@ PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY =
|
||||
OUTPUT_DIRECTORY = @abs_top_builddir@
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||
@ -104,7 +104,7 @@ INLINE_INHERITED_MEMB = NO
|
||||
# path before files name in the file list and in the header files. If set
|
||||
# to NO the shortest path that makes the file name unique will be used.
|
||||
|
||||
FULL_PATH_NAMES = YES
|
||||
FULL_PATH_NAMES = NO
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
|
||||
# can be used to strip a user-defined part of the path. Stripping is
|
||||
@ -113,7 +113,7 @@ FULL_PATH_NAMES = YES
|
||||
# If left blank the directory from which doxygen is run is used as the
|
||||
# path to strip.
|
||||
|
||||
STRIP_FROM_PATH = @top_srcdir@
|
||||
STRIP_FROM_PATH =
|
||||
|
||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
||||
# the path mentioned in the documentation of a class, which tells
|
||||
|
@ -4,7 +4,7 @@ libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libburn
|
||||
Description: Disc reading/writing library
|
||||
Description: Library to read/write optical discs
|
||||
Version: @VERSION@
|
||||
Requires:
|
||||
Libs: -L${libdir} -lburn
|
189
libburn/async.c
189
libburn/async.c
@ -10,9 +10,8 @@
|
||||
even if joinable and even if never joined.
|
||||
|
||||
To be activated after release of libburn-0.4.0
|
||||
|
||||
#define Libburn_create_detached_threadS 1
|
||||
*/
|
||||
#define Libburn_create_detached_threadS 1
|
||||
|
||||
/* Alternative : Threads are created joinable.
|
||||
Threads get detached in remove_worker() and thus should dispose themselves.
|
||||
@ -26,9 +25,9 @@
|
||||
#include "drive.h"
|
||||
#include "write.h"
|
||||
#include "options.h"
|
||||
#include "file.h"
|
||||
#include "async.h"
|
||||
#include "init.h"
|
||||
#include "file.h"
|
||||
#include "back_hacks.h"
|
||||
|
||||
#include <pthread.h>
|
||||
@ -44,7 +43,15 @@
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
#define SCAN_GOING() (workers && !workers->drive)
|
||||
/* ts A80714 : introduced type codes for the worker list */
|
||||
#define Burnworker_type_scaN 0
|
||||
#define Burnworker_type_erasE 1
|
||||
#define Burnworker_type_formaT 2
|
||||
#define Burnworker_type_writE 3
|
||||
#define Burnworker_type_fifO 4
|
||||
|
||||
#define SCAN_GOING() (workers != NULL && \
|
||||
workers->w_type == Burnworker_type_scaN)
|
||||
|
||||
typedef void *(*WorkerFunc) (void *);
|
||||
|
||||
@ -86,6 +93,9 @@ struct fifo_opts
|
||||
|
||||
struct w_list
|
||||
{
|
||||
/* ts A80714 */
|
||||
int w_type; /* see above define Burnworker_type_* */
|
||||
|
||||
struct burn_drive *drive;
|
||||
pthread_t thread;
|
||||
|
||||
@ -114,7 +124,8 @@ static struct w_list *find_worker(struct burn_drive *d)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
|
||||
static void add_worker(int w_type, struct burn_drive *d,
|
||||
WorkerFunc f, void *data)
|
||||
{
|
||||
struct w_list *a;
|
||||
struct w_list *tmp;
|
||||
@ -125,6 +136,7 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
|
||||
#endif
|
||||
|
||||
a = malloc(sizeof(struct w_list));
|
||||
a->w_type = w_type;
|
||||
a->drive = d;
|
||||
a->u = *(union w_list_data *)data;
|
||||
|
||||
@ -144,9 +156,11 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
attr_pt= &attr;
|
||||
/*
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
|
||||
"add_worker(): Creating detached thread.", 0, 0);
|
||||
*/
|
||||
#endif
|
||||
|
||||
if (pthread_create(&a->thread, attr_pt, f, a)) {
|
||||
@ -179,12 +193,14 @@ static void remove_worker(pthread_t th)
|
||||
dispose themselves.
|
||||
*/
|
||||
ret = pthread_detach(th);
|
||||
/*
|
||||
sprintf(msg,
|
||||
"remove_workers(): pid= %lu pthread_detach(%lu)= %d",
|
||||
(unsigned long) getpid(), (unsigned long) th, ret);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
|
||||
msg, 0, 0);
|
||||
*/
|
||||
|
||||
#endif /* Libburn_detach_done_workeR */
|
||||
|
||||
@ -256,7 +272,8 @@ drive_is_active:;
|
||||
o.drives = drives;
|
||||
o.n_drives = n_drives;
|
||||
o.done = 0;
|
||||
add_worker(NULL, (WorkerFunc) scan_worker_func, &o);
|
||||
add_worker(Burnworker_type_scaN, NULL,
|
||||
(WorkerFunc) scan_worker_func, &o);
|
||||
} else if (workers->u.scan.done) {
|
||||
/* its done */
|
||||
ret = workers->u.scan.done;
|
||||
@ -300,7 +317,7 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||
"NULL pointer caught in burn_disc_erase", 0, 0);
|
||||
return;
|
||||
}
|
||||
if ((SCAN_GOING()) || find_worker(drive)) {
|
||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||
0x00020102,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
@ -340,7 +357,8 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||
|
||||
o.drive = drive;
|
||||
o.fast = fast;
|
||||
add_worker(drive, (WorkerFunc) erase_worker_func, &o);
|
||||
add_worker(Burnworker_type_erasE, drive,
|
||||
(WorkerFunc) erase_worker_func, &o);
|
||||
}
|
||||
|
||||
|
||||
@ -358,10 +376,10 @@ static void *format_worker_func(struct w_list *w)
|
||||
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||
{
|
||||
struct format_opts o;
|
||||
int ok = 0;
|
||||
int ok = 0, ret;
|
||||
char msg[160];
|
||||
|
||||
if ((SCAN_GOING()) || find_worker(drive)) {
|
||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||
0x00020102,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
@ -389,6 +407,84 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||
size = 0;
|
||||
flag &= ~(2|8); /* no insisting in size 0, no expansion */
|
||||
flag |= 4; /* format up to maximum size */
|
||||
} else if (drive->current_profile == 0x12) {
|
||||
ok = 1; /* DVD-RAM */
|
||||
|
||||
} else if (drive->current_profile == 0x41) {
|
||||
/* BD-R SRM */
|
||||
ok= 1;
|
||||
ret = drive->read_format_capacities(drive, 0x00);
|
||||
if (ret > 0 &&
|
||||
drive->format_descr_type == BURN_FORMAT_IS_FORMATTED)
|
||||
ok = 0;
|
||||
if (drive->status != BURN_DISC_BLANK)
|
||||
ok = 0;
|
||||
if (!ok) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
drive->global_index, 0x00020162,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"BD-R not unformatted blank any more. Cannot format.",
|
||||
0, 0);
|
||||
drive->cancel = 1;
|
||||
return;
|
||||
}
|
||||
if (flag & 32) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
drive->global_index, 0x00020163,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Blank BD-R left unformatted for zero spare capacity.",
|
||||
0, 0);
|
||||
return;
|
||||
}
|
||||
} else if (drive->current_profile == 0x43) {
|
||||
ok = 1; /* BD-RE */
|
||||
|
||||
if ((flag & 32) && !(drive->current_feat23h_byte4 & 8)) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
drive->global_index, 0x00020164,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive does not format BD-RE without spares.",
|
||||
0, 0);
|
||||
drive->cancel = 1;
|
||||
return;
|
||||
|
||||
}
|
||||
if ((flag & 6) != 6 || (flag & 128)) {
|
||||
if ((flag & 64) && !(drive->current_feat23h_byte4 & 2)) {
|
||||
if (drive->current_feat23h_byte4 & 1) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
drive->global_index, 0x00020165,
|
||||
LIBDAX_MSGS_SEV_WARNING,
|
||||
LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive does not support fast formatting",
|
||||
0, 0);
|
||||
flag &= ~64;
|
||||
} else {
|
||||
no_non_default_bd_re:;
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
drive->global_index, 0x00020167,
|
||||
LIBDAX_MSGS_SEV_SORRY,
|
||||
LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive does not support non-default formatting",
|
||||
0, 0);
|
||||
drive->cancel = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((!(flag & 64)) && !(drive->current_feat23h_byte4 & 1)){
|
||||
if (drive->current_feat23h_byte4 & 2) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
drive->global_index, 0x00020166,
|
||||
LIBDAX_MSGS_SEV_WARNING,
|
||||
LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive does not support full formatting",
|
||||
0, 0);
|
||||
flag |= 64;
|
||||
} else
|
||||
goto no_non_default_bd_re;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
@ -404,7 +500,8 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||
o.drive = drive;
|
||||
o.size = size;
|
||||
o.flag = flag;
|
||||
add_worker(drive, (WorkerFunc) format_worker_func, &o);
|
||||
add_worker(Burnworker_type_formaT, drive,
|
||||
(WorkerFunc) format_worker_func, &o);
|
||||
}
|
||||
|
||||
|
||||
@ -430,12 +527,15 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||
{
|
||||
struct write_opts o;
|
||||
char reasons[BURN_REASONS_LEN+80];
|
||||
struct burn_drive *d;
|
||||
|
||||
d = opts->drive;
|
||||
|
||||
/* ts A61006 */
|
||||
/* a ssert(!SCAN_GOING()); */
|
||||
/* a ssert(!find_worker(opts->drive)); */
|
||||
if ((SCAN_GOING()) || find_worker(opts->drive)) {
|
||||
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||
if ((SCAN_GOING()) || find_worker(opts->drive) != NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020102,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"A drive operation is still going on (want to write)",
|
||||
@ -444,14 +544,14 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||
}
|
||||
|
||||
/* For the next lines any return indicates failure */
|
||||
opts->drive->cancel = 1;
|
||||
d->cancel = 1;
|
||||
|
||||
/* ts A70203 : people have been warned in API specs */
|
||||
if (opts->write_type == BURN_WRITE_NONE)
|
||||
return;
|
||||
|
||||
if (opts->drive->drive_role == 0) {
|
||||
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||
if (d->drive_role == 0) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020146,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
||||
@ -459,9 +559,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||
}
|
||||
|
||||
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
||||
if (opts->drive->drive_role == 1 && !opts->drive->mdata->valid) {
|
||||
if (d->drive_role == 1 && d->mdata->valid <= 0) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
opts->drive->global_index, 0x00020113,
|
||||
d->global_index, 0x00020113,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Drive capabilities not inquired yet", 0, 0);
|
||||
return;
|
||||
@ -472,28 +572,47 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||
*/
|
||||
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
||||
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
||||
== BURN_WRITE_NONE) {
|
||||
<= 0) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
opts->drive->global_index, 0x00020139,
|
||||
d->global_index, 0x00020139,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
reasons, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
opts->drive->cancel = 0; /* End of the return = failure area */
|
||||
/* ts A90106 : early catching of unformatted BD-RE */
|
||||
if (d->current_profile == 0x43)
|
||||
if (d->read_format_capacities(d, 0x00) > 0 &&
|
||||
d->format_descr_type != BURN_FORMAT_IS_FORMATTED) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x00020168,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Media not properly formatted. Cannot write.",
|
||||
0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
o.drive = opts->drive;
|
||||
d->cancel = 0; /* End of the return = failure area */
|
||||
|
||||
o.drive = d;
|
||||
o.opts = opts;
|
||||
o.disc = disc;
|
||||
|
||||
opts->refcount++;
|
||||
|
||||
add_worker(opts->drive, (WorkerFunc) write_disc_worker_func, &o);
|
||||
add_worker(Burnworker_type_writE, d,
|
||||
(WorkerFunc) write_disc_worker_func, &o);
|
||||
}
|
||||
|
||||
|
||||
static void *fifo_worker_func(struct w_list *w)
|
||||
{
|
||||
int old;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
||||
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
|
||||
|
||||
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
||||
remove_worker(pthread_self());
|
||||
return NULL;
|
||||
@ -516,12 +635,34 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
||||
|
||||
o.source = source;
|
||||
o.flag = flag;
|
||||
add_worker(NULL, (WorkerFunc) fifo_worker_func, &o);
|
||||
add_worker(Burnworker_type_fifO, NULL,
|
||||
(WorkerFunc) fifo_worker_func, &o);
|
||||
fs->is_started = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int burn_fifo_abort(struct burn_source_fifo *fs, int flag)
|
||||
{
|
||||
int ret;
|
||||
pthread_t pt;
|
||||
|
||||
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL)
|
||||
return(2);
|
||||
|
||||
#ifdef NIX
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Aborting running burn_source_fifo thread", 0, 0);
|
||||
#endif /* NIX */
|
||||
|
||||
pt= *((pthread_t *) fs->thread_handle);
|
||||
remove_worker(pt);
|
||||
ret = pthread_cancel(pt);
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libburn_has_burn_async_join_alL
|
||||
|
||||
/* ts A71019 : never used */
|
||||
|
@ -10,5 +10,9 @@ struct burn_write_opts;
|
||||
/* To be called when the first read() call comes to a fifo */
|
||||
int burn_fifo_start(struct burn_source *source, int flag);
|
||||
|
||||
/* ts A81108 */
|
||||
/* To abort a running fifo thread before the fifo object gets deleted */
|
||||
int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
|
||||
|
||||
|
||||
#endif /* BURN__ASYNC_H */
|
||||
|
@ -97,8 +97,8 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
||||
return(2);
|
||||
}
|
||||
if(cleanup_exiting) {
|
||||
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
|
||||
getpid(),signum);
|
||||
fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n",
|
||||
(double) getpid(), signum);
|
||||
return(0);
|
||||
}
|
||||
cleanup_exiting= 1;
|
||||
|
241
libburn/drive.c
241
libburn/drive.c
@ -40,12 +40,18 @@
|
||||
/* A70903 : for burn_scsi_setup_drive() */
|
||||
#include "spc.h"
|
||||
|
||||
/* A90815 : for mmc_obtain_profile_name() */
|
||||
#include "mmc.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
static struct burn_drive drive_array[255];
|
||||
static int drivetop = -1;
|
||||
|
||||
/* ts A80410 : in init.c */
|
||||
extern int burn_support_untested_profiles;
|
||||
|
||||
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
|
||||
*/
|
||||
int burn_setup_drive(struct burn_drive *d, char *fname)
|
||||
@ -58,6 +64,8 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
|
||||
d->released = 1;
|
||||
d->stdio_fd = -1;
|
||||
d->status = BURN_DISC_UNREADY;
|
||||
d->do_stream_recording = 0;
|
||||
d->stream_recording_start= 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -192,6 +200,31 @@ unsigned int burn_drive_count(void)
|
||||
}
|
||||
|
||||
|
||||
/* ts A80801 */
|
||||
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag)
|
||||
{
|
||||
int i, ret;
|
||||
char drive_adr[BURN_DRIVE_ADR_LEN], off_adr[BURN_DRIVE_ADR_LEN];
|
||||
|
||||
ret = burn_drive_convert_fs_adr(path, off_adr);
|
||||
if (ret <= 0)
|
||||
strcpy(off_adr, path);
|
||||
for (i = 0; i <= drivetop; i++) {
|
||||
if (drive_array[i].global_index < 0)
|
||||
continue;
|
||||
ret = burn_drive_d_get_adr(&(drive_array[i]), drive_adr);
|
||||
if (ret <= 0)
|
||||
continue;
|
||||
if(strcmp(off_adr, drive_adr) == 0) {
|
||||
if (found != NULL)
|
||||
*found= &(drive_array[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61125 : media status aspects of burn_drive_grab() */
|
||||
int burn_drive_inquire_media(struct burn_drive *d)
|
||||
{
|
||||
@ -201,7 +234,9 @@ int burn_drive_inquire_media(struct burn_drive *d)
|
||||
|
||||
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
|
||||
|
||||
if (d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||
/* ts A71128 : run read_disc_info() for any recognizeable profile */
|
||||
if (d->current_profile > 0 || d->current_is_guessed_profile ||
|
||||
d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||
d->mdata->dvdr_write || d->mdata->dvdram_write) {
|
||||
|
||||
#define Libburn_knows_correct_state_after_loaD 1
|
||||
@ -386,6 +421,9 @@ int burn_drive_unregister(struct burn_drive *d)
|
||||
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
||||
{
|
||||
struct burn_drive *t;
|
||||
char msg[BURN_DRIVE_ADR_LEN + 160];
|
||||
int ret;
|
||||
|
||||
/* ts A60821
|
||||
<<< debug: for tracing calls which might use open drive fds */
|
||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||
@ -398,13 +436,19 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
||||
mmc_function_spy(NULL, "enumerate_common : -------- doing grab");
|
||||
|
||||
/* try to get the drive info */
|
||||
if (t->grab(t)) {
|
||||
ret = t->grab(t);
|
||||
if (ret) {
|
||||
burn_print(2, "getting drive info\n");
|
||||
t->getcaps(t);
|
||||
t->unlock(t);
|
||||
t->released = 1;
|
||||
} else {
|
||||
burn_print(2, "unable to grab new located drive\n");
|
||||
/* ts A90602 */
|
||||
d->mdata->valid = -1;
|
||||
sprintf(msg, "Unable to grab scanned drive %s", d->devname);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002016f, LIBDAX_MSGS_SEV_DEBUG,
|
||||
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
||||
burn_drive_unregister(t);
|
||||
t = NULL;
|
||||
}
|
||||
@ -437,6 +481,9 @@ int burn_drive_mark_unready(struct burn_drive *d)
|
||||
burn_disc_free(d->disc);
|
||||
d->disc = NULL;
|
||||
}
|
||||
if (d->stdio_fd >= 0)
|
||||
close (d->stdio_fd);
|
||||
d->stdio_fd = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -486,6 +533,22 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
/* ts A90824
|
||||
@param flag bit0= wake up (else start snoozing)
|
||||
*/
|
||||
int burn_drive_snooze(struct burn_drive *d, int flag)
|
||||
{
|
||||
if (d->drive_role != 1)
|
||||
return 0;
|
||||
if (flag & 1)
|
||||
d->start_unit(d);
|
||||
else
|
||||
d->stop_unit(d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
void burn_drive_release(struct burn_drive *d, int le)
|
||||
{
|
||||
@ -583,14 +646,14 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
||||
|
||||
/*
|
||||
@param flag: bit0 = fill formatted size with zeros
|
||||
bit1, bit2 , bit4, bit7 - bit15 are for d->format_unit()
|
||||
bit1, bit2 , bit4, bit5, 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;
|
||||
struct buffer buf, *buf_mem = d->buffer;
|
||||
|
||||
/* reset the progress */
|
||||
d->progress.session = 0;
|
||||
@ -606,7 +669,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
||||
d->cancel = 0;
|
||||
d->busy = BURN_DRIVE_FORMATTING;
|
||||
|
||||
ret = d->format_unit(d, size, flag & 0xff96); /* forward bits */
|
||||
ret = d->format_unit(d, size, flag & 0xfff6); /* forward bits */
|
||||
if (ret <= 0)
|
||||
d->cancel = 1;
|
||||
|
||||
@ -672,7 +735,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
||||
ex:;
|
||||
d->progress.sector = 0x10000;
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
d->buffer = NULL;
|
||||
d->buffer = buf_mem;
|
||||
}
|
||||
|
||||
|
||||
@ -758,6 +821,18 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||
return d->busy;
|
||||
}
|
||||
|
||||
int burn_drive_set_stream_recording(struct burn_drive *d, int recmode,
|
||||
int start, int flag)
|
||||
{
|
||||
|
||||
if (recmode == 1)
|
||||
d->do_stream_recording = 1;
|
||||
else if (recmode == -1)
|
||||
d->do_stream_recording = 0;
|
||||
d->stream_recording_start = start;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void burn_drive_cancel(struct burn_drive *d)
|
||||
{
|
||||
pthread_mutex_lock(&d->access_lock);
|
||||
@ -808,7 +883,7 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
||||
a ssert(d->mdata);
|
||||
#endif
|
||||
|
||||
if (!d->idata->valid || !d->mdata->valid)
|
||||
if(d->idata->valid <= 0 || d->mdata->valid <= 0)
|
||||
return 0;
|
||||
|
||||
id = (struct burn_scsi_inquiry_data *)d->idata;
|
||||
@ -874,7 +949,7 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
*/
|
||||
unsigned char scanned[32];
|
||||
unsigned count = 0;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
/* ts A61007 : moved up to burn_drive_scan() */
|
||||
/* a ssert(burn_running); */
|
||||
@ -931,13 +1006,22 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
if (drive_array[i].global_index < 0)
|
||||
continue; /* invalid device */
|
||||
|
||||
while (!drive_getcaps(&drive_array[i],
|
||||
&(*drives)[*n_drives])) {
|
||||
/* ts A90602 : This old loop is not plausible. See A70907.
|
||||
while (!drive_getcaps(&drive_array[i],
|
||||
&(*drives)[*n_drives])) {
|
||||
sleep(1);
|
||||
}
|
||||
(*n_drives)++;
|
||||
}
|
||||
*/
|
||||
/* ts A90602 : A single call shall do (rather than a loop) */
|
||||
ret = drive_getcaps(&drive_array[i], &(*drives)[*n_drives]);
|
||||
if (ret > 0)
|
||||
(*n_drives)++;
|
||||
scanned[i / 8] |= 1 << (i % 8);
|
||||
}
|
||||
if (*drives != NULL && *n_drives == 0) {
|
||||
free ((char *) *drives);
|
||||
*drives = NULL;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
@ -1093,14 +1177,14 @@ void burn_sectors_to_msf(int sectors, int *m, int *s, int *f)
|
||||
|
||||
int burn_drive_get_read_speed(struct burn_drive *d)
|
||||
{
|
||||
if(!d->mdata->valid)
|
||||
if(d->mdata->valid <= 0)
|
||||
return 0;
|
||||
return d->mdata->max_read_speed;
|
||||
}
|
||||
|
||||
int burn_drive_get_write_speed(struct burn_drive *d)
|
||||
{
|
||||
if(!d->mdata->valid)
|
||||
if(d->mdata->valid <= 0)
|
||||
return 0;
|
||||
return d->mdata->max_write_speed;
|
||||
}
|
||||
@ -1108,7 +1192,7 @@ int burn_drive_get_write_speed(struct burn_drive *d)
|
||||
/* ts A61021 : New API function */
|
||||
int burn_drive_get_min_write_speed(struct burn_drive *d)
|
||||
{
|
||||
if(!d->mdata->valid)
|
||||
if(d->mdata->valid <= 0)
|
||||
return 0;
|
||||
return d->mdata->min_write_speed;
|
||||
}
|
||||
@ -1157,6 +1241,20 @@ int burn_drive_is_banned(char *device_address)
|
||||
}
|
||||
|
||||
|
||||
/* ts A80731 */
|
||||
int burn_drive_whitelist_count(void)
|
||||
{
|
||||
return enumeration_whitelist_top + 1;
|
||||
}
|
||||
|
||||
char *burn_drive_whitelist_item(int idx, int flag)
|
||||
{
|
||||
if (idx < 0 || idx > enumeration_whitelist_top)
|
||||
return NULL;
|
||||
return enumeration_whitelist[idx];
|
||||
}
|
||||
|
||||
|
||||
/* ts A70924 */
|
||||
int burn_drive__fd_from_special_adr(char *adr)
|
||||
{
|
||||
@ -1251,7 +1349,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
||||
d->current_is_supported_profile = 1;
|
||||
d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1;
|
||||
d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
|
||||
d->media_capacity_remaining = size;
|
||||
burn_drive_set_media_capacity_remaining(d, size);
|
||||
|
||||
/* >>> ? open file for a test ? (>>> beware of "-" = stdin) */;
|
||||
|
||||
@ -1681,6 +1779,10 @@ int burn_abort(int patience,
|
||||
unsigned long wait_grain= 100000;
|
||||
time_t start_time, current_time, pacifier_time, end_time;
|
||||
|
||||
#ifndef NIX
|
||||
time_t stdio_patience = 3;
|
||||
#endif
|
||||
|
||||
current_time = start_time = pacifier_time = time(0);
|
||||
end_time = start_time + patience;
|
||||
|
||||
@ -1696,6 +1798,37 @@ int burn_abort(int patience,
|
||||
occup = burn_drive_is_occupied(&(drive_array[i]));
|
||||
if(occup == -2)
|
||||
continue;
|
||||
|
||||
if(drive_array[i].drive_role != 1) {
|
||||
|
||||
#ifdef NIX
|
||||
|
||||
/* ts A90302
|
||||
<<< this causes a race condition with drive
|
||||
usage and drive disposal.
|
||||
*/
|
||||
drive_array[i].busy = BURN_DRIVE_IDLE;
|
||||
burn_drive_forget(&(drive_array[i]), 1);
|
||||
continue;
|
||||
|
||||
#else /* NIX */
|
||||
|
||||
/* ts A90318
|
||||
>>> but if a pipe breaks then the drive
|
||||
never gets idle.
|
||||
So for now with a short patience timespan
|
||||
and eventually a deliberate memory leak.
|
||||
*/
|
||||
if (current_time - start_time >
|
||||
stdio_patience) {
|
||||
drive_array[i].global_index = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif /* ! NIX */
|
||||
|
||||
}
|
||||
|
||||
if(occup <= 10) {
|
||||
burn_drive_forget(&(drive_array[i]), 1);
|
||||
} else if(occup <= 100) {
|
||||
@ -1775,11 +1908,16 @@ int burn_disc_read_atip(struct burn_drive *d)
|
||||
}
|
||||
if(d->drive_role != 1)
|
||||
return 0;
|
||||
if (d->current_profile == -1 || d->current_is_cd_profile) {
|
||||
if ((d->current_profile == -1 || d->current_is_cd_profile)
|
||||
&& (d->mdata->cdrw_write || d->current_profile != 0x08)) {
|
||||
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 */;
|
||||
/* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD
|
||||
(and it seems meaningless for non-burners).
|
||||
ts A90823: Pseudo-CD U3 memory stick stalls with ATIP.
|
||||
It is !cdrw_write and profile is 0x08.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -1860,8 +1998,8 @@ off_t burn_disc_available_space(struct burn_drive *d,
|
||||
return 0;
|
||||
if (d->drive_role != 1) {
|
||||
if (d->media_capacity_remaining <= 0)
|
||||
d->media_capacity_remaining =
|
||||
((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
||||
burn_drive_set_media_capacity_remaining(d,
|
||||
(off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
||||
} else {
|
||||
if (o != NULL)
|
||||
d->send_write_parameters(d, o);
|
||||
@ -1887,6 +2025,30 @@ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
|
||||
}
|
||||
|
||||
|
||||
/* ts A90815 : New API function */
|
||||
int burn_drive_get_all_profiles(struct burn_drive *d, int *num_profiles,
|
||||
int profiles[64], char is_current[64])
|
||||
{
|
||||
int i;
|
||||
|
||||
*num_profiles = d->num_profiles;
|
||||
for (i = 0; i < d->num_profiles; i++) {
|
||||
profiles[i] = (d->all_profiles[i * 4] << 8) |
|
||||
d->all_profiles[i * 4 + 1];
|
||||
is_current[i] = d->all_profiles[i * 4 + 2] & 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A90815 : New API function */
|
||||
int burn_obtain_profile_name(int profile_number, char name[80])
|
||||
{
|
||||
strcpy(name, mmc_obtain_profile_name(profile_number));
|
||||
return(name[0] != 0);
|
||||
}
|
||||
|
||||
|
||||
/* ts A61223 : New API function */
|
||||
int burn_drive_wrote_well(struct burn_drive *d)
|
||||
{
|
||||
@ -1986,7 +2148,7 @@ int burn_drive_get_speedlist(struct burn_drive *d,
|
||||
struct burn_speed_descriptor *sd, *csd = NULL;
|
||||
|
||||
(*speed_list) = NULL;
|
||||
if(!d->mdata->valid)
|
||||
if(d->mdata->valid <= 0)
|
||||
return 0;
|
||||
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
|
||||
ret = burn_speed_descriptor_new(&csd, NULL, csd, 0);
|
||||
@ -2011,7 +2173,7 @@ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
|
||||
if (speed_goal < 0)
|
||||
best_speed = 2000000000;
|
||||
*best_descr = NULL;
|
||||
if(!d->mdata->valid)
|
||||
if(d->mdata->valid <= 0)
|
||||
return 0;
|
||||
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
|
||||
if (flag & 1)
|
||||
@ -2093,7 +2255,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||
o->start_adr = 1;
|
||||
size = d->media_capacity_remaining;
|
||||
burn_os_stdio_capacity(d->devname, &size);
|
||||
d->media_capacity_remaining = size;
|
||||
burn_drive_set_media_capacity_remaining(d, size);
|
||||
o->start_range_high = size;
|
||||
o->start_alignment = 2048; /* imposting a drive, not a file */
|
||||
o->might_do_sao = 4;
|
||||
@ -2158,9 +2320,12 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||
if (wt == BURN_WRITE_NONE || wt == BURN_WRITE_SAO ||
|
||||
wt == BURN_WRITE_TAO)
|
||||
o->might_simulate = 1;
|
||||
} else if (d->current_profile == 0x12 || d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x1a) {
|
||||
/* DVD-RAM, overwriteable DVD-RW, DVD+RW */
|
||||
} else if (d->current_profile == 0x12 ||
|
||||
d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x1a ||
|
||||
d->current_profile == 0x43
|
||||
) {
|
||||
/* DVD-RAM, overwriteable DVD-RW, DVD+RW, BD-RE */
|
||||
o->start_adr = 1;
|
||||
ret = burn_disc_get_formats(d, &status, &size, &dummy,
|
||||
&num_formats);
|
||||
@ -2179,6 +2344,8 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||
}
|
||||
if (i >= num_formats) /* not expandable */
|
||||
o->start_range_high -= 32 * 1024;
|
||||
if (o->start_range_high < 0)
|
||||
o->start_range_high = 0;
|
||||
} else {
|
||||
o->start_alignment = 2 * 1024;
|
||||
if (d->best_format_size - 2048 >
|
||||
@ -2190,8 +2357,9 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||
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 */
|
||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
||||
d->current_profile == 0x41) {
|
||||
/* DVD+R , DVD+R/DL , BD-R SRM */
|
||||
o->multi_session = o->multi_track = 1;
|
||||
o->might_do_tao = 2;
|
||||
o->might_do_sao = 1;
|
||||
@ -2442,3 +2610,18 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid)
|
||||
}
|
||||
|
||||
|
||||
/* ts A80422 : centralizing this setting for debugging purposes
|
||||
*/
|
||||
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
||||
{
|
||||
d->media_capacity_remaining = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ts A81215 : API */
|
||||
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
||||
{
|
||||
*capacity = d->media_read_capacity;
|
||||
return (d->media_read_capacity != 0x7fffffff);
|
||||
}
|
||||
|
||||
|
@ -125,4 +125,14 @@ int burn_drive__fd_from_special_adr(char *adr);
|
||||
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid);
|
||||
|
||||
|
||||
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
||||
int burn_drive_is_banned(char *device_address);
|
||||
int burn_drive_whitelist_count(void);
|
||||
char *burn_drive_whitelist_item(int idx, int flag);
|
||||
|
||||
|
||||
/* ts A80801 */
|
||||
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
||||
|
||||
|
||||
#endif /* __DRIVE */
|
||||
|
254
libburn/file.c
254
libburn/file.c
@ -9,6 +9,8 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "source.h"
|
||||
#include "libburn.h"
|
||||
#include "file.h"
|
||||
@ -188,115 +190,8 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
||||
}
|
||||
|
||||
|
||||
/* ts A70930 */
|
||||
/* ----------------------------- fifo ---------------------------- */
|
||||
|
||||
/* The fifo mechanism consists of a burn_source proxy which is here,
|
||||
a thread management team which is located in async.c,
|
||||
and a synchronous shoveller which is here.
|
||||
*/
|
||||
|
||||
/* fifo_ng has a ringbuffer and runs in a thread. og is on its way out. */
|
||||
#define Libburn_fifo_nG 1
|
||||
|
||||
#ifndef Libburn_fifo_nG
|
||||
|
||||
static int fifo_read(struct burn_source *source,
|
||||
unsigned char *buffer,
|
||||
int size)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
int ret;
|
||||
|
||||
if (fs->is_started == 0) {
|
||||
ret = burn_fifo_start(source, 0);
|
||||
if (ret <= 0) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020152,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Cannot start fifo thread", 0, 0);
|
||||
return -1;
|
||||
}
|
||||
fs->is_started = 1;
|
||||
}
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
ret = read_full_buffer(fs->outlet[0], buffer, size);
|
||||
if (ret > 0)
|
||||
fs->out_counter += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static off_t fifo_get_size(struct burn_source *source)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
return fs->inp->get_size(fs->inp);
|
||||
}
|
||||
|
||||
|
||||
static int fifo_set_size(struct burn_source *source, off_t size)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
return fs->inp->set_size(fs->inp, size);
|
||||
}
|
||||
|
||||
|
||||
static void fifo_free(struct burn_source *source)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
if (fs->outlet[1] >= 0)
|
||||
close(fs->outlet[1]);
|
||||
free(fs);
|
||||
}
|
||||
|
||||
|
||||
int burn_fifo_source_shoveller_og(struct burn_source *source, int flag)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
int ret;
|
||||
|
||||
fs->thread_pid = getpid();
|
||||
fs->thread_pid_valid = 1;
|
||||
|
||||
while (1) {
|
||||
ret = fs->inp->read(fs->inp, (unsigned char *) fs->buf,
|
||||
fs->chunksize);
|
||||
if (ret > 0)
|
||||
fs->in_counter += ret;
|
||||
else if (ret == 0)
|
||||
break; /* EOF */
|
||||
else {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Read error on fifo input", errno, 0);
|
||||
break;
|
||||
}
|
||||
ret = write(fs->outlet[1], fs->buf, ret);
|
||||
if (ret == -1) {
|
||||
/* >>> write error */;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* >>> check and destroy ring buffer */;
|
||||
free(fs->buf);
|
||||
fs->buf = NULL;
|
||||
|
||||
if (fs->outlet[1] >= 0)
|
||||
close(fs->outlet[1]);
|
||||
fs->outlet[1] = -1;
|
||||
return (ret >= 0);
|
||||
}
|
||||
|
||||
#endif /* Libburn_fifo_nG */
|
||||
|
||||
|
||||
/* ts A71003 */
|
||||
/* ----------------------------- fifo ng ------------------------- */
|
||||
/* ------------------------------ fifo --------------------------- */
|
||||
|
||||
/* The fifo mechanism consists of a burn_source proxy which is here,
|
||||
a thread management team which is located in async.c,
|
||||
@ -311,7 +206,7 @@ static int fifo_sleep(int flag)
|
||||
}
|
||||
|
||||
|
||||
static int fifo_read_ng(struct burn_source *source,
|
||||
static int fifo_read(struct burn_source *source,
|
||||
unsigned char *buffer,
|
||||
int size)
|
||||
{
|
||||
@ -341,7 +236,7 @@ static int fifo_read_ng(struct burn_source *source,
|
||||
/* This needs no mutex because each volatile variable has one thread
|
||||
which may write and the other which only reads and is aware of
|
||||
volatility.
|
||||
The feeder of the ringbuffer is in burn_fifo_source_shoveller_ng().
|
||||
The feeder of the ringbuffer is in burn_fifo_source_shoveller().
|
||||
*/
|
||||
todo = size;
|
||||
bufsize = fs->chunksize * fs->chunks;
|
||||
@ -394,7 +289,7 @@ static int fifo_read_ng(struct burn_source *source,
|
||||
}
|
||||
|
||||
|
||||
static off_t fifo_get_size_ng(struct burn_source *source)
|
||||
static off_t fifo_get_size(struct burn_source *source)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
@ -402,7 +297,7 @@ static off_t fifo_get_size_ng(struct burn_source *source)
|
||||
}
|
||||
|
||||
|
||||
static int fifo_set_size_ng(struct burn_source *source, off_t size)
|
||||
static int fifo_set_size(struct burn_source *source, off_t size)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
@ -410,10 +305,11 @@ static int fifo_set_size_ng(struct burn_source *source, off_t size)
|
||||
}
|
||||
|
||||
|
||||
static void fifo_free_ng(struct burn_source *source)
|
||||
static void fifo_free(struct burn_source *source)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
burn_fifo_abort(fs, 0);
|
||||
if (fs->inp != NULL)
|
||||
burn_source_free(fs->inp);
|
||||
if (fs->buf != NULL)
|
||||
@ -422,14 +318,17 @@ static void fifo_free_ng(struct burn_source *source)
|
||||
}
|
||||
|
||||
|
||||
int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag)
|
||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
|
||||
char *bufpt;
|
||||
pthread_t thread_handle_storage;
|
||||
|
||||
fs->thread_handle= &thread_handle_storage;
|
||||
*((pthread_t *) fs->thread_handle)= pthread_self();
|
||||
fs->thread_pid = getpid();
|
||||
fs->thread_pid_valid = 1;
|
||||
fs->thread_is_valid = 1;
|
||||
|
||||
bufsize = fs->chunksize * fs->chunks;
|
||||
while (!fs->end_of_consumption) {
|
||||
@ -469,8 +368,12 @@ int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag)
|
||||
}
|
||||
|
||||
/* Obtain next chunk */
|
||||
ret = fs->inp->read(fs->inp, (unsigned char *) bufpt,
|
||||
fs->chunksize);
|
||||
if (fs->inp->read != NULL)
|
||||
ret = fs->inp->read(fs->inp,
|
||||
(unsigned char *) bufpt, fs->chunksize);
|
||||
else
|
||||
ret = fs->inp->read_xt( fs->inp,
|
||||
(unsigned char *) bufpt, fs->chunksize);
|
||||
if (ret > 0)
|
||||
fs->in_counter += ret;
|
||||
else if (ret == 0)
|
||||
@ -533,19 +436,18 @@ int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag)
|
||||
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
|
||||
fs->buf = NULL;
|
||||
|
||||
fs->thread_handle= NULL;
|
||||
fs->thread_is_valid = 0;
|
||||
return (fs->input_error == 0);
|
||||
}
|
||||
|
||||
|
||||
#define Libburn_fifo_nG 1
|
||||
|
||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
int burn_fifo_cancel(struct burn_source *source)
|
||||
{
|
||||
#ifndef Libburn_fifo_nG
|
||||
return burn_fifo_source_shoveller_og(source, flag);
|
||||
#else
|
||||
return burn_fifo_source_shoveller_ng(source, flag);
|
||||
#endif
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
burn_source_cancel(fs->inp);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
@ -554,9 +456,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
{
|
||||
struct burn_source_fifo *fs;
|
||||
struct burn_source *src;
|
||||
#ifndef Libburn_fifo_nG
|
||||
int ret, outlet[2];
|
||||
#endif
|
||||
|
||||
if (((double) chunksize) * ((double) chunks) > 1024.0*1024.0*1024.0) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020155,
|
||||
@ -570,29 +469,14 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
"Desired fifo buffer too small", 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef Libburn_fifo_nG
|
||||
outlet[0] = outlet[1] = -1;
|
||||
ret = pipe(outlet);
|
||||
if (ret == -1) {
|
||||
/* >>> error on pipe creation */;
|
||||
return NULL;
|
||||
}
|
||||
#endif /* ! Libburn_fifo_nG */
|
||||
|
||||
fs = malloc(sizeof(struct burn_source_fifo));
|
||||
if (fs == NULL)
|
||||
return NULL;
|
||||
fs->is_started = 0;
|
||||
fs->thread_handle = NULL;
|
||||
fs->thread_pid = 0;
|
||||
fs->thread_pid_valid = 0;
|
||||
fs->thread_is_valid = 0;
|
||||
fs->inp = NULL; /* set later */
|
||||
|
||||
#ifndef Libburn_fifo_nG
|
||||
fs->outlet[0] = outlet[0];
|
||||
fs->outlet[1] = outlet[1];
|
||||
#endif
|
||||
|
||||
fs->chunksize = chunksize;
|
||||
fs->chunks = chunks;
|
||||
fs->buf = NULL;
|
||||
@ -607,23 +491,15 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
free((char *) fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef Libburn_fifo_nG
|
||||
src->read = fifo_read;
|
||||
src->read = NULL;
|
||||
src->read_sub = NULL;
|
||||
src->get_size = fifo_get_size;
|
||||
src->set_size = fifo_set_size;
|
||||
src->free_data = fifo_free;
|
||||
#else /* Libburn_fifo_nG */
|
||||
src->read = fifo_read_ng;
|
||||
src->read_sub = NULL;
|
||||
src->get_size = fifo_get_size_ng;
|
||||
src->set_size = fifo_set_size_ng;
|
||||
src->free_data = fifo_free_ng;
|
||||
#endif /* ! Libburn_fifo_nG */
|
||||
|
||||
src->data = fs;
|
||||
|
||||
src->version= 1;
|
||||
src->read_xt = fifo_read;
|
||||
src->cancel= burn_fifo_cancel;
|
||||
fs->inp = inp;
|
||||
inp->refcount++; /* make sure inp lives longer than src */
|
||||
|
||||
@ -644,7 +520,7 @@ int burn_fifo_inquire_status(struct burn_source *source,
|
||||
*status_text = NULL;
|
||||
*size = 0;
|
||||
|
||||
if (source->free_data != fifo_free_ng) {
|
||||
if (source->free_data != fifo_free) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020157,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"burn_source is not a fifo object", 0, 0);
|
||||
@ -673,4 +549,64 @@ int burn_fifo_inquire_status(struct burn_source *source,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||
int flag)
|
||||
{
|
||||
int size, free_bytes, ret, wait_count= 0;
|
||||
char *status_text;
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
/* Eventually start fifo thread by reading 0 bytes */
|
||||
ret = fifo_read(source, (unsigned char *) NULL, 0);
|
||||
if (ret<0)
|
||||
return 0;
|
||||
|
||||
/* wait for at least bufsize bytes being ready */
|
||||
while (1) {
|
||||
ret= burn_fifo_inquire_status(source,
|
||||
&size, &free_bytes, &status_text);
|
||||
if (size < bufsize) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015c,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo size is smaller than desired peek buffer", 0, 0);
|
||||
return -1;
|
||||
}
|
||||
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo is already under consumption when peeking is desired",
|
||||
0, 0);
|
||||
return -1;
|
||||
}
|
||||
if(size - free_bytes >= bufsize) {
|
||||
|
||||
/* <<<
|
||||
fprintf(stderr,
|
||||
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
|
||||
wait_count, status_text, size - free_bytes);
|
||||
*/
|
||||
|
||||
memcpy(buf, fs->buf, bufsize);
|
||||
return 1;
|
||||
}
|
||||
if (ret&2) { /* input has ended, not enough data arrived */
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo input ended short of desired peek buffer size",
|
||||
0, 0);
|
||||
return 0;
|
||||
}
|
||||
usleep(100000);
|
||||
wait_count++;
|
||||
|
||||
/* <<<
|
||||
if(wait_count%10==0)
|
||||
fprintf(stderr,
|
||||
"libburn_DEBUG: waiting cycle %d : fifo %s , %d bytes\n",
|
||||
wait_count, status_text, size - free_bytes);
|
||||
*/
|
||||
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
@ -29,8 +29,9 @@ struct burn_source_fifo {
|
||||
*/
|
||||
int is_started;
|
||||
|
||||
void *thread_handle; /* actually a pointer to a thread_t */
|
||||
int thread_pid;
|
||||
int thread_pid_valid;
|
||||
int thread_is_valid;
|
||||
|
||||
/* the burn_source for which this fifo is acting as proxy */
|
||||
struct burn_source *inp;
|
||||
|
@ -247,7 +247,7 @@ int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
|
||||
|
||||
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
|
||||
if (ret <= 0)
|
||||
sevno = LIBDAX_MSGS_SEV_FATAL;
|
||||
sevno = LIBDAX_MSGS_SEV_ALL;
|
||||
if (error_code <= 0) {
|
||||
switch(sevno) {
|
||||
case LIBDAX_MSGS_SEV_ABORT: error_code = 0x00040000;
|
||||
@ -258,7 +258,7 @@ int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
|
||||
break; case LIBDAX_MSGS_SEV_NOTE: error_code = 0x00040005;
|
||||
break; case LIBDAX_MSGS_SEV_UPDATE: error_code = 0x00040006;
|
||||
break; case LIBDAX_MSGS_SEV_DEBUG: error_code = 0x00040007;
|
||||
break; default: error_code = 0x00040001;
|
||||
break; default: error_code = 0x00040008;
|
||||
}
|
||||
}
|
||||
if (d != NULL)
|
||||
@ -275,8 +275,16 @@ int burn_text_to_sev(char *severity_name, int *sevno, int flag)
|
||||
int ret;
|
||||
|
||||
ret = libdax_msgs__text_to_sev(severity_name, sevno, 0);
|
||||
if (ret <= 0)
|
||||
*sevno = LIBDAX_MSGS_SEV_FATAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A80202 API */
|
||||
int burn_sev_to_text(int severity_number, char **severity_name, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = libdax_msgs__sev_to_text(severity_number, severity_name, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,7 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
||||
if(o==NULL)
|
||||
return(-1);
|
||||
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
||||
o->path[LIBDAX_AUDIOXTR_STRLEN]= 0;
|
||||
o->path[LIBDAX_AUDIOXTR_STRLEN-1]= 0;
|
||||
o->fd= -1;
|
||||
strcpy(o->fmt,"unidentified");
|
||||
o->fmt_info[0]= 0;
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
/* libdax_msgs
|
||||
Message handling facility of libdax.
|
||||
Copyright (C) 2006 - 2007 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL
|
||||
Copyright (C) 2006 - 2009 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL version 2
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -40,7 +40,7 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
|
||||
if(ret==0)
|
||||
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
||||
o->process_id= getpid();
|
||||
o->driveno= -1;
|
||||
o->origin= -1;
|
||||
o->severity= LIBDAX_MSGS_SEV_ALL;
|
||||
o->priority= LIBDAX_MSGS_PRIO_ZERO;
|
||||
o->error_code= 0;
|
||||
@ -109,12 +109,12 @@ int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
|
||||
|
||||
|
||||
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
|
||||
double *timestamp, pid_t *process_id, int *driveno,
|
||||
double *timestamp, pid_t *process_id, int *origin,
|
||||
int flag)
|
||||
{
|
||||
*timestamp= item->timestamp;
|
||||
*process_id= item->process_id;
|
||||
*driveno= item->driveno;
|
||||
*origin= item->origin;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -252,6 +252,10 @@ int libdax_msgs__text_to_sev(char *severity_name, int *severity,
|
||||
*severity= LIBDAX_MSGS_SEV_ABORT;
|
||||
else if(strncmp(severity_name,"FATAL",5)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_FATAL;
|
||||
else if(strncmp(severity_name,"FAILURE",7)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_FAILURE;
|
||||
else if(strncmp(severity_name,"MISHAP",6)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_MISHAP;
|
||||
else if(strncmp(severity_name,"SORRY",5)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_SORRY;
|
||||
else if(strncmp(severity_name,"WARNING",7)==0)
|
||||
@ -264,10 +268,12 @@ int libdax_msgs__text_to_sev(char *severity_name, int *severity,
|
||||
*severity= LIBDAX_MSGS_SEV_UPDATE;
|
||||
else if(strncmp(severity_name,"DEBUG",5)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_DEBUG;
|
||||
else if(strncmp(severity_name,"ERRFILE",7)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_ERRFILE;
|
||||
else if(strncmp(severity_name,"ALL",3)==0)
|
||||
*severity= LIBDAX_MSGS_SEV_ALL;
|
||||
else {
|
||||
*severity= LIBDAX_MSGS_SEV_NEVER;
|
||||
*severity= LIBDAX_MSGS_SEV_ALL;
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
@ -278,8 +284,7 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||
int flag)
|
||||
{
|
||||
if(flag&1) {
|
||||
*severity_name=
|
||||
"NEVER\nABORT\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL";
|
||||
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL";
|
||||
return(1);
|
||||
}
|
||||
*severity_name= "";
|
||||
@ -289,6 +294,10 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||
*severity_name= "ABORT";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_FATAL)
|
||||
*severity_name= "FATAL";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_FAILURE)
|
||||
*severity_name= "FAILURE";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_MISHAP)
|
||||
*severity_name= "MISHAP";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_SORRY)
|
||||
*severity_name= "SORRY";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_WARNING)
|
||||
@ -301,6 +310,8 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||
*severity_name= "UPDATE";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_DEBUG)
|
||||
*severity_name= "DEBUG";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_ERRFILE)
|
||||
*severity_name= "ERRFILE";
|
||||
else if(severity>=LIBDAX_MSGS_SEV_ALL)
|
||||
*severity_name= "ALL";
|
||||
else {
|
||||
@ -311,7 +322,7 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||
}
|
||||
|
||||
|
||||
int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
|
||||
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||
int severity, int priority, char *msg_text,
|
||||
int os_errno, int flag)
|
||||
{
|
||||
@ -349,7 +360,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
|
||||
ret= libdax_msgs_item_new(&item,m->youngest,0);
|
||||
if(ret<=0)
|
||||
goto failed;
|
||||
item->driveno= driveno;
|
||||
item->origin= origin;
|
||||
item->error_code= error_code;
|
||||
item->severity= severity;
|
||||
item->priority= priority;
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
/* libdax_msgs
|
||||
Message handling facility of libdax.
|
||||
Copyright (C) 2006-2007 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL
|
||||
Copyright (C) 2006-2009 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL version 2
|
||||
*/
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ struct libdax_msgs_item {
|
||||
|
||||
double timestamp;
|
||||
pid_t process_id;
|
||||
int driveno;
|
||||
int origin;
|
||||
|
||||
int severity;
|
||||
int priority;
|
||||
@ -120,6 +120,19 @@ struct libdax_msgs_item;
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_ALL 0x00000000
|
||||
|
||||
|
||||
/** Messages of this severity shall transport plain disk file paths
|
||||
whenever an event of severity SORRY or above is related with an
|
||||
individual disk file.
|
||||
No message text shall be added to the file path. The ERRFILE message
|
||||
shall be issued before the human readable message which carries the
|
||||
true event severity. That message should contain the file path so it
|
||||
can be found by strstr(message, path)!=NULL.
|
||||
The error code shall be the same as with the human readable message.
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_ERRFILE 0x08000000
|
||||
|
||||
|
||||
/** Debugging messages not to be visible to normal users by default
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_DEBUG 0x10000000
|
||||
@ -140,15 +153,70 @@ struct libdax_msgs_item;
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_WARNING 0x50000000
|
||||
|
||||
/** Non-fatal error messages indicating that parts of the action failed
|
||||
but processing will/should go on
|
||||
|
||||
/** Non-fatal error messages indicating that parts of an action failed but
|
||||
processing may go on if one accepts deviations from the desired result.
|
||||
|
||||
SORRY may also be the severity for incidents which are severe enough
|
||||
for FAILURE but happen within already started irrevocable actions,
|
||||
like ISO image generation. A precondition for such a severity ease is
|
||||
that the action can be continued after the incident.
|
||||
See below MISHAP for what xorriso would need instead of this kind of SORRY
|
||||
and generates for itself in case of libisofs image generation.
|
||||
|
||||
E.g.: A pattern yields no result.
|
||||
A speed setting cannot be made.
|
||||
A libisofs input file is inaccessible during image generation.
|
||||
|
||||
After SORRY a function should try to go on if that makes any sense
|
||||
and if no threshold prescribes abort on SORRY. The function should
|
||||
nevertheless indicate some failure in its return value.
|
||||
It should - but it does not have to.
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_SORRY 0x60000000
|
||||
|
||||
|
||||
/** A FAILURE (see below) which can be tolerated during long lasting
|
||||
operations just because they cannot simply be stopped or revoked.
|
||||
|
||||
xorriso converts libisofs SORRY messages issued during image generation
|
||||
into MISHAP messages in order to allow its evaluators to distinguish
|
||||
image generation problems from minor image composition problems.
|
||||
E.g.:
|
||||
A libisofs input file is inaccessible during image generation.
|
||||
|
||||
After a MISHAP a function should behave like after SORRY.
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_MISHAP 0x64000000
|
||||
|
||||
|
||||
/** Non-fatal error indicating that an important part of an action failed and
|
||||
that only a new setup of preconditions will give hope for sufficient
|
||||
success.
|
||||
|
||||
E.g.: No media is inserted in the output drive.
|
||||
No write mode can be found for inserted media.
|
||||
A libisofs input file is inaccessible during grafting.
|
||||
|
||||
After FAILURE a function should end with a return value indicating failure.
|
||||
It is at the discretion of the function whether it ends immediately in any
|
||||
case or whether it tries to go on if the eventual threshold allows.
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_FAILURE 0x68000000
|
||||
|
||||
|
||||
/** An error message which puts the whole operation of the program in question
|
||||
|
||||
E.g.: Not enough memory for essential temporary objects.
|
||||
Irregular errors from resources.
|
||||
Programming errors (soft assert).
|
||||
|
||||
After FATAL a function should end very soon with a return value
|
||||
indicating severe failure.
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_FATAL 0x70000000
|
||||
|
||||
|
||||
/** A message from an abort handler which will finally finish libburn
|
||||
*/
|
||||
#define LIBDAX_MSGS_SEV_ABORT 0x71000000
|
||||
@ -173,6 +241,16 @@ struct libdax_msgs_item;
|
||||
#define LIBDAX_MSGS_PRIO_NEVER 0x7fffffff
|
||||
|
||||
|
||||
/* Origin numbers of libburn drives may range from 0 to 1048575 */
|
||||
#define LIBDAX_MSGS_ORIGIN_DRIVE_BASE 0
|
||||
#define LIBDAX_MSGS_ORIGIN_DRIVE_TOP 0xfffff
|
||||
|
||||
/* Origin numbers of libisofs images may range from 1048575 to 2097152 */
|
||||
#define LIBDAX_MSGS_ORIGIN_IMAGE_BASE 0x100000
|
||||
#define LIBDAX_MSGS_ORIGIN_IMAGE_TOP 0x1fffff
|
||||
|
||||
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
/* Calls initiated from inside the direct owner (e.g. from libburn) */
|
||||
@ -211,7 +289,10 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
|
||||
|
||||
|
||||
/** Submit a message to a message handling facility.
|
||||
@param driveno program specific drive number. Use -1 if no number is known.
|
||||
@param origin program specific identification number of the originator of
|
||||
a message. E.g. drive number. Programs should have an own
|
||||
range of origin numbers. See above LIBDAX_MSGS_ORIGIN_*_BASE
|
||||
Use -1 if no number is known.
|
||||
@param error_code Unique error code. Use only registered codes. See below.
|
||||
The same unique error_code may be issued at different
|
||||
occasions but those should be equivalent out of the view
|
||||
@ -224,11 +305,12 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@return 1 on success, 0 on rejection, <0 for severe errors
|
||||
*/
|
||||
int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
|
||||
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||
int severity, int priority, char *msg_text,
|
||||
int os_errno, int flag);
|
||||
|
||||
|
||||
|
||||
/* Calls from applications (to be forwarded by direct owner) */
|
||||
|
||||
|
||||
@ -300,7 +382,7 @@ int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
|
||||
@return 1 on success, 0 on invalid item, <0 for servere errors
|
||||
*/
|
||||
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
|
||||
double *timestamp, pid_t *process_id, int *driveno,
|
||||
double *timestamp, pid_t *process_id, int *origin,
|
||||
int flag);
|
||||
|
||||
|
||||
@ -350,6 +432,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
|
||||
0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock
|
||||
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
|
||||
0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive
|
||||
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
||||
|
||||
General library operations:
|
||||
|
||||
@ -441,7 +525,31 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020156 (SORRY,HIGH) = Desired fifo buffer too small
|
||||
0x00020157 (FATAL,HIGH) = burn_source is not a fifo object
|
||||
0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions
|
||||
|
||||
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
||||
0x0002015a (NOTE,HIGH) = Could not examine busy device
|
||||
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
|
||||
0x0002015c (FAILURE,HIGH) = Fifo size is smaller than desired peek buffer
|
||||
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
|
||||
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
|
||||
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
|
||||
0x00020160 (WARNING,HIGH) = Session without leadout encountered
|
||||
0x00020161 (WARNING,HIGH) = Empty session deleted
|
||||
0x00020162 (SORRY,HIGH) = BD-R not unformatted blank any more. Cannot format
|
||||
0x00020163 (NOTE,HIGH) = Blank BD-R left unformatted for zero spare capacity
|
||||
0x00020164 (SORRY,HIGH) = Drive does not format BD-RE without spares
|
||||
0x00020165 (WARNING,HIGH) = Drive does not support fast formatting
|
||||
0x00020166 (WARNING,HIGH) = Drive does not support full formatting
|
||||
0x00020167 (SORRY,HIGH) = Drive does not support non-default formatting
|
||||
0x00020168 (FAILURE,HIGH) = Media not properly formatted. Cannot write.
|
||||
0x00020169 (WARNING,HIGH) = Last session on media is still open
|
||||
0x0002016a (FAILURE,HIGH) = No MMC transport adapter is present
|
||||
0x0002016b (WARNING,HIGH) = No MMC transport adapter is present
|
||||
0x0002016c (DEBUG,HIGH) = No MMC transport adapter is present
|
||||
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
||||
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
||||
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
|
||||
|
||||
|
||||
libdax_audioxtr:
|
||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||
@ -453,34 +561,81 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
------------------------------------------------------------------------------
|
||||
Range "vreixo" : 0x00030000 to 0x0003ffff
|
||||
|
||||
General:
|
||||
0x00031001 (SORRY,HIGH) = Cannot read file (ignored)
|
||||
0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled)
|
||||
0x0003ffff (FAILURE,HIGH) = Operation canceled
|
||||
0x0003fffe (FATAL,HIGH) = Unknown or unexpected fatal error
|
||||
0x0003fffd (FAILURE,HIGH) = Unknown or unexpected error
|
||||
0x0003fffc (FATAL,HIGH) = Internal programming error
|
||||
0x0003fffb (FAILURE,HIGH) = NULL pointer where NULL not allowed
|
||||
0x0003fffa (FATAL,HIGH) = Memory allocation error
|
||||
0x0003fff9 (FATAL,HIGH) = Interrupted by a signal
|
||||
0x0003fff8 (FAILURE,HIGH) = Invalid parameter value
|
||||
0x0003fff7 (FATAL,HIGH) = Cannot create a needed thread
|
||||
0x0003fff6 (FAILURE,HIGH) = Write error
|
||||
0x0003fff5 (FAILURE,HIGH) = Buffer read error
|
||||
0x0003ffc0 (FAILURE,HIGH) = Trying to add a node already added to another dir
|
||||
0x0003ffbf (FAILURE,HIGH) = Node with same name already exist
|
||||
0x0003ffbe (FAILURE,HIGH) = Trying to remove a node that was not added to dir
|
||||
0x0003ffbd (FAILURE,HIGH) = A requested node does not exist
|
||||
0x0003ffbc (FAILURE,HIGH) = Image already bootable
|
||||
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
|
||||
0x0003ff80 (FAILURE,HIGH) = Error on file operation
|
||||
0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file
|
||||
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
|
||||
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
|
||||
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
|
||||
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned
|
||||
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
|
||||
0x0003ff79 (FAILURE,HIGH) = File read error
|
||||
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
|
||||
0x0003ff77 (FAILURE,HIGH) = Not symlink used where a symlink is expected
|
||||
0x0003ff76 (FAILURE,HIGH) = Cannot seek to specified location
|
||||
0x0003ff75 (HINT,MEDIUM) = File not supported in ECMA-119 tree and ignored
|
||||
0x0003ff74 (HINT,MEDIUM) = File bigger than supported by used standard
|
||||
0x0003ff73 (MISHAP,HIGH) = File read error during image creation
|
||||
0x0003ff72 (HINT,MEDIUM) = Cannot convert filename to requested charset
|
||||
0x0003ff71 (SORRY,HIGH) = File cannot be added to the tree
|
||||
0x0003ff70 (HINT,MEDIUM) = File path breaks specification constraints
|
||||
0x0003ff00 (FAILURE,HIGH) = Charset conversion error
|
||||
0x0003feff (FAILURE,HIGH) = Too much files to mangle
|
||||
0x0003fec0 (FAILURE,HIGH) = Wrong or damaged Primary Volume Descriptor
|
||||
0x0003febf (SORRY,HIGH) = Wrong or damaged RR entry
|
||||
0x0003febe (SORRY,HIGH) = Unsupported RR feature
|
||||
0x0003febd (FAILURE,HIGH) = Wrong or damaged ECMA-119
|
||||
0x0003febc (FAILURE,HIGH) = Unsupported ECMA-119 feature
|
||||
0x0003febb (SORRY,HIGH) = Wrong or damaged El-Torito catalog
|
||||
0x0003feba (SORRY,HIGH) = Unsupported El-Torito feature
|
||||
0x0003feb9 (SORRY,HIGH) = Cannot patch isolinux boot image
|
||||
0x0003feb8 (SORRY,HIGH) = Unsupported SUSP feature
|
||||
0x0003feb7 (WARNING,HIGH) = Error on a RR entry that can be ignored
|
||||
0x0003feb6 (HINT,MEDIUM) = Error on a RR entry that can be ignored
|
||||
0x0003feb5 (WARNING,HIGH) = Multiple ER SUSP entries found
|
||||
0x0003feb4 (HINT,MEDIUM) = Unsupported volume descriptor found
|
||||
0x0003feb3 (WARNING,HIGH) = El-Torito related warning
|
||||
0x0003feb2 (MISHAP,HIGH) = Image write cancelled
|
||||
0x0003feb1 (WARNING,HIGH) = El-Torito image is hidden
|
||||
|
||||
Image reading:
|
||||
0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image
|
||||
0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored
|
||||
0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image
|
||||
0x00031003 (SORRY,HIGH) = Cannot read previous image file
|
||||
|
||||
Rock-Ridge:
|
||||
0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored
|
||||
0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry
|
||||
0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found
|
||||
0x00030111 (SORRY,HIGH) = Unsupported RR feature
|
||||
0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry
|
||||
|
||||
El-Torito:
|
||||
0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored
|
||||
0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog
|
||||
0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
|
||||
0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
||||
0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
||||
0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
||||
enought info about it
|
||||
|
||||
Joliet:
|
||||
0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
||||
Outdated codes which may not be re-used for other purposes than
|
||||
re-instating them, if ever:
|
||||
|
||||
X 0x00031001 (SORRY,HIGH) = Cannot read file (ignored)
|
||||
X 0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled)
|
||||
X 0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image
|
||||
X 0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored
|
||||
X 0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image
|
||||
X 0x00031003 (SORRY,HIGH) = Cannot read previous image file
|
||||
X 0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored
|
||||
X 0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry
|
||||
X 0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found
|
||||
X 0x00030111 (SORRY,HIGH) = Unsupported RR feature
|
||||
X 0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry
|
||||
X 0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored
|
||||
X 0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog
|
||||
X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
|
||||
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
||||
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
||||
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
||||
X enought info about it
|
||||
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@ -494,6 +649,23 @@ Range "application" : 0x00040000 to 0x0004ffff
|
||||
0x00040005 (NOTE,HIGH) : Application supplied message
|
||||
0x00040006 (UPDATE,HIGH) : Application supplied message
|
||||
0x00040007 (DEBUG,HIGH) : Application supplied message
|
||||
0x00040008 (*,HIGH) : Application supplied message
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Range "libisofs-xorriso" : 0x00050000 to 0x0005ffff
|
||||
|
||||
This is an alternative representation of libisofs.so.6 error codes in xorriso.
|
||||
If values returned by iso_error_get_code() do not fit into 0x30000 to 0x3ffff
|
||||
then they get truncated to 16 bit and mapped into this range.
|
||||
(This should never need to happen, of course.)
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Range "libisoburn" : 0x00060000 to 0x00006ffff
|
||||
|
||||
0x00060000 (*,*) : Message which shall be attributed to libisoburn
|
||||
|
||||
>>> the messages of libisoburn need to be registered individually
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
1183
libburn/mmc.c
1183
libburn/mmc.c
File diff suppressed because it is too large
Load Diff
@ -72,6 +72,11 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||
struct buffer *buf);
|
||||
|
||||
/* ts A81210 : Determine the upper limit of readable data size */
|
||||
int mmc_read_capacity(struct burn_drive *d);
|
||||
|
||||
/* ts A61201 */
|
||||
char *mmc_obtain_profile_name(int profile_number);
|
||||
|
||||
|
||||
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
||||
|
@ -38,6 +38,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||
opts->start_byte = -1;
|
||||
opts->fill_up_media = 0;
|
||||
opts->force_is_set = 0;
|
||||
opts->do_stream_recording = 0;
|
||||
opts->has_mediacatalog = 0;
|
||||
opts->format = BURN_CDROM;
|
||||
opts->multi = 0;
|
||||
@ -142,7 +143,7 @@ int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
|
||||
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
||||
int underrun_proof)
|
||||
{
|
||||
if (!opts->drive->mdata->valid)
|
||||
if (opts->drive->mdata->valid <= 0)
|
||||
return 0;
|
||||
if (opts->drive->mdata->underrun_proof) {
|
||||
opts->underrun_proof = underrun_proof;
|
||||
@ -380,6 +381,16 @@ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
|
||||
}
|
||||
|
||||
|
||||
/* ts A80412: API */
|
||||
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
||||
int value)
|
||||
{
|
||||
opts->do_stream_recording = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ts A70901: API */
|
||||
struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts)
|
||||
{
|
||||
|
@ -49,6 +49,11 @@ struct burn_write_opts
|
||||
*/
|
||||
int force_is_set;
|
||||
|
||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
||||
This gets transferred to burn_drive.do_stream_recording */
|
||||
int do_stream_recording;
|
||||
|
||||
/** A disc can have a media catalog number */
|
||||
int has_mediacatalog;
|
||||
unsigned char mediacatalog[13];
|
||||
|
63
libburn/os-dummy.h
Normal file
63
libburn/os-dummy.h
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
/* os-dummy.h
|
||||
Operating system specific libburn definitions and declarations. Included
|
||||
by os.h in case of compilation for
|
||||
Unknown POSIX like systems
|
||||
with the dummy MMC transport adapter sg-dummy.c
|
||||
|
||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
*/
|
||||
|
||||
|
||||
/** List of all signals which shall be caught by signal handlers and trigger
|
||||
a graceful abort of libburn. (See man 7 signal.)
|
||||
*/
|
||||
/* Once as system defined macros */
|
||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
||||
SIGTTOU
|
||||
|
||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
||||
"SIGTTOU"
|
||||
|
||||
/* The number of above list items */
|
||||
#define BURN_OS_SIGNAL_COUNT 16
|
||||
|
||||
/** To list all signals which shall surely not be caught */
|
||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||
SIGKILL, SIGCHLD, SIGSTOP
|
||||
|
||||
/* The number of above list items */
|
||||
#define BURN_OS_NON_SIGNAL_COUNT 3
|
||||
|
||||
|
||||
/* The maximum size for a (SCSI) i/o transaction */
|
||||
/* Important : MUST be at least 32768 ! */
|
||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||
|
||||
|
||||
/* To hold the position of the most recently delivered address from
|
||||
device enumeration.
|
||||
*/
|
||||
struct burn_drive_enumerator_struct {
|
||||
int pos;
|
||||
int info_count;
|
||||
char **info_list;
|
||||
};
|
||||
|
||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
||||
|
||||
|
||||
/* The list of operating system dependent elements in struct burn_drive.
|
||||
Usually they are initialized in sg-*.c:enumerate_common().
|
||||
*/
|
||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||
int just_a_dummy;
|
||||
|
@ -43,16 +43,25 @@ SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
||||
/* The maximum size for a (SCSI) i/o transaction */
|
||||
/* Important : MUST be at least 32768 ! */
|
||||
/* ts A70523 : >32k seems not good with kernel 2.4 USB drivers and audio
|
||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
||||
*/
|
||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
||||
/* ts A80414 : curbed in write.c CD media to Libburn_cd_obS = 32 kiB
|
||||
re-enlarged transport to 64 kiB for BD-RE experiments
|
||||
*/
|
||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||
|
||||
|
||||
/* To hold the index number of the most recently delivered address from
|
||||
/* To hold the position of the most recently delivered address from
|
||||
device enumeration.
|
||||
*/
|
||||
struct burn_drive_enumerator_struct {
|
||||
int pos;
|
||||
int info_count;
|
||||
char **info_list;
|
||||
};
|
||||
|
||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||
typedef int burn_drive_enumerator_t;
|
||||
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
||||
|
||||
|
||||
/* Parameters for sibling list. See sibling_fds, sibling_fnames */
|
||||
|
15
libburn/os.h
15
libburn/os.h
@ -3,7 +3,7 @@
|
||||
Operating system specific libburn definitions and declarations.
|
||||
The macros defined here are used by libburn modules in order to
|
||||
avoid own system dependent case distinctions.
|
||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
*/
|
||||
|
||||
#ifndef BURN_OS_H_INCLUDED
|
||||
@ -20,14 +20,23 @@
|
||||
#include "os-freebsd.h"
|
||||
|
||||
|
||||
#else /* operating system case distinction */
|
||||
#else
|
||||
#ifdef __linux
|
||||
|
||||
|
||||
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
||||
#include "os-linux.h"
|
||||
|
||||
|
||||
#endif /* End of operating system case distinction */
|
||||
#else
|
||||
|
||||
|
||||
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
|
||||
#include "os-dummy.h"
|
||||
|
||||
|
||||
#endif /* ! __linux */
|
||||
#endif /* ! __FreeBSD__ */
|
||||
|
||||
|
||||
#endif /* ! BURN_OS_H_INCLUDED */
|
||||
|
@ -292,7 +292,7 @@ static void flipq(unsigned char *sub)
|
||||
|
||||
|
||||
/* ts A70904 */
|
||||
/** @param flag bit=be silent on data shortage */
|
||||
/** @param flag bit0=be silent on data shortage */
|
||||
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
||||
int flag)
|
||||
{
|
||||
@ -323,7 +323,20 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size, i;
|
||||
int sose_mem = 0, fd = -1, ret;
|
||||
char msg[81], *wpt;
|
||||
struct buffer buf;
|
||||
struct buffer buf, *buffer_mem = d->buffer;
|
||||
|
||||
/*
|
||||
#define Libburn_read_data_adr_logginG 1
|
||||
*/
|
||||
#ifdef Libburn_read_data_adr_logginG
|
||||
static FILE *log_fp= NULL;
|
||||
|
||||
if(log_fp == NULL)
|
||||
log_fp = fopen("/tmp/burn_read_data_log", "a");
|
||||
if(log_fp!=NULL)
|
||||
fprintf(log_fp, "%d\n", (int) (byte_address / 2048));
|
||||
#endif /* Libburn_read_data_logginG */
|
||||
|
||||
|
||||
*data_count = 0;
|
||||
sose_mem = d->silent_on_scsi_error;
|
||||
@ -375,9 +388,12 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
fd = open(d->devname, O_RDONLY | O_LARGEFILE);
|
||||
fd = d->stdio_fd;
|
||||
if (fd < 0)
|
||||
d->stdio_fd = fd =
|
||||
open(d->devname, O_RDONLY | O_LARGEFILE);
|
||||
if (fd == -1) {
|
||||
if (!(flag & 1))
|
||||
if (errno != ENOENT || !(flag & 2))
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index,
|
||||
0x00020005,
|
||||
@ -387,10 +403,12 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
ret = 0; goto ex;
|
||||
}
|
||||
if (lseek(fd, byte_address, SEEK_SET) == -1) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020147,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Cannot address start byte", errno, 0);
|
||||
if (!(flag & 2))
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index,
|
||||
0x00020147,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Cannot address start byte", errno, 0);
|
||||
ret = 0; goto ex;
|
||||
}
|
||||
}
|
||||
@ -416,7 +434,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
err = d->read_10(d, start, chunksize, d->buffer);
|
||||
} else {
|
||||
ret = burn_stdio_read(fd, (char *) d->buffer->data,
|
||||
cpy_size, d, 0);
|
||||
cpy_size, d, !!(flag & 2));
|
||||
err = 0;
|
||||
if (ret <= 0)
|
||||
err = BE_CANCELLED;
|
||||
@ -425,7 +443,8 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
d->silent_on_scsi_error = sose_mem;
|
||||
if (err == BE_CANCELLED) {
|
||||
/* Try to read a smaller part of the chunk */
|
||||
for (i = 0; i < chunksize - 1; i++) {
|
||||
if(!(flag & 4))
|
||||
for (i = 0; i < chunksize - 1; i++) {
|
||||
if (flag & 2)
|
||||
d->silent_on_scsi_error = 1;
|
||||
if (d->drive_role == 1) {
|
||||
@ -446,6 +465,13 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
wpt += 2048;
|
||||
*data_count += 2048;
|
||||
}
|
||||
if (!(flag & 2))
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index,
|
||||
0x00020000,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"burn_read_data() returns 0",
|
||||
0, 0);
|
||||
ret = 0; goto ex;
|
||||
}
|
||||
memcpy(wpt, d->buffer->data, cpy_size);
|
||||
@ -455,9 +481,11 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||
|
||||
ret = 1;
|
||||
ex:;
|
||||
/* <<< let it open until drive is given up or writing shall happen
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
d->buffer = NULL;
|
||||
*/
|
||||
d->buffer = buffer_mem;
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
return ret;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ int mmc_function_spy(struct burn_drive *d, char * text);
|
||||
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
||||
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
||||
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
||||
static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 };
|
||||
|
||||
void sbc_load(struct burn_drive *d)
|
||||
{
|
||||
@ -79,28 +80,46 @@ void sbc_eject(struct burn_drive *d)
|
||||
int sbc_start_unit(struct burn_drive *d)
|
||||
{
|
||||
struct command c;
|
||||
int ret;
|
||||
|
||||
if (mmc_function_spy(d, "start_unit") <= 0)
|
||||
return 0;
|
||||
|
||||
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||
/*
|
||||
memcpy(c.opcode, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||
c.oplen = sizeof(SBC_START_UNIT);
|
||||
c.page = NULL;
|
||||
*/
|
||||
c.retry = 1;
|
||||
|
||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
if (c.error)
|
||||
return 0;
|
||||
/* ts A70918 : now asynchronous */
|
||||
return spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||
d->is_stopped = 0;
|
||||
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ts A90824 : Trying to reduce drive noise */
|
||||
int sbc_stop_unit(struct burn_drive *d)
|
||||
{
|
||||
struct command c;
|
||||
int ret;
|
||||
|
||||
if (mmc_function_spy(d, "stop_unit") <= 0)
|
||||
return 0;
|
||||
|
||||
scsi_init_command(&c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
|
||||
c.retry = 1;
|
||||
c.opcode[1] |= 1; /* Immed */
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
if (c.error)
|
||||
return 0;
|
||||
ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
|
||||
d->is_stopped = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
||||
*/
|
||||
@ -109,6 +128,8 @@ int sbc_setup_drive(struct burn_drive *d)
|
||||
d->eject = sbc_eject;
|
||||
d->load = sbc_load;
|
||||
d->start_unit = sbc_start_unit;
|
||||
d->stop_unit = sbc_stop_unit;
|
||||
d->is_stopped = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,12 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
||||
/* Next we use source data */
|
||||
curr = valid;
|
||||
if (!track->eos) {
|
||||
valid = track->source->read(track->source, data + curr, count - curr);
|
||||
if (track->source->read != NULL)
|
||||
valid = track->source->read(track->source,
|
||||
data + curr, count - curr);
|
||||
else
|
||||
valid = track->source->read_xt(track->source,
|
||||
data + curr, count - curr);
|
||||
} else valid = 0;
|
||||
|
||||
if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */
|
||||
|
229
libburn/sg-dummy.c
Normal file
229
libburn/sg-dummy.c
Normal file
@ -0,0 +1,229 @@
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/*
|
||||
|
||||
This is the main operating system dependent SCSI part of libburn. It implements
|
||||
the transport level aspects of SCSI control and command i/o.
|
||||
|
||||
Present implementation: default dummy which enables libburn only to work
|
||||
with stdio: pseudo drive addresses.
|
||||
For real implementations see sg-linux.c or sg-freebsd.c
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef Libburn_os_has_statvfS
|
||||
#include <sys/statvfs.h>
|
||||
#endif /* Libburn_os_has_stavtfS */
|
||||
|
||||
#include "transport.h"
|
||||
#include "drive.h"
|
||||
#include "sg.h"
|
||||
#include "spc.h"
|
||||
#include "mmc.h"
|
||||
#include "sbc.h"
|
||||
#include "debug.h"
|
||||
#include "toc.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
|
||||
/** Returns the next index number and the next enumerated drive address.
|
||||
The enumeration has to cover all available and accessible drives. It is
|
||||
allowed to return addresses of drives which are not available but under
|
||||
some (even exotic) circumstances could be available. It is on the other
|
||||
hand allowed, only to hand out addresses which can really be used right
|
||||
in the moment of this call. (This implementation chooses the former.)
|
||||
@param idx An opaque handle. Make no own theories about it.
|
||||
@param adr Takes the reply
|
||||
@param adr_size Gives maximum size of reply including final 0
|
||||
@param initialize 1 = start new,
|
||||
0 = continue, use no other values for now
|
||||
-1 = finish
|
||||
@return 1 = reply is a valid address , 0 = no further address available
|
||||
-1 = severe error (e.g. adr_size too small)
|
||||
*/
|
||||
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||
char adr[], int adr_size, int initialize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Brings all available, not-whitelist-banned, and accessible drives into
|
||||
libburn's list of drives.
|
||||
*/
|
||||
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
||||
int scsi_enumerate_drives(void)
|
||||
{
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002016b,
|
||||
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
||||
0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/** Tells wether libburn has the given drive in use or exclusively reserved.
|
||||
If it is "open" then libburn will eventually call sg_release() on it when
|
||||
it is time to give up usage resp. reservation.
|
||||
*/
|
||||
/** Published as burn_drive.drive_is_open() */
|
||||
int sg_drive_is_open(struct burn_drive * d)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Opens the drive for SCSI commands and - if burn activities are prone
|
||||
to external interference on your system - obtains an exclusive access lock
|
||||
on the drive. (Note: this is not physical tray locking.)
|
||||
A drive that has been opened with sg_grab() will eventually be handed
|
||||
over to sg_release() for closing and unreserving.
|
||||
*/
|
||||
int sg_grab(struct burn_drive *d)
|
||||
{
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
||||
0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
||||
(Note: this is not physical tray locking.)
|
||||
*/
|
||||
int sg_release(struct burn_drive *d)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
the command succeeded or shall be retried or finally failed.
|
||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||
The callers get notified by c->error. An SCSI failure which leads not to
|
||||
a retry shall be notified via scsi_notify_error().
|
||||
The Libburn_log_sg_commandS facility might be of help when problems with
|
||||
a drive have to be examined. It shall stay disabled for normal use.
|
||||
@return: 1 success , <=0 failure
|
||||
*/
|
||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||
{
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
||||
0, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/** Tries to obtain SCSI address parameters.
|
||||
@return 1 is success , 0 is failure
|
||||
*/
|
||||
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||
int *target_no, int *lun_no)
|
||||
{
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002016c,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
||||
0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
int sg_is_enumerable_adr(char *adr)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/** Estimate the potential payload capacity of a file address.
|
||||
@param path The address of the file to be examined. If it does not
|
||||
exist yet, then the directory will be inquired.
|
||||
@param bytes The pointed value gets modified, but only if an estimation is
|
||||
possible.
|
||||
@return -2 = cannot perform necessary operations on file object
|
||||
-1 = neither path nor dirname of path exist
|
||||
0 = could not estimate size capacity of file object
|
||||
1 = estimation has been made, bytes was set
|
||||
*/
|
||||
int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
{
|
||||
struct stat stbuf;
|
||||
|
||||
#ifdef Libburn_os_has_statvfS
|
||||
struct statvfs vfsbuf;
|
||||
#endif
|
||||
|
||||
char testpath[4096], *cpt;
|
||||
long blocks;
|
||||
off_t add_size = 0;
|
||||
|
||||
testpath[0] = 0;
|
||||
blocks = *bytes / 512;
|
||||
if (stat(path, &stbuf) == -1) {
|
||||
strcpy(testpath, path);
|
||||
cpt = strrchr(testpath, '/');
|
||||
if(cpt == NULL)
|
||||
strcpy(testpath, ".");
|
||||
else if(cpt == testpath)
|
||||
testpath[1] = 0;
|
||||
else
|
||||
*cpt = 0;
|
||||
if (stat(testpath, &stbuf) == -1)
|
||||
return -1;
|
||||
|
||||
#ifdef Libburn_if_this_was_linuX
|
||||
|
||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||
fd = open(path, open_mode);
|
||||
if (fd == -1)
|
||||
return -2;
|
||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
||||
close(fd);
|
||||
if (ret == -1)
|
||||
return -2;
|
||||
*bytes = ((off_t) blocks) * (off_t) 512;
|
||||
|
||||
#endif /* Libburn_if_this_was_linuX */
|
||||
|
||||
} else if(S_ISREG(stbuf.st_mode)) {
|
||||
add_size = stbuf.st_blocks * (off_t) 512;
|
||||
strcpy(testpath, path);
|
||||
} else
|
||||
return 0;
|
||||
|
||||
if (testpath[0]) {
|
||||
|
||||
#ifdef Libburn_os_has_statvfS
|
||||
|
||||
if (statvfs(testpath, &vfsbuf) == -1)
|
||||
return -2;
|
||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
||||
(off_t) vfsbuf.f_bavail;
|
||||
|
||||
#else /* Libburn_os_has_statvfS */
|
||||
|
||||
return 0;
|
||||
|
||||
#endif /* ! Libburn_os_has_stavtfS */
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ Send feedback to libburn-hackers@pykix.org .
|
||||
#include <err.h> /* XXX */
|
||||
|
||||
|
||||
/* ts A70909 : >>> untestet yet wether this compiles */
|
||||
/* ts A70909 */
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@ -18,7 +17,7 @@
|
||||
#include <err.h> /* XXX */
|
||||
|
||||
|
||||
/* ts A70909 : >>> untestet yet wether this compiles */
|
||||
/* ts A70909 */
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
|
||||
@ -553,11 +552,26 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||
if (c->page) {
|
||||
ccb->csio.data_ptr = c->page->data;
|
||||
if (c->dir == FROM_DRIVE) {
|
||||
ccb->csio.dxfer_len = BUFFER_SIZE;
|
||||
|
||||
/* ts A90430 : Ticket 148 , by jwehle :
|
||||
"On ... FreeBSD 6.4 which has a usb memory reader in
|
||||
addition to a ATAPI DVD burner sg_issue_command
|
||||
will hang while the SCSI bus is being scanned"
|
||||
*/
|
||||
if (c->dxfer_len >= 0)
|
||||
ccb->csio.dxfer_len = c->dxfer_len;
|
||||
else
|
||||
ccb->csio.dxfer_len = BUFFER_SIZE;
|
||||
|
||||
/* touch page so we can use valgrind */
|
||||
memset(c->page->data, 0, BUFFER_SIZE);
|
||||
} else {
|
||||
assert(c->page->bytes > 0);
|
||||
/* ts A90430 */
|
||||
/* a ssert(c->page->bytes > 0); */
|
||||
if (c->page->bytes <= 0) {
|
||||
c->error = 1;
|
||||
return 0;
|
||||
}
|
||||
ccb->csio.dxfer_len = c->page->bytes;
|
||||
}
|
||||
} else {
|
||||
@ -622,7 +636,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
struct statvfs vfsbuf;
|
||||
char testpath[4096], *cpt;
|
||||
long blocks;
|
||||
int open_mode = O_RDWR, fd, ret;
|
||||
off_t add_size = 0;
|
||||
|
||||
testpath[0] = 0;
|
||||
@ -642,6 +655,8 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
#ifdef Libburn_if_this_was_linuX
|
||||
|
||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||
int open_mode = O_RDWR, fd, ret;
|
||||
|
||||
if(burn_sg_open_o_excl)
|
||||
open_mode |= O_EXCL;
|
||||
fd = open(path, open_mode);
|
||||
|
@ -90,6 +90,7 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
||||
|
||||
|
||||
/* ts A61211 : to eventually recognize CD devices on /dev/sr* */
|
||||
#include <limits.h>
|
||||
#include <linux/cdrom.h>
|
||||
|
||||
|
||||
@ -259,6 +260,37 @@ static void sg_select_device_family(void)
|
||||
}
|
||||
|
||||
|
||||
/* ts A80701 */
|
||||
/* This cares for the case that no /dev/srNN but only /dev/scdNN exists.
|
||||
A theoretical case which has its complement in SuSE 10.2 having
|
||||
/dev/sr but not /dev/scd.
|
||||
*/
|
||||
static int sg_exchange_scd_for_sr(char *fname, int flag)
|
||||
{
|
||||
struct stat stbuf;
|
||||
char scd[17], msg[160];
|
||||
|
||||
if (burn_sg_use_family != 0 || strncmp(fname, "/dev/sr", 7)!=0 ||
|
||||
strlen(fname)>9 || strlen(fname)<8)
|
||||
return 2;
|
||||
if (fname[7] < '0' || fname[7] > '9')
|
||||
return 2;
|
||||
if (fname [8] != 0 && (fname[7] < '0' || fname[7] > '9'))
|
||||
return 2;
|
||||
if (stat(fname, &stbuf) != -1)
|
||||
return 2;
|
||||
strcpy(scd, "/dev/scd");
|
||||
strcpy(scd + 8, fname + 7);
|
||||
if (stat(scd, &stbuf) == -1)
|
||||
return 2;
|
||||
sprintf(msg, "%s substitutes for non-existent %s", scd, fname);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
||||
strcpy(fname, scd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int sgio_test(int fd)
|
||||
{
|
||||
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
|
||||
@ -278,6 +310,33 @@ static int sgio_test(int fd)
|
||||
static int sg_handle_busy_device(char *fname, int os_errno)
|
||||
{
|
||||
char msg[4096];
|
||||
struct stat stbuf;
|
||||
int looks_like_hd= 0, fd, ret;
|
||||
|
||||
/* ts A80713 :
|
||||
check existence of /dev/hdX1 as hint for hard disk rather than CD
|
||||
Hint by Giulio Orsero: check /proc/ide/hdX/media for "disk"
|
||||
*/
|
||||
if (strncmp(fname, "/dev/hd", 7)==0) {
|
||||
sprintf(msg, "%s1", fname);
|
||||
if (stat(msg, &stbuf) != -1)
|
||||
looks_like_hd= 1;
|
||||
sprintf(msg, "/proc/ide/hd%c/media", fname[7]);
|
||||
fd = open(msg, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
ret = read(fd, msg, 10);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
msg[ret]= 0;
|
||||
close(fd);
|
||||
if (strncmp(msg, "disk\n", 5) == 0 ||
|
||||
strcmp(msg, "disk") == 0)
|
||||
looks_like_hd= 2;
|
||||
else if (strncmp(msg, "cdrom\n", 6) == 0 ||
|
||||
strcmp(msg, "cdrom") == 0)
|
||||
looks_like_hd= 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ts A60814 : i saw no way to do this more nicely */
|
||||
if (burn_sg_open_abort_busy) {
|
||||
@ -291,10 +350,26 @@ static int sg_handle_busy_device(char *fname, int os_errno)
|
||||
}
|
||||
|
||||
/* ts A60924 : now reporting to libdax_msgs */
|
||||
sprintf(msg, "Cannot open busy device '%s'", fname);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020001,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW,
|
||||
msg, os_errno, 0);
|
||||
if (looks_like_hd == 2) { /* is surely hard disk */
|
||||
;
|
||||
} else if (looks_like_hd) {
|
||||
sprintf(msg, "Could not examine busy device '%s'", fname);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015a,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_LOW,
|
||||
msg, os_errno, 0);
|
||||
sprintf(msg,
|
||||
"Busy '%s' seems to be a hard disk, as '%s1' exists. But better check.",
|
||||
fname, fname);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015b,
|
||||
LIBDAX_MSGS_SEV_HINT, LIBDAX_MSGS_PRIO_LOW,
|
||||
msg, 0, 0);
|
||||
|
||||
} else {
|
||||
sprintf(msg, "Cannot open busy device '%s'", fname);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020001,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW,
|
||||
msg, os_errno, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -307,6 +382,28 @@ static int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry)
|
||||
|
||||
if(*fd < 0)
|
||||
return(0);
|
||||
|
||||
#ifdef CDROM_MEDIA_CHANGED_disabled_because_not_helpful
|
||||
#ifdef CDSL_CURRENT
|
||||
/* ts A80217 : wondering whether the os knows about our activities */
|
||||
ret = ioctl(*fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT);
|
||||
sprintf(msg, "ioctl(CDROM_MEDIA_CHANGED) == %d", ret);
|
||||
libdax_msgs_submit(libdax_messenger, driveno, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
||||
|
||||
#ifdef BLKFLSBUF_disabled_because_not_helpful
|
||||
ret = ioctl(*fd, BLKFLSBUF, 0);
|
||||
sprintf(msg, "ioctl(BLKFLSBUF) == %d", ret);
|
||||
os_errno = 0;
|
||||
if(ret == -1)
|
||||
os_errno = errno;
|
||||
libdax_msgs_submit(libdax_messenger, driveno, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno,0);
|
||||
#endif /* BLKFLSBUF */
|
||||
|
||||
#endif /* CDSL_CURRENT */
|
||||
#endif /* CDROM_MEDIA_CHANGED */
|
||||
|
||||
ret = close(*fd);
|
||||
*fd = -1337;
|
||||
if(ret != -1) {
|
||||
@ -373,7 +470,7 @@ static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous)
|
||||
/* ts A60926 */
|
||||
static int sg_open_drive_fd(char *fname, int scan_mode)
|
||||
{
|
||||
int open_mode = O_RDWR, fd;
|
||||
int open_mode = O_RDWR, fd, tries= 0;
|
||||
char msg[81];
|
||||
|
||||
/* ts A70409 : DDLP-B */
|
||||
@ -405,7 +502,8 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
|
||||
"libburn: experimental: O_EXCL= %d , O_NDELAY= %d\n",
|
||||
!!(open_mode&O_EXCL),!!(open_mode&O_NDELAY));
|
||||
*/
|
||||
|
||||
|
||||
try_open:;
|
||||
fd = open(fname, open_mode);
|
||||
if (fd == -1) {
|
||||
/* <<< debugging
|
||||
@ -414,6 +512,17 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
|
||||
fname,errno);
|
||||
*/
|
||||
if (errno == EBUSY) {
|
||||
tries++;
|
||||
|
||||
/* <<< debugging
|
||||
fprintf(stderr,
|
||||
"\nlibburn_DEBUG: EBUSY , tries= %d\n", tries);
|
||||
*/
|
||||
|
||||
if (tries < 4) {
|
||||
usleep(2000000);
|
||||
goto try_open;
|
||||
}
|
||||
sg_handle_busy_device(fname, errno);
|
||||
return -1;
|
||||
|
||||
@ -547,12 +656,193 @@ failed:;
|
||||
}
|
||||
|
||||
|
||||
#define Libburn_drive_new_deaL 1
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
|
||||
/* ts A80731 */
|
||||
static int is_ata_drive(char *fname)
|
||||
{
|
||||
int fd;
|
||||
struct hd_driveid tm;
|
||||
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 0;
|
||||
}
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
||||
int *channel_no, int *target_no, int *lun_no)
|
||||
{
|
||||
int fd, sid_ret = 0, ret;
|
||||
struct sg_scsi_id sid;
|
||||
int sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0;
|
||||
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];
|
||||
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
if (sgio_test(fd) == -1) {
|
||||
if (linux_sg_enumerate_debug)
|
||||
fprintf(stderr,
|
||||
"FATAL: sgio_test() failed: errno=%d '%s'",
|
||||
errno, strerror(errno));
|
||||
|
||||
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CDROM_DRIVE_STATUS
|
||||
/* 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 */
|
||||
|
||||
}
|
||||
|
||||
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
|
||||
/* Hearsay A61005 */
|
||||
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1)
|
||||
*bus_no = -1;
|
||||
#endif
|
||||
|
||||
if (sg_close_drive_fd(fname, -1, &fd,
|
||||
sid.scsi_type == TYPE_ROM ) <= 0) {
|
||||
if (linux_sg_enumerate_debug)
|
||||
fprintf(stderr,
|
||||
"cannot close properly, errno=%d '%s'\n",
|
||||
errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ts A60927 : trying to do locking with growisofs */
|
||||
if(burn_sg_open_o_excl>1) {
|
||||
ret = sg_open_scsi_siblings(
|
||||
fname, -1, sibling_fds, sibling_fnames,
|
||||
&sibling_count,
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
/* the final occupation will be done in sg_grab() */
|
||||
sg_release_siblings(sibling_fds, sibling_fnames,
|
||||
&sibling_count);
|
||||
}
|
||||
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
|
||||
if(*bus_no == -1)
|
||||
*bus_no = 1000 * (sid.host_no + 1) + sid.channel;
|
||||
#else
|
||||
*bus_no = sid.host_no;
|
||||
#endif
|
||||
*host_no= sid.host_no;
|
||||
*channel_no= sid.channel;
|
||||
*target_no= sid.scsi_id;
|
||||
*lun_no= sid.lun;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* Libburn_drive_new_deaL */
|
||||
|
||||
|
||||
/** Speciality of Linux: detect non-SCSI ATAPI (EIDE) which will from
|
||||
then on used used via generic SCSI as is done with (emulated) SCSI drives */
|
||||
static void ata_enumerate(void)
|
||||
{
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
|
||||
int ret;
|
||||
|
||||
#else
|
||||
struct hd_driveid tm;
|
||||
int i, fd;
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
int i;
|
||||
char fname[10];
|
||||
|
||||
if (linux_ata_enumerate_verbous)
|
||||
@ -573,6 +863,17 @@ static void ata_enumerate(void)
|
||||
fprintf(stderr, "not in whitelist\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
|
||||
ret = is_ata_drive(fname);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret == 0)
|
||||
continue;
|
||||
|
||||
#else /* Libburn_drive_new_deaL */
|
||||
|
||||
fd = sg_open_drive_fd(fname, 1);
|
||||
if (fd == -1) {
|
||||
if (linux_ata_enumerate_verbous)
|
||||
@ -609,6 +910,10 @@ static void ata_enumerate(void)
|
||||
errno, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif /* Libburn_drive_new_deaL */
|
||||
|
||||
|
||||
if (linux_ata_enumerate_verbous)
|
||||
fprintf(stderr, "accepting as drive without SCSI address\n");
|
||||
enumerate_common(fname, -1, -1, -1, -1, -1);
|
||||
@ -619,12 +924,18 @@ static void ata_enumerate(void)
|
||||
/** Detects (probably emulated) SCSI drives */
|
||||
static void sg_enumerate(void)
|
||||
{
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
|
||||
#else
|
||||
struct sg_scsi_id sid;
|
||||
int i, fd, sibling_fds[BURN_OS_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;
|
||||
char fname[10];
|
||||
int fd, sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0;
|
||||
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];
|
||||
int sid_ret = 0;
|
||||
#endif
|
||||
|
||||
int i, ret;
|
||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
||||
char fname[17];
|
||||
|
||||
sg_select_device_family();
|
||||
|
||||
@ -638,6 +949,9 @@ static void sg_enumerate(void)
|
||||
for (i = 0; i < 32; i++) {
|
||||
sprintf(fname, linux_sg_device_family, i);
|
||||
|
||||
/* ts A80702 */
|
||||
sg_exchange_scd_for_sr(fname, 0);
|
||||
|
||||
if (linux_sg_enumerate_debug)
|
||||
fprintf(stderr, "libburn_debug: %s : ", fname);
|
||||
|
||||
@ -648,6 +962,23 @@ static void sg_enumerate(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
|
||||
ret = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
|
||||
&target_no, &lun_no);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret == 0)
|
||||
continue;
|
||||
if (linux_sg_enumerate_debug)
|
||||
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||
host_no, channel_no, target_no, lun_no, bus_no);
|
||||
enumerate_common(fname, bus_no, host_no, channel_no,
|
||||
target_no, lun_no);
|
||||
|
||||
#else /* Libburn_drive_new_deaL */
|
||||
|
||||
/* ts A60927 */
|
||||
fd = sg_open_drive_fd(fname, 1);
|
||||
if (fd == -1) {
|
||||
@ -757,16 +1088,223 @@ 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);
|
||||
#endif /* Libburn_drive_new_deaL */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
|
||||
|
||||
/* ts A80805 : eventually produce the other official name of a device file */
|
||||
static int fname_other_name(char *fname, char other_name[80], int flag)
|
||||
{
|
||||
if(strncmp(fname, "/dev/sr", 7) == 0 &&
|
||||
(fname[7] >= '0' && fname[7] <= '9') &&
|
||||
(fname[8] == 0 ||
|
||||
(fname[8] >= '0' && fname[8] <= '9' && fname[9] == 0))) {
|
||||
sprintf(other_name, "/dev/scd%s", fname + 7);
|
||||
return 1;
|
||||
}
|
||||
if(strncmp(fname, "/dev/scd", 8) == 0 &&
|
||||
(fname[8] >= '0' && fname[8] <= '9') &&
|
||||
(fname[9] == 0 ||
|
||||
(fname[9] >= '0' && fname[9] <= '9' && fname[10] == 0))) {
|
||||
sprintf(other_name, "/dev/sr%s", fname + 8);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ts A80805 */
|
||||
static int fname_drive_is_listed(char *fname, int flag)
|
||||
{
|
||||
char other_fname[80];
|
||||
|
||||
if (burn_drive_is_listed(fname, NULL, 0))
|
||||
return 1;
|
||||
if (fname_other_name(fname, other_fname, 0) > 0)
|
||||
if (burn_drive_is_listed(other_fname, NULL, 0))
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ts A80731 : Directly open the given address.
|
||||
@param flag bit0= do not complain about missing file
|
||||
bit1= do not check whether drive is already listed
|
||||
*/
|
||||
static int fname_enumerate(char *fname, int flag)
|
||||
{
|
||||
int is_ata= 0, is_scsi= 0;
|
||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
||||
char msg[BURN_DRIVE_ADR_LEN + 80];
|
||||
struct stat stbuf;
|
||||
|
||||
if (!(flag & 2))
|
||||
if (fname_drive_is_listed(fname, 0))
|
||||
return 2;
|
||||
if (stat(fname, &stbuf) == -1) {
|
||||
sprintf(msg, "File object '%s' not found", fname);
|
||||
if (!(flag & 1))
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002000b,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_ata = is_ata_drive(fname);
|
||||
if (is_ata < 0)
|
||||
return -1;
|
||||
if (!is_ata)
|
||||
is_scsi = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
|
||||
&target_no, &lun_no);
|
||||
if (is_scsi < 0)
|
||||
return -1;
|
||||
if (is_ata == 0 && is_scsi == 0)
|
||||
return 0;
|
||||
|
||||
if (linux_sg_enumerate_debug)
|
||||
fprintf(stderr,
|
||||
"(single) accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||
host_no, channel_no, target_no, lun_no, bus_no);
|
||||
enumerate_common(fname, bus_no, host_no, channel_no,
|
||||
target_no, lun_no);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A80731 : Directly open the given address from a single-item whitlist */
|
||||
static int single_enumerate(int flag)
|
||||
{
|
||||
int ret, wl_count;
|
||||
char *fname, msg[BURN_DRIVE_ADR_LEN + 80];
|
||||
|
||||
wl_count= burn_drive_whitelist_count();
|
||||
if (wl_count != 1)
|
||||
return 0;
|
||||
fname= burn_drive_whitelist_item(0, 0);
|
||||
if (fname == NULL)
|
||||
return 0;
|
||||
ret = fname_enumerate(fname, 2);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg, "Cannot access '%s' as SG_IO CDROM drive", fname);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A80801 : looking up drives listed in /proc/sys/dev/cdrom/info line like:
|
||||
drive name: sr1 hdc hda sr0
|
||||
@parm flag bit0= release list memory and exit
|
||||
*/
|
||||
static int proc_sys_dev_cdrom_info(char ***list, int *count, int flag)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[1024], fname[1024 + 5], *cpt, *retpt, *list_data;
|
||||
int maxl= 0, pass, i;
|
||||
|
||||
if (*list != NULL) {
|
||||
if ((*list)[0] != NULL)
|
||||
free((*list)[0]);
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
*count = 0;
|
||||
}
|
||||
if (flag & 1)
|
||||
return 1;
|
||||
|
||||
*count = 0;
|
||||
sg_evaluate_kernel();
|
||||
if (sg_kernel_age < 2) /* addresses are not suitable for kernel 2.4 */
|
||||
return 1;
|
||||
fp = fopen("/proc/sys/dev/cdrom/info", "r");
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
while (1) {
|
||||
retpt = fgets(line, sizeof(line), fp);
|
||||
if (retpt == NULL)
|
||||
break;
|
||||
if(strncmp(line, "drive name:", 11) == 0)
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
if (retpt == NULL)
|
||||
return 0;
|
||||
strcpy(fname, "/dev/");
|
||||
for(pass = 0; pass < 2; pass++) {
|
||||
*count = 0;
|
||||
cpt = line + 11;
|
||||
while (*cpt != 0) {
|
||||
for(; *cpt == ' ' || *cpt == '\t'; cpt++);
|
||||
if (*cpt == 0 || *cpt == '\n')
|
||||
break;
|
||||
sscanf(cpt, "%s", fname + 5);
|
||||
if (strlen(fname) > maxl)
|
||||
maxl = strlen(fname);
|
||||
if (pass == 1)
|
||||
strcpy((*list)[*count], fname);
|
||||
(*count)++;
|
||||
for(cpt++; *cpt != ' ' && *cpt != '\t'
|
||||
&& *cpt != 0 && *cpt != '\n'; cpt++);
|
||||
}
|
||||
if (pass == 0) {
|
||||
list_data = calloc(*count + 1, maxl+1);
|
||||
*list = calloc(*count + 1, sizeof(char *));
|
||||
if(list_data == NULL || *list == NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, -1,
|
||||
0x00000003,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Out of virtual memory", 0, 0);
|
||||
if (list_data != NULL)
|
||||
free(list_data);
|
||||
if (*list != NULL)
|
||||
free((char *) *list);
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i <= *count; i++)
|
||||
(*list)[i] = list_data + i * (maxl + 1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int add_proc_info_drives(int flag)
|
||||
{
|
||||
int ret, list_count, count = 0, i;
|
||||
char **list= NULL;
|
||||
|
||||
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
for (i = 0; i < list_count; i++) {
|
||||
if (burn_drive_is_banned(list[i]))
|
||||
continue;
|
||||
ret = fname_enumerate(list[i], 1);
|
||||
if (ret == 1)
|
||||
count++;
|
||||
}
|
||||
proc_sys_dev_cdrom_info(&list, &list_count, 1); /* free memory */
|
||||
return 1 + count;
|
||||
}
|
||||
|
||||
#endif /* Libburn_drive_new_deaL */
|
||||
|
||||
|
||||
/* ts A61115 */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* PORTING: Private functions which contain publicly needed functionality. */
|
||||
@ -851,10 +1389,14 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||
{
|
||||
/* os-linux.h : typedef int burn_drive_enumerator_t; */
|
||||
static int sg_limit = 32, ata_limit = 26;
|
||||
int baseno = 0;
|
||||
int baseno = 0, i;
|
||||
char other_name[80];
|
||||
|
||||
if (initialize == -1)
|
||||
if (initialize == -1) {
|
||||
proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count),
|
||||
1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sg_select_device_family();
|
||||
if (linux_sg_device_family[0] == 0)
|
||||
@ -862,26 +1404,56 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||
if (linux_ata_device_family[0] == 0)
|
||||
ata_limit = 0;
|
||||
|
||||
if (initialize == 1)
|
||||
*idx = -1;
|
||||
(*idx)++;
|
||||
if (*idx >= sg_limit)
|
||||
if (initialize == 1) {
|
||||
idx->pos = -1;
|
||||
idx->info_count= 0;
|
||||
idx->info_list= NULL;
|
||||
proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count),
|
||||
0);
|
||||
}
|
||||
(idx->pos)++;
|
||||
if (idx->pos >= sg_limit)
|
||||
goto next_ata;
|
||||
if (adr_size < 10)
|
||||
if (adr_size < 11)
|
||||
return -1;
|
||||
sprintf(adr, linux_sg_device_family, *idx);
|
||||
return 1;
|
||||
sprintf(adr, linux_sg_device_family, idx->pos);
|
||||
|
||||
sg_exchange_scd_for_sr(adr, 0);
|
||||
goto return_1_pre_proc;
|
||||
|
||||
next_ata:;
|
||||
baseno += sg_limit;
|
||||
if (*idx - baseno >= ata_limit)
|
||||
goto next_nothing;
|
||||
if (idx->pos - baseno >= ata_limit)
|
||||
goto next_proc_info;
|
||||
if (adr_size < 9)
|
||||
return -1;
|
||||
sprintf(adr, linux_ata_device_family, 'a' + (*idx - baseno));
|
||||
return 1;
|
||||
next_nothing:;
|
||||
sprintf(adr, linux_ata_device_family, 'a' + (idx->pos - baseno));
|
||||
goto return_1_pre_proc;
|
||||
|
||||
next_proc_info:;
|
||||
baseno += ata_limit;
|
||||
for (i = 0; i < idx->info_count; i++) {
|
||||
if ((idx->info_list)[i][0] == 0)
|
||||
continue;
|
||||
if (baseno == idx->pos) {
|
||||
if (adr_size < strlen((idx->info_list)[i]) + 1)
|
||||
return -1;
|
||||
strcpy(adr, (idx->info_list)[i]);
|
||||
return 1;
|
||||
}
|
||||
baseno++;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return_1_pre_proc:;
|
||||
for (i = 0; i < idx->info_count; i++) {
|
||||
if (strcmp((idx->info_list)[i], adr) == 0)
|
||||
(idx->info_list)[i][0] = 0;
|
||||
if (fname_other_name(adr, other_name, 0) > 0)
|
||||
if (strcmp((idx->info_list)[i], other_name) == 0)
|
||||
(idx->info_list)[i][0] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -903,8 +1475,27 @@ next_nothing:;
|
||||
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
||||
int scsi_enumerate_drives(void)
|
||||
{
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
/* Direct examination of eventually single whitelisted name */
|
||||
ret = single_enumerate(0);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
if (ret > 0)
|
||||
return 1;
|
||||
#endif /* Libburn_drive_new_deaL */
|
||||
|
||||
sg_enumerate();
|
||||
ata_enumerate();
|
||||
|
||||
#ifdef Libburn_drive_new_deaL
|
||||
add_proc_info_drives(0);
|
||||
#endif /* Libburn_drive_new_deaL */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1355,9 +1946,9 @@ int sg_is_enumerable_adr(char *adr)
|
||||
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
||||
if (first == 0)
|
||||
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
28
libburn/sg.c
28
libburn/sg.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* sg.c
|
||||
Switcher for operating system dependent transport level modules of libburn.
|
||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
*/
|
||||
|
||||
|
||||
@ -10,8 +10,32 @@
|
||||
#include "sg-freebsd.c"
|
||||
|
||||
#else
|
||||
#ifdef __linux
|
||||
|
||||
#include "sg-linux.c"
|
||||
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* The dummy adapter formally fulfills the expectations of libburn towards
|
||||
its SCSI command transport. It will show no drives and perform no SCSI
|
||||
commands.
|
||||
libburn will then be restricted to using its stdio pseudo drives.
|
||||
*/
|
||||
static int intentional_compiler_warning(void)
|
||||
{
|
||||
int INTENTIONAL_COMPILER_WARNING_;
|
||||
int Cannot_recognize_Linux_nor_FreeBSD_;
|
||||
int Have_to_use_dummy_MMC_transport_adapter_;
|
||||
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
||||
int Have_to_use_dummy_MMC_transport_adapter;
|
||||
int Cannot_recognize_Linux_nor_FreeBSD;
|
||||
int INTENTIONAL_COMPILER_WARNING;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#include "sg-dummy.c"
|
||||
|
||||
#endif /* ! __linux */
|
||||
#endif /* ! __FreeBSD__ */
|
||||
|
||||
|
@ -18,8 +18,6 @@ void burn_source_free(struct burn_source *src)
|
||||
enum burn_source_status burn_track_set_source(struct burn_track *t,
|
||||
struct burn_source *s)
|
||||
{
|
||||
if (!s->read)
|
||||
return BURN_SOURCE_FAILED;
|
||||
s->refcount++;
|
||||
t->source = s;
|
||||
|
||||
@ -43,3 +41,15 @@ struct burn_source *burn_source_new(void)
|
||||
out->refcount = 1;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/* ts A71223 */
|
||||
int burn_source_cancel(struct burn_source *src)
|
||||
{
|
||||
if(src->read == NULL)
|
||||
if(src->version > 0)
|
||||
if(src->cancel != NULL)
|
||||
src->cancel(src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -5,4 +5,6 @@
|
||||
|
||||
struct burn_source *burn_source_new(void);
|
||||
|
||||
int burn_source_cancel(struct burn_source *src);
|
||||
|
||||
#endif /*__SOURCE*/
|
||||
|
457
libburn/spc.c
457
libburn/spc.c
@ -104,7 +104,9 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
int flag)
|
||||
{
|
||||
int i, ret = 1, key = 0, asc = 0, ascq = 0;
|
||||
char msg[160];
|
||||
char msg[320];
|
||||
unsigned char sense[14];
|
||||
enum response resp;
|
||||
|
||||
if (!(flag & 1))
|
||||
usleep(100000);
|
||||
@ -117,9 +119,9 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
i, ret, (unsigned) key, (unsigned) asc, (unsigned) ascq);
|
||||
*/
|
||||
|
||||
if(ret > 0) /* ready */
|
||||
if (ret > 0) /* ready */
|
||||
break;
|
||||
if(key!=0x2 || asc!=0x4) {
|
||||
if (key!=0x2 || asc!=0x4) {
|
||||
if (key == 0x2 && asc == 0x3A) {
|
||||
ret = 1; /* medium not present = ok */
|
||||
/* <<<
|
||||
@ -138,10 +140,24 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
/* media change notice = try again */
|
||||
goto slumber;
|
||||
|
||||
#ifdef NIX
|
||||
sprintf(msg,
|
||||
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||
cmd_text, (unsigned) key, (unsigned) asc,
|
||||
(unsigned) ascq);
|
||||
#else
|
||||
|
||||
/* ts A90213 */
|
||||
sprintf(msg,
|
||||
"Asynchromous SCSI error on %s: ", cmd_text);
|
||||
sense[2] = key;
|
||||
sense[12] = asc;
|
||||
sense[13] = ascq;
|
||||
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg),
|
||||
&key, &asc, &ascq);
|
||||
|
||||
#endif /* ! NIX */
|
||||
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002014d,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
@ -275,7 +291,7 @@ void spc_allow(struct burn_drive *d)
|
||||
}
|
||||
|
||||
/*
|
||||
ts A70518 : Do not call with *alloc_len < 8
|
||||
ts A70518 - A90603 : Do not call with *alloc_len < 10
|
||||
*/
|
||||
/** flag&1= do only inquire alloc_len */
|
||||
static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
@ -287,13 +303,19 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
unsigned char *page;
|
||||
struct command c;
|
||||
struct burn_speed_descriptor *sd;
|
||||
char msg[BURN_DRIVE_ADR_LEN + 160];
|
||||
|
||||
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
|
||||
static int speed_debug = 0;
|
||||
|
||||
if (*alloc_len < 8)
|
||||
if (*alloc_len < 10)
|
||||
return 0;
|
||||
|
||||
/* ts A90602 : Clearing mdata before command execution */
|
||||
m = d->mdata;
|
||||
m->valid = 0;
|
||||
burn_mdata_free_subs(m);
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||
/*
|
||||
@ -312,12 +334,11 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
d->issue_command(d, &c);
|
||||
if (c.error) {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
d->mdata->valid = -1;
|
||||
m->valid = -1;
|
||||
was_error = 1;
|
||||
}
|
||||
|
||||
size = c.page->data[0] * 256 + c.page->data[1];
|
||||
m = d->mdata;
|
||||
page = c.page->data + 8;
|
||||
|
||||
/* ts A61225 :
|
||||
@ -326,18 +347,28 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
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".
|
||||
*/
|
||||
/* ts A90603 :
|
||||
SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
|
||||
defines Page Length as (n-1).
|
||||
*/
|
||||
page_length = page[1];
|
||||
old_alloc_len = *alloc_len;
|
||||
*alloc_len = page_length + 8;
|
||||
*alloc_len = page_length + 10;
|
||||
if (flag & 1)
|
||||
return !was_error;
|
||||
if (page_length + 8 > old_alloc_len)
|
||||
page_length = old_alloc_len - 8;
|
||||
if (page_length < 22)
|
||||
return 0;
|
||||
if (page_length + 10 > old_alloc_len)
|
||||
page_length = old_alloc_len - 10;
|
||||
|
||||
m->valid = 0;
|
||||
burn_mdata_free_subs(m);
|
||||
/* ts A90602 : 20 asserts page[21]. (see SPC-1 8.3.3) */
|
||||
if (page_length < 20) {
|
||||
m->valid = -1;
|
||||
sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
|
||||
d->devname, page_length);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
|
||||
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m->buffer_size = page[12] * 256 + page[13];
|
||||
m->dvdram_read = page[2] & 32;
|
||||
@ -368,12 +399,13 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
m->min_end_lba = 0x7fffffff;
|
||||
m->max_end_lba = 0;
|
||||
|
||||
m->valid = 1;
|
||||
if (!was_error)
|
||||
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 ? */
|
||||
if (page_length < 30) /* no write speed descriptors ? */
|
||||
goto try_mmc_get_performance;
|
||||
|
||||
m->cur_write_speed = page[28] * 256 + page[29];
|
||||
@ -397,12 +429,12 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
}
|
||||
|
||||
for (i = 0; i < num_write_speeds; i++) {
|
||||
speed = page[32 + 4*i + 2] * 256 + page[32 + 4*i + 3];
|
||||
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);
|
||||
i, speed, page[32 + 4 * i + 1] & 7);
|
||||
|
||||
/* ts A61226 */
|
||||
ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
|
||||
@ -415,7 +447,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
strcpy(sd->profile_name,
|
||||
d->current_profile_text);
|
||||
}
|
||||
sd->wrc = (( page[32 + 4*i +1] & 7 ) == 1 );
|
||||
sd->wrc = (( page[32 + 4 * i + 1] & 7 ) == 1 );
|
||||
sd->write_speed = speed;
|
||||
}
|
||||
|
||||
@ -431,19 +463,31 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||
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,
|
||||
if (m->cdrw_write || page_length >= 32) {
|
||||
/* ts A90823:
|
||||
One has to avoid U3 enhanced memory sticks here. On my
|
||||
SuSE 10.2 a SanDisk Cruzer 4GB stalls at the second occasion
|
||||
of ACh GET PERFORMANCE. (The first one is obviously called
|
||||
by the OS at plug time.)
|
||||
This pseudo drive returns no write capabilities and a page
|
||||
length of 28. MMC-3 describes page length 32. Regrettably
|
||||
MMC-2 prescribes a page length of 26. Here i have to trust
|
||||
m->cdrw_write to reliably indicate any MMC-2 burner.
|
||||
*/
|
||||
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->min_write_speed, m->max_write_speed);
|
||||
}
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
void spc_sense_caps(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len, start_len = 22, ret;
|
||||
int alloc_len, start_len = 30, ret;
|
||||
|
||||
if (mmc_function_spy(d, "sense_caps") <= 0)
|
||||
return;
|
||||
@ -566,17 +610,21 @@ void spc_sense_write_params(struct burn_drive *d)
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
|
||||
size = c.page->data[0] * 256 + c.page->data[1];
|
||||
/* ts A71128 : do not interpret reply if error */
|
||||
m = d->mdata;
|
||||
page = c.page->data + 8;
|
||||
burn_print(1, "write page length 0x%x\n", page[1]);
|
||||
m->write_page_length = page[1];
|
||||
m->write_page_valid = 1;
|
||||
if (!c.error) {
|
||||
size = c.page->data[0] * 256 + c.page->data[1];
|
||||
page = c.page->data + 8;
|
||||
burn_print(1, "write page length 0x%x\n", page[1]);
|
||||
m->write_page_length = page[1];
|
||||
m->write_page_valid = 1;
|
||||
} else
|
||||
m->write_page_valid = 0;
|
||||
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->current_profile == 0x12 || d->current_profile == 0x43)
|
||||
d->read_format_capacities(d, -1);
|
||||
else if (d->status == BURN_DISC_BLANK ||
|
||||
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
|
||||
@ -841,7 +889,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
||||
d->mdata = calloc(1, sizeof(struct scsi_mode_data));
|
||||
|
||||
/* ts A61007 : obsolete Assert in drive_getcaps() */
|
||||
if(d->idata == NULL || d->mdata == NULL) {
|
||||
if (d->idata == NULL || d->mdata == NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Could not allocate new drive object", 0, 0);
|
||||
@ -850,7 +898,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
||||
d->idata->valid = 0;
|
||||
d->mdata->valid = 0;
|
||||
d->mdata->speed_descriptors = NULL;
|
||||
if(!(flag & 1)) {
|
||||
if (!(flag & 1)) {
|
||||
ret = spc_setup_drive(d);
|
||||
if (ret<=0)
|
||||
return ret;
|
||||
@ -865,11 +913,14 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
||||
}
|
||||
|
||||
|
||||
/* ts A61122 */
|
||||
/* ts A61122 - A80829 */
|
||||
enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
||||
int senselen, char msg[161],
|
||||
int senselen, char msg_data[161],
|
||||
int *key, int *asc, int *ascq)
|
||||
{
|
||||
char *msg;
|
||||
|
||||
msg= msg_data;
|
||||
*key= *asc= *ascq= -1;
|
||||
|
||||
if (senselen<=0 || senselen>2)
|
||||
@ -879,50 +930,270 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
||||
if (senselen<=0 || senselen>13)
|
||||
*ascq = sense[13];
|
||||
|
||||
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
|
||||
msg= msg + strlen(msg);
|
||||
|
||||
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
|
||||
*key, *asc, *ascq, d->idata->vendor, d->idata->product);
|
||||
|
||||
switch (*asc) {
|
||||
case 0:
|
||||
sprintf(msg, "(no error reported by SCSI transaction)");
|
||||
case 0x00:
|
||||
sprintf(msg, "(No error reported by SCSI transaction)");
|
||||
return RETRY;
|
||||
|
||||
case 2:
|
||||
sprintf(msg, "not ready");
|
||||
case 0x02:
|
||||
sprintf(msg, "Not ready");
|
||||
return RETRY;
|
||||
case 4:
|
||||
case 0x04:
|
||||
sprintf(msg,
|
||||
"logical unit is in the process of becoming ready");
|
||||
"Logical unit is in the process of becoming ready");
|
||||
return RETRY;
|
||||
case 0x08:
|
||||
if (*key != 4)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Logical unit communication failure");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Logical unit communication timeout");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Logical unit communication parity error");
|
||||
else if (*ascq == 3)
|
||||
sprintf(msg, "Logical unit communication crc error");
|
||||
return RETRY;
|
||||
case 0x09:
|
||||
if (*key != 4)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Track following error");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Tracking servo failure");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Focus servo failure");
|
||||
else if (*ascq == 3)
|
||||
sprintf(msg, "Spindle servo failure");
|
||||
else if (*ascq == 4)
|
||||
sprintf(msg, "Head select fault");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x0C:
|
||||
if (*key == 2 && *ascq == 7)
|
||||
sprintf(msg, "Write error, recovery needed");
|
||||
else if (*key == 2 && *ascq == 0x0f)
|
||||
sprintf(msg, "Defects in error window");
|
||||
else if (*key == 3 && *ascq == 2)
|
||||
sprintf(msg, "Write error, auto reallocation failed");
|
||||
else if (*key == 3 && *ascq == 9)
|
||||
sprintf(msg, "Write error, loss of streaming");
|
||||
else if (*key == 3)
|
||||
sprintf(msg, "Write error");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x11:
|
||||
if (*key != 3)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Unrecovered read error");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Read retries exhausted");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Error too long to correct");
|
||||
else if (*ascq == 5)
|
||||
sprintf(msg, "L-EC uncorrectable error");
|
||||
else if (*ascq == 6)
|
||||
sprintf(msg, "CIRC uncorrectable error");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x15:
|
||||
if (*key != 3 && *key != 4)
|
||||
break;
|
||||
sprintf(msg, "Random positioning error");
|
||||
return FAIL;
|
||||
case 0x1a:
|
||||
if (*key != 5)
|
||||
break;
|
||||
sprintf(msg, "Parameter list length error");
|
||||
return FAIL;
|
||||
case 0x1b:
|
||||
if (*key != 4)
|
||||
break;
|
||||
sprintf(msg, "Synchronous data transfer error");
|
||||
return FAIL;
|
||||
case 0x20:
|
||||
if (*key == 5)
|
||||
sprintf(msg, "bad opcode");
|
||||
if (*key != 5)
|
||||
break;
|
||||
sprintf(msg, "Invalid command operation code");
|
||||
return FAIL;
|
||||
case 0x21:
|
||||
sprintf(msg, "invalid address");
|
||||
if (*key != 5)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Lba out of range");
|
||||
else if (*ascq == 3)
|
||||
sprintf(msg, "Invalid write crossing layer jump");
|
||||
else
|
||||
sprintf(msg, "Invalid address");
|
||||
return FAIL;
|
||||
case 0x24:
|
||||
if (*key == 5)
|
||||
sprintf(msg, "invalid field in cdb");
|
||||
else
|
||||
if (*key != 5)
|
||||
break;
|
||||
sprintf(msg, "Invalid field in cdb");
|
||||
return FAIL;
|
||||
case 0x26:
|
||||
if (*key == 5 )
|
||||
sprintf(msg, "invalid field in parameter list" );
|
||||
if (*key != 5)
|
||||
break;
|
||||
if (*ascq == 1)
|
||||
sprintf(msg, "Parameter not supported");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Parameter value invalid");
|
||||
else
|
||||
sprintf(msg, "Invalid field in parameter list");
|
||||
return FAIL;
|
||||
case 0x27:
|
||||
if (*key != 7)
|
||||
break;
|
||||
sprintf(msg, "Write protected");
|
||||
return FAIL;
|
||||
case 0x28:
|
||||
if (*key == 6)
|
||||
if (*key != 6)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Medium may have changed");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Format layer may have changed");
|
||||
else
|
||||
break;
|
||||
return RETRY;
|
||||
case 0x29:
|
||||
if (*key != 6)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg,
|
||||
"Power on, reset, or bus device reset occured");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Power on occured");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Bus reset occured");
|
||||
else if (*ascq == 3)
|
||||
sprintf(msg, "Bus device reset function occured");
|
||||
else if (*ascq == 4)
|
||||
sprintf(msg, "Device internal reset");
|
||||
else
|
||||
break;
|
||||
return RETRY;
|
||||
case 0x2c:
|
||||
if (*key != 5)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Command sequence error");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x2e:
|
||||
if (*key != 6)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg,
|
||||
"Insufficient time for operation");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x30:
|
||||
if (*key != 2 && *key != 5)
|
||||
break;
|
||||
if (*ascq == 1)
|
||||
sprintf(msg, "Cannot read medium, unknown format");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg,
|
||||
"Cannot read medium, incompatible format");
|
||||
else if (*ascq == 4)
|
||||
sprintf(msg, "Cannot write medium, unknown format");
|
||||
else if (*ascq == 5)
|
||||
sprintf(msg,
|
||||
"Cannot write medium, incompatible format");
|
||||
else if (*ascq == 6)
|
||||
sprintf(msg,
|
||||
"Cannot format medium, incompatible medium");
|
||||
else if (*ascq == 7)
|
||||
sprintf(msg, "Cleaning failure");
|
||||
else
|
||||
sprintf(msg, "Incompatible medium installed");
|
||||
return FAIL;
|
||||
case 0x31:
|
||||
if (*key != 3)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Medium unformatted or format corrupted");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Format command failed");
|
||||
return FAIL;
|
||||
case 0x3A:
|
||||
sprintf(msg, "Medium not present");
|
||||
if (*key != 2)
|
||||
break;
|
||||
if (*ascq == 1)
|
||||
sprintf(msg, "Medium not present, tray closed");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Medium not present, tray open");
|
||||
else if (*ascq == 3)
|
||||
sprintf(msg, "Medium not present, loadable");
|
||||
else
|
||||
sprintf(msg, "Medium not present");
|
||||
d->status = BURN_DISC_EMPTY;
|
||||
return FAIL;
|
||||
case 0x63:
|
||||
if (*key != 5)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg,
|
||||
"End of user area encountered on this track");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Packet does not fit in available space");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x64:
|
||||
if (*key != 5)
|
||||
break;
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Illegal mode for this track");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Invalid packet size");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x72:
|
||||
if (*key == 3)
|
||||
sprintf(msg, "Session fixation error");
|
||||
else if (*key == 5 && *ascq == 3)
|
||||
sprintf(msg,
|
||||
"Session fixation error, incomplete track in session");
|
||||
else if (*key == 5 && *ascq == 4)
|
||||
sprintf(msg,
|
||||
"Empty or partially written reserved track");
|
||||
else if (*key == 5 && *ascq == 5)
|
||||
sprintf(msg,
|
||||
"No more track reservations allowed");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
case 0x73:
|
||||
if (*key == 3 && *ascq == 0)
|
||||
sprintf(msg, "CD control error");
|
||||
else if (*key == 3 && *ascq == 2)
|
||||
sprintf(msg, "Power calibration area is full");
|
||||
else if (*key == 3 && *ascq == 3)
|
||||
sprintf(msg, "Power calibration area error");
|
||||
else if (*key == 3 && *ascq == 4)
|
||||
sprintf(msg, "Program memory area update failure");
|
||||
else if (*key == 3 && *ascq == 5)
|
||||
sprintf(msg, "Program memory area is full");
|
||||
else
|
||||
break;
|
||||
return FAIL;
|
||||
}
|
||||
sprintf(msg,
|
||||
sprintf(msg_data,
|
||||
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
|
||||
*key, *asc, *ascq);
|
||||
return FAIL;
|
||||
@ -947,6 +1218,68 @@ enum response scsi_error(struct burn_drive *d, unsigned char *sense,
|
||||
}
|
||||
|
||||
|
||||
static char *scsi_command_name(unsigned int c, int flag)
|
||||
{
|
||||
switch (c) {
|
||||
case 0x00:
|
||||
return "TEST UNIT READY";
|
||||
case 0x03:
|
||||
return "REQUEST SENSE";
|
||||
case 0x04:
|
||||
return "FORMAT UNIT";
|
||||
case 0x1b:
|
||||
return "START/STOP UNIT";
|
||||
case 0x1e:
|
||||
return "PREVENT/ALLOW MEDIA REMOVAL";
|
||||
case 0x23:
|
||||
return "READ FORMAT CAPACITIES";
|
||||
case 0x28:
|
||||
return "READ(10)";
|
||||
case 0x2a:
|
||||
return "WRITE(10)";
|
||||
case 0x35:
|
||||
return "SYNCHRONIZE CACHE";
|
||||
case 0x43:
|
||||
return "READ TOC/PMA/ATIP";
|
||||
case 0x46:
|
||||
return "GET CONFIGURATION";
|
||||
case 0x4a:
|
||||
return "GET EVENT STATUS NOTIFICATION";
|
||||
case 0x51:
|
||||
return "READ DISC INFORMATION";
|
||||
case 0x52:
|
||||
return "READ TRACK INFORMATION";
|
||||
case 0x53:
|
||||
return "RESERVE TRACK";
|
||||
case 0x54:
|
||||
return "SEND OPC INFORMATION";
|
||||
case 0x55:
|
||||
return "MODE SELECT";
|
||||
case 0x5a:
|
||||
return "SEND OPC INFORMATION";
|
||||
case 0x5b:
|
||||
return "CLOSE TRACK/SESSION";
|
||||
case 0x5c:
|
||||
return "READ BUFFER CAPACITY";
|
||||
case 0x5d:
|
||||
return "SEND CUE SHEET";
|
||||
case 0xa1:
|
||||
return "BLANK";
|
||||
case 0xaa:
|
||||
return "WRITE(12)";
|
||||
case 0xac:
|
||||
return "GET PERFORMANCE";
|
||||
case 0xb6:
|
||||
return "SET STREAMING";
|
||||
case 0xbb:
|
||||
return "SET CD SPEED";
|
||||
case 0xbe:
|
||||
return "READ CD";
|
||||
}
|
||||
return "(NOT IN COMMAND LIST)";
|
||||
}
|
||||
|
||||
|
||||
/* ts A61030 - A61115 */
|
||||
/* @param flag bit0=do report conditions which are considered not an error */
|
||||
int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||
@ -958,12 +1291,9 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||
if (d->silent_on_scsi_error)
|
||||
return 1;
|
||||
|
||||
strcpy(scsi_msg, " \"");
|
||||
scsi_error_msg(d, sense, senselen, scsi_msg + strlen(scsi_msg),
|
||||
&key, &asc, &ascq);
|
||||
strcat(scsi_msg, "\"");
|
||||
scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq);
|
||||
|
||||
if(!(flag & 1)) {
|
||||
if (!(flag & 1)) {
|
||||
/* SPC : TEST UNIT READY command */
|
||||
if (c->opcode[0] == 0)
|
||||
return 1;
|
||||
@ -974,7 +1304,11 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf(msg,"SCSI error condition on command %2.2Xh :", c->opcode[0]);
|
||||
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
|
||||
c->opcode[0],
|
||||
scsi_command_name((unsigned int) c->opcode[0], 0));
|
||||
|
||||
#ifdef NIX
|
||||
if (key>=0)
|
||||
sprintf(msg+strlen(msg), " key=%Xh", key);
|
||||
if (asc>=0)
|
||||
@ -988,6 +1322,13 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
scsi_msg,0,0);
|
||||
#else
|
||||
strcat(msg, scsi_msg);
|
||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
||||
|
||||
#endif /* NIX */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -104,6 +104,30 @@ int burn_disc_add_session(struct burn_disc *d, struct burn_session *s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A81202: this function was in the API but not implemented.
|
||||
*/
|
||||
int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s)
|
||||
{
|
||||
int i, skip = 0;
|
||||
|
||||
if (d->session == NULL)
|
||||
return 0;
|
||||
for (i = 0; i < d->sessions; i++) {
|
||||
if (s == d->session[i]) {
|
||||
skip++;
|
||||
continue;
|
||||
}
|
||||
d->session[i - skip] = d->session[i];
|
||||
}
|
||||
if (!skip)
|
||||
return 0;
|
||||
burn_session_free(s);
|
||||
d->sessions--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct burn_track *burn_track_create(void)
|
||||
{
|
||||
struct burn_track *t;
|
||||
@ -330,11 +354,19 @@ 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;
|
||||
off_t size = 0;
|
||||
int sectors, seclen;
|
||||
|
||||
seclen = burn_sector_length(t->mode);
|
||||
size = t->offset + t->source->get_size(t->source) + t->tail;
|
||||
if (t->source != NULL) /* ts A80808 : mending sigsegv */
|
||||
size = t->offset + t->source->get_size(t->source) + t->tail;
|
||||
else if(t->entry != NULL) {
|
||||
/* ts A80808 : all burn_toc_entry of track starts should now
|
||||
have (extensions_valid & 1), even those from CD.
|
||||
*/
|
||||
if (t->entry->extensions_valid & 1)
|
||||
size = ((off_t) t->entry->track_blocks) * (off_t) 2048;
|
||||
}
|
||||
sectors = size / seclen;
|
||||
if (size % seclen)
|
||||
sectors++;
|
||||
@ -468,6 +500,7 @@ int burn_session_get_sectors(struct burn_session *s)
|
||||
return sectors;
|
||||
}
|
||||
|
||||
|
||||
int burn_disc_get_sectors(struct burn_disc *d)
|
||||
{
|
||||
int sectors = 0, i;
|
||||
@ -515,3 +548,84 @@ int burn_session_get_hidefirst(struct burn_session *session)
|
||||
{
|
||||
return session->hidefirst;
|
||||
}
|
||||
|
||||
|
||||
/* ts A80808 : Enhance CD toc to DVD toc */
|
||||
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag)
|
||||
{
|
||||
int sidx= 0, tidx= 0;
|
||||
struct burn_toc_entry *entry, *prev_entry= NULL;
|
||||
/* ts A81126 : ticket 146 : There was a SIGSEGV in here */
|
||||
char msg_data[321], *msg;
|
||||
|
||||
strcpy(msg_data,
|
||||
"Damaged CD table-of-content detected and truncated.");
|
||||
strcat(msg_data, " In burn_disc_cd_toc_extensions: ");
|
||||
msg = msg_data + strlen(msg_data);
|
||||
if (d->session == NULL) {
|
||||
strcpy(msg, "d->session == NULL");
|
||||
goto failure;
|
||||
}
|
||||
for (sidx = 0; sidx < d->sessions; sidx++) {
|
||||
if (d->session[sidx] == NULL) {
|
||||
sprintf(msg, "d->session[%d of %d] == NULL",
|
||||
sidx, d->sessions);
|
||||
goto failure;
|
||||
}
|
||||
if (d->session[sidx]->track == NULL) {
|
||||
sprintf(msg, "d->session[%d of %d]->track == NULL",
|
||||
sidx, d->sessions);
|
||||
goto failure;
|
||||
}
|
||||
if (d->session[sidx]->leadout_entry == NULL) {
|
||||
sprintf(msg,
|
||||
" Session %d of %d: Leadout entry missing.",
|
||||
sidx, d->sessions);
|
||||
goto failure;
|
||||
}
|
||||
for (tidx = 0; tidx < d->session[sidx]->tracks + 1; tidx++) {
|
||||
if (tidx < d->session[sidx]->tracks) {
|
||||
if (d->session[sidx]->track[tidx] == NULL) {
|
||||
sprintf(msg,
|
||||
"d->session[%d of %d]->track[%d of %d] == NULL",
|
||||
sidx, d->sessions, tidx, d->session[sidx]->tracks);
|
||||
goto failure;
|
||||
}
|
||||
entry = d->session[sidx]->track[tidx]->entry;
|
||||
if (entry == NULL) {
|
||||
sprintf(msg,
|
||||
"session %d of %d, track %d of %d, entry == NULL",
|
||||
sidx, d->sessions, tidx,
|
||||
d->session[sidx]->tracks);
|
||||
goto failure;
|
||||
}
|
||||
} else
|
||||
entry = d->session[sidx]->leadout_entry;
|
||||
entry->session_msb = 0;
|
||||
entry->point_msb = 0;
|
||||
entry->start_lba = burn_msf_to_lba(entry->pmin,
|
||||
entry->psec, entry->pframe);
|
||||
if (tidx > 0) {
|
||||
prev_entry->track_blocks =
|
||||
entry->start_lba
|
||||
- prev_entry->start_lba;
|
||||
prev_entry->extensions_valid |= 1;
|
||||
}
|
||||
if (tidx == d->session[sidx]->tracks) {
|
||||
entry->session_msb = 0;
|
||||
entry->point_msb = 0;
|
||||
entry->track_blocks = 0;
|
||||
entry->extensions_valid |= 1;
|
||||
}
|
||||
prev_entry = entry;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
failure:
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015f,
|
||||
LIBDAX_MSGS_SEV_MISHAP, LIBDAX_MSGS_PRIO_HIGH, msg_data, 0, 0);
|
||||
d->sessions= sidx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,4 +109,8 @@ int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag);
|
||||
off_t burn_track_get_default_size(struct burn_track *t);
|
||||
|
||||
|
||||
/* ts A80808 : Enhance CD toc to DVD toc */
|
||||
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
|
||||
|
||||
|
||||
#endif /* BURN__STRUCTURE_H */
|
||||
|
@ -161,6 +161,11 @@ struct burn_drive
|
||||
char current_profile_text[80];
|
||||
int current_is_cd_profile;
|
||||
int current_is_supported_profile;
|
||||
/* ts A90603 */
|
||||
int current_is_guessed_profile;
|
||||
/* ts A90815 */
|
||||
unsigned char all_profiles[256];
|
||||
int num_profiles;
|
||||
|
||||
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
||||
Quite internal. Regard as opaque :)
|
||||
@ -171,6 +176,19 @@ struct burn_drive
|
||||
/* Link Size item number 0 from feature 0021h descriptor */
|
||||
int current_feat21h_link_size;
|
||||
|
||||
/* Flags from feature 0023h for formatting BD mmc5r03c.pdf 5.3.13
|
||||
Byte 4 BD-RE:
|
||||
bit0= Cert format 30h sub-type 10b
|
||||
bit1= QCert format 30h sub-type 11b
|
||||
bit2= Expand format 01h
|
||||
bit3= RENoSA format 31h
|
||||
Byte 8 BD-R:
|
||||
bit0= RRM format 32h sub-type 10b
|
||||
*/
|
||||
int current_feat23h_byte4;
|
||||
int current_feat23h_byte8;
|
||||
|
||||
|
||||
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
|
||||
bit1= DVD-RW supported
|
||||
bit2= Test Write available
|
||||
@ -187,6 +205,16 @@ struct burn_drive
|
||||
synchronize chache has happened yet */
|
||||
int needs_sync_cache;
|
||||
|
||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||
rather than WRITE10. Speeds up DVD-RAM. Might help
|
||||
with BD-RE */
|
||||
int do_stream_recording;
|
||||
|
||||
/* ts A90227 : the LBA where stream recording shall start.
|
||||
Writing to lower LBA will be done without streaming.
|
||||
*/
|
||||
int stream_recording_start;
|
||||
|
||||
/* ts A61218 from 51h READ DISC INFORMATION */
|
||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||
|
||||
@ -218,6 +246,9 @@ struct burn_drive
|
||||
|
||||
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
||||
int complete_sessions;
|
||||
/* ts A90107 */
|
||||
int state_of_last_session;
|
||||
|
||||
/* ts A70129 :
|
||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||
int last_track_no;
|
||||
@ -230,6 +261,9 @@ struct burn_drive
|
||||
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
||||
int media_lba_limit;
|
||||
|
||||
/* ts A81210 : Upper limit of readable data size,
|
||||
0x7fffffff = unknown */
|
||||
int media_read_capacity;
|
||||
|
||||
int toc_temp;
|
||||
struct burn_disc *disc; /* disc structure */
|
||||
@ -283,6 +317,11 @@ struct burn_drive
|
||||
void (*eject) (struct burn_drive *);
|
||||
void (*load) (struct burn_drive *);
|
||||
int (*start_unit) (struct burn_drive *);
|
||||
|
||||
/* ts A90824 : Calming down noisy drives */
|
||||
int (*stop_unit) (struct burn_drive *);
|
||||
int is_stopped;
|
||||
|
||||
void (*read_disc_info) (struct burn_drive *);
|
||||
void (*read_sectors) (struct burn_drive *,
|
||||
int start,
|
||||
@ -348,4 +387,9 @@ struct burn_drive
|
||||
|
||||
/* end of generic 'drive' data structures */
|
||||
|
||||
/* ts A80422 : centralizing this setting for debugging purposes
|
||||
*/
|
||||
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value);
|
||||
|
||||
|
||||
#endif /* __TRANSPORT */
|
||||
|
@ -4,7 +4,11 @@
|
||||
/* #include <a ssert.h> */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../version.h"
|
||||
|
||||
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
|
||||
#include "v ersion.h"
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
#include "libburn.h"
|
||||
|
||||
@ -47,7 +51,8 @@ char *burn_strndup(char *s, int n)
|
||||
|
||||
void burn_version(int *major, int *minor, int *micro)
|
||||
{
|
||||
*major = BURN_MAJOR_VERSION;
|
||||
*minor = BURN_MINOR_VERSION;
|
||||
*micro = BURN_MICRO_VERSION;
|
||||
/* ts A80408 : switched from configure.ac versioning to libburn.h versioning */
|
||||
*major = burn_header_version_major;
|
||||
*minor = burn_header_version_minor;
|
||||
*micro = burn_header_version_micro;
|
||||
}
|
||||
|
374
libburn/write.c
374
libburn/write.c
@ -43,11 +43,30 @@
|
||||
#include "write.h"
|
||||
#include "options.h"
|
||||
#include "structure.h"
|
||||
#include "source.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
|
||||
/* The maximum output size to be used with CD media. This is also curbed
|
||||
by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
|
||||
*/
|
||||
#define Libburn_cd_obS (32 * 1024)
|
||||
|
||||
/* The size to be used with DVD media.
|
||||
*/
|
||||
#define Libburn_dvd_obS (32 * 1024)
|
||||
|
||||
/* The size to be used with BD-RE media in normal, not streamed mode.
|
||||
*/
|
||||
#define Libburn_bd_re_obS (32 * 1024)
|
||||
|
||||
/* The size to be used with BD-RE media in streamed mode.
|
||||
*/
|
||||
#define Libburn_bd_re_streamed_obS (64 * 1024)
|
||||
|
||||
|
||||
static int type_to_ctrl(int mode)
|
||||
{
|
||||
int ctrl = 0;
|
||||
@ -836,6 +855,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
/* ts A61103 */
|
||||
ret = 1;
|
||||
ex:;
|
||||
if (d->cancel)
|
||||
burn_source_cancel(t->source);
|
||||
if (o->write_type == BURN_WRITE_TAO) {
|
||||
|
||||
/* ts A71002 */
|
||||
@ -964,8 +985,9 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
||||
if (d->status == BURN_DISC_UNSUITABLE)
|
||||
goto unsuitable_profile;
|
||||
if (d->drive_role == 2 ||
|
||||
d->current_profile == 0x1a || d->current_profile == 0x12) {
|
||||
/* DVD+RW , DVD-RAM , emulated drive on stdio file */
|
||||
d->current_profile == 0x1a || d->current_profile == 0x12 ||
|
||||
d->current_profile == 0x43) {
|
||||
/* DVD+RW , DVD-RAM , BD-RE, emulated drive on stdio file */
|
||||
if (o->start_byte >= 0 && (o->start_byte % 2048))
|
||||
strcat(reasons,
|
||||
"write start address not properly aligned to 2048, ");
|
||||
@ -983,8 +1005,10 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
||||
} else if (d->drive_role == 3 ||
|
||||
d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||
d->current_profile == 0x15 ||
|
||||
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
|
||||
/* DVD-R* Sequential , DVD+R[/DL] , sequential stdio "drive" */
|
||||
d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
||||
d->current_profile == 0x41) {
|
||||
/* DVD-R* Sequential , DVD+R[/DL] , BD-R,
|
||||
sequential stdio "drive" */
|
||||
if (o->start_byte >= 0)
|
||||
strcat(reasons, "write start address not supported, ");
|
||||
} else {
|
||||
@ -1084,6 +1108,10 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
||||
if (o->write_type == BURN_WRITE_SAO &&
|
||||
! burn_track_is_open_ended(s->track[tnum])) {
|
||||
/* Round track size up to 32 KiB and reserve track */
|
||||
|
||||
/* ts A81208 */
|
||||
/* >>> ??? round to 64 KiB for BD-R ? (It is not mandatory) */
|
||||
|
||||
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
||||
* (off_t) 2048;
|
||||
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
||||
@ -1131,19 +1159,29 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
|
||||
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
char msg[80];
|
||||
|
||||
sprintf(msg, "Finalizing %s ...",
|
||||
d->current_profile_text);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
"Finalizing DVD+R ...", 0, 0);
|
||||
msg, 0, 0);
|
||||
|
||||
/* CLOSE SESSION, 101b, Finalize with minimal radius */
|
||||
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
|
||||
if(d->current_profile == 0x41) { /* BD-R */
|
||||
/* CLOSE SESSION, 110b, Finalize Disc */
|
||||
d->close_track_session(d, 3, 0); /* (3<<1)|0 = 6 */
|
||||
} else {
|
||||
/* CLOSE SESSION, 101b, Finalize with minimal radius */
|
||||
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
|
||||
}
|
||||
|
||||
sprintf(msg, "... finalizing %s done ",
|
||||
d->current_profile_text);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
"... finalizing DVD+R done ", 0, 0);
|
||||
msg, 0, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1178,7 +1216,7 @@ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 - A70129 */
|
||||
/* ts A61218 - A81208 */
|
||||
int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
struct burn_session *s, int tnum, int is_last_track)
|
||||
{
|
||||
@ -1202,6 +1240,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
} else if (d->current_profile == 0x41) {
|
||||
/* BD-R SRM */
|
||||
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
sectors = burn_track_get_sectors(t);
|
||||
@ -1270,9 +1313,17 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
is_last_track);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
} else if (d->current_profile == 0x41) {
|
||||
/* BD-R SRM */
|
||||
ret = burn_disc_close_track_dvd_plus_r(o, s, tnum,
|
||||
is_last_track);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
ret = 1;
|
||||
ex:;
|
||||
if (d->cancel)
|
||||
burn_source_cancel(t->source);
|
||||
if (!is_flushed)
|
||||
d->sync_cache(d); /* burn_write_flush() was not called */
|
||||
return ret;
|
||||
@ -1348,10 +1399,70 @@ int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o,
|
||||
int burn_dvd_write_session(struct burn_write_opts *o,
|
||||
struct burn_session *s, int is_last_session)
|
||||
{
|
||||
int i,ret;
|
||||
int i, ret, multi_mem;
|
||||
struct burn_drive *d = o->drive;
|
||||
|
||||
/* >>> open_session ? */
|
||||
/* ts A90108 */
|
||||
if (d->current_profile == 0x41 && d->status == BURN_DISC_APPENDABLE &&
|
||||
d->state_of_last_session == 1) {
|
||||
/* last session on BD-R is still open */;
|
||||
|
||||
/* BR-R were not closed by libburn-0.6.0.pl00 if o->multi==0.
|
||||
This leads to an unreadable, but recoverable) media state.
|
||||
Technically they are appendable although the last session
|
||||
is not readable.
|
||||
|
||||
By default the open session gets closed here before the new
|
||||
session is written. E.g. after writing a small dummy seesion
|
||||
number 2 one can read session 1 and write session 3 which
|
||||
points to data of session 1.
|
||||
|
||||
For the case that no media with 3 sessions is desired it is
|
||||
possible to activate the following coarse single-session
|
||||
closing code:
|
||||
No new session will be written but calling programs will
|
||||
report success. Quite misleading.
|
||||
Activate only if really needed by
|
||||
# define Libburn_bug_A90108_close_disC yes
|
||||
*/
|
||||
|
||||
|
||||
#ifdef Libburn_bug_A90108_close_disC
|
||||
|
||||
/* Close open session and media.
|
||||
That was the goal of the failed run which led to the
|
||||
unreadable (but recoverable) media state.
|
||||
|
||||
It is not easy to implement a general close function for
|
||||
all media types. Therefore this pseudo write code is under
|
||||
control of #ifdef.
|
||||
*/
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020171,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Closing BD-R with accidently open session",
|
||||
0, 0);
|
||||
d->close_track_session(d, 3, 0); /* CLOSE SESSION, 110b */
|
||||
d->state_of_last_session = 3; /* mark as complete session */
|
||||
d->status = BURN_DISC_FULL;
|
||||
sleep(3); /* The caller might need time to arrange itself */
|
||||
return 1;
|
||||
|
||||
#else /* Libburn_bug_A90108_close_disC */
|
||||
|
||||
/* This is the default mode.
|
||||
*/
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020170,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Closing open session before writing new one",
|
||||
0, 0);
|
||||
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
|
||||
d->state_of_last_session = 3; /* mark as complete session */
|
||||
|
||||
#endif /* ! Libburn_bug_A90108_close_disC */
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < s->tracks; i++) {
|
||||
ret = burn_dvd_write_track(o, s, i,
|
||||
@ -1362,11 +1473,15 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
||||
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||
d->current_profile == 0x15) {
|
||||
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
|
||||
multi_mem = o->multi;
|
||||
if (!is_last_session)
|
||||
o->multi = 1;
|
||||
ret = burn_disc_close_session_dvd_minus_r(o, s);
|
||||
o->multi = multi_mem;
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
} else if (d->current_profile == 0x12) {
|
||||
/* DVD-RAM */
|
||||
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
|
||||
/* DVD-RAM , BD-RE */
|
||||
/* ??? any finalization needed ? */;
|
||||
} else if (d->current_profile == 0x13) {
|
||||
/* DVD-RW restricted overwrite */
|
||||
@ -1384,6 +1499,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
||||
}
|
||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||
/* DVD+R , DVD+R/DL do each track as an own session */;
|
||||
} else if (d->current_profile == 0x41) {
|
||||
/* BD-R SRM do each track as an own session */;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1395,7 +1512,6 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
int ret;
|
||||
char msg[160];
|
||||
|
||||
if (d->bg_format_status==0 || d->bg_format_status==1) {
|
||||
d->busy = BURN_DRIVE_FORMATTING;
|
||||
@ -1406,16 +1522,6 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
d->needs_close_session = 1;
|
||||
}
|
||||
d->nwa = 0;
|
||||
if (o->start_byte >= 0) {
|
||||
d->nwa = o->start_byte / 2048;
|
||||
|
||||
sprintf(msg, "Write start address is %d * 2048", d->nwa);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020127,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
}
|
||||
|
||||
/* >>> perform OPC if needed */;
|
||||
|
||||
@ -1505,7 +1611,7 @@ int burn_disc_setup_dvd_plus_r(struct burn_write_opts *o,
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 - A70129 */
|
||||
/* ts A61218 - A70415 */
|
||||
int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
struct burn_disc *disc)
|
||||
{
|
||||
@ -1517,8 +1623,12 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
|
||||
d->needs_close_session = 0;
|
||||
|
||||
if (d->current_profile == 0x1a || d->current_profile == 0x12) {
|
||||
/* DVD+RW , DVD-RAM */
|
||||
/* buffer flush trigger for sector.c:get_sector() */
|
||||
o->obs = Libburn_dvd_obS;
|
||||
|
||||
if (d->current_profile == 0x1a || d->current_profile == 0x12 ||
|
||||
d->current_profile == 0x43) {
|
||||
/* DVD+RW , DVD-RAM , BD-RE */
|
||||
ret = 1;
|
||||
if (d->current_profile == 0x1a)
|
||||
ret = burn_disc_setup_dvd_plus_rw(o, disc);
|
||||
@ -1531,7 +1641,24 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
msg, 0, 0);
|
||||
goto early_failure;
|
||||
}
|
||||
d->nwa = 0;
|
||||
if (o->start_byte >= 0) {
|
||||
d->nwa = o->start_byte / 2048;
|
||||
sprintf(msg, "Write start address is %d * 2048",
|
||||
d->nwa);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020127,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
}
|
||||
o->obs_pad = 0; /* no filling-up of track's last 32k buffer */
|
||||
if (d->current_profile == 0x43) /* BD-RE */
|
||||
o->obs = Libburn_bd_re_obS;
|
||||
if (d->do_stream_recording) {
|
||||
o->obs_pad = 1;
|
||||
if (d->current_profile == 0x43) /* BD-RE */
|
||||
o->obs = Libburn_bd_re_streamed_obS;
|
||||
}
|
||||
|
||||
} else if (d->current_profile == 0x13) {
|
||||
/* DVD-RW Restricted Overwrite */
|
||||
@ -1577,8 +1704,12 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
/* ??? padding needed ??? cowardly doing it for now */
|
||||
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
||||
|
||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||
/* DVD+R , DVD+R/DL */
|
||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
||||
d->current_profile == 0x41) {
|
||||
/* DVD+R , DVD+R/DL , BD-R SRM */
|
||||
|
||||
/* >>> ts A81208 : with BD-R set o->obs to 64 kB ? */
|
||||
|
||||
t = disc->session[0]->track[0];
|
||||
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
|
||||
default_size = burn_track_get_default_size(t);
|
||||
@ -1593,8 +1724,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
}
|
||||
ret = burn_disc_setup_dvd_plus_r(o, disc);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg,
|
||||
"Write preparation setup failed for DVD+R");
|
||||
sprintf(msg, "Write preparation setup failed for %s",
|
||||
d->current_profile == 0x41 ? "BD-R" : "DVD+R");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020121,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
@ -1604,7 +1735,19 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
/* ??? padding needed ??? cowardly doing it for now */
|
||||
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
||||
}
|
||||
o->obs = 32*1024; /* buffer flush trigger for sector.c:get_sector() */
|
||||
|
||||
|
||||
/* <<< test only : Does this increase effective speed with USB ?
|
||||
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
|
||||
>>> next try is 128 kB
|
||||
o->obs = 128 * 1024;
|
||||
*/
|
||||
|
||||
|
||||
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
||||
d->current_profile, o->obs, o->obs_pad);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
|
||||
|
||||
for (i = 0; i < disc->sessions; i++) {
|
||||
/* update progress */
|
||||
@ -1693,7 +1836,11 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
|
||||
int count= 0, todo;
|
||||
|
||||
for(todo = bufsize; todo > 0; todo -= count) {
|
||||
count = source->read(source,
|
||||
if(source->read!=NULL)
|
||||
count = source->read(source,
|
||||
(unsigned char *) (buf + (bufsize - todo)), todo);
|
||||
else
|
||||
count = source->read_xt(source,
|
||||
(unsigned char *) (buf + (bufsize - todo)), todo);
|
||||
if (count <= 0)
|
||||
break;
|
||||
@ -1706,6 +1853,13 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
|
||||
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
|
||||
int flag)
|
||||
{
|
||||
if (d->cancel)
|
||||
return 0;
|
||||
/*
|
||||
fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
|
||||
fd, (unsigned long) buf, count);
|
||||
*/
|
||||
|
||||
if (write(fd, buf, count) != count) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020148,
|
||||
@ -1718,16 +1872,6 @@ int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
|
||||
}
|
||||
|
||||
|
||||
/* ts A70911
|
||||
If defined this makes stdio run on top of sector_data() rather than
|
||||
own stdio read and write functions. The MMC function pointers d->write()
|
||||
and d->sync_cache() get replaced by stdio substitutes.
|
||||
*/
|
||||
#define Libburn_stdio_track_by_sector_datA 1
|
||||
|
||||
|
||||
#ifdef Libburn_stdio_track_by_sector_datA
|
||||
|
||||
/* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() */
|
||||
int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
{
|
||||
@ -1849,9 +1993,6 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
|
||||
}
|
||||
|
||||
|
||||
#endif /* Libburn_stdio_track_by_sector_datA */
|
||||
|
||||
|
||||
/* ts A70904 */
|
||||
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
int tnum, int flag)
|
||||
@ -1860,14 +2001,9 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
struct burn_track *t = s->track[tnum];
|
||||
struct burn_drive *d = o->drive;
|
||||
char buf[16*2048];
|
||||
#ifdef Libburn_stdio_track_by_sector_datA
|
||||
int i, prev_sync_sector = 0;
|
||||
struct buffer *out = d->buffer;
|
||||
struct timeval prev_time;
|
||||
#else
|
||||
int eof_seen = 0;
|
||||
off_t t_size, w_count;
|
||||
#endif
|
||||
|
||||
bufsize = sizeof(buf);
|
||||
fd = d->stdio_fd;
|
||||
@ -1876,8 +2012,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
burn_disc_init_track_status(o, s, tnum, sectors);
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
#ifdef Libburn_stdio_track_by_sector_datA
|
||||
|
||||
/* attach stdio emulators for mmc_*() functions */
|
||||
if (o->simulate)
|
||||
d->write = burn_stdio_mmc_dummy_write;
|
||||
@ -1889,7 +2023,7 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
for (i = 0; open_ended || i < sectors; i++) {
|
||||
/* transact a (CD sized) sector */
|
||||
if (!sector_data(o, t, 0))
|
||||
return 0;
|
||||
{ret= 0; goto ex;}
|
||||
if (open_ended) {
|
||||
d->progress.sectors = sectors = d->progress.sector;
|
||||
if (burn_track_is_data_done(t))
|
||||
@ -1912,60 +2046,11 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
out->bytes = o->obs;
|
||||
}
|
||||
ret = burn_write_flush(o, t);
|
||||
|
||||
#else /* Libburn_stdio_track_by_sector_datA */
|
||||
|
||||
t_size = t->source->get_size(t->source);
|
||||
|
||||
/* >>> write t->offset zeros */;
|
||||
|
||||
for(w_count = 0; w_count < t_size || open_ended; w_count += ret) {
|
||||
|
||||
|
||||
if (t_size - w_count < bufsize && ! open_ended)
|
||||
|
||||
/* >>> what about final sector padding ? */
|
||||
|
||||
bufsize = t_size - w_count;
|
||||
if (eof_seen)
|
||||
ret = 0;
|
||||
else
|
||||
ret = burn_stdio_read_source(t->source, buf,
|
||||
bufsize, o, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == 0 && open_ended)
|
||||
break;
|
||||
if (ret < bufsize && !open_ended) {
|
||||
memset(buf + ret, 0, bufsize - ret);
|
||||
eof_seen = 1;
|
||||
ret = bufsize;
|
||||
}
|
||||
t->sourcecount += ret;
|
||||
if (!o->simulate)
|
||||
ret = burn_stdio_write(fd, buf, ret, d, 0);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
d->progress.sector = (w_count + (off_t) ret) / (off_t) 2048;
|
||||
if (open_ended)
|
||||
d->progress.sectors = d->progress.sector;
|
||||
t->writecount += ret;
|
||||
t->written_sectors = t->writecount / 2048;
|
||||
|
||||
/* Flush to physical device after each full MB */
|
||||
if (d->progress.sector - prev_sync_sector >= 512) {
|
||||
prev_sync_sector = d->progress.sector;
|
||||
if (!o->simulate)
|
||||
burn_stdio_sync_cache(fd, d, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* >>> write t->tail zeros */;
|
||||
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
ret= 1;
|
||||
ex:;
|
||||
if (d->cancel)
|
||||
burn_source_cancel(t->source);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -2023,9 +2108,9 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
{
|
||||
struct cue_sheet *sheet;
|
||||
struct burn_drive *d = o->drive;
|
||||
struct buffer buf;
|
||||
struct buffer *buffer_mem = o->drive->buffer;
|
||||
struct burn_track *lt, *t;
|
||||
int first = 1, i, ret, lba, nwa = 0;
|
||||
int first = 1, i, ret, lba, nwa = 0, multi_mem;
|
||||
off_t default_size;
|
||||
char msg[80];
|
||||
|
||||
@ -2036,8 +2121,40 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
/* ts A61224 */
|
||||
burn_disc_init_write_status(o, disc); /* must be done very early */
|
||||
|
||||
d->buffer = &buf;
|
||||
/* ts A80412 , A90227 */
|
||||
d->do_stream_recording = !!o->do_stream_recording;
|
||||
if (o->do_stream_recording >= 16)
|
||||
d->stream_recording_start = o->do_stream_recording;
|
||||
else
|
||||
d->stream_recording_start = 0;
|
||||
|
||||
d->buffer = calloc(sizeof(struct buffer), 1);
|
||||
if (d->buffer == NULL)
|
||||
goto fail_wo_sync;
|
||||
|
||||
|
||||
/* >>> ts A90321
|
||||
|
||||
memset(d->buffer, 0, sizeof(struct buffer));
|
||||
|
||||
fprintf(stderr, "libburn_DEBUG: d->buffer = %lX , size = %d\n",
|
||||
(unsigned long) d->buffer, (int) sizeof(struct buffer));
|
||||
|
||||
calloc() seems not to have the desired effect. valgrind warns:
|
||||
==18251== Syscall param write(buf) points to uninitialised byte(s)
|
||||
==18251== at 0x5071DEB: (within /lib64/libpthread-2.5.so)
|
||||
==18251== by 0x4723FA: burn_stdio_write (write.c:1850)
|
||||
==18251== by 0x4725DC: burn_stdio_mmc_write (write.c:1894)
|
||||
==18251== by 0x483B7A: get_sector (sector.c:229)
|
||||
==18251== by 0x484F11: sector_data (sector.c:639)
|
||||
==18251== by 0x4729FE: burn_stdio_write_track (write.c:2012)
|
||||
==18251== by 0x472CF4: burn_stdio_write_sync (write.c:2072)
|
||||
==18251== by 0x472E8D: burn_disc_write_sync (write.c:2125) <<< we are here
|
||||
==18251== by 0x460254: write_disc_worker_func (async.c:514)
|
||||
==18251== by 0x506B09D: start_thread (in /lib64/libpthread-2.5.so)
|
||||
==18251== by 0x55484CC: clone (in /lib64/libc-2.5.so)
|
||||
*/
|
||||
|
||||
d->rlba = -150;
|
||||
d->toc_temp = 9;
|
||||
|
||||
@ -2046,16 +2163,26 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
ret = burn_stdio_write_sync(o, disc);
|
||||
if (ret <= 0)
|
||||
goto fail_wo_sync;
|
||||
return;
|
||||
goto ex;
|
||||
}
|
||||
/* ts A61218 */
|
||||
if (! d->current_is_cd_profile) {
|
||||
ret = burn_dvd_write_sync(o, disc);
|
||||
if (ret <= 0)
|
||||
goto fail_wo_sync;
|
||||
return;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* ts A70521 : Linux 2.4 USB audio fails with 64 kiB */
|
||||
/* ts A80414 : might need 64 kiB for BD-RE streaming */
|
||||
/* buffer flush trigger for sector.c:get_sector() */
|
||||
o->obs = Libburn_cd_obS;
|
||||
|
||||
sprintf(msg, "cd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
||||
d->current_profile, o->obs, o->obs_pad);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
|
||||
|
||||
/* ts A70218 */
|
||||
if (o->write_type == BURN_WRITE_SAO) {
|
||||
for (i = 0 ; i < disc->session[0]->tracks; i++) {
|
||||
@ -2162,7 +2289,12 @@ return crap. so we send the command, then ignore the result.
|
||||
d->alba += 4500;
|
||||
}
|
||||
}
|
||||
if (!burn_write_session(o, disc->session[i]))
|
||||
multi_mem = o->multi;
|
||||
if(i < disc->sessions - 1)
|
||||
o->multi = 1;
|
||||
ret = burn_write_session(o, disc->session[i]);
|
||||
o->multi = multi_mem;
|
||||
if (!ret)
|
||||
goto fail;
|
||||
|
||||
lt = disc->session[i]->track[disc->session[i]->tracks - 1];
|
||||
@ -2206,7 +2338,7 @@ return crap. so we send the command, then ignore the result.
|
||||
|
||||
/* ts A61012 : This return was traditionally missing. I suspect this
|
||||
to have caused Cdrskin_eject() failures */
|
||||
return;
|
||||
goto ex;
|
||||
|
||||
fail:
|
||||
d->sync_cache(d);
|
||||
@ -2218,6 +2350,12 @@ fail_wo_sync:;
|
||||
"Burn run failed", 0, 0);
|
||||
d->cancel = 1;
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
ex:;
|
||||
d->do_stream_recording = 0;
|
||||
if (d->buffer != NULL)
|
||||
free((char *) d->buffer);
|
||||
d->buffer = buffer_mem;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ts A70811 : API function */
|
||||
@ -2226,7 +2364,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
||||
{
|
||||
int alignment = 0, start, upto, chunksize, err, fd = -1, ret;
|
||||
char msg[81], *rpt;
|
||||
struct buffer buf;
|
||||
struct buffer buf, *buffer_mem = d->buffer;
|
||||
|
||||
if (d->released) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
@ -2251,6 +2389,8 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
||||
alignment = 32 * 1024;
|
||||
if (d->current_profile == 0x1a) /* DVD+RW */
|
||||
alignment = 2 * 1024;
|
||||
if (d->current_profile == 0x43) /* BD-RE */
|
||||
alignment = 2 * 1024;
|
||||
if (alignment == 0) {
|
||||
sprintf(msg, "Write start address not supported");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
@ -2335,7 +2475,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
||||
|
||||
if(fd >= 0)
|
||||
close(fd);
|
||||
d->buffer = NULL;
|
||||
d->buffer = buffer_mem;
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
||||
/* Copyright (C) 2005 - 2007 Thomas Schmitt <scdbackup@gmx.net> */
|
||||
/* Copyright (C) 2005 - 2009 Thomas Schmitt <scdbackup@gmx.net> */
|
||||
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
|
||||
|
||||
|
||||
@ -8,8 +8,9 @@
|
||||
|
||||
libburner is a minimal demo application for the library libburn as provided
|
||||
on http://libburnia-project.org . It can list the available devices, can
|
||||
blank a CD-RW or DVD-RW, can format a DVD-RW, can burn to CD-R, CD-RW, DVD-R,
|
||||
DVD+R, DVD+RW, DVD-RAM or DVD-RW. Not supported yet: double layer media.
|
||||
blank a CD-RW or DVD-RW, can format DVD-RW and BD, can burn to CD-R,
|
||||
CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RW, DVD-RAM, BD-R, BD-RE.
|
||||
Not supported yet: DVD-R/DL.
|
||||
|
||||
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
|
||||
@ -28,8 +29,9 @@
|
||||
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
|
||||
or an unused BD to default size with spare blocks
|
||||
libburner_format()
|
||||
With the aquired drive you can burn to CD, DVD, BD
|
||||
libburner_payload()
|
||||
When everything is done, main() releases the drive and shuts down libburn:
|
||||
burn_drive_release();
|
||||
@ -104,7 +106,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)
|
||||
if (ret <= 0 || *driveno <= 0)
|
||||
return ret;
|
||||
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||
current_profile_name);
|
||||
@ -258,7 +260,8 @@ int libburner_aquire_by_driveno(int *driveno)
|
||||
}
|
||||
|
||||
|
||||
/** Makes a previously used CD-RW ready for thorough re-usal.
|
||||
/** Makes a previously used CD-RW or unformatted DVD-RW ready for thorough
|
||||
re-usal.
|
||||
|
||||
To our knowledge it is hardly possible to abort an ongoing blank operation
|
||||
because after start it is entirely handled by the drive.
|
||||
@ -313,26 +316,56 @@ 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.
|
||||
|
||||
/** Formats unformatted DVD-RW 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.
|
||||
|
||||
Formats unformatted BD-RE to default size. This will allocate some
|
||||
reserve space, test for bad blocks and make the media ready for writing.
|
||||
Expect a very long run time.
|
||||
|
||||
Formats unformatted blank BD-R to hold a default amount of spare blocks
|
||||
for eventual mishaps during writing. If BD-R get written without being
|
||||
formatted, then they get no such reserve and will burn at full speed.
|
||||
*/
|
||||
int libburner_format_row(struct burn_drive *drive)
|
||||
int libburner_format(struct burn_drive *drive)
|
||||
{
|
||||
struct burn_progress p;
|
||||
double percent = 1.0;
|
||||
int ret, status, num_formats, format_flag= 0;
|
||||
off_t size = 0;
|
||||
unsigned dummy;
|
||||
enum burn_disc_status disc_state;
|
||||
|
||||
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");
|
||||
} else if (current_profile == 0x41 || current_profile == 0x43) {
|
||||
disc_state = burn_disc_get_status(drive);
|
||||
if (disc_state != BURN_DISC_BLANK && current_profile == 0x41) {
|
||||
fprintf(stderr,
|
||||
"FATAL: BD-R is not blank. Cannot format.\n");
|
||||
return 0;
|
||||
}
|
||||
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
|
||||
&num_formats);
|
||||
if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) {
|
||||
fprintf(stderr,
|
||||
"IDLE: BD media is already formatted\n");
|
||||
return 2;
|
||||
}
|
||||
size = 0; /* does not really matter */
|
||||
format_flag = 3<<1; /* format to default size, no quick */
|
||||
} else if (current_profile == 0x14) { /* sequential DVD-RW */
|
||||
size = 128 * 1024 * 1024;
|
||||
format_flag = 1; /* write initial 128 MiB */
|
||||
} else {
|
||||
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Beginning to format media.\n");
|
||||
burn_disc_format(drive, (off_t) 0, 0);
|
||||
burn_disc_format(drive, size, format_flag);
|
||||
|
||||
sleep(1);
|
||||
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
||||
@ -344,9 +377,10 @@ int libburner_format_row(struct burn_drive *drive)
|
||||
}
|
||||
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||
current_profile_name);
|
||||
printf("Media type now: %4.4xh \"%s\"\n",
|
||||
current_profile, current_profile_name);
|
||||
if (current_profile != 0x13) {
|
||||
if (current_profile == 0x14 || current_profile == 0x13)
|
||||
printf("Media type now: %4.4xh \"%s\"\n",
|
||||
current_profile, current_profile_name);
|
||||
if (current_profile == 0x14) {
|
||||
fprintf(stderr,
|
||||
"FATAL: Failed to change media profile to desired value\n");
|
||||
return 0;
|
||||
@ -443,7 +477,8 @@ int libburner_payload(struct burn_drive *drive,
|
||||
/* Use the fifo object as data source for the track */
|
||||
if (burn_track_set_source(track, fifo_src[trackno])
|
||||
!= BURN_SOURCE_OK) {
|
||||
printf("FATAL: Cannot attach source object to track object\n");
|
||||
fprintf(stderr,
|
||||
"FATAL: Cannot attach source object to track object\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -453,7 +488,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||
/* Give up local reference to the data burn_source object */
|
||||
burn_source_free(data_src);
|
||||
|
||||
} /* trackno loop end */
|
||||
} /* trackno loop end */
|
||||
|
||||
/* Evaluate drive and media */
|
||||
disc_state = burn_disc_get_status(drive);
|
||||
@ -533,7 +568,8 @@ int libburner_payload(struct burn_drive *drive,
|
||||
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 */
|
||||
current_profile != 0x12 && current_profile != 0x43)
|
||||
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
||||
printf("NOTE: Media left appendable.\n");
|
||||
if (simulate_burn)
|
||||
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
|
||||
@ -590,7 +626,8 @@ int libburner_setup(int argc, char **argv)
|
||||
}
|
||||
strcpy(drive_adr, argv[i]);
|
||||
}
|
||||
} else if (!strcmp(argv[i], "--format_overwrite")) {
|
||||
} else if ((!strcmp(argv[i], "--format_overwrite")) ||
|
||||
(!strcmp(argv[i], "--format"))) {
|
||||
do_blank = 101;
|
||||
|
||||
} else if (!strcmp(argv[i], "--multi")) {
|
||||
@ -631,8 +668,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|--format] [--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");
|
||||
@ -645,8 +681,8 @@ int libburner_setup(int argc, char **argv)
|
||||
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("Format a DVD-RW, BD-RE or BD-R:\n");
|
||||
printf(" %s --drive /dev/hdc --format\n", argv[0]);
|
||||
printf("Burn two audio tracks (to CD only):\n");
|
||||
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
||||
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
||||
@ -696,7 +732,7 @@ int main(int argc, char **argv)
|
||||
{ ret = 0; goto release_drive; }
|
||||
if (do_blank) {
|
||||
if (do_blank > 100)
|
||||
ret = libburner_format_row(drive_list[driveno].drive);
|
||||
ret = libburner_format(drive_list[driveno].drive);
|
||||
else
|
||||
ret = libburner_blank_disc(drive_list[driveno].drive,
|
||||
do_blank == 1);
|
||||
|
@ -606,7 +606,8 @@ int telltoc_read_and_print(struct burn_drive *drive,
|
||||
if (start_sector == -1)
|
||||
start_sector = last_track_start;
|
||||
if (sector_count == -1) {
|
||||
sector_count = last_track_size;
|
||||
sector_count = last_track_start + last_track_size
|
||||
- start_sector;
|
||||
if (media_is_cd_profile) /* In case it is a TAO track */
|
||||
final_cd_try = 0; /* allow it (-1 is denial) */
|
||||
}
|
||||
|
Reference in New Issue
Block a user