Compare commits
112 Commits
ZeroFourEi
...
ZeroSixFou
Author | SHA1 | Date | |
---|---|---|---|
fc1b93b15c | |||
b3e1136694 | |||
34bb592b60 | |||
34535a9cbf | |||
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 |
@ -1,7 +1,7 @@
|
|||||||
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2008 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
20
Makefile.am
20
Makefile.am
@ -82,32 +82,34 @@ noinst_PROGRAMS = \
|
|||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
cdrskin/cdrskin
|
cdrskin/cdrskin
|
||||||
|
|
||||||
|
LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||||
|
|
||||||
test_libburner_CPPFLAGS = -Ilibburn
|
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_libburner_SOURCES = test/libburner.c
|
||||||
test_telltoc_CPPFLAGS = -Ilibburn
|
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_telltoc_SOURCES = test/telltoc.c
|
||||||
test_dewav_CPPFLAGS = -Ilibburn
|
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_dewav_SOURCES = test/dewav.c
|
||||||
test_fake_au_CPPFLAGS =
|
test_fake_au_CPPFLAGS =
|
||||||
test_fake_au_LDADD =
|
test_fake_au_LDADD =
|
||||||
test_fake_au_SOURCES = test/fake_au.c
|
test_fake_au_SOURCES = test/fake_au.c
|
||||||
test_poll_CPPFLAGS = -Ilibburn
|
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_poll_SOURCES = test/poll.c
|
||||||
test_structest_CPPFLAGS = -Ilibburn
|
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
|
test_structest_SOURCES = test/structest.c
|
||||||
|
|
||||||
## cdrskin construction site - ts A60816 - A80510
|
## cdrskin construction site - ts A60816 - A90313
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_4_7
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_6_4
|
||||||
|
|
||||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||||
cdrskin_cdrskin_LDADD = libburn/libburn.la $(THREAD_LIBS)
|
cdrskin_cdrskin_LDADD = libburn/libburn.la $(LIBBURN_EXTRALIBS)
|
||||||
|
|
||||||
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
||||||
##
|
##
|
||||||
|
192
README
192
README
@ -4,49 +4,60 @@
|
|||||||
This all is under GPL.
|
This all is under GPL.
|
||||||
(See GPL reference, our clarification and commitment at the end of this text)
|
(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>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2008 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
||||||
|
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||||
Still containing parts of
|
and Ben Jansens <xor@orodu.net>
|
||||||
Libburn. By Derek Foreman <derek@signalmarketing.com> and
|
|
||||||
Ben Jansens <xor@orodu.net>
|
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
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-2008 Thomas Schmitt
|
http://files.libburnia-project.org/releases/libburn-0.6.4.pl00.tar.gz
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Build and Installation
|
Build and Installation
|
||||||
|
|
||||||
Our build system is based on autotools. For preparing the build of a SVN
|
From tarball
|
||||||
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
|
|
||||||
|
|
||||||
Alternatively you may unpack a release tarball for which you do not need
|
Obtain libburn-0.6.4.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
autotools installed.
|
|
||||||
|
|
||||||
To build a libburnia-project.org subproject it should be sufficient to go
|
tar xzf libburn-0.6.4.pl00.tar.gz
|
||||||
into its toplevel directory (here: "libburn") and execute
|
cd libburn-0.6.4
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
To make libburn accessible for running resp. application development,
|
To make libburn accessible for running resp. application development,
|
||||||
and to install the cdrecord compatibility binary cdrskin, do:
|
and to install the cdrecord compatibility binary cdrskin, do
|
||||||
|
(as Superuser):
|
||||||
|
|
||||||
make install
|
make install
|
||||||
|
|
||||||
|
This procedure installs libburn.so.4 and cdrskin depending on it.
|
||||||
Above procedure installs cdrskin depending on libburn.so.4 .
|
|
||||||
For a standalone cdrskin binary, see cdrskin/README.
|
For a standalone cdrskin binary, see cdrskin/README.
|
||||||
|
|
||||||
|
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-0.6.3
|
||||||
|
cd libburn-0.6.3
|
||||||
|
./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
|
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||||
launchpad.net :
|
launchpad.net :
|
||||||
@ -57,7 +68,6 @@ Another part the project, libisoburn, is hosted in the libburnia SVN, too:
|
|||||||
|
|
||||||
See README files there.
|
See README files there.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@ -65,24 +75,27 @@ See README files there.
|
|||||||
|
|
||||||
libburnia-project.org is an open-source software project for reading, mastering
|
libburnia-project.org is an open-source software project for reading, mastering
|
||||||
and writing optical discs.
|
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
|
The project comprises of several more or less interdependent parts which
|
||||||
together strive to be a usable foundation for application development.
|
together strive to be a usable foundation for application development.
|
||||||
These are libraries, language bindings, and middleware binaries which emulate
|
These are libraries, language bindings, and middleware binaries which emulate
|
||||||
classical (and valuable) Linux tools.
|
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
|
For full ports to other systems we would need : login on a development machine
|
||||||
we would need : login on a development machine resp. a live OS on CD or DVD,
|
resp. a live OS on CD or DVD, advise from a system person about the equivalent
|
||||||
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
|
||||||
volunteers for testing of realistic use cases.
|
|
||||||
|
|
||||||
We have a well tested code base for burning data and audio CDs and many DVD
|
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
||||||
types. The burn API is quite comprehensively documented and can be used to
|
The burn API is quite comprehensively documented and can be used to build a
|
||||||
build a presentable application.
|
presentable application.
|
||||||
We have a functional binary which emulates the core use cases of cdrecord in
|
We have a functional application which emulates the core use cases of cdrecord
|
||||||
order to prove that usability, and in order to allow you to explore libburn's
|
in order to prove that usability, and in order to allow you to explore
|
||||||
scope by help of existing cdrecord frontends.
|
libburn's scope by help of existing cdrecord frontends.
|
||||||
|
|
||||||
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
||||||
and manipulated quite freely. This capability together with our burn capability
|
and manipulated quite freely. This capability together with our burn capability
|
||||||
@ -122,8 +135,9 @@ The project components (list subject to growth, hopefully):
|
|||||||
- xorriso is an application of all three libraries which creates, loads,
|
- xorriso is an application of all three libraries which creates, loads,
|
||||||
manipulates and writes ISO 9660 filesystem images with
|
manipulates and writes ISO 9660 filesystem images with
|
||||||
Rock Ridge extensions. Manipulation is not only adding or
|
Rock Ridge extensions. Manipulation is not only adding or
|
||||||
overwriting of files but also deletion, renaming, and attribute
|
overwriting of files but also deleting, renaming, attribute
|
||||||
changing.
|
changing, incremental backups, activating boot images, and
|
||||||
|
extracting of files from ISO images to disk.
|
||||||
See xorriso/README for more.
|
See xorriso/README for more.
|
||||||
|
|
||||||
- "test" is a collection of application gestures and examples given by the
|
- "test" is a collection of application gestures and examples given by the
|
||||||
@ -142,10 +156,17 @@ 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.
|
x.y.*[02468]. As soon as it is released, a feature is promised to persist.
|
||||||
|
|
||||||
SONAMES:
|
SONAMES:
|
||||||
libburn.so.4 (since 0.3.4, March 2007),
|
libburn.so.4 (since 0.3.4, March 2007),
|
||||||
libisofs.so.6 (since 0.6.2, February 2008),
|
libisofs.so.6 (since 0.6.2, February 2008),
|
||||||
libisoburn.so.1 (since 0.1.0, 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.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Project history as far as known to me:
|
Project history as far as known to me:
|
||||||
@ -173,7 +194,7 @@ Project history as far as known to me:
|
|||||||
discontent.
|
discontent.
|
||||||
The situation first caused me to publically regret it and then - after i
|
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
|
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:
|
icculus.org/burn. Posted to both projects:
|
||||||
http://lists.freedesktop.org/archives/libburn/2006-August/000446.html
|
http://lists.freedesktop.org/archives/libburn/2006-August/000446.html
|
||||||
http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html
|
http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html
|
||||||
@ -277,13 +298,96 @@ Project history as far as known to me:
|
|||||||
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
|
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
|
xorriso makes use of new libisofs features by performing incremental
|
||||||
updates of directory trees and by cutting oversized data files into
|
updates of directory trees and by cutting oversized data files into
|
||||||
pieces. A primitive single session emulation of cdrcord and mkisofs is
|
pieces. A primitive single session emulation of cdrecord and mkisofs is
|
||||||
provided.
|
provided.
|
||||||
|
|
||||||
- 10th May 2008 libburn-0.4.6 supports formatting and writing of BD-RE,
|
- 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
|
full nominal speed for DVD-RAM and BD-RE. cdrskin has a unified blank
|
||||||
type with automatic media state recognition.
|
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.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -14,7 +14,9 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
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
|
esac
|
||||||
|
|
||||||
|
@ -4,15 +4,18 @@
|
|||||||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Integrated sub project of libburnia-project.org but also published via:
|
Integrated sub project of libburnia-project.org but also published via:
|
||||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
http://scdbackup.sourceforge.net/cdrskin-0.4.7.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-0.6.4.pl00.tar.gz
|
||||||
Copyright (C) 2006-2008 Thomas Schmitt, provided under GPL version 2.
|
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
||||||
most of the libburn features from the command line.
|
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 pseudo 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
|
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 ..."
|
"This software is provided as is. There is no warranty implied and ..."
|
||||||
@ -20,10 +23,10 @@ By using this software you agree to the disclaimer at the end of this text
|
|||||||
|
|
||||||
Compilation, First Glimpse, Installation
|
Compilation, First Glimpse, Installation
|
||||||
|
|
||||||
Obtain cdrskin-0.4.7.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-0.6.4.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-0.4.7.tar.gz
|
tar xzf cdrskin-0.6.4.pl00.tar.gz
|
||||||
cd cdrskin-0.4.7
|
cd cdrskin-0.6.4
|
||||||
|
|
||||||
Within that directory execute:
|
Within that directory execute:
|
||||||
|
|
||||||
@ -118,6 +121,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.
|
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.
|
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
|
Usage examples
|
||||||
|
|
||||||
@ -139,8 +147,8 @@ Obtain some info about the drive
|
|||||||
Obtain some info about the drive and the inserted media
|
Obtain some info about the drive and the inserted media
|
||||||
cdrskin dev=0,1,0 -atip -v
|
cdrskin dev=0,1,0 -atip -v
|
||||||
|
|
||||||
Make used CD-RW or used unformatted DVD-RW writeable again
|
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
||||||
cdrskin -v dev=0,1,0 blank=fast -eject
|
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
||||||
|
|
||||||
Format DVD-RW to avoid need for blanking before re-use
|
Format DVD-RW to avoid need for blanking before re-use
|
||||||
cdrskin -v dev=0,1,0 blank=format_overwrite
|
cdrskin -v dev=0,1,0 blank=format_overwrite
|
||||||
@ -154,16 +162,16 @@ Burn image file my_image.iso to media
|
|||||||
|
|
||||||
Write multi-session to the same CD , DVD-R[W] or DVD+R[/DL]
|
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 1.iso
|
||||||
cdrskin dev=/dev/hdc padsize=300k -multi -tao 2.iso
|
cdrskin dev=/dev/hdc padsize=300k -multi 2.iso
|
||||||
cdrskin dev=/dev/hdc padsize=300k -multi -tao 3.iso
|
cdrskin dev=/dev/hdc padsize=300k -multi 3.iso
|
||||||
cdrskin dev=/dev/hdc padsize=300k -tao 4.iso
|
cdrskin dev=/dev/hdc padsize=300k 4.iso
|
||||||
|
|
||||||
Get multi-session info for option -C of program mkisofs:
|
Get multi-session info for option -C of program mkisofs:
|
||||||
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
|
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
|
||||||
mkisofs ... -C "$c_values" ...
|
mkisofs ... -C "$c_values" ...
|
||||||
|
|
||||||
Burn a compressed afio archive to media on-the-fly
|
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 -
|
driveropts=burnfree padsize=300k -
|
||||||
|
|
||||||
Burn 6 audio tracks from files with different formats to CD (not to any DVD).
|
Burn 6 audio tracks from files with different formats to CD (not to any DVD).
|
||||||
@ -186,8 +194,6 @@ See output of command
|
|||||||
cdrskin --list_ignored_options
|
cdrskin --list_ignored_options
|
||||||
If you have use cases for them, please report your wishes and expectations.
|
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
|
On the other hand, the capability of multi-session and of writing streams
|
||||||
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
|
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
|
||||||
|
|
||||||
@ -275,13 +281,16 @@ behavior.
|
|||||||
BD-RE media need formatting before first use. cdrskin option "blank=as_needed"
|
BD-RE media need formatting before first use. cdrskin option "blank=as_needed"
|
||||||
recognizes unformatted BD-RE and applies a lengthy formatting run.
|
recognizes unformatted BD-RE and applies a lengthy formatting run.
|
||||||
|
|
||||||
During write operations DVD-RAM and BD-RE automatically apply defect
|
During write operations DVD-RAM and BD-RE automatically apply Defect
|
||||||
management. This usually slows them down to half nominal speed. If drive
|
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
|
and media produce flawless results anyway, then one can try to reach full
|
||||||
nominal speed by option "stream_recording=on".
|
nominal speed by option "stream_recording=on".
|
||||||
In this case bad blocks are not detected during write and not even previously
|
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
|
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.
|
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.
|
||||||
|
|
||||||
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
|
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
|
||||||
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
|
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
|
||||||
@ -351,14 +360,24 @@ Incremental Streaming afterwards. So blank=fast will do full blanking.
|
|||||||
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
|
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
|
||||||
|
|
||||||
|
|
||||||
DVD+R and DVD+R DL
|
DVD+R , DVD+R DL , BD-R
|
||||||
|
|
||||||
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
|
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
|
||||||
into an own session, though.
|
into an own session, though.
|
||||||
|
|
||||||
DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address
|
DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address
|
||||||
of the layer break where ia reading drive might show some delay while switching
|
of the layer break where a reading drive might show some delay while switching
|
||||||
between both media layers.
|
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
|
Emulated Drives
|
||||||
|
|
||||||
@ -407,9 +426,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
|
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
|
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.
|
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
|
system because of drives gnawing endlessly on ill media. Permanent hardware
|
||||||
damage did not occur in 2.5 years of development.
|
damage did not occur in 3.5 years of development. But one never knows ...
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -437,7 +456,7 @@ contributions in a due way.
|
|||||||
Based on and sub project of:
|
Based on and sub project of:
|
||||||
libburnia-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2008 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
libburnia-project.org is inspired by and in other components still containing
|
libburnia-project.org is inspired by and in other components still containing
|
||||||
parts of
|
parts of
|
||||||
|
@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
|
|||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-release"
|
changes="./libburn-release"
|
||||||
|
|
||||||
skin_release="0.4.6"
|
skin_release="0.6.4"
|
||||||
patch_level=".pl00"
|
patch_level=".pl00"
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
|
|||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-develop"
|
changes="./libburn-develop"
|
||||||
|
|
||||||
skin_release="0.4.7"
|
skin_release="0.6.5"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ rm -rf "$target"
|
|||||||
./"$bintarget_dynamic" -version
|
./"$bintarget_dynamic" -version
|
||||||
./"$bintarget_static" -version
|
./"$bintarget_static" -version
|
||||||
ls -l "$cdrskin_tarball"
|
ls -l "$cdrskin_tarball"
|
||||||
ls -l "$bintarget_dynamic"*
|
ls -l "$bintarget_dynamic"
|
||||||
ls -l "$bintarget_static"
|
ls -l "$bintarget_static"
|
||||||
ls -l $(basename "$man_page_html")
|
ls -l $(basename "$man_page_html")
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.TH CDRSKIN 1 "May 10, 2008"
|
.TH CDRSKIN 1 "Jan 07, 2009"
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.\"
|
.\"
|
||||||
.\" Some roff macros, for reference:
|
.\" Some roff macros, for reference:
|
||||||
@ -16,7 +16,7 @@
|
|||||||
.\" .sp <n> insert n+1 empty lines
|
.\" .sp <n> insert n+1 empty lines
|
||||||
.\" for manpage-specific macros, see man(7)
|
.\" for manpage-specific macros, see man(7)
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cdrskin \- burns preformatted data to CD, DVD, and BD-RE via libburn.
|
cdrskin \- burns preformatted data to CD, DVD, and BD via libburn.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B cdrskin
|
.B cdrskin
|
||||||
.RI [ options | track_source_addresses ]
|
.RI [ options | track_source_addresses ]
|
||||||
@ -28,14 +28,14 @@ cdrskin \- burns preformatted data to CD, DVD, and BD-RE via libburn.
|
|||||||
.\" respectively.
|
.\" respectively.
|
||||||
.PP
|
.PP
|
||||||
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
||||||
in a compatible way for CD media. With DVD and BD-RE 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.
|
You do not need to be superuser for its daily usage.
|
||||||
.SS
|
.SS
|
||||||
.B Overview of features:
|
.B Overview of features:
|
||||||
.br
|
.br
|
||||||
Blanking of CD-RW and DVD-RW.
|
Blanking of CD-RW and DVD-RW.
|
||||||
.br
|
.br
|
||||||
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD-RE.
|
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
|
||||||
.br
|
.br
|
||||||
Burning of data or audio tracks to CD,
|
Burning of data or audio tracks to CD,
|
||||||
.br
|
.br
|
||||||
@ -45,7 +45,7 @@ or in Session at Once mode for seamless tracks.
|
|||||||
.br
|
.br
|
||||||
Multi session on CD (follow-up sessions in TAO only)
|
Multi session on CD (follow-up sessions in TAO only)
|
||||||
.br
|
.br
|
||||||
or on DVD-R[W] (in Incremental mode) or on DVD+R[/DL].
|
or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R.
|
||||||
.br
|
.br
|
||||||
Single session on DVD-RW or DVD-R (Disk-at-once).
|
Single session on DVD-RW or DVD-R (Disk-at-once).
|
||||||
.br
|
.br
|
||||||
@ -108,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
|
data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems
|
||||||
are established as a format which can represent a tree of directories and
|
are established as a format which can represent a tree of directories and
|
||||||
files on all major operating systems. Such filesystem images can be
|
files on all major operating systems. Such filesystem images can be
|
||||||
produced by programs mkisofs or genisoimage. They can also be extended by
|
produced by programs mkisofs or genisoimage or xorriso.
|
||||||
follow-up tracks if prepared properly. See the man pages of said programs.
|
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.
|
cdrskin is able to fulfill the needs about their option -C.
|
||||||
.br
|
.br
|
||||||
Another type of data track content are archive formats which originally
|
Another type of data track content are archive formats which originally
|
||||||
@ -160,14 +161,16 @@ round of overwriting. Usually
|
|||||||
is the appropriate option.
|
is the appropriate option.
|
||||||
Blanking damages the previous content but does not
|
Blanking damages the previous content but does not
|
||||||
make it completely unreadable. It is no effective privacy precaution.
|
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
|
.SS
|
||||||
.B Sequentially Recordable DVD Media:
|
.B Sequentially Recordable DVD or BD Media:
|
||||||
.br
|
.br
|
||||||
Currently DVD-RW, DVD-R and DVD+R[/DL] can be used for the Sequential recording
|
Currently DVD-RW, DVD-R , DVD+R[/DL], and BD-R can be used for the Sequential
|
||||||
model.
|
recording model. It resembles the model of CD media. Only DVD-RW can be
|
||||||
|
blanked and re-used from scratch.
|
||||||
.br
|
.br
|
||||||
This applies to DVD-RW only if they are in state "Sequential Recording".
|
DVD-RW are sequential media if they are in state "Sequential Recording".
|
||||||
The media must be either blank or appendable.
|
The media must be either blank or appendable.
|
||||||
Newly purchased DVD-RW and DVD-R media are in this state.
|
Newly purchased DVD-RW and DVD-R media are in this state.
|
||||||
Used DVD-RW get into blank sequential state by option
|
Used DVD-RW get into blank sequential state by option
|
||||||
@ -199,14 +202,18 @@ unpredicted length and to keep media appendable by option
|
|||||||
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
||||||
Multiple tracks per session are permissible.
|
Multiple tracks per session are permissible.
|
||||||
.br
|
.br
|
||||||
The write modes for DVD+R[/DL] resemble those with DVD-R except that with +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
|
each track gets wrapped in an own session. There is no -dummy writing
|
||||||
DVD+R[/DL].
|
with DVD+R[/DL] or BD-R.
|
||||||
.br
|
.br
|
||||||
Quite deliberately write mode -sao insists in the tradition of a predicted
|
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
|
track size and blank media, whereas -tao writes the tracks open ended and
|
||||||
allows appendable media.
|
allows appendable media.
|
||||||
.br
|
.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:
|
.B Note:
|
||||||
Option -multi might make DVD media unreadable in some DVD-ROM drives.
|
Option -multi might make DVD media unreadable in some DVD-ROM drives.
|
||||||
Best reader compatibility is achieved without it
|
Best reader compatibility is achieved without it
|
||||||
@ -351,7 +358,7 @@ audio track. Same is done for suffix ".au" and SUN Audio.
|
|||||||
Option -audio may be used only with CD media and not with DVD or BD.
|
Option -audio may be used only with CD media and not with DVD or BD.
|
||||||
.TP
|
.TP
|
||||||
.BI blank= type
|
.BI blank= type
|
||||||
Blank a CD-RW, DVD-RW, or format a DVD-RW, DVD+RW, DVD-RAM, BD-RE.
|
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.
|
This is combinable with burning in the same run of cdrskin.
|
||||||
The type given with blank= selects the particular behavior:
|
The type given with blank= selects the particular behavior:
|
||||||
.RS
|
.RS
|
||||||
@ -363,7 +370,7 @@ It is a reason to abort if the media cannot assume thoroughly writeable state,
|
|||||||
e.g. if it is non-blank write-once.
|
e.g. if it is non-blank write-once.
|
||||||
.br
|
.br
|
||||||
This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use
|
This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use
|
||||||
blank=format_overwriteable.
|
blank=format_overwriteable. Blank unformatted BD-R stay unformatted.
|
||||||
.br
|
.br
|
||||||
(Note: blank=as_needed is not an original cdrecord option.)
|
(Note: blank=as_needed is not an original cdrecord option.)
|
||||||
.TP
|
.TP
|
||||||
@ -392,10 +399,11 @@ This is faster than full blanking but may yield media incapable of
|
|||||||
Incremental Streaming (-tao).
|
Incremental Streaming (-tao).
|
||||||
.TP
|
.TP
|
||||||
format_if_needed
|
format_if_needed
|
||||||
Format a media if it is not overwriteably formatted yet,
|
Format a media if it is not formatted yet,
|
||||||
and if cdrskin supports formatting for the media type,
|
and if cdrskin supports formatting for the media type,
|
||||||
and if formatting will not happen automatically during write.
|
and if formatting will not happen automatically during write.
|
||||||
This currently applies to unformatted DVD-RW, DVD-RAM and BD-RE.
|
This currently applies to unformatted DVD-RW, DVD-RAM, BD-RE,
|
||||||
|
and blank unformatted BD-R.
|
||||||
Eventually the appropriate default formatting is chosen.
|
Eventually the appropriate default formatting is chosen.
|
||||||
If other media or states are encountered then nothing happens.
|
If other media or states are encountered then nothing happens.
|
||||||
.br
|
.br
|
||||||
@ -425,7 +433,7 @@ For DVD+RW this is the only supported explicit formatting type. It provides
|
|||||||
complete "de-icing" so no reader slips on unwritten data areas.
|
complete "de-icing" so no reader slips on unwritten data areas.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt
|
format_defectmgt
|
||||||
Format DVD-RAM or BD-RE to reserve the default amount of spare blocks for
|
Format DVD-RAM or BD to reserve the default amount of spare blocks for
|
||||||
defect management.
|
defect management.
|
||||||
.br
|
.br
|
||||||
The following format_defectmgt_* allow to submit user wishes which
|
The following format_defectmgt_* allow to submit user wishes which
|
||||||
@ -449,25 +457,25 @@ Whether there happens certification at all depends much on the media state
|
|||||||
and the actually selected format descriptor.
|
and the actually selected format descriptor.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_max
|
format_defectmgt_max
|
||||||
Format DVD-RAM or BD-RE to reserve a maximum number of spare blocks.
|
Format DVD-RAM or BD to reserve a maximum number of spare blocks.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_min
|
format_defectmgt_min
|
||||||
Format DVD-RAM or BD-RE to reserve a minimum number of spare blocks.
|
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
|
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.
|
offered the most minmal spare blocks sizes for format_defectmgt_min.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_none
|
format_defectmgt_none
|
||||||
Format DVD-RAM or BD-RE to the largest available payload in the hope to disable
|
Format DVD-RAM or BD-RE to the largest available payload in the hope to disable
|
||||||
defect management at all. This seems not to have a speed increasing effect,
|
defect management at all. This may or may not have a speed increasing effect.
|
||||||
though.
|
Unformatted blank BD-R will be left unformatted.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_payload_<size>
|
format_defectmgt_payload_<size>
|
||||||
Format DVD-RAM or BD-RE. The text after "format_defectmgt_payload_" gives a
|
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
|
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.
|
of spare blocks will be chosen which allows at least the given payload size.
|
||||||
.TP
|
.TP
|
||||||
format_by_index_<number>
|
format_by_index_<number>
|
||||||
Format DVD-RW, DVD+RW, DVD-RAM or BD-RE.
|
Format DVD-RW, DVD+RW, DVD-RAM or BD.
|
||||||
The number after "format_by_index_" is used as index to the list of available
|
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.
|
format descriptors. This list can be obtained by option --list_formats.
|
||||||
The numbers after text "Format idx" are the ones to be used with
|
The numbers after text "Format idx" are the ones to be used with
|
||||||
@ -617,7 +625,8 @@ Note: msifile=path is actually an option of wodim and not of cdrecord.
|
|||||||
.TP
|
.TP
|
||||||
.BI \-msinfo
|
.BI \-msinfo
|
||||||
Retrieve multi-session info for preparing a follow-up session by option -C
|
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
|
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.
|
--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.
|
The result string shall be used as argument of option -C with said programs.
|
||||||
@ -1080,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.
|
Wether this leads to senseful behavior depends on operating system and kernel.
|
||||||
.TP
|
.TP
|
||||||
.BI drive_scsi_dev_family= sr | scd | sg
|
.BI drive_scsi_dev_family= sr | scd | sg
|
||||||
Linux specific: Select a SCSI device file family to be used for drive command
|
Linux specific: Select a SCSI device file family to be scanned for by
|
||||||
transactions. Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
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
|
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.
|
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.
|
On kernel 2.4 families sr and scd will find no drives.
|
||||||
@ -1176,13 +1186,15 @@ 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
|
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||||
original cdrecord.
|
original cdrecord.
|
||||||
.TP
|
.TP
|
||||||
.BI stream_recording="on"|"off"
|
.BI stream_recording="on"|"off"|number
|
||||||
By setting "on" request that compliance to the desired speed setting is
|
By setting "on" request that compliance to the desired speed setting is
|
||||||
preferred over management of write errors. With DVD-RAM and BD-RE this can
|
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.
|
bring effective write speed near to the nominal write speed of the media.
|
||||||
But it will also disable the automatic use of replacement blocks
|
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.
|
if write errors occur. It might as well be disliked or ignored by the drive.
|
||||||
.br
|
.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
|
.SH EXAMPLES
|
||||||
.SS
|
.SS
|
||||||
.B Get an overview of drives and their addresses:
|
.B Get an overview of drives and their addresses:
|
||||||
@ -1229,13 +1241,13 @@ blank=as_needed padsize=300k -
|
|||||||
.SS
|
.SS
|
||||||
.B Write multi-session to the same CD, DVD-R[W] or DVD+R[/DL]:
|
.B Write multi-session to the same CD, DVD-R[W] or DVD+R[/DL]:
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso
|
cdrskin dev=/dev/hdc -v padsize=300k -multi 1.iso
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso
|
cdrskin dev=/dev/hdc -v padsize=300k -multi 2.iso
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso
|
cdrskin dev=/dev/hdc -v padsize=300k -multi 3.iso
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso
|
cdrskin dev=/dev/hdc -v padsize=300k 4.iso
|
||||||
.SS
|
.SS
|
||||||
.B Get multi-session info for option -C of program mkisofs:
|
.B Get multi-session info for option -C of program mkisofs:
|
||||||
.br
|
.br
|
||||||
@ -1243,9 +1255,9 @@ c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
|
|||||||
.br
|
.br
|
||||||
mkisofs ... -C "$c_values" ...
|
mkisofs ... -C "$c_values" ...
|
||||||
.SS
|
.SS
|
||||||
.B Inquire free space on media for a -tao -multi run:
|
.B Inquire free space on media for a -multi run:
|
||||||
.br
|
.br
|
||||||
x=$(cdrskin dev=/dev/sr0 -tao -multi \\
|
x=$(cdrskin dev=/dev/sr0 -multi \\
|
||||||
.br
|
.br
|
||||||
--tell_media_space 2>/dev/null)
|
--tell_media_space 2>/dev/null)
|
||||||
.br
|
.br
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
cdrskin.c , Copyright 2006-2008 Thomas Schmitt <scdbackup@gmx.net>
|
cdrskin.c , Copyright 2006-2009 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2. See future commitment below.
|
Provided under GPL version 2. See future commitment below.
|
||||||
|
|
||||||
A cdrecord compatible command line interface for libburn.
|
A cdrecord compatible command line interface for libburn.
|
||||||
@ -88,7 +88,7 @@ or
|
|||||||
|
|
||||||
/** The official program version */
|
/** The official program version */
|
||||||
#ifndef Cdrskin_prog_versioN
|
#ifndef Cdrskin_prog_versioN
|
||||||
#define Cdrskin_prog_versioN "0.4.7"
|
#define Cdrskin_prog_versioN "0.6.4"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** The official libburn interface revision to use.
|
/** The official libburn interface revision to use.
|
||||||
@ -98,10 +98,10 @@ or
|
|||||||
#define Cdrskin_libburn_majoR 0
|
#define Cdrskin_libburn_majoR 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef Cdrskin_libburn_minoR
|
#ifndef Cdrskin_libburn_minoR
|
||||||
#define Cdrskin_libburn_minoR 4
|
#define Cdrskin_libburn_minoR 6
|
||||||
#endif
|
#endif
|
||||||
#ifndef Cdrskin_libburn_micrO
|
#ifndef Cdrskin_libburn_micrO
|
||||||
#define Cdrskin_libburn_micrO 7
|
#define Cdrskin_libburn_micrO 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -135,44 +135,44 @@ or
|
|||||||
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
||||||
|
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_4_6
|
#ifdef Cdrskin_libburn_0_6_4
|
||||||
#define Cdrskin_libburn_versioN "0.4.6"
|
#define Cdrskin_libburn_versioN "0.6.4"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
#endif /* Cdrskin_libburn_0_4_6 */
|
#endif /* Cdrskin_libburn_0_6_4 */
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_4_7
|
#ifdef Cdrskin_libburn_0_6_5
|
||||||
#define Cdrskin_libburn_versioN "0.4.7"
|
#define Cdrskin_libburn_versioN "0.6.5"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
|
|
||||||
/* Place novelty switch macros here.
|
/* Place novelty switch macros here.
|
||||||
Move them down to Cdrskin_libburn_from_pykix_svN on version leap
|
Move them down to Cdrskin_libburn_from_pykix_svN on version leap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* there are no libburn novelties in 0.4.7 yet */
|
/* there are no libburn novelties in 0.6.5 yet */
|
||||||
|
|
||||||
#endif /* Cdrskin_libburn_0_4_7 */
|
#endif /* Cdrskin_libburn_0_6_5 */
|
||||||
|
|
||||||
#ifndef Cdrskin_libburn_versioN
|
#ifndef Cdrskin_libburn_versioN
|
||||||
#define Cdrskin_libburn_0_4_6
|
#define Cdrskin_libburn_0_6_4
|
||||||
#define Cdrskin_libburn_versioN "0.4.6"
|
#define Cdrskin_libburn_versioN "0.6.4"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_4_6
|
#ifdef Cdrskin_libburn_0_6_4
|
||||||
#undef Cdrskin_libburn_majoR
|
#undef Cdrskin_libburn_majoR
|
||||||
#undef Cdrskin_libburn_minoR
|
#undef Cdrskin_libburn_minoR
|
||||||
#undef Cdrskin_libburn_micrO
|
#undef Cdrskin_libburn_micrO
|
||||||
#define Cdrskin_libburn_majoR 0
|
#define Cdrskin_libburn_majoR 0
|
||||||
#define Cdrskin_libburn_minoR 4
|
#define Cdrskin_libburn_minoR 6
|
||||||
#define Cdrskin_libburn_micrO 6
|
#define Cdrskin_libburn_micrO 4
|
||||||
#endif
|
#endif
|
||||||
#ifdef Cdrskin_libburn_0_4_7
|
#ifdef Cdrskin_libburn_0_6_5
|
||||||
#undef Cdrskin_libburn_majoR
|
#undef Cdrskin_libburn_majoR
|
||||||
#undef Cdrskin_libburn_minoR
|
#undef Cdrskin_libburn_minoR
|
||||||
#undef Cdrskin_libburn_micrO
|
#undef Cdrskin_libburn_micrO
|
||||||
#define Cdrskin_libburn_majoR 0
|
#define Cdrskin_libburn_majoR 0
|
||||||
#define Cdrskin_libburn_minoR 4
|
#define Cdrskin_libburn_minoR 6
|
||||||
#define Cdrskin_libburn_micrO 7
|
#define Cdrskin_libburn_micrO 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -248,6 +248,18 @@ or
|
|||||||
/* 0.4.6 */
|
/* 0.4.6 */
|
||||||
#define Cdrskin_libburn_has_stream_recordinG 1
|
#define Cdrskin_libburn_has_stream_recordinG 1
|
||||||
|
|
||||||
|
/* 0.4.8 */
|
||||||
|
/* Bug fix release for write_start_address=... on DVD-RAM and BD-RE */
|
||||||
|
|
||||||
|
/* 0.5.0 , 0.5.2 , 0.5.4 , 0.5.6 , 0.5.8 , 0.6.0 , 0.6.2 */
|
||||||
|
/* novel libburn features are transparent to cdrskin */
|
||||||
|
|
||||||
|
/* 0.6.4 */
|
||||||
|
/* Ended to mark novelties by macros.
|
||||||
|
libburnia libburn and cdrskin are fixely in sync now.
|
||||||
|
icculus libburn did not move for 30 months.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef Cdrskin_new_api_tesT
|
#ifdef Cdrskin_new_api_tesT
|
||||||
|
|
||||||
@ -2408,11 +2420,11 @@ return:
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\tformat_overwrite_full\t\tfull-size format a DVD-RW or DVD+RW\n");
|
"\tformat_overwrite_full\t\tfull-size format a DVD-RW or DVD+RW\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\tformat_defectmgt[_max|_min|_none]\tformat DVD-RAM or BD-RE\n");
|
"\tformat_defectmgt[_max|_min|_none]\tformat DVD-RAM or BD-R[E]\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\tformat_defectmgt[_cert_on|_cert_off]\tcertification slow|quick\n");
|
"\tformat_defectmgt[_cert_on|_cert_off]\tcertification slow|quick\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\tformat_defectmgt_payload_<size>\tformat DVD-RAM or BD-RE\n");
|
"\tformat_defectmgt_payload_<size>\tformat DVD-RAM or BD-R[E]\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\tformat_by_index_<number>\t\tformat by index from --list_formats\n");
|
"\tformat_by_index_<number>\t\tformat by index from --list_formats\n");
|
||||||
|
|
||||||
@ -2686,10 +2698,13 @@ set_dev:;
|
|||||||
" --single_track accept only last argument as source_address\n");
|
" --single_track accept only last argument as source_address\n");
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_has_stream_recordinG
|
#ifdef Cdrskin_libburn_has_stream_recordinG
|
||||||
|
printf(" stream_recording=\"on\"|\"off\"|number\n");
|
||||||
printf(
|
printf(
|
||||||
" stream_recording=\"on\"|\"off\" \"on\" requests to prefer speed\n");
|
" \"on\" requests to prefer speed over write\n");
|
||||||
printf(
|
printf(
|
||||||
" over write error management.\n");
|
" error management. A number prevents this with\n");
|
||||||
|
printf(
|
||||||
|
" byte addresses below that number.\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Cdrskin_allow_libburn_taO
|
#ifdef Cdrskin_allow_libburn_taO
|
||||||
@ -2886,7 +2901,7 @@ set_severities:;
|
|||||||
int major, minor, micro;
|
int major, minor, micro;
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
"Cdrecord 2.01-Emulation Copyright (C) 2006-2008, see libburnia-project.org\n");
|
"Cdrecord 2.01-Emulation Copyright (C) 2006-2009, see libburnia-project.org\n");
|
||||||
printf("libburn interface : %d.%d.%d\n",
|
printf("libburn interface : %d.%d.%d\n",
|
||||||
burn_header_version_major, burn_header_version_minor,
|
burn_header_version_major, burn_header_version_minor,
|
||||||
burn_header_version_micro);
|
burn_header_version_micro);
|
||||||
@ -3114,7 +3129,7 @@ struct CdrskiN {
|
|||||||
int gracetime;
|
int gracetime;
|
||||||
int dummy_mode;
|
int dummy_mode;
|
||||||
int force_is_set;
|
int force_is_set;
|
||||||
int stream_recording_is_set;
|
int stream_recording_is_set; /* see burn_write_opts_set_stream_recording() */
|
||||||
int single_track;
|
int single_track;
|
||||||
int prodvd_cli_compatible;
|
int prodvd_cli_compatible;
|
||||||
|
|
||||||
@ -3144,12 +3159,12 @@ struct CdrskiN {
|
|||||||
bit10= format to maximum available size
|
bit10= format to maximum available size
|
||||||
bit11= - reserved -
|
bit11= - reserved -
|
||||||
bit12= - reserved -
|
bit12= - reserved -
|
||||||
bit13= - reserved -
|
bit13= try to disable eventual defect management
|
||||||
bit14= - reserved -
|
bit14= - reserved -
|
||||||
bit15= format by index
|
bit15= format by index
|
||||||
2=deformat_sequential (blank_fast might matter)
|
2=deformat_sequential (blank_fast might matter)
|
||||||
3=format (= format_overwrite restricted to DVD+RW)
|
3=format (= format_overwrite restricted to DVD+RW)
|
||||||
4=format_defectmgt for DVD-RAM, BD-RE
|
4=format_defectmgt for DVD-RAM, BD-R[E]
|
||||||
bit8-15: bit0-7 of burn_disc_format(flag)
|
bit8-15: bit0-7 of burn_disc_format(flag)
|
||||||
bit8 = write zeros after formatting
|
bit8 = write zeros after formatting
|
||||||
bit9+10: size mode
|
bit9+10: size mode
|
||||||
@ -5142,10 +5157,12 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
|||||||
skin->blank_format_type= 1|(1<<8);
|
skin->blank_format_type= 1|(1<<8);
|
||||||
skin->blank_format_size= 128*1024*1024;
|
skin->blank_format_size= 128*1024*1024;
|
||||||
} else if(profile_number == 0x12 ||
|
} else if(profile_number == 0x12 ||
|
||||||
profile_number == 0x43) { /* DVD-RAM , BD-RE */;
|
profile_number == 0x43 ||
|
||||||
|
(profile_number == 0x41 && do_format==6)) {
|
||||||
|
/* DVD-RAM , BD-RE , BD-R SRM */
|
||||||
#ifdef Cdrskin_libburn_has_burn_disc_formaT
|
#ifdef Cdrskin_libburn_has_burn_disc_formaT
|
||||||
ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
|
ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
|
||||||
if(ret>0 && status!=BURN_FORMAT_IS_FORMATTED) {
|
if((ret>0 && status!=BURN_FORMAT_IS_FORMATTED)) {
|
||||||
do_format= 4;
|
do_format= 4;
|
||||||
skin->blank_format_type= 4|(3<<9); /* default payload size */
|
skin->blank_format_type= 4|(3<<9); /* default payload size */
|
||||||
skin->blank_format_size= 0;
|
skin->blank_format_size= 0;
|
||||||
@ -5222,9 +5239,10 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
|||||||
|
|
||||||
} else if(do_format==4) {
|
} else if(do_format==4) {
|
||||||
/* Formatting and influencing defect management of DVD-RAM , BD-RE */
|
/* Formatting and influencing defect management of DVD-RAM , BD-RE */
|
||||||
if(!(profile_number == 0x12 || profile_number == 0x43)) {
|
if(!(profile_number == 0x12 || profile_number == 0x41 ||
|
||||||
|
profile_number == 0x43)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"cdrskin: SORRY : blank=%s for now does DVD-RAM and BD-RE only\n",
|
"cdrskin: SORRY : blank=%s for now does DVD-RAM and BD only\n",
|
||||||
fmt_text);
|
fmt_text);
|
||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
}
|
}
|
||||||
@ -5502,7 +5520,7 @@ thank_you_for_patience:;
|
|||||||
if(skin->is_writing)
|
if(skin->is_writing)
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\rcdrskin: thank you for being patient since %.f seconds ",
|
"\rcdrskin: thank you for being patient for %.f seconds ",
|
||||||
elapsed_total_time);
|
elapsed_total_time);
|
||||||
}
|
}
|
||||||
advance_interval= 1;
|
advance_interval= 1;
|
||||||
@ -5833,10 +5851,12 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
|||||||
profile_number==0x12 ||
|
profile_number==0x12 ||
|
||||||
profile_number==0x11 || profile_number==0x14 ||
|
profile_number==0x11 || profile_number==0x14 ||
|
||||||
profile_number==0x15 ||
|
profile_number==0x15 ||
|
||||||
profile_number==0x1b || profile_number==0x2b)
|
profile_number==0x1b || profile_number==0x2b ||
|
||||||
|
profile_number==0x41 || profile_number==0x43)
|
||||||
&& might_do_tao) {
|
&& might_do_tao) {
|
||||||
/* DVD+RW, DVD-RW Restricted Overwrite, DVD-RAM,
|
/* DVD+RW, DVD-RW Restricted Overwrite, DVD-RAM,
|
||||||
DVD-R[W][/DL] Sequential Recording, DVD+R[/DL] */
|
DVD-R[W][/DL] Sequential Recording, DVD+R[/DL],
|
||||||
|
BD-R SRM , BD-RE */
|
||||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||||
} else {
|
} else {
|
||||||
strcpy(skin->preskin->write_mode_name,"SAO");
|
strcpy(skin->preskin->write_mode_name,"SAO");
|
||||||
@ -6455,7 +6475,7 @@ burn_failed:;
|
|||||||
burn_write_opts_set_force(o, !!skin->force_is_set);
|
burn_write_opts_set_force(o, !!skin->force_is_set);
|
||||||
#endif
|
#endif
|
||||||
#ifdef Cdrskin_libburn_has_stream_recordinG
|
#ifdef Cdrskin_libburn_has_stream_recordinG
|
||||||
burn_write_opts_set_stream_recording(o, !!skin->stream_recording_is_set);
|
burn_write_opts_set_stream_recording(o, skin->stream_recording_is_set);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(skin->dummy_mode) {
|
if(skin->dummy_mode) {
|
||||||
@ -6977,7 +6997,7 @@ sorry_failed_to_eject:;
|
|||||||
int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag)
|
int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag)
|
||||||
{
|
{
|
||||||
int i,k,l,ret,source_has_size=0, idx= -1;
|
int i,k,l,ret,source_has_size=0, idx= -1;
|
||||||
double value,grab_and_wait_value= -1.0;
|
double value,grab_and_wait_value= -1.0, num;
|
||||||
char *cpt,*value_pt,adr[Cdrskin_adrleN],*blank_mode= "";
|
char *cpt,*value_pt,adr[Cdrskin_adrleN],*blank_mode= "";
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
@ -7714,9 +7734,15 @@ set_speed:;
|
|||||||
set_stream_recording:;
|
set_stream_recording:;
|
||||||
if(strcmp(value_pt, "on")==0)
|
if(strcmp(value_pt, "on")==0)
|
||||||
skin->stream_recording_is_set= 1;
|
skin->stream_recording_is_set= 1;
|
||||||
else
|
else if(value_pt[0] >= '0' && value_pt[0] <= '9') {
|
||||||
|
num= Scanf_io_size(value_pt, 0);
|
||||||
|
num/= 2048.0;
|
||||||
|
if(num >= 16 && num <= 0x7FFFFFFF)
|
||||||
|
skin->stream_recording_is_set= num;
|
||||||
|
else
|
||||||
|
skin->stream_recording_is_set= 0;
|
||||||
|
} else
|
||||||
skin->stream_recording_is_set= 0;
|
skin->stream_recording_is_set= 0;
|
||||||
|
|
||||||
} else if(strcmp(argv[i],"-swab")==0) {
|
} else if(strcmp(argv[i],"-swab")==0) {
|
||||||
skin->swap_audio_bytes= 0;
|
skin->swap_audio_bytes= 0;
|
||||||
|
|
||||||
@ -8026,11 +8052,15 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
|
|||||||
printf("cdrskin: scanning for devices ...\n");
|
printf("cdrskin: scanning for devices ...\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
#ifdef Cdrskin_libburn_has_burn_msgS
|
||||||
|
if(skin->preskin->verbosity<Cdrskin_verbose_debuG)
|
||||||
|
burn_msgs_set_severities("NEVER", "NOTE", "cdrskin: ");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* In cdrskin there is not much sense in queueing library messages.
|
/* In cdrskin there is not much sense in queueing library messages.
|
||||||
It is done here only for testing it from time to time */
|
It is done here only for testing it from time to time */
|
||||||
Cdrpreskin_queue_msgs(skin->preskin,1);
|
Cdrpreskin_queue_msgs(skin->preskin,1);
|
||||||
|
|
||||||
|
|
||||||
#ifndef Cdrskin_oldfashioned_api_usE
|
#ifndef Cdrskin_oldfashioned_api_usE
|
||||||
if(stdio_drive) {
|
if(stdio_drive) {
|
||||||
ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr,0);
|
ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr,0);
|
||||||
@ -8051,6 +8081,11 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Cdrskin_libburn_has_burn_msgS
|
||||||
|
burn_msgs_set_severities(skin->preskin->queue_severity,
|
||||||
|
skin->preskin->print_severity, "cdrskin: ");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This prints the eventual queued messages */
|
/* This prints the eventual queued messages */
|
||||||
Cdrpreskin_queue_msgs(skin->preskin,0);
|
Cdrpreskin_queue_msgs(skin->preskin,0);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
|
<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, DVD+R/DL, DVD-RAM, BD-RE, 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">
|
<META NAME="robots" CONTENT="follow">
|
||||||
<TITLE>cdrskin homepage english</TITLE>
|
<TITLE>cdrskin homepage english</TITLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<P>
|
<P>
|
||||||
<H2>Purpose:</H2>
|
<H2>Purpose:</H2>
|
||||||
Burns preformatted data to CD, DVD, and BD media:<BR>
|
Burns preformatted data to CD, DVD, and BD media:<BR>
|
||||||
CD-R, DVD-R, DVD+R, DVD+R/DL, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
CD-R, DVD-R, DVD+R, DVD+R/DL, BD-R, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
||||||
</P>
|
</P>
|
||||||
<P>
|
<P>
|
||||||
|
|
||||||
@ -47,6 +47,8 @@ and to MMC-5 for DVD or BD).
|
|||||||
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
|
<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.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>
|
<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>
|
<DT>libpthread</DT>
|
||||||
<DD>is supposed to be a standard system component.</DD>
|
<DD>is supposed to be a standard system component.</DD>
|
||||||
</DL>
|
</DL>
|
||||||
@ -57,15 +59,18 @@ and to MMC-5 for DVD or BD).
|
|||||||
GPL software included:<BR>
|
GPL software included:<BR>
|
||||||
</H2>
|
</H2>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>libburn-0.4.6</DT>
|
<DT>libburn-0.6.4</DT>
|
||||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||||
furthered by team of libburnia-project.org)</DD>
|
developed and maintained since August 2006 by
|
||||||
<DD>transfers data to CD and DVD</DD>
|
Thomas Schmitt from team of libburnia-project.org)
|
||||||
|
</DD>
|
||||||
|
<DD>transfers data to CD, DVD, BD</DD>
|
||||||
</DL>
|
</DL>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
<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.
|
Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
@ -87,8 +92,8 @@ Ports to other usable systems are appreciated. Reports are welcome.
|
|||||||
are provided in a compatible way.<BR>
|
are provided in a compatible way.<BR>
|
||||||
On all DVD media except DVD-R DL, 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.
|
which is possible with cdrecord.
|
||||||
Other than with cdrecord, options -multi and -tao are supported with
|
Other than with cdrecord, option -multi is supported with many DVD types and
|
||||||
most DVD types and with BD-RE.
|
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW.
|
||||||
</DT>
|
</DT>
|
||||||
<BR><BR>
|
<BR><BR>
|
||||||
<DT>Get an overview of drives and their addresses</DT>
|
<DT>Get an overview of drives and their addresses</DT>
|
||||||
@ -126,23 +131,26 @@ as listed by option --devices.</DT>
|
|||||||
<DD><KBD> blank=as_needed 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[/DL]:</DT>
|
<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 -tao 1.iso</KBD>
|
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi 1.iso</KBD>
|
||||||
</DD>
|
</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>
|
||||||
<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>
|
||||||
<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>
|
<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> c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)</KBD></DD>
|
||||||
<DD>$<KBD> mkisofs ... -C "$c_values" ...</KBD></DD>
|
<DD>$<KBD> mkisofs ... -C "$c_values" ...</KBD></DD>
|
||||||
|
|
||||||
<DT>Inquire free space on media for a -tao -multi run:</DT>
|
<DT>Inquire free space on media for a -multi run:</DT>
|
||||||
<DD>$<KBD> x=$(cdrskin dev=/dev/sr0 -tao -multi \</KBD></DD>
|
<DD>$<KBD> x=$(cdrskin dev=/dev/sr0 -multi \</KBD></DD>
|
||||||
<DD><KBD> --tell_media_space 2>/dev/null)</KBD></DD>
|
<DD><KBD> --tell_media_space 2>/dev/null)</KBD></DD>
|
||||||
<DD>$<KBD> echo "Available: $x blocks of 2048 data bytes"</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>
|
<DT>Write audio tracks to CD:</DT>
|
||||||
<DD>$<KBD> cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
|
<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>
|
<DD><KBD> track1.wav track2.au -audio -swab track3.raw</KBD></DD>
|
||||||
@ -186,8 +194,8 @@ or to do experiments on BD-R media.
|
|||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Download as source code (see README):</DT>
|
<DT>Download as source code (see README):</DT>
|
||||||
<DD><A HREF="cdrskin-0.4.6.pl00.tar.gz">cdrskin-0.4.6.pl00.tar.gz</A>
|
<DD><A HREF="cdrskin-0.6.4.pl00.tar.gz">cdrskin-0.6.4.pl00.tar.gz</A>
|
||||||
(730 KB).
|
(750 KB).
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
The cdrskin tarballs are source code identical with libburn releases
|
The cdrskin tarballs are source code identical with libburn releases
|
||||||
@ -236,43 +244,43 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
|||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
Enhancements towards previous stable version cdrskin-0.4.4.pl00:
|
Enhancements towards previous stable version cdrskin-0.6.2.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Support for BD-RE media is now official</LI>
|
<LI>New operating system adapter "dummy" for stdio on general X/Open systems
|
||||||
<LI>New option stream_recording=on can speed up DVD-RAM and BD-RE</LI>
|
</LI>
|
||||||
<LI>New option --list_formats</LI>
|
<LI>New stream recording mode with start address</LI>
|
||||||
<LI>New blank types for expert formatting of DVD-RAM and BD-RE</LI>
|
<LI></LI>
|
||||||
<LI>New blank type blank=as_needed for automatic handling
|
|
||||||
of media type and state</LI>
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Bug fixes towards cdrskin-0.4.4.pl00:
|
<LI>none</LI>
|
||||||
<UL>
|
|
||||||
<LI>none yet</LI>
|
|
||||||
</UL>
|
|
||||||
-->
|
-->
|
||||||
|
</UL>
|
||||||
|
|
||||||
</P>
|
Bug fixes towards cdrskin-0.6.2.pl00:
|
||||||
|
<UL>
|
||||||
|
<LI>none</LI>
|
||||||
|
<!--
|
||||||
|
<LI>none</LI>
|
||||||
|
-->
|
||||||
|
</UL>
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 0.4.7 :</H3></DT>
|
<DT><H3>Development snapshot, version 0.6.5 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 0.4.6.pl00:
|
<DD>Enhancements towards current stable version 0.6.4.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
-->
|
-->
|
||||||
<LI>none yet</LI>
|
|
||||||
|
|
||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 0.4.7</A>
|
<DD><A HREF="README_cdrskin_devel">README 0.6.5</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.4.7 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin_0.6.5 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.4.7 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin_0.6.5 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.4.7)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.6.5)</A></DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||||
@ -292,8 +300,8 @@ admins with full system souvereignty.</DT>
|
|||||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
<A HREF="cdrskin-0.4.7.tar.gz">cdrskin-0.4.7.tar.gz</A>
|
<A HREF="cdrskin-0.6.5.tar.gz">cdrskin-0.6.5.tar.gz</A>
|
||||||
(730 KB).
|
(750 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<!-- This is not offered any more since spring 2008
|
<!-- This is not offered any more since spring 2008
|
||||||
@ -334,14 +342,33 @@ provide libburn with invaluable examples on how to deal with DVD media.
|
|||||||
<A NAME="examples">
|
<A NAME="examples">
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Example for a setup of device permissions. To be done by the superuser:</DT>
|
<DT>Example for a setup of device permissions.</DT>
|
||||||
<DT>(CD devices which offer no rw-permission are invisible to normal users.)
|
<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>
|
</DT>
|
||||||
<DD># <KBD><B>cdrskin --devices</B></KBD></DD>
|
<DD># <KBD><B>cdrskin --devices</B></KBD></DD>
|
||||||
<DD><KBD>...</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>
|
<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>
|
<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>
|
</DL>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
@ -426,7 +453,7 @@ cdrecord but not vice versa.
|
|||||||
I am a long time user of cdrecord and it works fine for me.
|
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
|
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
|
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>
|
<BR>
|
||||||
But the author of cdrecord and the Linux kernel people foster a very hostile
|
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).
|
relationship. Ok, that's their business, not mine (or ours if you are with me).
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2008.05.14.165258"
|
#define Cdrskin_timestamP "2009.03.13.080001"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
|||||||
debug_opts="-O2"
|
debug_opts="-O2"
|
||||||
def_opts=
|
def_opts=
|
||||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||||
libvers="-DCdrskin_libburn_0_4_7"
|
libvers="-DCdrskin_libburn_0_6_4"
|
||||||
cleanup_src_or_obj="libburn/cleanup.o"
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
@ -33,15 +33,15 @@ do
|
|||||||
libdax_audioxtr_o=
|
libdax_audioxtr_o=
|
||||||
libdax_msgs_o="libburn/message.o"
|
libdax_msgs_o="libburn/message.o"
|
||||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
||||||
elif test "$i" = "-libburn_0_4_6"
|
elif test "$i" = "-libburn_0_6_4"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_4_6"
|
libvers="-DCdrskin_libburn_0_6_4"
|
||||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
cleanup_src_or_obj="libburn/cleanup.o"
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
elif test "$i" = "-libburn_svn"
|
elif test "$i" = "-libburn_svn"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_4_7"
|
libvers="-DCdrskin_libburn_0_6_5"
|
||||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
cleanup_src_or_obj="libburn/cleanup.o"
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
@ -75,10 +75,8 @@ do
|
|||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||||
echo " -compile_dewav compile program test/dewav without libburn."
|
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_6_4 set macro to match libburn-0.6.4"
|
||||||
echo " -libburn_0_4_6 set macro to match libburn-0.4.6."
|
|
||||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
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 " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
echo " -experimental use newly introduced libburn features."
|
echo " -experimental use newly introduced libburn features."
|
||||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
||||||
|
@ -10,8 +10,8 @@ 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.
|
traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way.
|
||||||
Overwriteable media DVD-RAM, DVD+RW, DVD-RW, and BD-RE are handled differently
|
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.
|
than with cdrecord-ProDVD in order to offer TAO-like single track recording.
|
||||||
Sequential DVD-R[W], DVD+R, DVD+R DL are handled like CD-R[W] with TAO and
|
Sequential DVD-R[W], DVD+R, DVD+R DL, BD-R are handled like CD-R[W] with TAO
|
||||||
multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
|
and multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
|
||||||
with DVD-R[W].
|
with DVD-R[W].
|
||||||
|
|
||||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||||
|
43
configure.ac
43
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libburn], [0.4.7], [http://libburnia-project.org])
|
AC_INIT([libburn], [0.6.4], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ AC_CANONICAL_TARGET
|
|||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
|
||||||
dnl Notes by ts A71207 - A80126 :
|
dnl Notes by ts A71207 - A81111 :
|
||||||
dnl
|
dnl
|
||||||
dnl Regrettably the meaning of the various version types was misunderstood
|
dnl Regrettably the meaning of the various version types was misunderstood
|
||||||
dnl before version 0.4.1.
|
dnl before version 0.4.1.
|
||||||
@ -42,7 +42,8 @@ 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 ill SONAME, the value of CURRENT must be larger than AGE.
|
||||||
dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces
|
dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces
|
||||||
dnl
|
dnl
|
||||||
dnl The name of the dynamic library will be libburn.so.$SONAME.$AGE.$REV .
|
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 In the terminology of this file:
|
||||||
dnl CURRENT = LT_CURRENT
|
dnl CURRENT = LT_CURRENT
|
||||||
dnl AGE = LT_AGE
|
dnl AGE = LT_AGE
|
||||||
@ -61,6 +62,15 @@ dnl Neatly versioned stable releases meanwhile:
|
|||||||
dnl 0.4.2 = libburn.so.4.7.0
|
dnl 0.4.2 = libburn.so.4.7.0
|
||||||
dnl 0.4.4 = libburn.so.4.9.0
|
dnl 0.4.4 = libburn.so.4.9.0
|
||||||
dnl 0.4.6 = libburn.so.4.11.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
|
dnl
|
||||||
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
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 SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||||
@ -85,8 +95,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
|||||||
dnl
|
dnl
|
||||||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||||
BURN_MAJOR_VERSION=0
|
BURN_MAJOR_VERSION=0
|
||||||
BURN_MINOR_VERSION=4
|
BURN_MINOR_VERSION=6
|
||||||
BURN_MICRO_VERSION=7
|
BURN_MICRO_VERSION=4
|
||||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(BURN_MAJOR_VERSION)
|
AC_SUBST(BURN_MAJOR_VERSION)
|
||||||
@ -97,15 +107,16 @@ AC_SUBST(BURN_VERSION)
|
|||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
dnl
|
dnl
|
||||||
dnl ts A80510
|
dnl ts A90313
|
||||||
dnl ### This was the release version libburn-0.4.6 = libburn.so.4.11.0
|
dnl This is the release version libburn-0.6.4 = libburn.so.4.29.0
|
||||||
dnl This is the development version after above release version
|
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 not yet happened.
|
||||||
|
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 15 - 11 = 4 . Library name = libburn.so.4.11.0
|
dnl SONAME = 33 - 29 = 4 . Linux library name = libburn.so.4.29.0
|
||||||
LT_CURRENT=15
|
LT_CURRENT=33
|
||||||
|
LT_AGE=29
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_AGE=11
|
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
AC_SUBST(LT_RELEASE)
|
AC_SUBST(LT_RELEASE)
|
||||||
@ -153,6 +164,16 @@ TARGET_SHIZZLE
|
|||||||
AC_SUBST(ARCH)
|
AC_SUBST(ARCH)
|
||||||
AC_SUBST(LIBBURN_ARCH_LIBS)
|
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 Add compiler-specific flags
|
||||||
|
|
||||||
dnl See if the user wants aggressive optimizations of the code
|
dnl See if the user wants aggressive optimizations of the code
|
||||||
|
128
doc/comments
128
doc/comments
@ -1,106 +1,51 @@
|
|||||||
/**
|
/**
|
||||||
@author Mario Danic, Thomas Schmitt
|
@author Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
@mainpage Libburnia Documentation Index
|
@mainpage Libburn Documentation Index
|
||||||
|
|
||||||
@section intro Introduction
|
@section intro Introduction
|
||||||
|
|
||||||
Libburnia is an open-source project for reading, mastering and writing
|
Libburnia is an open-source project for reading, mastering and writing
|
||||||
optical discs.
|
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,
|
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
||||||
DVD-R, BD-RE.
|
DVD-R, BD-R, BD-RE.
|
||||||
|
|
||||||
Not supported yet are DVD-R/DL, HD-DVD, BD-R (blue ray). Testers for
|
Not supported yet are DVD-R/DL. Testers wanted.
|
||||||
DVD-R/DL are wanted, though. BD-R programming efforts would be made
|
|
||||||
if an interested tester contacts us.
|
|
||||||
|
|
||||||
The project comprises of several more or less interdependent parts which
|
Our scope is currently Linux 2.4 and 2.6, or FreeBSD . For ports to other
|
||||||
together strive to be a usable foundation for application development.
|
systems we would need : login on a development machine resp. a live OS on CD
|
||||||
These are libraries, language bindings, and middleware binaries which emulate
|
or DVD, advise from a system person about the equivalent of Linux sg or FreeBSD
|
||||||
classical (and valuable) Linux tools.
|
CAM, volunteers for testing of realistic use cases.
|
||||||
|
|
||||||
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
|
libburn is the library by which preformatted data get onto optical media.
|
||||||
we would need : login on a development machine resp. a live OS on CD or DVD,
|
Its code is independent of cdrecord. Its DVD capabilities are learned from
|
||||||
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
studying the code of dvd+rw-tools and MMC-5 specs. No code but only the pure
|
||||||
volunteers for testing of realistic use cases.
|
SCSI knowledge has been taken from dvd+rw-tools, though.
|
||||||
|
|
||||||
We have a well tested code base for burning data and audio CDs and many DVD
|
cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||||
types. The burn API is quite comprehensively documented and can be used to
|
cdrecord is a powerful GPL'ed burn program included in Joerg Schilling's
|
||||||
build a presentable application.
|
cdrtools. cdrskin strives to be a second source for the services traditionally
|
||||||
We have a functional binary which emulates the core use cases of cdrecord in
|
provided by cdrecord. Additionally it provides libburn's DVD/BD capabilities,
|
||||||
order to prove that usability, and in order to allow you to explore libburn's
|
where only -sao is compatible with cdrecord.
|
||||||
scope by help of existing cdrecord frontends.
|
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.
|
||||||
|
|
||||||
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
The burn API example of libburn is named test/libburner.c . The API for media
|
||||||
and manipulated quite freely. This capability together with our burn capability
|
information inquiry is demonstrated in test/telltoc.c .
|
||||||
makes possible a single binary application which covers all steps of image
|
Explore these examples if you look for inspiration.
|
||||||
composition, updating and writing. Quite unique in the Linux world.
|
|
||||||
|
|
||||||
@subsection components The project components (list subject to growth, hopefully):
|
SONAME:
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
- 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
|
|
||||||
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.
|
|
||||||
|
|
||||||
- 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 deletion, renaming, and attribute
|
|
||||||
changing. An incremental backup feature is provided.
|
|
||||||
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 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),
|
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).
|
|
||||||
|
|
||||||
|
|
||||||
@section using Using the libraries
|
@section using Using libburn
|
||||||
|
|
||||||
Our build system is based on autotools.
|
Our build system is based on autotools.
|
||||||
User experience tells us that you will need at least autotools version 1.7.
|
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
|
To build libburn and its companion applications go into its toplevel directory
|
||||||
its toplevel directory and execute
|
and execute
|
||||||
|
|
||||||
- ./bootstrap (needed if you downloaded from SVN)
|
- ./bootstrap (needed if you downloaded from SVN)
|
||||||
|
|
||||||
@ -112,29 +57,24 @@ To make the libraries accessible for running resp. developing applications
|
|||||||
|
|
||||||
- make install
|
- 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
|
@section libburner Libburner
|
||||||
|
|
||||||
libburner is a minimal demo application for the library libburn
|
libburner is a minimal demo application for the library libburn
|
||||||
(see: libburn/libburn.h) as provided on http://libburnia-project.org .
|
(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
|
It can list the available devices, can burn to recordable CD, DVD, or BD,
|
||||||
can burn to recordable CD and recordable single layer DVD.
|
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
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
to serve the libburnia team as reference application. libburner does indeed
|
to serve the libburnia team as reference application. libburner does indeed
|
||||||
define the standard way how above three gestures can be implemented and
|
define the standard way how above gestures can be implemented and stay upward
|
||||||
stay upward compatible for a good while.
|
compatible for a good while.
|
||||||
|
|
||||||
@subsection libburner-help Libburner --help
|
@subsection libburner-help Libburner --help
|
||||||
<pre>
|
<pre>
|
||||||
Usage: test/libburner
|
Usage: test/libburner
|
||||||
[--drive <address>|<driveno>|"-"] [--audio]
|
[--drive <address>|<driveno>|"-"] [--audio]
|
||||||
[--blank_fast|--blank_full|--format_overwrite]
|
[--blank_fast|--blank_full|--format] [--try_to_simulate]
|
||||||
[--try_to_simulate]
|
|
||||||
[--multi] [<one or more imagefiles>|"-"]
|
[--multi] [<one or more imagefiles>|"-"]
|
||||||
Examples
|
Examples
|
||||||
A bus scan (needs rw-permissions to see a drive):
|
A bus scan (needs rw-permissions to see a drive):
|
||||||
@ -147,8 +87,8 @@ Blank a used CD-RW (is combinable with burning in one run):
|
|||||||
test/libburner --drive /dev/hdc --blank_fast
|
test/libburner --drive /dev/hdc --blank_fast
|
||||||
Blank a used DVD-RW (is combinable with burning in one run):
|
Blank a used DVD-RW (is combinable with burning in one run):
|
||||||
test/libburner --drive /dev/hdc --blank_full
|
test/libburner --drive /dev/hdc --blank_full
|
||||||
Format a DVD-RW to avoid need for blanking before re-use:
|
Format a DVD-RW, BD-RE or BD-R:
|
||||||
test/libburner --drive /dev/hdc --format_overwrite
|
test/libburner --drive /dev/hdc --format
|
||||||
Burn two audio tracks (to CD only):
|
Burn two audio tracks (to CD only):
|
||||||
lame --decode -t /path/to/track1.mp3 track1.cd
|
lame --decode -t /path/to/track1.mp3 track1.cd
|
||||||
test/dewav /path/to/track2.wav -o track2.cd
|
test/dewav /path/to/track2.wav -o track2.cd
|
||||||
|
213
doc/cookbook.txt
213
doc/cookbook.txt
@ -1,4 +1,4 @@
|
|||||||
libburnia-project.org Optical Media Rotisserie Recipes as of April 2008
|
libburnia-project.org Optical Media Rotisserie Recipes as of January 2009
|
||||||
|
|
||||||
Content:
|
Content:
|
||||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||||
@ -6,6 +6,7 @@ Content:
|
|||||||
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE)
|
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE)
|
||||||
- Sequential DVD-R[W] Cookbook
|
- Sequential DVD-R[W] Cookbook
|
||||||
- DVD+R[/DL] Cookbook
|
- DVD+R[/DL] Cookbook
|
||||||
|
- BD-R Cookbook
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
TAO Multi-Session CD Cookbook
|
TAO Multi-Session CD Cookbook
|
||||||
@ -404,7 +405,7 @@ correctness of Pre-gap and Post-gap would become evident.
|
|||||||
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
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/
|
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||||
by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L,
|
by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L,
|
||||||
and by BD-RE experiments done by Giulio Orsero on LG BE06LU10.
|
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>
|
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
@ -432,6 +433,10 @@ The recipes described here are depending on formatting state:
|
|||||||
- DVD-RAM and BD-RE formatting
|
- DVD-RAM and BD-RE formatting
|
||||||
- DVD-RAM and BD-RE speed tuning
|
- 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 :
|
Overwriting in general :
|
||||||
|
|
||||||
@ -522,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.
|
This is the state of previously unused DVD+RW media.
|
||||||
|
|
||||||
@ -693,9 +698,14 @@ managment. There is no way to increase payload capacity by format 01h.
|
|||||||
(mmc5r03c.pdf 6.5.4.2.2.1)
|
(mmc5r03c.pdf 6.5.4.2.2.1)
|
||||||
|
|
||||||
With BD-RE there are three format types : 00h, 30h and 31h.
|
With BD-RE there are three format types : 00h, 30h and 31h.
|
||||||
00h offers the default size format.
|
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
|
30h offers several sizes with defect management. Usually there are three
|
||||||
size to choose: #1: default size, #2: maximum spare area, #3: minimal spare.
|
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
|
31h offers a single size and disables defect management. This has the side
|
||||||
effect to speed up writing to nominal speed.
|
effect to speed up writing to nominal speed.
|
||||||
(mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472)
|
(mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472)
|
||||||
@ -734,7 +744,7 @@ DVD-RAM and BD-RE tuning :
|
|||||||
|
|
||||||
A special aspect of DVD-RAM and BD-RE is their low speed with write operations,
|
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.
|
which usually is only half than the nominal speed of media and drive.
|
||||||
This is blamed to the automatic checkreading which happens ifor managing
|
This is blamed to the automatic checkreading which happens for managing
|
||||||
eventual defects.
|
eventual defects.
|
||||||
|
|
||||||
Defect management of BD-RE can be disabled by format type 31h. See above.
|
Defect management of BD-RE can be disabled by format type 31h. See above.
|
||||||
@ -745,7 +755,7 @@ The only known way to get full speed from DVD-RAM or BD-RE with enabled defect
|
|||||||
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
||||||
(mmc5r03c.pdf 6.45)
|
(mmc5r03c.pdf 6.45)
|
||||||
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
||||||
With the tested BD-RE ione has to write write full 64 kB buffers.
|
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
|
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
|
cumbersome checkread but also to ignore known defects and to write data
|
||||||
@ -756,10 +766,80 @@ incorrectable errors.
|
|||||||
|
|
||||||
Caveat:
|
Caveat:
|
||||||
MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
|
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 0043 promises the existence of
|
None of the features of profiles 0012h and 0043h promises the existence of
|
||||||
AAh WRITE12.
|
AAh WRITE12.
|
||||||
Nevertheless it worked on all tested drives is proper alignment was observed.
|
|
||||||
(mmc5r03c.pdf 5.4.13, 6.45)
|
(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).
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -1199,3 +1279,118 @@ 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
|
# 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.
|
# 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
|
# 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
|
# 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
|
# 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.
|
# 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
|
# 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
|
# 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
|
# If left blank the directory from which doxygen is run is used as the
|
||||||
# path to strip.
|
# 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 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
|
# the path mentioned in the documentation of a class, which tells
|
||||||
|
178
libburn/async.c
178
libburn/async.c
@ -25,9 +25,9 @@
|
|||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "write.h"
|
#include "write.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
#include "file.h"
|
||||||
#include "async.h"
|
#include "async.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "file.h"
|
|
||||||
#include "back_hacks.h"
|
#include "back_hacks.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@ -43,7 +43,15 @@
|
|||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
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 *);
|
typedef void *(*WorkerFunc) (void *);
|
||||||
|
|
||||||
@ -85,6 +93,9 @@ struct fifo_opts
|
|||||||
|
|
||||||
struct w_list
|
struct w_list
|
||||||
{
|
{
|
||||||
|
/* ts A80714 */
|
||||||
|
int w_type; /* see above define Burnworker_type_* */
|
||||||
|
|
||||||
struct burn_drive *drive;
|
struct burn_drive *drive;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
|
|
||||||
@ -113,7 +124,8 @@ static struct w_list *find_worker(struct burn_drive *d)
|
|||||||
return NULL;
|
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 *a;
|
||||||
struct w_list *tmp;
|
struct w_list *tmp;
|
||||||
@ -124,6 +136,7 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
a = malloc(sizeof(struct w_list));
|
a = malloc(sizeof(struct w_list));
|
||||||
|
a->w_type = w_type;
|
||||||
a->drive = d;
|
a->drive = d;
|
||||||
a->u = *(union w_list_data *)data;
|
a->u = *(union w_list_data *)data;
|
||||||
|
|
||||||
@ -259,7 +272,8 @@ drive_is_active:;
|
|||||||
o.drives = drives;
|
o.drives = drives;
|
||||||
o.n_drives = n_drives;
|
o.n_drives = n_drives;
|
||||||
o.done = 0;
|
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) {
|
} else if (workers->u.scan.done) {
|
||||||
/* its done */
|
/* its done */
|
||||||
ret = workers->u.scan.done;
|
ret = workers->u.scan.done;
|
||||||
@ -303,7 +317,7 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
"NULL pointer caught in burn_disc_erase", 0, 0);
|
"NULL pointer caught in burn_disc_erase", 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((SCAN_GOING()) || find_worker(drive)) {
|
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020102,
|
0x00020102,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -343,7 +357,8 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
|
|
||||||
o.drive = drive;
|
o.drive = drive;
|
||||||
o.fast = fast;
|
o.fast = fast;
|
||||||
add_worker(drive, (WorkerFunc) erase_worker_func, &o);
|
add_worker(Burnworker_type_erasE, drive,
|
||||||
|
(WorkerFunc) erase_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -361,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)
|
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
{
|
{
|
||||||
struct format_opts o;
|
struct format_opts o;
|
||||||
int ok = 0;
|
int ok = 0, ret;
|
||||||
char msg[160];
|
char msg[160];
|
||||||
|
|
||||||
if ((SCAN_GOING()) || find_worker(drive)) {
|
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020102,
|
0x00020102,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -394,8 +409,82 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
|||||||
flag |= 4; /* format up to maximum size */
|
flag |= 4; /* format up to maximum size */
|
||||||
} else if (drive->current_profile == 0x12) {
|
} else if (drive->current_profile == 0x12) {
|
||||||
ok = 1; /* DVD-RAM */
|
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) {
|
} else if (drive->current_profile == 0x43) {
|
||||||
ok = 1; /* BD-RE */
|
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) {
|
if (!ok) {
|
||||||
@ -411,7 +500,8 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
|||||||
o.drive = drive;
|
o.drive = drive;
|
||||||
o.size = size;
|
o.size = size;
|
||||||
o.flag = flag;
|
o.flag = flag;
|
||||||
add_worker(drive, (WorkerFunc) format_worker_func, &o);
|
add_worker(Burnworker_type_formaT, drive,
|
||||||
|
(WorkerFunc) format_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -437,12 +527,15 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
{
|
{
|
||||||
struct write_opts o;
|
struct write_opts o;
|
||||||
char reasons[BURN_REASONS_LEN+80];
|
char reasons[BURN_REASONS_LEN+80];
|
||||||
|
struct burn_drive *d;
|
||||||
|
|
||||||
|
d = opts->drive;
|
||||||
|
|
||||||
/* ts A61006 */
|
/* ts A61006 */
|
||||||
/* a ssert(!SCAN_GOING()); */
|
/* a ssert(!SCAN_GOING()); */
|
||||||
/* a ssert(!find_worker(opts->drive)); */
|
/* a ssert(!find_worker(opts->drive)); */
|
||||||
if ((SCAN_GOING()) || find_worker(opts->drive)) {
|
if ((SCAN_GOING()) || find_worker(opts->drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020102,
|
0x00020102,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"A drive operation is still going on (want to write)",
|
"A drive operation is still going on (want to write)",
|
||||||
@ -451,14 +544,14 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* For the next lines any return indicates failure */
|
/* For the next lines any return indicates failure */
|
||||||
opts->drive->cancel = 1;
|
d->cancel = 1;
|
||||||
|
|
||||||
/* ts A70203 : people have been warned in API specs */
|
/* ts A70203 : people have been warned in API specs */
|
||||||
if (opts->write_type == BURN_WRITE_NONE)
|
if (opts->write_type == BURN_WRITE_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (opts->drive->drive_role == 0) {
|
if (d->drive_role == 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020146,
|
0x00020146,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
||||||
@ -466,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() */
|
/* 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) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
opts->drive->global_index, 0x00020113,
|
d->global_index, 0x00020113,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive capabilities not inquired yet", 0, 0);
|
"Drive capabilities not inquired yet", 0, 0);
|
||||||
return;
|
return;
|
||||||
@ -479,28 +572,47 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
*/
|
*/
|
||||||
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
||||||
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
||||||
== BURN_WRITE_NONE) {
|
<= 0) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
opts->drive->global_index, 0x00020139,
|
d->global_index, 0x00020139,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
reasons, 0, 0);
|
reasons, 0, 0);
|
||||||
return;
|
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.opts = opts;
|
||||||
o.disc = disc;
|
o.disc = disc;
|
||||||
|
|
||||||
opts->refcount++;
|
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)
|
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);
|
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -523,12 +635,34 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
|||||||
|
|
||||||
o.source = source;
|
o.source = source;
|
||||||
o.flag = flag;
|
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;
|
fs->is_started = 1;
|
||||||
return 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
|
#ifdef Libburn_has_burn_async_join_alL
|
||||||
|
|
||||||
/* ts A71019 : never used */
|
/* ts A71019 : never used */
|
||||||
|
@ -10,5 +10,9 @@ struct burn_write_opts;
|
|||||||
/* To be called when the first read() call comes to a fifo */
|
/* To be called when the first read() call comes to a fifo */
|
||||||
int burn_fifo_start(struct burn_source *source, int flag);
|
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 */
|
#endif /* BURN__ASYNC_H */
|
||||||
|
@ -97,8 +97,8 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
|||||||
return(2);
|
return(2);
|
||||||
}
|
}
|
||||||
if(cleanup_exiting) {
|
if(cleanup_exiting) {
|
||||||
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
|
fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n",
|
||||||
getpid(),signum);
|
(double) getpid(), signum);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
cleanup_exiting= 1;
|
cleanup_exiting= 1;
|
||||||
|
@ -62,6 +62,7 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
|
|||||||
d->stdio_fd = -1;
|
d->stdio_fd = -1;
|
||||||
d->status = BURN_DISC_UNREADY;
|
d->status = BURN_DISC_UNREADY;
|
||||||
d->do_stream_recording = 0;
|
d->do_stream_recording = 0;
|
||||||
|
d->stream_recording_start= 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +197,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() */
|
/* ts A61125 : media status aspects of burn_drive_grab() */
|
||||||
int burn_drive_inquire_media(struct burn_drive *d)
|
int burn_drive_inquire_media(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
@ -599,7 +625,7 @@ 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;
|
int ret, buf_secs, err, i, stages = 1, pbase, pfill, pseudo_sector;
|
||||||
off_t num_bufs;
|
off_t num_bufs;
|
||||||
char msg[80];
|
char msg[80];
|
||||||
struct buffer buf;
|
struct buffer buf, *buf_mem = d->buffer;
|
||||||
|
|
||||||
/* reset the progress */
|
/* reset the progress */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
@ -681,7 +707,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||||||
ex:;
|
ex:;
|
||||||
d->progress.sector = 0x10000;
|
d->progress.sector = 0x10000;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
d->buffer = NULL;
|
d->buffer = buf_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -767,6 +793,18 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
|||||||
return d->busy;
|
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)
|
void burn_drive_cancel(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&d->access_lock);
|
pthread_mutex_lock(&d->access_lock);
|
||||||
@ -1166,6 +1204,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 */
|
/* ts A70924 */
|
||||||
int burn_drive__fd_from_special_adr(char *adr)
|
int burn_drive__fd_from_special_adr(char *adr)
|
||||||
{
|
{
|
||||||
@ -1705,10 +1757,18 @@ int burn_abort(int patience,
|
|||||||
occup = burn_drive_is_occupied(&(drive_array[i]));
|
occup = burn_drive_is_occupied(&(drive_array[i]));
|
||||||
if(occup == -2)
|
if(occup == -2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
|
/* <<< this causes a race condition with drive usage
|
||||||
|
and drive disposal
|
||||||
|
*/
|
||||||
if(drive_array[i].drive_role != 1) {
|
if(drive_array[i].drive_role != 1) {
|
||||||
drive_array[i].busy = BURN_DRIVE_IDLE;
|
drive_array[i].busy = BURN_DRIVE_IDLE;
|
||||||
burn_drive_forget(&(drive_array[i]), 1);
|
burn_drive_forget(&(drive_array[i]), 1);
|
||||||
} else if(occup <= 10) {
|
} else
|
||||||
|
#endif /* NIX */
|
||||||
|
|
||||||
|
if(occup <= 10) {
|
||||||
burn_drive_forget(&(drive_array[i]), 1);
|
burn_drive_forget(&(drive_array[i]), 1);
|
||||||
} else if(occup <= 100) {
|
} else if(occup <= 100) {
|
||||||
if(first_round)
|
if(first_round)
|
||||||
@ -2207,8 +2267,9 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
o->might_do_sao = 4;
|
o->might_do_sao = 4;
|
||||||
o->might_do_tao = 2;
|
o->might_do_tao = 2;
|
||||||
o->advised_write_mode = BURN_WRITE_TAO;
|
o->advised_write_mode = BURN_WRITE_TAO;
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
||||||
/* DVD+R , DVD+R/DL */
|
d->current_profile == 0x41) {
|
||||||
|
/* DVD+R , DVD+R/DL , BD-R SRM */
|
||||||
o->multi_session = o->multi_track = 1;
|
o->multi_session = o->multi_track = 1;
|
||||||
o->might_do_tao = 2;
|
o->might_do_tao = 2;
|
||||||
o->might_do_sao = 1;
|
o->might_do_sao = 1;
|
||||||
@ -2467,3 +2528,10 @@ int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
|||||||
return 1;
|
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);
|
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 */
|
#endif /* __DRIVE */
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
@ -307,6 +309,7 @@ static void fifo_free(struct burn_source *source)
|
|||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
|
burn_fifo_abort(fs, 0);
|
||||||
if (fs->inp != NULL)
|
if (fs->inp != NULL)
|
||||||
burn_source_free(fs->inp);
|
burn_source_free(fs->inp);
|
||||||
if (fs->buf != NULL)
|
if (fs->buf != NULL)
|
||||||
@ -320,9 +323,12 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
|
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
|
||||||
char *bufpt;
|
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 = getpid();
|
||||||
fs->thread_pid_valid = 1;
|
fs->thread_is_valid = 1;
|
||||||
|
|
||||||
bufsize = fs->chunksize * fs->chunks;
|
bufsize = fs->chunksize * fs->chunks;
|
||||||
while (!fs->end_of_consumption) {
|
while (!fs->end_of_consumption) {
|
||||||
@ -430,6 +436,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
|
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
|
||||||
fs->buf = NULL;
|
fs->buf = NULL;
|
||||||
|
|
||||||
|
fs->thread_handle= NULL;
|
||||||
|
fs->thread_is_valid = 0;
|
||||||
return (fs->input_error == 0);
|
return (fs->input_error == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,8 +473,9 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
|||||||
if (fs == NULL)
|
if (fs == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->is_started = 0;
|
fs->is_started = 0;
|
||||||
|
fs->thread_handle = NULL;
|
||||||
fs->thread_pid = 0;
|
fs->thread_pid = 0;
|
||||||
fs->thread_pid_valid = 0;
|
fs->thread_is_valid = 0;
|
||||||
fs->inp = NULL; /* set later */
|
fs->inp = NULL; /* set later */
|
||||||
fs->chunksize = chunksize;
|
fs->chunksize = chunksize;
|
||||||
fs->chunks = chunks;
|
fs->chunks = chunks;
|
||||||
@ -540,3 +549,64 @@ int burn_fifo_inquire_status(struct burn_source *source,
|
|||||||
return ret;
|
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;
|
int is_started;
|
||||||
|
|
||||||
|
void *thread_handle; /* actually a pointer to a thread_t */
|
||||||
int thread_pid;
|
int thread_pid;
|
||||||
int thread_pid_valid;
|
int thread_is_valid;
|
||||||
|
|
||||||
/* the burn_source for which this fifo is acting as proxy */
|
/* the burn_source for which this fifo is acting as proxy */
|
||||||
struct burn_source *inp;
|
struct burn_source *inp;
|
||||||
|
@ -3,11 +3,15 @@
|
|||||||
#ifndef LIBBURN_H
|
#ifndef LIBBURN_H
|
||||||
#define LIBBURN_H
|
#define LIBBURN_H
|
||||||
|
|
||||||
/* Needed for off_t which is the (POSIX-ly) appropriate type for
|
/*
|
||||||
expressing a file or stream size.
|
|
||||||
|
Applications must use 64 bit off_t. E.g. by defining
|
||||||
|
#define _LARGEFILE_SOURCE
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
or take special precautions to interface with the library by 64 bit integers
|
||||||
|
where this .h files prescribe off_t. Not to use 64 bit file i/o will keep the
|
||||||
|
application from producing and processing ISO images of more than 2 GB size.
|
||||||
|
|
||||||
XXX we should enforce 64-bitness for off_t
|
|
||||||
ts A61101 : this is usually done by the build system (if it is not broken)
|
|
||||||
*/
|
*/
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -183,26 +187,51 @@ enum burn_block_types
|
|||||||
BURN_BLOCK_SAO = 16384
|
BURN_BLOCK_SAO = 16384
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Possible status' of the drive in regard to the disc in it. */
|
/** Possible status of the drive in regard to the disc in it. */
|
||||||
enum burn_disc_status
|
enum burn_disc_status
|
||||||
{
|
{
|
||||||
/** The current status is not yet known */
|
/** The current status is not yet known */
|
||||||
BURN_DISC_UNREADY,
|
BURN_DISC_UNREADY,
|
||||||
/** The drive holds a blank disc */
|
|
||||||
|
/** The drive holds a blank disc. It is ready for writing from scratch.
|
||||||
|
Unused multi-session media:
|
||||||
|
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
||||||
|
Blanked multi-session media (i.e. treated by burn_disc_erase())
|
||||||
|
CD-RW, DVD-RW
|
||||||
|
Overwriteable media with or without valid data
|
||||||
|
DVD-RAM, DVD+RW, formatted DVD-RW, BD-RE
|
||||||
|
*/
|
||||||
BURN_DISC_BLANK,
|
BURN_DISC_BLANK,
|
||||||
|
|
||||||
/** There is no disc at all in the drive */
|
/** There is no disc at all in the drive */
|
||||||
BURN_DISC_EMPTY,
|
BURN_DISC_EMPTY,
|
||||||
/** There is an incomplete disc in the drive */
|
|
||||||
|
/** There is an incomplete disc in the drive. It is ready for appending
|
||||||
|
another session.
|
||||||
|
Written but not yet closed multi-session media
|
||||||
|
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
||||||
|
*/
|
||||||
BURN_DISC_APPENDABLE,
|
BURN_DISC_APPENDABLE,
|
||||||
/** There is a disc with data on it in the drive */
|
|
||||||
|
/** There is a disc with data on it in the drive. It is usable only for
|
||||||
|
reading.
|
||||||
|
Written and closed multi-session media
|
||||||
|
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
||||||
|
Read-Only media
|
||||||
|
CD-ROM, DVD-ROM, BD-ROM
|
||||||
|
Note that many DVD-ROM drives report any written media
|
||||||
|
as Read-Only media and not by their real media types.
|
||||||
|
*/
|
||||||
BURN_DISC_FULL,
|
BURN_DISC_FULL,
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
|
/* @since 0.2.4 */
|
||||||
/** The drive was not grabbed when the status was inquired */
|
/** The drive was not grabbed when the status was inquired */
|
||||||
BURN_DISC_UNGRABBED,
|
BURN_DISC_UNGRABBED,
|
||||||
|
|
||||||
/* ts A61020 */
|
/* ts A61020 */
|
||||||
/** The media seems not to be suitable for burning */
|
/* @since 0.2.6 */
|
||||||
|
/** The media seems to be unsuitable for reading and for writing */
|
||||||
BURN_DISC_UNSUITABLE
|
BURN_DISC_UNSUITABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -242,6 +271,7 @@ enum burn_drive_status
|
|||||||
BURN_DRIVE_GRABBING,
|
BURN_DRIVE_GRABBING,
|
||||||
|
|
||||||
/* ts A61102 */
|
/* ts A61102 */
|
||||||
|
/* @since 0.2.6 */
|
||||||
/** The drive gets written zeroes before the track payload data */
|
/** The drive gets written zeroes before the track payload data */
|
||||||
BURN_DRIVE_WRITING_PREGAP,
|
BURN_DRIVE_WRITING_PREGAP,
|
||||||
/** The drive is told to close a track (TAO only) */
|
/** The drive is told to close a track (TAO only) */
|
||||||
@ -250,10 +280,12 @@ enum burn_drive_status
|
|||||||
BURN_DRIVE_CLOSING_SESSION,
|
BURN_DRIVE_CLOSING_SESSION,
|
||||||
|
|
||||||
/* ts A61223 */
|
/* ts A61223 */
|
||||||
|
/* @since 0.3.0 */
|
||||||
/** The drive is formatting media */
|
/** The drive is formatting media */
|
||||||
BURN_DRIVE_FORMATTING,
|
BURN_DRIVE_FORMATTING,
|
||||||
|
|
||||||
/* ts A70822 */
|
/* ts A70822 */
|
||||||
|
/* @since 0.4.0 */
|
||||||
/** The drive is busy in synchronous read (if you see this then it
|
/** The drive is busy in synchronous read (if you see this then it
|
||||||
has been interrupted) */
|
has been interrupted) */
|
||||||
BURN_DRIVE_READING_SYNC,
|
BURN_DRIVE_READING_SYNC,
|
||||||
@ -301,12 +333,14 @@ struct burn_toc_entry
|
|||||||
|
|
||||||
/* Indicates whether extension data are valid and eventually override
|
/* Indicates whether extension data are valid and eventually override
|
||||||
older elements in this structure:
|
older elements in this structure:
|
||||||
bit0= DVD extension is valid
|
bit0= DVD extension is valid @since 0.3.2
|
||||||
|
@since 0.5.2 : DVD extensions are made valid for CD too
|
||||||
*/
|
*/
|
||||||
unsigned char extensions_valid;
|
unsigned char extensions_valid;
|
||||||
|
|
||||||
/* ts A70201 : DVD extension.
|
/* ts A70201 : DVD extension.
|
||||||
If invalid the members are guaranteed to be 0. */
|
If invalid the members are guaranteed to be 0. */
|
||||||
|
/* @since 0.3.2 */
|
||||||
/* Tracks and session numbers are 16 bit. Here are the high bytes. */
|
/* Tracks and session numbers are 16 bit. Here are the high bytes. */
|
||||||
unsigned char session_msb;
|
unsigned char session_msb;
|
||||||
unsigned char point_msb;
|
unsigned char point_msb;
|
||||||
@ -377,6 +411,13 @@ struct burn_source {
|
|||||||
The size of a sector depends on BURN_MODE_*. The known range is
|
The size of a sector depends on BURN_MODE_*. The known range is
|
||||||
2048 to 2352.
|
2048 to 2352.
|
||||||
|
|
||||||
|
If this call is reading from a pipe then it will learn
|
||||||
|
about the end of data only when that pipe gets closed on the
|
||||||
|
feeder side. So if the track size is not fixed or if the pipe
|
||||||
|
delivers less than the predicted amount or if the size is not
|
||||||
|
block aligned, then burning will halt until the input process
|
||||||
|
closes the pipe.
|
||||||
|
|
||||||
IMPORTANT:
|
IMPORTANT:
|
||||||
If this function pointer is NULL, then the struct burn_source is of
|
If this function pointer is NULL, then the struct burn_source is of
|
||||||
version >= 1 and the job of .(*read)() is done by .(*read_xt)().
|
version >= 1 and the job of .(*read)() is done by .(*read_xt)().
|
||||||
@ -402,6 +443,7 @@ struct burn_source {
|
|||||||
|
|
||||||
|
|
||||||
/* ts A70125 : BROKE BINARY BACKWARD COMPATIBILITY AT libburn-0.3.1. */
|
/* ts A70125 : BROKE BINARY BACKWARD COMPATIBILITY AT libburn-0.3.1. */
|
||||||
|
/* @since 0.3.2 */
|
||||||
/** Program the reply of (*get_size) to a fixed value. It is advised
|
/** Program the reply of (*get_size) to a fixed value. It is advised
|
||||||
to implement this by a attribute off_t fixed_size; in *data .
|
to implement this by a attribute off_t fixed_size; in *data .
|
||||||
The read() function does not have to take into respect this fake
|
The read() function does not have to take into respect this fake
|
||||||
@ -449,7 +491,7 @@ struct burn_source {
|
|||||||
|
|
||||||
|
|
||||||
/* ts A71222 : Supposed to be binary backwards compatible extension. */
|
/* ts A71222 : Supposed to be binary backwards compatible extension. */
|
||||||
|
/* @since 0.4.2 */
|
||||||
/** Valid only if above member .(*read)() is NULL. This indicates a
|
/** Valid only if above member .(*read)() is NULL. This indicates a
|
||||||
version of struct burn_source younger than 0.
|
version of struct burn_source younger than 0.
|
||||||
From then on, member .version tells which further members exist
|
From then on, member .version tells which further members exist
|
||||||
@ -574,12 +616,14 @@ struct burn_progress {
|
|||||||
int sector;
|
int sector;
|
||||||
|
|
||||||
/* ts A61023 */
|
/* ts A61023 */
|
||||||
|
/* @since 0.2.6 */
|
||||||
/** The capacity of the drive buffer */
|
/** The capacity of the drive buffer */
|
||||||
unsigned buffer_capacity;
|
unsigned buffer_capacity;
|
||||||
/** The free space in the drive buffer (might be slightly outdated) */
|
/** The free space in the drive buffer (might be slightly outdated) */
|
||||||
unsigned buffer_available;
|
unsigned buffer_available;
|
||||||
|
|
||||||
/* ts A61119 */
|
/* ts A61119 */
|
||||||
|
/* @since 0.2.6 */
|
||||||
/** The number of bytes sent to the drive buffer */
|
/** The number of bytes sent to the drive buffer */
|
||||||
off_t buffered_bytes;
|
off_t buffered_bytes;
|
||||||
/** The minimum number of bytes stored in buffer during write.
|
/** The minimum number of bytes stored in buffer during write.
|
||||||
@ -591,6 +635,7 @@ struct burn_progress {
|
|||||||
|
|
||||||
|
|
||||||
/* ts A61226 */
|
/* ts A61226 */
|
||||||
|
/* @since 0.3.0 */
|
||||||
/** Description of a speed capability as reported by the drive in conjunction
|
/** Description of a speed capability as reported by the drive in conjunction
|
||||||
with eventually loaded media. There can be more than one such object per
|
with eventually loaded media. There can be more than one such object per
|
||||||
drive. So they are chained via .next and .prev , where NULL marks the end
|
drive. So they are chained via .next and .prev , where NULL marks the end
|
||||||
@ -673,6 +718,7 @@ void burn_finish(void);
|
|||||||
@return 1 ok, all went well
|
@return 1 ok, all went well
|
||||||
0 had to leave a drive in unclean state
|
0 had to leave a drive in unclean state
|
||||||
<0 severe error, do no use libburn again
|
<0 severe error, do no use libburn again
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_abort(int patience,
|
int burn_abort(int patience,
|
||||||
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
@ -722,6 +768,7 @@ void burn_set_verbosity(int level);
|
|||||||
@param abort_on_busy Unconditionally abort process when a non blocking
|
@param abort_on_busy Unconditionally abort process when a non blocking
|
||||||
exclusive opening attempt indicates a busy drive.
|
exclusive opening attempt indicates a busy drive.
|
||||||
Use this only after thorough tests with your app.
|
Use this only after thorough tests with your app.
|
||||||
|
@since 0.2.2
|
||||||
*/
|
*/
|
||||||
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
|
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
|
||||||
|
|
||||||
@ -735,6 +782,7 @@ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
|
|||||||
If ever then this call should be done soon after burn_initialize() before
|
If ever then this call should be done soon after burn_initialize() before
|
||||||
any drive scanning.
|
any drive scanning.
|
||||||
@param yes 1=allow all implemented profiles, 0=only tested media (default)
|
@param yes 1=allow all implemented profiles, 0=only tested media (default)
|
||||||
|
@since 0.3.4
|
||||||
*/
|
*/
|
||||||
void burn_allow_untested_profiles(int yes);
|
void burn_allow_untested_profiles(int yes);
|
||||||
|
|
||||||
@ -799,7 +847,8 @@ void burn_allow_untested_profiles(int yes);
|
|||||||
If the path does not exist in the filesystem yet, it is attempted to create
|
If the path does not exist in the filesystem yet, it is attempted to create
|
||||||
it as a regular file as soon as write operations are started.
|
it as a regular file as soon as write operations are started.
|
||||||
|
|
||||||
The capabilities of role 3 resemble a blank DVD-R.
|
The capabilities of role 3 resemble a blank DVD-R. Nevertheless each
|
||||||
|
burn_disc_write() run may only write a single track.
|
||||||
|
|
||||||
One may distinguish pseudo-drives from MMC drives by call
|
One may distinguish pseudo-drives from MMC drives by call
|
||||||
burn_drive_get_drive_role().
|
burn_drive_get_drive_role().
|
||||||
@ -818,17 +867,21 @@ void burn_allow_untested_profiles(int yes);
|
|||||||
@param load Nonzero to make the drive attempt to load a disc (close its
|
@param load Nonzero to make the drive attempt to load a disc (close its
|
||||||
tray door, etc).
|
tray door, etc).
|
||||||
@return 1 = success , 0 = drive not found , -1 = other error
|
@return 1 = success , 0 = drive not found , -1 = other error
|
||||||
|
@since 0.2.2
|
||||||
*/
|
*/
|
||||||
int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[],
|
int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[],
|
||||||
char* adr, int load);
|
char* adr, int load);
|
||||||
|
|
||||||
|
|
||||||
/* ts A51221 */
|
/* ts A51221 */
|
||||||
|
/* @since 0.2.2 */
|
||||||
/** Maximum number of particularly permissible drive addresses */
|
/** Maximum number of particularly permissible drive addresses */
|
||||||
#define BURN_DRIVE_WHITELIST_LEN 255
|
#define BURN_DRIVE_WHITELIST_LEN 255
|
||||||
|
|
||||||
/** Add a device to the list of permissible drives. As soon as some entry is in
|
/** Add a device to the list of permissible drives. As soon as some entry is in
|
||||||
the whitelist all non-listed drives are banned from scanning.
|
the whitelist all non-listed drives are banned from scanning.
|
||||||
@return 1 success, <=0 failure
|
@return 1 success, <=0 failure
|
||||||
|
@since 0.2.2
|
||||||
*/
|
*/
|
||||||
int burn_drive_add_whitelist(char *device_address);
|
int burn_drive_add_whitelist(char *device_address);
|
||||||
|
|
||||||
@ -875,6 +928,7 @@ int burn_drive_scan(struct burn_drive_info *drive_infos[],
|
|||||||
Use these two only. Further values are to be defined.
|
Use these two only. Further values are to be defined.
|
||||||
@return 1 on success, 2 if drive was already forgotten,
|
@return 1 on success, 2 if drive was already forgotten,
|
||||||
0 if not permissible, <0 on other failures,
|
0 if not permissible, <0 on other failures,
|
||||||
|
@since 0.2.2
|
||||||
*/
|
*/
|
||||||
int burn_drive_info_forget(struct burn_drive_info *drive_info, int force);
|
int burn_drive_info_forget(struct burn_drive_info *drive_info, int force);
|
||||||
|
|
||||||
@ -887,23 +941,28 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[]);
|
|||||||
|
|
||||||
|
|
||||||
/* ts A60823 */
|
/* ts A60823 */
|
||||||
|
/* @since 0.2.2 */
|
||||||
/** Maximum length+1 to expect with a persistent drive address string */
|
/** Maximum length+1 to expect with a persistent drive address string */
|
||||||
#define BURN_DRIVE_ADR_LEN 1024
|
#define BURN_DRIVE_ADR_LEN 1024
|
||||||
|
|
||||||
|
/* ts A70906 */
|
||||||
/** Inquire the persistent address of the given drive.
|
/** Inquire the persistent address of the given drive.
|
||||||
@param drive The drive to inquire.
|
@param drive The drive to inquire.
|
||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The persistent address gets copied to it.
|
||||||
@return >0 success , <=0 error (due to libburn internal problem)
|
@return >0 success , <=0 error (due to libburn internal problem)
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]);
|
int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]);
|
||||||
|
|
||||||
|
/* A60823 */
|
||||||
/** Inquire the persistent address of a drive via a given drive_info object.
|
/** Inquire the persistent address of a drive via a given drive_info object.
|
||||||
(Note: This is a legacy call.)
|
(Note: This is a legacy call.)
|
||||||
@param drive_info The drive to inquire.Usually some &(drive_infos[driveno])
|
@param drive_info The drive to inquire.Usually some &(drive_infos[driveno])
|
||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The persistent address gets copied to it.
|
||||||
@return >0 success , <=0 error (due to libburn internal problem)
|
@return >0 success , <=0 error (due to libburn internal problem)
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]);
|
int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]);
|
||||||
|
|
||||||
@ -912,6 +971,7 @@ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]);
|
|||||||
/** Evaluate whether the given address would be a possible persistent drive
|
/** Evaluate whether the given address would be a possible persistent drive
|
||||||
address of libburn.
|
address of libburn.
|
||||||
@return 1 means yes, 0 means no
|
@return 1 means yes, 0 means no
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_is_enumerable_adr(char *adr);
|
int burn_drive_is_enumerable_adr(char *adr);
|
||||||
|
|
||||||
@ -924,6 +984,7 @@ int burn_drive_is_enumerable_adr(char *adr);
|
|||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The persistent address gets copied to it.
|
||||||
@return 1 = success , 0 = failure , -1 = severe error
|
@return 1 = success , 0 = failure , -1 = severe error
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_convert_fs_adr(char *path, char adr[]);
|
int burn_drive_convert_fs_adr(char *path, char adr[]);
|
||||||
|
|
||||||
@ -941,6 +1002,7 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
|
|||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The persistent address gets copied to it.
|
||||||
@return 1 = success , 0 = failure , -1 = severe error
|
@return 1 = success , 0 = failure , -1 = severe error
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
|
int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
|
||||||
int target_no, int lun_no, char adr[]);
|
int target_no, int lun_no, char adr[]);
|
||||||
@ -951,6 +1013,7 @@ int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
|
|||||||
drive address obtained via burn_drive_d_get_adr(). It is also supposed to
|
drive address obtained via burn_drive_d_get_adr(). It is also supposed to
|
||||||
succeed with any device file of a (possibly emulated) SCSI device.
|
succeed with any device file of a (possibly emulated) SCSI device.
|
||||||
@return 1 = success , 0 = failure , -1 = severe error
|
@return 1 = success , 0 = failure , -1 = severe error
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no,
|
int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no,
|
||||||
int *channel_no, int *target_no, int *lun_no);
|
int *channel_no, int *target_no, int *lun_no);
|
||||||
@ -983,6 +1046,7 @@ void burn_drive_release(struct burn_drive *drive, int eject);
|
|||||||
@param drive The drive to release and leave locked.
|
@param drive The drive to release and leave locked.
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
@return 1 means success, <=0 means failure
|
@return 1 means success, <=0 means failure
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_leave_locked(struct burn_drive *d, int flag);
|
int burn_drive_leave_locked(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
@ -1003,6 +1067,7 @@ enum burn_disc_status burn_disc_get_status(struct burn_drive *drive);
|
|||||||
or BURN_DISC_UNSUITABLE. Thus marking media as writable which actually
|
or BURN_DISC_UNSUITABLE. Thus marking media as writable which actually
|
||||||
failed to declare themselves either blank or (partially) filled.
|
failed to declare themselves either blank or (partially) filled.
|
||||||
@return 1 drive status has been set , 0 = unsuitable drive status
|
@return 1 drive status has been set , 0 = unsuitable drive status
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_disc_pretend_blank(struct burn_drive *drive);
|
int burn_disc_pretend_blank(struct burn_drive *drive);
|
||||||
|
|
||||||
@ -1012,6 +1077,7 @@ int burn_disc_pretend_blank(struct burn_drive *drive);
|
|||||||
Sets the drive status to BURN_DISC_FULL if it is BURN_DISC_UNREADY
|
Sets the drive status to BURN_DISC_FULL if it is BURN_DISC_UNREADY
|
||||||
or BURN_DISC_UNSUITABLE. Thus marking media as blankable which actually
|
or BURN_DISC_UNSUITABLE. Thus marking media as blankable which actually
|
||||||
failed to declare themselves either blank or (partially) filled.
|
failed to declare themselves either blank or (partially) filled.
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_disc_pretend_full(struct burn_drive *drive);
|
int burn_disc_pretend_full(struct burn_drive *drive);
|
||||||
|
|
||||||
@ -1022,6 +1088,7 @@ int burn_disc_pretend_full(struct burn_drive *drive);
|
|||||||
burn_drive_get_start_end_lba(). The drive must be grabbed for this call.
|
burn_drive_get_start_end_lba(). The drive must be grabbed for this call.
|
||||||
@param drive The drive to query.
|
@param drive The drive to query.
|
||||||
@return 1=sucess, 0=no valid ATIP info read, -1 severe error
|
@return 1=sucess, 0=no valid ATIP info read, -1 severe error
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_disc_read_atip(struct burn_drive *drive);
|
int burn_disc_read_atip(struct burn_drive *drive);
|
||||||
|
|
||||||
@ -1036,6 +1103,7 @@ int burn_disc_read_atip(struct burn_drive *drive);
|
|||||||
@param end_lba Returns the end lba value
|
@param end_lba Returns the end lba value
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
@return 1 if lba values are valid , 0 if invalid
|
@return 1 if lba values are valid , 0 if invalid
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_start_end_lba(struct burn_drive *drive,
|
int burn_drive_get_start_end_lba(struct burn_drive *drive,
|
||||||
int *start_lba, int *end_lba, int flag);
|
int *start_lba, int *end_lba, int flag);
|
||||||
@ -1053,6 +1121,7 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive,
|
|||||||
@param lba return value: start lba
|
@param lba return value: start lba
|
||||||
@param nwa return value: Next Writeable Address
|
@param nwa return value: Next Writeable Address
|
||||||
@return 1=nwa is valid , 0=nwa is not valid , -1=error
|
@return 1=nwa is valid , 0=nwa is not valid , -1=error
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||||
int trackno, int *lba, int *nwa);
|
int trackno, int *lba, int *nwa);
|
||||||
@ -1064,6 +1133,7 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
|||||||
@param d The drive to query.
|
@param d The drive to query.
|
||||||
@param start_lba returns the start address of that track
|
@param start_lba returns the start address of that track
|
||||||
@return <= 0 : failure, 1 = ok
|
@return <= 0 : failure, 1 = ok
|
||||||
|
@since 0.3.2
|
||||||
*/
|
*/
|
||||||
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
||||||
|
|
||||||
@ -1080,6 +1150,7 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
|||||||
@param d The drive to query.
|
@param d The drive to query.
|
||||||
@param o If not NULL: write parameters to be set on drive before query
|
@param o If not NULL: write parameters to be set on drive before query
|
||||||
@return number of most probably available free bytes
|
@return number of most probably available free bytes
|
||||||
|
@since 0.3.4
|
||||||
*/
|
*/
|
||||||
off_t burn_disc_available_space(struct burn_drive *d,
|
off_t burn_disc_available_space(struct burn_drive *d,
|
||||||
struct burn_write_opts *o);
|
struct burn_write_opts *o);
|
||||||
@ -1093,7 +1164,8 @@ off_t burn_disc_available_space(struct burn_drive *d,
|
|||||||
0x11 "DVD-R sequential recording", 0x12 "DVD-RAM",
|
0x11 "DVD-R sequential recording", 0x12 "DVD-RAM",
|
||||||
0x13 "DVD-RW restricted overwrite", 0x14 "DVD-RW sequential recording",
|
0x13 "DVD-RW restricted overwrite", 0x14 "DVD-RW sequential recording",
|
||||||
0x1a "DVD+RW", 0x1b "DVD+R",
|
0x1a "DVD+RW", 0x1b "DVD+R",
|
||||||
0x2b "DVD+R/DL", 0x43 "BD-RE",
|
0x2b "DVD+R/DL",
|
||||||
|
0x41 "BD-R sequential recording", 0x43 "BD-RE",
|
||||||
0xffff "stdio file"
|
0xffff "stdio file"
|
||||||
Note: 0xffff is not a MMC profile but a libburn invention.
|
Note: 0xffff is not a MMC profile but a libburn invention.
|
||||||
If enabled by burn_allow_untested_profiles() it also writes to profiles
|
If enabled by burn_allow_untested_profiles() it also writes to profiles
|
||||||
@ -1101,12 +1173,13 @@ off_t burn_disc_available_space(struct burn_drive *d,
|
|||||||
Read-only are the profiles
|
Read-only are the profiles
|
||||||
0x08 "CD-ROM", 0x10 "DVD-ROM",
|
0x08 "CD-ROM", 0x10 "DVD-ROM",
|
||||||
0x40 "BD-ROM",
|
0x40 "BD-ROM",
|
||||||
For now read-only are BD-R profiles (testers wanted)
|
For now read-only is BD-R profile (testers wanted)
|
||||||
0x41 "BD-R sequential recording", 0x42 "BD-R random recording"
|
0x42 "BD-R random recording"
|
||||||
@param d The drive where the media is inserted.
|
@param d The drive where the media is inserted.
|
||||||
@param pno Profile Number. See also mmc5r03c.pdf, table 89
|
@param pno Profile Number. See also mmc5r03c.pdf, table 89
|
||||||
@param name Profile Name (see above list, unknown profiles have empty name)
|
@param name Profile Name (see above list, unknown profiles have empty name)
|
||||||
@return 1 profile is valid, 0 no profile info available
|
@return 1 profile is valid, 0 no profile info available
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]);
|
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]);
|
||||||
|
|
||||||
@ -1124,8 +1197,8 @@ int burn_disc_erasable(struct burn_drive *d);
|
|||||||
enum burn_drive_status burn_drive_get_status(struct burn_drive *drive,
|
enum burn_drive_status burn_drive_get_status(struct burn_drive *drive,
|
||||||
struct burn_progress *p);
|
struct burn_progress *p);
|
||||||
|
|
||||||
/** Creates a write_opts struct for burning to the specified drive
|
/** Creates a write_opts struct for burning to the specified drive.
|
||||||
must be freed with burn_write_opts_free
|
The returned object must later be freed with burn_write_opts_free().
|
||||||
@param drive The drive to write with
|
@param drive The drive to write with
|
||||||
@return The write_opts, NULL on error
|
@return The write_opts, NULL on error
|
||||||
*/
|
*/
|
||||||
@ -1136,6 +1209,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive);
|
|||||||
/** Inquires the drive associated with a burn_write_opts object.
|
/** Inquires the drive associated with a burn_write_opts object.
|
||||||
@param opts object to inquire
|
@param opts object to inquire
|
||||||
@return pointer to drive
|
@return pointer to drive
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts);
|
struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts);
|
||||||
|
|
||||||
@ -1174,7 +1248,8 @@ void burn_disc_erase(struct burn_drive *drive, int fast);
|
|||||||
/** Format media for use with libburn. This currently applies to DVD-RW
|
/** Format media for use with libburn. This currently applies to DVD-RW
|
||||||
in state "Sequential Recording" (profile 0014h) which get formatted to
|
in state "Sequential Recording" (profile 0014h) which get formatted to
|
||||||
state "Restricted Overwrite" (profile 0013h). DVD+RW can be "de-iced"
|
state "Restricted Overwrite" (profile 0013h). DVD+RW can be "de-iced"
|
||||||
by setting bit2 of flag. Other media cannot be formatted yet.
|
by setting bit2 of flag. DVD-RAM and BD-RE may get formatted initially
|
||||||
|
or re-formatted to adjust their Defect Managment.
|
||||||
This function usually returns while the drive is still in the process
|
This function usually returns while the drive is still in the process
|
||||||
of formatting. The formatting is done, when burn_drive_get_status()
|
of formatting. The formatting is done, when burn_drive_get_status()
|
||||||
returns BURN_DRIVE_IDLE. This may be immediately after return or may
|
returns BURN_DRIVE_IDLE. This may be immediately after return or may
|
||||||
@ -1189,7 +1264,8 @@ void burn_disc_erase(struct burn_drive *drive, int fast);
|
|||||||
bit1+2: size mode
|
bit1+2: size mode
|
||||||
0 = use parameter size as far as it makes sense
|
0 = use parameter size as far as it makes sense
|
||||||
1 = insist in size 0 even if there is a better default known
|
1 = insist in size 0 even if there is a better default known
|
||||||
(on DVD-RAM or BD-RE identical to size mode 0)
|
(on DVD-RAM or BD-R identical to size mode 0,
|
||||||
|
i.e. they never get formatted with payload size 0)
|
||||||
2 = without bit7: format to maximum available size
|
2 = without bit7: format to maximum available size
|
||||||
with bit7 : take size from indexed format descriptor
|
with bit7 : take size from indexed format descriptor
|
||||||
3 = without bit7: format to default size
|
3 = without bit7: format to default size
|
||||||
@ -1198,23 +1274,29 @@ void burn_disc_erase(struct burn_drive *drive, int fast);
|
|||||||
bit4= enforce re-format of (partly) formatted media
|
bit4= enforce re-format of (partly) formatted media
|
||||||
bit5= try to disable eventual defect management
|
bit5= try to disable eventual defect management
|
||||||
bit6= try to avoid lengthy media certification
|
bit6= try to avoid lengthy media certification
|
||||||
bit7= MMC expert application mode (else libburn tries to
|
bit7, bit8 to bit15 =
|
||||||
choose a suitable format type):
|
bit7 enables MMC expert application mode (else libburn
|
||||||
bit8 to bit15 contain the index of the format to use. See
|
tries to choose a suitable format type):
|
||||||
burn_disc_get_formats(), burn_disc_get_format_descr().
|
If it is set then bit8 to bit15 contain the index of
|
||||||
|
the format to use. See burn_disc_get_formats(),
|
||||||
|
burn_disc_get_format_descr().
|
||||||
Acceptable types are: 0x00, 0x01, 0x10, 0x11, 0x13,
|
Acceptable types are: 0x00, 0x01, 0x10, 0x11, 0x13,
|
||||||
0x15, 0x26, 0x30, 0x31.
|
0x15, 0x26, 0x30, 0x31, 0x32.
|
||||||
If bit7 is set, bit4 is set automatically.
|
If bit7 is set, then bit4 is set automatically.
|
||||||
|
bit16= enable POW on blank BD-R
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
void burn_disc_format(struct burn_drive *drive, off_t size, int flag);
|
void burn_disc_format(struct burn_drive *drive, off_t size, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70112 */
|
/* ts A70112 */
|
||||||
|
/* @since 0.3.0 */
|
||||||
/** Possible formatting status values */
|
/** Possible formatting status values */
|
||||||
#define BURN_FORMAT_IS_UNFORMATTED 1
|
#define BURN_FORMAT_IS_UNFORMATTED 1
|
||||||
#define BURN_FORMAT_IS_FORMATTED 2
|
#define BURN_FORMAT_IS_FORMATTED 2
|
||||||
#define BURN_FORMAT_IS_UNKNOWN 3
|
#define BURN_FORMAT_IS_UNKNOWN 3
|
||||||
|
|
||||||
|
/* ts A70112 */
|
||||||
/** Inquire the formatting status, the associated sizes and the number of
|
/** Inquire the formatting status, the associated sizes and the number of
|
||||||
available formats. The info is media specific and stems from MMC command
|
available formats. The info is media specific and stems from MMC command
|
||||||
23h READ FORMAT CAPACITY. See mmc5r03c.pdf 6.24 for background details.
|
23h READ FORMAT CAPACITY. See mmc5r03c.pdf 6.24 for background details.
|
||||||
@ -1233,10 +1315,12 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag);
|
|||||||
burn_disc_get_format_descr() to obtain such a format
|
burn_disc_get_format_descr() to obtain such a format
|
||||||
and eventually with burn_disc_format() to select one.
|
and eventually with burn_disc_format() to select one.
|
||||||
@return 1 reply is valid , <=0 failure
|
@return 1 reply is valid , <=0 failure
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
int burn_disc_get_formats(struct burn_drive *drive, int *status, off_t *size,
|
int burn_disc_get_formats(struct burn_drive *drive, int *status, off_t *size,
|
||||||
unsigned *bl_sas, int *num_formats);
|
unsigned *bl_sas, int *num_formats);
|
||||||
|
|
||||||
|
/* ts A70112 */
|
||||||
/** Inquire parameters of an available media format.
|
/** Inquire parameters of an available media format.
|
||||||
@param drive The drive with the disc to format.
|
@param drive The drive with the disc to format.
|
||||||
@param index The index of the format item. Beginning with 0 up to reply
|
@param index The index of the format item. Beginning with 0 up to reply
|
||||||
@ -1249,6 +1333,7 @@ int burn_disc_get_formats(struct burn_drive *drive, int *status, off_t *size,
|
|||||||
@param size The maximum size in bytes achievable with this format.
|
@param size The maximum size in bytes achievable with this format.
|
||||||
@param tdp Type Dependent Parameter. See mmc5r03c.pdf.
|
@param tdp Type Dependent Parameter. See mmc5r03c.pdf.
|
||||||
@return 1 reply is valid , <=0 failure
|
@return 1 reply is valid , <=0 failure
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
int burn_disc_get_format_descr(struct burn_drive *drive, int index,
|
int burn_disc_get_format_descr(struct burn_drive *drive, int index,
|
||||||
int *type, off_t *size, unsigned *tdp);
|
int *type, off_t *size, unsigned *tdp);
|
||||||
@ -1267,6 +1352,7 @@ void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
|
|||||||
|
|
||||||
|
|
||||||
/* ts A70222 */
|
/* ts A70222 */
|
||||||
|
/* @since 0.3.4 */
|
||||||
/** The length of a rejection reasons string for burn_precheck_write() and
|
/** The length of a rejection reasons string for burn_precheck_write() and
|
||||||
burn_write_opts_auto_write_type() .
|
burn_write_opts_auto_write_type() .
|
||||||
*/
|
*/
|
||||||
@ -1282,6 +1368,7 @@ void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
|
|||||||
@param reasons Eventually returns a list of rejection reason statements
|
@param reasons Eventually returns a list of rejection reason statements
|
||||||
@param silent 1= do not issue error messages , 0= report problems
|
@param silent 1= do not issue error messages , 0= report problems
|
||||||
@return 1 ok, -1= no recordable media detected, 0= other failure
|
@return 1 ok, -1= no recordable media detected, 0= other failure
|
||||||
|
@since 0.3.4
|
||||||
*/
|
*/
|
||||||
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
||||||
char reasons[BURN_REASONS_LEN], int silent);
|
char reasons[BURN_REASONS_LEN], int silent);
|
||||||
@ -1301,6 +1388,28 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|||||||
*/
|
*/
|
||||||
void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc);
|
void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90227 */
|
||||||
|
/** Control stream recording during the write run and eventually set the start
|
||||||
|
LBA for stream recording.
|
||||||
|
Stream recording is set from struct burn_write_opts when the write run
|
||||||
|
gets started. See burn_write_opts_set_stream_recording().
|
||||||
|
The call described here can be used later to override this setting and
|
||||||
|
to program automatic switching at a given LBA. It also affects subsequent
|
||||||
|
calls to burn_random_access_write().
|
||||||
|
@param drive The drive which performs the write operation.
|
||||||
|
@param recmode -1= disable stream recording
|
||||||
|
0= leave setting as is
|
||||||
|
1= enable stream recording
|
||||||
|
@param start The LBA where actual stream recording shall start.
|
||||||
|
(0 means unconditional stream recording)
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||||
|
@return 1=success , <=0 failure
|
||||||
|
@since 0.6.4
|
||||||
|
*/
|
||||||
|
int burn_drive_set_stream_recording(struct burn_drive *drive, int recmode,
|
||||||
|
int start, int flag);
|
||||||
|
|
||||||
/** Cancel an operation on a drive.
|
/** Cancel an operation on a drive.
|
||||||
This will only work when the drive's busy state is BURN_DRIVE_READING or
|
This will only work when the drive's busy state is BURN_DRIVE_READING or
|
||||||
BURN_DRIVE_WRITING.
|
BURN_DRIVE_WRITING.
|
||||||
@ -1315,6 +1424,7 @@ void burn_drive_cancel(struct burn_drive *drive);
|
|||||||
during write, a call to burn_drive_cancel() by the application thread.
|
during write, a call to burn_drive_cancel() by the application thread.
|
||||||
@param d The drive to inquire.
|
@param d The drive to inquire.
|
||||||
@return 1=burn seems to have went well, 0=burn failed
|
@return 1=burn seems to have went well, 0=burn failed
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_wrote_well(struct burn_drive *d);
|
int burn_drive_wrote_well(struct burn_drive *d);
|
||||||
|
|
||||||
@ -1431,6 +1541,7 @@ void burn_track_define_data(struct burn_track *t, int offset, int tail,
|
|||||||
@param t The track to change
|
@param t The track to change
|
||||||
@param swap_source_bytes 0=do not swap, 1=swap byte pairs
|
@param swap_source_bytes 0=do not swap, 1=swap byte pairs
|
||||||
@return 1=success , 0=unacceptable value
|
@return 1=success , 0=unacceptable value
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
|
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
|
||||||
|
|
||||||
@ -1484,6 +1595,7 @@ enum burn_source_status burn_track_set_source(struct burn_track *t,
|
|||||||
@param t The track to change
|
@param t The track to change
|
||||||
@param size The size to set
|
@param size The size to set
|
||||||
@return 0=failure 1=sucess
|
@return 0=failure 1=sucess
|
||||||
|
@since 0.3.4
|
||||||
*/
|
*/
|
||||||
int burn_track_set_default_size(struct burn_track *t, off_t size);
|
int burn_track_set_default_size(struct burn_track *t, off_t size);
|
||||||
|
|
||||||
@ -1543,6 +1655,7 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
|
|||||||
to be disposed by calling burn_source_free() for each.
|
to be disposed by calling burn_source_free() for each.
|
||||||
inp can be freed immediately, the returned fifo may be
|
inp can be freed immediately, the returned fifo may be
|
||||||
kept as handle for burn_fifo_inquire_status().
|
kept as handle for burn_fifo_inquire_status().
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||||
int chunksize, int chunks, int flag);
|
int chunksize, int chunks, int flag);
|
||||||
@ -1564,17 +1677,43 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
|||||||
5="abandoned" : consumption has ended prematurely
|
5="abandoned" : consumption has ended prematurely
|
||||||
6="ended" : consumption has ended without input error
|
6="ended" : consumption has ended without input error
|
||||||
7="aborted" : consumption has ended after input error
|
7="aborted" : consumption has ended after input error
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
|
int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
|
||||||
int *free_bytes, char **status_text);
|
int *free_bytes, char **status_text);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80713 */
|
||||||
|
/** Obtain a preview of the first input data of a fifo which was created
|
||||||
|
by burn_fifo_source_new(). The data will later be delivered normally to
|
||||||
|
the consumer track of the fifo.
|
||||||
|
bufsize may not be larger than the fifo size (chunk_size * chunks).
|
||||||
|
This call will succeed only if data consumption by the track has not
|
||||||
|
started yet, i.e. best before the call to burn_disc_write().
|
||||||
|
It will start the worker thread of the fifo with the expectable side
|
||||||
|
effects on the external data source. Then it waits either until enough
|
||||||
|
data have arrived or until it becomes clear that this will not happen.
|
||||||
|
The call may be repeated with increased bufsize. It will always yield
|
||||||
|
the bytes beginning from the first one in the fifo.
|
||||||
|
@param fifo The fifo object to inquire
|
||||||
|
@param buf Pointer to memory of at least bufsize bytes where to
|
||||||
|
deliver the peeked data
|
||||||
|
@param bufsize Number of bytes to peek from the start of the fifo data
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||||
|
@return <0 on severe error, 0 if not enough data, 1 if bufsize bytes read
|
||||||
|
@since 0.5.0
|
||||||
|
*/
|
||||||
|
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70328 */
|
/* ts A70328 */
|
||||||
/** Sets a fixed track size after the data source object has already been
|
/** Sets a fixed track size after the data source object has already been
|
||||||
created.
|
created.
|
||||||
@param t The track to operate on
|
@param t The track to operate on
|
||||||
@param size the number of bytes to use as track size
|
@param size the number of bytes to use as track size
|
||||||
@return <=0 indicates failure , >0 success
|
@return <=0 indicates failure , >0 success
|
||||||
|
@since 0.3.6
|
||||||
*/
|
*/
|
||||||
int burn_track_set_size(struct burn_track *t, off_t size);
|
int burn_track_set_size(struct burn_track *t, off_t size);
|
||||||
|
|
||||||
@ -1587,7 +1726,12 @@ int burn_track_get_sectors(struct burn_track *);
|
|||||||
|
|
||||||
/* ts A61101 */
|
/* ts A61101 */
|
||||||
/** Tells how many source bytes have been read and how many data bytes have
|
/** Tells how many source bytes have been read and how many data bytes have
|
||||||
been written by the track during burn */
|
been written by the track during burn.
|
||||||
|
@param t The track to inquire
|
||||||
|
@param read_bytes Number of bytes read from the track source
|
||||||
|
@param written_bytes Number of bytes written to track
|
||||||
|
@since 0.2.6
|
||||||
|
*/
|
||||||
int burn_track_get_counters(struct burn_track *t,
|
int burn_track_get_counters(struct burn_track *t,
|
||||||
off_t *read_bytes, off_t *written_bytes);
|
off_t *read_bytes, off_t *written_bytes);
|
||||||
|
|
||||||
@ -1632,6 +1776,7 @@ void burn_drive_set_speed(struct burn_drive *d, int read, int write);
|
|||||||
@param min_percent Minimum of desired buffer oscillation: 25 to 100
|
@param min_percent Minimum of desired buffer oscillation: 25 to 100
|
||||||
@param max_percent Maximum of desired buffer oscillation: 25 to 100
|
@param max_percent Maximum of desired buffer oscillation: 25 to 100
|
||||||
@return 1=success , 0=failure
|
@return 1=success , 0=failure
|
||||||
|
@since 0.3.8
|
||||||
*/
|
*/
|
||||||
int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
|
int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
|
||||||
int min_usec, int max_usec, int timeout_sec,
|
int min_usec, int max_usec, int timeout_sec,
|
||||||
@ -1669,6 +1814,7 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts,
|
|||||||
bit1= do not issue error messages via burn_msgs queue
|
bit1= do not issue error messages via burn_msgs queue
|
||||||
(is automatically set with bit0)
|
(is automatically set with bit0)
|
||||||
@return Chosen write type. BURN_WRITE_NONE on failure.
|
@return Chosen write type. BURN_WRITE_NONE on failure.
|
||||||
|
@since 0.3.2
|
||||||
*/
|
*/
|
||||||
enum burn_write_types burn_write_opts_auto_write_type(
|
enum burn_write_types burn_write_opts_auto_write_type(
|
||||||
struct burn_write_opts *opts, struct burn_disc *disc,
|
struct burn_write_opts *opts, struct burn_disc *disc,
|
||||||
@ -1733,6 +1879,7 @@ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned cha
|
|||||||
being the last one and thus creating a BURN_DISC_APPENDABLE media.
|
being the last one and thus creating a BURN_DISC_APPENDABLE media.
|
||||||
@param opts The option object to be manipulated
|
@param opts The option object to be manipulated
|
||||||
@param multi 1=media will be appendable, 0=media will be closed (default)
|
@param multi 1=media will be appendable, 0=media will be closed (default)
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
|
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
|
||||||
|
|
||||||
@ -1749,6 +1896,7 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
|
|||||||
.start_range_low , .start_range_high .
|
.start_range_low , .start_range_high .
|
||||||
@param opts The write opts to change
|
@param opts The write opts to change
|
||||||
@param value The address in bytes (-1 = start at default address)
|
@param value The address in bytes (-1 = start at default address)
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value);
|
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value);
|
||||||
|
|
||||||
@ -1761,6 +1909,7 @@ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value);
|
|||||||
by the last track of the last session.
|
by the last track of the last session.
|
||||||
@param opts The write opts to change
|
@param opts The write opts to change
|
||||||
@param fill_up_media If 1 : fill up by last track, if 0 = do not fill up
|
@param fill_up_media If 1 : fill up by last track, if 0 = do not fill up
|
||||||
|
@since 0.3.4
|
||||||
*/
|
*/
|
||||||
void burn_write_opts_set_fillup(struct burn_write_opts *opts,
|
void burn_write_opts_set_fillup(struct burn_write_opts *opts,
|
||||||
int fill_up_media);
|
int fill_up_media);
|
||||||
@ -1772,19 +1921,23 @@ void burn_write_opts_set_fillup(struct burn_write_opts *opts,
|
|||||||
- the check whether the media profile supports simulated burning
|
- the check whether the media profile supports simulated burning
|
||||||
@param opts The write opts to change
|
@param opts The write opts to change
|
||||||
@param use_force 1=ignore above checks, 0=refuse work on failed check
|
@param use_force 1=ignore above checks, 0=refuse work on failed check
|
||||||
|
@since 0.3.4
|
||||||
*/
|
*/
|
||||||
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force);
|
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force);
|
||||||
|
|
||||||
|
|
||||||
/* ts A80412 */
|
/* ts A80412 */
|
||||||
/** Eventually makes use of the more modern write command AAh WRITE12 and
|
/** Eventually makes use of the more modern write command AAh WRITE12 and
|
||||||
sets the Streaming bit. With DVD-RAM this can override the traditional
|
sets the Streaming bit. With DVD-RAM and BD this can override the
|
||||||
slowdown to half nominal speed. But if it speeds up writing then it also
|
traditional slowdown to half nominal speed. But if it speeds up writing
|
||||||
disables error management and correction. Weigh your priorities.
|
then it also disables error management and correction. Weigh your
|
||||||
This only affects the write operations of burn_disc_write().
|
priorities. This affects the write operations of burn_disc_write()
|
||||||
@since 0.4.6
|
and subsequent calls of burn_random_access_write().
|
||||||
@param opts The write opts to change
|
@param opts The write opts to change
|
||||||
@param value 0=use 2Ah WRITE10, 1=use AAh WRITE12 with Streaming bit
|
@param value 0=use 2Ah WRITE10, 1=use AAh WRITE12 with Streaming bit
|
||||||
|
@since 0.6.4:
|
||||||
|
>=16 use WRITE12 but not before the LBA given by value
|
||||||
|
@since 0.4.6
|
||||||
*/
|
*/
|
||||||
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
||||||
int value);
|
int value);
|
||||||
@ -1860,6 +2013,7 @@ int burn_drive_get_write_speed(struct burn_drive *d);
|
|||||||
again by call burn_drive_grab() and again by call burn_disc_read_atip().
|
again by call burn_drive_grab() and again by call burn_disc_read_atip().
|
||||||
@param d Drive to query
|
@param d Drive to query
|
||||||
@return Minimum write speed in K/s
|
@return Minimum write speed in K/s
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_min_write_speed(struct burn_drive *d);
|
int burn_drive_get_min_write_speed(struct burn_drive *d);
|
||||||
|
|
||||||
@ -1882,6 +2036,7 @@ int burn_drive_get_read_speed(struct burn_drive *d);
|
|||||||
@param d Drive to query
|
@param d Drive to query
|
||||||
@param speed_list The copy. If empty, *speed_list gets returned as NULL.
|
@param speed_list The copy. If empty, *speed_list gets returned as NULL.
|
||||||
@return 1=success , 0=list empty , <0 severe error
|
@return 1=success , 0=list empty , <0 severe error
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_speedlist(struct burn_drive *d,
|
int burn_drive_get_speedlist(struct burn_drive *d,
|
||||||
struct burn_speed_descriptor **speed_list);
|
struct burn_speed_descriptor **speed_list);
|
||||||
@ -1901,6 +2056,7 @@ int burn_drive_get_speedlist(struct burn_drive *d,
|
|||||||
bit1= look for any source type (else look for source==2 first
|
bit1= look for any source type (else look for source==2 first
|
||||||
and for any other source type only with CD media)
|
and for any other source type only with CD media)
|
||||||
@return >0 indicates a valid best_descr, 0 = no valid best_descr
|
@return >0 indicates a valid best_descr, 0 = no valid best_descr
|
||||||
|
@since 0.3.8
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
|
int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
|
||||||
struct burn_speed_descriptor **best_descr, int flag);
|
struct burn_speed_descriptor **best_descr, int flag);
|
||||||
@ -1911,11 +2067,13 @@ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
|
|||||||
burn_drive_get_speedlist().
|
burn_drive_get_speedlist().
|
||||||
@param speed_list The list copy. *speed_list gets set to NULL.
|
@param speed_list The list copy. *speed_list gets set to NULL.
|
||||||
@return 1=list disposed , 0= *speedlist was already NULL
|
@return 1=list disposed , 0= *speedlist was already NULL
|
||||||
|
@since 0.3.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list);
|
int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70203 */
|
/* ts A70203 */
|
||||||
|
/* @since 0.3.2 */
|
||||||
/** The reply structure for burn_disc_get_multi_caps()
|
/** The reply structure for burn_disc_get_multi_caps()
|
||||||
*/
|
*/
|
||||||
struct burn_multi_caps {
|
struct burn_multi_caps {
|
||||||
@ -1993,7 +2151,8 @@ struct burn_multi_caps {
|
|||||||
/** Wether the current profile indicates CD media. 1=yes, 0=no */
|
/** Wether the current profile indicates CD media. 1=yes, 0=no */
|
||||||
int current_is_cd_profile;
|
int current_is_cd_profile;
|
||||||
|
|
||||||
/* ts A70528, added to version 0.3.7 */
|
/* ts A70528 */
|
||||||
|
/* @since 0.3.8 */
|
||||||
/** Wether the current profile is able to perform simulated write */
|
/** Wether the current profile is able to perform simulated write */
|
||||||
int might_simulate;
|
int might_simulate;
|
||||||
};
|
};
|
||||||
@ -2010,6 +2169,7 @@ struct burn_multi_caps {
|
|||||||
@param caps returns the info structure
|
@param caps returns the info structure
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
@return < 0 : error , 0 : writing seems impossible , 1 : writing possible
|
@return < 0 : error , 0 : writing seems impossible , 1 : writing possible
|
||||||
|
@since 0.3.2
|
||||||
*/
|
*/
|
||||||
int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||||
struct burn_multi_caps **caps, int flag);
|
struct burn_multi_caps **caps, int flag);
|
||||||
@ -2018,6 +2178,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
burn_disc_get_multi_caps(). The pointer *caps gets set to NULL.
|
burn_disc_get_multi_caps(). The pointer *caps gets set to NULL.
|
||||||
@param caps the info structure to dispose (note: pointer to pointer)
|
@param caps the info structure to dispose (note: pointer to pointer)
|
||||||
@return 0 : *caps was already NULL, 1 : memory object was disposed
|
@return 0 : *caps was already NULL, 1 : memory object was disposed
|
||||||
|
@since 0.3.2
|
||||||
*/
|
*/
|
||||||
int burn_disc_free_multi_caps(struct burn_multi_caps **caps);
|
int burn_disc_free_multi_caps(struct burn_multi_caps **caps);
|
||||||
|
|
||||||
@ -2080,6 +2241,7 @@ void burn_version(int *major, int *minor, int *micro);
|
|||||||
|
|
||||||
|
|
||||||
/* ts A80129 */
|
/* ts A80129 */
|
||||||
|
/* @since 0.4.4 */
|
||||||
/** These three release version numbers tell the revision of this header file
|
/** These three release version numbers tell the revision of this header file
|
||||||
and of the API it describes. They are memorized by applications at build
|
and of the API it describes. They are memorized by applications at build
|
||||||
time.
|
time.
|
||||||
@ -2097,8 +2259,8 @@ void burn_version(int *major, int *minor, int *micro);
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#define burn_header_version_major 0
|
#define burn_header_version_major 0
|
||||||
#define burn_header_version_minor 4
|
#define burn_header_version_minor 6
|
||||||
#define burn_header_version_micro 7
|
#define burn_header_version_micro 4
|
||||||
/** Note:
|
/** Note:
|
||||||
Above version numbers are also recorded in configure.ac because libtool
|
Above version numbers are also recorded in configure.ac because libtool
|
||||||
wants them as parameters at build time.
|
wants them as parameters at build time.
|
||||||
@ -2160,12 +2322,13 @@ These two advises are mutually exclusive.
|
|||||||
to stderr. Default: "FATAL".
|
to stderr. Default: "FATAL".
|
||||||
@param print_id A text prefix to be printed before the message.
|
@param print_id A text prefix to be printed before the message.
|
||||||
@return >0 for success, <=0 for error
|
@return >0 for success, <=0 for error
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_msgs_set_severities(char *queue_severity,
|
int burn_msgs_set_severities(char *queue_severity,
|
||||||
char *print_severity, char *print_id);
|
char *print_severity, char *print_id);
|
||||||
|
|
||||||
/* ts A60924 : ticket 74 */
|
/* ts A60924 : ticket 74 */
|
||||||
|
/* @since 0.2.6 */
|
||||||
#define BURN_MSGS_MESSAGE_LEN 4096
|
#define BURN_MSGS_MESSAGE_LEN 4096
|
||||||
|
|
||||||
/** Obtain the oldest pending libburn message from the queue which has at
|
/** Obtain the oldest pending libburn message from the queue which has at
|
||||||
@ -2183,6 +2346,7 @@ int burn_msgs_set_severities(char *queue_severity,
|
|||||||
@param severity Will become the severity related to the message and
|
@param severity Will become the severity related to the message and
|
||||||
should provide at least 80 bytes.
|
should provide at least 80 bytes.
|
||||||
@return 1 if a matching item was found, 0 if not, <0 for severe errors
|
@return 1 if a matching item was found, 0 if not, <0 for severe errors
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_msgs_obtain(char *minimum_severity,
|
int burn_msgs_obtain(char *minimum_severity,
|
||||||
int *error_code, char msg_text[], int *os_errno,
|
int *error_code, char msg_text[], int *os_errno,
|
||||||
@ -2205,6 +2369,7 @@ int burn_msgs_obtain(char *minimum_severity,
|
|||||||
Submit NULL if the message is not specific to a
|
Submit NULL if the message is not specific to a
|
||||||
particular drive object.
|
particular drive object.
|
||||||
@return 1 if message was delivered, <=0 if failure
|
@return 1 if message was delivered, <=0 if failure
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
|
int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
|
||||||
char severity[], struct burn_drive *d);
|
char severity[], struct burn_drive *d);
|
||||||
@ -2217,6 +2382,7 @@ int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
|
|||||||
@param severity_number The rank number: the higher, the more severe.
|
@param severity_number The rank number: the higher, the more severe.
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
@return >0 success, <=0 failure
|
@return >0 success, <=0 failure
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_text_to_sev(char *severity_name, int *severity_number, int flag);
|
int burn_text_to_sev(char *severity_name, int *severity_number, int flag);
|
||||||
|
|
||||||
@ -2227,6 +2393,7 @@ int burn_text_to_sev(char *severity_name, int *severity_number, int flag);
|
|||||||
@param severity_number The rank number: the higher, the more severe.
|
@param severity_number The rank number: the higher, the more severe.
|
||||||
@param severity_name A name as with burn_msgs_submit(), e.g. "SORRY".
|
@param severity_name A name as with burn_msgs_submit(), e.g. "SORRY".
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@since 0.4.4
|
||||||
*/
|
*/
|
||||||
int burn_sev_to_text(int severity_number, char **severity_name, int flag);
|
int burn_sev_to_text(int severity_number, char **severity_name, int flag);
|
||||||
|
|
||||||
@ -2238,11 +2405,13 @@ int burn_sev_to_text(int severity_number, char **severity_name, int flag);
|
|||||||
See also: libisofs, API function iso_get_messenger().
|
See also: libisofs, API function iso_get_messenger().
|
||||||
@param messenger The foreign but compatible message handle.
|
@param messenger The foreign but compatible message handle.
|
||||||
@return 1 : success, <=0 : failure
|
@return 1 : success, <=0 : failure
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_set_messenger(void *messenger);
|
int burn_set_messenger(void *messenger);
|
||||||
|
|
||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
|
/* @since 0.2.6 */
|
||||||
/** The prototype of a handler function suitable for burn_set_abort_handling().
|
/** The prototype of a handler function suitable for burn_set_abort_handling().
|
||||||
Such a function has to return -2 if it does not want the process to
|
Such a function has to return -2 if it does not want the process to
|
||||||
exit with value 1.
|
exit with value 1.
|
||||||
@ -2261,6 +2430,7 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
|
|||||||
Arguments (text, NULL, 0) activate the builtin abort handler. It will
|
Arguments (text, NULL, 0) activate the builtin abort handler. It will
|
||||||
eventually call burn_abort() and then perform exit(1). If text is not NULL
|
eventually call burn_abort() and then perform exit(1). If text is not NULL
|
||||||
then it is used as prefix for pacifier messages of burn_abort_pacifier().
|
then it is used as prefix for pacifier messages of burn_abort_pacifier().
|
||||||
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
int mode);
|
int mode);
|
||||||
@ -2293,11 +2463,27 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
|||||||
@param flag Bitfield for control purposes:
|
@param flag Bitfield for control purposes:
|
||||||
bit0 = flush the drive buffer after eventual writing
|
bit0 = flush the drive buffer after eventual writing
|
||||||
@return 1=sucessful , <=0 : number of transfered bytes * -1
|
@return 1=sucessful , <=0 : number of transfered bytes * -1
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
||||||
char *data, off_t data_count, int flag);
|
char *data, off_t data_count, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A81215 */
|
||||||
|
/** Inquire the maximum amount of readable data.
|
||||||
|
It is supposed that all LBAs in the range from 0 to media_read_acpacity-1
|
||||||
|
can be read via burn_read_data() although some of them may never have been
|
||||||
|
recorded. If tracks are recognizable then it is better to only read
|
||||||
|
LBAs which are part of some track.
|
||||||
|
@param d The drive from which to read
|
||||||
|
@param capacity Will return the result if valid
|
||||||
|
@param flag Bitfield for control purposes: Unused yet, submit 0.
|
||||||
|
@return 1=sucessful , <=0 an error occured
|
||||||
|
@since 0.6.0
|
||||||
|
*/
|
||||||
|
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70812 */
|
/* ts A70812 */
|
||||||
/** Read data in random access mode.
|
/** Read data in random access mode.
|
||||||
The drive must be grabbed successfully before calling this function.
|
The drive must be grabbed successfully before calling this function.
|
||||||
@ -2307,7 +2493,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
This is a synchronous call which returns only after the full read job
|
This is a synchronous call which returns only after the full read job
|
||||||
has ended (sucessfully or not). So it is wise not to read giant amounts
|
has ended (sucessfully or not). So it is wise not to read giant amounts
|
||||||
of data in a single call.
|
of data in a single call.
|
||||||
@param d The drive to which to write
|
@param d The drive from which to read
|
||||||
@param byte_address The start address of the read in byte (aligned to 2048)
|
@param byte_address The start address of the read in byte (aligned to 2048)
|
||||||
@param data A memory buffer capable of taking data_size bytes
|
@param data A memory buffer capable of taking data_size bytes
|
||||||
@param data_size The amount of data to be read. This does not have to
|
@param data_size The amount of data to be read. This does not have to
|
||||||
@ -2316,7 +2502,10 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
@param flag Bitfield for control purposes:
|
@param flag Bitfield for control purposes:
|
||||||
bit0= - reserved -
|
bit0= - reserved -
|
||||||
bit1= do not submit error message if read error
|
bit1= do not submit error message if read error
|
||||||
|
bit2= on error do not try to read a second time
|
||||||
|
with single block steps. @since 0.5.2
|
||||||
@return 1=sucessful , <=0 an error occured
|
@return 1=sucessful , <=0 an error occured
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
char data[], off_t data_size, off_t *data_count, int flag);
|
char data[], off_t data_size, off_t *data_count, int flag);
|
||||||
@ -2330,6 +2519,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
|||||||
1= real MMC drive
|
1= real MMC drive
|
||||||
2= stdio-drive, random access, read-write
|
2= stdio-drive, random access, read-write
|
||||||
3= stdio-drive, sequential, write-only
|
3= stdio-drive, sequential, write-only
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_drive_role(struct burn_drive *d);
|
int burn_drive_get_drive_role(struct burn_drive *d);
|
||||||
|
|
||||||
@ -2356,6 +2546,7 @@ int burn_drive_get_drive_role(struct burn_drive *d);
|
|||||||
prefix "stdio:".
|
prefix "stdio:".
|
||||||
@return 1= adr2 leads to d1 , 0= adr2 seems not to lead to d1,
|
@return 1= adr2 leads to d1 , 0= adr2 seems not to lead to d1,
|
||||||
-1 = adr2 is bad
|
-1 = adr2 is bad
|
||||||
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_equals_adr(struct burn_drive *d1, char *adr2, int drive_role2);
|
int burn_drive_equals_adr(struct burn_drive *d1, char *adr2, int drive_role2);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2009 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2009 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -432,6 +432,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
|
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
|
||||||
0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock
|
0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock
|
||||||
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
|
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:
|
General library operations:
|
||||||
|
|
||||||
@ -524,6 +526,29 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020157 (FATAL,HIGH) = burn_source is not a fifo object
|
0x00020157 (FATAL,HIGH) = burn_source is not a fifo object
|
||||||
0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions
|
0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions
|
||||||
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
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
|
||||||
|
|
||||||
|
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
||||||
|
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
|
||||||
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
|
429
libburn/mmc.c
429
libburn/mmc.c
@ -55,14 +55,17 @@ extern struct libdax_msgs *libdax_messenger;
|
|||||||
/* ts A70306 */
|
/* ts A70306 */
|
||||||
#define Libburn_support_dvd_plus_R 1
|
#define Libburn_support_dvd_plus_R 1
|
||||||
|
|
||||||
/* ts A70509 : handling 0x41 and 0x42 as read-only types */
|
/* ts A70509 : handling 0x41 as read-only type */
|
||||||
#define Libburn_support_bd_r_readonlY 1
|
#define Libburn_support_bd_r_readonlY 1
|
||||||
|
|
||||||
|
/* ts A81208 */
|
||||||
|
#define Libburn_support_bd_plus_r_srM 1
|
||||||
|
|
||||||
|
|
||||||
/* ts A80410 : <<< Dangerous experiment: Pretend that DVD-RAM is BD-RE
|
/* ts A80410 : <<< Dangerous experiment: Pretend that DVD-RAM is BD-RE
|
||||||
# define Libburn_dvd_ram_as_bd_rE yes
|
# define Libburn_dvd_ram_as_bd_rE yes
|
||||||
*/
|
*/
|
||||||
/* ts A80509 : <<< Experiment: pretend that DVD-COM and CD-ROM are other media
|
/* ts A80509 : <<< Experiment: pretend that DVD-ROM and CD-ROM are other media
|
||||||
like BD-ROM (0x40), BD-R seq (0x41), BD-R random (0x42)
|
like BD-ROM (0x40), BD-R seq (0x41), BD-R random (0x42)
|
||||||
# define Libburn_rom_as_profilE 0x40
|
# define Libburn_rom_as_profilE 0x40
|
||||||
*/
|
*/
|
||||||
@ -119,6 +122,9 @@ extern struct libdax_msgs *libdax_messenger;
|
|||||||
drive->do_stream_recording it does full nominal speed.
|
drive->do_stream_recording it does full nominal speed.
|
||||||
ts A80506 : Giulio Orsero reports success with BD-RE formatting.
|
ts A80506 : Giulio Orsero reports success with BD-RE formatting.
|
||||||
BD-RE is now an officially supported profile.
|
BD-RE is now an officially supported profile.
|
||||||
|
ts A81209 : The first two sessions have been written to BD-R SRM
|
||||||
|
(auto formatted without Defect Management).
|
||||||
|
ts A90107 : BD-R is now supported media type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ts A70519 : With MMC commands of data direction FROM_DRIVE:
|
/* ts A70519 : With MMC commands of data direction FROM_DRIVE:
|
||||||
@ -198,6 +204,10 @@ static unsigned char MMC_RESERVE_TRACK[] =
|
|||||||
static unsigned char MMC_READ_10[] =
|
static unsigned char MMC_READ_10[] =
|
||||||
{ 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
{ 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
/* ts A81210 : Determine the upper limit of readable data size */
|
||||||
|
static unsigned char MMC_READ_CAPACITY[] =
|
||||||
|
{ 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
|
||||||
static int mmc_function_spy_do_tell = 0;
|
static int mmc_function_spy_do_tell = 0;
|
||||||
|
|
||||||
@ -735,7 +745,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
mmc_wait_for_buffer_free(d, buf);
|
mmc_wait_for_buffer_free(d, buf);
|
||||||
|
|
||||||
/* ts A80412 */
|
/* ts A80412 */
|
||||||
if(d->do_stream_recording > 0) {
|
if(d->do_stream_recording > 0 && start >= d->stream_recording_start) {
|
||||||
|
|
||||||
/* >>> ??? is WRITE12 available ? */
|
/* >>> ??? is WRITE12 available ? */
|
||||||
/* >>> ??? inquire feature 107h Stream Writing bit ? */
|
/* >>> ??? inquire feature 107h Stream Writing bit ? */
|
||||||
@ -773,11 +783,24 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
|
|
||||||
/* >>> make this scsi_notify_error() when liberated */
|
/* >>> make this scsi_notify_error() when liberated */
|
||||||
if (c.sense[2]!=0) {
|
if (c.sense[2]!=0) {
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
char msg[160];
|
char msg[160];
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"SCSI error on write(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
"SCSI error on write(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
start, len,
|
start, len,
|
||||||
c.sense[2],c.sense[12],c.sense[13]);
|
c.sense[2],c.sense[12],c.sense[13]);
|
||||||
|
#else /* NIX */
|
||||||
|
char msg[256];
|
||||||
|
int key, asc, ascq;
|
||||||
|
|
||||||
|
sprintf(msg, "SCSI error on write(%d,%d): ",
|
||||||
|
start, len);
|
||||||
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
|
#endif /* !NIX */
|
||||||
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002011d,
|
0x0002011d,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -1130,8 +1153,9 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
struct command c;
|
struct command c;
|
||||||
int dlen;
|
int dlen;
|
||||||
int i, bpl= 12, old_alloc_len;
|
int i, bpl= 12, old_alloc_len, t_idx;
|
||||||
unsigned char *tdata;
|
unsigned char *tdata;
|
||||||
|
char msg[321];
|
||||||
|
|
||||||
if (*alloc_len < 4)
|
if (*alloc_len < 4)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1207,7 +1231,9 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
ts A61007 : if re-enabled then not via Assert.
|
ts A61007 : if re-enabled then not via Assert.
|
||||||
a ssert(((dlen - 2) % 11) == 0);
|
a ssert(((dlen - 2) % 11) == 0);
|
||||||
*/
|
*/
|
||||||
d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
|
/* ts A81202: plus number of sessions as reserve for leadout default */
|
||||||
|
d->toc_entry = calloc(d->toc_entries + (unsigned char) c.page->data[3],
|
||||||
|
sizeof(struct burn_toc_entry));
|
||||||
if(d->toc_entry == NULL) /* ts A70825 */
|
if(d->toc_entry == NULL) /* ts A70825 */
|
||||||
return 0;
|
return 0;
|
||||||
tdata = c.page->data + 4;
|
tdata = c.page->data + 4;
|
||||||
@ -1293,6 +1319,46 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
if (d->status == BURN_DISC_UNREADY)
|
if (d->status == BURN_DISC_UNREADY)
|
||||||
d->status = BURN_DISC_FULL;
|
d->status = BURN_DISC_FULL;
|
||||||
toc_find_modes(d);
|
toc_find_modes(d);
|
||||||
|
|
||||||
|
/* ts A81202 ticket 146 : a drive reported a session with no leadout */
|
||||||
|
for (i = 0; i < d->disc->sessions; i++) {
|
||||||
|
if (d->disc->session[i]->leadout_entry != NULL)
|
||||||
|
continue;
|
||||||
|
sprintf(msg, "Session %d of %d encountered without leadout",
|
||||||
|
i + 1, d->disc->sessions);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020160,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
|
||||||
|
/* Produce default leadout entry from last track of session
|
||||||
|
which will thus get its size set to 0 */;
|
||||||
|
if (d->disc->session[i]->track != NULL &&
|
||||||
|
d->disc->session[i]->tracks > 0) {
|
||||||
|
t_idx = d->toc_entries++;
|
||||||
|
memcpy(d->toc_entry + t_idx,
|
||||||
|
d->disc->session[i]->track[
|
||||||
|
d->disc->session[i]->tracks - 1]->entry,
|
||||||
|
sizeof(struct burn_toc_entry));
|
||||||
|
d->toc_entry[t_idx].point = 0xA2;
|
||||||
|
d->disc->session[i]->leadout_entry =
|
||||||
|
d->toc_entry + t_idx;
|
||||||
|
} else {
|
||||||
|
burn_disc_remove_session(d->disc, d->disc->session[i]);
|
||||||
|
sprintf(msg,
|
||||||
|
"Empty session %d deleted. Now %d sessions.",
|
||||||
|
i + 1, d->disc->sessions);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020161,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A80808 */
|
||||||
|
burn_disc_cd_toc_extensions(d->disc, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1401,7 +1467,8 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
struct command c;
|
struct command c;
|
||||||
char msg[160];
|
char msg[160];
|
||||||
/* ts A70131 : had to move mmc_read_toc() to end of function */
|
/* ts A70131 : had to move mmc_read_toc() to end of function */
|
||||||
int do_read_toc = 0, session_state, disc_status, len, old_alloc_len;
|
int do_read_toc = 0, disc_status, len, old_alloc_len;
|
||||||
|
int ret, number_of_sessions = -1;
|
||||||
|
|
||||||
/* ts A61020 */
|
/* ts A61020 */
|
||||||
d->start_lba = d->end_lba = -2000000000;
|
d->start_lba = d->end_lba = -2000000000;
|
||||||
@ -1412,6 +1479,9 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->media_capacity_remaining = 0;
|
d->media_capacity_remaining = 0;
|
||||||
d->media_lba_limit = 0;
|
d->media_lba_limit = 0;
|
||||||
|
|
||||||
|
/* ts A81210 */
|
||||||
|
d->media_read_capacity = 0x7fffffff;
|
||||||
|
|
||||||
/* ts A61202 */
|
/* ts A61202 */
|
||||||
d->toc_entries = 0;
|
d->toc_entries = 0;
|
||||||
if (d->status == BURN_DISC_EMPTY)
|
if (d->status == BURN_DISC_EMPTY)
|
||||||
@ -1457,6 +1527,9 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->erasable = !!(data[2] & 16);
|
d->erasable = !!(data[2] & 16);
|
||||||
|
|
||||||
disc_status = data[2] & 3;
|
disc_status = data[2] & 3;
|
||||||
|
d->state_of_last_session = (data[2] >> 2) & 3;
|
||||||
|
number_of_sessions = (data[9] << 8) | data[4];
|
||||||
|
|
||||||
if (d->current_profile == 0x10 || d->current_profile == 0x40) {
|
if (d->current_profile == 0x10 || d->current_profile == 0x40) {
|
||||||
/* DVD-ROM , BD-ROM */
|
/* DVD-ROM , BD-ROM */
|
||||||
disc_status = 2; /* always full and finalized */
|
disc_status = 2; /* always full and finalized */
|
||||||
@ -1472,8 +1545,15 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
#ifdef Libburn_support_bd_r_readonlY
|
#ifdef Libburn_support_bd_r_readonlY
|
||||||
/* <<< For now: declaring BD-R read-only
|
/* <<< For now: declaring BD-R read-only
|
||||||
*/
|
*/
|
||||||
if (d->current_profile == 0x41 || d->current_profile == 0x42) {
|
#ifndef Libburn_support_bd_plus_r_srM
|
||||||
/* BD-R seq, BD-R rnd */
|
if (d->current_profile == 0x41) {
|
||||||
|
/* BD-R seq as readonly dummy */
|
||||||
|
disc_status = 2; /* always full and finalized */
|
||||||
|
d->erasable = 0; /* never erasable */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (d->current_profile == 0x42) {
|
||||||
|
/* BD-R rnd */
|
||||||
disc_status = 2; /* always full and finalized */
|
disc_status = 2; /* always full and finalized */
|
||||||
d->erasable = 0; /* never erasable */
|
d->erasable = 0; /* never erasable */
|
||||||
}
|
}
|
||||||
@ -1481,6 +1561,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
|
|
||||||
switch (disc_status) {
|
switch (disc_status) {
|
||||||
case 0:
|
case 0:
|
||||||
|
regard_as_blank:;
|
||||||
d->toc_entries = 0;
|
d->toc_entries = 0;
|
||||||
d->start_lba = burn_msf_to_lba(data[17], data[18], data[19]);
|
d->start_lba = burn_msf_to_lba(data[17], data[18], data[19]);
|
||||||
d->end_lba = burn_msf_to_lba(data[21], data[22], data[23]);
|
d->end_lba = burn_msf_to_lba(data[21], data[22], data[23]);
|
||||||
@ -1495,28 +1576,40 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
d->status = BURN_DISC_APPENDABLE;
|
d->status = BURN_DISC_APPENDABLE;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (disc_status == 2)
|
if (disc_status == 2)
|
||||||
d->status = BURN_DISC_FULL;
|
d->status = BURN_DISC_FULL;
|
||||||
|
|
||||||
|
/* ts A81210 */
|
||||||
|
ret = mmc_read_capacity(d);
|
||||||
|
/* Freshly formatted, unwritten BD-R pretend to be appendable
|
||||||
|
but in our model they need to be regarded as blank.
|
||||||
|
Criterion: BD-R seq, read capacity known and 0,
|
||||||
|
declared appendable, single empty session
|
||||||
|
*/
|
||||||
|
if (d->current_profile == 0x41 &&
|
||||||
|
d->status == BURN_DISC_APPENDABLE &&
|
||||||
|
ret > 0 && d->media_read_capacity == 0 &&
|
||||||
|
d->state_of_last_session == 0 && number_of_sessions == 1)
|
||||||
|
goto regard_as_blank;
|
||||||
|
|
||||||
|
if (d->current_profile == 0x41 &&
|
||||||
|
d->status == BURN_DISC_APPENDABLE &&
|
||||||
|
d->state_of_last_session == 1) {
|
||||||
|
|
||||||
|
/* ??? apply this test to other media types ? */
|
||||||
|
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020169,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Last session on media is still open.", 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
do_read_toc = 1;
|
do_read_toc = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
/* <<< on its way out. DVD-R DL are current_is_supported_profile
|
|
||||||
unconditionally. Writeability is handled above now.
|
|
||||||
*/
|
|
||||||
/* ts A80207 : DVD - R DL can normally be read but not be written */
|
|
||||||
if(d->current_profile == 0x15 && !d->current_is_supported_profile) {
|
|
||||||
if(d->status == BURN_DISC_APPENDABLE)
|
|
||||||
d->status = BURN_DISC_FULL;
|
|
||||||
d->erasable = 0; /* never erasable */
|
|
||||||
d->current_is_supported_profile = 1;
|
|
||||||
}
|
|
||||||
#endif /* NIX */
|
|
||||||
|
|
||||||
|
|
||||||
if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY)
|
if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY)
|
||||||
&& ! d->current_is_supported_profile) {
|
&& ! d->current_is_supported_profile) {
|
||||||
if (!d->silent_on_scsi_error) {
|
if (!d->silent_on_scsi_error) {
|
||||||
@ -1560,10 +1653,9 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->complete_sessions = 0;
|
d->complete_sessions = 0;
|
||||||
} else {
|
} else {
|
||||||
/* ts A70131 : number of non-empty sessions */
|
/* ts A70131 : number of non-empty sessions */
|
||||||
d->complete_sessions = (data[9] << 8) | data[4];
|
d->complete_sessions = number_of_sessions;
|
||||||
session_state = (data[2] >> 2) & 3;
|
|
||||||
/* mmc5r03c.pdf 6.22.3.1.3 State of Last Session: 3=complete */
|
/* mmc5r03c.pdf 6.22.3.1.3 State of Last Session: 3=complete */
|
||||||
if (session_state != 3 && d->complete_sessions >= 1)
|
if (d->state_of_last_session != 3 && d->complete_sessions >= 1)
|
||||||
d->complete_sessions--;
|
d->complete_sessions--;
|
||||||
|
|
||||||
/* ts A70129 : mmc5r03c.pdf 6.22.3.1.7
|
/* ts A70129 : mmc5r03c.pdf 6.22.3.1.7
|
||||||
@ -1920,8 +2012,9 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
struct command c;
|
struct command c;
|
||||||
int b, eff_end_lba;
|
int b, eff_end_lba;
|
||||||
char msg[160];
|
char msg[256];
|
||||||
unsigned char *pd;
|
unsigned char *pd;
|
||||||
|
int key, asc, ascq;
|
||||||
|
|
||||||
if (mmc_function_spy(d, "mmc_set_streaming") <= 0)
|
if (mmc_function_spy(d, "mmc_set_streaming") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1984,6 +2077,8 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
if (c.sense[2]!=0 && !d->silent_on_scsi_error) {
|
if (c.sense[2]!=0 && !d->silent_on_scsi_error) {
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"SCSI error on set_streaming(%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
"SCSI error on set_streaming(%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
w_speed,
|
w_speed,
|
||||||
@ -1993,6 +2088,15 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||||||
0x00020124,
|
0x00020124,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
|
#else /* NIX */
|
||||||
|
|
||||||
|
sprintf(msg,
|
||||||
|
"SCSI error on set_streaming(%d): ", w_speed);
|
||||||
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
|
#endif /* !NIX */
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2125,6 +2229,8 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->current_is_supported_profile = 0;
|
d->current_is_supported_profile = 0;
|
||||||
d->current_has_feat21h = 0;
|
d->current_has_feat21h = 0;
|
||||||
d->current_feat21h_link_size = -1;
|
d->current_feat21h_link_size = -1;
|
||||||
|
d->current_feat23h_byte4 = 0;
|
||||||
|
d->current_feat23h_byte8 = 0;
|
||||||
d->current_feat2fh_byte4 = -1;
|
d->current_feat2fh_byte4 = -1;
|
||||||
|
|
||||||
scsi_init_command(&c, MMC_GET_CONFIGURATION,
|
scsi_init_command(&c, MMC_GET_CONFIGURATION,
|
||||||
@ -2171,7 +2277,11 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->current_is_supported_profile = 1;
|
d->current_is_supported_profile = 1;
|
||||||
|
|
||||||
#ifdef Libburn_support_bd_r_readonlY
|
#ifdef Libburn_support_bd_r_readonlY
|
||||||
if (cp == 0x41 || cp == 0x42) /* BD-R sequential, BD-R random */
|
#ifndef Libburn_support_bd_plus_r_srM
|
||||||
|
if (cp == 0x41) /* BD-R sequential (here as read-only dummy) */
|
||||||
|
d->current_is_supported_profile = 1;
|
||||||
|
#endif
|
||||||
|
if (cp == 0x42) /* BD-R random recording */
|
||||||
d->current_is_supported_profile = 1;
|
d->current_is_supported_profile = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2212,6 +2322,10 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
if (cp == 0x1b || cp == 0x2b) /* DVD+R , DVD+R/DL */
|
if (cp == 0x1b || cp == 0x2b) /* DVD+R , DVD+R/DL */
|
||||||
d->current_is_supported_profile = 1;
|
d->current_is_supported_profile = 1;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Libburn_support_bd_plus_r_srM
|
||||||
|
if (cp == 0x41) /* BD-R SRM */
|
||||||
|
d->current_is_supported_profile = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable this to get loud and repeated reports about the feature set :
|
/* Enable this to get loud and repeated reports about the feature set :
|
||||||
#define Libburn_print_feature_descriptorS 1
|
#define Libburn_print_feature_descriptorS 1
|
||||||
@ -2278,6 +2392,20 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (feature_code == 0x23) {
|
||||||
|
d->current_feat23h_byte4 = descr[4];
|
||||||
|
d->current_feat23h_byte8 = descr[8];
|
||||||
|
#ifdef Libburn_print_feature_descriptorS
|
||||||
|
if (cp >= 0x41 && cp <= 0x43)
|
||||||
|
fprintf(stderr,
|
||||||
|
"LIBBURN_EXPERIMENTAL : BD formats: %s%s%s%s%s\n",
|
||||||
|
descr[4] & 1 ? " Cert" : "",
|
||||||
|
descr[4] & 2 ? " QCert" : "",
|
||||||
|
descr[4] & 4 ? " Expand" : "",
|
||||||
|
descr[4] & 8 ? " RENoSA" : "",
|
||||||
|
descr[8] & 1 ? " RRM" : "");
|
||||||
|
#endif /* Libburn_print_feature_descriptorS */
|
||||||
|
|
||||||
} else if (feature_code == 0x2F) {
|
} else if (feature_code == 0x2F) {
|
||||||
if (descr[2] & 1)
|
if (descr[2] & 1)
|
||||||
d->current_feat2fh_byte4 = descr[4];
|
d->current_feat2fh_byte4 = descr[4];
|
||||||
@ -2685,6 +2813,7 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
|
|||||||
bit6= try to avoid lengthy media certification
|
bit6= try to avoid lengthy media certification
|
||||||
bit7= bit8 to bit15 contain the index of the format to use
|
bit7= bit8 to bit15 contain the index of the format to use
|
||||||
bit8-bit15 = see bit7
|
bit8-bit15 = see bit7
|
||||||
|
bit16= enable POW on blank BD-R
|
||||||
*/
|
*/
|
||||||
int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
|
int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
|
||||||
{
|
{
|
||||||
@ -2694,7 +2823,9 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
|
|||||||
int index, format_sub_type = 0, format_00_index, size_mode;
|
int index, format_sub_type = 0, format_00_index, size_mode;
|
||||||
int accept_count = 0;
|
int accept_count = 0;
|
||||||
off_t num_of_blocks = 0, diff, format_size, i_size, format_00_max_size;
|
off_t num_of_blocks = 0, diff, format_size, i_size, format_00_max_size;
|
||||||
char msg[160],descr[80];
|
off_t min_size = -1, max_size = -1;
|
||||||
|
char msg[256],descr[80];
|
||||||
|
int key, asc, ascq;
|
||||||
int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */
|
int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */
|
||||||
|
|
||||||
if (mmc_function_spy(d, "mmc_format_unit") <= 0)
|
if (mmc_function_spy(d, "mmc_format_unit") <= 0)
|
||||||
@ -2739,7 +2870,8 @@ selected_not_suitable:;
|
|||||||
d->current_profile == 0x14 ||
|
d->current_profile == 0x14 ||
|
||||||
d->current_profile == 0x1a ||
|
d->current_profile == 0x1a ||
|
||||||
d->current_profile == 0x12 ||
|
d->current_profile == 0x12 ||
|
||||||
d->current_profile == 0x43))
|
d->current_profile == 0x41 ||
|
||||||
|
d->current_profile == 0x43))
|
||||||
goto unsuitable_media;
|
goto unsuitable_media;
|
||||||
|
|
||||||
format_type = d->format_descriptors[index].type;
|
format_type = d->format_descriptors[index].type;
|
||||||
@ -2747,7 +2879,8 @@ selected_not_suitable:;
|
|||||||
format_type == 0x10 ||
|
format_type == 0x10 ||
|
||||||
format_type == 0x11 || format_type == 0x13 ||
|
format_type == 0x11 || format_type == 0x13 ||
|
||||||
format_type == 0x15 || format_type == 0x26 ||
|
format_type == 0x15 || format_type == 0x26 ||
|
||||||
format_type == 0x30 || format_type == 0x31 ))
|
format_type == 0x30 || format_type == 0x31 ||
|
||||||
|
format_type == 0x32))
|
||||||
goto selected_not_suitable;
|
goto selected_not_suitable;
|
||||||
if (flag & 4) {
|
if (flag & 4) {
|
||||||
num_of_blocks =
|
num_of_blocks =
|
||||||
@ -2759,7 +2892,8 @@ selected_not_suitable:;
|
|||||||
c.page->data[9 + i] =
|
c.page->data[9 + i] =
|
||||||
( d->format_descriptors[index].tdp >>
|
( d->format_descriptors[index].tdp >>
|
||||||
(16 - 8 * i)) & 0xff;
|
(16 - 8 * i)) & 0xff;
|
||||||
if (format_type == 0x30 || format_type == 0x31) {
|
if (format_type == 0x30 || format_type == 0x31 ||
|
||||||
|
format_type == 0x32) {
|
||||||
if (flag & 64)
|
if (flag & 64)
|
||||||
format_sub_type = 3; /* Quick certification */
|
format_sub_type = 3; /* Quick certification */
|
||||||
else
|
else
|
||||||
@ -2975,6 +3109,116 @@ no_suitable_formatting_type:;
|
|||||||
c.opcode[1] |= 0x08;
|
c.opcode[1] |= 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (d->current_profile == 0x41) {
|
||||||
|
/* BD-R SRM */
|
||||||
|
|
||||||
|
index = -1;
|
||||||
|
format_size = -1;
|
||||||
|
if (d->num_format_descr <= 0)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
if (d->format_descriptors[0].type != 0)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
for (i = 0; i < d->num_format_descr; i++) {
|
||||||
|
format_type = d->format_descriptors[i].type;
|
||||||
|
i_size = d->format_descriptors[i].size;
|
||||||
|
if (format_type != 0x00 && format_type != 0x32)
|
||||||
|
continue;
|
||||||
|
if (flag & 32) { /* No defect mgt */
|
||||||
|
/* ts A81211 : MMC-5 6.5.4.2.17.1
|
||||||
|
When formatted with Format Type 32h,
|
||||||
|
the BD-R disc is required to allocate
|
||||||
|
a non-zero number of spares.
|
||||||
|
*/
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
|
||||||
|
} else if(size_mode == 2) { /* max payload size */
|
||||||
|
/* search largest 0x32 format descriptor */
|
||||||
|
if(format_type != 0x32)
|
||||||
|
continue;
|
||||||
|
} else if(size_mode == 3) { /* default payload size */
|
||||||
|
if (format_type == 0x00) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else { /* defect managed format with size wish */
|
||||||
|
|
||||||
|
#ifdef Libburn_bd_r_format_olD
|
||||||
|
|
||||||
|
/* search for smallest 0x32 >= size */
|
||||||
|
if(format_type != 0x32)
|
||||||
|
continue;
|
||||||
|
if (i_size < size)
|
||||||
|
continue;
|
||||||
|
if (format_size >= 0 && i_size >= format_size)
|
||||||
|
continue;
|
||||||
|
index = i;
|
||||||
|
format_size = i_size;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#else /* Libburn_bd_r_format_olD */
|
||||||
|
|
||||||
|
/* search largest and smallest 0x32 */
|
||||||
|
if(format_type != 0x32)
|
||||||
|
continue;
|
||||||
|
if (i_size < min_size || min_size < 0)
|
||||||
|
min_size = i_size;
|
||||||
|
if (i_size > max_size)
|
||||||
|
max_size = i_size;
|
||||||
|
|
||||||
|
#endif /* ! Libburn_bd_r_format_olD */
|
||||||
|
|
||||||
|
}
|
||||||
|
/* common for all cases which search largest
|
||||||
|
descriptors */
|
||||||
|
if (i_size > format_size) {
|
||||||
|
format_size = i_size;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size_mode == 2 && index < 0 && !(flag & 32))
|
||||||
|
index = 0;
|
||||||
|
if (index < 0)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
format_type = d->format_descriptors[index].type;
|
||||||
|
if (flag & (1 << 16))
|
||||||
|
format_sub_type = 0; /* SRM + POW */
|
||||||
|
else
|
||||||
|
format_sub_type = 1; /* SRM (- POW) */
|
||||||
|
|
||||||
|
#ifdef Libburn_bd_r_format_olD
|
||||||
|
if (0) {
|
||||||
|
#else
|
||||||
|
if (size_mode == 0 || size_mode == 1) {
|
||||||
|
#endif /* ! Libburn_bd_r_format_olD */
|
||||||
|
|
||||||
|
if (min_size < 0 || max_size < 0)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
if (size <= 0)
|
||||||
|
size = min_size;
|
||||||
|
if (size % 0x10000)
|
||||||
|
size += 0x10000 - (size % 0x10000);
|
||||||
|
if (size < min_size)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
else if(size > max_size)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
num_of_blocks = size / 2048;
|
||||||
|
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
c.page->data[9 + i] = 0;
|
||||||
|
} else {
|
||||||
|
num_of_blocks =
|
||||||
|
d->format_descriptors[index].size / 2048;
|
||||||
|
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
c.page->data[9 + i] =
|
||||||
|
( d->format_descriptors[index].tdp >>
|
||||||
|
(16 - 8 * i)) & 0xff;
|
||||||
|
}
|
||||||
|
sprintf(descr, "%s", d->current_profile_text);
|
||||||
|
return_immediately = 1; /* caller must do the waiting */
|
||||||
|
c.page->data[1] |= 0x80; /* FOV = this flag vector is valid */
|
||||||
|
|
||||||
} else if (d->current_profile == 0x43) {
|
} else if (d->current_profile == 0x43) {
|
||||||
/* BD-RE */
|
/* BD-RE */
|
||||||
index = -1;
|
index = -1;
|
||||||
@ -3000,6 +3244,17 @@ no_suitable_formatting_type:;
|
|||||||
} else if(size_mode == 3) { /* default payload size */
|
} else if(size_mode == 3) { /* default payload size */
|
||||||
if (accept_count < 1)
|
if (accept_count < 1)
|
||||||
index = 0; /* this cannot certify */
|
index = 0; /* this cannot certify */
|
||||||
|
|
||||||
|
/* ts A81129
|
||||||
|
LG GGW-H20L YL03 refuses on 0x30 with
|
||||||
|
"Quick certification". dvd+rw-format
|
||||||
|
does 0x00 by default and succeeds quickly.
|
||||||
|
*/
|
||||||
|
if ((flag & 64) && format_type == 0x00) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(format_type != 0x30)
|
if(format_type != 0x30)
|
||||||
continue;
|
continue;
|
||||||
accept_count++;
|
accept_count++;
|
||||||
@ -3007,6 +3262,9 @@ no_suitable_formatting_type:;
|
|||||||
index = i;
|
index = i;
|
||||||
continue;
|
continue;
|
||||||
} else { /* defect managed format with size wish */
|
} else { /* defect managed format with size wish */
|
||||||
|
|
||||||
|
#ifdef Libburn_bd_re_format_olD
|
||||||
|
|
||||||
/* search for smallest 0x30 >= size */
|
/* search for smallest 0x30 >= size */
|
||||||
if(format_type != 0x30)
|
if(format_type != 0x30)
|
||||||
continue;
|
continue;
|
||||||
@ -3017,6 +3275,19 @@ no_suitable_formatting_type:;
|
|||||||
index = i;
|
index = i;
|
||||||
format_size = i_size;
|
format_size = i_size;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#else /* Libburn_bd_re_format_olD */
|
||||||
|
|
||||||
|
/* search largest and smallest 0x30 */
|
||||||
|
if(format_type != 0x30)
|
||||||
|
continue;
|
||||||
|
if (i_size < min_size || min_size < 0)
|
||||||
|
min_size = i_size;
|
||||||
|
if (i_size > max_size)
|
||||||
|
max_size = i_size;
|
||||||
|
|
||||||
|
#endif /* ! Libburn_bd_re_format_olD */
|
||||||
|
|
||||||
}
|
}
|
||||||
/* common for all cases which search largest
|
/* common for all cases which search largest
|
||||||
descriptors */
|
descriptors */
|
||||||
@ -3025,6 +3296,7 @@ no_suitable_formatting_type:;
|
|||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_mode == 2 && index < 0 && !(flag & 32))
|
if (size_mode == 2 && index < 0 && !(flag & 32))
|
||||||
index = 0;
|
index = 0;
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
@ -3036,12 +3308,36 @@ no_suitable_formatting_type:;
|
|||||||
else
|
else
|
||||||
format_sub_type = 2; /* Full certification */
|
format_sub_type = 2; /* Full certification */
|
||||||
}
|
}
|
||||||
num_of_blocks = d->format_descriptors[index].size / 2048;
|
|
||||||
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
#ifdef Libburn_bd_re_format_olD
|
||||||
for (i = 0; i < 3; i++)
|
if (0) {
|
||||||
c.page->data[9 + i] =
|
#else
|
||||||
( d->format_descriptors[index].tdp >>
|
if (size_mode == 0 || size_mode == 1) {
|
||||||
(16 - 8 * i)) & 0xff;
|
#endif /* ! Libburn_bd_re_format_olD */
|
||||||
|
|
||||||
|
if (min_size < 0 || max_size < 0)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
if (size <= 0)
|
||||||
|
size = min_size;
|
||||||
|
if (size % 0x10000)
|
||||||
|
size += 0x10000 - (size % 0x10000);
|
||||||
|
if (size < min_size)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
else if(size > max_size)
|
||||||
|
goto no_suitable_formatting_type;
|
||||||
|
num_of_blocks = size / 2048;
|
||||||
|
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
c.page->data[9 + i] = 0;
|
||||||
|
} else {
|
||||||
|
num_of_blocks =
|
||||||
|
d->format_descriptors[index].size / 2048;
|
||||||
|
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
c.page->data[9 + i] =
|
||||||
|
( d->format_descriptors[index].tdp >>
|
||||||
|
(16 - 8 * i)) & 0xff;
|
||||||
|
}
|
||||||
sprintf(descr, "%s", d->current_profile_text);
|
sprintf(descr, "%s", d->current_profile_text);
|
||||||
return_immediately = 1; /* caller must do the waiting */
|
return_immediately = 1; /* caller must do the waiting */
|
||||||
c.page->data[1] |= 0x80; /* FOV = this flag vector is valid */
|
c.page->data[1] |= 0x80; /* FOV = this flag vector is valid */
|
||||||
@ -3096,6 +3392,8 @@ unsuitable_media:;
|
|||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error && !tolerate_failure) {
|
if (c.error && !tolerate_failure) {
|
||||||
if (c.sense[2]!=0) {
|
if (c.sense[2]!=0) {
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"SCSI error on format_unit(%s): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
"SCSI error on format_unit(%s): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
descr,
|
descr,
|
||||||
@ -3104,6 +3402,13 @@ unsuitable_media:;
|
|||||||
0x00020122,
|
0x00020122,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
|
#else /* NIX */
|
||||||
|
sprintf(msg, "SCSI error on format_unit(%s): ", descr);
|
||||||
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
|
#endif /* !NIX */
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((!c.error) && (format_type == 0x13 || format_type == 0x15))
|
} else if ((!c.error) && (format_type == 0x13 || format_type == 0x15))
|
||||||
@ -3351,8 +3656,9 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||||||
|
|
||||||
} else if (d->current_profile == 0x1a || d->current_profile == 0x1b ||
|
} else if (d->current_profile == 0x1a || d->current_profile == 0x1b ||
|
||||||
d->current_profile == 0x2b || d->current_profile == 0x12 ||
|
d->current_profile == 0x2b || d->current_profile == 0x12 ||
|
||||||
|
d->current_profile == 0x41 || d->current_profile == 0x42 ||
|
||||||
d->current_profile == 0x43) {
|
d->current_profile == 0x43) {
|
||||||
/* not with DVD+R[W][/DL] or DVD-RAM or BD-RE */;
|
/* not with DVD+R[W][/DL] or DVD-RAM or BD-R[E] */;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
/* Traditional setup for CD */
|
/* Traditional setup for CD */
|
||||||
@ -3405,11 +3711,24 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
|
|||||||
c.dir = FROM_DRIVE;
|
c.dir = FROM_DRIVE;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
char msg[160];
|
char msg[160];
|
||||||
|
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"SCSI error on read_10(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
"SCSI error on read_10(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
start, amount,
|
start, amount,
|
||||||
c.sense[2],c.sense[12],c.sense[13]);
|
c.sense[2],c.sense[12],c.sense[13]);
|
||||||
|
#else /* NIX */
|
||||||
|
char msg[256];
|
||||||
|
int key, asc, ascq;
|
||||||
|
|
||||||
|
sprintf(msg, "SCSI error on read_10(%d,%d): ", start, amount);
|
||||||
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
|
#endif /* !NIX */
|
||||||
|
|
||||||
if(!d->silent_on_scsi_error)
|
if(!d->silent_on_scsi_error)
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020144,
|
0x00020144,
|
||||||
@ -3424,6 +3743,34 @@ 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)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct command c;
|
||||||
|
int alloc_len= 8;
|
||||||
|
|
||||||
|
d->media_read_capacity = 0x7fffffff;
|
||||||
|
if (mmc_function_spy(d, "mmc_read_capacity") <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
scsi_init_command(&c, MMC_READ_CAPACITY, sizeof(MMC_READ_CAPACITY));
|
||||||
|
c.dxfer_len = alloc_len;
|
||||||
|
c.retry = 1;
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
d->media_read_capacity = mmc_four_char_to_int(c.page->data);
|
||||||
|
if (d->media_read_capacity < 0) {
|
||||||
|
d->media_read_capacity = 0x7fffffff;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||||
*/
|
*/
|
||||||
int mmc_setup_drive(struct burn_drive *d)
|
int mmc_setup_drive(struct burn_drive *d)
|
||||||
@ -3465,15 +3812,19 @@ int mmc_setup_drive(struct burn_drive *d)
|
|||||||
d->current_is_supported_profile = 0;
|
d->current_is_supported_profile = 0;
|
||||||
d->current_has_feat21h = 0;
|
d->current_has_feat21h = 0;
|
||||||
d->current_feat21h_link_size = -1;
|
d->current_feat21h_link_size = -1;
|
||||||
|
d->current_feat23h_byte4 = 0;
|
||||||
|
d->current_feat23h_byte8 = 0;
|
||||||
d->current_feat2fh_byte4 = -1;
|
d->current_feat2fh_byte4 = -1;
|
||||||
d->needs_close_session = 0;
|
d->needs_close_session = 0;
|
||||||
d->needs_sync_cache = 0;
|
d->needs_sync_cache = 0;
|
||||||
d->bg_format_status = -1;
|
d->bg_format_status = -1;
|
||||||
d->num_format_descr = 0;
|
d->num_format_descr = 0;
|
||||||
d->complete_sessions = 0;
|
d->complete_sessions = 0;
|
||||||
|
d->state_of_last_session = -1;
|
||||||
d->last_track_no = 1;
|
d->last_track_no = 1;
|
||||||
d->media_capacity_remaining = 0;
|
d->media_capacity_remaining = 0;
|
||||||
d->media_lba_limit = 0;
|
d->media_lba_limit = 0;
|
||||||
|
d->media_read_capacity = 0x7fffffff;
|
||||||
d->pessimistic_buffer_free = 0;
|
d->pessimistic_buffer_free = 0;
|
||||||
d->pbf_altered = 0;
|
d->pbf_altered = 0;
|
||||||
d->wait_for_buffer_free = Libburn_wait_for_buffer_freE;
|
d->wait_for_buffer_free = Libburn_wait_for_buffer_freE;
|
||||||
|
@ -72,6 +72,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||||||
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||||
struct buffer *buf);
|
struct buffer *buf);
|
||||||
|
|
||||||
|
/* ts A81210 : Determine the upper limit of readable data size */
|
||||||
|
int mmc_read_capacity(struct burn_drive *d);
|
||||||
|
|
||||||
|
|
||||||
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
||||||
|
@ -385,7 +385,7 @@ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
|
|||||||
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
||||||
int value)
|
int value)
|
||||||
{
|
{
|
||||||
opts->do_stream_recording = !!value;
|
opts->do_stream_recording = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
@ -51,11 +51,17 @@ SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
|||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
#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.
|
device enumeration.
|
||||||
*/
|
*/
|
||||||
|
struct burn_drive_enumerator_struct {
|
||||||
|
int pos;
|
||||||
|
int info_count;
|
||||||
|
char **info_list;
|
||||||
|
};
|
||||||
|
|
||||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
#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 */
|
/* 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.
|
Operating system specific libburn definitions and declarations.
|
||||||
The macros defined here are used by libburn modules in order to
|
The macros defined here are used by libburn modules in order to
|
||||||
avoid own system dependent case distinctions.
|
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
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
@ -20,14 +20,23 @@
|
|||||||
#include "os-freebsd.h"
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
#else /* operating system case distinction */
|
#else
|
||||||
|
#ifdef __linux
|
||||||
|
|
||||||
|
|
||||||
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
||||||
#include "os-linux.h"
|
#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 */
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
@ -323,7 +323,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
|||||||
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size, i;
|
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size, i;
|
||||||
int sose_mem = 0, fd = -1, ret;
|
int sose_mem = 0, fd = -1, ret;
|
||||||
char msg[81], *wpt;
|
char msg[81], *wpt;
|
||||||
struct buffer buf;
|
struct buffer buf, *buffer_mem = d->buffer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define Libburn_read_data_adr_logginG 1
|
#define Libburn_read_data_adr_logginG 1
|
||||||
@ -443,7 +443,8 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
|||||||
d->silent_on_scsi_error = sose_mem;
|
d->silent_on_scsi_error = sose_mem;
|
||||||
if (err == BE_CANCELLED) {
|
if (err == BE_CANCELLED) {
|
||||||
/* Try to read a smaller part of the chunk */
|
/* 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)
|
if (flag & 2)
|
||||||
d->silent_on_scsi_error = 1;
|
d->silent_on_scsi_error = 1;
|
||||||
if (d->drive_role == 1) {
|
if (d->drive_role == 1) {
|
||||||
@ -484,7 +485,7 @@ ex:;
|
|||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
*/
|
*/
|
||||||
d->buffer = NULL;
|
d->buffer = buffer_mem;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
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 */
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 : >>> untestet yet wether this compiles */
|
/* ts A70909 */
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <err.h> /* XXX */
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 : >>> untestet yet wether this compiles */
|
/* ts A70909 */
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
|
||||||
@ -622,7 +622,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
char testpath[4096], *cpt;
|
char testpath[4096], *cpt;
|
||||||
long blocks;
|
long blocks;
|
||||||
int open_mode = O_RDWR, fd, ret;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
|
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
@ -642,6 +641,8 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#ifdef Libburn_if_this_was_linuX
|
#ifdef Libburn_if_this_was_linuX
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
|
int open_mode = O_RDWR, fd, ret;
|
||||||
|
|
||||||
if(burn_sg_open_o_excl)
|
if(burn_sg_open_o_excl)
|
||||||
open_mode |= O_EXCL;
|
open_mode |= O_EXCL;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
|
@ -260,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)
|
static int sgio_test(int fd)
|
||||||
{
|
{
|
||||||
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
|
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
|
||||||
@ -279,6 +310,33 @@ static int sgio_test(int fd)
|
|||||||
static int sg_handle_busy_device(char *fname, int os_errno)
|
static int sg_handle_busy_device(char *fname, int os_errno)
|
||||||
{
|
{
|
||||||
char msg[4096];
|
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 */
|
/* ts A60814 : i saw no way to do this more nicely */
|
||||||
if (burn_sg_open_abort_busy) {
|
if (burn_sg_open_abort_busy) {
|
||||||
@ -292,10 +350,26 @@ static int sg_handle_busy_device(char *fname, int os_errno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ts A60924 : now reporting to libdax_msgs */
|
/* ts A60924 : now reporting to libdax_msgs */
|
||||||
sprintf(msg, "Cannot open busy device '%s'", fname);
|
if (looks_like_hd == 2) { /* is surely hard disk */
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020001,
|
;
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW,
|
} else if (looks_like_hd) {
|
||||||
msg, os_errno, 0);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,12 +644,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
|
/** 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 */
|
then on used used via generic SCSI as is done with (emulated) SCSI drives */
|
||||||
static void ata_enumerate(void)
|
static void ata_enumerate(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#else
|
||||||
struct hd_driveid tm;
|
struct hd_driveid tm;
|
||||||
int i, fd;
|
int fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int i;
|
||||||
char fname[10];
|
char fname[10];
|
||||||
|
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
@ -596,6 +851,17 @@ static void ata_enumerate(void)
|
|||||||
fprintf(stderr, "not in whitelist\n");
|
fprintf(stderr, "not in whitelist\n");
|
||||||
continue;
|
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);
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
@ -632,6 +898,10 @@ static void ata_enumerate(void)
|
|||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
fprintf(stderr, "accepting as drive without SCSI address\n");
|
fprintf(stderr, "accepting as drive without SCSI address\n");
|
||||||
enumerate_common(fname, -1, -1, -1, -1, -1);
|
enumerate_common(fname, -1, -1, -1, -1, -1);
|
||||||
@ -642,12 +912,18 @@ static void ata_enumerate(void)
|
|||||||
/** Detects (probably emulated) SCSI drives */
|
/** Detects (probably emulated) SCSI drives */
|
||||||
static void sg_enumerate(void)
|
static void sg_enumerate(void)
|
||||||
{
|
{
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
|
#else
|
||||||
struct sg_scsi_id sid;
|
struct sg_scsi_id sid;
|
||||||
int i, fd, sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0, ret;
|
int fd, sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0;
|
||||||
int sid_ret = 0;
|
|
||||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
|
||||||
char fname[10];
|
|
||||||
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];
|
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();
|
sg_select_device_family();
|
||||||
|
|
||||||
@ -661,6 +937,9 @@ static void sg_enumerate(void)
|
|||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
sprintf(fname, linux_sg_device_family, i);
|
sprintf(fname, linux_sg_device_family, i);
|
||||||
|
|
||||||
|
/* ts A80702 */
|
||||||
|
sg_exchange_scd_for_sr(fname, 0);
|
||||||
|
|
||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
fprintf(stderr, "libburn_debug: %s : ", fname);
|
fprintf(stderr, "libburn_debug: %s : ", fname);
|
||||||
|
|
||||||
@ -671,6 +950,23 @@ static void sg_enumerate(void)
|
|||||||
continue;
|
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 */
|
/* ts A60927 */
|
||||||
fd = sg_open_drive_fd(fname, 1);
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
@ -780,16 +1076,223 @@ static void sg_enumerate(void)
|
|||||||
#else
|
#else
|
||||||
bus_no = sid.host_no;
|
bus_no = sid.host_no;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||||
sid.host_no, sid.channel, sid.scsi_id, sid.lun,
|
sid.host_no, sid.channel, sid.scsi_id, sid.lun,
|
||||||
bus_no);
|
bus_no);
|
||||||
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
|
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
|
||||||
sid.scsi_id, sid.lun);
|
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 */
|
/* ts A61115 */
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/* PORTING: Private functions which contain publicly needed functionality. */
|
/* PORTING: Private functions which contain publicly needed functionality. */
|
||||||
@ -874,10 +1377,14 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
{
|
{
|
||||||
/* os-linux.h : typedef int burn_drive_enumerator_t; */
|
/* os-linux.h : typedef int burn_drive_enumerator_t; */
|
||||||
static int sg_limit = 32, ata_limit = 26;
|
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;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sg_select_device_family();
|
sg_select_device_family();
|
||||||
if (linux_sg_device_family[0] == 0)
|
if (linux_sg_device_family[0] == 0)
|
||||||
@ -885,26 +1392,56 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
if (linux_ata_device_family[0] == 0)
|
if (linux_ata_device_family[0] == 0)
|
||||||
ata_limit = 0;
|
ata_limit = 0;
|
||||||
|
|
||||||
if (initialize == 1)
|
if (initialize == 1) {
|
||||||
*idx = -1;
|
idx->pos = -1;
|
||||||
(*idx)++;
|
idx->info_count= 0;
|
||||||
if (*idx >= sg_limit)
|
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;
|
goto next_ata;
|
||||||
if (adr_size < 10)
|
if (adr_size < 11)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(adr, linux_sg_device_family, *idx);
|
sprintf(adr, linux_sg_device_family, idx->pos);
|
||||||
return 1;
|
|
||||||
|
sg_exchange_scd_for_sr(adr, 0);
|
||||||
|
goto return_1_pre_proc;
|
||||||
|
|
||||||
next_ata:;
|
next_ata:;
|
||||||
baseno += sg_limit;
|
baseno += sg_limit;
|
||||||
if (*idx - baseno >= ata_limit)
|
if (idx->pos - baseno >= ata_limit)
|
||||||
goto next_nothing;
|
goto next_proc_info;
|
||||||
if (adr_size < 9)
|
if (adr_size < 9)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(adr, linux_ata_device_family, 'a' + (*idx - baseno));
|
sprintf(adr, linux_ata_device_family, 'a' + (idx->pos - baseno));
|
||||||
return 1;
|
goto return_1_pre_proc;
|
||||||
next_nothing:;
|
|
||||||
|
next_proc_info:;
|
||||||
baseno += ata_limit;
|
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 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -926,8 +1463,27 @@ next_nothing:;
|
|||||||
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
||||||
int scsi_enumerate_drives(void)
|
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();
|
sg_enumerate();
|
||||||
ata_enumerate();
|
ata_enumerate();
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
add_proc_info_drives(0);
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1378,9 +1934,9 @@ int sg_is_enumerable_adr(char *adr)
|
|||||||
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
||||||
return 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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
libburn/sg.c
28
libburn/sg.c
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* sg.c
|
/* sg.c
|
||||||
Switcher for operating system dependent transport level modules of libburn.
|
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"
|
#include "sg-freebsd.c"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
#ifdef __linux
|
||||||
|
|
||||||
#include "sg-linux.c"
|
#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__ */
|
||||||
|
|
||||||
|
359
libburn/spc.c
359
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 flag)
|
||||||
{
|
{
|
||||||
int i, ret = 1, key = 0, asc = 0, ascq = 0;
|
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))
|
if (!(flag & 1))
|
||||||
usleep(100000);
|
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);
|
i, ret, (unsigned) key, (unsigned) asc, (unsigned) ascq);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(ret > 0) /* ready */
|
if (ret > 0) /* ready */
|
||||||
break;
|
break;
|
||||||
if(key!=0x2 || asc!=0x4) {
|
if (key!=0x2 || asc!=0x4) {
|
||||||
if (key == 0x2 && asc == 0x3A) {
|
if (key == 0x2 && asc == 0x3A) {
|
||||||
ret = 1; /* medium not present = ok */
|
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 */
|
/* media change notice = try again */
|
||||||
goto slumber;
|
goto slumber;
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
|
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
cmd_text, (unsigned) key, (unsigned) asc,
|
cmd_text, (unsigned) key, (unsigned) asc,
|
||||||
(unsigned) ascq);
|
(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,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002014d,
|
0x0002014d,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -568,7 +584,7 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
|
|
||||||
/* ts A71128 : do not interpret reply if error */
|
/* ts A71128 : do not interpret reply if error */
|
||||||
m = d->mdata;
|
m = d->mdata;
|
||||||
if(!c.error) {
|
if (!c.error) {
|
||||||
size = c.page->data[0] * 256 + c.page->data[1];
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
page = c.page->data + 8;
|
page = c.page->data + 8;
|
||||||
burn_print(1, "write page length 0x%x\n", page[1]);
|
burn_print(1, "write page length 0x%x\n", page[1]);
|
||||||
@ -845,7 +861,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));
|
d->mdata = calloc(1, sizeof(struct scsi_mode_data));
|
||||||
|
|
||||||
/* ts A61007 : obsolete Assert in drive_getcaps() */
|
/* 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_submit(libdax_messenger, -1, 0x00020108,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Could not allocate new drive object", 0, 0);
|
"Could not allocate new drive object", 0, 0);
|
||||||
@ -854,7 +870,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
|||||||
d->idata->valid = 0;
|
d->idata->valid = 0;
|
||||||
d->mdata->valid = 0;
|
d->mdata->valid = 0;
|
||||||
d->mdata->speed_descriptors = NULL;
|
d->mdata->speed_descriptors = NULL;
|
||||||
if(!(flag & 1)) {
|
if (!(flag & 1)) {
|
||||||
ret = spc_setup_drive(d);
|
ret = spc_setup_drive(d);
|
||||||
if (ret<=0)
|
if (ret<=0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -869,11 +885,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,
|
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)
|
int *key, int *asc, int *ascq)
|
||||||
{
|
{
|
||||||
|
char *msg;
|
||||||
|
|
||||||
|
msg= msg_data;
|
||||||
*key= *asc= *ascq= -1;
|
*key= *asc= *ascq= -1;
|
||||||
|
|
||||||
if (senselen<=0 || senselen>2)
|
if (senselen<=0 || senselen>2)
|
||||||
@ -883,50 +902,258 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
if (senselen<=0 || senselen>13)
|
if (senselen<=0 || senselen>13)
|
||||||
*ascq = sense[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",
|
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
|
||||||
*key, *asc, *ascq, d->idata->vendor, d->idata->product);
|
*key, *asc, *ascq, d->idata->vendor, d->idata->product);
|
||||||
|
|
||||||
switch (*asc) {
|
switch (*asc) {
|
||||||
case 0:
|
case 0x00:
|
||||||
sprintf(msg, "(no error reported by SCSI transaction)");
|
sprintf(msg, "(No error reported by SCSI transaction)");
|
||||||
return RETRY;
|
return RETRY;
|
||||||
|
|
||||||
case 2:
|
case 0x02:
|
||||||
sprintf(msg, "not ready");
|
sprintf(msg, "Not ready");
|
||||||
return RETRY;
|
return RETRY;
|
||||||
case 4:
|
case 0x04:
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"logical unit is in the process of becoming ready");
|
"Logical unit is in the process of becoming ready");
|
||||||
return RETRY;
|
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:
|
case 0x20:
|
||||||
if (*key == 5)
|
if (*key != 5)
|
||||||
sprintf(msg, "bad opcode");
|
break;
|
||||||
|
sprintf(msg, "Invalid command operation code");
|
||||||
return FAIL;
|
return FAIL;
|
||||||
case 0x21:
|
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;
|
return FAIL;
|
||||||
case 0x24:
|
case 0x24:
|
||||||
if (*key == 5)
|
if (*key != 5)
|
||||||
sprintf(msg, "invalid field in cdb");
|
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
|
sprintf(msg, "Invalid field in cdb");
|
||||||
return FAIL;
|
return FAIL;
|
||||||
case 0x26:
|
case 0x26:
|
||||||
if (*key == 5 )
|
if (*key != 5)
|
||||||
sprintf(msg, "invalid field in parameter list" );
|
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;
|
return FAIL;
|
||||||
case 0x28:
|
case 0x28:
|
||||||
if (*key == 6)
|
if (*key != 6)
|
||||||
|
break;
|
||||||
|
if (*ascq == 0)
|
||||||
sprintf(msg, "Medium may have changed");
|
sprintf(msg, "Medium may have changed");
|
||||||
|
else if (*ascq == 2)
|
||||||
|
sprintf(msg, "Format layer may have changed");
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
return RETRY;
|
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:
|
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;
|
d->status = BURN_DISC_EMPTY;
|
||||||
return FAIL;
|
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",
|
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
|
||||||
*key, *asc, *ascq);
|
*key, *asc, *ascq);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@ -951,6 +1178,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 */
|
/* ts A61030 - A61115 */
|
||||||
/* @param flag bit0=do report conditions which are considered not an error */
|
/* @param flag bit0=do report conditions which are considered not an error */
|
||||||
int scsi_notify_error(struct burn_drive *d, struct command *c,
|
int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||||
@ -962,12 +1251,9 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
|||||||
if (d->silent_on_scsi_error)
|
if (d->silent_on_scsi_error)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
strcpy(scsi_msg, " \"");
|
scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq);
|
||||||
scsi_error_msg(d, sense, senselen, scsi_msg + strlen(scsi_msg),
|
|
||||||
&key, &asc, &ascq);
|
|
||||||
strcat(scsi_msg, "\"");
|
|
||||||
|
|
||||||
if(!(flag & 1)) {
|
if (!(flag & 1)) {
|
||||||
/* SPC : TEST UNIT READY command */
|
/* SPC : TEST UNIT READY command */
|
||||||
if (c->opcode[0] == 0)
|
if (c->opcode[0] == 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -978,7 +1264,11 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
|||||||
return 1;
|
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)
|
if (key>=0)
|
||||||
sprintf(msg+strlen(msg), " key=%Xh", key);
|
sprintf(msg+strlen(msg), " key=%Xh", key);
|
||||||
if (asc>=0)
|
if (asc>=0)
|
||||||
@ -992,6 +1282,13 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
|||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
scsi_msg,0,0);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +104,30 @@ int burn_disc_add_session(struct burn_disc *d, struct burn_session *s,
|
|||||||
return 1;
|
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 *burn_track_create(void)
|
||||||
{
|
{
|
||||||
struct burn_track *t;
|
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)
|
int burn_track_get_sectors(struct burn_track *t)
|
||||||
{
|
{
|
||||||
/* ts A70125 : was int */
|
/* ts A70125 : was int */
|
||||||
off_t size;
|
off_t size = 0;
|
||||||
int sectors, seclen;
|
int sectors, seclen;
|
||||||
|
|
||||||
seclen = burn_sector_length(t->mode);
|
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;
|
sectors = size / seclen;
|
||||||
if (size % seclen)
|
if (size % seclen)
|
||||||
sectors++;
|
sectors++;
|
||||||
@ -468,6 +500,7 @@ int burn_session_get_sectors(struct burn_session *s)
|
|||||||
return sectors;
|
return sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_disc_get_sectors(struct burn_disc *d)
|
int burn_disc_get_sectors(struct burn_disc *d)
|
||||||
{
|
{
|
||||||
int sectors = 0, i;
|
int sectors = 0, i;
|
||||||
@ -515,3 +548,84 @@ int burn_session_get_hidefirst(struct burn_session *session)
|
|||||||
{
|
{
|
||||||
return session->hidefirst;
|
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);
|
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 */
|
#endif /* BURN__STRUCTURE_H */
|
||||||
|
@ -171,6 +171,19 @@ struct burn_drive
|
|||||||
/* Link Size item number 0 from feature 0021h descriptor */
|
/* Link Size item number 0 from feature 0021h descriptor */
|
||||||
int current_feat21h_link_size;
|
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 :
|
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
|
||||||
bit1= DVD-RW supported
|
bit1= DVD-RW supported
|
||||||
bit2= Test Write available
|
bit2= Test Write available
|
||||||
@ -192,6 +205,11 @@ struct burn_drive
|
|||||||
with BD-RE */
|
with BD-RE */
|
||||||
int do_stream_recording;
|
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 */
|
/* ts A61218 from 51h READ DISC INFORMATION */
|
||||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||||
|
|
||||||
@ -223,6 +241,9 @@ struct burn_drive
|
|||||||
|
|
||||||
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
||||||
int complete_sessions;
|
int complete_sessions;
|
||||||
|
/* ts A90107 */
|
||||||
|
int state_of_last_session;
|
||||||
|
|
||||||
/* ts A70129 :
|
/* ts A70129 :
|
||||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||||
int last_track_no;
|
int last_track_no;
|
||||||
@ -235,6 +256,9 @@ struct burn_drive
|
|||||||
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
||||||
int media_lba_limit;
|
int media_lba_limit;
|
||||||
|
|
||||||
|
/* ts A81210 : Upper limit of readable data size,
|
||||||
|
0x7fffffff = unknown */
|
||||||
|
int media_read_capacity;
|
||||||
|
|
||||||
int toc_temp;
|
int toc_temp;
|
||||||
struct burn_disc *disc; /* disc structure */
|
struct burn_disc *disc; /* disc structure */
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
#include <stdlib.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 "util.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
|
|
||||||
@ -48,13 +52,7 @@ char *burn_strndup(char *s, int n)
|
|||||||
void burn_version(int *major, int *minor, int *micro)
|
void burn_version(int *major, int *minor, int *micro)
|
||||||
{
|
{
|
||||||
/* ts A80408 : switched from configure.ac versioning to libburn.h versioning */
|
/* ts A80408 : switched from configure.ac versioning to libburn.h versioning */
|
||||||
#ifdef burn_header_version_major
|
*major = burn_header_version_major;
|
||||||
*major = burn_header_version_major;
|
*minor = burn_header_version_minor;
|
||||||
*minor = burn_header_version_minor;
|
*micro = burn_header_version_micro;
|
||||||
*micro = burn_header_version_micro;
|
|
||||||
#else
|
|
||||||
*major = BURN_MAJOR_VERSION;
|
|
||||||
*minor = BURN_MINOR_VERSION;
|
|
||||||
*micro = BURN_MICRO_VERSION;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
147
libburn/write.c
147
libburn/write.c
@ -1005,8 +1005,10 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|||||||
} else if (d->drive_role == 3 ||
|
} else if (d->drive_role == 3 ||
|
||||||
d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||||
d->current_profile == 0x15 ||
|
d->current_profile == 0x15 ||
|
||||||
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
|
d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
||||||
/* DVD-R* Sequential , DVD+R[/DL] , sequential stdio "drive" */
|
d->current_profile == 0x41) {
|
||||||
|
/* DVD-R* Sequential , DVD+R[/DL] , BD-R,
|
||||||
|
sequential stdio "drive" */
|
||||||
if (o->start_byte >= 0)
|
if (o->start_byte >= 0)
|
||||||
strcat(reasons, "write start address not supported, ");
|
strcat(reasons, "write start address not supported, ");
|
||||||
} else {
|
} else {
|
||||||
@ -1106,6 +1108,10 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
if (o->write_type == BURN_WRITE_SAO &&
|
if (o->write_type == BURN_WRITE_SAO &&
|
||||||
! burn_track_is_open_ended(s->track[tnum])) {
|
! burn_track_is_open_ended(s->track[tnum])) {
|
||||||
/* Round track size up to 32 KiB and reserve track */
|
/* Round track size up to 32 KiB and reserve track */
|
||||||
|
|
||||||
|
/* ts A81208 */
|
||||||
|
/* >>> ??? round to 64 KiB for BD-R ? (It is not mandatory) */
|
||||||
|
|
||||||
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
||||||
* (off_t) 2048;
|
* (off_t) 2048;
|
||||||
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
||||||
@ -1153,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)
|
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = o->drive;
|
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,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00000002,
|
0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
"Finalizing DVD+R ...", 0, 0);
|
msg, 0, 0);
|
||||||
|
|
||||||
/* CLOSE SESSION, 101b, Finalize with minimal radius */
|
if(d->current_profile == 0x41) { /* BD-R */
|
||||||
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
|
/* 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,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00000002,
|
0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
"... finalizing DVD+R done ", 0, 0);
|
msg, 0, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1200,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,
|
int burn_dvd_write_track(struct burn_write_opts *o,
|
||||||
struct burn_session *s, int tnum, int is_last_track)
|
struct burn_session *s, int tnum, int is_last_track)
|
||||||
{
|
{
|
||||||
@ -1224,6 +1240,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto ex;
|
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);
|
sectors = burn_track_get_sectors(t);
|
||||||
@ -1292,6 +1313,12 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
is_last_track);
|
is_last_track);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto ex;
|
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;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
@ -1372,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,
|
int burn_dvd_write_session(struct burn_write_opts *o,
|
||||||
struct burn_session *s, int is_last_session)
|
struct burn_session *s, int is_last_session)
|
||||||
{
|
{
|
||||||
int i,ret;
|
int i, ret, multi_mem;
|
||||||
struct burn_drive *d = o->drive;
|
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++) {
|
for (i = 0; i < s->tracks; i++) {
|
||||||
ret = burn_dvd_write_track(o, s, i,
|
ret = burn_dvd_write_track(o, s, i,
|
||||||
@ -1386,7 +1473,11 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
|||||||
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||||
d->current_profile == 0x15) {
|
d->current_profile == 0x15) {
|
||||||
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
|
/* 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);
|
ret = burn_disc_close_session_dvd_minus_r(o, s);
|
||||||
|
o->multi = multi_mem;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
|
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
|
||||||
@ -1408,6 +1499,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||||
/* DVD+R , DVD+R/DL do each track as an own session */;
|
/* 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;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1611,8 +1704,12 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
/* ??? padding needed ??? cowardly doing it for now */
|
/* ??? padding needed ??? cowardly doing it for now */
|
||||||
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
||||||
|
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
||||||
/* DVD+R , DVD+R/DL */
|
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];
|
t = disc->session[0]->track[0];
|
||||||
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
|
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
|
||||||
default_size = burn_track_get_default_size(t);
|
default_size = burn_track_get_default_size(t);
|
||||||
@ -1627,8 +1724,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
ret = burn_disc_setup_dvd_plus_r(o, disc);
|
ret = burn_disc_setup_dvd_plus_r(o, disc);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
sprintf(msg,
|
sprintf(msg, "Write preparation setup failed for %s",
|
||||||
"Write preparation setup failed for DVD+R");
|
d->current_profile == 0x41 ? "BD-R" : "DVD+R");
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020121,
|
0x00020121,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -1996,9 +2093,9 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
|||||||
{
|
{
|
||||||
struct cue_sheet *sheet;
|
struct cue_sheet *sheet;
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
struct buffer buf;
|
struct buffer buf, *buffer_mem = o->drive->buffer;
|
||||||
struct burn_track *lt, *t;
|
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;
|
off_t default_size;
|
||||||
char msg[80];
|
char msg[80];
|
||||||
|
|
||||||
@ -2009,8 +2106,12 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
|||||||
/* ts A61224 */
|
/* ts A61224 */
|
||||||
burn_disc_init_write_status(o, disc); /* must be done very early */
|
burn_disc_init_write_status(o, disc); /* must be done very early */
|
||||||
|
|
||||||
/* ts A80412 */
|
/* ts A80412 , A90227 */
|
||||||
d->do_stream_recording = o->do_stream_recording;
|
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 = &buf;
|
d->buffer = &buf;
|
||||||
memset(d->buffer, 0, sizeof(struct buffer));
|
memset(d->buffer, 0, sizeof(struct buffer));
|
||||||
@ -2148,7 +2249,12 @@ return crap. so we send the command, then ignore the result.
|
|||||||
d->alba += 4500;
|
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;
|
goto fail;
|
||||||
|
|
||||||
lt = disc->session[i]->track[disc->session[i]->tracks - 1];
|
lt = disc->session[i]->track[disc->session[i]->tracks - 1];
|
||||||
@ -2206,6 +2312,7 @@ fail_wo_sync:;
|
|||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
ex:;
|
ex:;
|
||||||
d->do_stream_recording = 0;
|
d->do_stream_recording = 0;
|
||||||
|
d->buffer = buffer_mem;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2215,7 +2322,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
{
|
{
|
||||||
int alignment = 0, start, upto, chunksize, err, fd = -1, ret;
|
int alignment = 0, start, upto, chunksize, err, fd = -1, ret;
|
||||||
char msg[81], *rpt;
|
char msg[81], *rpt;
|
||||||
struct buffer buf;
|
struct buffer buf, *buffer_mem = d->buffer;
|
||||||
|
|
||||||
if (d->released) {
|
if (d->released) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
@ -2326,7 +2433,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
|
|
||||||
if(fd >= 0)
|
if(fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
d->buffer = NULL;
|
d->buffer = buffer_mem;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
/* 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 */
|
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
|
||||||
|
|
||||||
|
|
||||||
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
libburner is a minimal demo application for the library libburn as provided
|
libburner is a minimal demo application for the library libburn as provided
|
||||||
on http://libburnia-project.org . It can list the available devices, can
|
on http://libburnia-project.org . It can list the available devices, can
|
||||||
blank a CD-RW or DVD-RW, can format DVD-RW and BD-RE, can burn to CD-R,
|
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-RE.
|
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, BD-R.
|
Not supported yet: DVD-R/DL.
|
||||||
|
|
||||||
It's main purpose, nevertheless, is to show you how to use libburn and also
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
to serve the libburnia team as reference application. libburner.c does indeed
|
to serve the libburnia team as reference application. libburner.c does indeed
|
||||||
@ -29,9 +29,9 @@
|
|||||||
With that aquired drive you can blank a CD-RW
|
With that aquired drive you can blank a CD-RW
|
||||||
libburner_blank_disc()
|
libburner_blank_disc()
|
||||||
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
||||||
or an unused BD-RE to default size
|
or an unused BD to default size with spare blocks
|
||||||
libburner_format_owrt()
|
libburner_format()
|
||||||
With the aquired drive you can burn to CD or DVD
|
With the aquired drive you can burn to CD, DVD, BD
|
||||||
libburner_payload()
|
libburner_payload()
|
||||||
When everything is done, main() releases the drive and shuts down libburn:
|
When everything is done, main() releases the drive and shuts down libburn:
|
||||||
burn_drive_release();
|
burn_drive_release();
|
||||||
@ -260,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
|
To our knowledge it is hardly possible to abort an ongoing blank operation
|
||||||
because after start it is entirely handled by the drive.
|
because after start it is entirely handled by the drive.
|
||||||
@ -322,24 +323,35 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
Formats unformatted BD-RE to default size. This will allocate some
|
Formats unformatted BD-RE to default size. This will allocate some
|
||||||
reserve space, test for bad blocks and make the media ready for writing.
|
reserve space, test for bad blocks and make the media ready for writing.
|
||||||
Expect a very long run time.
|
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_owrt(struct burn_drive *drive)
|
int libburner_format(struct burn_drive *drive)
|
||||||
{
|
{
|
||||||
struct burn_progress p;
|
struct burn_progress p;
|
||||||
double percent = 1.0;
|
double percent = 1.0;
|
||||||
int ret, status, num_formats, format_flag= 0;
|
int ret, status, num_formats, format_flag= 0;
|
||||||
off_t size = 0;
|
off_t size = 0;
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
|
enum burn_disc_status disc_state;
|
||||||
|
|
||||||
if (current_profile == 0x13) {
|
if (current_profile == 0x13) {
|
||||||
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
|
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
|
||||||
return 2;
|
return 2;
|
||||||
} else if (current_profile == 0x43) {
|
} 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,
|
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
|
||||||
&num_formats);
|
&num_formats);
|
||||||
if (ret > 0 && status == BURN_FORMAT_IS_FORMATTED) {
|
if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"IDLE: BD-RE media is already formatted\n");
|
"IDLE: BD media is already formatted\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
size = 0; /* does not really matter */
|
size = 0; /* does not really matter */
|
||||||
@ -348,7 +360,7 @@ int libburner_format_owrt(struct burn_drive *drive)
|
|||||||
size = 128 * 1024 * 1024;
|
size = 128 * 1024 * 1024;
|
||||||
format_flag = 1; /* write initial 128 MiB */
|
format_flag = 1; /* write initial 128 MiB */
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "FATAL: Can only format DVD-RW or BD-RE\n");
|
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +488,7 @@ int libburner_payload(struct burn_drive *drive,
|
|||||||
/* Give up local reference to the data burn_source object */
|
/* Give up local reference to the data burn_source object */
|
||||||
burn_source_free(data_src);
|
burn_source_free(data_src);
|
||||||
|
|
||||||
} /* trackno loop end */
|
} /* trackno loop end */
|
||||||
|
|
||||||
/* Evaluate drive and media */
|
/* Evaluate drive and media */
|
||||||
disc_state = burn_disc_get_status(drive);
|
disc_state = burn_disc_get_status(drive);
|
||||||
@ -614,7 +626,8 @@ int libburner_setup(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
strcpy(drive_adr, argv[i]);
|
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;
|
do_blank = 101;
|
||||||
|
|
||||||
} else if (!strcmp(argv[i], "--multi")) {
|
} else if (!strcmp(argv[i], "--multi")) {
|
||||||
@ -655,8 +668,7 @@ int libburner_setup(int argc, char **argv)
|
|||||||
if (print_help || insuffient_parameters ) {
|
if (print_help || insuffient_parameters ) {
|
||||||
printf("Usage: %s\n", argv[0]);
|
printf("Usage: %s\n", argv[0]);
|
||||||
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
|
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
|
||||||
printf(" [--blank_fast|--blank_full|--format_overwrite]\n");
|
printf(" [--blank_fast|--blank_full|--format] [--try_to_simulate]\n");
|
||||||
printf(" [--try_to_simulate]\n");
|
|
||||||
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
|
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
|
||||||
printf("Examples\n");
|
printf("Examples\n");
|
||||||
printf("A bus scan (needs rw-permissions to see a drive):\n");
|
printf("A bus scan (needs rw-permissions to see a drive):\n");
|
||||||
@ -669,8 +681,8 @@ int libburner_setup(int argc, char **argv)
|
|||||||
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
|
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("Blank a used DVD-RW (is combinable with burning in one run):\n");
|
||||||
printf(" %s --drive /dev/hdc --blank_full\n",argv[0]);
|
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("Format a DVD-RW, BD-RE or BD-R:\n");
|
||||||
printf(" %s --drive /dev/hdc --format_overwrite\n", argv[0]);
|
printf(" %s --drive /dev/hdc --format\n", argv[0]);
|
||||||
printf("Burn two audio tracks (to CD only):\n");
|
printf("Burn two audio tracks (to CD only):\n");
|
||||||
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
||||||
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
||||||
@ -720,7 +732,7 @@ int main(int argc, char **argv)
|
|||||||
{ ret = 0; goto release_drive; }
|
{ ret = 0; goto release_drive; }
|
||||||
if (do_blank) {
|
if (do_blank) {
|
||||||
if (do_blank > 100)
|
if (do_blank > 100)
|
||||||
ret = libburner_format_owrt(drive_list[driveno].drive);
|
ret = libburner_format(drive_list[driveno].drive);
|
||||||
else
|
else
|
||||||
ret = libburner_blank_disc(drive_list[driveno].drive,
|
ret = libburner_blank_disc(drive_list[driveno].drive,
|
||||||
do_blank == 1);
|
do_blank == 1);
|
||||||
|
Reference in New Issue
Block a user