Compare commits
110 Commits
ZeroSevenF
...
ZeroEightT
Author | SHA1 | Date | |
---|---|---|---|
7e01bae7e6 | |||
7c0a33420a | |||
101a8813d5 | |||
3a5acf9989 | |||
e9828cddd0 | |||
7f0358892a | |||
bc40ce2876 | |||
6674667b7f | |||
cc4d72bf8b | |||
1eee6ab8a0 | |||
736d8b9019 | |||
8345eb8a71 | |||
cc7548f1c7 | |||
edca339338 | |||
9323cceff1 | |||
8b1b3f08c6 | |||
e332f4a438 | |||
960fe6d188 | |||
92c5f6f998 | |||
2069ffa863 | |||
e787d328c7 | |||
fafc190fd4 | |||
e6029ae238 | |||
6e17c59f6b | |||
0e777ec688 | |||
8dcdb5a87f | |||
4f372c00bc | |||
9f6d80d87d | |||
b33df8fbd5 | |||
b4bb522053 | |||
3289ffd1e6 | |||
196ef37108 | |||
cdad7fcd80 | |||
ed6e2df81b | |||
ae667ca2e8 | |||
873e3f5d78 | |||
72f9ff8b8c | |||
eb95f7fc16 | |||
3519b42c14 | |||
b4e5afd317 | |||
7446ed7daa | |||
2d40b098e5 | |||
ac64aef090 | |||
74a68adc6e | |||
937bc87bfc | |||
de482489c1 | |||
295fa1d526 | |||
99bba3e98e | |||
bd3016e085 | |||
dd74364ebb | |||
255e5362f9 | |||
471a0d0058 | |||
f5b556db47 | |||
c12bbff7d1 | |||
6db992e646 | |||
bd017a108e | |||
3a76f9245f | |||
580ca08cc5 | |||
a6bd4c24db | |||
54005cb60e | |||
15fbe0a7ea | |||
da1d260753 | |||
95865ee34d | |||
eb8b8faa3b | |||
39fd8b922d | |||
7ead54c8b9 | |||
2a85fc7d91 | |||
1e42a76415 | |||
734759190a | |||
16ffa10831 | |||
cdfc357064 | |||
df612390d3 | |||
77971f3680 | |||
5c75d583d7 | |||
2ff03841d7 | |||
a88745c82e | |||
96167b3d8e | |||
1ca38962d4 | |||
80bcabfd57 | |||
d9239aeafc | |||
758a197d06 | |||
ed972271ec | |||
0544ac8cd3 | |||
12a2be8d86 | |||
509db68d82 | |||
00ed59f34e | |||
2b8e8c2521 | |||
e3ff0bb0f6 | |||
8efb24ca6d | |||
d53c5db98e | |||
0320b7bf2a | |||
cee271f9cb | |||
c2a3e3677d | |||
fc3445215b | |||
4ce8bd45cf | |||
08169d63bc | |||
e13b6369ba | |||
d3988dd74b | |||
ef42052900 | |||
240afa7c3a | |||
5b72e5d06e | |||
4aa08e32ff | |||
eb34561262 | |||
dd85e37ac8 | |||
e566340261 | |||
7e86db207c | |||
a30ecd1abb | |||
45b28b6c31 | |||
afedcdd72b | |||
b8a98e0728 |
@ -1,12 +1,12 @@
|
|||||||
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-2009 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2010 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
|
||||||
it under the terms of the GNU General Public License version 2 as
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
published by the Free Software Foundation.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
13
Makefile.am
13
Makefile.am
@ -70,9 +70,6 @@ libburn_libburn_la_SOURCES = \
|
|||||||
libburn/write.h \
|
libburn/write.h \
|
||||||
version.h
|
version.h
|
||||||
|
|
||||||
## libburn/lec.c \
|
|
||||||
## libburn/lec.h \
|
|
||||||
|
|
||||||
## libburn/sg-@ARCH@.c \
|
## libburn/sg-@ARCH@.c \
|
||||||
|
|
||||||
libinclude_HEADERS = \
|
libinclude_HEADERS = \
|
||||||
@ -113,9 +110,9 @@ test_structest_CPPFLAGS = -Ilibburn
|
|||||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
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 - A91012
|
## cdrskin construction site - ts A60816 - B00611
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_3
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_8_2
|
||||||
|
|
||||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
# 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
|
||||||
@ -202,10 +199,16 @@ EXTRA_DIST = \
|
|||||||
cdrskin/wiki_plain.txt \
|
cdrskin/wiki_plain.txt \
|
||||||
cdrskin/cleanup.h \
|
cdrskin/cleanup.h \
|
||||||
cdrskin/cleanup.c \
|
cdrskin/cleanup.c \
|
||||||
|
libburn/os-dummy.h \
|
||||||
libburn/os-freebsd.h \
|
libburn/os-freebsd.h \
|
||||||
libburn/os-linux.h \
|
libburn/os-linux.h \
|
||||||
|
libburn/os-libcdio.h \
|
||||||
|
libburn/os-solaris.h \
|
||||||
|
libburn/sg-dummy.c \
|
||||||
libburn/sg-freebsd.c \
|
libburn/sg-freebsd.c \
|
||||||
libburn/sg-linux.c \
|
libburn/sg-linux.c \
|
||||||
|
libburn/sg-libcdio.c \
|
||||||
|
libburn/sg-solaris.c \
|
||||||
COPYING \
|
COPYING \
|
||||||
NEWS \
|
NEWS \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
|
96
README
96
README
@ -6,12 +6,12 @@ This all is under GPL.
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
libburn-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-2009 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
|
||||||
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||||
and Ben Jansens <xor@orodu.net>
|
and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
http://files.libburnia-project.org/releases/libburn-0.7.2.pl00.tar.gz
|
http://files.libburnia-project.org/releases/libburn-0.8.2.pl00.tar.gz
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
|||||||
|
|
||||||
From tarball
|
From tarball
|
||||||
|
|
||||||
Obtain libburn-0.7.2.pl00.tar.gz, take it to a directory of your choice and do:
|
Obtain libburn-0.8.2.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf libburn-0.7.2.pl00.tar.gz
|
tar xzf libburn-0.8.2.pl00.tar.gz
|
||||||
cd libburn-0.7.2
|
cd libburn-0.8.2
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
@ -72,6 +72,10 @@ configure time by:
|
|||||||
--enable-dvd-obs-64k
|
--enable-dvd-obs-64k
|
||||||
This may be combined with above --enable-track-src-odirect .
|
This may be combined with above --enable-track-src-odirect .
|
||||||
|
|
||||||
|
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
||||||
|
You may install it and re-run libburn's ./configure with option
|
||||||
|
--enable-libcdio
|
||||||
|
|
||||||
Make sure to re-compile all source files after running ./configure
|
Make sure to re-compile all source files after running ./configure
|
||||||
make clean ; make
|
make clean ; make
|
||||||
make install
|
make install
|
||||||
@ -101,8 +105,9 @@ 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
|
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
||||||
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
|
||||||
|
and on OpenSolaris (tested with kernel 5.11).
|
||||||
On other X/Open compliant systems there will only be pseudo drives, but no
|
On other X/Open compliant systems there will only be pseudo drives, but no
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
direct MMC operation on real CD/DVD/BD drives.
|
||||||
|
|
||||||
@ -140,6 +145,8 @@ The project components (list subject to growth, hopefully):
|
|||||||
also allows to grow ISO-9660 filesystem images on multi-session
|
also allows to grow ISO-9660 filesystem images on multi-session
|
||||||
media as well as on overwriteable media via the same API.
|
media as well as on overwriteable media via the same API.
|
||||||
All media peculiarities are handled automatically.
|
All media peculiarities are handled automatically.
|
||||||
|
It also contains the methods of command oriented application
|
||||||
|
xorriso and offers them via a C language API.
|
||||||
|
|
||||||
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||||
cdrecord is a powerful GPL'ed burn program included in Joerg
|
cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||||
@ -159,6 +166,8 @@ The project components (list subject to growth, hopefully):
|
|||||||
changing, incremental backups, activating boot images, and
|
changing, incremental backups, activating boot images, and
|
||||||
extracting of files from ISO images to disk. An own ISO 9660
|
extracting of files from ISO images to disk. An own ISO 9660
|
||||||
extension stores ACLs, xattr, and MD5 of file content.
|
extension stores ACLs, xattr, and MD5 of file content.
|
||||||
|
All features of xorriso are also available via a C language API
|
||||||
|
of libisoburn.
|
||||||
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
|
||||||
@ -185,8 +194,8 @@ Applications must use 64 bit off_t. E.g. by defining
|
|||||||
#define _LARGEFILE_SOURCE
|
#define _LARGEFILE_SOURCE
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
or take special precautions to interface with the libraries by 64 bit integers
|
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
|
where the .h files prescribe off_t. To reduce libburn's off_t size to 32 bit
|
||||||
application from producing and processing ISO images of more than 2 GB size.
|
will keep it from processing tracks of more than 2 GB size.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@ -472,12 +481,58 @@ Project history as far as known to me:
|
|||||||
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
|
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
|
||||||
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
|
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
|
||||||
|
|
||||||
|
- 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners,
|
||||||
|
provides throughput enhancements with hampered busses on Linux, and new
|
||||||
|
API calls to log SCSI commands and to control the libburn fifo.
|
||||||
|
|
||||||
|
- 09 Dec 2009 libisoburn-0.4.6 allows performance tuning of output to DVD
|
||||||
|
drives or disk files.
|
||||||
|
|
||||||
|
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
|
||||||
|
the files of the generic system adapter for X/Open.
|
||||||
|
|
||||||
|
- 29 Dec 2009 Our project received a donation for purchasing a fine small
|
||||||
|
computer which shall serve as OS farm for development and support.
|
||||||
|
|
||||||
|
- 20 Jan 2010 Version 0.6.26 of libisofs fixes minor bugs and shall enhance
|
||||||
|
portability.
|
||||||
|
|
||||||
|
- 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD,
|
||||||
|
fixes bugs about the generic X/Open system adapter, and allows to use
|
||||||
|
libcdio >= 0.83 as SCSI transport facility.
|
||||||
|
|
||||||
|
- 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which
|
||||||
|
was introduced by version 0.6.22 in August 2009.
|
||||||
|
|
||||||
|
- 23 Feb 2010 libisoburn-0.5.0 marks the transition of the xorriso standalone
|
||||||
|
version to an official GNU project. The name changed to "GNU xorriso" and its
|
||||||
|
license is now GPLv3+.
|
||||||
|
The licenses of libburnia libraries and applications are not affected by
|
||||||
|
this change.
|
||||||
|
|
||||||
|
- 10 Mar 2010 libburn-0.7.8 fixes bugs and improves the built-in abort handler
|
||||||
|
on FreeBSD.
|
||||||
|
|
||||||
|
- 30 Mar 2010 Release 0.5.2 of libisoburn provides xorriso documentation in
|
||||||
|
GNU Texinfo format with embedded extra data to derive a full man page.
|
||||||
|
|
||||||
|
- 09 Apr 2010 libburn-0.8.0 now works with ahci driver on FreeBSD 8-STABLE.
|
||||||
|
|
||||||
|
- 03 May 2010 Version 0.6.32 of libisofs is able to create ISO images with
|
||||||
|
multiple boot images. All boot catalog parameters described in El-Torito
|
||||||
|
specs can be set and inquired. This allows to use GRUB boot images for EFI.
|
||||||
|
|
||||||
|
- 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs
|
||||||
|
capabilities about boot images.
|
||||||
|
|
||||||
|
- 11 Jun 2010 libburn-0.8.2 now works on Solaris.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
the Free Software Foundation. To be exact: version 2 of that License.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@ -495,16 +550,16 @@ other copyrighted code has been replaced by ours and by copyright-free
|
|||||||
contributions of our friends:
|
contributions of our friends:
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
We, the copyright holders, agree on the interpretation that dynamical linking
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
of our libraries constitutes "use of" and not "derivation from" our work in
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
the sense of GPL, provided those libraries are compiled from our unaltered
|
||||||
those libraries are compiled from our unaltered code.
|
code or from altered code published under GPL.
|
||||||
|
|
||||||
Thus you may link our libraries dynamically with applications
|
So we will not raise legal protest if you link our libraries dynamically with
|
||||||
which are not under GPL. You may distribute our libraries and
|
applications which are not under GPL, or if you distribute our libraries
|
||||||
application tools in binary form, if you fulfill the usual
|
and application tools in binary form, as long as you fulfill the usual
|
||||||
condition of GPL to offer a copy of the source code -altered
|
condition of GPL to offer a copy of their source code -altered or unaltered-
|
||||||
or unaltered- under GPL.
|
under GPL.
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
We ask you politely to use our work in open source spirit
|
||||||
and with the due reference to the entire open source community.
|
and with the due reference to the entire open source community.
|
||||||
@ -521,4 +576,5 @@ means to qualify for GPL.
|
|||||||
For now we are firmly committed to maintain one single license: GPL.
|
For now we are firmly committed to maintain one single license: GPL.
|
||||||
|
|
||||||
signed: Mario Danic, Thomas Schmitt
|
signed: Mario Danic, Thomas Schmitt
|
||||||
|
Agreement joined later by: Vreixo Formoso
|
||||||
|
|
||||||
|
21
acinclude.m4
21
acinclude.m4
@ -1,3 +1,14 @@
|
|||||||
|
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
||||||
|
[
|
||||||
|
case $target_os in
|
||||||
|
freebsd*)
|
||||||
|
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||||
|
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
AC_DEFUN([TARGET_SHIZZLE],
|
AC_DEFUN([TARGET_SHIZZLE],
|
||||||
[
|
[
|
||||||
ARCH=""
|
ARCH=""
|
||||||
@ -6,16 +17,20 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||||||
AC_MSG_CHECKING([target operating system])
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
|
|
||||||
case $target in
|
case $target_os in
|
||||||
*-*-linux*)
|
linux*)
|
||||||
ARCH=linux
|
ARCH=linux
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
;;
|
;;
|
||||||
*-*-freebsd*)
|
freebsd*)
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
||||||
;;
|
;;
|
||||||
|
kfreebsd*-gnu)
|
||||||
|
ARCH=freebsd
|
||||||
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
ARCH=
|
ARCH=
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
|
165
cdrskin/README
165
cdrskin/README
@ -4,17 +4,19 @@
|
|||||||
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.7.3.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-0.8.2.pl00.tar.gz
|
||||||
|
|
||||||
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
|
Copyright (C) 2006-2010 Thomas Schmitt, provided under GPL version 2 or later.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
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 supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
||||||
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
on FreeBSD and on OpenSolaris.
|
||||||
|
IDE drives under Linux 2.4. need kernel module ide-scsi.
|
||||||
|
ATA and SATA drives under FreeBSD need kernel module atapicam.
|
||||||
On other X/Open compliant systems there will only be emulated drives, but no
|
On other X/Open compliant systems there will only be emulated drives, but no
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
direct MMC operation on real CD/DVD/BD drives.
|
||||||
|
|
||||||
@ -24,10 +26,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.7.3.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-0.8.2.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-0.7.3.tar.gz
|
tar xzf cdrskin-0.8.2.pl00.tar.gz
|
||||||
cd cdrskin-0.7.3
|
cd cdrskin-0.8.2
|
||||||
|
|
||||||
Within that directory execute:
|
Within that directory execute:
|
||||||
|
|
||||||
@ -102,17 +104,25 @@ The output of cdrskin --devices might look like
|
|||||||
0 dev='/dev/sr0' rwrwr- : '_NEC' 'DVD_RW ND-4570A'
|
0 dev='/dev/sr0' rwrwr- : '_NEC' 'DVD_RW ND-4570A'
|
||||||
1 dev='/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
|
1 dev='/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
|
||||||
|
|
||||||
So full and insecure enabling of both for everybody would look like
|
On Linux, full and insecure enabling of both for everybody would look like
|
||||||
|
chmod a+rw /dev/sr0 /dev/hda
|
||||||
chmod a+rw /dev/sr0 /dev/sr1
|
|
||||||
|
|
||||||
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
||||||
|
|
||||||
|
On FreeBSD, device permissions are to be set in /etc/devfs.rules.
|
||||||
|
On Solaris, pfexec privileges may be restricted to "basic,sys_devices".
|
||||||
|
See below "System Dependend Drive Permission Examples".
|
||||||
|
|
||||||
I strongly discourage to run cdrskin with setuid root or via sudo !
|
I strongly discourage to run cdrskin with setuid root or via sudo !
|
||||||
It is not checked for the necessary degree of hacker safety.
|
It is not checked for the necessary degree of hacker safety.
|
||||||
|
Better consider to grant the necessary permissions to group "floppy"
|
||||||
|
and to add users to it.
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
Consider to put all authorized users into group "floppy", to chgrp the
|
|
||||||
device file to that group and to disallow w-access to others.
|
|
||||||
|
|
||||||
Helpful with Linux kernel 2.4 is a special SCSI feature:
|
Helpful with Linux kernel 2.4 is a special SCSI feature:
|
||||||
It is possible to address a scsi(-emulated) drive via associated device files
|
It is possible to address a scsi(-emulated) drive via associated device files
|
||||||
@ -121,11 +131,6 @@ 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
|
||||||
|
|
||||||
@ -145,7 +150,7 @@ Obtain some info about the drive
|
|||||||
cdrskin dev=0,1,0 -checkdrive
|
cdrskin dev=0,1,0 -checkdrive
|
||||||
|
|
||||||
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 -minfo
|
||||||
|
|
||||||
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
||||||
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
||||||
@ -398,13 +403,14 @@ drive. See man page section FILES for a way to lift that ban.
|
|||||||
Special compilation variations
|
Special compilation variations
|
||||||
|
|
||||||
All following options of ./configure and cdrskin/compile_cdrskin.sh are
|
All following options of ./configure and cdrskin/compile_cdrskin.sh are
|
||||||
combinable.
|
combinable. After runs of ./configure do as next:
|
||||||
|
make clean ; make
|
||||||
|
|
||||||
In some situations Linux may deliver a better write performance to drives if
|
In some situations Linux may deliver a better write performance to drives if
|
||||||
the track input is read with O_DIRECT (see man 2 open). The API call
|
the track input is read with O_DIRECT (see man 2 open). The API call
|
||||||
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
||||||
can be told to use this peculiar read mode by:
|
can be told to use this peculiar read mode by:
|
||||||
--enable-track-src-odirect
|
--enable-track-src-odirect
|
||||||
|
|
||||||
But often cdrskin option dvd_obs=64k will yield even better performance in
|
But often cdrskin option dvd_obs=64k will yield even better performance in
|
||||||
such a situation. 64k can be made default at compile time by
|
such a situation. 64k can be made default at compile time by
|
||||||
@ -412,6 +418,10 @@ such a situation. 64k can be made default at compile time by
|
|||||||
It can also be enabled at configure time by
|
It can also be enabled at configure time by
|
||||||
./configure ... --enable-dvd-obs-64k ...
|
./configure ... --enable-dvd-obs-64k ...
|
||||||
|
|
||||||
|
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
||||||
|
You may install it and re-run libburn's ./configure with option
|
||||||
|
--enable-libcdio
|
||||||
|
|
||||||
You may get a (super fat) statically linked binary by :
|
You may get a (super fat) statically linked binary by :
|
||||||
cdrskin/compile_cdrskin.sh -static
|
cdrskin/compile_cdrskin.sh -static
|
||||||
if your system supports static linking, at all. This will not help with kernels
|
if your system supports static linking, at all. This will not help with kernels
|
||||||
@ -427,6 +437,84 @@ It will not read startup files, will abort on option dev_translation= ,
|
|||||||
will not have a fifo buffer, and will not be able to put out help texts or
|
will not have a fifo buffer, and will not be able to put out help texts or
|
||||||
debugging messages.
|
debugging messages.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
System Dependend Drive Permission Examples
|
||||||
|
|
||||||
|
Accessing the optical drives requires privileges which usually are granted
|
||||||
|
only to the superuser. Linux, FreeBSD and Solaris offer quite different
|
||||||
|
approaches for avoiding the need for unrestricted privileges.
|
||||||
|
|
||||||
|
First check whether some friendly system setting already allows you to
|
||||||
|
access the drives as normal user:
|
||||||
|
cdrskin --devices
|
||||||
|
Those drives of which you see address and type strings are already usable.
|
||||||
|
|
||||||
|
If there remain drives invisible which the superuser can see by the same
|
||||||
|
command, then the following examples might help:
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
On all three systems:
|
||||||
|
---------------------
|
||||||
|
Add the authorized users of CD drives to group "floppy" in /etc/group.
|
||||||
|
If missing: create this group.
|
||||||
|
Changes to /etc/group often only affect new login sessions. So log out and in
|
||||||
|
before making the first tests.
|
||||||
|
|
||||||
|
---------
|
||||||
|
On Linux:
|
||||||
|
---------
|
||||||
|
Allow rw-access to the drives
|
||||||
|
chgrp floppy /dev/sr0 /dev/sr1
|
||||||
|
chmod g+rw /dev/sr0 /dev/sr1
|
||||||
|
It might be necessary to perform chgrp and chmod after each reboot or to
|
||||||
|
edit distro dependent device configuration files for permanent settings.
|
||||||
|
|
||||||
|
-----------
|
||||||
|
On FreeBSD:
|
||||||
|
-----------
|
||||||
|
Edit /etc/devfs.rules and make sure to have these lines
|
||||||
|
[localrules=10]
|
||||||
|
add path 'acd*' mode 0664 group floppy
|
||||||
|
add path 'cd*' mode 0664 group floppy
|
||||||
|
add path 'pass*' mode 0664 group floppy
|
||||||
|
add path 'xpt*' mode 0664 group floppy
|
||||||
|
[localrules=5]
|
||||||
|
add path 'pass*' mode 0664 group floppy
|
||||||
|
add path 'cd*' mode 0664 group floppy
|
||||||
|
add path 'xpt*' mode 0664 group floppy
|
||||||
|
add path 'acd*' mode 0664 group floppy
|
||||||
|
|
||||||
|
Edit /etc/rc.conf and add the following line if missing
|
||||||
|
devfs_system_ruleset="localrules"
|
||||||
|
|
||||||
|
This gets into effect by reboot or by command
|
||||||
|
/etc/rc.d/devfs start
|
||||||
|
|
||||||
|
-----------
|
||||||
|
On Solaris:
|
||||||
|
-----------
|
||||||
|
Run cdrskin by
|
||||||
|
pfexec cdrskin ...arguments...
|
||||||
|
|
||||||
|
The following settings will make pfexec keep original UID and EUID and prevent
|
||||||
|
most superuser powers. Be aware that you still can manipulate all device files
|
||||||
|
if you have the file permissions for that.
|
||||||
|
Full root privileges for cdrskin can then be aquired only by command su.
|
||||||
|
|
||||||
|
Edit /etc/security/exec_attr and add this line to the other "Media Backup"
|
||||||
|
lines:
|
||||||
|
Media Backup:solaris:cmd:::/usr/local/bin/cdrskin:privs=basic,sys_devices
|
||||||
|
Edit /etc/user_attr and add profile "Media Backup" to the user's line:
|
||||||
|
thomas::::profiles=Media Backup,Primary Administrator;roles=root
|
||||||
|
See also man privileges, man exec_attr, man user_attr.
|
||||||
|
|
||||||
|
Then allow the group r-access to the drives
|
||||||
|
pfexec chgrp floppy /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2
|
||||||
|
pfexec chmod g+r /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2
|
||||||
|
The last two commands have to be executed after each boot. I do not know
|
||||||
|
the relevant device configuration files yet.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Project aspects and legal stuff
|
Project aspects and legal stuff
|
||||||
@ -455,7 +543,7 @@ contributions in a due way.
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
as published by the Free Software Foundation.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
@ -471,7 +559,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-2009 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2010 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
|
||||||
@ -482,34 +570,3 @@ See toplevel README for an overview of the current copyright situation in
|
|||||||
libburnia-project.org.
|
libburnia-project.org.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
cdrskin is currently copyright Thomas Schmitt only.
|
|
||||||
It adopts the following commitment by the toplevel copyright holders:
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
|
||||||
those libraries are compiled from our unaltered code.
|
|
||||||
|
|
||||||
Thus you may link our libraries dynamically with applications
|
|
||||||
which are not under GPL. You may distribute our libraries and
|
|
||||||
application tools in binary form, if you fulfill the usual
|
|
||||||
condition of GPL to offer a copy of the source code -altered
|
|
||||||
or unaltered- under GPL.
|
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
|
||||||
and with the due reference to the entire open source community.
|
|
||||||
|
|
||||||
If there should really arise the case where above clarification
|
|
||||||
does not suffice to fulfill a clear and neat request in open source
|
|
||||||
spirit that would otherwise be declined for mere formal reasons,
|
|
||||||
only in that case we will duely consider to issue a special license
|
|
||||||
covering only that special case.
|
|
||||||
It is the open source idea of responsible freedom which will be
|
|
||||||
decisive and you will have to prove that you exhausted all own
|
|
||||||
means to qualify for GPL.
|
|
||||||
|
|
||||||
For now we are firmly committed to maintain one single license: GPL.
|
|
||||||
|
|
||||||
signed for cdrskin: Thomas Schmitt
|
|
||||||
|
@ -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.7.2"
|
skin_release="0.8.2"
|
||||||
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.7.3"
|
skin_release="0.8.3"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
@ -203,10 +203,11 @@ int Cdrfifo_close(struct CdrfifO *o, int flag)
|
|||||||
if(o->dest_fd!=-1)
|
if(o->dest_fd!=-1)
|
||||||
close(o->dest_fd);
|
close(o->dest_fd);
|
||||||
o->dest_fd= -1;
|
o->dest_fd= -1;
|
||||||
for(i=0; i<o->follow_up_fd_counter; i++)
|
for(i=0; i<o->follow_up_fd_counter; i++) {
|
||||||
if(o->follow_up_fds[i][1]!=-1)
|
if(o->follow_up_fds[i][1]!=-1)
|
||||||
close(o->follow_up_fds[i][1]);
|
close(o->follow_up_fds[i][1]);
|
||||||
o->follow_up_fds[i][1]= -1;
|
o->follow_up_fds[i][1]= -1;
|
||||||
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 "Nov 16, 2009"
|
.TH CDRSKIN 1 "Jun 10, 2010"
|
||||||
.\" 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:
|
||||||
@ -82,7 +82,7 @@ A \fBtrack\fP stores a stream of bytes.
|
|||||||
.br
|
.br
|
||||||
Each track is initiated by one track source address argument, which may either
|
Each track is initiated by one track source address argument, which may either
|
||||||
be "-" for standard input or the address of a readable file. If no write mode
|
be "-" for standard input or the address of a readable file. If no write mode
|
||||||
is given explicitely then one will be chosen which matches the peculiarities
|
is given explicitly then one will be chosen which matches the peculiarities
|
||||||
of track sources and the state of the output media.
|
of track sources and the state of the output media.
|
||||||
.PP
|
.PP
|
||||||
More than one track can be burned by a single run of cdrskin.
|
More than one track can be burned by a single run of cdrskin.
|
||||||
@ -93,13 +93,13 @@ Some media types can be kept appendable so that further tracks can
|
|||||||
be written to them in subsequent runs of cdrskin (see option -multi).
|
be written to them in subsequent runs of cdrskin (see option -multi).
|
||||||
Info about the addresses of burned tracks is kept in a table of
|
Info about the addresses of burned tracks is kept in a table of
|
||||||
content (TOC) on media and can be retrieved via cdrskin option -toc.
|
content (TOC) on media and can be retrieved via cdrskin option -toc.
|
||||||
These informations are also used by the operating systems' CD-ROM read drivers.
|
This information is also used by the operating systems' CD-ROM read drivers.
|
||||||
.PP
|
.PP
|
||||||
In general there are two types of tracks: data and audio. They differ in
|
In general there are two types of tracks: data and audio. They differ in
|
||||||
sector size, throughput and readability via the systems' CD-ROM drivers
|
sector size, throughput and readability via the systems' CD-ROM drivers
|
||||||
resp. by music CD players. With DVD and BD there is only type data.
|
resp. by music CD players. With DVD and BD there is only type data.
|
||||||
.br
|
.br
|
||||||
If not explicitely option -audio is given, then any track is burned as type
|
If not explicitly option -audio is given, then any track is burned as type
|
||||||
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
||||||
header part which identifies it as MS-WAVE resp. SUN Audio with suitable
|
header part which identifies it as MS-WAVE resp. SUN Audio with suitable
|
||||||
parameters. Such files are burned as audio tracks by default.
|
parameters. Such files are burned as audio tracks by default.
|
||||||
@ -138,7 +138,7 @@ try to choose a write mode which matches the defined recording job,
|
|||||||
the capabilities of the drive and the state of the present media.
|
the capabilities of the drive and the state of the present media.
|
||||||
.br
|
.br
|
||||||
So the mentioning of write modes in the following paragraphs and in the
|
So the mentioning of write modes in the following paragraphs and in the
|
||||||
examples is not so much a demand that the user shall choose one explicitely,
|
examples is not so much a demand that the user shall choose one explicitly,
|
||||||
but rather an illustration of what to expect with particular media types.
|
but rather an illustration of what to expect with particular media types.
|
||||||
.SS
|
.SS
|
||||||
.B Recordable CD Media:
|
.B Recordable CD Media:
|
||||||
@ -181,20 +181,20 @@ With DVD-R[W] two write modes may be available:
|
|||||||
Mode DAO has many restrictions. It does not work with
|
Mode DAO has many restrictions. It does not work with
|
||||||
appendable media, allows no -multi and only a single track. The size of the
|
appendable media, allows no -multi and only a single track. The size of the
|
||||||
track needs to be known in advance. So either its source has to be a disk file
|
track needs to be known in advance. So either its source has to be a disk file
|
||||||
of recognizable size or the size has to be announced explicitely by options
|
of recognizable size or the size has to be announced explicitly by options
|
||||||
.B tsize=
|
.B tsize=
|
||||||
or
|
or
|
||||||
.B tao_to_sao_tsize= .
|
.B tao_to_sao_tsize= .
|
||||||
.br
|
.br
|
||||||
DAO is the only mode for media which do not offer feature 21h Incremental
|
DAO is the only mode for media which do not offer feature 21h Incremental
|
||||||
Streaming. DAO may also be selected explicitely by option
|
Streaming. DAO may also be selected explicitly by option
|
||||||
.B -sao .
|
.B -sao .
|
||||||
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
|
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
|
||||||
DVD-ROM/-Video compatibility.
|
DVD-ROM/-Video compatibility.
|
||||||
.br
|
.br
|
||||||
The other mode, Incremental Streaming, is the default write mode if
|
The other mode, Incremental Streaming, is the default write mode if
|
||||||
it is available and if the restrictions of DAO would prevent the job.
|
it is available and if the restrictions of DAO would prevent the job.
|
||||||
Incremental Streaming may be selected explicitely by option
|
Incremental Streaming may be selected explicitly by option
|
||||||
.B -tao
|
.B -tao
|
||||||
as it resembles much CD TAO by allowing track sources of
|
as it resembles much CD TAO by allowing track sources of
|
||||||
unpredicted length and to keep media appendable by option
|
unpredicted length and to keep media appendable by option
|
||||||
@ -225,7 +225,7 @@ Currently types DVD+RW, DVD-RW, DVD-RAM and BD-RE can be overwritten via
|
|||||||
cdrskin.
|
cdrskin.
|
||||||
.br
|
.br
|
||||||
Option -audio is not allowed. Only one track is allowed.
|
Option -audio is not allowed. Only one track is allowed.
|
||||||
Option -multi cannot mark a recognizeable end of overwriteable media.
|
Option -multi cannot mark a recognizable end of overwriteable media.
|
||||||
Therefore -multi is banned unless ISO-9660 images shall be expandable by help
|
Therefore -multi is banned unless ISO-9660 images shall be expandable by help
|
||||||
of option
|
of option
|
||||||
.B --grow_overwriteable_iso .
|
.B --grow_overwriteable_iso .
|
||||||
@ -271,19 +271,22 @@ the drive is somewhat higher but the overall system is much less at stake.
|
|||||||
Consider to restrict rw-access to a single group which bundles the users who
|
Consider to restrict rw-access to a single group which bundles the users who
|
||||||
are allowed to use the burner drive (like group "floppy").
|
are allowed to use the burner drive (like group "floppy").
|
||||||
.br
|
.br
|
||||||
|
For drive permission examples on Linux, FreeBSD, and Solaris,
|
||||||
|
see cdrskin/README.
|
||||||
|
.br
|
||||||
.PP
|
.PP
|
||||||
If you only got one CD capable drive then you may leave out cdrskin option
|
If you only got one CD capable drive then you may leave out cdrskin option
|
||||||
\fBdev=\fP. Else you should use this option to address the drive you want.
|
\fBdev=\fP. Else you should use this option to address the drive you want.
|
||||||
.br
|
.br
|
||||||
cdrskin option dev= not only accepts the listed addresses but also
|
cdrskin option dev= not only accepts the listed addresses but also
|
||||||
traditional cdrecord SCSI addresses which on Linux consist of three
|
traditional cdrecord SCSI addresses which consist of three numbers:
|
||||||
numbers: Bus,Target,Lun. There is also a related address family "ATA" which
|
Bus,Target,Lun. On Linux there is also a related address family "ATA" which
|
||||||
accesses IDE drives not under control of Linux SCSI drivers:
|
accesses IDE drives not under control of Linux SCSI drivers:
|
||||||
ATA:Bus,Target,Lun.
|
ATA:Bus,Target,Lun.
|
||||||
.br
|
.br
|
||||||
See option -scanbus for getting a list of cdrecord style addresses.
|
See option -scanbus for getting a list of cdrecord style addresses.
|
||||||
.br
|
.br
|
||||||
Further are accepted on Linux: links to libburn-suitable device files,
|
Further are accepted: links to libburn-suitable device files,
|
||||||
device files which have the same major and minor device number,
|
device files which have the same major and minor device number,
|
||||||
and device files which have the same SCSI address parameters (e.g. /dev/sg0).
|
and device files which have the same SCSI address parameters (e.g. /dev/sg0).
|
||||||
.br
|
.br
|
||||||
@ -350,7 +353,7 @@ print "Mounted Media:" and media type text.
|
|||||||
Announces that the subsequent tracks are to be burned as audio.
|
Announces that the subsequent tracks are to be burned as audio.
|
||||||
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
|
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
|
||||||
stereo. For little-endian byte order (which is usual on PCs) use option
|
stereo. For little-endian byte order (which is usual on PCs) use option
|
||||||
-swab. Unless marked explicitely by option -data, input files with suffix
|
-swab. Unless marked explicitly by option -data, input files with suffix
|
||||||
".wav" are examined wether they have a header in MS-WAVE format confirming
|
".wav" are examined wether they have a header in MS-WAVE format confirming
|
||||||
those parameters and eventually raw audio data get extracted and burned as
|
those parameters and eventually raw audio data get extracted and burned as
|
||||||
audio track. Same is done for suffix ".au" and SUN Audio.
|
audio track. Same is done for suffix ".au" and SUN Audio.
|
||||||
@ -527,7 +530,7 @@ of Bus,Target,Lun addresses.
|
|||||||
Set "driveropts=noburnfree" to disable the drive's eventual protection
|
Set "driveropts=noburnfree" to disable the drive's eventual protection
|
||||||
mechanism against temporary lack of source data (i.e. buffer underrun).
|
mechanism against temporary lack of source data (i.e. buffer underrun).
|
||||||
A drive that announces no such capabilities will not get them enabled anyway,
|
A drive that announces no such capabilities will not get them enabled anyway,
|
||||||
even if attempted explicitely via "driveropts=burnfree".
|
even if attempted explicitly via "driveropts=burnfree".
|
||||||
.TP
|
.TP
|
||||||
.BI \-dummy
|
.BI \-dummy
|
||||||
Try to perform the drive operations without actually affecting the inserted
|
Try to perform the drive operations without actually affecting the inserted
|
||||||
@ -597,7 +600,7 @@ will be used under the assumption that it is a single session filesystem.
|
|||||||
.br
|
.br
|
||||||
If not, then the burn run will be aborted.
|
If not, then the burn run will be aborted.
|
||||||
.br
|
.br
|
||||||
The range of -isosize is exactly one track. Further tracks may be preceeded
|
The range of -isosize is exactly one track. Further tracks may be preceded
|
||||||
by further -isosize options, though. At least 15 blocks of padding will be
|
by further -isosize options, though. At least 15 blocks of padding will be
|
||||||
added to each -isosize track. But be advised to rather use padsize=300k.
|
added to each -isosize track. But be advised to rather use padsize=300k.
|
||||||
.br
|
.br
|
||||||
@ -705,7 +708,7 @@ No -multi is allowed with DVD-R[W] -sao.
|
|||||||
only imposes restrictions without providing known advantages.
|
only imposes restrictions without providing known advantages.
|
||||||
.br
|
.br
|
||||||
-sao can only be used for tracks of fixely predicted size. This implies that
|
-sao can only be used for tracks of fixely predicted size. This implies that
|
||||||
track arguments which depict stdin or named pipes need to be preceeded by
|
track arguments which depict stdin or named pipes need to be preceded by
|
||||||
option tsize= or by option tao_to_sao_tsize=.
|
option tsize= or by option tao_to_sao_tsize=.
|
||||||
.br
|
.br
|
||||||
-sao cannot be used on appendable media.
|
-sao cannot be used on appendable media.
|
||||||
@ -822,7 +825,7 @@ Alphabetical list of options which are genuine to cdrskin and intended for
|
|||||||
normal use:
|
normal use:
|
||||||
.TP
|
.TP
|
||||||
.BI \--adjust_speed_to_drive
|
.BI \--adjust_speed_to_drive
|
||||||
Curb explicitely given speed= values to the maximum which is announced by the
|
Curb explicitly given speed= values to the maximum which is announced by the
|
||||||
drive for the loaded media. By default, such an adjustment is only made with
|
drive for the loaded media. By default, such an adjustment is only made with
|
||||||
pseudo-speeds 0 and -1 whereas speed settings > 0 are sent unchanged to the
|
pseudo-speeds 0 and -1 whereas speed settings > 0 are sent unchanged to the
|
||||||
drive which will then choose an appropriate speed on its own.
|
drive which will then choose an appropriate speed on its own.
|
||||||
@ -916,7 +919,7 @@ to cdrskin, then cdrskin will delegate the job to said command.
|
|||||||
The natural commands to be given are cdrecord or wodim but one may well submit
|
The natural commands to be given are cdrecord or wodim but one may well submit
|
||||||
the address of an own program.
|
the address of an own program.
|
||||||
.br
|
.br
|
||||||
The fallback programm will get all arguments of cdrskin which do not match
|
The fallback program will get all arguments of cdrskin which do not match
|
||||||
the shell patterns --?* or *_*=* . This eventually suppresses path names of
|
the shell patterns --?* or *_*=* . This eventually suppresses path names of
|
||||||
track sources which happen to match those patterns. The options from the
|
track sources which happen to match those patterns. The options from the
|
||||||
startup files are not handed to the fallback program.
|
startup files are not handed to the fallback program.
|
||||||
@ -962,12 +965,12 @@ source is a ISO-9660 filesystem image.
|
|||||||
With overwriteable media and no option blank=fast|all present it expands an
|
With overwriteable media and no option blank=fast|all present it expands an
|
||||||
eventual ISO-9660 filesystem on media. It is assumed that this image's inner
|
eventual ISO-9660 filesystem on media. It is assumed that this image's inner
|
||||||
size description points to the end of the valuable data.
|
size description points to the end of the valuable data.
|
||||||
Overwriteable media with a recognizeable ISO-9660 size will be regarded as
|
Overwriteable media with a recognizable ISO-9660 size will be regarded as
|
||||||
appendable rather than as blank. I.e. options -msinfo and -toc will work.
|
appendable rather than as blank. I.e. options -msinfo and -toc will work.
|
||||||
-toc will always show a single session with its size increasing with
|
-toc will always show a single session with its size increasing with
|
||||||
every added mkisofs image.
|
every added mkisofs image.
|
||||||
.br
|
.br
|
||||||
If not overriden by option write_start_address=, the track with the new image
|
If not overridden by option write_start_address=, the track with the new image
|
||||||
will be placed behind the end of the old one. One may use option
|
will be placed behind the end of the old one. One may use option
|
||||||
assert_write_lba= to make sure that media state and mkisofs job do match.
|
assert_write_lba= to make sure that media state and mkisofs job do match.
|
||||||
.br
|
.br
|
||||||
@ -1062,7 +1065,7 @@ the available capacity. So for most realistic results one may set up
|
|||||||
the full burn session and add --tell_media_space. But if one has to expect
|
the full burn session and add --tell_media_space. But if one has to expect
|
||||||
a cdrskin version prior to 0.3.3 no track source should be given in order
|
a cdrskin version prior to 0.3.3 no track source should be given in order
|
||||||
not to start an involuntary burn session.
|
not to start an involuntary burn session.
|
||||||
In this case set at least -sao or -tao explicitely.
|
In this case set at least -sao or -tao explicitly.
|
||||||
.br
|
.br
|
||||||
The result gets printed to standard output. It is 0 or empty if no writing
|
The result gets printed to standard output. It is 0 or empty if no writing
|
||||||
is possible with the given options.
|
is possible with the given options.
|
||||||
@ -1130,7 +1133,7 @@ Wether this leads to senseful behavior depends on operating system and kernel.
|
|||||||
Linux specific: Select a SCSI device file family to be scanned for by
|
Linux specific: Select a SCSI device file family to be scanned for by
|
||||||
options --devices and -scanbus.
|
options --devices and -scanbus.
|
||||||
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
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 explicitly 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.
|
||||||
.br
|
.br
|
||||||
@ -1242,7 +1245,7 @@ cdrskin dev=0,1,0 -checkdrive
|
|||||||
.br
|
.br
|
||||||
cdrskin dev=ATA:1,0,0 -v -atip
|
cdrskin dev=ATA:1,0,0 -v -atip
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/hdc -toc
|
cdrskin dev=/dev/hdc -minfo
|
||||||
.SS
|
.SS
|
||||||
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
|
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
|
||||||
.br
|
.br
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
cdrskin.c , Copyright 2006-2009 Thomas Schmitt <scdbackup@gmx.net>
|
cdrskin.c , Copyright 2006-2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2. See future commitment below.
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
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.7.3"
|
#define Cdrskin_prog_versioN "0.8.2"
|
||||||
#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 7
|
#define Cdrskin_libburn_minoR 8
|
||||||
#endif
|
#endif
|
||||||
#ifndef Cdrskin_libburn_micrO
|
#ifndef Cdrskin_libburn_micrO
|
||||||
#define Cdrskin_libburn_micrO 3
|
#define Cdrskin_libburn_micrO 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -135,48 +135,46 @@ or
|
|||||||
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
||||||
|
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_7_2
|
#ifdef Cdrskin_libburn_0_8_2
|
||||||
#define Cdrskin_libburn_versioN "0.7.2"
|
#define Cdrskin_libburn_versioN "0.8.2"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
#endif /* Cdrskin_libburn_0_7_2 */
|
#endif /* Cdrskin_libburn_0_8_2 */
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_7_3
|
#ifdef Cdrskin_libburn_0_8_3
|
||||||
#define Cdrskin_libburn_versioN "0.7.3"
|
#define Cdrskin_libburn_versioN "0.8.3"
|
||||||
#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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* burn_write_opts_set_dvd_obs() and burn_write_opts_set_stdio_fsync()
|
/* Do not stay in signal handler but only cancel and set Cdrskin_abort_leveL.
|
||||||
|
Make use of burn_is_aborting() to detect pending libburn aborts.
|
||||||
*/
|
*/
|
||||||
#define Cdrskin_libburn_has_fsync_obS 1
|
|
||||||
|
|
||||||
/* >>> do not forget to remove Libburn_has_open_trac_srC at release of 0.7.4 */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* Cdrskin_libburn_0_7_3 */
|
#endif /* Cdrskin_libburn_0_8_3 */
|
||||||
|
|
||||||
#ifndef Cdrskin_libburn_versioN
|
#ifndef Cdrskin_libburn_versioN
|
||||||
#define Cdrskin_libburn_0_7_2
|
#define Cdrskin_libburn_0_8_2
|
||||||
#define Cdrskin_libburn_versioN "0.7.2"
|
#define Cdrskin_libburn_versioN "0.8.2"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_7_2
|
#ifdef Cdrskin_libburn_0_8_2
|
||||||
#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 7
|
#define Cdrskin_libburn_minoR 8
|
||||||
#define Cdrskin_libburn_micrO 2
|
#define Cdrskin_libburn_micrO 2
|
||||||
#endif
|
#endif
|
||||||
#ifdef Cdrskin_libburn_0_7_3
|
#ifdef Cdrskin_libburn_0_8_3
|
||||||
#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 7
|
#define Cdrskin_libburn_minoR 8
|
||||||
#define Cdrskin_libburn_micrO 3
|
#define Cdrskin_libburn_micrO 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -374,7 +372,34 @@ or
|
|||||||
#define Cleanup_app_handler_T burn_abort_handler_t
|
#define Cleanup_app_handler_T burn_abort_handler_t
|
||||||
#else
|
#else
|
||||||
#include "cleanup.h"
|
#include "cleanup.h"
|
||||||
|
#ifdef Cdrskin_use_libburn_cleanuP
|
||||||
|
#undef Cdrskin_use_libburn_cleanuP
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
# define Cdrskin_use_libburn_cleanuP 1
|
||||||
|
*/
|
||||||
|
/* May not use libburn cleanup with cdrskin fifo */
|
||||||
|
#ifndef Cdrskin_use_libburn_fifO
|
||||||
|
#ifdef Cdrskin_use_libburn_cleanuP
|
||||||
|
#undef Cdrskin_use_libburn_cleanuP
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Cdrskin_use_libburn_cleanuP
|
||||||
|
#define Cleanup_handler_funC NULL
|
||||||
|
#define Cleanup_handler_handlE "cdrskin: "
|
||||||
|
#define Cleanup_handler_flaG 48
|
||||||
|
#else
|
||||||
|
#define Cleanup_handler_funC (Cleanup_app_handler_T) Cdrskin_abort_handler
|
||||||
|
#define Cleanup_handler_handlE skin
|
||||||
|
#define Cleanup_handler_flaG 4
|
||||||
|
#endif /* ! Cdrskin_use_libburn_cleanuP */
|
||||||
|
|
||||||
|
/* 0= no abort going on, -1= Cdrskin_abort_handler was called
|
||||||
|
*/
|
||||||
|
static int Cdrskin_abort_leveL= 0;
|
||||||
|
|
||||||
|
|
||||||
/** The size of a string buffer for pathnames and similar texts */
|
/** The size of a string buffer for pathnames and similar texts */
|
||||||
@ -1463,14 +1488,12 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
|
|||||||
if(is_wav==-3)
|
if(is_wav==-3)
|
||||||
return(0);
|
return(0);
|
||||||
if(is_wav==0) {
|
if(is_wav==0) {
|
||||||
#ifdef Libburn_has_open_trac_srC
|
|
||||||
if(track->track_type != BURN_MODE1 ||
|
if(track->track_type != BURN_MODE1 ||
|
||||||
(track->cdxa_conversion & 0x7fffffff))
|
(track->cdxa_conversion & 0x7fffffff))
|
||||||
flag&= ~4; /* Better avoid O_DIRECT with odd sectors */
|
flag&= ~4; /* Better avoid O_DIRECT with odd sectors */
|
||||||
if(flag & 4)
|
if(flag & 4)
|
||||||
*fd= burn_os_open_track_src(track->source_path, O_RDONLY, 0);
|
*fd= burn_os_open_track_src(track->source_path, O_RDONLY, 0);
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
*fd= open(track->source_path, O_RDONLY);
|
*fd= open(track->source_path, O_RDONLY);
|
||||||
}
|
}
|
||||||
if(*fd==-1) {
|
if(*fd==-1) {
|
||||||
@ -1804,7 +1827,6 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
|
|||||||
|
|
||||||
Cdrskin_get_fifo_par(track->boss, &fifo_enabled, &fifo_size, &fifo_start_at,
|
Cdrskin_get_fifo_par(track->boss, &fifo_enabled, &fifo_size, &fifo_start_at,
|
||||||
0);
|
0);
|
||||||
fd_src= src;
|
|
||||||
|
|
||||||
if(track->track_type == BURN_AUDIO)
|
if(track->track_type == BURN_AUDIO)
|
||||||
chunksize= 2352;
|
chunksize= 2352;
|
||||||
@ -1814,6 +1836,7 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
|
|||||||
chunksize= 2048;
|
chunksize= 2048;
|
||||||
chunks= fifo_size / chunksize;
|
chunks= fifo_size / chunksize;
|
||||||
if(chunks > 1 && fifo_enabled) {
|
if(chunks > 1 && fifo_enabled) {
|
||||||
|
fd_src= src;
|
||||||
src= burn_fifo_source_new(fd_src, chunksize, chunks,
|
src= burn_fifo_source_new(fd_src, chunksize, chunks,
|
||||||
(chunksize * chunks >= 128 * 1024));
|
(chunksize * chunks >= 128 * 1024));
|
||||||
if((flag & 1) || src == NULL)
|
if((flag & 1) || src == NULL)
|
||||||
@ -2880,11 +2903,9 @@ set_dev:;
|
|||||||
printf(
|
printf(
|
||||||
" --drive_scsi_exclusive try to exclusively reserve device files\n");
|
" --drive_scsi_exclusive try to exclusively reserve device files\n");
|
||||||
printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n");
|
printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n");
|
||||||
#ifdef Cdrskin_libburn_has_fsync_obS
|
|
||||||
printf(" dvd_obs=\"default\"|number\n");
|
printf(" dvd_obs=\"default\"|number\n");
|
||||||
printf(
|
printf(
|
||||||
" set number of bytes per DVD/BD write: 32k or 64k\n");
|
" set number of bytes per DVD/BD write: 32k or 64k\n");
|
||||||
#endif
|
|
||||||
#ifdef Cdrskin_burn_drive_eject_brokeN
|
#ifdef Cdrskin_burn_drive_eject_brokeN
|
||||||
printf(
|
printf(
|
||||||
" eject_device=<path> set the device address for command eject\n");
|
" eject_device=<path> set the device address for command eject\n");
|
||||||
@ -2935,13 +2956,11 @@ set_dev:;
|
|||||||
printf(
|
printf(
|
||||||
" byte addresses below that number.\n");
|
" byte addresses below that number.\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef Cdrskin_libburn_has_fsync_obS
|
|
||||||
printf(" stdio_sync=\"default\"|\"off\"|number\n");
|
printf(" stdio_sync=\"default\"|\"off\"|number\n");
|
||||||
printf(
|
printf(
|
||||||
" set number of bytes after which to force output\n");
|
" set number of bytes after which to force output\n");
|
||||||
printf(
|
printf(
|
||||||
" to drives with prefix \"stdio:\".\n");
|
" to drives with prefix \"stdio:\".\n");
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Cdrskin_allow_libburn_taO
|
#ifdef Cdrskin_allow_libburn_taO
|
||||||
printf(
|
printf(
|
||||||
@ -3155,7 +3174,17 @@ set_severities:;
|
|||||||
int major, minor, micro;
|
int major, minor, micro;
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
"Cdrecord 2.01-Emulation Copyright (C) 2006-2009, see libburnia-project.org\n");
|
"Cdrecord 2.01-Emulation Copyright (C) 2006-2010, see libburnia-project.org\n");
|
||||||
|
if(o->fallback_program[0]) {
|
||||||
|
char *hargv[2];
|
||||||
|
|
||||||
|
printf("Fallback program : %s\n",o->fallback_program);
|
||||||
|
printf("Fallback version :\n");
|
||||||
|
hargv[0]= argv[0];
|
||||||
|
hargv[1]= "-version";
|
||||||
|
Cdrpreskin_fallback(o,2,hargv,1); /* dirty never come back */
|
||||||
|
}
|
||||||
|
printf("System adapter : %s\n", burn_scsi_transport_id(0));
|
||||||
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);
|
||||||
@ -3171,15 +3200,6 @@ set_severities:;
|
|||||||
|
|
||||||
printf("Version timestamp : %s\n",Cdrskin_timestamP);
|
printf("Version timestamp : %s\n",Cdrskin_timestamP);
|
||||||
printf("Build timestamp : %s\n",Cdrskin_build_timestamP);
|
printf("Build timestamp : %s\n",Cdrskin_build_timestamP);
|
||||||
if(o->fallback_program[0]) {
|
|
||||||
char *hargv[2];
|
|
||||||
|
|
||||||
printf("Fallback program : %s\n",o->fallback_program);
|
|
||||||
printf("Fallback version :\n");
|
|
||||||
hargv[0]= argv[0];
|
|
||||||
hargv[1]= "-version";
|
|
||||||
Cdrpreskin_fallback(o,2,hargv,1); /* dirty never come back */
|
|
||||||
}
|
|
||||||
{ret= 2; goto ex;}
|
{ret= 2; goto ex;}
|
||||||
|
|
||||||
} else if(strcmp(argv[i],"-waiti")==0) {
|
} else if(strcmp(argv[i],"-waiti")==0) {
|
||||||
@ -3196,7 +3216,9 @@ set_severities:;
|
|||||||
final_checks:;
|
final_checks:;
|
||||||
if(flag&1)
|
if(flag&1)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
if(o->verbosity >= Cdrskin_verbose_debuG)
|
||||||
|
ClN(fprintf(stderr,
|
||||||
|
"cdrskin: DEBUG : Using %s\n", burn_scsi_transport_id(0)));
|
||||||
if(o->do_waiti) {
|
if(o->do_waiti) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"cdrskin: Option -waiti pauses program until input appears at stdin\n");
|
"cdrskin: Option -waiti pauses program until input appears at stdin\n");
|
||||||
@ -3624,6 +3646,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
|
|||||||
o->write_type= BURN_WRITE_SAO;
|
o->write_type= BURN_WRITE_SAO;
|
||||||
o->block_type= BURN_BLOCK_SAO;
|
o->block_type= BURN_BLOCK_SAO;
|
||||||
o->multi= 0;
|
o->multi= 0;
|
||||||
|
o->cdxa_conversion= 0;
|
||||||
o->modesty_on_drive= 0;
|
o->modesty_on_drive= 0;
|
||||||
o->min_buffer_percent= 65;
|
o->min_buffer_percent= 65;
|
||||||
o->max_buffer_percent= 95;
|
o->max_buffer_percent= 95;
|
||||||
@ -4095,7 +4118,8 @@ ex:;
|
|||||||
#ifdef Cdrskin_grab_abort_brokeN
|
#ifdef Cdrskin_grab_abort_brokeN
|
||||||
if(restore_handler) {
|
if(restore_handler) {
|
||||||
int Cdrskin_abort_handler(struct CdrskiN *, int, int);
|
int Cdrskin_abort_handler(struct CdrskiN *, int, int);
|
||||||
Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,4);
|
Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC,
|
||||||
|
Cleanup_handler_flaG);
|
||||||
}
|
}
|
||||||
#endif /* Cdrskin_grab_abort_brokeN */
|
#endif /* Cdrskin_grab_abort_brokeN */
|
||||||
|
|
||||||
@ -4128,17 +4152,42 @@ int Cdrskin_release_drive(struct CdrskiN *skin, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Cdrskin__is_aborting(int flag)
|
||||||
|
{
|
||||||
|
if(Cdrskin_abort_leveL)
|
||||||
|
return(-1);
|
||||||
|
return(burn_is_aborting(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Cdrskin_abort(struct CdrskiN *skin, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
Cdrskin_abort_leveL= 1;
|
||||||
|
ret= burn_abort(skin->abort_max_wait, burn_abort_pacifier, "cdrskin: ");
|
||||||
|
if(ret<=0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\ncdrskin: ABORT : Cannot cancel burn session and release drive.\n");
|
||||||
|
return(0);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"cdrskin: ABORT : Drive is released and library is shut down now.\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr,
|
||||||
|
"cdrskin: ABORT : Program done. Even if you do not see a shell prompt.\n");
|
||||||
|
fprintf(stderr,"\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Clean up resources in abort situations. To be called by Cleanup subsystem
|
/** Clean up resources in abort situations. To be called by Cleanup subsystem
|
||||||
but hardly ever by the application. The program must exit afterwards.
|
but hardly ever by the application. The program must exit afterwards.
|
||||||
*/
|
*/
|
||||||
int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_has_burn_aborT
|
#ifndef Cdrskin_libburn_has_burn_aborT
|
||||||
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
int wait_grain= 100000,first_status= 1;
|
int wait_grain= 100000,first_status= 1;
|
||||||
double start_time,last_time,current_time;
|
double start_time,last_time,current_time;
|
||||||
@ -4151,8 +4200,9 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
|||||||
if(getpid()!=skin->control_pid) {
|
if(getpid()!=skin->control_pid) {
|
||||||
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
||||||
ClN(fprintf(stderr,
|
ClN(fprintf(stderr,
|
||||||
"\ncdrskin_debug: ABORT : [%d] Thread rejected: pid=%d, signum=%d\n",
|
"\ncdrskin_debug: ABORT : [%lu] Thread rejected: pid=%lu, signum=%lu\n",
|
||||||
skin->control_pid,getpid(),signum));
|
(unsigned long int) skin->control_pid, (unsigned long int) getpid(),
|
||||||
|
(unsigned long int) signum));
|
||||||
|
|
||||||
#ifdef Not_yeT
|
#ifdef Not_yeT
|
||||||
/* >>> find more abstract and system independent way to determine
|
/* >>> find more abstract and system independent way to determine
|
||||||
@ -4190,14 +4240,15 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
|||||||
fprintf(stderr,"cdrskin: ABORT : Usually it is done with 4x speed after about a MINUTE\n");
|
fprintf(stderr,"cdrskin: ABORT : Usually it is done with 4x speed after about a MINUTE\n");
|
||||||
fprintf(stderr,"cdrskin: URGE : But wait at least the normal burning time before any kill -9\n");
|
fprintf(stderr,"cdrskin: URGE : But wait at least the normal burning time before any kill -9\n");
|
||||||
}
|
}
|
||||||
|
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
||||||
|
ClN(fprintf(stderr,"cdrskin_debug: ABORT : Calling burn_abort()\n"));
|
||||||
|
|
||||||
ret= burn_abort(skin->abort_max_wait, burn_abort_pacifier, "cdrskin: ");
|
Cdrskin_abort_leveL= -1;
|
||||||
if(ret<=0) {
|
if (!(flag & 1))
|
||||||
fprintf(stderr,
|
burn_abort(-1, burn_abort_pacifier, "cdrskin: ");
|
||||||
"\ncdrskin: ABORT : Cannot cancel burn session and release drive.\n");
|
fprintf(stderr,
|
||||||
return(0);
|
"cdrskin: ABORT : Urged drive worker threads to do emergency halt.\n");
|
||||||
}
|
return -2;
|
||||||
fprintf(stderr,"\n");
|
|
||||||
|
|
||||||
#else /* Cdrskin_libburn_has_burn_aborT */
|
#else /* Cdrskin_libburn_has_burn_aborT */
|
||||||
|
|
||||||
@ -5226,8 +5277,8 @@ int Cdrskin_minfo(struct CdrskiN *skin, int flag)
|
|||||||
/* If last two blocks not readable then assume TAO and subtract 2
|
/* If last two blocks not readable then assume TAO and subtract 2
|
||||||
from lra and size.
|
from lra and size.
|
||||||
*/;
|
*/;
|
||||||
ret= burn_read_data(drive, (off_t) lra * (off_t) 2048, buf, 2 * 2048,
|
ret= burn_read_data(drive, (off_t) (lra - 1) * (off_t) 2048, buf,
|
||||||
&buf_count, 2 | 4);
|
2 * 2048, &buf_count, 2 | 4);
|
||||||
if(ret <= 0) {
|
if(ret <= 0) {
|
||||||
lra-= 2;
|
lra-= 2;
|
||||||
size-= 2;
|
size-= 2;
|
||||||
@ -6042,6 +6093,8 @@ ex:;
|
|||||||
skin->drive_is_busy= 0;
|
skin->drive_is_busy= 0;
|
||||||
if(skin->drive_is_grabbed)
|
if(skin->drive_is_grabbed)
|
||||||
Cdrskin_release_drive(skin,0);
|
Cdrskin_release_drive(skin,0);
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
Cdrskin_abort(skin, 0); /* Never comes back */
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6095,6 +6148,9 @@ int Cdrskin_burn_pacifier(struct CdrskiN *skin,
|
|||||||
/* for debugging */
|
/* for debugging */
|
||||||
static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out;
|
static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out;
|
||||||
|
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
Cdrskin_abort(skin, 0); /* Never comes back */
|
||||||
|
|
||||||
current_time= Sfile_microtime(0);
|
current_time= Sfile_microtime(0);
|
||||||
elapsed_total_time= current_time-start_time;
|
elapsed_total_time= current_time-start_time;
|
||||||
elapsed_time= current_time-*last_time;
|
elapsed_time= current_time-*last_time;
|
||||||
@ -7218,7 +7274,6 @@ burn_failed:;
|
|||||||
#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
|
||||||
#ifdef Cdrskin_libburn_has_fsync_obS
|
|
||||||
#ifdef Cdrskin_dvd_obs_default_64K
|
#ifdef Cdrskin_dvd_obs_default_64K
|
||||||
if(skin->dvd_obs == 0)
|
if(skin->dvd_obs == 0)
|
||||||
burn_write_opts_set_dvd_obs(o, 64 * 1024);
|
burn_write_opts_set_dvd_obs(o, 64 * 1024);
|
||||||
@ -7226,7 +7281,6 @@ burn_failed:;
|
|||||||
#endif
|
#endif
|
||||||
burn_write_opts_set_dvd_obs(o, skin->dvd_obs);
|
burn_write_opts_set_dvd_obs(o, skin->dvd_obs);
|
||||||
burn_write_opts_set_stdio_fsync(o, skin->stdio_sync);
|
burn_write_opts_set_stdio_fsync(o, skin->stdio_sync);
|
||||||
#endif /* Cdrskin_libburn_has_fsync_obS */
|
|
||||||
|
|
||||||
if(skin->dummy_mode) {
|
if(skin->dummy_mode) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -7305,7 +7359,8 @@ fifo_filling_failed:;
|
|||||||
skin->drive_is_busy= 1;
|
skin->drive_is_busy= 1;
|
||||||
burn_disc_write(o, disc);
|
burn_disc_write(o, disc);
|
||||||
if(skin->preskin->abort_handler==-1)
|
if(skin->preskin->abort_handler==-1)
|
||||||
Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,4);
|
Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC,
|
||||||
|
Cleanup_handler_flaG);
|
||||||
last_time= start_time= Sfile_microtime(0);
|
last_time= start_time= Sfile_microtime(0);
|
||||||
|
|
||||||
burn_write_opts_free(o);
|
burn_write_opts_free(o);
|
||||||
@ -7324,7 +7379,7 @@ fifo_filling_failed:;
|
|||||||
|
|
||||||
/* >>> how do i learn about success or failure ? */
|
/* >>> how do i learn about success or failure ? */
|
||||||
|
|
||||||
if(loop_counter>0)
|
if(loop_counter>0 || Cdrskin__is_aborting(0))
|
||||||
Cdrskin_burn_pacifier(skin,drive_status,&p,start_time,&last_time,
|
Cdrskin_burn_pacifier(skin,drive_status,&p,start_time,&last_time,
|
||||||
&total_count,&last_count,&min_buffer_fill,0);
|
&total_count,&last_count,&min_buffer_fill,0);
|
||||||
|
|
||||||
@ -7398,6 +7453,9 @@ fifo_filling_failed:;
|
|||||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
Cdrskin_abort(skin, 0); /* Never comes back */
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_has_wrote_welL
|
#ifdef Cdrskin_libburn_has_wrote_welL
|
||||||
wrote_well = burn_drive_wrote_well(drive);
|
wrote_well = burn_drive_wrote_well(drive);
|
||||||
#endif
|
#endif
|
||||||
@ -8896,9 +8954,11 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
|
|||||||
*o= skin;
|
*o= skin;
|
||||||
if(skin->preskin->abort_handler==1 || skin->preskin->abort_handler==3 ||
|
if(skin->preskin->abort_handler==1 || skin->preskin->abort_handler==3 ||
|
||||||
skin->preskin->abort_handler==4)
|
skin->preskin->abort_handler==4)
|
||||||
Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,4);
|
Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC,
|
||||||
|
Cleanup_handler_flaG);
|
||||||
else if(skin->preskin->abort_handler==2)
|
else if(skin->preskin->abort_handler==2)
|
||||||
Cleanup_set_handlers(skin,(Cleanup_app_handler_T) Cdrskin_abort_handler,2|8);
|
Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC,
|
||||||
|
2 | 8);
|
||||||
|
|
||||||
printf("cdrskin: scanning for devices ...\n");
|
printf("cdrskin: scanning for devices ...\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -8974,21 +9034,28 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
if(skin->do_devices) {
|
if(skin->do_devices) {
|
||||||
if(skin->n_drives<=0 && skin->preskin->scan_demands_drive)
|
if(skin->n_drives<=0 && skin->preskin->scan_demands_drive)
|
||||||
{*exit_value= 4; goto no_drive;}
|
{*exit_value= 4; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_scanbus(skin,1);
|
ret= Cdrskin_scanbus(skin,1);
|
||||||
if(ret<=0) {
|
if(ret<=0) {
|
||||||
fprintf(stderr,"cdrskin: FATAL : --devices failed.\n");
|
fprintf(stderr,"cdrskin: FATAL : --devices failed.\n");
|
||||||
{*exit_value= 4; goto ex;}
|
{*exit_value= 4; goto ex;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skin->do_scanbus) {
|
if(skin->do_scanbus) {
|
||||||
if(skin->n_drives<=0 && skin->preskin->scan_demands_drive)
|
if(skin->n_drives<=0 && skin->preskin->scan_demands_drive)
|
||||||
{*exit_value= 5; goto no_drive;}
|
{*exit_value= 5; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_scanbus(skin,0);
|
ret= Cdrskin_scanbus(skin,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
fprintf(stderr,"cdrskin: FATAL : -scanbus failed.\n");
|
fprintf(stderr,"cdrskin: FATAL : -scanbus failed.\n");
|
||||||
{*exit_value= 5*(ret<=0); goto ex;}
|
{*exit_value= 5*(ret<=0); goto ex;}
|
||||||
}
|
}
|
||||||
if(skin->do_load) {
|
if(skin->do_load) {
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_grab_drive(skin,8);
|
ret= Cdrskin_grab_drive(skin,8);
|
||||||
if(ret>0) {
|
if(ret>0) {
|
||||||
if(skin->do_load==2 && !skin->do_eject) {
|
if(skin->do_load==2 && !skin->do_eject) {
|
||||||
@ -9004,12 +9071,16 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
{*exit_value= 14*(ret<=0); goto ex;}
|
{*exit_value= 14*(ret<=0); goto ex;}
|
||||||
}
|
}
|
||||||
if(skin->do_checkdrive) {
|
if(skin->do_checkdrive) {
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_checkdrive(skin,"",(skin->do_checkdrive==2)<<1);
|
ret= Cdrskin_checkdrive(skin,"",(skin->do_checkdrive==2)<<1);
|
||||||
{*exit_value= 6*(ret<=0); goto ex;}
|
{*exit_value= 6*(ret<=0); goto ex;}
|
||||||
}
|
}
|
||||||
if(skin->do_msinfo) {
|
if(skin->do_msinfo) {
|
||||||
if(skin->n_drives<=0)
|
if(skin->n_drives<=0)
|
||||||
{*exit_value= 12; goto no_drive;}
|
{*exit_value= 12; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_msinfo(skin,0);
|
ret= Cdrskin_msinfo(skin,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
{*exit_value= 12; goto ex;}
|
{*exit_value= 12; goto ex;}
|
||||||
@ -9017,6 +9088,8 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
if(skin->do_atip) {
|
if(skin->do_atip) {
|
||||||
if(skin->n_drives<=0)
|
if(skin->n_drives<=0)
|
||||||
{*exit_value= 7; goto no_drive;}
|
{*exit_value= 7; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_atip(skin, skin->do_atip == 4 ? 4 :
|
ret= Cdrskin_atip(skin, skin->do_atip == 4 ? 4 :
|
||||||
(skin->do_atip>1) | (2 * (skin->do_atip > 2)));
|
(skin->do_atip>1) | (2 * (skin->do_atip > 2)));
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
@ -9025,6 +9098,8 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
if(skin->do_list_formats) {
|
if(skin->do_list_formats) {
|
||||||
if(skin->n_drives<=0)
|
if(skin->n_drives<=0)
|
||||||
{*exit_value= 14; goto no_drive;}
|
{*exit_value= 14; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_list_formats(skin, 0);
|
ret= Cdrskin_list_formats(skin, 0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
{*exit_value= 14; goto ex;}
|
{*exit_value= 14; goto ex;}
|
||||||
@ -9032,6 +9107,8 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
if(skin->do_blank) {
|
if(skin->do_blank) {
|
||||||
if(skin->n_drives<=0)
|
if(skin->n_drives<=0)
|
||||||
{*exit_value= 8; goto no_drive;}
|
{*exit_value= 8; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_blank(skin,0);
|
ret= Cdrskin_blank(skin,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
{*exit_value= 8; goto ex;}
|
{*exit_value= 8; goto ex;}
|
||||||
@ -9040,6 +9117,8 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
#ifdef Cdrskin_libburn_has_random_access_rW
|
#ifdef Cdrskin_libburn_has_random_access_rW
|
||||||
if(skin->do_direct_write) {
|
if(skin->do_direct_write) {
|
||||||
skin->do_burn= 0;
|
skin->do_burn= 0;
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_direct_write(skin,0);
|
ret= Cdrskin_direct_write(skin,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
{*exit_value= 13; goto ex;}
|
{*exit_value= 13; goto ex;}
|
||||||
@ -9049,11 +9128,15 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
|
|||||||
if(skin->do_burn || skin->tell_media_space) {
|
if(skin->do_burn || skin->tell_media_space) {
|
||||||
if(skin->n_drives<=0)
|
if(skin->n_drives<=0)
|
||||||
{*exit_value= 10; goto no_drive;}
|
{*exit_value= 10; goto no_drive;}
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
goto ex;
|
||||||
ret= Cdrskin_burn(skin,0);
|
ret= Cdrskin_burn(skin,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
{*exit_value= 10; goto ex;}
|
{*exit_value= 10; goto ex;}
|
||||||
}
|
}
|
||||||
ex:;
|
ex:;
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
Cdrskin_abort(skin, 0); /* Never comes back */
|
||||||
return((*exit_value)==0);
|
return((*exit_value)==0);
|
||||||
no_drive:;
|
no_drive:;
|
||||||
fprintf(stderr,"cdrskin: FATAL : This run would need an accessible drive\n");
|
fprintf(stderr,"cdrskin: FATAL : This run would need an accessible drive\n");
|
||||||
@ -9101,7 +9184,7 @@ int main(int argc, char **argv)
|
|||||||
messaging need libburn running */
|
messaging need libburn running */
|
||||||
ret= Cdrpreskin_initialize_lib(preskin,0);
|
ret= Cdrpreskin_initialize_lib(preskin,0);
|
||||||
if(ret<=0) {
|
if(ret<=0) {
|
||||||
fprintf(stderr,"cdrskin: FATAL : Initializiation of burn library failed\n");
|
fprintf(stderr,"cdrskin: FATAL : Initialization of burn library failed\n");
|
||||||
{exit_value= 2; goto ex;}
|
{exit_value= 2; goto ex;}
|
||||||
}
|
}
|
||||||
lib_initialized= 1;
|
lib_initialized= 1;
|
||||||
@ -9141,9 +9224,13 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Cdrskin_run(skin,&exit_value,0);
|
if(!Cdrskin__is_aborting(0))
|
||||||
|
Cdrskin_run(skin,&exit_value,0);
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
|
if(Cdrskin__is_aborting(0))
|
||||||
|
Cdrskin_abort(skin, 0); /* Never comes back */
|
||||||
|
|
||||||
if(preskin!=NULL)
|
if(preskin!=NULL)
|
||||||
h_preskin= preskin;
|
h_preskin= preskin;
|
||||||
else if(skin!=NULL)
|
else if(skin!=NULL)
|
||||||
|
@ -38,8 +38,8 @@ About any CD, DVD, or BD recorder produced in the recent ten years.
|
|||||||
<BR>
|
<BR>
|
||||||
<A HREF="http://libburnia-project.org">libburn</A>
|
<A HREF="http://libburnia-project.org">libburn</A>
|
||||||
supports recorders which are compliant to standards MMC-1 for CD and
|
supports recorders which are compliant to standards MMC-1 for CD and
|
||||||
MMC-5 for DVD or BD. Linux and FreeBSD allow to access drives connected
|
MMC-5 for DVD or BD. Linux, FreeBSD, and Solaris allow to access drives
|
||||||
via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||||
<BR>
|
<BR>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
@ -50,7 +50,10 @@ via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||||||
<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>
|
<DT>or FreeBSD (with libc, of course) :</DT>
|
||||||
<DD>ATAPI/CAM support has to be enabled in the kernel, see atapicam(4).</DD>
|
<DD>ATA and SATA drives need atapicam running.</DD>
|
||||||
|
<DD>libcam has to be installed.</DD>
|
||||||
|
<DT>or Solaris (with libc, of course) :</DT>
|
||||||
|
<DD>Tested on kernel 5.11, hopefully suitable for older ones too.</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>
|
||||||
@ -61,7 +64,7 @@ via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||||||
GPL software included:<BR>
|
GPL software included:<BR>
|
||||||
</H2>
|
</H2>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>libburn-0.7.2</DT>
|
<DT>libburn-0.8.2</DT>
|
||||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||||
developed and maintained since August 2006 by
|
developed and maintained since August 2006 by
|
||||||
Thomas Schmitt from team of libburnia-project.org)
|
Thomas Schmitt from team of libburnia-project.org)
|
||||||
@ -71,8 +74,8 @@ Thomas Schmitt from team of libburnia-project.org)
|
|||||||
</P>
|
</P>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
This program system has been tested on Intel/AMD Linux and FreeBSD systems
|
This program system has been tested on Intel/AMD with Linux, FreeBSD,
|
||||||
only.<BR>
|
and OpenSolaris based operating systems.<BR>
|
||||||
Ports to other usable systems are appreciated. Reports are welcome.
|
Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
@ -104,8 +107,9 @@ BD-R. Write mode -tao works with anything but quickly blanked DVD-RW.
|
|||||||
<DD>#<KBD> cdrskin --devices</KBD></DD>
|
<DD>#<KBD> cdrskin --devices</KBD></DD>
|
||||||
<DT>Being superuser avoids permission problems with /dev/srN resp. /dev/hdX .
|
<DT>Being superuser avoids permission problems with /dev/srN resp. /dev/hdX .
|
||||||
</DT>
|
</DT>
|
||||||
<DT>Ordinary users should then get granted rw access to the /dev files
|
<DT>Ordinary users should then get granted access to the /dev files
|
||||||
as listed by option --devices.</DT>
|
as listed by option --devices. Linux and FreeBSD demand rw-permission.
|
||||||
|
On Solaris it is r-permission and privileges "basic,sys_devices".</DT>
|
||||||
<DT> </DT>
|
<DT> </DT>
|
||||||
|
|
||||||
<DT>Get info about a particular drive or loaded media:</DT>
|
<DT>Get info about a particular drive or loaded media:</DT>
|
||||||
@ -193,8 +197,8 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
|
|||||||
<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.7.2.pl01.tar.gz">cdrskin-0.7.2.pl01.tar.gz</A>
|
<DD><A HREF="cdrskin-0.8.2.pl00.tar.gz">cdrskin-0.8.2.pl00.tar.gz</A>
|
||||||
(780 KB).
|
(845 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
|
||||||
@ -243,41 +247,38 @@ 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.7.0.pl00:
|
Enhancements towards previous stable version cdrskin-0.8.0.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Better interpretation of options -mode2, -xa, -xa1, -xa2</LI>
|
<LI>A new system adapter allows to burn CD, DVD and BD on OpenSolaris</LI>
|
||||||
<LI>New option --xa1-ignore</LI>
|
|
||||||
<LI>New -atip report lines "Product Id:" and "Producer:"</LI>
|
|
||||||
<LI>Emulation of some -minfo output</LI>
|
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-0.7.0.pl00:
|
Bug fixes towards cdrskin-0.8.0.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>CD TAO sessions with multiple tracks did not work in -dummy mode</LI>
|
<LI>
|
||||||
|
CD TOC was not read if the first track did not start at LBA 0
|
||||||
|
</LI>
|
||||||
|
<LI>
|
||||||
|
CD-ROM media got attributed random lead-in and lead-out adresses
|
||||||
|
</LI>
|
||||||
|
<LI>
|
||||||
|
SIGSEGV of experimental libcdio system adapter if drive list is empty
|
||||||
|
</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-0.7.2.pl00:
|
|
||||||
<UL>
|
|
||||||
<LI>Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.</LI>
|
|
||||||
<LI>Workaround for Pioneer DVR-216D which did not always eject the tray.</LI>
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 0.7.3 :</H3></DT>
|
<DT><H3>Development snapshot, version 0.8.3 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 0.7.2.pl00:
|
<DD>Enhancements towards current stable version 0.8.2.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Implemented option -V for logging of SCSI commands</LI>
|
<LI>none yet</LI>
|
||||||
<LI>New options dvd_obs= and stdio_fsync=</LI>
|
|
||||||
<LI>New compile_cdrskin.sh options -o_direct (Linux only), -dvd_obs_64k</LI>
|
|
||||||
<!--
|
<!--
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
@ -285,10 +286,9 @@ Bug fixes towards cdrskin-0.7.2.pl00:
|
|||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD>Bug fixes towards cdrskin-0.7.2.pl00:
|
<DD>Bug fixes towards cdrskin-0.8.2.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.</LI>
|
<LI>none yet</LI>
|
||||||
<LI>Workaround for Pioneer DVR-216D which did not always eject the tray.</LI>
|
|
||||||
<!--
|
<!--
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
@ -296,10 +296,10 @@ Bug fixes towards cdrskin-0.7.2.pl00:
|
|||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 0.7.3</A>
|
<DD><A HREF="README_cdrskin_devel">README 0.8.3</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.3 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin_0.8.3 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.3 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin_0.8.3 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.3)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.8.3)</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>
|
||||||
@ -319,8 +319,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.7.3.tar.gz">cdrskin-0.7.3.tar.gz</A>
|
<A HREF="cdrskin-0.8.3.tar.gz">cdrskin-0.8.3.tar.gz</A>
|
||||||
(800 KB).
|
(845 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<!-- This is not offered any more since spring 2008
|
<!-- This is not offered any more since spring 2008
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2009.12.06.093847"
|
#define Cdrskin_timestamP "2010.06.11.080001"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,14 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# compile_cdrskin.sh
|
# compile_cdrskin.sh
|
||||||
# Copyright 2005 - 2009 Thomas Schmitt, scdbackup@gmx.net, GPL version 2
|
# Copyright 2005 - 2010 Thomas Schmitt, scdbackup@gmx.net, GPL
|
||||||
# to be executed within ./libburn-* resp ./cdrskin-*
|
# to be executed within ./libburn-* resp ./cdrskin-*
|
||||||
|
|
||||||
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"
|
||||||
fifo_opts="-DCdrskin_use_libburn_fifO"
|
fifo_opts=""
|
||||||
libvers="-DCdrskin_libburn_0_7_3"
|
libvers="-DCdrskin_libburn_0_8_2"
|
||||||
|
|
||||||
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
||||||
# burn="libburn/libburn_libburn_la-"
|
# burn="libburn/libburn_libburn_la-"
|
||||||
@ -20,11 +20,19 @@ libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
|||||||
do_strip=0
|
do_strip=0
|
||||||
static_opts=
|
static_opts=
|
||||||
warn_opts="-Wall"
|
warn_opts="-Wall"
|
||||||
|
libcdio=
|
||||||
fifo_source="cdrskin/cdrfifo.c"
|
fifo_source="cdrskin/cdrfifo.c"
|
||||||
compile_cdrskin=1
|
compile_cdrskin=1
|
||||||
compile_cdrfifo=0
|
compile_cdrfifo=0
|
||||||
compile_dewav=0
|
compile_dewav=0
|
||||||
|
|
||||||
|
libcam=
|
||||||
|
os=$(uname -s)
|
||||||
|
case $os in
|
||||||
|
*FreeBSD)
|
||||||
|
libcam="-lcam"
|
||||||
|
esac
|
||||||
|
|
||||||
for i in "$@"
|
for i in "$@"
|
||||||
do
|
do
|
||||||
if test "$i" = "-compile_cdrfifo"
|
if test "$i" = "-compile_cdrfifo"
|
||||||
@ -39,15 +47,15 @@ do
|
|||||||
libdax_audioxtr_o=
|
libdax_audioxtr_o=
|
||||||
libdax_msgs_o="$burn"message.o
|
libdax_msgs_o="$burn"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_7_2"
|
elif test "$i" = "-libburn_0_8_2"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_7_2"
|
libvers="-DCdrskin_libburn_0_8_2"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-libburn_svn"
|
elif test "$i" = "-libburn_svn"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_7_3"
|
libvers="-DCdrskin_libburn_0_8_3"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
@ -85,6 +93,13 @@ do
|
|||||||
then
|
then
|
||||||
fifo_source=
|
fifo_source=
|
||||||
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
||||||
|
elif test "$i" = "-use_libburn_cleanup"
|
||||||
|
then
|
||||||
|
fifo_source=
|
||||||
|
fifo_opts="-DCdrskin_use_libburn_cleanuP -DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
||||||
|
elif test "$i" = "-use_libcdio"
|
||||||
|
then
|
||||||
|
libcdio="-lcdio"
|
||||||
elif test "$i" = "-g"
|
elif test "$i" = "-g"
|
||||||
then
|
then
|
||||||
debug_opts="-g"
|
debug_opts="-g"
|
||||||
@ -94,9 +109,10 @@ 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 " -libburn_0_7_2 set macro to match libburn-0.7.2"
|
echo " -libburn_0_8_2 set macro to match libburn-0.8.2"
|
||||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||||
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
||||||
|
echo " -use_libcdio link with -lcdio because libburn uses it."
|
||||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
||||||
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
||||||
@ -120,7 +136,7 @@ echo "Build timestamp : $timestamp"
|
|||||||
|
|
||||||
if test "$compile_cdrskin"
|
if test "$compile_cdrskin"
|
||||||
then
|
then
|
||||||
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj"
|
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj $libcdio $libcam"
|
||||||
cc -I. \
|
cc -I. \
|
||||||
$warn_opts \
|
$warn_opts \
|
||||||
$static_opts \
|
$static_opts \
|
||||||
@ -165,6 +181,8 @@ then
|
|||||||
"$burn"crc.o \
|
"$burn"crc.o \
|
||||||
"$burn"ecma130ab.o \
|
"$burn"ecma130ab.o \
|
||||||
\
|
\
|
||||||
|
$libcdio \
|
||||||
|
$libcam \
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
ret=$?
|
ret=$?
|
||||||
|
65
configure.ac
65
configure.ac
@ -1,13 +1,15 @@
|
|||||||
AC_INIT([libburn], [0.7.3], [http://libburnia-project.org])
|
AC_INIT([libburn], [0.8.2], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_CANONICAL_TARGET
|
AC_CANONICAL_TARGET
|
||||||
|
|
||||||
|
LIBBURNIA_SET_FLAGS
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
|
||||||
dnl Notes by ts A71207 - A91012 :
|
dnl Notes by ts A71207 - B00611 :
|
||||||
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.
|
||||||
@ -75,6 +77,11 @@ dnl 0.6.6 = libburn.so.4.31.0
|
|||||||
dnl 0.6.8 = libburn.so.4.33.0
|
dnl 0.6.8 = libburn.so.4.33.0
|
||||||
dnl 0.7.0 = libburn.so.4.35.0
|
dnl 0.7.0 = libburn.so.4.35.0
|
||||||
dnl 0.7.2 = libburn.so.4.37.0
|
dnl 0.7.2 = libburn.so.4.37.0
|
||||||
|
dnl 0.7.4 = libburn.so.4.39.0
|
||||||
|
dnl 0.7.6 = libburn.so.4.41.0
|
||||||
|
dnl 0.7.8 = libburn.so.4.43.0
|
||||||
|
dnl 0.8.0 = libburn.so.4.45.0
|
||||||
|
dnl 0.8.2 = libburn.so.4.47.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.
|
||||||
@ -99,8 +106,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=7
|
BURN_MINOR_VERSION=8
|
||||||
BURN_MICRO_VERSION=3
|
BURN_MICRO_VERSION=2
|
||||||
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)
|
||||||
@ -111,15 +118,15 @@ 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 A91116
|
dnl ts B00409
|
||||||
dnl ### This is the release version libburn-0.7.2 = libburn.so.4.37.0
|
dnl This is the release version libburn-0.8.2
|
||||||
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 ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 42 - 38 = 4 . Linux library name = libburn.so.4.38.0
|
dnl SONAME = 51 - 47 = 4 . Linux library name = libburn.so.4.47.0
|
||||||
LT_CURRENT=42
|
LT_CURRENT=51
|
||||||
LT_AGE=38
|
LT_AGE=47
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
@ -196,8 +203,8 @@ CFLAGS="$CFLAGS $LIBBURN_O_DIRECT_DEF"
|
|||||||
|
|
||||||
dnl ts A91116
|
dnl ts A91116
|
||||||
AC_ARG_ENABLE(dvd-obs-64k,
|
AC_ARG_ENABLE(dvd-obs-64k,
|
||||||
[ --enable-dvd-obs-64k 64 KB default size for DVD/BD writing, default=no],
|
[ --enable-dvd-obs-64k 64 KB default size for DVD/BD writing, default=no],
|
||||||
, enable_fifo_odirect=no)
|
, enable_dvd_obs_64k=no)
|
||||||
if test x$enable_dvd_obs_64k = xyes; then
|
if test x$enable_dvd_obs_64k = xyes; then
|
||||||
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
||||||
echo "enabled write size default 64 KB on DVD and BD"
|
echo "enabled write size default 64 KB on DVD and BD"
|
||||||
@ -205,10 +212,36 @@ else
|
|||||||
LIBBURN_DVD_OBS_64K=
|
LIBBURN_DVD_OBS_64K=
|
||||||
echo "disabled write size default 64 KB on DVD and BD"
|
echo "disabled write size default 64 KB on DVD and BD"
|
||||||
fi
|
fi
|
||||||
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
|
|
||||||
dnl ### AC_SUBST(LIBBURN_DVD_OBS_64K)
|
|
||||||
CFLAGS="$CFLAGS $LIBBURN_DVD_OBS_64K"
|
CFLAGS="$CFLAGS $LIBBURN_DVD_OBS_64K"
|
||||||
|
|
||||||
|
dnl ts A91218
|
||||||
|
AC_ARG_ENABLE(libcdio,
|
||||||
|
[ --enable-libcdio Enable EXPERIMENTAL use of libcdio as system adapter, default=no],
|
||||||
|
, enable_libcdio=no)
|
||||||
|
if test x$enable_libcdio = xyes; then
|
||||||
|
dnl Check whether there is libcdio-devel and libcdio-runtime.
|
||||||
|
dnl If not, erase this macro
|
||||||
|
LIBCDIO_DEF="-DLibburn_use_libcdiO"
|
||||||
|
dnl The empty yes case obviously causes -lcdio to be linked
|
||||||
|
AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= )
|
||||||
|
else
|
||||||
|
LIBCDIO_DEF=
|
||||||
|
fi
|
||||||
|
if test x$LIBCDIO_DEF = x
|
||||||
|
then
|
||||||
|
if test x$enable_libcdio = xyes
|
||||||
|
then
|
||||||
|
echo "WARNING: could not enable use of libcdio as system adapter"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "enabled EXPERIMENTAL use of libcdio as system adapter"
|
||||||
|
CFLAGS="$CFLAGS $LIBCDIO_DEF"
|
||||||
|
|
||||||
|
LIBCDIO_REQUIRED=0.83
|
||||||
|
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl Add compiler-specific flags
|
dnl Add compiler-specific flags
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ 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] [--try_to_simulate]
|
[--blank_fast|--blank_full|--format] [--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):
|
||||||
test/libburner --drive -
|
test/libburner --drive -
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
libburnia-project.org Optical Media Rotisserie Recipes as of January 2009
|
libburnia-project.org Optical Media Rotisserie Recipes as of January 2010
|
||||||
|
|
||||||
Content:
|
Content:
|
||||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||||
@ -86,7 +86,7 @@ parameters:
|
|||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 4 for data , 0 for audio
|
Track Mode Describes frame type 4 for data , 0 for audio
|
||||||
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
||||||
@ -119,19 +119,22 @@ A track must at least contain 300 payload blocks: 4 seconds of audio or
|
|||||||
600 KiB of data.
|
600 KiB of data.
|
||||||
(mmc5r03c.pdf 6.3.3.1.2)
|
(mmc5r03c.pdf 6.3.3.1.2)
|
||||||
|
|
||||||
The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b.
|
Up to december 2009 the track was closed by 5Bh CLOSE TRACK SESSION Close
|
||||||
Older MMC specifies a valid Logical Track Number FFh to depict the open track.
|
Function 001b. Older MMC specifies a valid Logical Track Number FFh to depict
|
||||||
MMC-5 is quite silent about this. FFh works for my drives.
|
the open track. MMC-5 is quite silent about this. FFh worked for my drives.
|
||||||
(mmc5r03c.pdf 6.3.3.1.2)
|
(mmc5r03c.pdf 6.3.3.1.2)
|
||||||
|
This is omitted since libburn-0.7.4, relying entirely on 35h SYNCHRONIZE CACHE.
|
||||||
|
First appeared a drive where CLOSE TRACK fails in simulation mode, later
|
||||||
|
another one produced error replies even with real burning.
|
||||||
|
|
||||||
After that, a new track may be written beginning with sending the mode page 05h
|
After that, a new track may be written beginning with sending the mode page 05h
|
||||||
again. It is not tested wether 05h can be omitted if Track Mode and Data Block
|
again. It is not tested whether 05h can be omitted if Track Mode and Data Block
|
||||||
Type are the same as with the previous track.
|
Type are the same as with the previous track.
|
||||||
The new track will be added to the session which was opened by the first track.
|
The new track will be added to the session which was opened by the first track.
|
||||||
|
|
||||||
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
||||||
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
||||||
value in mode page 05h wether the disc is finalized or stays appendable.
|
value in mode page 05h whether the disc is finalized or stays appendable.
|
||||||
(mmc5r03c.pdf 6.3.3.1.3)
|
(mmc5r03c.pdf 6.3.3.1.3)
|
||||||
|
|
||||||
|
|
||||||
@ -202,7 +205,7 @@ for finalized disc.
|
|||||||
In libburn the address of the first track in the last session is obtained from
|
In libburn the address of the first track in the last session is obtained from
|
||||||
the last session's POINT = A0h and from the track descriptor with the POINT
|
the last session's POINT = A0h and from the track descriptor with the POINT
|
||||||
value matching the PMIN value of the A0h descriptor.
|
value matching the PMIN value of the A0h descriptor.
|
||||||
Untested is wether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
Untested is whether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
||||||
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
||||||
|
|
||||||
|
|
||||||
@ -308,7 +311,7 @@ A Write Parameters mode page 05h has to be composed and transmitted via
|
|||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 0 (is ignored)
|
Track Mode Describes frame type 0 (is ignored)
|
||||||
Data Block Type Layout of payload blocks 0 (is ignored)
|
Data Block Type Layout of payload blocks 0 (is ignored)
|
||||||
@ -349,7 +352,7 @@ There is no separator between the tracks of a pure mode SAO session.
|
|||||||
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
||||||
between data mode tracks and audio mode tracks.)
|
between data mode tracks and audio mode tracks.)
|
||||||
(libburn sends its own buffer to the drive at the end of each track but does
|
(libburn sends its own buffer to the drive at the end of each track but does
|
||||||
not sync the drive's chache. It is unclear wether this separation of tracks
|
not sync the drive's chache. It is unclear whether this separation of tracks
|
||||||
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
||||||
harm in any case and would probably be unavoidable if audio and data tracks
|
harm in any case and would probably be unavoidable if audio and data tracks
|
||||||
were mixed.)
|
were mixed.)
|
||||||
@ -755,7 +758,8 @@ 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 one has to write full 64 kB buffers.
|
With the tested BD-RE one must write full 64 kB buffers, or else writing
|
||||||
|
might not get into effect at all.
|
||||||
|
|
||||||
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
|
||||||
@ -769,7 +773,8 @@ MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
|
|||||||
None of the features of profiles 0012h and 0043h promises the existence of
|
None of the features of profiles 0012h and 0043h promises the existence of
|
||||||
AAh WRITE12.
|
AAh WRITE12.
|
||||||
(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.
|
Nevertheless it worked on all tested drives if proper alignment and block
|
||||||
|
size was observed.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -841,6 +846,8 @@ 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
|
address gives the size of a particular session. ECMA-119 explains how to
|
||||||
retrieve more info from the PVD (e.g. the volume id).
|
retrieve more info from the PVD (e.g. the volume id).
|
||||||
|
|
||||||
|
See also the multi-session example in libisofs/doc/checksums.txt.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -933,7 +940,7 @@ Multi-Session by the application.
|
|||||||
LS_V Link size valid 1=true
|
LS_V Link size valid 1=true
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 5 [*1]
|
Track Mode Describes frame type 5 [*1]
|
||||||
Data Block Type Layout of payload blocks 8 [*2]
|
Data Block Type Layout of payload blocks 8 [*2]
|
||||||
@ -980,7 +987,7 @@ from the reply of 51h READ DISC INFORMATION requesting Data Type 000b
|
|||||||
Multiple tracks are permissible in a single session. After all of them have
|
Multiple tracks are permissible in a single session. After all of them have
|
||||||
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
||||||
Number 0 closes the session. It depends on the Multi-Session value in mode
|
Number 0 closes the session. It depends on the Multi-Session value in mode
|
||||||
page 05h wether the disc is finalized or stays appendable.
|
page 05h whether the disc is finalized or stays appendable.
|
||||||
(mmc5r03c.pdf 6.3.3.2.3)
|
(mmc5r03c.pdf 6.3.3.2.3)
|
||||||
|
|
||||||
|
|
||||||
@ -1005,7 +1012,7 @@ The mode page 05h to be sent :
|
|||||||
LS_V Link size valid 0=false [*3]
|
LS_V Link size valid 0=false [*3]
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
Track Mode Describes frame type 5 [*1]
|
Track Mode Describes frame type 5 [*1]
|
||||||
Data Block Type Layout of payload blocks 8 [*2]
|
Data Block Type Layout of payload blocks 8 [*2]
|
||||||
Link Size ??? 0 [*3]
|
Link Size ??? 0 [*3]
|
||||||
@ -1222,7 +1229,7 @@ No mode page 05h is to be sent.
|
|||||||
growisofs sends a page but the specs clearly state that one shall not do.
|
growisofs sends a page but the specs clearly state that one shall not do.
|
||||||
(mmc5r03c.pdf 7.5.3)
|
(mmc5r03c.pdf 7.5.3)
|
||||||
|
|
||||||
It is optional wether a track size is reserved in advance or not. Eventually
|
It is optional whether a track size is reserved in advance or not. Eventually
|
||||||
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
||||||
already be aligned to 32 KiB.
|
already be aligned to 32 KiB.
|
||||||
(mmc5r03c.pdf 6.31)
|
(mmc5r03c.pdf 6.31)
|
||||||
|
116
libburn/async.c
116
libburn/async.c
@ -1,5 +1,9 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
/* ts A71019 */
|
/* ts A71019 */
|
||||||
|
|
||||||
@ -19,6 +23,9 @@
|
|||||||
#define Libburn_detach_done_workeR 1
|
#define Libburn_detach_done_workeR 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
@ -36,6 +43,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <a ssert.h>
|
#include <a ssert.h>
|
||||||
@ -228,6 +236,22 @@ static void *scan_worker_func(struct w_list *w)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
|
||||||
|
int indices, int sectors, int flag)
|
||||||
|
{
|
||||||
|
/* reset the progress indicator */
|
||||||
|
d->progress.session = 0;
|
||||||
|
d->progress.sessions = sessions;
|
||||||
|
d->progress.track = 0;
|
||||||
|
d->progress.tracks = tracks;
|
||||||
|
d->progress.index = 0;
|
||||||
|
d->progress.indices = indices;
|
||||||
|
d->progress.start_sector = 0;
|
||||||
|
d->progress.sectors = sectors;
|
||||||
|
d->progress.sector = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
||||||
{
|
{
|
||||||
struct scan_opts o;
|
struct scan_opts o;
|
||||||
@ -297,8 +321,27 @@ drive_is_active:;
|
|||||||
|
|
||||||
static void *erase_worker_func(struct w_list *w)
|
static void *erase_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define Libburn_protect_erase_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_erase_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect blank thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_erase_threaD */
|
||||||
|
|
||||||
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_erase_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_erase_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +353,7 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
/* a ssert(drive); */
|
/* a ssert(drive); */
|
||||||
/* a ssert(!SCAN_GOING()); */
|
/* a ssert(!SCAN_GOING()); */
|
||||||
/* a ssert(!find_worker(drive)); */
|
/* a ssert(!find_worker(drive)); */
|
||||||
|
|
||||||
if((drive == NULL)) {
|
if((drive == NULL)) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020104,
|
0x00020104,
|
||||||
@ -325,6 +369,9 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
0, 0);
|
0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
||||||
|
|
||||||
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
||||||
drive->cancel = 1;
|
drive->cancel = 1;
|
||||||
|
|
||||||
@ -365,9 +412,28 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
/* ts A61230 */
|
/* ts A61230 */
|
||||||
static void *format_worker_func(struct w_list *w)
|
static void *format_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define Libburn_protect_format_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_format_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect format thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_format_threaD */
|
||||||
|
|
||||||
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
||||||
w->u.format.flag);
|
w->u.format.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_format_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_format_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,6 +445,8 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
|||||||
int ok = 0, ret;
|
int ok = 0, ret;
|
||||||
char msg[160];
|
char msg[160];
|
||||||
|
|
||||||
|
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
||||||
|
|
||||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
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,
|
||||||
@ -508,8 +576,22 @@ no_non_default_bd_re:;
|
|||||||
static void *write_disc_worker_func(struct w_list *w)
|
static void *write_disc_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = w->u.write.drive;
|
struct burn_drive *d = w->u.write.drive;
|
||||||
|
char msg[80];
|
||||||
|
|
||||||
|
#define Libburn_protect_write_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_write_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect write thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_write_threaD */
|
||||||
|
|
||||||
d->thread_pid = getpid();
|
d->thread_pid = getpid();
|
||||||
|
d->thread_tid = pthread_self();
|
||||||
d->thread_pid_valid= 1;
|
d->thread_pid_valid= 1;
|
||||||
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
||||||
d->thread_pid_valid= 0;
|
d->thread_pid_valid= 0;
|
||||||
@ -519,7 +601,19 @@ static void *write_disc_worker_func(struct w_list *w)
|
|||||||
*/
|
*/
|
||||||
burn_write_opts_free(w->u.write.opts);
|
burn_write_opts_free(w->u.write.opts);
|
||||||
|
|
||||||
|
sprintf(msg, "Write thread on drive %d ended", d->global_index);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020178,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_write_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_write_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,6 +637,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset_progress(d, disc->sessions, disc->session[0]->tracks,
|
||||||
|
disc->session[0]->track[0]->indices, 0, 0);
|
||||||
|
|
||||||
/* For the next lines any return indicates failure */
|
/* For the next lines any return indicates failure */
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
|
|
||||||
@ -609,12 +706,30 @@ static void *fifo_worker_func(struct w_list *w)
|
|||||||
{
|
{
|
||||||
int old;
|
int old;
|
||||||
|
|
||||||
|
#define Libburn_protect_fifo_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_fifo_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect fifo thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_fifo_threaD */
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
||||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
||||||
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
|
/* 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());
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_fifo_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_fifo_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,6 +754,7 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
|||||||
add_worker(Burnworker_type_fifO, NULL,
|
add_worker(Burnworker_type_fifO, NULL,
|
||||||
(WorkerFunc) fifo_worker_func, &o);
|
(WorkerFunc) fifo_worker_func, &o);
|
||||||
fs->is_started = 1;
|
fs->is_started = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
|
Copyright (c) 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
This file bundles variables which disable changes in libburn which are
|
This file bundles variables which disable changes in libburn which are
|
||||||
not yet completely accepted.
|
not yet completely accepted.
|
||||||
|
@ -3,13 +3,17 @@
|
|||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPL license within GPL projects, BSD license elsewise.
|
Provided under GPLv2+ license within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -40,7 +44,8 @@ static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
|
|||||||
#else /* ! Cleanup_has_no_libburn_os_H */
|
#else /* ! Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
/* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */
|
/* Outdated. GNU/Linux only.
|
||||||
|
For backward compatibility with pre-libburn-0.2.3 */
|
||||||
|
|
||||||
/* Signals to be caught */
|
/* Signals to be caught */
|
||||||
static int signal_list[]= {
|
static int signal_list[]= {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPL license within GPL projects, BSD license elsewise.
|
Provided under GPLv2+ within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Cleanup_includeD
|
#ifndef Cleanup_includeD
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
static unsigned short ccitt_table[256] = {
|
static unsigned short ccitt_table[256] = {
|
||||||
@ -104,6 +108,15 @@ unsigned long crc32_table[256] = {
|
|||||||
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Exploration ts B00214 :
|
||||||
|
ECMA-130, 22.3.6 "CRC field"
|
||||||
|
Generating polynomial: x^16 + x^12 + x^5 + 1
|
||||||
|
Also known as CRC-16-CCITT, CRC-CCITT
|
||||||
|
|
||||||
|
Use in libburn for raw write modes in sector.c.
|
||||||
|
There is also disabled code in read.c which would use it.
|
||||||
|
*/
|
||||||
unsigned short crc_ccitt(unsigned char *q, int len)
|
unsigned short crc_ccitt(unsigned char *q, int len)
|
||||||
{
|
{
|
||||||
unsigned short crc = 0;
|
unsigned short crc = 0;
|
||||||
@ -112,6 +125,20 @@ unsigned short crc_ccitt(unsigned char *q, int len)
|
|||||||
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
||||||
return ~crc;
|
return ~crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Exploration ts B00214 :
|
||||||
|
ECMA-130, 14.3 "EDC field"
|
||||||
|
"The EDC codeword must be divisible by the check polynomial:
|
||||||
|
P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
||||||
|
"
|
||||||
|
|
||||||
|
>>> Test whether this coincides with CRC-32 IEEE 802.3
|
||||||
|
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10
|
||||||
|
+ x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
|
||||||
|
|
||||||
|
Used for raw writing in sector.c
|
||||||
|
*/
|
||||||
unsigned int crc_32(unsigned char *data, int len)
|
unsigned int crc_32(unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
unsigned int crc = 0;
|
unsigned int crc = 0;
|
||||||
|
@ -3,7 +3,21 @@
|
|||||||
#ifndef BURN__CRC_H
|
#ifndef BURN__CRC_H
|
||||||
#define BURN__CRC_H
|
#define BURN__CRC_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Xorriso_standalonE
|
||||||
|
/* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
|
#define Libburn_no_crc_C 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
|
|
||||||
unsigned short crc_ccitt(unsigned char *, int len);
|
unsigned short crc_ccitt(unsigned char *, int len);
|
||||||
unsigned int crc_32(unsigned char *, int len);
|
unsigned int crc_32(unsigned char *, int len);
|
||||||
|
|
||||||
|
#endif /* Libburn_no_crc_C */
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__CRC_H */
|
#endif /* BURN__CRC_H */
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
194
libburn/drive.c
194
libburn/drive.c
@ -1,9 +1,19 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
/* #include <m alloc.h> ts A61013 : not in Linux man 3 malloc */
|
/* #include <m alloc.h> ts A61013 : not in GNU/Linux man 3 malloc */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -90,6 +100,7 @@ void burn_drive_free_subs(struct burn_drive *d)
|
|||||||
if (d->stdio_fd >= 0)
|
if (d->stdio_fd >= 0)
|
||||||
close (d->stdio_fd);
|
close (d->stdio_fd);
|
||||||
d->stdio_fd = -1;
|
d->stdio_fd = -1;
|
||||||
|
sg_dispose_drive(d, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -369,6 +380,7 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
|
|||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
d->thread_pid = 0;
|
d->thread_pid = 0;
|
||||||
d->thread_pid_valid = 0;
|
d->thread_pid_valid = 0;
|
||||||
|
memset(&(d->thread_tid), 0, sizeof(d->thread_tid));
|
||||||
d->toc_entries = 0;
|
d->toc_entries = 0;
|
||||||
d->toc_entry = NULL;
|
d->toc_entry = NULL;
|
||||||
d->disc = NULL;
|
d->disc = NULL;
|
||||||
@ -614,8 +626,9 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||||||
d->idata->product);
|
d->idata->product);
|
||||||
|
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
d->busy = BURN_DRIVE_ERASING;
|
|
||||||
d->erase(d, fast);
|
#ifdef Libburn_reset_progress_asynC
|
||||||
|
/* <<< This is now done in async.c */
|
||||||
/* reset the progress */
|
/* reset the progress */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
d->progress.sessions = 1;
|
d->progress.sessions = 1;
|
||||||
@ -626,6 +639,11 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||||||
d->progress.start_sector = 0;
|
d->progress.start_sector = 0;
|
||||||
d->progress.sectors = 0x10000;
|
d->progress.sectors = 0x10000;
|
||||||
d->progress.sector = 0;
|
d->progress.sector = 0;
|
||||||
|
#endif /* Libburn_reset_progress_asynC */
|
||||||
|
|
||||||
|
d->erase(d, fast);
|
||||||
|
d->busy = BURN_DRIVE_ERASING;
|
||||||
|
|
||||||
/* read the initial 0 stage */
|
/* read the initial 0 stage */
|
||||||
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
|
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
@ -652,6 +670,8 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||||||
char msg[80];
|
char msg[80];
|
||||||
struct buffer buf, *buf_mem = d->buffer;
|
struct buffer buf, *buf_mem = d->buffer;
|
||||||
|
|
||||||
|
#ifdef Libburn_reset_progress_asynC
|
||||||
|
/* <<< This is now done in async.c */
|
||||||
/* reset the progress */
|
/* reset the progress */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
d->progress.sessions = 1;
|
d->progress.sessions = 1;
|
||||||
@ -662,6 +682,8 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||||||
d->progress.start_sector = 0;
|
d->progress.start_sector = 0;
|
||||||
d->progress.sectors = 0x10000;
|
d->progress.sectors = 0x10000;
|
||||||
d->progress.sector = 0;
|
d->progress.sector = 0;
|
||||||
|
#endif /* Libburn_reset_progress_asynC */
|
||||||
|
|
||||||
stages = 1 + ((flag & 1) && size > 1024 * 1024);
|
stages = 1 + ((flag & 1) && size > 1024 * 1024);
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
d->busy = BURN_DRIVE_FORMATTING;
|
d->busy = BURN_DRIVE_FORMATTING;
|
||||||
@ -798,10 +820,22 @@ int burn_disc_erasable(struct burn_drive *d)
|
|||||||
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||||
struct burn_progress *p)
|
struct burn_progress *p)
|
||||||
{
|
{
|
||||||
|
/* --- Part of asynchronous signal handling --- */
|
||||||
|
/* This frequently used call may be used to react on messages from
|
||||||
|
the libburn built-in signal handler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ts B00225 :
|
||||||
|
If aborting with action 2:
|
||||||
|
catch control thread after it returned from signal handler.
|
||||||
|
Let it run burn_abort(4440,...)
|
||||||
|
*/
|
||||||
|
burn_init_catch_on_abort(0);
|
||||||
|
|
||||||
/* ts A70928 : inform control thread of signal in sub-threads */
|
/* ts A70928 : inform control thread of signal in sub-threads */
|
||||||
if (burn_global_abort_level > 0)
|
if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 0)
|
||||||
burn_global_abort_level++;
|
burn_global_abort_level++;
|
||||||
if (burn_global_abort_level > 5) {
|
if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 5) {
|
||||||
if (burn_global_signal_handler == NULL)
|
if (burn_global_signal_handler == NULL)
|
||||||
kill(getpid(), burn_global_abort_signum);
|
kill(getpid(), burn_global_abort_signum);
|
||||||
else
|
else
|
||||||
@ -811,6 +845,9 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
|||||||
burn_global_abort_level = -1;
|
burn_global_abort_level = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- End of asynchronous signal handling --- */
|
||||||
|
|
||||||
|
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
||||||
/* TODO: add mutex */
|
/* TODO: add mutex */
|
||||||
@ -832,9 +869,13 @@ int burn_drive_set_stream_recording(struct burn_drive *d, int recmode,
|
|||||||
|
|
||||||
void burn_drive_cancel(struct burn_drive *d)
|
void burn_drive_cancel(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
|
/* ts B00225 : these mutexes are unnecessary because "= 1" is atomar.
|
||||||
pthread_mutex_lock(&d->access_lock);
|
pthread_mutex_lock(&d->access_lock);
|
||||||
|
*/
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
|
/*
|
||||||
pthread_mutex_unlock(&d->access_lock);
|
pthread_mutex_unlock(&d->access_lock);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61007 : defunct because unused */
|
/* ts A61007 : defunct because unused */
|
||||||
@ -907,20 +948,27 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
|||||||
out->c2_errors = !!d->mdata->c2_pointers;
|
out->c2_errors = !!d->mdata->c2_pointers;
|
||||||
out->drive = d;
|
out->drive = d;
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_dummy_probe_wM
|
#ifdef Libburn_dummy_probe_write_modeS
|
||||||
|
|
||||||
/* ts A91112 */
|
/* ts A91112 */
|
||||||
/* Set default block types. The call d->probe_write_modes() is quite
|
/* Set default block types. The call d->probe_write_modes() is quite
|
||||||
obtrusive. It may be performed explicitely by new API call
|
obtrusive. It may be performed explicitely by new API call
|
||||||
burn_drive_probe_cd_write_modes().
|
burn_drive_probe_cd_write_modes().
|
||||||
*/
|
*/
|
||||||
out->tao_block_types = d->block_types[BURN_WRITE_TAO] =
|
if (out->write_dvdram || out->write_dvdr ||
|
||||||
BURN_BLOCK_MODE1 | BURN_BLOCK_RAW0;
|
out->write_cdrw || out->write_cdr) {
|
||||||
out->sao_block_types = d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
|
out->tao_block_types = d->block_types[BURN_WRITE_TAO] =
|
||||||
|
BURN_BLOCK_MODE1 | BURN_BLOCK_RAW0;
|
||||||
|
out->sao_block_types = d->block_types[BURN_WRITE_SAO] =
|
||||||
|
BURN_BLOCK_SAO;
|
||||||
|
} else {
|
||||||
|
out->tao_block_types = d->block_types[BURN_WRITE_TAO] = 0;
|
||||||
|
out->sao_block_types = d->block_types[BURN_WRITE_SAO] = 0;
|
||||||
|
}
|
||||||
out->raw_block_types = d->block_types[BURN_WRITE_RAW] = 0;
|
out->raw_block_types = d->block_types[BURN_WRITE_RAW] = 0;
|
||||||
out->packet_block_types = 0;
|
out->packet_block_types = 0;
|
||||||
|
|
||||||
#else /* Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
#else /* Libburn_dummy_probe_write_modeS */
|
||||||
|
|
||||||
/* update available block types for burners */
|
/* update available block types for burners */
|
||||||
if (out->write_dvdram || out->write_dvdr ||
|
if (out->write_dvdram || out->write_dvdr ||
|
||||||
@ -931,15 +979,14 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
|||||||
out->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
out->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
||||||
out->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
out->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
||||||
|
|
||||||
#endif /* ! Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
#endif /* ! Libburn_dummy_probe_write_modeS */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_dummy_probe_wM
|
|
||||||
|
|
||||||
/* ts A91112 candidate for API */
|
/* ts A91112 - B00114 API */
|
||||||
/* Probe available CD write modes and block types.
|
/* Probe available CD write modes and block types.
|
||||||
*/
|
*/
|
||||||
int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo)
|
int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo)
|
||||||
@ -958,8 +1005,6 @@ int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70907 : added parameter flag */
|
/* ts A70907 : added parameter flag */
|
||||||
/* @param flag bit0= reset global drive list */
|
/* @param flag bit0= reset global drive list */
|
||||||
@ -1317,6 +1362,7 @@ int burn_drive__fd_from_special_adr(char *adr)
|
|||||||
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
||||||
{
|
{
|
||||||
int ret = -1, fd = -1, role = 0;
|
int ret = -1, fd = -1, role = 0;
|
||||||
|
int is_block_dev = 0;
|
||||||
/* divided by 512 it needs to fit into a signed long integer */
|
/* divided by 512 it needs to fit into a signed long integer */
|
||||||
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
||||||
off_t read_size = -1;
|
off_t read_size = -1;
|
||||||
@ -1333,17 +1379,18 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||||||
else
|
else
|
||||||
ret = stat(fname, &stbuf);
|
ret = stat(fname, &stbuf);
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
|
is_block_dev = burn_os_is_2k_seekrw(fname, 0);
|
||||||
if (S_ISREG(stbuf.st_mode))
|
if (S_ISREG(stbuf.st_mode))
|
||||||
read_size = stbuf.st_size;
|
read_size = stbuf.st_size;
|
||||||
else if (S_ISBLK(stbuf.st_mode)) {
|
else if (is_block_dev) {
|
||||||
ret = burn_os_stdio_capacity(fname,
|
ret = burn_os_stdio_capacity(fname,
|
||||||
&read_size);
|
&read_size);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
read_size = -1;
|
read_size = (off_t) 0x7ffffff0 *
|
||||||
|
(off_t) 2048;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == -1 || S_ISBLK(stbuf.st_mode) ||
|
if (ret == -1 || is_block_dev || S_ISREG(stbuf.st_mode)) {
|
||||||
S_ISREG(stbuf.st_mode)) {
|
|
||||||
ret = burn_os_stdio_capacity(fname, &size);
|
ret = burn_os_stdio_capacity(fname, &size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
@ -1559,14 +1606,23 @@ int burn_drive_is_enumerable_adr(char *adr)
|
|||||||
#define BURN_DRIVE_MAX_LINK_DEPTH 20
|
#define BURN_DRIVE_MAX_LINK_DEPTH 20
|
||||||
|
|
||||||
/* ts A60922 ticket 33 */
|
/* ts A60922 ticket 33 */
|
||||||
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
/* @param flag bit0= no debug messages
|
||||||
|
bit1= resolve only links,
|
||||||
|
do not rely on drive list for resolving via st_rdev
|
||||||
|
*/
|
||||||
|
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
|
||||||
|
int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char link_target[4096], msg[4096+100], link_adr[4096], *adrpt;
|
char link_target[4096], msg[4096+100], link_adr[4096], *adrpt;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )", path);
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )",
|
||||||
|
path);
|
||||||
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
|
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
|
||||||
burn_drive_adr_debug_msg(
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg(
|
||||||
"burn_drive_resolve_link aborts because link too deep",
|
"burn_drive_resolve_link aborts because link too deep",
|
||||||
NULL);
|
NULL);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1574,12 +1630,15 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
|||||||
(*recursion_count)++;
|
(*recursion_count)++;
|
||||||
ret = readlink(path, link_target, sizeof(link_target));
|
ret = readlink(path, link_target, sizeof(link_target));
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
burn_drive_adr_debug_msg("readlink( %s ) returns -1", path);
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg("readlink( %s ) returns -1",
|
||||||
|
path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ret >= sizeof(link_target) - 1) {
|
if (ret >= sizeof(link_target) - 1) {
|
||||||
sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret);
|
sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret);
|
||||||
burn_drive_adr_debug_msg(msg, NULL);
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg(msg, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
link_target[ret] = 0;
|
link_target[ret] = 0;
|
||||||
@ -1592,10 +1651,25 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
|||||||
} else
|
} else
|
||||||
adrpt = link_target;
|
adrpt = link_target;
|
||||||
}
|
}
|
||||||
ret = burn_drive_convert_fs_adr_sub(adrpt, adr, recursion_count);
|
if (flag & 2) {
|
||||||
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
|
/* Link-only recursion */
|
||||||
link_target, ret);
|
if (lstat(adrpt, &stbuf) == -1) {
|
||||||
burn_drive_adr_debug_msg(msg, NULL);
|
;
|
||||||
|
} else if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
||||||
|
ret = burn_drive_resolve_link(adrpt, adr,
|
||||||
|
recursion_count, flag);
|
||||||
|
} else {
|
||||||
|
strcpy(adr, adrpt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Link and device number recursion */
|
||||||
|
ret = burn_drive_convert_fs_adr_sub(adrpt, adr,
|
||||||
|
recursion_count);
|
||||||
|
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
|
||||||
|
link_target, ret);
|
||||||
|
}
|
||||||
|
if (flag & 1)
|
||||||
|
burn_drive_adr_debug_msg(msg, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1769,7 +1843,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
||||||
ret = burn_drive_resolve_link(path, adr, rec_count);
|
ret = burn_drive_resolve_link(path, adr, rec_count, 0);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
return 1;
|
return 1;
|
||||||
burn_drive_adr_debug_msg("link fallback via stat( %s )", path);
|
burn_drive_adr_debug_msg("link fallback via stat( %s )", path);
|
||||||
@ -1818,17 +1892,12 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Abort any running drive operation and finish libburn.
|
/* ts B00226 : Outsourced backend of burn_abort()
|
||||||
@param patience Maximum number of seconds to wait for drives to finish
|
@param flag bit0= do not call burn_finish()
|
||||||
@param pacifier_func Function to produce appeasing messages. See
|
|
||||||
burn_abort_pacifier() for an example.
|
|
||||||
@return 1 ok, all went well
|
|
||||||
0 had to leave a drive in unclean state
|
|
||||||
<0 severe error, do no use libburn again
|
|
||||||
*/
|
*/
|
||||||
int burn_abort(int patience,
|
int burn_abort_5(int patience,
|
||||||
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
void *handle)
|
void *handle, int elapsed, int flag)
|
||||||
{
|
{
|
||||||
int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1;
|
int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1;
|
||||||
unsigned long wait_grain= 100000;
|
unsigned long wait_grain= 100000;
|
||||||
@ -1838,7 +1907,14 @@ int burn_abort(int patience,
|
|||||||
time_t stdio_patience = 3;
|
time_t stdio_patience = 3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr,
|
||||||
|
"libburn_EXPERIMENTAL: burn_abort_5(%d,%d)\n", patience, flag);
|
||||||
|
*/
|
||||||
|
|
||||||
current_time = start_time = pacifier_time = time(0);
|
current_time = start_time = pacifier_time = time(0);
|
||||||
|
start_time -= elapsed;
|
||||||
end_time = start_time + patience;
|
end_time = start_time + patience;
|
||||||
|
|
||||||
/* >>> ts A71002 : are there any threads at work ?
|
/* >>> ts A71002 : are there any threads at work ?
|
||||||
@ -1846,7 +1922,7 @@ int burn_abort(int patience,
|
|||||||
change status on their own.
|
change status on their own.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while(current_time-end_time < patience) {
|
while(current_time < end_time || (patience <= 0 && first_round)) {
|
||||||
still_not_done = 0;
|
still_not_done = 0;
|
||||||
|
|
||||||
for(i = 0; i < drivetop + 1; i++) {
|
for(i = 0; i < drivetop + 1; i++) {
|
||||||
@ -1885,6 +1961,9 @@ int burn_abort(int patience,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(occup <= 10) {
|
if(occup <= 10) {
|
||||||
|
if (drive_array[i].drive_role != 1)
|
||||||
|
/* occup == -1 comes early */
|
||||||
|
usleep(1000000);
|
||||||
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)
|
||||||
@ -1896,7 +1975,7 @@ int burn_abort(int patience,
|
|||||||
}
|
}
|
||||||
first_round = 0;
|
first_round = 0;
|
||||||
|
|
||||||
if(still_not_done == 0)
|
if(still_not_done == 0 || patience <= 0)
|
||||||
break;
|
break;
|
||||||
usleep(wait_grain);
|
usleep(wait_grain);
|
||||||
current_time = time(0);
|
current_time = time(0);
|
||||||
@ -1909,11 +1988,35 @@ int burn_abort(int patience,
|
|||||||
pacifier_time = current_time;
|
pacifier_time = current_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
burn_finish();
|
if (!(flag & 1))
|
||||||
|
burn_finish();
|
||||||
return(still_not_done == 0);
|
return(still_not_done == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Abort any running drive operation and finish libburn.
|
||||||
|
@param patience Maximum number of seconds to wait for drives to finish
|
||||||
|
@param pacifier_func Function to produce appeasing messages. See
|
||||||
|
burn_abort_pacifier() for an example.
|
||||||
|
@return 1 ok, all went well
|
||||||
|
0 had to leave a drive in unclean state
|
||||||
|
<0 severe error, do no use libburn again
|
||||||
|
*/
|
||||||
|
int burn_abort(int patience,
|
||||||
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
|
void *handle)
|
||||||
|
{
|
||||||
|
int ret, flg = 0;
|
||||||
|
|
||||||
|
if (patience < 0) {
|
||||||
|
patience = 0;
|
||||||
|
flg |= 1;
|
||||||
|
}
|
||||||
|
ret = burn_abort_5(patience, pacifier_func, handle, 0, flg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61020 API function */
|
/* ts A61020 API function */
|
||||||
int burn_drive_get_start_end_lba(struct burn_drive *d,
|
int burn_drive_get_start_end_lba(struct burn_drive *d,
|
||||||
int *start_lba, int *end_lba, int flag)
|
int *start_lba, int *end_lba, int flag)
|
||||||
@ -2608,6 +2711,9 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
|
|||||||
if (S_ISBLK(stbuf1.st_mode) && S_ISBLK(stbuf2.st_mode) &&
|
if (S_ISBLK(stbuf1.st_mode) && S_ISBLK(stbuf2.st_mode) &&
|
||||||
stbuf1.st_rdev == stbuf2.st_rdev)
|
stbuf1.st_rdev == stbuf2.st_rdev)
|
||||||
return 1; /* same major,minor device number */
|
return 1; /* same major,minor device number */
|
||||||
|
if (S_ISCHR(stbuf1.st_mode) && S_ISCHR(stbuf2.st_mode) &&
|
||||||
|
stbuf1.st_rdev == stbuf2.st_rdev)
|
||||||
|
return 1; /* same major,minor device number */
|
||||||
|
|
||||||
/* Are both filesystem objects related to the same MMC drive */
|
/* Are both filesystem objects related to the same MMC drive */
|
||||||
if (conv_ret2 <= 0)
|
if (conv_ret2 <= 0)
|
||||||
@ -2644,7 +2750,8 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
pthread_t tid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2656,7 +2763,8 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (drive_array[i].thread_pid_valid &&
|
if (drive_array[i].thread_pid_valid &&
|
||||||
drive_array[i].thread_pid == pid) {
|
drive_array[i].thread_pid == pid &&
|
||||||
|
pthread_equal(drive_array[i].thread_tid, tid)) {
|
||||||
*d = &(drive_array[i]);
|
*d = &(drive_array[i]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __DRIVE
|
#ifndef __DRIVE
|
||||||
#define __DRIVE
|
#define __DRIVE
|
||||||
|
|
||||||
@ -121,8 +127,9 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
|
|||||||
int burn_drive__fd_from_special_adr(char *adr);
|
int burn_drive__fd_from_special_adr(char *adr);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70929 : Find the drive which is being worked on by pid */
|
/* ts A70929 : Find the drive which is being worked on by pid , tid */
|
||||||
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,
|
||||||
|
pthread_t tid);
|
||||||
|
|
||||||
|
|
||||||
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
||||||
@ -135,4 +142,12 @@ char *burn_drive_whitelist_item(int idx, int flag);
|
|||||||
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00226 : Outsourced backend of burn_abort()
|
||||||
|
@param elapsed to be subtracted from start time
|
||||||
|
@param flag bit0= do not shutdown the library
|
||||||
|
*/
|
||||||
|
int burn_abort_5(int patience,
|
||||||
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
|
void *handle, int elapsed, int flag);
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
|
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c
|
/* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c
|
||||||
|
|
||||||
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
This code module implements the production of RSPC parity bytes (P- and Q-
|
This code module implements the production of RSPC parity bytes (P- and Q-
|
||||||
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
|
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
|
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
|
||||||
|
|
||||||
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
This code module implements the computations prescribed in ECMA-130 Annex A
|
This code module implements the computations prescribed in ECMA-130 Annex A
|
||||||
and B. For explanations of the underlying mathematics see ecma130ab.c .
|
and B. For explanations of the underlying mathematics see ecma130ab.c .
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -83,7 +93,9 @@ static off_t file_size(struct burn_source *source)
|
|||||||
|
|
||||||
if (fs->fixed_size > 0)
|
if (fs->fixed_size > 0)
|
||||||
return fs->fixed_size;
|
return fs->fixed_size;
|
||||||
if (fstat(fs->datafd, &buf) == -1)
|
if (fstat(fs->datafd, &buf) != 0)
|
||||||
|
return (off_t) 0;
|
||||||
|
if ((buf.st_mode & S_IFMT) != S_IFREG)
|
||||||
return (off_t) 0;
|
return (off_t) 0;
|
||||||
return (off_t) buf.st_size;
|
return (off_t) buf.st_size;
|
||||||
}
|
}
|
||||||
@ -391,9 +403,13 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
else
|
else
|
||||||
ret = fs->inp->read_xt( fs->inp,
|
ret = fs->inp->read_xt( fs->inp,
|
||||||
(unsigned char *) bufpt, fs->inp_read_size);
|
(unsigned char *) bufpt, fs->inp_read_size);
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
|
|
||||||
|
/* >>> ??? ts B00326 */
|
||||||
|
/* >>> report EOF of fifo input and fs->in_counter */;
|
||||||
|
|
||||||
break; /* EOF */
|
break; /* EOF */
|
||||||
else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Read error on fifo input", errno, 0);
|
"Read error on fifo input", errno, 0);
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__FILE_H
|
#ifndef BURN__FILE_H
|
||||||
#define BURN__FILE_H
|
#define BURN__FILE_H
|
||||||
|
|
||||||
|
164
libburn/init.c
164
libburn/init.c
@ -1,5 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
@ -9,6 +19,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
/* ts A70928 : init.h is for others, not for init .c
|
/* ts A70928 : init.h is for others, not for init .c
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
@ -32,14 +43,16 @@ struct libdax_msgs *libdax_messenger= NULL;
|
|||||||
|
|
||||||
int burn_running = 0;
|
int burn_running = 0;
|
||||||
|
|
||||||
/* ts A60813 : Linux: wether to use O_EXCL on open() of device files */
|
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
|
||||||
|
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
|
||||||
|
*/
|
||||||
int burn_sg_open_o_excl = 1;
|
int burn_sg_open_o_excl = 1;
|
||||||
|
|
||||||
/* ts A70403 : Linux: wether to use fcntl(,F_SETLK,)
|
/* ts A70403 : GNU/Linux: wether to use fcntl(,F_SETLK,)
|
||||||
after open() of device files */
|
after open() of device files */
|
||||||
int burn_sg_fcntl_f_setlk = 1;
|
int burn_sg_fcntl_f_setlk = 1;
|
||||||
|
|
||||||
/* ts A70314 : Linux: what device family to use :
|
/* ts A70314 : GNU/Linux: what device family to use :
|
||||||
0= default family
|
0= default family
|
||||||
1= sr
|
1= sr
|
||||||
2= scd
|
2= scd
|
||||||
@ -59,6 +72,12 @@ int burn_sg_open_o_nonblock = 1;
|
|||||||
to unconditional abort of the process */
|
to unconditional abort of the process */
|
||||||
int burn_sg_open_abort_busy = 0;
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* The message returned from sg_id_string() and/or sg_initialize()
|
||||||
|
*/
|
||||||
|
static char sg_initialize_msg[1024] = {""};
|
||||||
|
|
||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
|
|
||||||
#include "cleanup.h"
|
#include "cleanup.h"
|
||||||
@ -66,10 +85,13 @@ int burn_sg_open_abort_busy = 0;
|
|||||||
/* Parameters for builtin abort handler */
|
/* Parameters for builtin abort handler */
|
||||||
static char abort_message_prefix[81] = {"libburn : "};
|
static char abort_message_prefix[81] = {"libburn : "};
|
||||||
static pid_t abort_control_pid= 0;
|
static pid_t abort_control_pid= 0;
|
||||||
|
static pthread_t abort_control_thread;
|
||||||
volatile int burn_global_abort_level= 0;
|
volatile int burn_global_abort_level= 0;
|
||||||
int burn_global_abort_signum= 0;
|
int burn_global_abort_signum= 0;
|
||||||
void *burn_global_signal_handle = NULL;
|
void *burn_global_signal_handle = NULL;
|
||||||
burn_abort_handler_t burn_global_signal_handler = NULL;
|
burn_abort_handler_t burn_global_signal_handler = NULL;
|
||||||
|
int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */
|
||||||
|
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : wether implemented untested profiles are supported */
|
/* ts A70223 : wether implemented untested profiles are supported */
|
||||||
@ -110,6 +132,14 @@ int burn_initialize(void)
|
|||||||
ret = burn_msgs_initialize();
|
ret = burn_msgs_initialize();
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
ret = sg_initialize(sg_initialize_msg, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
|
0x00020175,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
sg_initialize_msg, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
burn_running = 1;
|
burn_running = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -137,10 +167,22 @@ void burn_finish(void)
|
|||||||
/* ts A60924 : ticket 74 */
|
/* ts A60924 : ticket 74 */
|
||||||
libdax_msgs_destroy(&libdax_messenger,0);
|
libdax_msgs_destroy(&libdax_messenger,0);
|
||||||
|
|
||||||
|
sg_shutdown(0);
|
||||||
|
|
||||||
burn_running = 0;
|
burn_running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91226 */
|
||||||
|
/** API function. See libburn.h */
|
||||||
|
char *burn_scsi_transport_id(int flag)
|
||||||
|
{
|
||||||
|
if (!burn_running)
|
||||||
|
sg_id_string(sg_initialize_msg, 0);
|
||||||
|
return sg_initialize_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A60813 */
|
/* ts A60813 */
|
||||||
/** API function. See libburn.h */
|
/** API function. See libburn.h */
|
||||||
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)
|
||||||
@ -295,6 +337,20 @@ int burn_sev_to_text(int severity_number, char **severity_name, int flag)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts B00224 */
|
||||||
|
char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
||||||
|
{
|
||||||
|
int i, l;
|
||||||
|
|
||||||
|
sprintf(text, "[%lu,", (unsigned long int) getpid());
|
||||||
|
l= strlen(text);
|
||||||
|
for(i= 0; i < sizeof(pthread_t) && 2 * i < 80 - l - 3; i++)
|
||||||
|
sprintf(text + l + 2 * i,
|
||||||
|
"%2.2X", ((unsigned char *) &tid)[i]);
|
||||||
|
|
||||||
|
sprintf(text + l + 2 * i, "]");
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
{
|
{
|
||||||
@ -303,15 +359,53 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
/*
|
/*
|
||||||
#define Libburn_signal_handler_verbouS 1
|
#define Libburn_signal_handler_verbouS 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
|
|
||||||
#ifdef Libburn_signal_handler_verbouS
|
#ifdef Libburn_signal_handler_verbouS
|
||||||
fprintf(stderr,
|
char text[80];
|
||||||
"libburn_ABORT: pid = %d , abort_control_pid = %d , sig= %d\n",
|
|
||||||
getpid(), abort_control_pid, signum);
|
fprintf(stderr, "libburn_ABORT: in = %s\n",
|
||||||
|
burn_util_thread_id(getpid(), pthread_self(), text));
|
||||||
|
fprintf(stderr, "libburn_ABORT: ctrl = %s\n",
|
||||||
|
burn_util_thread_id(abort_control_pid, abort_control_thread,
|
||||||
|
text));
|
||||||
|
if (burn_global_signal_handler == burn_builtin_abort_handler)
|
||||||
|
fprintf(stderr, "libburn_ABORT: signal action = %d\n",
|
||||||
|
burn_builtin_signal_action);
|
||||||
|
|
||||||
|
/* >>> find writing drives and report their tid
|
||||||
|
fprintf(stderr, "libburn_ABORT: wrt = %s\n",
|
||||||
|
burn_util_thread_id(0, burn_write_thread_id, text));
|
||||||
|
fprintf(stderr, "libburn_ABORT: sig= %d\n", signum);
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
burn_builtin_triggered_action = burn_builtin_signal_action;
|
||||||
|
burn_global_abort_level = -1;
|
||||||
|
|
||||||
|
if (burn_builtin_signal_action > 1) {
|
||||||
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
if (burn_builtin_signal_action == 4)
|
||||||
|
return -2;
|
||||||
|
fprintf(stderr,"%sABORT : Trying to shut down busy drives\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
burn_abort_5(0, burn_abort_pacifier, abort_message_prefix,
|
||||||
|
0, 1);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020177,
|
||||||
|
LIBDAX_MSGS_SEV_ABORT, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Urged drive worker threads to do emergency halt",
|
||||||
|
0, 0);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- old deprecated stuck-in-abort-handler loop ---- */
|
||||||
|
|
||||||
/* ts A70928:
|
/* ts A70928:
|
||||||
Must be quick. Allowed to coincide with other thread and to share
|
Must be quick. Allowed to coincide with other thread and to share
|
||||||
the increment with that one. It must not decrease, though, and
|
the increment with that one. It must not decrease, though, and
|
||||||
@ -324,7 +418,8 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
|
|
||||||
#ifdef Libburn_new_thread_signal_handleR
|
#ifdef Libburn_new_thread_signal_handleR
|
||||||
|
|
||||||
ret = burn_drive_find_by_thread_pid(&d, getpid());
|
ret = burn_drive_find_by_thread_pid(&d, getpid(),
|
||||||
|
pthread_self());
|
||||||
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
||||||
/* This is an active writer thread */
|
/* This is an active writer thread */
|
||||||
|
|
||||||
@ -364,13 +459,13 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
}
|
}
|
||||||
burn_global_abort_level = -1;
|
burn_global_abort_level = -1;
|
||||||
Cleanup_set_handlers(NULL, NULL, 2);
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
|
||||||
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%sABORT : Wait the normal burning time before any kill -9\n",
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
close(0); /* somehow stdin as input blocks abort until EOF */
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
|
||||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -380,28 +475,71 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61002 : API */
|
||||||
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)
|
||||||
{
|
{
|
||||||
if(handler == NULL && mode == 0) {
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_experimental: burn_set_signal_handling, handler==%lx mode=%d\n", (unsigned long) handler, mode);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(handler == NULL) {
|
||||||
handler = burn_builtin_abort_handler;
|
handler = burn_builtin_abort_handler;
|
||||||
/*
|
/*
|
||||||
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
if ((mode & ~4) == 0)
|
||||||
|
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
strcpy(abort_message_prefix, "libburn : ");
|
strcpy(abort_message_prefix, "libburn : ");
|
||||||
if(handle != NULL)
|
abort_message_prefix[0] = 0;
|
||||||
|
if(handle != NULL && handler == burn_builtin_abort_handler)
|
||||||
strncpy(abort_message_prefix, (char *) handle,
|
strncpy(abort_message_prefix, (char *) handle,
|
||||||
sizeof(abort_message_prefix)-1);
|
sizeof(abort_message_prefix)-1);
|
||||||
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||||
abort_control_pid = getpid();
|
abort_control_pid = getpid();
|
||||||
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
abort_control_thread = pthread_self();
|
||||||
|
burn_builtin_signal_action = (mode >> 4) & 15;
|
||||||
|
if((mode & 11) != 0)
|
||||||
|
burn_builtin_signal_action = 0;
|
||||||
|
if(burn_builtin_signal_action > 1)
|
||||||
|
burn_builtin_triggered_action = 0;
|
||||||
|
if(burn_builtin_signal_action == 0)
|
||||||
|
burn_builtin_signal_action = 1;
|
||||||
|
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler,
|
||||||
|
(mode & 15) | 4);
|
||||||
burn_global_signal_handle = handle;
|
burn_global_signal_handle = handle;
|
||||||
burn_global_signal_handler = handler;
|
burn_global_signal_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00304 : API */
|
||||||
|
int burn_is_aborting(int flag)
|
||||||
|
{
|
||||||
|
return burn_builtin_triggered_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00225 */
|
||||||
|
/* @return 0= no abort action 2 pending , 1= not control thread
|
||||||
|
*/
|
||||||
|
int burn_init_catch_on_abort(int flag)
|
||||||
|
{
|
||||||
|
if (burn_builtin_triggered_action != 2)
|
||||||
|
return 0;
|
||||||
|
if (abort_control_pid != getpid() ||
|
||||||
|
abort_control_thread != pthread_self())
|
||||||
|
return 1;
|
||||||
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : API */
|
/* ts A70223 : API */
|
||||||
void burn_allow_untested_profiles(int yes)
|
void burn_allow_untested_profiles(int yes)
|
||||||
{
|
{
|
||||||
|
@ -17,5 +17,15 @@ extern int burn_global_abort_signum;
|
|||||||
extern void *burn_global_signal_handle;
|
extern void *burn_global_signal_handle;
|
||||||
extern burn_abort_handler_t burn_global_signal_handler;
|
extern burn_abort_handler_t burn_global_signal_handler;
|
||||||
|
|
||||||
|
extern int burn_builtin_signal_action; /* burn_set_signal_handling() */
|
||||||
|
extern volatile int burn_builtin_triggered_action; /* burn_is_aborting() */
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00225 */
|
||||||
|
/* @return 0= no abort pending , 1= not control thread ,
|
||||||
|
-1= surprisingly burn_abort returned
|
||||||
|
*/
|
||||||
|
int burn_init_catch_on_abort(int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__INIT_H */
|
#endif /* BURN__INIT_H */
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
|
This is the official API definition of libburn.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef LIBBURN_H
|
#ifndef LIBBURN_H
|
||||||
#define LIBBURN_H
|
#define LIBBURN_H
|
||||||
|
|
||||||
@ -9,8 +18,10 @@ Applications must use 64 bit off_t. E.g. by defining
|
|||||||
#define _LARGEFILE_SOURCE
|
#define _LARGEFILE_SOURCE
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
or take special precautions to interface with the library by 64 bit integers
|
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
|
where this .h files prescribe off_t.
|
||||||
application from producing and processing ISO images of more than 2 GB size.
|
|
||||||
|
To prevent 64 bit file i/o in the library would keep the application from
|
||||||
|
processing tracks of more than 2 GB size.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -725,17 +736,22 @@ void burn_finish(void);
|
|||||||
|
|
||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
/** Abort any running drive operation and finally call burn_finish().
|
/** Abort any running drive operation and eventually call burn_finish().
|
||||||
You MUST calm down the busy drive if an aborting event occurs during a
|
|
||||||
|
You MUST shut down the busy drives if an aborting event occurs during a
|
||||||
burn run. For that you may call this function either from your own signal
|
burn run. For that you may call this function either from your own signal
|
||||||
handling code or indirectly by activating the builtin signal handling:
|
handling code or indirectly by activating the built-in signal handling:
|
||||||
burn_set_signal_handling("my_app_name : ", NULL, 0);
|
burn_set_signal_handling("my_app_name : ", NULL, 0);
|
||||||
Else you may eventually call burn_drive_cancel() on the active drive and
|
Else you may eventually call burn_drive_cancel() on the active drives and
|
||||||
wait for it to assume state BURN_DRIVE_IDLE.
|
wait for them to assume state BURN_DRIVE_IDLE.
|
||||||
@param patience Maximum number of seconds to wait for drives to finish
|
@param patience Maximum number of seconds to wait for drives to
|
||||||
|
finish.
|
||||||
|
@since 0.7.8 :
|
||||||
|
If this is -1, then only the cancel operations will
|
||||||
|
be performed and no burn_finish() will happen.
|
||||||
@param pacifier_func If not NULL: a function to produce appeasing messages.
|
@param pacifier_func If not NULL: a function to produce appeasing messages.
|
||||||
See burn_abort_pacifier() for an example.
|
See burn_abort_pacifier() for an example.
|
||||||
@param handle Opaque handle to be used with pacifier_func
|
@param handle Opaque handle to be used with pacifier_func
|
||||||
@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
|
||||||
@ -763,13 +779,10 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed);
|
|||||||
void burn_set_verbosity(int level);
|
void burn_set_verbosity(int level);
|
||||||
|
|
||||||
/* ts A91111 */
|
/* ts A91111 */
|
||||||
/** Enable resp. disable logging of SCSI commands (currently Linux only).
|
/** Enable resp. disable logging of SCSI commands (currently GNU/Linux only).
|
||||||
This call can be made at any time - even before burn_initialize().
|
This call can be made at any time - even before burn_initialize().
|
||||||
It is in effect for all active drives and currently not very thread
|
It is in effect for all active drives and currently not very thread
|
||||||
safe for multiple drives.
|
safe for multiple drives.
|
||||||
|
|
||||||
>>> ??? Shouldn't the file path with bit1 be adjustable ?
|
|
||||||
|
|
||||||
@param flag Bitfield for control purposes. The default is 0.
|
@param flag Bitfield for control purposes. The default is 0.
|
||||||
bit0= log to file /tmp/libburn_sg_command_log
|
bit0= log to file /tmp/libburn_sg_command_log
|
||||||
bit1= log to stderr
|
bit1= log to stderr
|
||||||
@ -783,12 +796,11 @@ void burn_set_scsi_logging(int flag);
|
|||||||
after burn_initialize() and before any bus scan. But not mandatory at all.
|
after burn_initialize() and before any bus scan. But not mandatory at all.
|
||||||
Parameter value 1 enables a feature, 0 disables.
|
Parameter value 1 enables a feature, 0 disables.
|
||||||
Default is (1,0,0). Have a good reason before you change it.
|
Default is (1,0,0). Have a good reason before you change it.
|
||||||
@param exclusive Linux only:
|
@param exclusive
|
||||||
0 = no attempt to make drive access exclusive.
|
0 = no attempt to make drive access exclusive.
|
||||||
1 = Try to open only devices which are not marked as busy
|
1 = Try to open only devices which are not marked as busy
|
||||||
and try to mark them busy if opened sucessfully. (O_EXCL)
|
and try to mark them busy if opened sucessfully. (O_EXCL
|
||||||
There are kernels which simply don't care about O_EXCL.
|
on GNU/Linux , flock(LOCK_EX) on FreeBSD.)
|
||||||
Some have it off, some have it on, some are switchable.
|
|
||||||
2 = in case of a SCSI device, also try to open exclusively
|
2 = in case of a SCSI device, also try to open exclusively
|
||||||
the matching /dev/sr, /dev/scd and /dev/st .
|
the matching /dev/sr, /dev/scd and /dev/st .
|
||||||
One may select a device SCSI file family by adding
|
One may select a device SCSI file family by adding
|
||||||
@ -797,8 +809,8 @@ void burn_set_scsi_logging(int flag);
|
|||||||
8 = /dev/scd%d
|
8 = /dev/scd%d
|
||||||
16 = /dev/sg%d
|
16 = /dev/sg%d
|
||||||
Do not use other values !
|
Do not use other values !
|
||||||
Add 32 to demand an exclusive lock by fcntl(,F_SETLK,)
|
Add 32 to demand on GNU/Linux an exclusive lock by
|
||||||
after open() has succeeded.
|
fcntl(,F_SETLK,) after open() has succeeded.
|
||||||
@param blocking Try to wait for drives which do not open immediately but
|
@param blocking Try to wait for drives which do not open immediately but
|
||||||
also do not return an error as well. (O_NONBLOCK)
|
also do not return an error as well. (O_NONBLOCK)
|
||||||
This might stall indefinitely with /dev/hdX hard disks.
|
This might stall indefinitely with /dev/hdX hard disks.
|
||||||
@ -868,12 +880,12 @@ void burn_allow_untested_profiles(int yes);
|
|||||||
If the path leads to an existing file of any type other than directory,
|
If the path leads to an existing file of any type other than directory,
|
||||||
then the result is a sequential write-only stdio-drive = drive role 3.
|
then the result is a sequential write-only stdio-drive = drive role 3.
|
||||||
|
|
||||||
The special address form "stdio:/dev/fd/<number>" is interpreted literally
|
The special address form "stdio:/dev/fd/{number}" is interpreted literally
|
||||||
as reference to open file descriptor <number>. This address form coincides
|
as reference to open file descriptor {number}. This address form coincides
|
||||||
with real files on some systems, but it is in fact hardcoded in libburn.
|
with real files on some systems, but it is in fact hardcoded in libburn.
|
||||||
Special address "stdio:-" means stdout = "stdio:/dev/fd/1".
|
Special address "stdio:-" means stdout = "stdio:/dev/fd/1".
|
||||||
The role of such a drive is determined by the file type obtained via
|
The role of such a drive is determined by the file type obtained via
|
||||||
fstat(<number>).
|
fstat({number}).
|
||||||
|
|
||||||
Roles 2 and 3 perform all their eventual data transfer activities on a file
|
Roles 2 and 3 perform all their eventual data transfer activities on a file
|
||||||
via standard i/o functions open(2), lseek(2), read(2), write(2), close(2).
|
via standard i/o functions open(2), lseek(2), read(2), write(2), close(2).
|
||||||
@ -1065,6 +1077,19 @@ int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no,
|
|||||||
*/
|
*/
|
||||||
int burn_drive_grab(struct burn_drive *drive, int load);
|
int burn_drive_grab(struct burn_drive *drive, int load);
|
||||||
|
|
||||||
|
/* ts B00114 */
|
||||||
|
/* Probe available CD write modes and block types. In earlier versions this
|
||||||
|
was done unconditionally on drive examination or aquiration. But it is
|
||||||
|
lengthy and obtrusive, up to spoiling burn runs on the examined drives.
|
||||||
|
So now this probing is omitted by default. All drives which announce to be
|
||||||
|
capable of CD or DVD writing, get blindly attributed the capability for
|
||||||
|
SAO and TAO. Applications which are interested in RAW modes or want to
|
||||||
|
rely on the traditional write mode information, may use this call.
|
||||||
|
@param drive_info drive object to be inquired
|
||||||
|
@return >0 indicates success, <=0 means failure
|
||||||
|
@since 0.7.6
|
||||||
|
*/
|
||||||
|
int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info);
|
||||||
|
|
||||||
/* ts A90824 */
|
/* ts A90824 */
|
||||||
/** Calm down or alert a drive. Some drives stay alert after reading for
|
/** Calm down or alert a drive. Some drives stay alert after reading for
|
||||||
@ -1073,7 +1098,7 @@ int burn_drive_grab(struct burn_drive *drive, int load);
|
|||||||
sense to calm down the drive if no read operation is expected for the
|
sense to calm down the drive if no read operation is expected for the
|
||||||
next few seconds. The drive will get alert automatically if operations
|
next few seconds. The drive will get alert automatically if operations
|
||||||
are required.
|
are required.
|
||||||
@param drive The drive to influence.
|
@param d The drive to influence.
|
||||||
@param flag Bitfield for control purposes
|
@param flag Bitfield for control purposes
|
||||||
bit0= become alert (else start snoozing)
|
bit0= become alert (else start snoozing)
|
||||||
This is not mandatory to allow further drive operations
|
This is not mandatory to allow further drive operations
|
||||||
@ -1085,7 +1110,6 @@ int burn_drive_snooze(struct burn_drive *d, int flag);
|
|||||||
|
|
||||||
/** Release a drive. This should not be done until the drive is no longer
|
/** Release a drive. This should not be done until the drive is no longer
|
||||||
busy (see burn_drive_get_status).
|
busy (see burn_drive_get_status).
|
||||||
Linux: The drive device file is not reserved afterwards. (O_EXCL, F_SETLK).
|
|
||||||
@param drive The drive to release.
|
@param drive The drive to release.
|
||||||
@param eject Nonzero to make the drive eject the disc in it.
|
@param eject Nonzero to make the drive eject the disc in it.
|
||||||
*/
|
*/
|
||||||
@ -1097,7 +1121,7 @@ void burn_drive_release(struct burn_drive *drive, int eject);
|
|||||||
eject button disabled. This physically locked drive state will last until
|
eject button disabled. This physically locked drive state will last until
|
||||||
the drive is grabbed again and released via burn_drive_release().
|
the drive is grabbed again and released via burn_drive_release().
|
||||||
Programs like eject, cdrecord, growisofs will break that ban too.
|
Programs like eject, cdrecord, growisofs will break that ban too.
|
||||||
@param drive The drive to release and leave locked.
|
@param d 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
|
@since 0.4.0
|
||||||
@ -1190,7 +1214,7 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
|||||||
/* ts A90909 */
|
/* ts A90909 */
|
||||||
/** Retrieve some media information which is mainly specific to CD. For other
|
/** Retrieve some media information which is mainly specific to CD. For other
|
||||||
media only the bits in reply parameter valid are supposed to be meaningful.
|
media only the bits in reply parameter valid are supposed to be meaningful.
|
||||||
@param drive The drive to query.
|
@param d The drive to query.
|
||||||
@param disc_type A string saying either "CD-DA or CD-ROM", or "CD-I",
|
@param disc_type A string saying either "CD-DA or CD-ROM", or "CD-I",
|
||||||
or ""CD-ROM XA", or "undefined".
|
or ""CD-ROM XA", or "undefined".
|
||||||
@param disc_id A 32 bit number read from the media. (Meaning unclear yet)
|
@param disc_id A 32 bit number read from the media. (Meaning unclear yet)
|
||||||
@ -1796,10 +1820,6 @@ struct burn_source *burn_file_source_new(const char *path,
|
|||||||
|
|
||||||
/* ts A91122 : An interface to open(O_DIRECT) or similar OS tricks. */
|
/* ts A91122 : An interface to open(O_DIRECT) or similar OS tricks. */
|
||||||
|
|
||||||
/* <<< temporary indicator until release 0.7.4
|
|
||||||
*/
|
|
||||||
#define Libburn_has_open_trac_srC 1
|
|
||||||
|
|
||||||
/** Opens a file with eventual acceleration preparations which may depend
|
/** Opens a file with eventual acceleration preparations which may depend
|
||||||
on the operating system and on compile time options of libburn.
|
on the operating system and on compile time options of libburn.
|
||||||
You may use this call instead of open(2) for opening file descriptors
|
You may use this call instead of open(2) for opening file descriptors
|
||||||
@ -1945,7 +1965,7 @@ int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
|
|||||||
@param full_counter The number of times the fifo was full.
|
@param full_counter The number of times the fifo was full.
|
||||||
@since 0.7.4
|
@since 0.7.4
|
||||||
*/
|
*/
|
||||||
void burn_fifo_get_statistics(struct burn_source *source,
|
void burn_fifo_get_statistics(struct burn_source *fifo,
|
||||||
int *total_min_fill, int *interval_min_fill,
|
int *total_min_fill, int *interval_min_fill,
|
||||||
int *put_counter, int *get_counter,
|
int *put_counter, int *get_counter,
|
||||||
int *empty_counter, int *full_counter);
|
int *empty_counter, int *full_counter);
|
||||||
@ -1959,8 +1979,7 @@ void burn_fifo_get_statistics(struct burn_source *source,
|
|||||||
burn_fifo_next_interval() was called.
|
burn_fifo_next_interval() was called.
|
||||||
@since 0.7.4
|
@since 0.7.4
|
||||||
*/
|
*/
|
||||||
void burn_fifo_next_interval(struct burn_source *source,
|
void burn_fifo_next_interval(struct burn_source *fifo, int *interval_min_fill);
|
||||||
int *interval_min_fill);
|
|
||||||
|
|
||||||
/* ts A80713 */
|
/* ts A80713 */
|
||||||
/** Obtain a preview of the first input data of a fifo which was created
|
/** Obtain a preview of the first input data of a fifo which was created
|
||||||
@ -1982,7 +2001,7 @@ void burn_fifo_next_interval(struct burn_source *source,
|
|||||||
@return <0 on severe error, 0 if not enough data, 1 if bufsize bytes read
|
@return <0 on severe error, 0 if not enough data, 1 if bufsize bytes read
|
||||||
@since 0.5.0
|
@since 0.5.0
|
||||||
*/
|
*/
|
||||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
int burn_fifo_peek_data(struct burn_source *fifo, char *buf, int bufsize,
|
||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
/* ts A91125 */
|
/* ts A91125 */
|
||||||
@ -1999,7 +2018,7 @@ int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
|||||||
1 if desired amount or fifo full
|
1 if desired amount or fifo full
|
||||||
@since 0.7.4
|
@since 0.7.4
|
||||||
*/
|
*/
|
||||||
int burn_fifo_fill(struct burn_source *source, int bufsize, int flag);
|
int burn_fifo_fill(struct burn_source *fifo, int fill, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70328 */
|
/* ts A70328 */
|
||||||
@ -2608,12 +2627,12 @@ 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 7
|
#define burn_header_version_minor 8
|
||||||
#define burn_header_version_micro 3
|
#define burn_header_version_micro 2
|
||||||
/** 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.
|
||||||
For the library compatibility check BURN_*_VERSION in configure.ac
|
For the library compatibility check, BURN_*_VERSION in configure.ac
|
||||||
are not decisive. Only the three numbers above do matter.
|
are not decisive. Only the three numbers above do matter.
|
||||||
*/
|
*/
|
||||||
/** Usage discussion:
|
/** Usage discussion:
|
||||||
@ -2659,6 +2678,15 @@ These two advises are mutually exclusive.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ts A91226 */
|
||||||
|
/** Obtain the id string of the SCSI transport interface.
|
||||||
|
This interface may be a system specific adapter module of libburn or
|
||||||
|
an adapter to a supporting library like libcdio.
|
||||||
|
@flag Bitfield for control puposes, submit 0 for now
|
||||||
|
@return A pointer to the id string. Do not alter the string content.
|
||||||
|
@since 0.7.6
|
||||||
|
*/
|
||||||
|
char *burn_scsi_transport_id(int flag);
|
||||||
|
|
||||||
/* ts A60924 : ticket 74 */
|
/* ts A60924 : ticket 74 */
|
||||||
/** Control queueing and stderr printing of messages from libburn.
|
/** Control queueing and stderr printing of messages from libburn.
|
||||||
@ -2761,30 +2789,82 @@ int burn_set_messenger(void *messenger);
|
|||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
/* @since 0.2.6 */
|
/* @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_signal_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.
|
||||||
*/
|
*/
|
||||||
typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
|
typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
|
||||||
|
|
||||||
/** Control builtin signal handling. See also burn_abort().
|
/** Control built-in signal handling. Either by setting an own handler or
|
||||||
|
by activating the built-in signal handler.
|
||||||
|
|
||||||
|
A function parameter handle of NULL activates the built-in abort handler.
|
||||||
|
Depending on mode it may cancel all drive operations, wait for all drives
|
||||||
|
to become idle, exit(1). It may also prepare function
|
||||||
|
burn_drive_get_status() for waiting and performing exit(1).
|
||||||
|
If parameter handle may be NULL or a text that shall be used as prefix for
|
||||||
|
pacifier messages of burn_abort_pacifier(). Other than with an application
|
||||||
|
provided handler, the prefix char array does not have to be kept existing
|
||||||
|
until the eventual signal event.
|
||||||
|
Before version 0.7.8 only action 0 was available. I.e. the built-in handler
|
||||||
|
waited for the drives to become idle and then performed exit(1) directly.
|
||||||
|
But during burn_disc_write() onto real CD or DVD, FreeBSD 8.0 pauses the
|
||||||
|
other threads until the signal handler returns.
|
||||||
|
The new actions try to avoid this deadlock. It is advised to use action 3
|
||||||
|
at least during burn_disc_write(), burn_disc_rease(), burn_disc_format():
|
||||||
|
burn_set_signal_handling(text, NULL, 0x30);
|
||||||
|
and to call burn_is_aborting(0) when the drive is BURN_DRIVE_IDLE.
|
||||||
|
If burn_is_aborting(0) returns 1, then call burn_abort() and exit(1).
|
||||||
|
|
||||||
@param handle Opaque handle eventually pointing to an application
|
@param handle Opaque handle eventually pointing to an application
|
||||||
provided memory object
|
provided memory object
|
||||||
@param handler A function to be called on signals. It will get handle as
|
@param handler A function to be called on signals. It will get handle as
|
||||||
argument. It should finally call burn_abort(). See there.
|
argument. flag will be 0.
|
||||||
@param mode : 0 call handler(handle, signum, 0) on nearly all signals
|
It should finally call burn_abort(). See there.
|
||||||
1 enable system default reaction on all signals
|
@param mode : bit0 - bit3:
|
||||||
2 try to ignore nearly all signals
|
Receiving signals:
|
||||||
10 like mode 2 but handle SIGABRT like with mode 0
|
0 Call handler(handle, signum, 0) on nearly all signals
|
||||||
Arguments (text, NULL, 0) activate the builtin abort handler. It will
|
1 Enable system default reaction on all signals
|
||||||
eventually call burn_abort() and then perform exit(1). If text is not NULL
|
2 Try to ignore nearly all signals
|
||||||
then it is used as prefix for pacifier messages of burn_abort_pacifier().
|
10 like mode 2 but handle SIGABRT like with mode 0
|
||||||
|
bit4 - bit7: With handler == NULL :
|
||||||
|
Action of built-in handler. "control thread" is the one
|
||||||
|
which called burn_set_signal_handling().
|
||||||
|
All actions activate receive mode 2 to ignore further
|
||||||
|
signals.
|
||||||
|
0 Same as 1 (for pre-0.7.8 backward compatibility)
|
||||||
|
@since 0.7.8
|
||||||
|
1 Catch the control thread in abort handler, call
|
||||||
|
burn_abort(>0) and finally exit(1).
|
||||||
|
Does not always work with FreeBSD.
|
||||||
|
2 Call burn_abort(-1) and return from handler. When the
|
||||||
|
control thread calls burn_drive_get_status(), then do
|
||||||
|
burn_abort(>0) instead, and finally exit(1).
|
||||||
|
Does not always work with FreeBSD.
|
||||||
|
3 Call burn_abort(-1), return from handler. It is duty of
|
||||||
|
the application to detect a pending abort condition
|
||||||
|
by calling burn_is_aborting() and to wait for all
|
||||||
|
drives to become idle. E.g. by calling burn_abort(>0).
|
||||||
|
4 Like 3, but without calling burn_abort(-1). Only the
|
||||||
|
indicator of burn_is_aborting() gets set.
|
||||||
@since 0.2.6
|
@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);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00304 */
|
||||||
|
/* Inquire whether the built-in abort handler was triggered by a signal.
|
||||||
|
This has to be done to detect pending abort handling if signal handling
|
||||||
|
was set to the built-in handler and action was set to 2 or 3.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 0 = no abort was triggered
|
||||||
|
>0 = action that was triggered (action 0 is reported as 1)
|
||||||
|
@since 0.7.8
|
||||||
|
*/
|
||||||
|
int burn_is_aborting(int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70811 */
|
/* ts A70811 */
|
||||||
/** Write data in random access mode.
|
/** Write data in random access mode.
|
||||||
The drive must be grabbed successfully before calling this function which
|
The drive must be grabbed successfully before calling this function which
|
||||||
@ -2928,16 +3008,8 @@ BURN_END_DECLS
|
|||||||
For other modes resp. real probing one has to call
|
For other modes resp. real probing one has to call
|
||||||
burn_drive_probe_cd_write_modes().
|
burn_drive_probe_cd_write_modes().
|
||||||
|
|
||||||
# define Libburn_pioneer_dvr_216d_dummy_probe_wM 1
|
|
||||||
*/
|
*/
|
||||||
#ifdef Libburn_pioneer_dvr_216d_dummy_probe_wM
|
#define Libburn_dummy_probe_write_modeS 1
|
||||||
|
|
||||||
/* Probe available CD write modes and block types.
|
|
||||||
@param drive_info drive object to be inquired
|
|
||||||
*/
|
|
||||||
int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info)
|
|
||||||
|
|
||||||
#endif /* Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBBURN_H*/
|
#endif /*LIBBURN_H*/
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
|
||||||
/* libdax_audioxtr
|
/* libdax_audioxtr
|
||||||
Audio track data extraction facility of libdax and libburn.
|
Audio track data extraction facility of libdax and libburn.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* libdax_audioxtr
|
/* libdax_audioxtr
|
||||||
Audio track data extraction facility of libdax and libburn.
|
Audio track data extraction facility of libdax and libburn.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006 - 2009 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -12,6 +16,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
/* Only this single source module is entitled to do this */
|
/* Only this single source module is entitled to do this */
|
||||||
#define LIBDAX_MSGS_H_INTERNAL 1
|
#define LIBDAX_MSGS_H_INTERNAL 1
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006-2009 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2010 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -434,6 +434,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
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
|
0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive
|
||||||
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
||||||
|
0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration
|
||||||
|
0x0002000d (FAILURE,HIGH) = Cannot enumerate next device
|
||||||
|
|
||||||
General library operations:
|
General library operations:
|
||||||
|
|
||||||
@ -552,6 +554,10 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
||||||
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
||||||
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
||||||
|
0x00020175 (FATAL,HIGH) = Supporting library is too old
|
||||||
|
0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer
|
||||||
|
0x00020177 (ABORT,HIGH) = Urged drive worker threads to do emergency halt
|
||||||
|
0x00020178 (DEBUG,HIGH) = Write thread ended
|
||||||
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ts A61009 */
|
/* ts A61009 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
@ -419,6 +429,10 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
|||||||
if (mmc_function_spy(d, "mmc_get_nwa") <= 0)
|
if (mmc_function_spy(d, "mmc_get_nwa") <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* ts B00327 : Avoid to inquire unsuitable media states */
|
||||||
|
if (d->status != BURN_DISC_BLANK && d->status != BURN_DISC_APPENDABLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ret = mmc_read_track_info(d, trackno, &buf, alloc_len);
|
ret = mmc_read_track_info(d, trackno, &buf, alloc_len);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1390,6 +1404,11 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]);
|
fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef Libburn_allow_first_hiddeN
|
||||||
|
/* ts B00430 : this causes problems because the track has
|
||||||
|
no entry. One would have to coordinate this
|
||||||
|
with other parts of libburn.
|
||||||
|
*/
|
||||||
if (tdata[3] == 1) {
|
if (tdata[3] == 1) {
|
||||||
if (burn_msf_to_lba(tdata[8], tdata[9], tdata[10])) {
|
if (burn_msf_to_lba(tdata[8], tdata[9], tdata[10])) {
|
||||||
d->disc->session[0]->hidefirst = 1;
|
d->disc->session[0]->hidefirst = 1;
|
||||||
@ -1398,9 +1417,10 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
session[tdata[0] - 1],
|
session[tdata[0] - 1],
|
||||||
track, BURN_POS_END);
|
track, BURN_POS_END);
|
||||||
burn_track_free(track);
|
burn_track_free(track);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* Libburn_allow_first_hiddeN */
|
||||||
|
|
||||||
if (tdata[0] <= 0 || tdata[0] > d->disc->sessions)
|
if (tdata[0] <= 0 || tdata[0] > d->disc->sessions)
|
||||||
tdata[0] = d->disc->sessions;
|
tdata[0] = d->disc->sessions;
|
||||||
if (tdata[3] < 100 && tdata[0] > 0) {
|
if (tdata[3] < 100 && tdata[0] > 0) {
|
||||||
@ -1958,8 +1978,13 @@ void mmc_read_atip(struct burn_drive *d)
|
|||||||
|
|
||||||
c.dir = FROM_DRIVE;
|
c.dir = FROM_DRIVE;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
burn_print(1, "atip shit for you\n");
|
/* ts B00501 : now caring for error */
|
||||||
|
if (c.error) {
|
||||||
|
d->erasable= 0;
|
||||||
|
d->start_lba= 0;
|
||||||
|
d->end_lba= 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* ts A61021 */
|
/* ts A61021 */
|
||||||
data = c.page->data;
|
data = c.page->data;
|
||||||
@ -4078,7 +4103,7 @@ int mmc_read_disc_structure(struct burn_drive *d,
|
|||||||
desired payload bytes. The drive then returns 35
|
desired payload bytes. The drive then returns 35
|
||||||
bytes as requested and the media id is "RITEKF1".
|
bytes as requested and the media id is "RITEKF1".
|
||||||
Nevertheless this is not a generally usable gesture
|
Nevertheless this is not a generally usable gesture
|
||||||
because older Linux USB dislikes requests to fetch
|
because older GNU/Linux USB dislikes requests to fetch
|
||||||
more bytes than the drive will deliver.
|
more bytes than the drive will deliver.
|
||||||
|
|
||||||
# define Libburn_enforce_structure_code_0x0E 1
|
# define Libburn_enforce_structure_code_0x0E 1
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __MMC
|
#ifndef __MMC
|
||||||
#define __MMC
|
#define __MMC
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "null.h"
|
#include "null.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__OPTIONS_H
|
#ifndef BURN__OPTIONS_H
|
||||||
#define BURN__OPTIONS_H
|
#define BURN__OPTIONS_H
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Unknown POSIX like systems
|
Unknown POSIX like systems
|
||||||
with the dummy MMC transport adapter sg-dummy.c
|
with the dummy MMC transport adapter sg-dummy.c
|
||||||
|
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
FreeBSD with CAM
|
FreeBSD with CAM
|
||||||
|
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** List of all signals which shall be caught by signal handlers and trigger
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
@ -57,5 +57,8 @@ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
|
|||||||
To be initialized and used within sg-*.c .
|
To be initialized and used within sg-*.c .
|
||||||
*/
|
*/
|
||||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
struct cam_device* cam;
|
struct cam_device* cam; \
|
||||||
|
int lock_fd; \
|
||||||
|
int is_ahci; \
|
||||||
|
|
||||||
|
|
||||||
|
72
libburn/os-libcdio.h
Normal file
72
libburn/os-libcdio.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
/* os-libcdio.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
Unknown X/Open-like systems
|
||||||
|
with GNU libcdio MMC transport adapter sg-libcdio.c
|
||||||
|
|
||||||
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** 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 ! */
|
||||||
|
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
|
||||||
|
with buffer size 32 kB. So stream recording is allowed only with size 64k.
|
||||||
|
This makes it worth to have a special case for GNU/Linux buffer size here.
|
||||||
|
*/
|
||||||
|
#ifdef __linux
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
#else
|
||||||
|
/* (It might be risky to use 64k. FreeBSD is said to can only 32k.) */
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* To hold the position of the most recently delivered address from
|
||||||
|
device enumeration.
|
||||||
|
*/
|
||||||
|
struct burn_drive_enumerator_struct {
|
||||||
|
char **ppsz_cd_drives;
|
||||||
|
char **pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#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 \
|
||||||
|
void *p_cdio; /* actually a pointer to CdIo_t */ \
|
||||||
|
char libcdio_name[4096]; /* The drive path as used by libcdio */ \
|
||||||
|
|
@ -2,9 +2,10 @@
|
|||||||
/* os-linux.h
|
/* os-linux.h
|
||||||
Operating system specific libburn definitions and declarations. Included
|
Operating system specific libburn definitions and declarations. Included
|
||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg)
|
Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg)
|
||||||
|
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
68
libburn/os-solaris.h
Normal file
68
libburn/os-solaris.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
/* os-solaris.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
Solaris based systems, e.g. SunOS 5.11
|
||||||
|
with Solaris uscsi MMC transport adapter sg-solaris.c
|
||||||
|
|
||||||
|
Copyright (C) 2010 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
|
a graceful abort of libburn. (See man signal.h)
|
||||||
|
*/
|
||||||
|
/* 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, SIGURG, SIGWINCH
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT 5
|
||||||
|
|
||||||
|
|
||||||
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
/* Important : MUST be at least 32768 ! */
|
||||||
|
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
|
||||||
|
with buffer size 32 kB. So stream recording is allowed only with size 64k.
|
||||||
|
|
||||||
|
>>> ??? is 64 kB ok for Solaris uscsi ?
|
||||||
|
*/
|
||||||
|
#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 {
|
||||||
|
void *dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
#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 fd;
|
||||||
|
|
41
libburn/os.h
41
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) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BURN_OS_H_INCLUDED
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
@ -13,6 +13,23 @@
|
|||||||
Operating system case distinction
|
Operating system case distinction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_dummY
|
||||||
|
|
||||||
|
|
||||||
|
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
|
||||||
|
#include "os-dummy.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef Libburn_use_libcdiO
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------- X/Open with GNU libcdio ---------------------- */
|
||||||
|
#include "os-libcdio.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
|
||||||
@ -20,14 +37,30 @@
|
|||||||
#include "os-freebsd.h"
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD_kernel__
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------- FreeBSD with CAM under Debian ------------------- */
|
||||||
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
|
|
||||||
|
|
||||||
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
/* ------- Linux kernels 2.4 and 2.6 with GNU/Linux SCSI Generic (sg) ------ */
|
||||||
#include "os-linux.h"
|
#include "os-linux.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __sun
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Solaris (e.g. SunOS 5.11) with uscsi ------ */
|
||||||
|
#include "os-solaris.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
@ -35,8 +68,12 @@
|
|||||||
#include "os-dummy.h"
|
#include "os-dummy.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! __sun*/
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
|
#endif /* ! __FreeBSD__kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! BURN_OS_H_INCLUDED */
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* #include <m alloc.h> ts A61013 : not in Linux man 3 malloc */
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* #include <m alloc.h> ts A61013 : not in GNU/Linux man 3 malloc */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -94,7 +104,13 @@ drive, or only store a subset of the _opts structs in drives */
|
|||||||
fakesub[20] = 2;
|
fakesub[20] = 2;
|
||||||
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
||||||
d->toc->toc_entry[0].adr;
|
d->toc->toc_entry[0].adr;
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(fakesub + 12, 10);
|
crc = crc_ccitt(fakesub + 12, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
fakesub[22] = crc >> 8;
|
fakesub[22] = crc >> 8;
|
||||||
fakesub[23] = crc & 0xFF;
|
fakesub[23] = crc & 0xFF;
|
||||||
write(o->subfd, fakesub, 96);
|
write(o->subfd, fakesub, 96);
|
||||||
@ -241,6 +257,8 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
crc = (*(sub + 22) << 8) + *(sub + 23);
|
crc = (*(sub + 22) << 8) + *(sub + 23);
|
||||||
|
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
if (crc != crc_ccitt(sub + 12, 10)) {
|
if (crc != crc_ccitt(sub + 12, 10)) {
|
||||||
burn_print(1, "sending error on %s %s\n",
|
burn_print(1, "sending error on %s %s\n",
|
||||||
d->idata->vendor, d->idata->product);
|
d->idata->vendor, d->idata->product);
|
||||||
@ -249,6 +267,8 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
|||||||
*/
|
*/
|
||||||
burn_print(1, "crc mismatch in Q\n");
|
burn_print(1, "crc mismatch in Q\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* else process_q(d, sub + 12); */
|
/* else process_q(d, sub + 12); */
|
||||||
/*
|
/*
|
||||||
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
||||||
|
@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
/* scsi block commands */
|
/* scsi block commands */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -74,14 +83,17 @@ void sbc_eject(struct burn_drive *d)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
/* c.opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
|
||||||
c.page = NULL;
|
c.page = NULL;
|
||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
|
/* ts A70918 : Wait long. A late eject could surprise or hurt user.
|
||||||
|
ts B00109 : Asynchronous eject revoked, as one cannot reliably
|
||||||
|
distinguish out from unready.
|
||||||
if (c.error)
|
if (c.error)
|
||||||
return;
|
return;
|
||||||
/* ts A70918 : Wait long. A late eject could surprise or hurt user. */
|
|
||||||
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SBC
|
#ifndef __SBC
|
||||||
#define __SBC
|
#define __SBC
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
@ -25,7 +34,7 @@ extern struct libdax_msgs *libdax_messenger;
|
|||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -96,7 +105,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
|||||||
int valid, shortage, curr, i, tr;
|
int valid, shortage, curr, i, tr;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
static int tee_fd= -1;
|
static int tee_fd= -1;
|
||||||
if(tee_fd==-1)
|
if(tee_fd==-1)
|
||||||
tee_fd= open("/tmp/libburn_sg_readin",
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
@ -142,7 +151,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
|||||||
track->sourcecount += valid;
|
track->sourcecount += valid;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
if(tee_fd!=-1 && valid>0) {
|
if(tee_fd!=-1 && valid>0) {
|
||||||
write(tee_fd, data + curr, valid);
|
write(tee_fd, data + curr, valid);
|
||||||
}
|
}
|
||||||
@ -405,7 +414,13 @@ a2 - lout ctrl
|
|||||||
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
||||||
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
||||||
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xFF;
|
q[11] = crc & 0xFF;
|
||||||
d->toc_temp++;
|
d->toc_temp++;
|
||||||
@ -502,7 +517,13 @@ static void subcode_lout(struct burn_write_opts *o, unsigned char control,
|
|||||||
q[7] = dec_to_bcd(min);
|
q[7] = dec_to_bcd(min);
|
||||||
q[8] = dec_to_bcd(sec);
|
q[8] = dec_to_bcd(sec);
|
||||||
q[9] = dec_to_bcd(frame);
|
q[9] = dec_to_bcd(frame);
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xFF;
|
q[11] = crc & 0xFF;
|
||||||
}
|
}
|
||||||
@ -622,7 +643,13 @@ void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
|
|||||||
}
|
}
|
||||||
q[0] = (control << 4) + qmode;
|
q[0] = (control << 4) + qmode;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xff;
|
q[11] = crc & 0xff;
|
||||||
}
|
}
|
||||||
@ -654,7 +681,7 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
|||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
data = get_sector(o, t, t->mode);
|
data = get_sector(o, t, t->mode);
|
||||||
if (!data)
|
if (data == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
if (convert_data(o, t, t->mode, data) <= 0)
|
if (convert_data(o, t, t->mode, data) <= 0)
|
||||||
@ -768,7 +795,13 @@ int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
|||||||
out[15] = modebyte;
|
out[15] = modebyte;
|
||||||
}
|
}
|
||||||
if (mode & BURN_MODE1) {
|
if (mode & BURN_MODE1) {
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_32(out, 2064);
|
crc = crc_32(out, 2064);
|
||||||
|
#endif
|
||||||
|
|
||||||
out[2064] = crc & 0xFF;
|
out[2064] = crc & 0xFF;
|
||||||
crc >>= 8;
|
crc >>= 8;
|
||||||
out[2065] = crc & 0xFF;
|
out[2065] = crc & 0xFF;
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SECTOR
|
#ifndef __SECTOR
|
||||||
#define __SECTOR
|
#define __SECTOR
|
||||||
|
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
@ -7,8 +17,8 @@ the transport level aspects of SCSI control and command i/o.
|
|||||||
|
|
||||||
Present implementation: default dummy which enables libburn only to work
|
Present implementation: default dummy which enables libburn only to work
|
||||||
with stdio: pseudo drive addresses.
|
with stdio: pseudo drive addresses.
|
||||||
For real implementations see sg-linux.c or sg-freebsd.c
|
For real implementations see sg-linux.c, sg-freebsd.c,
|
||||||
|
sg-libcdio.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +49,59 @@ Present implementation: default dummy which enables libburn only to work
|
|||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal X/Open adapter sg-dummy");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
The enumeration has to cover all available and accessible drives. It is
|
The enumeration has to cover all available and accessible drives. It is
|
||||||
allowed to return addresses of drives which are not available but under
|
allowed to return addresses of drives which are not available but under
|
||||||
@ -153,6 +216,23 @@ int sg_is_enumerable_adr(char *adr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
seeked, read, and possibly written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (S_ISBLK(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
exist yet, then the directory will be inquired.
|
exist yet, then the directory will be inquired.
|
||||||
@ -215,7 +295,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
|
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
|
|
||||||
#else /* Libburn_os_has_statvfS */
|
#else /* Libburn_os_has_statvfS */
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
@ -29,12 +35,28 @@ and of deriving the following system specific files from existing examples:
|
|||||||
Said sg-*.c operations are defined by a public function interface, which has
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
to be implemented in a way that provides libburn with the desired services:
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
|
sg_id_string() returns an id string of the SCSI transport adapter.
|
||||||
|
It may be called before initialization but then may
|
||||||
|
return only a preliminary id.
|
||||||
|
|
||||||
|
sg_initialize() performs global initialization of the SCSI transport
|
||||||
|
adapter and eventually needed operating system
|
||||||
|
facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
|
||||||
|
sg_shutdown() performs global finalizations and releases golbally
|
||||||
|
aquired resources.
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
|
||||||
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
|
on destruction. Releases resources which were aquired
|
||||||
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
sg_drive_is_open() tells wether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
@ -48,14 +70,35 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
|
|||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
|
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
||||||
|
that can be used in 2 kB granularity by lseek(2),
|
||||||
|
read(2), and possibly write(2) if not read-only.
|
||||||
|
E.g. a USB stick or a hard disk.
|
||||||
|
|
||||||
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
|
burn_os_open_track_src() opens a disk file in a way that allows best
|
||||||
|
throughput with file reading and/or SCSI write command
|
||||||
|
transmission.
|
||||||
|
|
||||||
|
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
||||||
|
descriptors issued by burn_os_open_track_src().
|
||||||
|
The buffer size may be rounded up for alignment
|
||||||
|
reasons.
|
||||||
|
|
||||||
|
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
||||||
|
|
||||||
|
|
||||||
Porting hints are marked by the text "PORTING:".
|
Porting hints are marked by the text "PORTING:".
|
||||||
Send feedback to libburn-hackers@pykix.org .
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------- OS dependent headers and definitions ------ */
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
@ -230,6 +273,61 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd-port");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
The enumeration has to cover all available and accessible drives. It is
|
The enumeration has to cover all available and accessible drives. It is
|
||||||
allowed to return addresses of drives which are not available but under
|
allowed to return addresses of drives which are not available but under
|
||||||
@ -299,7 +397,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
|
|||||||
break;
|
break;
|
||||||
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||||
result->periph_name, result->unit_number);
|
result->periph_name, result->unit_number);
|
||||||
if(adr_size <= strlen(buf)
|
if(adr_size <= strlen(buf))
|
||||||
return -1;
|
return -1;
|
||||||
strcpy(adr, buf);
|
strcpy(adr, buf);
|
||||||
|
|
||||||
@ -323,7 +421,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
|
|||||||
int scsi_enumerate_drives(void)
|
int scsi_enumerate_drives(void)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1;
|
int initialize = 1, ret;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -338,6 +436,7 @@ int scsi_enumerate_drives(void)
|
|||||||
idx.result->target_lun);
|
idx.result->target_lun);
|
||||||
}
|
}
|
||||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -360,11 +459,12 @@ int sg_drive_is_open(struct burn_drive * d)
|
|||||||
*/
|
*/
|
||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int count;
|
|
||||||
struct cam_device *cam;
|
struct cam_device *cam;
|
||||||
|
|
||||||
if(d->cam != NULL)
|
if(d->cam != NULL) {
|
||||||
return 0;
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
cam = cam_open_device(d->devname, O_RDWR);
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
if (cam == NULL) {
|
if (cam == NULL) {
|
||||||
@ -515,7 +615,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
int *target_no, int *lun_no)
|
int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1;
|
int initialize = 1, ret;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
struct periph_match_result* result;
|
struct periph_match_result* result;
|
||||||
|
|
||||||
@ -524,7 +624,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
initialize = 0;
|
initialize = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
break;
|
break;
|
||||||
if (strcmp(adr, buf) != 0)
|
if (strcmp(path, buf) != 0)
|
||||||
continue;
|
continue;
|
||||||
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
*bus_no = result->path_id;
|
*bus_no = result->path_id;
|
||||||
@ -546,7 +646,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
int sg_is_enumerable_adr(char* adr)
|
int sg_is_enumerable_adr(char* adr)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1;
|
int initialize = 1, ret;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -564,6 +664,47 @@ int sg_is_enumerable_adr(char* adr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00115 */
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
seeked, written, and read with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
char *spt;
|
||||||
|
int i, e;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (!S_ISCHR(stbuf.st_mode))
|
||||||
|
return 0;
|
||||||
|
spt = strrchr(path, '/');
|
||||||
|
if (spt == NULL)
|
||||||
|
spt = path;
|
||||||
|
else
|
||||||
|
spt++;
|
||||||
|
e = strlen(spt);
|
||||||
|
for (i = strlen(spt) - 1; i > 0; i--)
|
||||||
|
if (spt[i] >= '0' && spt[i] <= '9')
|
||||||
|
e = i;
|
||||||
|
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
@ -623,7 +764,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -7,6 +16,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/file.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
@ -16,10 +26,24 @@
|
|||||||
|
|
||||||
#include <err.h> /* XXX */
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
/* ts B00121 */
|
||||||
|
#include <sys/disk.h> /* DIOCGMEDIASIZE */
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00326 : For use of CAM_PASS_ERR_RECOVER with ahci */
|
||||||
|
#define Libburn_for_freebsd_ahcI yes
|
||||||
|
|
||||||
|
/* ts B00327 : for debugging of cam_send_cdb() failures
|
||||||
|
# define Libburn_ahci_verbouS yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ts B00327 : Apply CAM_PASS_ERR_RECOVER to drives even if not ahci
|
||||||
|
# define libburn_ahci_style_for_alL yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
@ -54,6 +78,79 @@ int burn_drive_is_banned(char *device_address);
|
|||||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00113
|
||||||
|
Whether to log SCSI commands:
|
||||||
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
|
bit1= log to stderr
|
||||||
|
bit2= flush every line
|
||||||
|
*/
|
||||||
|
extern int burn_sg_log_scsi;
|
||||||
|
|
||||||
|
/* ts B00114 */
|
||||||
|
/* Storage object is in libburn/init.c
|
||||||
|
whether to strive for exclusive access to the drive
|
||||||
|
*/
|
||||||
|
extern int burn_sg_open_o_excl;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
||||||
sg_give_next_adr() */
|
sg_give_next_adr() */
|
||||||
/* Some helper functions for scsi_give_next_adr() */
|
/* Some helper functions for scsi_give_next_adr() */
|
||||||
@ -145,7 +242,7 @@ static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index object state and the next enumerated drive address.
|
||||||
@param idx An opaque handle. Make no own theories about it.
|
@param idx An opaque handle. Make no own theories about it.
|
||||||
@param adr Takes the reply
|
@param adr Takes the reply
|
||||||
@param adr_size Gives maximum size of reply including final 0
|
@param adr_size Gives maximum size of reply including final 0
|
||||||
@ -199,9 +296,15 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
|||||||
struct periph_match_result* result;
|
struct periph_match_result* result;
|
||||||
|
|
||||||
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
||||||
|
/* ts B00112 : we really want only "cd" devices.
|
||||||
|
|
||||||
if (idx->skip_device ||
|
if (idx->skip_device ||
|
||||||
strcmp(result->periph_name, "pass") == 0)
|
strcmp(result->periph_name, "pass") == 0)
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
|
if (idx->skip_device ||
|
||||||
|
strcmp(result->periph_name, "cd") != 0)
|
||||||
|
break;
|
||||||
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
||||||
result->periph_name, result->unit_number);
|
result->periph_name, result->unit_number);
|
||||||
if(ret >= adr_size)
|
if(ret >= adr_size)
|
||||||
@ -212,7 +315,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
|||||||
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* printf(stderr, "unknown match type\n"); */
|
/* fprintf(stderr, "unknown match type\n"); */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
(idx->i)++;
|
(idx->i)++;
|
||||||
@ -287,6 +390,10 @@ int sg_close_drive(struct burn_drive * d)
|
|||||||
cam_close_device(d->cam);
|
cam_close_device(d->cam);
|
||||||
d->cam = NULL;
|
d->cam = NULL;
|
||||||
}
|
}
|
||||||
|
if (d->lock_fd > 0) {
|
||||||
|
close(d->lock_fd);
|
||||||
|
d->lock_fd = -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +447,10 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
out.lun = lun_no;
|
out.lun = lun_no;
|
||||||
|
|
||||||
out.devname = burn_strdup(fname);
|
out.devname = burn_strdup(fname);
|
||||||
|
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
|
out.lock_fd = -1;
|
||||||
|
out.is_ahci = 0;
|
||||||
|
|
||||||
out.start_lba= -2000000000;
|
out.start_lba= -2000000000;
|
||||||
out.end_lba= -2000000000;
|
out.end_lba= -2000000000;
|
||||||
@ -432,6 +542,9 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* Operating system adapter is CAM */
|
/* Operating system adapter is CAM */
|
||||||
/* Adapter specific handles and data */
|
/* Adapter specific handles and data */
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
|
out.lock_fd = -1;
|
||||||
|
out.is_ahci = 0;
|
||||||
|
|
||||||
/* Adapter specific functions */
|
/* Adapter specific functions */
|
||||||
out.grab = sg_grab;
|
out.grab = sg_grab;
|
||||||
out.release = sg_release;
|
out.release = sg_release;
|
||||||
@ -444,15 +557,145 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
||||||
|
|
||||||
/* ts A61021: do not believe this:
|
|
||||||
we use the sg reference count to decide whether we can use the
|
/* Lock the inode associated to dev_fd and the inode associated to devname.
|
||||||
drive or not.
|
Return OS errno, number of pass device of dev_fd, locked fd to devname,
|
||||||
if refcount is not one, drive is open somewhere else.
|
error message.
|
||||||
|
A return value of > 0 means success, <= 0 means failure.
|
||||||
*/
|
*/
|
||||||
|
static int freebsd_dev_lock(int dev_fd, char *devname,
|
||||||
|
int *os_errno, int *pass_dev_no, int *lock_fd, char msg[4096],
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int lock_denied = 0, fd_stbuf_valid, name_stbuf_valid, i, pass_l = 100;
|
||||||
|
int max_retry = 3, tries = 0;
|
||||||
|
struct stat fd_stbuf, name_stbuf;
|
||||||
|
char pass_name[16], *lock_name;
|
||||||
|
|
||||||
|
*os_errno = 0;
|
||||||
|
*pass_dev_no = -1;
|
||||||
|
*lock_fd = -1;
|
||||||
|
msg[0] = 0;
|
||||||
|
|
||||||
|
fd_stbuf_valid = !fstat(dev_fd, &fd_stbuf);
|
||||||
|
|
||||||
|
/* Try to find name of pass device by inode number */
|
||||||
|
lock_name = (char *) "effective device";
|
||||||
|
if(fd_stbuf_valid) {
|
||||||
|
for (i = 0; i < pass_l; i++) {
|
||||||
|
sprintf(pass_name, "/dev/pass%d", i);
|
||||||
|
if (stat(pass_name, &name_stbuf) != -1)
|
||||||
|
if(fd_stbuf.st_ino == name_stbuf.st_ino &&
|
||||||
|
fd_stbuf.st_dev == name_stbuf.st_dev)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < pass_l) {
|
||||||
|
lock_name = pass_name;
|
||||||
|
*pass_dev_no = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name_stbuf_valid = !stat(devname, &name_stbuf);
|
||||||
|
for (tries= 0; tries <= max_retry; tries++) {
|
||||||
|
lock_denied = flock(dev_fd, LOCK_EX | LOCK_NB);
|
||||||
|
*os_errno = errno;
|
||||||
|
if (lock_denied) {
|
||||||
|
if (errno == EAGAIN && tries < max_retry) {
|
||||||
|
/* <<< debugging
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nlibcdio_DEBUG: EAGAIN pass, tries= %d\n",
|
||||||
|
tries);
|
||||||
|
*/
|
||||||
|
usleep(2000000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sprintf(msg,
|
||||||
|
"Device busy. flock(LOCK_EX) failed on %s of %s",
|
||||||
|
strlen(lock_name) > 2000 || *pass_dev_no < 0 ?
|
||||||
|
"pass device" : lock_name,
|
||||||
|
strlen(devname) > 2000 ? "drive" : devname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_DEBUG: flock obtained on %s of %s\n",
|
||||||
|
lock_name, devname);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Eventually lock the official device node too */
|
||||||
|
if (fd_stbuf_valid && name_stbuf_valid &&
|
||||||
|
(fd_stbuf.st_ino != name_stbuf.st_ino ||
|
||||||
|
fd_stbuf.st_dev != name_stbuf.st_dev)) {
|
||||||
|
|
||||||
|
*lock_fd = open(devname, O_RDONLY);
|
||||||
|
if (*lock_fd == 0) {
|
||||||
|
close(*lock_fd);
|
||||||
|
*lock_fd = -1;
|
||||||
|
} if (*lock_fd > 0) {
|
||||||
|
for (tries = 0; tries <= max_retry; tries++) {
|
||||||
|
lock_denied =
|
||||||
|
flock(*lock_fd, LOCK_EX | LOCK_NB);
|
||||||
|
if (lock_denied) {
|
||||||
|
if (errno == EAGAIN &&
|
||||||
|
tries < max_retry) {
|
||||||
|
/* <<< debugging
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nlibcdio_DEBUG: EAGAIN dev, tries= %d\n",
|
||||||
|
tries);
|
||||||
|
*/
|
||||||
|
|
||||||
|
usleep(2000000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
close(*lock_fd);
|
||||||
|
*lock_fd = -1;
|
||||||
|
sprintf(msg,
|
||||||
|
"Device busy. flock(LOCK_EX) failed on %s",
|
||||||
|
strlen(devname) > 4000 ? "drive" : devname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_DEBUG: flock obtained on %s\n",
|
||||||
|
devname);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_lock(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
int ret, os_errno, pass_dev_no = -1, flock_fd = -1;
|
||||||
|
char msg[4096];
|
||||||
|
|
||||||
|
ret = freebsd_dev_lock(d->cam->fd, d->devname,
|
||||||
|
&os_errno, &pass_dev_no, &flock_fd, msg, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020008,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, os_errno, 0);
|
||||||
|
sg_close_drive(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (d->lock_fd > 0)
|
||||||
|
close(d->lock_fd);
|
||||||
|
d->lock_fd = flock_fd;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int count;
|
|
||||||
struct cam_device *cam;
|
struct cam_device *cam;
|
||||||
|
char path_string[80];
|
||||||
|
|
||||||
if (mmc_function_spy(d, "sg_grab") <= 0)
|
if (mmc_function_spy(d, "sg_grab") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -464,22 +707,31 @@ int sg_grab(struct burn_drive *d)
|
|||||||
|
|
||||||
cam = cam_open_device(d->devname, O_RDWR);
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
if (cam == NULL) {
|
if (cam == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
0x00020003,
|
||||||
"Could not grab drive", 0/*os_errno*/, 0);
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not grab drive", errno, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* er = ioctl(fd, SG_GET_ACCESS_COUNT, &count);*/
|
d->cam = cam;
|
||||||
count = 1;
|
if (burn_sg_open_o_excl & 63)
|
||||||
if (1 == count) {
|
if (sg_lock(d, 0) <= 0)
|
||||||
d->cam = cam;
|
return 0;
|
||||||
fcntl(cam->fd, F_SETOWN, getpid());
|
fcntl(cam->fd, F_SETOWN, getpid());
|
||||||
d->released = 0;
|
|
||||||
return 1;
|
cam_path_string(d->cam, path_string, sizeof(path_string));
|
||||||
}
|
|
||||||
burn_print(1, "could not acquire drive - already open\n");
|
#ifdef Libburn_ahci_verbouS
|
||||||
sg_close_drive(d);
|
fprintf(stderr, "libburn_EXPERIMENTAL: CAM path = %s\n", path_string);
|
||||||
return 0;
|
#endif
|
||||||
|
|
||||||
|
if (strstr(path_string, ":ahcich") != NULL)
|
||||||
|
d->is_ahci = 1;
|
||||||
|
else
|
||||||
|
d->is_ahci = -1;
|
||||||
|
|
||||||
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -507,11 +759,12 @@ int sg_release(struct burn_drive *d)
|
|||||||
|
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0;
|
||||||
int err;
|
int cam_pass_err_recover = 0;
|
||||||
union ccb *ccb;
|
union ccb *ccb;
|
||||||
|
|
||||||
char buf[161];
|
char buf[161];
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
|
||||||
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
||||||
(void*)d->cam, d->released);
|
(void*)d->cam, d->released);
|
||||||
mmc_function_spy(NULL, buf);
|
mmc_function_spy(NULL, buf);
|
||||||
@ -520,6 +773,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
c->error = 0;
|
c->error = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (burn_sg_log_scsi & 1) {
|
||||||
|
if (fp == NULL) {
|
||||||
|
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||||
|
fprintf(fp,
|
||||||
|
"\n-----------------------------------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
|
|
||||||
@ -546,6 +808,23 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_for_freebsd_ahcI
|
||||||
|
/* ts B00325 : Advise by Alexander Motin */
|
||||||
|
/* Runs well on 8-STABLE (23 Mar 2003)
|
||||||
|
But on 8-RELEASE cam_send_ccb() returns non-zero with errno 6
|
||||||
|
on eject. Long lasting TEST UNIT READY cycles break with
|
||||||
|
errno 16.
|
||||||
|
*/
|
||||||
|
#ifdef Libburn_ahci_style_for_alL
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
if (d->is_ahci > 0) {
|
||||||
|
#endif
|
||||||
|
ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
|
||||||
|
cam_pass_err_recover = 1;
|
||||||
|
}
|
||||||
|
#endif /* Libburn_for_freebsd_ahcI */
|
||||||
|
|
||||||
ccb->csio.cdb_len = c->oplen;
|
ccb->csio.cdb_len = c->oplen;
|
||||||
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
||||||
|
|
||||||
@ -568,12 +847,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
/* touch page so we can use valgrind */
|
/* touch page so we can use valgrind */
|
||||||
memset(c->page->data, 0, BUFFER_SIZE);
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
} else {
|
} else {
|
||||||
/* ts A90430 */
|
|
||||||
/* a ssert(c->page->bytes > 0); */
|
|
||||||
if (c->page->bytes <= 0) {
|
|
||||||
c->error = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ccb->csio.dxfer_len = c->page->bytes;
|
ccb->csio.dxfer_len = c->page->bytes;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -582,31 +855,114 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
err = cam_send_ccb(d->cam, ccb);
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
if (err == -1) {
|
|
||||||
|
ignore_error = sense_len = 0;
|
||||||
|
/* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */
|
||||||
|
if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
|
||||||
|
/* ts B00110 */
|
||||||
|
/* Better curb sense_len */
|
||||||
|
sense_len = ccb->csio.sense_len;
|
||||||
|
if (sense_len > sizeof(c->sense))
|
||||||
|
sense_len = sizeof(c->sense);
|
||||||
|
memcpy(c->sense, &ccb->csio.sense_data, sense_len);
|
||||||
|
if (sense_len >= 14 && cam_pass_err_recover &&
|
||||||
|
(c->sense[2] & 0x0f))
|
||||||
|
ignore_error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == -1 && cam_pass_err_recover && ! ignore_error) {
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (errno == ENXIO && c->opcode[0] != 0) {
|
||||||
|
/* Operations on empty or ejected tray */
|
||||||
|
/* MEDIUM NOT PRESENT */
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,3A,00] MEDIUM NOT PRESENT\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[2] = 0x02;
|
||||||
|
c->sense[12] = 0x3A;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
sense_len = 14;
|
||||||
|
ignore_error = 1;
|
||||||
|
} else if (c->opcode[0] == 0 &&
|
||||||
|
(errno == EBUSY || errno == ENXIO)) {
|
||||||
|
/* Timeout of TEST UNIT READY loop */
|
||||||
|
/* Inquiries while tray is being loaded */
|
||||||
|
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[2] = 0x02;
|
||||||
|
c->sense[12] = 0x04;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
sense_len = 14;
|
||||||
|
ignore_error = 1;
|
||||||
|
} else if (errno == EINVAL) {
|
||||||
|
/* Inappropriate MODE SENSE */
|
||||||
|
/* INVALID FIELD IN CDB */
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [5,24,00] INVALID FIELD IN CDB\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[2] = 0x05;
|
||||||
|
c->sense[12] = 0x24;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
sense_len = 14;
|
||||||
|
ignore_error = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == -1 && !ignore_error) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x0002010c,
|
d->global_index, 0x0002010c,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Failed to transfer command to drive",
|
"Failed to transfer command to drive",
|
||||||
errno, 0);
|
errno, 0);
|
||||||
cam_freeccb(ccb);
|
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
d->released = 1;
|
d->released = 1;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
return -1;
|
{ret = -1; goto ex;}
|
||||||
}
|
}
|
||||||
/* XXX */
|
/* XXX */
|
||||||
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
|
||||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
if (!c->retry) {
|
if (sense_len < 14) {
|
||||||
|
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: CAM_STATUS= %d .Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n", (ccb->ccb_h.status & CAM_STATUS_MASK));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[2] = 0x02;
|
||||||
|
c->sense[12] = 0x04;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
no_retry = 1;
|
||||||
|
}
|
||||||
|
if (no_retry || ignore_error || !c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
cam_freeccb(ccb);
|
{ret = 1; goto ex;}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
switch (scsi_error(d, c->sense, 0)) {
|
switch (scsi_error(d, c->sense, 0)) {
|
||||||
case RETRY:
|
case RETRY:
|
||||||
done = 0;
|
done = 0;
|
||||||
|
if (burn_sg_log_scsi & 3) {
|
||||||
|
/* >>> Need own duration time
|
||||||
|
measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 0,
|
||||||
|
(c->error != 0) | 2);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FAIL:
|
case FAIL:
|
||||||
done = 1;
|
done = 1;
|
||||||
@ -617,8 +973,58 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
if (c->error)
|
||||||
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
/* >>> Need own duration time measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 0, (c->error != 0) | 2);
|
||||||
|
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return 1;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00115 */
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
seeked, read and eventually written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
char *spt;
|
||||||
|
int i, e;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (!S_ISCHR(stbuf.st_mode))
|
||||||
|
return 0;
|
||||||
|
spt = strrchr(path, '/');
|
||||||
|
if (spt == NULL)
|
||||||
|
spt = path;
|
||||||
|
else
|
||||||
|
spt++;
|
||||||
|
e = strlen(spt);
|
||||||
|
for (i = strlen(spt) - 1; i > 0; i--)
|
||||||
|
if (spt[i] >= '0' && spt[i] <= '9')
|
||||||
|
e = i;
|
||||||
|
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -639,6 +1045,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
char testpath[4096], *cpt;
|
char testpath[4096], *cpt;
|
||||||
long blocks;
|
long blocks;
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
|
int fd, ret;
|
||||||
|
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
blocks = *bytes / 512;
|
||||||
@ -673,6 +1080,15 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#endif /* Libburn_if_this_was_linuX */
|
#endif /* Libburn_if_this_was_linuX */
|
||||||
|
|
||||||
|
|
||||||
|
} else if(S_ISCHR(stbuf.st_mode)) {
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return -2;
|
||||||
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
|
close(fd);
|
||||||
|
if (ret == -1)
|
||||||
|
return -2;
|
||||||
|
*bytes = add_size;
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} else if(S_ISREG(stbuf.st_mode)) {
|
||||||
add_size = stbuf.st_blocks * (off_t) 512;
|
add_size = stbuf.st_blocks * (off_t) 512;
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
@ -682,7 +1098,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
1000
libburn/sg-libcdio.c
Normal file
1000
libburn/sg-libcdio.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* <<< ts A91112 : experiments to get better speed with USB
|
/* <<< ts A91112 : experiments to get better speed with USB
|
||||||
#define Libburn_sgio_as_growisofS 1
|
#define Libburn_sgio_as_growisofS 1
|
||||||
@ -11,7 +17,7 @@
|
|||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
the transport level aspects of SCSI control and command i/o.
|
the transport level aspects of SCSI control and command i/o.
|
||||||
|
|
||||||
Present implementation: Linux SCSI Generic (sg)
|
Present implementation: GNU/Linux SCSI Generic (sg)
|
||||||
|
|
||||||
|
|
||||||
PORTING:
|
PORTING:
|
||||||
@ -35,12 +41,28 @@ and of deriving the following system specific files from existing examples:
|
|||||||
Said sg-*.c operations are defined by a public function interface, which has
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
to be implemented in a way that provides libburn with the desired services:
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
|
sg_id_string() returns an id string of the SCSI transport adapter.
|
||||||
|
It may be called before initialization but then may
|
||||||
|
return only a preliminary id.
|
||||||
|
|
||||||
|
sg_initialize() performs global initialization of the SCSI transport
|
||||||
|
adapter and eventually needed operating system
|
||||||
|
facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
|
||||||
|
sg_shutdown() performs global finalizations and releases golbally
|
||||||
|
aquired resources.
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
|
||||||
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
|
on destruction. Releases resources which were aquired
|
||||||
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
sg_drive_is_open() tells wether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
@ -55,15 +77,17 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
|
|||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
|
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
||||||
|
that can be used in 2 kB granularity by lseek(2) and
|
||||||
|
read(2), and possibly write(2) if not read-only.
|
||||||
|
E.g. a USB stick or a hard disk.
|
||||||
|
|
||||||
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
burn_os_open_track_src() opens a disk file in a way that allows best
|
burn_os_open_track_src() opens a disk file in a way that allows best
|
||||||
throughput with file reading and/or SCSI write command
|
throughput with file reading and/or SCSI write command
|
||||||
transmission.
|
transmission.
|
||||||
|
|
||||||
burn_os_close_track_src() closes a filedescriptor obtained by
|
|
||||||
burn_os_open_track_src().
|
|
||||||
|
|
||||||
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
||||||
descriptors issued by burn_os_open_track_src().
|
descriptors issued by burn_os_open_track_src().
|
||||||
The buffer size may be rounded up for alignment
|
The buffer size may be rounded up for alignment
|
||||||
@ -80,6 +104,10 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------- OS dependent headers and definitions ------ */
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
@ -875,7 +903,7 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
#endif /* Libburn_drive_new_deaL */
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
|
||||||
/** Speciality of Linux: detect non-SCSI ATAPI (EIDE) which will from
|
/** Speciality of GNU/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)
|
||||||
{
|
{
|
||||||
@ -1384,7 +1412,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
/* PORTING: ------------------- non portable part --------------- */
|
/* PORTING: ------------------- non portable part --------------- */
|
||||||
|
|
||||||
/* Operating system adapter is Linux Generic SCSI (sg) */
|
/* Operating system adapter is GNU/Linux Generic SCSI (sg) */
|
||||||
/* Adapter specific handles and data */
|
/* Adapter specific handles and data */
|
||||||
out.fd = -1337;
|
out.fd = -1337;
|
||||||
out.sibling_count = 0;
|
out.sibling_count = 0;
|
||||||
@ -1410,8 +1438,63 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal GNU/Linux SG_IO adapter sg-linux");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** PORTING:
|
/** PORTING:
|
||||||
In this Linux implementation, this function mirrors the enumeration
|
In this GNU/Linux implementation, this function mirrors the enumeration
|
||||||
done in sg_enumerate and ata_enumerate(). It would be better to base those
|
done in sg_enumerate and ata_enumerate(). It would be better to base those
|
||||||
functions on this sg_give_next_adr() but the situation is not inviting.
|
functions on this sg_give_next_adr() but the situation is not inviting.
|
||||||
*/
|
*/
|
||||||
@ -1508,7 +1591,7 @@ return_1_pre_proc:;
|
|||||||
libburn's list of drives.
|
libburn's list of drives.
|
||||||
*/
|
*/
|
||||||
/** PORTING:
|
/** PORTING:
|
||||||
If not stricken with an incompletely unified situation like in Linux
|
If not stricken with an incompletely unified situation like in GNU/Linux
|
||||||
one would rather implement this by a loop calling sg_give_next_adr().
|
one would rather implement this by a loop calling sg_give_next_adr().
|
||||||
If needed with your sg_give_next_adr() results, do a test for existence
|
If needed with your sg_give_next_adr() results, do a test for existence
|
||||||
and accessability. If burn activities are prone to external interference
|
and accessability. If burn activities are prone to external interference
|
||||||
@ -1572,6 +1655,7 @@ int sg_drive_is_open(struct burn_drive * d)
|
|||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int fd, os_errno= 0, ret;
|
int fd, os_errno= 0, ret;
|
||||||
|
int max_tries = 3, tries = 0;
|
||||||
|
|
||||||
/* ts A60813 */
|
/* ts A60813 */
|
||||||
int open_mode = O_RDWR;
|
int open_mode = O_RDWR;
|
||||||
@ -1605,6 +1689,7 @@ int sg_grab(struct burn_drive *d)
|
|||||||
value -1 of open(2) war used. */
|
value -1 of open(2) war used. */
|
||||||
if(! burn_drive_is_open(d)) {
|
if(! burn_drive_is_open(d)) {
|
||||||
|
|
||||||
|
try_open:;
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
<<< debug: for tracing calls which might use open drive fds */
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
mmc_function_spy(NULL, "sg_grab ----------- opening");
|
mmc_function_spy(NULL, "sg_grab ----------- opening");
|
||||||
@ -1638,13 +1723,19 @@ int sg_grab(struct burn_drive *d)
|
|||||||
fcntl(fd, F_SETOWN, getpid());
|
fcntl(fd, F_SETOWN, getpid());
|
||||||
d->released = 0;
|
d->released = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if (errno == EBUSY)
|
||||||
|
goto drive_is_in_use;
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Could not grab drive", os_errno, 0);
|
"Could not grab drive", os_errno, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
drive_is_in_use:;
|
drive_is_in_use:;
|
||||||
|
tries++;
|
||||||
|
if (tries < max_tries) {
|
||||||
|
usleep(2000000);
|
||||||
|
goto try_open;
|
||||||
|
}
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020003,
|
0x00020003,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -1682,43 +1773,8 @@ int sg_release(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* <<< ts A91111: on its way out */
|
#ifdef NIX
|
||||||
/** ts A70518:
|
/* <<< now in spc.c as scsi_log_err */
|
||||||
Debugging log facility. Controlled by existence of macros:
|
|
||||||
Libburn_log_sg_commandS enables logging to file
|
|
||||||
/tmp/libburn_sg_command_log
|
|
||||||
Libburn_fflush_log_sg_commandS enables fflush after each output line
|
|
||||||
Libburn_log_sg_command_stderR enables additional log to stderr
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
ts A91111: now enabled by default and controlled burn_sg_log_scsi
|
|
||||||
*/
|
|
||||||
#define Libburn_log_sg_commandS 1
|
|
||||||
#define Libburn_fflush_log_sg_commandS 1
|
|
||||||
#define Libburn_log_sg_command_stderR 1
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_log_sg_commandS
|
|
||||||
|
|
||||||
/** Logs command (before execution) */
|
|
||||||
static int sg_log_cmd(struct command *c, FILE *fp, int flag)
|
|
||||||
{
|
|
||||||
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
|
||||||
scsi_show_cmd_text(c, fp, 0);
|
|
||||||
|
|
||||||
#ifdef Libburn_fflush_log_sg_commandS
|
|
||||||
if (burn_sg_log_scsi & 4)
|
|
||||||
fflush(fp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef Libburn_log_sg_command_stderR
|
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
|
||||||
return 1;
|
|
||||||
sg_log_cmd(c, stderr, flag);
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** logs outcome of a sg command. flag&1 causes an error message */
|
/** logs outcome of a sg command. flag&1 causes an error message */
|
||||||
static int sg_log_err(struct command *c, FILE *fp,
|
static int sg_log_err(struct command *c, FILE *fp,
|
||||||
@ -1734,21 +1790,17 @@ static int sg_log_err(struct command *c, FILE *fp,
|
|||||||
scsi_show_cmd_reply(c, fp, 0);
|
scsi_show_cmd_reply(c, fp, 0);
|
||||||
fprintf(fp,"%6d ms\n", s->duration);
|
fprintf(fp,"%6d ms\n", s->duration);
|
||||||
}
|
}
|
||||||
#ifdef Libburn_fflush_log_sg_commandS
|
|
||||||
if (burn_sg_log_scsi & 4)
|
if (burn_sg_log_scsi & 4)
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef Libburn_log_sg_command_stderR
|
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
sg_log_err(c, stderr, s, flag);
|
sg_log_err(c, stderr, s, flag);
|
||||||
#endif
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* NIX */
|
||||||
#endif /* Libburn_log_sg_commandS */
|
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
@ -1756,8 +1808,6 @@ static int sg_log_err(struct command *c, FILE *fp,
|
|||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
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
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
a retry shall be notified via scsi_notify_error().
|
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
|
@return: 1 success , <=0 failure
|
||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
@ -1766,11 +1816,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
int err;
|
int err;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
sg_io_hdr_t s;
|
sg_io_hdr_t s;
|
||||||
|
|
||||||
#ifdef Libburn_log_sg_commandS
|
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
static FILE *fp= NULL;
|
static FILE *fp= NULL;
|
||||||
#endif /* Libburn_log_sg_commandS */
|
|
||||||
|
|
||||||
/* <<< ts A60821
|
/* <<< ts A60821
|
||||||
debug: for tracing calls which might use open drive fds */
|
debug: for tracing calls which might use open drive fds */
|
||||||
@ -1779,7 +1826,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
d->fd,d->released);
|
d->fd,d->released);
|
||||||
mmc_function_spy(NULL, buf);
|
mmc_function_spy(NULL, buf);
|
||||||
|
|
||||||
#ifdef Libburn_log_sg_commandS
|
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
if (burn_sg_log_scsi & 1) {
|
if (burn_sg_log_scsi & 1) {
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
@ -1789,9 +1835,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
sg_log_cmd(c,fp,0);
|
scsi_log_cmd(c,fp,0);
|
||||||
#endif /* Libburn_log_sg_commandS */
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61010 : with no fd there is no chance to send an ioctl */
|
/* ts A61010 : with no fd there is no chance to send an ioctl */
|
||||||
if (d->fd < 0) {
|
if (d->fd < 0) {
|
||||||
@ -1888,6 +1932,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
switch (scsi_error(d, s.sbp, s.sb_len_wr)) {
|
switch (scsi_error(d, s.sbp, s.sb_len_wr)) {
|
||||||
case RETRY:
|
case RETRY:
|
||||||
done = 0;
|
done = 0;
|
||||||
|
if (burn_sg_log_scsi & 3) {
|
||||||
|
scsi_log_err(c, fp, s.sbp, s.duration,
|
||||||
|
c->error != 0);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FAIL:
|
case FAIL:
|
||||||
done = 1;
|
done = 1;
|
||||||
@ -1931,12 +1980,9 @@ ex:;
|
|||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libburn_log_sg_commandS
|
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
sg_log_err(c, fp, &s, c->error != 0);
|
/* <<< sg_log_err(c, fp, &s, c->error != 0); */
|
||||||
#endif /* Libburn_log_sg_commandS */
|
scsi_log_err(c, fp, s.sbp, s.duration, c->error != 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2032,6 +2078,24 @@ int sg_is_enumerable_adr(char *adr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00115 */
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
seeked, read, and possibly written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (S_ISBLK(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
@ -2083,7 +2147,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
868
libburn/sg-solaris.c
Normal file
868
libburn/sg-solaris.c
Normal file
@ -0,0 +1,868 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
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: Solaris uscsi, e.g. for SunOS 5.11
|
||||||
|
|
||||||
|
|
||||||
|
PORTING:
|
||||||
|
|
||||||
|
Porting libburn typically will consist of adding a new operating system case
|
||||||
|
to the following switcher files:
|
||||||
|
os.h Operating system specific libburn definitions and declarations.
|
||||||
|
sg.c Operating system dependent transport level modules.
|
||||||
|
and of deriving the following system specific files from existing examples:
|
||||||
|
os-*.h Included by os.h. You will need some general system knowledge
|
||||||
|
about signals and knowledge about the storage object needs of your
|
||||||
|
transport level module sg-*.c.
|
||||||
|
|
||||||
|
sg-*.c This source module. You will need special system knowledge about
|
||||||
|
how to detect all potentially available drives, how to open them,
|
||||||
|
eventually how to exclusively reserve them, how to perform
|
||||||
|
SCSI transactions, how to inquire the (pseudo-)SCSI driver.
|
||||||
|
You will not need to care about CD burning, MMC or other high-level
|
||||||
|
SCSI aspects.
|
||||||
|
|
||||||
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
|
sg_id_string() returns an id string of the SCSI transport adapter.
|
||||||
|
It may be called before initialization but then may
|
||||||
|
return only a preliminary id.
|
||||||
|
|
||||||
|
sg_initialize() performs global initialization of the SCSI transport
|
||||||
|
adapter and eventually needed operating system
|
||||||
|
facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
|
||||||
|
sg_shutdown() performs global finalizations and releases golbally
|
||||||
|
aquired resources.
|
||||||
|
|
||||||
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
|
address strings.
|
||||||
|
|
||||||
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
|
on destruction. Releases resources which were aquired
|
||||||
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
|
undisturbed access.
|
||||||
|
|
||||||
|
sg_release() closes a drive opened by sg_grab()
|
||||||
|
|
||||||
|
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||||
|
and evaluates wether the command succeeded or shall
|
||||||
|
be retried or finally failed.
|
||||||
|
|
||||||
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
|
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
||||||
|
that can be used in 2 kB granularity by lseek(2),
|
||||||
|
read(2), and possibly write(2) if not read-only..
|
||||||
|
E.g. a USB stick or a hard disk.
|
||||||
|
|
||||||
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
|
burn_os_open_track_src() opens a disk file in a way that allows best
|
||||||
|
throughput with file reading and/or SCSI write command
|
||||||
|
transmission.
|
||||||
|
|
||||||
|
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
||||||
|
descriptors issued by burn_os_open_track_src().
|
||||||
|
The buffer size may be rounded up for alignment
|
||||||
|
reasons.
|
||||||
|
|
||||||
|
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
||||||
|
|
||||||
|
Porting hints are marked by the text "PORTING:".
|
||||||
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stropts.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#ifdef Libburn_os_has_statvfS
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#endif /* Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
|
#include <sys/dkio.h>
|
||||||
|
#include <sys/vtoc.h>
|
||||||
|
|
||||||
|
#include <sys/scsi/impl/uscsi.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* The waiting time before eventually retrying a failed SCSI command.
|
||||||
|
Before each retry wait Libburn_sg_linux_retry_incR longer than with
|
||||||
|
the previous one.
|
||||||
|
*/
|
||||||
|
#define Libburn_sg_solaris_retry_usleeP 100000
|
||||||
|
#define Libburn_sg_solaris_retry_incR 100000
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "sg.h"
|
||||||
|
#include "spc.h"
|
||||||
|
#include "sbc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/* is in portable part of libburn */
|
||||||
|
int burn_drive_is_banned(char *device_address);
|
||||||
|
int burn_drive_resolve_link(char *path, char adr[],
|
||||||
|
int *recursion_count, int flag); /* drive.c */
|
||||||
|
|
||||||
|
/* Whether to log SCSI commands:
|
||||||
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
|
bit1= log to stderr
|
||||||
|
bit2= flush every line
|
||||||
|
*/
|
||||||
|
extern int burn_sg_log_scsi;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Private definitions. Port only if needed by public functions. */
|
||||||
|
/* (Public functions are listed below) */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/* Storage object is in libburn/init.c
|
||||||
|
whether to strive for exclusive access to the drive
|
||||||
|
*/
|
||||||
|
extern int burn_sg_open_o_excl;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Private functions. Port only if needed by public functions */
|
||||||
|
/* (Public functions are listed below) */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_close_drive(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
if (d->fd != -1) {
|
||||||
|
close(d->fd);
|
||||||
|
d->fd = -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int decode_btl_number(char **cpt, int stopper, int *no)
|
||||||
|
{
|
||||||
|
*no = 0;
|
||||||
|
for ((*cpt)++; **cpt != stopper; (*cpt)++) {
|
||||||
|
if (**cpt < '0' || **cpt > '9')
|
||||||
|
return 0;
|
||||||
|
*no = *no * 10 + **cpt - '0';
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Read bus, target, lun from name "cXtYdZs2".
|
||||||
|
Return 0 if name is not of the desired form.
|
||||||
|
*/
|
||||||
|
static int decode_btl_solaris(char *name, int *busno, int *tgtno, int *lunno,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
char *cpt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*busno = *tgtno = *lunno = -1;
|
||||||
|
cpt = name;
|
||||||
|
if (*cpt != 'c')
|
||||||
|
return 0;
|
||||||
|
ret = decode_btl_number(&cpt, 't', busno);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
ret = decode_btl_number(&cpt, 'd', tgtno);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
ret = decode_btl_number(&cpt, 's', lunno);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
cpt++;
|
||||||
|
if (*cpt != '2' || *(cpt + 1) != 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int start_enum_cXtYdZs2(burn_drive_enumerator_t *idx, int flag)
|
||||||
|
{
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
idx->dir = NULL;
|
||||||
|
dir = opendir("/dev/rdsk");
|
||||||
|
if (dir == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
|
0x0002000c, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Cannot start device file enumeration. opendir(\"/dev/rdsk\") failed.",
|
||||||
|
errno, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
idx->dir = dir;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int next_enum_cXtYdZs2(burn_drive_enumerator_t *idx,
|
||||||
|
char adr[], int adr_size, int flag)
|
||||||
|
{
|
||||||
|
int busno, tgtno, lunno, ret, fd = -1;
|
||||||
|
char volpath[160];
|
||||||
|
struct dirent *entry;
|
||||||
|
struct dk_cinfo cinfo;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
dir = idx->dir;
|
||||||
|
while (1) {
|
||||||
|
errno = 0;
|
||||||
|
entry = readdir(dir);
|
||||||
|
if (entry == NULL) {
|
||||||
|
if (errno) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
-1, 0x0002000d,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Cannot enumerate next device. readdir() from \"/dev/rdsk\" failed.",
|
||||||
|
errno, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strlen(entry->d_name) > sizeof(volpath) - 11)
|
||||||
|
continue;
|
||||||
|
ret = decode_btl_solaris(entry->d_name,
|
||||||
|
&busno, &tgtno, &lunno, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
continue; /* not cXtYdZs2 */
|
||||||
|
|
||||||
|
sprintf(volpath, "/dev/rdsk/%s", entry->d_name);
|
||||||
|
if (burn_drive_is_banned(volpath))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fd = open(volpath, O_RDONLY | O_NDELAY);
|
||||||
|
if (fd < 0)
|
||||||
|
continue;
|
||||||
|
/* See man dkio */
|
||||||
|
ret = ioctl(fd, DKIOCINFO, &cinfo);
|
||||||
|
close(fd);
|
||||||
|
if (ret < 0)
|
||||||
|
continue;
|
||||||
|
if (cinfo.dki_ctype != DKC_CDROM)
|
||||||
|
continue;
|
||||||
|
if (adr_size <= strlen(volpath))
|
||||||
|
return -1;
|
||||||
|
strcpy(adr, volpath);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int end_enum_cXtYdZs2(burn_drive_enumerator_t *idx, int flag)
|
||||||
|
{
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
dir = idx->dir;
|
||||||
|
if(dir != NULL)
|
||||||
|
closedir(dir);
|
||||||
|
idx->dir = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
/* PORTING: Private functions which contain publicly needed functionality. */
|
||||||
|
/* Their portable part must be performed. So it is probably best */
|
||||||
|
/* to replace the non-portable part and to call these functions */
|
||||||
|
/* in your port, too. */
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/** Wraps a detected drive into libburn structures and hands it over to
|
||||||
|
libburn drive list.
|
||||||
|
*/
|
||||||
|
static void enumerate_common(char *fname,
|
||||||
|
int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct burn_drive out;
|
||||||
|
|
||||||
|
/* General libburn drive setup */
|
||||||
|
burn_setup_drive(&out, fname);
|
||||||
|
|
||||||
|
/* This transport adapter uses SCSI-family commands and models
|
||||||
|
(seems the adapter would know better than its boss, if ever) */
|
||||||
|
ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
|
||||||
|
target_no, lun_no, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* PORTING: ------------------- non portable part --------------- */
|
||||||
|
|
||||||
|
/* Transport adapter is Solaris uscsi */
|
||||||
|
/* Adapter specific handles and data */
|
||||||
|
out.fd = -1;
|
||||||
|
|
||||||
|
/* PORTING: ---------------- end of non portable part ------------ */
|
||||||
|
|
||||||
|
/* Adapter specific functions with standardized names */
|
||||||
|
out.grab = sg_grab;
|
||||||
|
out.release = sg_release;
|
||||||
|
out.drive_is_open = sg_drive_is_open;
|
||||||
|
out.issue_command = sg_issue_command;
|
||||||
|
/* Finally register drive and inquire drive information */
|
||||||
|
burn_drive_finish_enum(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Public functions. These MUST be ported. */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
sprintf(msg, "internal Solaris uscsi adapter sg-solaris");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 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 latter.)
|
||||||
|
@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)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (initialize == 1) {
|
||||||
|
ret = start_enum_cXtYdZs2(idx, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
} else if (initialize == -1) {
|
||||||
|
ret = end_enum_cXtYdZs2(idx, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ret = next_enum_cXtYdZs2(idx, adr, adr_size, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Brings all available, not-whitelist-banned, and accessible drives into
|
||||||
|
libburn's list of drives.
|
||||||
|
*/
|
||||||
|
int scsi_enumerate_drives(void)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1, ret, i_bus_no = -1;
|
||||||
|
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (burn_drive_is_banned(buf))
|
||||||
|
continue;
|
||||||
|
sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no,
|
||||||
|
&i_channel_no, &i_target_no, &i_lun_no);
|
||||||
|
enumerate_common(buf,
|
||||||
|
i_bus_no, i_host_no, i_channel_no,
|
||||||
|
i_target_no, i_lun_no);
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tells whether 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 (d->fd != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 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)
|
||||||
|
{
|
||||||
|
char msg[4096];
|
||||||
|
int os_errno, ret;
|
||||||
|
struct dk_cinfo cinfo;
|
||||||
|
|
||||||
|
if (d->fd != -1) {
|
||||||
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
d->fd = open(d->devname, O_RDONLY | O_NDELAY);
|
||||||
|
if (d->fd == -1) {
|
||||||
|
os_errno = errno;
|
||||||
|
sprintf(msg, "Could not grab drive '%s'", d->devname);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020003,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, os_errno, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ret = ioctl(d->fd, DKIOCINFO, &cinfo);
|
||||||
|
if (ret < 0)
|
||||||
|
goto revoke;
|
||||||
|
if (cinfo.dki_ctype != DKC_CDROM)
|
||||||
|
goto revoke;
|
||||||
|
|
||||||
|
/* >>> obtain eventual locks */;
|
||||||
|
|
||||||
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
|
revoke:;
|
||||||
|
sprintf(msg, "Could not grab drive '%s'. Not a CDROM device.",
|
||||||
|
d->devname);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020003,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING: Is mainly about the call to sg_close_drive() and whether it
|
||||||
|
implements the demanded functionality.
|
||||||
|
*/
|
||||||
|
/** 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)
|
||||||
|
{
|
||||||
|
if (d->fd < 0) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sg_close_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)
|
||||||
|
{
|
||||||
|
int i, usleep_time, timeout_ms, no_retry = 0, ret;
|
||||||
|
time_t start_time;
|
||||||
|
struct uscsi_cmd cgc;
|
||||||
|
char msg[80];
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
|
||||||
|
c->error = 0;
|
||||||
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
|
if (d->fd == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (burn_sg_log_scsi & 1) {
|
||||||
|
if (fp == NULL) {
|
||||||
|
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||||
|
fprintf(fp,
|
||||||
|
"\n-----------------------------------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
|
||||||
|
memset (&cgc, 0, sizeof (struct uscsi_cmd));
|
||||||
|
/* No error messages, no retries,
|
||||||
|
do not execute with other commands, request sense data
|
||||||
|
*/
|
||||||
|
cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE
|
||||||
|
| USCSI_RQENABLE;
|
||||||
|
cgc.uscsi_timeout = 200;
|
||||||
|
cgc.uscsi_cdb = (caddr_t) c->opcode;
|
||||||
|
cgc.uscsi_bufaddr = (caddr_t) c->page->data;
|
||||||
|
if (c->dir == TO_DRIVE) {
|
||||||
|
cgc.uscsi_flags |= USCSI_WRITE;
|
||||||
|
cgc.uscsi_buflen = c->page->bytes;
|
||||||
|
} else if (c->dir == FROM_DRIVE) {
|
||||||
|
cgc.uscsi_flags |= USCSI_READ;
|
||||||
|
if (c->dxfer_len >= 0)
|
||||||
|
cgc.uscsi_buflen = c->dxfer_len;
|
||||||
|
else
|
||||||
|
cgc.uscsi_buflen = BUFFER_SIZE;
|
||||||
|
/* touch page so we can use valgrind */
|
||||||
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
|
} else {
|
||||||
|
cgc.uscsi_buflen = 0;
|
||||||
|
}
|
||||||
|
cgc.uscsi_cdblen = c->oplen;
|
||||||
|
cgc.uscsi_rqlen = sizeof(c->sense);
|
||||||
|
cgc.uscsi_rqbuf = (caddr_t) c->sense;
|
||||||
|
|
||||||
|
/* retry-loop */
|
||||||
|
start_time = time(NULL);
|
||||||
|
timeout_ms = 200000;
|
||||||
|
for(i = 0; ; i++) {
|
||||||
|
|
||||||
|
ret = ioctl(d->fd, USCSICMD, &cgc);
|
||||||
|
|
||||||
|
/* For cgc.uscsi_status see SAM-3 5.3.1, Table 22
|
||||||
|
0 = GOOD , 2 = CHECK CONDITION : Sense Data are delivered
|
||||||
|
8 = BUSY
|
||||||
|
*/
|
||||||
|
if (ret != 0 && cgc.uscsi_status != 2) {
|
||||||
|
sprintf(msg,
|
||||||
|
"Failed to transfer command to drive. (uscsi_status = 0x%X)",
|
||||||
|
(unsigned int) cgc.uscsi_status),
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x0002010c,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, errno, 0);
|
||||||
|
sg_close_drive(d);
|
||||||
|
d->released = 1;
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
c->error = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->sense[2] &= 15;
|
||||||
|
|
||||||
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
|
if (c->sense[2] || c->sense[12] || c->sense[13]) {
|
||||||
|
if (no_retry || !c->retry) {
|
||||||
|
c->error = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
switch (scsi_error(d, c->sense, 18)) {
|
||||||
|
case RETRY:
|
||||||
|
if (burn_sg_log_scsi & 3) {
|
||||||
|
/* >>> Need own duration time
|
||||||
|
measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 0,
|
||||||
|
(c->error != 0) | 2);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FAIL:
|
||||||
|
c->error = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Calming down retries and breaking up endless cycle
|
||||||
|
*/
|
||||||
|
usleep_time = Libburn_sg_solaris_retry_usleeP +
|
||||||
|
i * Libburn_sg_solaris_retry_incR;
|
||||||
|
if (time(NULL) + usleep_time / 1000000 - start_time >
|
||||||
|
timeout_ms / 1000 + 1) {
|
||||||
|
c->error = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
usleep(usleep_time);
|
||||||
|
} else
|
||||||
|
break; /* retry-loop */
|
||||||
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
if (c->error)
|
||||||
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
/* >>> Need own duration time measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 0, (c->error != 0) | 2);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Try to guess from path */
|
||||||
|
if (strncmp("/dev/rdsk/", path, 10) == 0) {
|
||||||
|
ret = decode_btl_solaris(path + 10,
|
||||||
|
bus_no, target_no, lun_no, 0);
|
||||||
|
if (ret > 0) {
|
||||||
|
*host_no = *bus_no;
|
||||||
|
*channel_no = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*bus_no = *host_no = *channel_no = *target_no = *lun_no = -1;
|
||||||
|
|
||||||
|
/* >>> Could need a ioctl which gives SCSI numbers */;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||||
|
functions.
|
||||||
|
*/
|
||||||
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1, ret;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(adr, buf) == 0) {
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
seeked, read, and possibly written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (S_ISBLK(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
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;
|
||||||
|
|
||||||
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
|
int open_mode = O_RDONLY, fd;
|
||||||
|
|
||||||
|
fd = open(path, open_mode);
|
||||||
|
if (fd == -1)
|
||||||
|
return -2;
|
||||||
|
*bytes = lseek(fd, 0, SEEK_END);
|
||||||
|
close(fd);
|
||||||
|
if (*bytes == -1) {
|
||||||
|
*bytes = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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_frsize) *
|
||||||
|
(off_t) vfsbuf.f_bavail;
|
||||||
|
|
||||||
|
#else /* Libburn_os_has_statvfS */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif /* ! Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||||
|
|
||||||
|
#ifdef Libburn_read_o_direcT
|
||||||
|
|
||||||
|
/* No special O_DIRECT-like precautions are implemented here */
|
||||||
|
|
||||||
|
#endif /* Libburn_read_o_direcT */
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, open_flags);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||||
|
{
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
buf = calloc(1, amount);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
return 0;
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
36
libburn/sg.c
36
libburn/sg.c
@ -1,19 +1,45 @@
|
|||||||
|
|
||||||
/* 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) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
|
provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#undef HAVE_CONFIG_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_dummY
|
||||||
|
|
||||||
|
#include "sg-dummy.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef Libburn_use_libcdiO
|
||||||
|
|
||||||
|
#include "sg-libcdio.c"
|
||||||
|
|
||||||
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
#include "sg-freebsd.c"
|
#include "sg-freebsd.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD_kernel__
|
||||||
|
|
||||||
|
#include "sg-freebsd.c"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
|
|
||||||
#include "sg-linux.c"
|
#include "sg-linux.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __sun
|
||||||
|
|
||||||
|
#include "sg-solaris.c"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* The dummy adapter formally fulfills the expectations of libburn towards
|
/* The dummy adapter formally fulfills the expectations of libburn towards
|
||||||
@ -24,11 +50,11 @@
|
|||||||
static int intentional_compiler_warning(void)
|
static int intentional_compiler_warning(void)
|
||||||
{
|
{
|
||||||
int INTENTIONAL_COMPILER_WARNING_;
|
int INTENTIONAL_COMPILER_WARNING_;
|
||||||
int Cannot_recognize_Linux_nor_FreeBSD_;
|
int Cannot_recognize_GNU_Linux_nor_FreeBSD_;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter_;
|
int Have_to_use_dummy_MMC_transport_adapter_;
|
||||||
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter;
|
int Have_to_use_dummy_MMC_transport_adapter;
|
||||||
int Cannot_recognize_Linux_nor_FreeBSD;
|
int Cannot_recognize_GNU_Linux_nor_FreeBSD;
|
||||||
int INTENTIONAL_COMPILER_WARNING;
|
int INTENTIONAL_COMPILER_WARNING;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
@ -36,6 +62,10 @@ static int intentional_compiler_warning(void)
|
|||||||
|
|
||||||
#include "sg-dummy.c"
|
#include "sg-dummy.c"
|
||||||
|
|
||||||
|
#endif /* ! __sun */
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
|
#endif /* ! __FreeBSD_kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
48
libburn/sg.h
48
libburn/sg.h
@ -1,5 +1,8 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SG
|
#ifndef __SG
|
||||||
#define __SG
|
#define __SG
|
||||||
|
|
||||||
@ -31,6 +34,51 @@ int scsi_enumerate_drives(void);
|
|||||||
|
|
||||||
int sg_drive_is_open(struct burn_drive * d);
|
int sg_drive_is_open(struct burn_drive * d);
|
||||||
|
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag);
|
||||||
|
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes);
|
int burn_os_stdio_capacity(char *path, off_t *bytes);
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag);
|
||||||
|
|
||||||
|
/* ts A91225 */
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag);
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag);
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __SG */
|
#endif /* __SG */
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
|
132
libburn/spc.c
132
libburn/spc.c
@ -1,7 +1,16 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
/* scsi primary commands */
|
/* scsi primary commands */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -27,6 +36,14 @@
|
|||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
/* ts A91111 :
|
||||||
|
whether to log SCSI commands:
|
||||||
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
|
bit1= log to stderr
|
||||||
|
bit2= flush every line
|
||||||
|
*/
|
||||||
|
extern int burn_sg_log_scsi;
|
||||||
|
|
||||||
|
|
||||||
/* spc command set */
|
/* spc command set */
|
||||||
/* ts A70519 : allocation length byte 3+4 was 0,255 */
|
/* ts A70519 : allocation length byte 3+4 was 0,255 */
|
||||||
@ -36,8 +53,7 @@ static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 36, 0 };
|
|||||||
static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 };
|
static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 };
|
||||||
static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 };
|
static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 };
|
||||||
static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||||
static unsigned char SPC_MODE_SELECT[] =
|
static unsigned char SPC_MODE_SELECT[] = { 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
{ 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 };
|
static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 };
|
||||||
static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 };
|
static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
@ -100,7 +116,8 @@ int spc_test_unit_ready(struct burn_drive *d)
|
|||||||
int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
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, clueless_start = 0;
|
||||||
|
static int clueless_timeout = 5 * 10;
|
||||||
char msg[320];
|
char msg[320];
|
||||||
unsigned char sense[14];
|
unsigned char sense[14];
|
||||||
enum response resp;
|
enum response resp;
|
||||||
@ -130,6 +147,7 @@ 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;
|
||||||
|
|
||||||
|
handle_error:;
|
||||||
/* ts A90213 */
|
/* ts A90213 */
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Asynchronous SCSI error on %s: ", cmd_text);
|
"Asynchronous SCSI error on %s: ", cmd_text);
|
||||||
@ -144,7 +162,23 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
|||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
break;
|
break;
|
||||||
}
|
} else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */
|
||||||
|
/* Might be a clueless system adapter */
|
||||||
|
if (clueless_start == 0)
|
||||||
|
clueless_start = i;
|
||||||
|
if (i - clueless_start > clueless_timeout) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index,
|
||||||
|
0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Ended clueless NOT READY cycle",
|
||||||
|
0, 0);
|
||||||
|
ret = 1; /* medium not present = ok */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (ascq == 0x02 || ascq == 0x03)
|
||||||
|
goto handle_error;
|
||||||
|
|
||||||
slumber:;
|
slumber:;
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
@ -321,7 +355,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
was_error = 1;
|
was_error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = c.page->data[0] * 256 + c.page->data[1];
|
size = c.page->data[0] * 256 + c.page->data[1] + 2;
|
||||||
page = c.page->data + 8;
|
page = c.page->data + 8;
|
||||||
|
|
||||||
/* ts A61225 :
|
/* ts A61225 :
|
||||||
@ -517,7 +551,7 @@ void spc_sense_error_params(struct burn_drive *d)
|
|||||||
c.dir = FROM_DRIVE;
|
c.dir = FROM_DRIVE;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
size = c.page->data[0] * 256 + c.page->data[1];
|
size = c.page->data[0] * 256 + c.page->data[1] + 2;
|
||||||
m = d->mdata;
|
m = d->mdata;
|
||||||
page = c.page->data + 8;
|
page = c.page->data + 8;
|
||||||
d->params.retries = page[3];
|
d->params.retries = page[3];
|
||||||
@ -600,7 +634,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] + 2;
|
||||||
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]);
|
||||||
m->write_page_length = page[1];
|
m->write_page_length = page[1];
|
||||||
@ -925,18 +959,36 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
int *key, int *asc, int *ascq)
|
int *key, int *asc, int *ascq)
|
||||||
{
|
{
|
||||||
char *msg;
|
char *msg;
|
||||||
|
static char key_def[16][40] = {
|
||||||
|
"(no specific error)",
|
||||||
|
"Recovered error",
|
||||||
|
"Drive not ready",
|
||||||
|
"Medium error",
|
||||||
|
"Drive error",
|
||||||
|
"Illegal request",
|
||||||
|
"Drive event",
|
||||||
|
"Data protected",
|
||||||
|
"Blank/Nonblank",
|
||||||
|
"Vendor specific code",
|
||||||
|
"Copy aborted",
|
||||||
|
"Command aborted",
|
||||||
|
"(obsolete error code)",
|
||||||
|
"Volume overflow",
|
||||||
|
"Miscompare",
|
||||||
|
"(reserved error code)",
|
||||||
|
};
|
||||||
|
|
||||||
msg= msg_data;
|
msg= msg_data;
|
||||||
*key= *asc= *ascq= -1;
|
*key= *asc= *ascq= -1;
|
||||||
|
|
||||||
if (senselen<=0 || senselen>2)
|
if (senselen<=0 || senselen>2)
|
||||||
*key = sense[2];
|
*key = sense[2] & 0x0f;
|
||||||
if (senselen<=0 || senselen>12)
|
if (senselen<=0 || senselen>12)
|
||||||
*asc = sense[12];
|
*asc = sense[12];
|
||||||
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);
|
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
|
||||||
msg= msg + strlen(msg);
|
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",
|
||||||
@ -951,8 +1003,11 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
sprintf(msg, "Not ready");
|
sprintf(msg, "Not ready");
|
||||||
return RETRY;
|
return RETRY;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
sprintf(msg,
|
if (*ascq == 1)
|
||||||
|
sprintf(msg,
|
||||||
"Logical unit is in the process of becoming ready");
|
"Logical unit is in the process of becoming ready");
|
||||||
|
else
|
||||||
|
sprintf(msg, "Logical unit is not ready");
|
||||||
return RETRY;
|
return RETRY;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
if (*key != 4)
|
if (*key != 4)
|
||||||
@ -1205,8 +1260,8 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
sprintf(msg_data,
|
sprintf(msg_data,
|
||||||
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
|
"See MMC specs: Sense Key %X \"%s\", ASC %2.2X ASCQ %2.2X",
|
||||||
*key, *asc, *ascq);
|
*key & 0xf, key_def[(*key) & 0xf], *asc, *ascq);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1412,3 +1467,56 @@ int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
|
|||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91218 (former sg_log_cmd ts A70518) */
|
||||||
|
/** Logs command (before execution) */
|
||||||
|
int scsi_log_cmd(struct command *c, void *fp_in, int flag)
|
||||||
|
{
|
||||||
|
FILE *fp = fp_in;
|
||||||
|
|
||||||
|
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||||
|
scsi_show_cmd_text(c, fp, 0);
|
||||||
|
if (burn_sg_log_scsi & 4)
|
||||||
|
fflush(fp);
|
||||||
|
}
|
||||||
|
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||||
|
return 1;
|
||||||
|
scsi_log_cmd(c, stderr, flag);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
|
/** Logs outcome of a sg command.
|
||||||
|
@param flag bit0 causes an error message
|
||||||
|
bit1 do not print duration
|
||||||
|
*/
|
||||||
|
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
||||||
|
int duration, int flag)
|
||||||
|
{
|
||||||
|
char durtxt[20];
|
||||||
|
FILE *fp = fp_in;
|
||||||
|
|
||||||
|
if(fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||||
|
if(flag & 1) {
|
||||||
|
durtxt[0] = 0;
|
||||||
|
if (!(flag & 2))
|
||||||
|
sprintf(durtxt, " (%6d ms)\n",duration);
|
||||||
|
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
|
||||||
|
sense[2], sense[12], sense[13], durtxt);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
scsi_show_cmd_reply(c, fp, 0);
|
||||||
|
if (!(flag & 2))
|
||||||
|
fprintf(fp,"%6d ms\n", duration);
|
||||||
|
}
|
||||||
|
if (burn_sg_log_scsi & 4)
|
||||||
|
fflush(fp);
|
||||||
|
}
|
||||||
|
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||||
|
return 1;
|
||||||
|
scsi_log_err(c, stderr, sense, duration, flag);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SPC
|
#ifndef __SPC
|
||||||
#define __SPC
|
#define __SPC
|
||||||
|
|
||||||
@ -65,5 +71,14 @@ int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
|||||||
/* ts A91106 */
|
/* ts A91106 */
|
||||||
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
|
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
|
/* ts A91218 (former sg_log_cmd ts A70518) */
|
||||||
|
/** Logs command (before execution) */
|
||||||
|
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
|
/** Logs outcome of a sg command. */
|
||||||
|
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
||||||
|
int duration, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*__SPC*/
|
#endif /*__SPC*/
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__STRUCTURE_H
|
#ifndef BURN__STRUCTURE_H
|
||||||
#define BURN__STRUCTURE_H
|
#define BURN__STRUCTURE_H
|
||||||
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
@ -130,7 +139,7 @@ void toc_find_modes(struct burn_drive *d)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
t->mode = BURN_MODE1;
|
t->mode = BURN_MODE1;
|
||||||
/* ts A70519 : this does not work with Linux 2.4 USB because one cannot
|
/* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot
|
||||||
predict the exact dxfer_size without knowing the sector type.
|
predict the exact dxfer_size without knowing the sector type.
|
||||||
mem.sectors = 1;
|
mem.sectors = 1;
|
||||||
d->read_sectors(d, lba, mem.sectors, &o, &mem);
|
d->read_sectors(d, lba, mem.sectors, &o, &mem);
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TOC_H
|
#ifndef __TOC_H
|
||||||
#define __TOC_H
|
#define __TOC_H
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TRANSPORT
|
#ifndef __TRANSPORT
|
||||||
#define __TRANSPORT
|
#define __TRANSPORT
|
||||||
|
|
||||||
@ -306,6 +312,8 @@ struct burn_drive
|
|||||||
/* ts A70929 */
|
/* ts A70929 */
|
||||||
pid_t thread_pid;
|
pid_t thread_pid;
|
||||||
int thread_pid_valid;
|
int thread_pid_valid;
|
||||||
|
/* ts B00225 */
|
||||||
|
pthread_t thread_tid;
|
||||||
|
|
||||||
|
|
||||||
/* transport functions */
|
/* transport functions */
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
@ -132,6 +142,10 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
|
|
||||||
|
if (m_li == 0 && s_li == 2 && f_li == 0) {
|
||||||
|
result = strdup("(no manufacturer code)");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
f_li_0 = f_li - (f_li % 10);
|
f_li_0 = f_li - (f_li % 10);
|
||||||
for (i = 0; mid_list[i].manufacturer[0]; i++) {
|
for (i = 0; mid_list[i].manufacturer[0]; i++) {
|
||||||
if (m_li == mid_list[i].m_li &&
|
if (m_li == mid_list[i].m_li &&
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
@ -33,7 +43,6 @@
|
|||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "crc.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
@ -937,6 +946,8 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
|||||||
|
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
|
|
||||||
|
#ifdef Libburn_reset_progress_asynC
|
||||||
|
/* <<< This is now done in async.c */
|
||||||
/* init progress before showing the state */
|
/* init progress before showing the state */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
d->progress.sessions = disc->sessions;
|
d->progress.sessions = disc->sessions;
|
||||||
@ -951,6 +962,7 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
|||||||
d->progress.sectors = 0;
|
d->progress.sectors = 0;
|
||||||
d->progress.sector = 0;
|
d->progress.sector = 0;
|
||||||
d->progress.track = 0;
|
d->progress.track = 0;
|
||||||
|
#endif /* Libburn_reset_progress_asynC */
|
||||||
|
|
||||||
/* ts A61023 */
|
/* ts A61023 */
|
||||||
d->progress.buffer_capacity = 0;
|
d->progress.buffer_capacity = 0;
|
||||||
@ -1263,8 +1275,8 @@ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
|
|
||||||
/* ts A91114 : EXPERIMENTAL, NOT COMPLETELY IMPLEMENTED
|
/* ts A91114 : EXPERIMENTAL, NOT COMPLETELY IMPLEMENTED
|
||||||
|
|
||||||
Simplified data transmission for DVD. libburn via Linux USB is 30 % slower
|
Simplified data transmission for DVD. libburn via GNU/Linux USB is 30 %
|
||||||
than growisofs or cdrecord when transmitting 32 KB chunks.
|
slower than growisofs or cdrecord when transmitting 32 KB chunks.
|
||||||
With 64 KB chunks it is 20% faster than the competitors.
|
With 64 KB chunks it is 20% faster than the competitors.
|
||||||
No heavy CPU load is visible but there might be subtle race conditions in
|
No heavy CPU load is visible but there might be subtle race conditions in
|
||||||
the USB driver which work better with shorter time gaps between WRITE
|
the USB driver which work better with shorter time gaps between WRITE
|
||||||
@ -1304,7 +1316,7 @@ static int transact_dvd_chunk(struct burn_write_opts *opts,
|
|||||||
unsigned char *data = out->data;
|
unsigned char *data = out->data;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
static int tee_fd= -1;
|
static int tee_fd= -1;
|
||||||
if(tee_fd==-1)
|
if(tee_fd==-1)
|
||||||
tee_fd= open("/tmp/libburn_sg_readin",
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
@ -1923,6 +1935,10 @@ 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 */
|
||||||
|
if (d->do_stream_recording) {
|
||||||
|
if (d->current_profile == 0x41) /* BD-R */
|
||||||
|
o->obs = Libburn_bd_re_streamed_obS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libburn_dvd_obs_default_64K
|
#ifdef Libburn_dvd_obs_default_64K
|
||||||
@ -1949,6 +1965,18 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
o->obs = 32 * 1024; /* This size is required to work */
|
o->obs = 32 * 1024; /* This size is required to work */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d->do_stream_recording &&
|
||||||
|
(d->current_profile == 0x43 || d->current_profile == 0x41) &&
|
||||||
|
o->obs < Libburn_bd_re_streamed_obS) {
|
||||||
|
/* LG GGW-H20 writes junk with stream recording and obs=32k */
|
||||||
|
sprintf(msg,
|
||||||
|
"Stream recording disabled because of small OS buffer");
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020176, LIBDAX_MSGS_SEV_NOTE,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
||||||
|
d->do_stream_recording = 0;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
||||||
d->current_profile, o->obs, o->obs_pad);
|
d->current_profile, o->obs, o->obs_pad);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||||
@ -1978,7 +2006,7 @@ ex:;
|
|||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d);
|
||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
||||||
return ret;
|
return ret;
|
||||||
early_failure:;
|
early_failure:;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2241,8 +2269,9 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
prev_sync_sector = d->progress.sector;
|
prev_sync_sector = d->progress.sector;
|
||||||
if (!o->simulate)
|
if (!o->simulate)
|
||||||
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
||||||
burn_stdio_slowdown(d, &prev_time, 512 * 2, 0);
|
|
||||||
}
|
}
|
||||||
|
if ((d->progress.sector % 512) == 0)
|
||||||
|
burn_stdio_slowdown(d, &prev_time, 512 * 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pad up buffer to next full o->obs (usually 32 kB) */
|
/* Pad up buffer to next full o->obs (usually 32 kB) */
|
||||||
@ -2305,7 +2334,7 @@ ex:;
|
|||||||
/* update media state records */
|
/* update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d);
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2381,7 +2410,7 @@ calloc() seems not to have the desired effect. valgrind warns:
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A70521 : Linux 2.4 USB audio fails with 64 kiB */
|
/* ts A70521 : GNU/Linux 2.4 USB audio fails with 64 kiB */
|
||||||
/* ts A80414 : might need 64 kiB for BD-RE streaming */
|
/* ts A80414 : might need 64 kiB for BD-RE streaming */
|
||||||
/* buffer flush trigger for sector.c:get_sector() */
|
/* buffer flush trigger for sector.c:get_sector() */
|
||||||
o->obs = Libburn_cd_obS;
|
o->obs = Libburn_cd_obS;
|
||||||
@ -2542,7 +2571,7 @@ return crap. so we send the command, then ignore the result.
|
|||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
|
|
||||||
burn_print(1, "done\n");
|
burn_print(1, "done\n");
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
||||||
|
|
||||||
/* ts A61012 : This return was traditionally missing. I suspect this
|
/* ts A61012 : This return was traditionally missing. I suspect this
|
||||||
to have caused Cdrskin_eject() failures */
|
to have caused Cdrskin_eject() failures */
|
||||||
@ -2557,7 +2586,7 @@ fail_wo_sync:;
|
|||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Burn run failed", 0, 0);
|
"Burn run failed", 0, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
||||||
ex:;
|
ex:;
|
||||||
d->do_stream_recording = 0;
|
d->do_stream_recording = 0;
|
||||||
if (d->buffer != NULL)
|
if (d->buffer != NULL)
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BURN__WRITE_H
|
#ifndef BURN__WRITE_H
|
||||||
#define BURN__WRITE_H
|
#define BURN__WRITE_H
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* 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 - 2009 Thomas Schmitt <scdbackup@gmx.net> */
|
/* Copyright (C) 2005 - 2010 Thomas Schmitt <scdbackup@gmx.net> */
|
||||||
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
|
/* Provided under GPL, see also "License and copyright aspects" at file end */
|
||||||
|
|
||||||
|
|
||||||
/** Overview
|
/** Overview
|
||||||
@ -26,7 +26,7 @@
|
|||||||
approaches are shown here in application functions:
|
approaches are shown here in application functions:
|
||||||
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
||||||
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
||||||
With that aquired drive you can blank a CD-RW
|
With that aquired drive you can blank a CD-RW or DVD-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 to default size with spare blocks
|
or an unused BD to default size with spare blocks
|
||||||
@ -36,9 +36,25 @@
|
|||||||
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();
|
||||||
burn_finish()
|
burn_finish()
|
||||||
|
|
||||||
|
FreeBSD does not work well with the convenient synchronous signal handler. So
|
||||||
|
the waiting loops for blanking, formatting, and writing use the asynchronous
|
||||||
|
mode of the libburn signal handler. It will not shutdown the library and
|
||||||
|
abort the program, but rather tell the ongoing drive operation to stop as
|
||||||
|
soon as possible. After the loops and at the end of the program there is a
|
||||||
|
call to determine whether an abort happened:
|
||||||
|
burn_is_aborting()
|
||||||
|
|
||||||
|
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 libburn/libburn.h prescribes off_t.
|
||||||
|
This program gets fed with appropriate settings externally by libburn's
|
||||||
|
autotools generated build system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** See this for the decisive API specs . libburn.h is The Original */
|
/** See this for the decisive API specs . libburn.h is The Original */
|
||||||
/* For using the installed header file : #include <libburn/libburn.h> */
|
/* For using the installed header file : #include <libburn/libburn.h> */
|
||||||
/* This program insists in the own headerfile. */
|
/* This program insists in the own headerfile. */
|
||||||
@ -300,9 +316,12 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
"FATAL : Media is not of erasable type\n");
|
"FATAL : Media is not of erasable type\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf(
|
/* Switch to asynchronous signal handling for the time of waiting */
|
||||||
"Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
|
printf("Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
||||||
burn_disc_erase(drive, blank_fast);
|
burn_disc_erase(drive, blank_fast);
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
||||||
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||||
@ -311,6 +330,10 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
printf("Blanking ( %.1f%% done )\n", percent);
|
printf("Blanking ( %.1f%% done )\n", percent);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
if (burn_is_aborting(0) > 0)
|
||||||
|
return -1;
|
||||||
|
/* Back to synchronous handling */
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0);
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -363,6 +386,7 @@ int libburner_format(struct burn_drive *drive)
|
|||||||
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
printf("Beginning to format media.\n");
|
printf("Beginning to format media.\n");
|
||||||
burn_disc_format(drive, size, format_flag);
|
burn_disc_format(drive, size, format_flag);
|
||||||
@ -375,6 +399,9 @@ int libburner_format(struct burn_drive *drive)
|
|||||||
printf("Formatting ( %.1f%% done )\n", percent);
|
printf("Formatting ( %.1f%% done )\n", percent);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
if (burn_is_aborting(0) > 0)
|
||||||
|
return -1;
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0);
|
||||||
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||||
current_profile_name);
|
current_profile_name);
|
||||||
if (current_profile == 0x14 || current_profile == 0x13)
|
if (current_profile == 0x14 || current_profile == 0x13)
|
||||||
@ -520,6 +547,7 @@ int libburner_payload(struct burn_drive *drive,
|
|||||||
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
||||||
start_time = time(0);
|
start_time = time(0);
|
||||||
@ -567,6 +595,8 @@ int libburner_payload(struct burn_drive *drive,
|
|||||||
}
|
}
|
||||||
burn_session_free(session);
|
burn_session_free(session);
|
||||||
burn_disc_free(target_disc);
|
burn_disc_free(target_disc);
|
||||||
|
if (burn_is_aborting(0) > 0)
|
||||||
|
return -1;
|
||||||
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
||||||
current_profile != 0x12 && current_profile != 0x43)
|
current_profile != 0x12 && current_profile != 0x43)
|
||||||
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
||||||
@ -702,6 +732,13 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* A warning to programmers who start their own projekt from here. */
|
||||||
|
if (sizeof(off_t) != 8) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nFATAL: Compile time misconfiguration. off_t is not 64 bit.\n\n");
|
||||||
|
exit(39);
|
||||||
|
}
|
||||||
|
|
||||||
ret = libburner_setup(argc, argv);
|
ret = libburner_setup(argc, argv);
|
||||||
if (ret)
|
if (ret)
|
||||||
exit(ret);
|
exit(ret);
|
||||||
@ -718,7 +755,7 @@ int main(int argc, char **argv)
|
|||||||
/* Print messages of severity SORRY or more directly to stderr */
|
/* Print messages of severity SORRY or more directly to stderr */
|
||||||
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
||||||
|
|
||||||
/* Activate the default signal handler which eventually will try to
|
/* Activate the synchronous signal handler which eventually will try to
|
||||||
properly shutdown drive and library on aborting events. */
|
properly shutdown drive and library on aborting events. */
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0);
|
burn_set_signal_handling("libburner : ", NULL, 0);
|
||||||
|
|
||||||
@ -752,10 +789,14 @@ release_drive:;
|
|||||||
burn_drive_release(drive_list[driveno].drive, 0);
|
burn_drive_release(drive_list[driveno].drive, 0);
|
||||||
|
|
||||||
finish_libburn:;
|
finish_libburn:;
|
||||||
|
if (burn_is_aborting(0) > 0) {
|
||||||
|
burn_abort(4400, burn_abort_pacifier, "libburner : ");
|
||||||
|
fprintf(stderr,"\nlibburner run aborted\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
/* This app does not bother to know about exact scan state.
|
/* This app does not bother to know about exact scan state.
|
||||||
Better to accept a memory leak here. We are done anyway. */
|
Better to accept a memory leak here. We are done anyway. */
|
||||||
/* burn_drive_info_free(drive_list); */
|
/* burn_drive_info_free(drive_list); */
|
||||||
|
|
||||||
burn_finish();
|
burn_finish();
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
@ -768,37 +809,6 @@ Read. Try. Think. Play. Write yourself some code. Be free of my copyright.
|
|||||||
|
|
||||||
Be also invited to study the code of cdrskin/cdrskin.c et al.
|
Be also invited to study the code of cdrskin/cdrskin.c et al.
|
||||||
|
|
||||||
|
|
||||||
Clarification in my name and in the name of Mario Danic, copyright holder
|
|
||||||
on toplevel of libburnia. To be fully in effect after the remaining other
|
|
||||||
copyrighted code has been replaced by ours and by copyright-free contributions
|
|
||||||
of our friends:
|
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
|
||||||
those libraries are compiled from our unaltered code.
|
|
||||||
|
|
||||||
Thus you may link our libraries dynamically with applications
|
|
||||||
which are not under GPL. You may distribute our libraries and
|
|
||||||
application tools in binary form, if you fulfill the usual
|
|
||||||
condition of GPL to offer a copy of the source code -altered
|
|
||||||
or unaltered- under GPL.
|
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
|
||||||
and with the due reference to the entire open source community.
|
|
||||||
|
|
||||||
If there should really arise the case where above clarification
|
|
||||||
does not suffice to fulfill a clear and neat request in open source
|
|
||||||
spirit that would otherwise be declined for mere formal reasons,
|
|
||||||
only in that case we will duely consider to issue a special license
|
|
||||||
covering only that special case.
|
|
||||||
It is the open source idea of responsible freedom which will be
|
|
||||||
decisive and you will have to prove that you exhausted all own
|
|
||||||
means to qualify for GPL.
|
|
||||||
|
|
||||||
For now we are firmly committed to maintain one single license: GPL.
|
|
||||||
|
|
||||||
History:
|
History:
|
||||||
libburner is a compilation of my own contributions to test/burniso.c and
|
libburner is a compilation of my own contributions to test/burniso.c and
|
||||||
fresh code which replaced the remaining parts under copyright of
|
fresh code which replaced the remaining parts under copyright of
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* test/telltoc.c , API illustration of obtaining media status info */
|
/* test/telltoc.c , API illustration of obtaining media status info */
|
||||||
/* Copyright (C) 2006 - 2007 Thomas Schmitt <scdbackup@gmx.net>
|
/* Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 */
|
Provided under GPL */
|
||||||
|
|
||||||
/** Overview
|
/** Overview
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user