Compare commits
63 Commits
ZeroSevenE
...
ZeroEightS
Author | SHA1 | Date | |
---|---|---|---|
4fa7c8d477 | |||
6d2fd6e947 | |||
5ae5205553 | |||
45e252ec1a | |||
df390ae7d3 | |||
c1f4063193 | |||
4cc524097b | |||
fb159b8dbd | |||
c693798571 | |||
34847fff80 | |||
54651df146 | |||
d4e4607a84 | |||
98b2e06c21 | |||
d5ecb382aa | |||
cdcda19384 | |||
b96aeece99 | |||
7bbf99384e | |||
9f61db5378 | |||
2a48b34bcd | |||
15266fb310 | |||
e2bdd521d8 | |||
7a3b871c4e | |||
713ec46f23 | |||
85eb091025 | |||
c866b6bc35 | |||
0250a2831d | |||
4c47b81a9c | |||
bb88ba5861 | |||
b30a2af7c7 | |||
b10cfb3d22 | |||
a2df41713d | |||
86ce32d170 | |||
7ba30596ce | |||
2f8ad976ea | |||
d0d37af096 | |||
81768cd4b0 | |||
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 |
261
ChangeLog
261
ChangeLog
@ -1 +1,260 @@
|
|||||||
nothing here now
|
libburn-0.8.6.pl00.tar.gz Fri Sep 17 2010
|
||||||
|
===============================================================================
|
||||||
|
* Lifted test reservation on DVD-R DL media.
|
||||||
|
* Hiding all non-API symbols from the linker by use of --version-script
|
||||||
|
* Now with history of release notes in ./ChangeLog file.
|
||||||
|
|
||||||
|
libburn-0.8.4.pl00.tar.gz Wed Jun 30 2010
|
||||||
|
===============================================================================
|
||||||
|
* General POSIX system adapters ignore SIGWINCH and SIGURG if defined
|
||||||
|
* Allowed 64 kB max output buffer size on all OSes
|
||||||
|
|
||||||
|
libburn-0.8.2.pl00.tar.gz Fri Jun 11 2010
|
||||||
|
===============================================================================
|
||||||
|
* New system adapter for Solaris uscsi (tested on snv134, kernel 5.11)
|
||||||
|
* Bug fix: CD TOC was not read if the first track did not start at LBA 0
|
||||||
|
* Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses
|
||||||
|
* Bug fix: SIGSEGV of experimental libcdio system adapter if drive list is
|
||||||
|
empty
|
||||||
|
|
||||||
|
libburn-0.8.0.pl00.tar.gz Fri Apr 09 2010
|
||||||
|
===============================================================================
|
||||||
|
* libburn now works with ahci driver on FreeBSD 8-STABLE.
|
||||||
|
|
||||||
|
libburn-0.7.8.pl00.tar.gz Wed Mar 10 2010
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: On FreeBSD, piped input was falsely attributed a small fixed size.
|
||||||
|
* Built-in abort handling is more suitable for FreeBSD now.
|
||||||
|
cdrskin novelties:
|
||||||
|
* Bug fix: Option fs=0 led to SIGSEGV. Regression introduced by version 0.7.4
|
||||||
|
in december 2009.
|
||||||
|
* Abort handling is more suitable for FreeBSD now.
|
||||||
|
|
||||||
|
libburn-0.7.6.pl00.tar.gz Sat Jan 23 2010
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: System adapter for generic X/Open was missing in libburn release
|
||||||
|
tarball
|
||||||
|
* Bug fix: with non-Linux adapters there were 0 readable bytes on block devices
|
||||||
|
* Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
|
||||||
|
* Enabled FreeBSD system adapter for Debian kfreebsd
|
||||||
|
* Experimental SCSI transport adapter via GNU libcdio 0.83git
|
||||||
|
cdrskin novelties:
|
||||||
|
* none
|
||||||
|
|
||||||
|
libburn-0.7.4.pl01.tar.gz Sat Dec 26 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Added missing system adapter for generic X/Open to libburn release
|
||||||
|
tarball
|
||||||
|
|
||||||
|
Libburn 0.7.4.pl00 Mon Dec 07 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG
|
||||||
|
GH22LS30
|
||||||
|
* Bug fix: DVD DAO track size was rounded up much too generously
|
||||||
|
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.
|
||||||
|
(already fixed in 0.7.2.pl01)
|
||||||
|
* Workaround for Pioneer DVR-216D refusal to eject.
|
||||||
|
(already fixed in 0.7.2.pl01)
|
||||||
|
* Configure options --enable-dvd-obs-64k, --enable-track-src-odirect
|
||||||
|
* New API calls burn_write_opts_set_dvd_obs(),
|
||||||
|
burn_write_opts_set_stdio_fsync()
|
||||||
|
* New API call burn_set_scsi_logging()
|
||||||
|
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(),
|
||||||
|
burn_fifo_fill()
|
||||||
|
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
|
||||||
|
cdrskin novelties:
|
||||||
|
* cdrskin option -V for logging of SCSI commands
|
||||||
|
* New cdrskin options dvd_obs= and stdio_fsync=
|
||||||
|
* New compile_cdrskin.sh option -dvd_obs_64k
|
||||||
|
|
||||||
|
libburn-0.7.2.pl01.tar.gz Fri Nov 13 2009
|
||||||
|
===============================================================================
|
||||||
|
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.
|
||||||
|
* Workaround for Pioneer DVR-216D refusal to eject.
|
||||||
|
|
||||||
|
Libburn 0.7.2.pl00 Mon Oct 12 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode
|
||||||
|
* New API calls burn_get_media_product_id() , burn_guess_manufacturer() ,
|
||||||
|
burn_guess_cd_manufacturer()
|
||||||
|
* New API call burn_disc_get_cd_info()
|
||||||
|
* New API call burn_track_set_cdxa_conv()
|
||||||
|
cdrskin novelties:
|
||||||
|
* Better interpretation of options -mode2, -xa, -xa1, -xa2
|
||||||
|
* New option --xa1-ignore
|
||||||
|
* New -atip report lines "Product Id:" and "Producer:"
|
||||||
|
|
||||||
|
libburn-0.7.0.pl00.tar.gz Thu Aug 27 2009
|
||||||
|
===============================================================================
|
||||||
|
* New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() allow
|
||||||
|
to inquire and process the list of supported media types. cdrskin lists all
|
||||||
|
supported profiles with option -atip -v
|
||||||
|
* New API call burn_drive_snooze() allows to calm down a drive when no i/o is
|
||||||
|
expected for a while.
|
||||||
|
* Bug fix: Some SCSI commands stalled on U3 memory sticks which appear as a hub
|
||||||
|
with a memory stick and a CD-ROM drive containing a small CD. These commands
|
||||||
|
make not much sense with a CD-ROM and are now avoided for this media
|
||||||
|
situation.
|
||||||
|
|
||||||
|
libburn-0.6.8.pl00.tar.gz Tue Jul 14 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length.
|
||||||
|
* cdrskin -scanbus now works with high SCSI bus numbers.
|
||||||
|
|
||||||
|
libburn-0.6.6.pl00.tar.gz Fri May 8 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Improper abort handling with broken pipe during outputto a stdio:
|
||||||
|
pseudo-drive.
|
||||||
|
* Bug fix: Device scan stalled on FreeBSD with non-burner USB device
|
||||||
|
|
||||||
|
libburn-0.6.4.pl00.tar.gz Fri Mar 13 2009
|
||||||
|
===============================================================================
|
||||||
|
* New operating system adapter "dummy" for stdio on general X/Open systems
|
||||||
|
* New API function burn_drive_set_stream_recording() allows to write the
|
||||||
|
crucial start blocks of a filesystem with slow BD-RE Defect Management and to
|
||||||
|
write the bulk of data with full nominal speed.
|
||||||
|
|
||||||
|
libburn-0.6.2.pl00.tar.gz Fri Feb 20 2009
|
||||||
|
===============================================================================
|
||||||
|
* Improvements with build system for FreeBSD
|
||||||
|
|
||||||
|
libburn-0.6.0.pl01.tar.gz Wed Jan 07 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: BD-R were not correctly finalized
|
||||||
|
|
||||||
|
libburn-0.6.0.pl00.tar.gz Sun Jan 04 2009
|
||||||
|
===============================================================================
|
||||||
|
* Formatting and writing of BD-R media
|
||||||
|
* New API function burn_get_read_capacity()
|
||||||
|
|
||||||
|
libburn-0.5.8.pl00.tar.gz Mon Dec 08 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: A session without leadout entry on CD caused a SIGSEGV by NULL
|
||||||
|
* Improvements about BD-RE formatting
|
||||||
|
|
||||||
|
libburn-0.5.6.pl00.tar.gz Wed Nov 12 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: libburn fifo thread was not aborted when burn run was aborted which
|
||||||
|
could lead to use of freed memory.
|
||||||
|
|
||||||
|
libburn-0.5.4.pl00.tar.gz Mon Oct 6 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: On Linux 2.4 /dev/sr0 was accepted as enumerable address but then
|
||||||
|
failed to work.
|
||||||
|
|
||||||
|
libburn-0.5.2.pl00.tar.gz Wed Aug 20 2008
|
||||||
|
===============================================================================
|
||||||
|
* Larger set of possibly acceptable drive device file names
|
||||||
|
|
||||||
|
libburn-0.5.0.pl00.tar.gz Thu Jul 17 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin option drive_scsi_dev_family=scd lead to buffer overflow
|
||||||
|
* Ability to use /dev/scd as fallback if /dev/sr does not exist
|
||||||
|
* New API call burn_fifo_peek_data()
|
||||||
|
|
||||||
|
libburn-0.4.8.pl00.tar.gz Sat May 17 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Random access addressing for DVD-RAM and BD-RE did not work.
|
||||||
|
* cdrskin: Affected were options write_start_address= and
|
||||||
|
-- grow_overwriteable_iso on DVD-RAM or BD-RE.
|
||||||
|
* xorriso: Affected were sessions on DVD-RAM or BD-RE after the first one.
|
||||||
|
|
||||||
|
libburn-0.4.6.pl00.tar.gz Sun May 11 2008
|
||||||
|
===============================================================================
|
||||||
|
* Support for BD-RE media is now official
|
||||||
|
* New burn_write_opts_set_stream_recording() can speed up DVD-RAM and BD-RE
|
||||||
|
* New cdrskin option --list_formats
|
||||||
|
* New cdrskin blank types for expert formatting of DVD-RAM and BD-RE
|
||||||
|
* New cdrskin blank type blank=as_needed for automatic handling of media
|
||||||
|
|
||||||
|
libburn-0.4.4.tar.gz Thu April 10 2008
|
||||||
|
===============================================================================
|
||||||
|
* Support for DVD+R/DL media is now official
|
||||||
|
|
||||||
|
libburn-0.4.2.tar.gz Sun Feb 3 2008
|
||||||
|
===============================================================================
|
||||||
|
* Long term commitment to ABI libburn.so.4.
|
||||||
|
* ABI compatibility is guaranteed for any older feature set released since
|
||||||
|
libburn-0.3.2 about one year ago.
|
||||||
|
* libburn provides means for compile time and runtime checking of its version.
|
||||||
|
* Compile time check in cdrskin for proper version of libburn include file.
|
||||||
|
Required is at least 0.4.2.
|
||||||
|
* Runtime check in cdrskin prevents dynamic linking with outdated version of
|
||||||
|
libburn.so.4. Required is at least the version seen in the include file at
|
||||||
|
compile time.
|
||||||
|
|
||||||
|
libburn-0.4.0.tar.gz Mon Oct 29 2007
|
||||||
|
===============================================================================
|
||||||
|
* New option direct_write_amount=
|
||||||
|
* New option --grow_overwriteable_iso
|
||||||
|
* New option --allow_emulated_drives dev=stdio:<path>
|
||||||
|
* More cdrecord options supported: -format, -inq, -load, -lock, -immed, -waiti
|
||||||
|
* New option fallback_program=
|
||||||
|
* A lot of libburn API additions.
|
||||||
|
|
||||||
|
libburn-0.3.8.tar.gz Tue Jul 31 2007
|
||||||
|
===============================================================================
|
||||||
|
* Now able to cope with the peculiarities of Linux 2.4 USB
|
||||||
|
* Refusal to perform -dummy runs on media which cannot simulate burning
|
||||||
|
* New option modesty_on_drive= may help with hda -> hdb burns
|
||||||
|
* New option minbuf= , cdrecord compatible frontend of modesty_on_drive=
|
||||||
|
* New option --adjust_speed_to_drive
|
||||||
|
* Precautions against using the burner drive as track source
|
||||||
|
* Note: ABI has not been broken.
|
||||||
|
|
||||||
|
libburn-0.3.6.tar.gz Thu Apr 26 2007
|
||||||
|
===============================================================================
|
||||||
|
* On Linux kernel 2.6, /dev/sr* gets used rather than /dev/sg*.
|
||||||
|
* DVD+R now get finalized (if not -multi is given)
|
||||||
|
|
||||||
|
libburn-0.3.4.tar.gz Mon Mar 12 2007
|
||||||
|
===============================================================================
|
||||||
|
* Multi-session recording on DVD+R, including -toc, -msinfo
|
||||||
|
* Options --tell_media_space , assert_write_lba=
|
||||||
|
* Bug fix of rare multi track fifo stall
|
||||||
|
|
||||||
|
libburn-0.3.2.tar.gz Feb 11 2007
|
||||||
|
===============================================================================
|
||||||
|
* Burnfree enabled by default
|
||||||
|
* Multi-session recording on sequential DVD-R[W], including -toc, -msinfo
|
||||||
|
* DVD-R[W] Disk-at-once recording
|
||||||
|
|
||||||
|
libburn-0.3.0.1.tar.gz Tue Jan 30 2007
|
||||||
|
===============================================================================
|
||||||
|
* Improved recognition of unsuitable media types
|
||||||
|
* Replaced ban of chmod u+s by loud warning
|
||||||
|
* detailed man page for cdrskin
|
||||||
|
* Burning of DVD+RW and DVD-RAM media as single-track TAO-like initial session
|
||||||
|
* Formatting and then burning to DVD-RW like to DVD+RW
|
||||||
|
* New option -msifile=path from cdrkit/wodim
|
||||||
|
* 0.3.0.1 release notes *
|
||||||
|
* Bug fix enabling tracks >= 1.3 GB from disk file
|
||||||
|
|
||||||
|
libburn-0.2.6.3.tar.gz Fri Dec 29 2006
|
||||||
|
===============================================================================
|
||||||
|
* 0.2.6 release notes (Wed Nov 22 2006)
|
||||||
|
* After a lot of time with dedication to this project, we proudly present you
|
||||||
|
libburn 0.2.6. It is the first version of cdrskin and libburn after they have
|
||||||
|
been split from genisofs and libisofs. Main new features are write mode TAO
|
||||||
|
and support for multi session.
|
||||||
|
* 0.2.6.1 release notes (Fri Nov 24 2006)
|
||||||
|
* Point release to fix misleading version numbers in messages and documentation
|
||||||
|
* 0.2.6.2 release notes (Sat Dec 16 2006)
|
||||||
|
* cdrskin man page backported from development version 0.2.7.
|
||||||
|
* 0.2.6.3 release notes (Fri Dec 29 2006)
|
||||||
|
* Point release to fix build system problems people have experienced with the
|
||||||
|
past release.
|
||||||
|
|
||||||
|
libburn-0.2.3.snapshot02.tar.gz Thu Nov 02 2006
|
||||||
|
===============================================================================
|
||||||
|
* Stabilized snapshot including release 0.2.4.pl01 of cdrskin
|
||||||
|
* cdrskin 0.2.4 release notes
|
||||||
|
* Compatibility with cdrecord has been improved in respect to drive addresses,
|
||||||
|
audio extraction from .wav, -scanbus, -toc, drive buffer fill indicator.
|
||||||
|
* Note: The previous snapshot01 with the same source base is handicapped by a
|
||||||
|
broken ./configure setup. It works well on Intel compatible CPUs but is
|
||||||
|
supposed to be unusable on big-endian architectures.
|
||||||
|
|
||||||
|
libburn-0.2.2.tar.gz Wed Sep 20 2006
|
||||||
|
===============================================================================
|
||||||
|
Initial release of libburnia's libburn combined with cdrskin.
|
||||||
|
12
Makefile.am
12
Makefile.am
@ -110,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 - B00122
|
## cdrskin construction site - ts A60816 - B00611
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_7
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_8_6
|
||||||
|
|
||||||
# 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
|
||||||
@ -143,7 +143,10 @@ doc/html: doc/doxygen.conf
|
|||||||
doc-upload: doc/html
|
doc-upload: doc/html
|
||||||
scp -r $</* $(webhost):$(webpath)
|
scp -r $</* $(webhost):$(webpath)
|
||||||
|
|
||||||
all: doc
|
## ts B00729
|
||||||
|
## Not by default any more.
|
||||||
|
## It is unclear who is supposed to create file ./doc/doc.lock
|
||||||
|
# all: doc
|
||||||
|
|
||||||
install-data-local:
|
install-data-local:
|
||||||
if [ -f ./doc/doc.lock ]; then \
|
if [ -f ./doc/doc.lock ]; then \
|
||||||
@ -199,14 +202,17 @@ EXTRA_DIST = \
|
|||||||
cdrskin/wiki_plain.txt \
|
cdrskin/wiki_plain.txt \
|
||||||
cdrskin/cleanup.h \
|
cdrskin/cleanup.h \
|
||||||
cdrskin/cleanup.c \
|
cdrskin/cleanup.c \
|
||||||
|
libburn/libburn.ver \
|
||||||
libburn/os-dummy.h \
|
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-libcdio.h \
|
||||||
|
libburn/os-solaris.h \
|
||||||
libburn/sg-dummy.c \
|
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-libcdio.c \
|
||||||
|
libburn/sg-solaris.c \
|
||||||
COPYING \
|
COPYING \
|
||||||
NEWS \
|
NEWS \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
|
76
README
76
README
@ -11,7 +11,7 @@ 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.6.pl00.tar.gz
|
http://files.libburnia-project.org/releases/libburn-0.8.6.pl00.tar.gz
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
|||||||
|
|
||||||
From tarball
|
From tarball
|
||||||
|
|
||||||
Obtain libburn-0.7.6.pl00.tar.gz, take it to a directory of your choice and do:
|
Obtain libburn-0.8.6.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf libburn-0.7.6.pl00.tar.gz
|
tar xzf libburn-0.8.6.pl00.tar.gz
|
||||||
cd libburn-0.7.6
|
cd libburn-0.8.6
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
@ -76,6 +76,12 @@ 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
|
You may install it and re-run libburn's ./configure with option
|
||||||
--enable-libcdio
|
--enable-libcdio
|
||||||
|
|
||||||
|
By use of a version script, the libburn.so library exposes no other function
|
||||||
|
names but those of the API definition in libburn/libburn.h.
|
||||||
|
If -Wl,--version-script=... makes problems with the local compiler, then
|
||||||
|
disable this encapsulation feature by
|
||||||
|
--disable-versioned-libs
|
||||||
|
|
||||||
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
|
||||||
@ -105,8 +111,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.
|
||||||
|
|
||||||
@ -138,12 +145,15 @@ The project components (list subject to growth, hopefully):
|
|||||||
|
|
||||||
- libisofs is the library to pack up hard disk files and directories into a
|
- libisofs is the library to pack up hard disk files and directories into a
|
||||||
ISO 9660 disk image. This may then be brought to CD via libburn.
|
ISO 9660 disk image. This may then be brought to CD via libburn.
|
||||||
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
An own ISO 9660 extension stores ACLs, xattr, and MD5 of file
|
||||||
|
content.
|
||||||
|
|
||||||
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
||||||
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
|
||||||
@ -161,8 +171,10 @@ The project components (list subject to growth, hopefully):
|
|||||||
Rock Ridge extensions. Manipulation is not only adding or
|
Rock Ridge extensions. Manipulation is not only adding or
|
||||||
overwriting of files but also deleting, renaming, attribute
|
overwriting of files but also deleting, renaming, attribute
|
||||||
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. There is also a
|
||||||
extension stores ACLs, xattr, and MD5 of file content.
|
sparse emulation of cdrecord and a more laborate one of mkisofs.
|
||||||
|
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
|
||||||
@ -496,6 +508,52 @@ Project history as far as known to me:
|
|||||||
fixes bugs about the generic X/Open system adapter, and allows to use
|
fixes bugs about the generic X/Open system adapter, and allows to use
|
||||||
libcdio >= 0.83 as SCSI transport facility.
|
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.
|
||||||
|
|
||||||
|
- 14 Jun 2010 By release 0.5.8.pl00 of libisoburn, xorriso becomes a public C
|
||||||
|
language API of libisoburn. The emulations of mkisofs and cdrecord have
|
||||||
|
been enhanced.
|
||||||
|
|
||||||
|
- Tue Jun 29 2010 Version 0.6.34 of libisofs provides new features about
|
||||||
|
hiding file names from directory trees.
|
||||||
|
|
||||||
|
- Wed Jun 30 2010 libburn-0.8.4 removes some restrictions on operating
|
||||||
|
systems other than Linux and FreeBSD.
|
||||||
|
|
||||||
|
- Fri Jul 02 2010 Release 0.6.0.pl00 of libisoburn adds more options to the
|
||||||
|
mkisofs emulation of xorriso. It also fixes minor bugs and shortcommings.
|
||||||
|
|
||||||
|
- Wed Sep 15 2010 Version 0.6.36 of libisofs can produce ISO images which
|
||||||
|
bear a partiton 1 with non-zero start address. They can be mounted from
|
||||||
|
USB stick via the main device file (e.g. /dev/sdb) as well as via the
|
||||||
|
partition device file (e.g. /dev/sdb1).
|
||||||
|
|
||||||
|
- Fri Sep 17 2010 libburn-0.8.6 lifts the test reservation on DVD-R DL media.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
15
acinclude.m4
15
acinclude.m4
@ -42,6 +42,21 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl LIBBURN_ASSERT_VERS_LIBS is by Thomas Schmitt, libburnia project
|
||||||
|
dnl It tests whether -Wl,--version-script=... works with the compiler
|
||||||
|
AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
|
||||||
|
[
|
||||||
|
libburnia_save_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="$LDFLAGS -Wl,--version-script=libburn/libburn.ver"
|
||||||
|
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
||||||
|
[vers_libs_test="yes"], [vers_libs_test="no"])
|
||||||
|
if test x$vers_libs_test = xno
|
||||||
|
then
|
||||||
|
LDFLAGS="$libburnia_save_LDFLAGS"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
||||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||||
dnl
|
dnl
|
||||||
|
114
cdrskin/README
114
cdrskin/README
@ -4,7 +4,7 @@
|
|||||||
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.7.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-0.8.6.pl00.tar.gz
|
||||||
|
|
||||||
Copyright (C) 2006-2010 Thomas Schmitt, provided under GPL version 2 or later.
|
Copyright (C) 2006-2010 Thomas Schmitt, provided under GPL version 2 or later.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@ -13,7 +13,8 @@ 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.
|
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
||||||
|
on FreeBSD and on OpenSolaris.
|
||||||
IDE drives under Linux 2.4. need kernel module ide-scsi.
|
IDE drives under Linux 2.4. need kernel module ide-scsi.
|
||||||
ATA and SATA drives under FreeBSD need kernel module atapicam.
|
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
|
||||||
@ -25,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.7.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-0.8.6.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-0.7.7.tar.gz
|
tar xzf cdrskin-0.8.6.pl00.tar.gz
|
||||||
cd cdrskin-0.7.7
|
cd cdrskin-0.8.6
|
||||||
|
|
||||||
Within that directory execute:
|
Within that directory execute:
|
||||||
|
|
||||||
@ -103,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
|
||||||
@ -122,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
|
||||||
|
|
||||||
@ -433,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
|
||||||
|
@ -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.6"
|
skin_release="0.8.6"
|
||||||
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.7"
|
skin_release="0.8.7"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Macro for creation of arrays of objects (or single objects) */
|
/* Macro for creation of arrays of objects (or single objects) */
|
||||||
#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ));
|
#define TSOB_FELD(typ,anz) (typ *) calloc(anz, sizeof(typ));
|
||||||
|
|
||||||
|
|
||||||
#define Cdrfifo_buffer_chunK 2048
|
#define Cdrfifo_buffer_chunK 2048
|
||||||
|
@ -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 "Feb 29, 2010"
|
.TH CDRSKIN 1 "Aug 21, 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:
|
||||||
@ -47,7 +47,7 @@ Multi session on CD (follow-up sessions in TAO only)
|
|||||||
.br
|
.br
|
||||||
or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R.
|
or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R.
|
||||||
.br
|
.br
|
||||||
Single session on DVD-RW or DVD-R (Disk-at-once).
|
Single session Disk-at-once on DVD-RW, DVD-R, DVD-R DL.
|
||||||
.br
|
.br
|
||||||
Single session or emulated ISO-9660 multi-session
|
Single session or emulated ISO-9660 multi-session
|
||||||
.br
|
.br
|
||||||
@ -166,7 +166,7 @@ needed.
|
|||||||
.SS
|
.SS
|
||||||
.B Sequentially Recordable DVD or BD Media:
|
.B Sequentially Recordable DVD or BD Media:
|
||||||
.br
|
.br
|
||||||
Currently DVD-RW, DVD-R , DVD+R[/DL], and BD-R can be used for the Sequential
|
Currently DVD-RW, DVD-R[DL], DVD+R[DL], and BD-R can be used for the Sequential
|
||||||
recording model. It resembles the model of CD media. Only DVD-RW can be
|
recording model. It resembles the model of CD media. Only DVD-RW can be
|
||||||
blanked and re-used from scratch.
|
blanked and re-used from scratch.
|
||||||
.br
|
.br
|
||||||
@ -186,8 +186,8 @@ of recognizable size or the size has to be announced explicitly by options
|
|||||||
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 DVD-R media which do not offer feature 21h Incremental
|
||||||
Streaming. DAO may also be selected explicitly by option
|
Streaming (e.g. DVD-R DL). 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.
|
||||||
@ -198,7 +198,7 @@ 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
|
||||||
.B -multi .
|
.B -multi . It does not work with DVD-R DL and minimally blanked DVD-RW.
|
||||||
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
||||||
Multiple tracks per session are permissible.
|
Multiple tracks per session are permissible.
|
||||||
.br
|
.br
|
||||||
@ -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
|
||||||
@ -656,7 +659,8 @@ Without it the disc gets closed and may not be written any more - unless it
|
|||||||
is a -RW and gets blanked which causes loss of its content.
|
is a -RW and gets blanked which causes loss of its content.
|
||||||
.br
|
.br
|
||||||
The following sessions can only be written in -tao mode. -multi is prohibited
|
The following sessions can only be written in -tao mode. -multi is prohibited
|
||||||
with DVD-R[W] DAO write mode. Option --prodvd_cli_compatible eventually makes
|
with DVD-R[W] DAO write mode and on DVD-R DL media.
|
||||||
|
Option --prodvd_cli_compatible eventually makes
|
||||||
-multi tolerable but cannot make it work.
|
-multi tolerable but cannot make it work.
|
||||||
.br
|
.br
|
||||||
In order to have all filesystem content accessible, the eventual ISO-9660
|
In order to have all filesystem content accessible, the eventual ISO-9660
|
||||||
@ -750,6 +754,8 @@ Mode -tao can be used with track sources of unpredictable size, like standard
|
|||||||
input or named pipes. It is also the only mode that can be used for writing
|
input or named pipes. It is also the only mode that can be used for writing
|
||||||
to appendable media which already hold data. With unformatted DVD-R[W] it is
|
to appendable media which already hold data. With unformatted DVD-R[W] it is
|
||||||
the only mode which allows -multi.
|
the only mode which allows -multi.
|
||||||
|
.br
|
||||||
|
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
|
||||||
.TP
|
.TP
|
||||||
.BI \-toc
|
.BI \-toc
|
||||||
Print the table of content (TOC) which describes the tracks recorded on disc.
|
Print the table of content (TOC) which describes the tracks recorded on disc.
|
||||||
@ -1087,12 +1093,11 @@ This option is only needed for revoking eventual --ignore_signals or
|
|||||||
.TP
|
.TP
|
||||||
.BI \--allow_untested_media
|
.BI \--allow_untested_media
|
||||||
Enable the use of media profiles which have been implemented but not yet
|
Enable the use of media profiles which have been implemented but not yet
|
||||||
tested. Currently this applies to :
|
tested. Currently this option is without effect because no media types are
|
||||||
|
under test reservation.
|
||||||
.br
|
.br
|
||||||
Profile 0015h , DVD-R/DL Sequential (will not allow -multi).
|
(If you really test experimental media, then please report the outcome on
|
||||||
.br
|
libburn-hackers@pykix.org)
|
||||||
If you really test such media, then please report the outcome on
|
|
||||||
libburn-hackers@pykix.org
|
|
||||||
.TP
|
.TP
|
||||||
.BI dev_translation= <sep><from><sep><to>
|
.BI dev_translation= <sep><from><sep><to>
|
||||||
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
|
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
|
||||||
@ -1262,7 +1267,7 @@ cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
|
|||||||
.br
|
.br
|
||||||
blank=as_needed -eject padsize=300k my_image.iso
|
blank=as_needed -eject padsize=300k my_image.iso
|
||||||
.SS
|
.SS
|
||||||
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW):
|
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW or DVD-R DL):
|
||||||
.br
|
.br
|
||||||
find . | afio -oZ - | \\
|
find . | afio -oZ - | \\
|
||||||
.br
|
.br
|
||||||
|
@ -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.7"
|
#define Cdrskin_prog_versioN "0.8.6"
|
||||||
#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 7
|
#define Cdrskin_libburn_micrO 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -135,13 +135,13 @@ or
|
|||||||
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
||||||
|
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_7_6
|
#ifdef Cdrskin_libburn_0_8_6
|
||||||
#define Cdrskin_libburn_versioN "0.7.6"
|
#define Cdrskin_libburn_versioN "0.8.6"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
#endif /* Cdrskin_libburn_0_7_6 */
|
#endif /* Cdrskin_libburn_0_8_6 */
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_7_7
|
#ifdef Cdrskin_libburn_0_8_7
|
||||||
#define Cdrskin_libburn_versioN "0.7.7"
|
#define Cdrskin_libburn_versioN "0.8.7"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
|
|
||||||
/* Place novelty switch macros here.
|
/* Place novelty switch macros here.
|
||||||
@ -151,31 +151,30 @@ or
|
|||||||
/* Do not stay in signal handler but only cancel and set Cdrskin_abort_leveL.
|
/* 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.
|
Make use of burn_is_aborting() to detect pending libburn aborts.
|
||||||
*/
|
*/
|
||||||
#define Cdrskin_signal_handler_return_2 1
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* Cdrskin_libburn_0_7_7 */
|
#endif /* Cdrskin_libburn_0_8_7 */
|
||||||
|
|
||||||
#ifndef Cdrskin_libburn_versioN
|
#ifndef Cdrskin_libburn_versioN
|
||||||
#define Cdrskin_libburn_0_7_6
|
#define Cdrskin_libburn_0_8_6
|
||||||
#define Cdrskin_libburn_versioN "0.7.6"
|
#define Cdrskin_libburn_versioN "0.8.6"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_0_7_6
|
#ifdef Cdrskin_libburn_0_8_6
|
||||||
#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 6
|
#define Cdrskin_libburn_micrO 6
|
||||||
#endif
|
#endif
|
||||||
#ifdef Cdrskin_libburn_0_7_7
|
#ifdef Cdrskin_libburn_0_8_7
|
||||||
#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 7
|
#define Cdrskin_libburn_micrO 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -364,9 +363,6 @@ or
|
|||||||
|
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_has_audioxtR
|
|
||||||
#include "../libburn/libdax_audioxtr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_has_cleanup_handleR
|
#ifdef Cdrskin_libburn_has_cleanup_handleR
|
||||||
#define Cleanup_set_handlers burn_set_signal_handling
|
#define Cleanup_set_handlers burn_set_signal_handling
|
||||||
@ -424,7 +420,7 @@ static int Cdrskin_abort_leveL= 0;
|
|||||||
/* Imported from scdbackup-0.8.5/src/cd_backup_planer.c */
|
/* Imported from scdbackup-0.8.5/src/cd_backup_planer.c */
|
||||||
|
|
||||||
/** Macro for creation of arrays of objects (or single objects) */
|
/** Macro for creation of arrays of objects (or single objects) */
|
||||||
#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ));
|
#define TSOB_FELD(typ,anz) (typ *) calloc(anz, sizeof(typ));
|
||||||
|
|
||||||
|
|
||||||
/** Convert a text so that eventual characters special to the shell are
|
/** Convert a text so that eventual characters special to the shell are
|
||||||
@ -574,7 +570,7 @@ int Sfile_multi_read_argv(char *progname, char **filenames, int filename_count,
|
|||||||
if(pass==0)
|
if(pass==0)
|
||||||
maxl= strlen(progname)+1;
|
maxl= strlen(progname)+1;
|
||||||
else {
|
else {
|
||||||
(*argv)[0]= (char *) malloc(strlen(progname)+1);
|
(*argv)[0]= (char *) calloc(1, strlen(progname)+1);
|
||||||
if((*argv)[0]==NULL)
|
if((*argv)[0]==NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
strcpy((*argv)[0],progname);
|
strcpy((*argv)[0],progname);
|
||||||
@ -605,7 +601,7 @@ int Sfile_multi_read_argv(char *progname, char **filenames, int filename_count,
|
|||||||
} else {
|
} else {
|
||||||
if(argcount >= *argc)
|
if(argcount >= *argc)
|
||||||
break;
|
break;
|
||||||
(*argv)[argcount]= (char *) malloc(l+1);
|
(*argv)[argcount]= (char *) calloc(1, l+1);
|
||||||
if((*argv)[argcount]==NULL)
|
if((*argv)[argcount]==NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
strcpy((*argv)[argcount],buf);
|
strcpy((*argv)[argcount],buf);
|
||||||
@ -619,9 +615,9 @@ int Sfile_multi_read_argv(char *progname, char **filenames, int filename_count,
|
|||||||
if(pass==0){
|
if(pass==0){
|
||||||
*argc= argcount;
|
*argc= argcount;
|
||||||
if(argcount>0) {
|
if(argcount>0) {
|
||||||
*argv= (char **) malloc(argcount*sizeof(char *));
|
*argv= (char **) calloc(argcount, sizeof(char *));
|
||||||
*argidx= (int *) malloc(argcount*sizeof(int));
|
*argidx= (int *) calloc(argcount, sizeof(int));
|
||||||
*arglno= (int *) malloc(argcount*sizeof(int));
|
*arglno= (int *) calloc(argcount, sizeof(int));
|
||||||
if(*argv==NULL || *argidx==NULL || *arglno==NULL)
|
if(*argv==NULL || *argidx==NULL || *arglno==NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
}
|
}
|
||||||
@ -821,8 +817,8 @@ int Cdradrtrn_add(struct CdradrtrN *trn, char *from, char *to, int flag)
|
|||||||
}
|
}
|
||||||
if(strlen(from)>=Cdrskin_adrleN || strlen(to)>=Cdrskin_adrleN)
|
if(strlen(from)>=Cdrskin_adrleN || strlen(to)>=Cdrskin_adrleN)
|
||||||
return(0);
|
return(0);
|
||||||
trn->from_address[cnt]= malloc(strlen(from_pt)+1);
|
trn->from_address[cnt]= calloc(1, strlen(from_pt)+1);
|
||||||
trn->to_address[cnt]= malloc(strlen(to_pt)+1);
|
trn->to_address[cnt]= calloc(1, strlen(to_pt)+1);
|
||||||
if(trn->from_address[cnt]==NULL ||
|
if(trn->from_address[cnt]==NULL ||
|
||||||
trn->to_address[cnt]==NULL)
|
trn->to_address[cnt]==NULL)
|
||||||
return(-2);
|
return(-2);
|
||||||
@ -4157,11 +4153,7 @@ int Cdrskin__is_aborting(int flag)
|
|||||||
{
|
{
|
||||||
if(Cdrskin_abort_leveL)
|
if(Cdrskin_abort_leveL)
|
||||||
return(-1);
|
return(-1);
|
||||||
#ifdef Cdrskin_signal_handler_return_2
|
|
||||||
return(burn_is_aborting(0));
|
return(burn_is_aborting(0));
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4192,11 +4184,7 @@ int Cdrskin_abort(struct CdrskiN *skin, int flag)
|
|||||||
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;
|
||||||
@ -4209,8 +4197,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
|
||||||
@ -4251,8 +4240,6 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
|||||||
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
||||||
ClN(fprintf(stderr,"cdrskin_debug: ABORT : Calling burn_abort()\n"));
|
ClN(fprintf(stderr,"cdrskin_debug: ABORT : Calling burn_abort()\n"));
|
||||||
|
|
||||||
#ifdef Cdrskin_signal_handler_return_2
|
|
||||||
|
|
||||||
Cdrskin_abort_leveL= -1;
|
Cdrskin_abort_leveL= -1;
|
||||||
if (!(flag & 1))
|
if (!(flag & 1))
|
||||||
burn_abort(-1, burn_abort_pacifier, "cdrskin: ");
|
burn_abort(-1, burn_abort_pacifier, "cdrskin: ");
|
||||||
@ -4260,16 +4247,6 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
|||||||
"cdrskin: ABORT : Urged drive worker threads to do emergency halt.\n");
|
"cdrskin: ABORT : Urged drive worker threads to do emergency halt.\n");
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
#endif /* Cdrskin_signal_handler_return_2 */
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
fprintf(stderr,"\n");
|
|
||||||
|
|
||||||
#else /* Cdrskin_libburn_has_burn_aborT */
|
#else /* Cdrskin_libburn_has_burn_aborT */
|
||||||
|
|
||||||
if(skin->grabbed_drive!=NULL) {
|
if(skin->grabbed_drive!=NULL) {
|
||||||
@ -4764,8 +4741,8 @@ int Cdrskin_scanbus(struct CdrskiN *skin, int flag)
|
|||||||
int *drives_busses= NULL;
|
int *drives_busses= NULL;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
drives_shown= malloc(skin->n_drives+1);
|
drives_shown= calloc(1, skin->n_drives+1);
|
||||||
drives_busses= malloc((skin->n_drives+1) * sizeof(int));
|
drives_busses= calloc((skin->n_drives+1), sizeof(int));
|
||||||
if(drives_shown == NULL || drives_busses == NULL)
|
if(drives_shown == NULL || drives_busses == NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
for(i=0;i<skin->n_drives;i++)
|
for(i=0;i<skin->n_drives;i++)
|
||||||
@ -5297,8 +5274,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;
|
||||||
@ -6920,7 +6897,7 @@ int Cdrskin_direct_write(struct CdrskiN *skin, int flag)
|
|||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
buf= malloc(max_chunksize);
|
buf= calloc(1, max_chunksize);
|
||||||
if(buf==NULL) {
|
if(buf==NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"cdrskin: FATAL : Cannot allocate %d bytes of read buffer.\n",
|
"cdrskin: FATAL : Cannot allocate %d bytes of read buffer.\n",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
|
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
|
||||||
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW, DVD+R, DVD+R/DL, DVD-RAM, BD-RE, BD-R, cdrecord, compatible, scdbackup">
|
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-R DL, DVD-RW, DVD+RW, DVD+R, DVD+R DL, DVD-RAM, BD-RE, BD-R, cdrecord, compatible, scdbackup">
|
||||||
<META NAME="robots" CONTENT="follow">
|
<META NAME="robots" CONTENT="follow">
|
||||||
<TITLE>cdrskin homepage english</TITLE>
|
<TITLE>cdrskin homepage english</TITLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
@ -24,7 +24,8 @@
|
|||||||
<P>
|
<P>
|
||||||
<H2>Purpose:</H2>
|
<H2>Purpose:</H2>
|
||||||
Burns preformatted data to CD, DVD, and BD media:<BR>
|
Burns preformatted data to CD, DVD, and BD media:<BR>
|
||||||
CD-R, DVD-R, DVD+R, DVD+R/DL, BD-R, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
CD-R, DVD-R, DVD-R DL, DVD+R, DVD+R DL, BD-R, CD-RW,
|
||||||
|
DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
||||||
</P>
|
</P>
|
||||||
<P>
|
<P>
|
||||||
|
|
||||||
@ -38,8 +39,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>
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||||||
<DT>or FreeBSD (with libc, of course) :</DT>
|
<DT>or FreeBSD (with libc, of course) :</DT>
|
||||||
<DD>ATA and SATA drives need atapicam running.</DD>
|
<DD>ATA and SATA drives need atapicam running.</DD>
|
||||||
<DD>libcam has to be installed.</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>
|
||||||
@ -62,7 +65,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.6</DT>
|
<DT>libburn-0.8.6</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)
|
||||||
@ -72,8 +75,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>
|
||||||
|
|
||||||
@ -93,10 +96,11 @@ Ports to other usable systems are appreciated. Reports are welcome.
|
|||||||
<DL>
|
<DL>
|
||||||
<DT>The most common options of cdrecord for data and audio on CD media
|
<DT>The most common options of cdrecord for data and audio on CD media
|
||||||
are provided in a compatible way.<BR>
|
are provided in a compatible way.<BR>
|
||||||
On all DVD media except DVD-R DL, cdrskin is able to perform any recording job
|
On all DVD media, cdrskin is able to perform any recording job
|
||||||
which is possible with cdrecord.
|
which is possible with cdrecord.
|
||||||
Other than with cdrecord, option -multi is supported with many DVD types and
|
Other than with cdrecord, option -multi is supported with many DVD types and
|
||||||
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW.
|
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW and
|
||||||
|
DVD-R DL, which both support no -multi.
|
||||||
</DT>
|
</DT>
|
||||||
<BR><BR>
|
<BR><BR>
|
||||||
<DT>Get an overview of drives and their addresses</DT>
|
<DT>Get an overview of drives and their addresses</DT>
|
||||||
@ -105,8 +109,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>
|
||||||
@ -128,7 +133,8 @@ as listed by option --devices.</DT>
|
|||||||
<DD>$<KBD> cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
|
<DD>$<KBD> cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
|
||||||
<DD><KBD> blank=as_needed -eject padsize=300k my_image.iso</KBD></DD>
|
<DD><KBD> blank=as_needed -eject padsize=300k my_image.iso</KBD></DD>
|
||||||
|
|
||||||
<DT>Write compressed afio archive on-the-fly:</DT>
|
<DT>Write compressed afio archive on-the-fly
|
||||||
|
(not DVD-R DL or minimally blanked DVD-RW):</DT>
|
||||||
<DD>$<KBD> find . | afio -oZ - | \</KBD></DD>
|
<DD>$<KBD> find . | afio -oZ - | \</KBD></DD>
|
||||||
<DD><KBD> cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
|
<DD><KBD> cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
|
||||||
<DD><KBD> blank=as_needed padsize=300k -</KBD></DD>
|
<DD><KBD> blank=as_needed padsize=300k -</KBD></DD>
|
||||||
@ -194,8 +200,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.6.pl00.tar.gz">cdrskin-0.7.6.pl00.tar.gz</A>
|
<DD><A HREF="cdrskin-0.8.6.pl00.tar.gz">cdrskin-0.8.6.pl00.tar.gz</A>
|
||||||
(820 KB).
|
(850 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
|
||||||
@ -244,22 +250,21 @@ 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.4.pl00:
|
Enhancements towards previous stable version cdrskin-0.8.4.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>
|
<LI>
|
||||||
Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
|
Lifted test reservation on DVD-R DL media.
|
||||||
</LI>
|
</LI>
|
||||||
<LI>Experimental system adapter via GNU libcdio on X/Open systems</LI>
|
|
||||||
<LI>Experimentally using FreeBSD system adapter for Debian kfreebsd</LI>
|
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-0.7.4.pl00:
|
Bug fixes towards cdrskin-0.8.4.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
<!--
|
<!--
|
||||||
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
@ -267,29 +272,31 @@ Bug fixes towards cdrskin-0.7.4.pl00:
|
|||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 0.7.7 :</H3></DT>
|
<DT><H3>Development snapshot, version 0.8.7 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 0.7.6.pl00:
|
<DD>Enhancements towards current stable version 0.8.6.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD>Bug fixes towards cdrskin-0.7.6.pl00:
|
<DD>Bug fixes towards cdrskin-0.8.6.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 0.7.7</A>
|
<DD><A HREF="README_cdrskin_devel">README 0.8.7</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.7 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin_0.8.7 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.7 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin_0.8.7 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.7)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.8.7)</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>
|
||||||
@ -309,8 +316,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.7.tar.gz">cdrskin-0.7.7.tar.gz</A>
|
<A HREF="cdrskin-0.8.7.tar.gz">cdrskin-0.8.7.tar.gz</A>
|
||||||
(820 KB).
|
(850 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 "2010.03.09.140341"
|
#define Cdrskin_timestamP "2010.09.16.113001"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ 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=""
|
fifo_opts=""
|
||||||
libvers="-DCdrskin_libburn_0_7_7"
|
libvers="-DCdrskin_libburn_0_8_6"
|
||||||
|
|
||||||
# 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-"
|
||||||
@ -47,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_6"
|
elif test "$i" = "-libburn_0_8_6"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_7_6"
|
libvers="-DCdrskin_libburn_0_8_6"
|
||||||
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_7"
|
libvers="-DCdrskin_libburn_0_8_7"
|
||||||
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
|
||||||
@ -109,7 +109,7 @@ 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_6 set macro to match libburn-0.7.6"
|
echo " -libburn_0_8_6 set macro to match libburn-0.8.6"
|
||||||
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 " -use_libcdio link with -lcdio because libburn uses it."
|
||||||
|
45
configure.ac
45
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libburn], [0.7.7], [http://libburnia-project.org])
|
AC_INIT([libburn], [0.8.6], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ LIBBURNIA_SET_FLAGS
|
|||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
|
||||||
dnl Notes by ts A71207 - B00122 :
|
dnl Notes by ts A71207 - B00630 :
|
||||||
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.
|
||||||
@ -79,6 +79,11 @@ 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.4 = libburn.so.4.39.0
|
||||||
dnl 0.7.6 = libburn.so.4.41.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 0.8.4 = libburn.so.4.49.0
|
||||||
|
dnl 0.8.6 = libburn.so.4.51.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.
|
||||||
@ -103,8 +108,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=7
|
BURN_MICRO_VERSION=6
|
||||||
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)
|
||||||
@ -115,15 +120,14 @@ 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 B00122
|
dnl ### This is the release version libburn-0.8.6
|
||||||
dnl ### This is the release version libburn-0.7.6 = libburn.so.4.41.0
|
|
||||||
dnl This is the development version after above release version
|
dnl This is the development version after above release version
|
||||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 45 - 41 = 4 . Linux library name = libburn.so.4.41.0
|
dnl SONAME = 55 - 51 = 4 . Linux library name = libburn.so.4.51.0
|
||||||
LT_CURRENT=45
|
LT_CURRENT=55
|
||||||
LT_AGE=41
|
LT_AGE=51
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
@ -201,7 +205,7 @@ 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"
|
||||||
@ -239,6 +243,27 @@ else
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ts B00704
|
||||||
|
# Library versioning normally serves a complex purpose.
|
||||||
|
# Since libburn obeys strict ABI backward compatibility, it needs only the
|
||||||
|
# simple feature to declare function names "global:" or "local:". Only the
|
||||||
|
# global ones are visible to applications at library load time.
|
||||||
|
AC_ARG_ENABLE(versioned-libs,
|
||||||
|
[ --enable-versioned-libs Enable strict symbol encapsulation , default=yes],
|
||||||
|
, enable_versioned_libs=yes)
|
||||||
|
if test x$enable_versioned_libs = xyes; then
|
||||||
|
vers_libs_test=no
|
||||||
|
LIBBURN_ASSERT_VERS_LIBS
|
||||||
|
if test x$vers_libs_test = xno
|
||||||
|
then
|
||||||
|
echo "disabled strict symbol encapsulation (test failed)"
|
||||||
|
else
|
||||||
|
echo "enabled strict symbol encapsulation"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "disabled strict symbol encapsulation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl Add compiler-specific flags
|
dnl Add compiler-specific flags
|
||||||
|
|
||||||
|
@ -154,13 +154,6 @@ QT_AUTOBRIEF = NO
|
|||||||
|
|
||||||
MULTILINE_CPP_IS_BRIEF = YES
|
MULTILINE_CPP_IS_BRIEF = YES
|
||||||
|
|
||||||
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
|
|
||||||
# will output the detailed description near the top, like JavaDoc.
|
|
||||||
# If set to NO, the detailed description appears after the member
|
|
||||||
# documentation.
|
|
||||||
|
|
||||||
DETAILS_AT_TOP = YES
|
|
||||||
|
|
||||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||||
# member inherits the documentation from any documented member that it
|
# member inherits the documentation from any documented member that it
|
||||||
# re-implements.
|
# re-implements.
|
||||||
|
@ -23,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"
|
||||||
@ -140,7 +143,7 @@ static void add_worker(int w_type, struct burn_drive *d,
|
|||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
a = malloc(sizeof(struct w_list));
|
a = calloc(1, sizeof(struct w_list));
|
||||||
a->w_type = w_type;
|
a->w_type = w_type;
|
||||||
a->drive = d;
|
a->drive = d;
|
||||||
a->u = *(union w_list_data *)data;
|
a->u = *(union w_list_data *)data;
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
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>
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
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>
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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 GNU/Linux man 3 malloc */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -1293,7 +1294,7 @@ int burn_drive_add_whitelist(char *device_address)
|
|||||||
if(enumeration_whitelist_top+1 >= BURN_DRIVE_WHITELIST_LEN)
|
if(enumeration_whitelist_top+1 >= BURN_DRIVE_WHITELIST_LEN)
|
||||||
return 0;
|
return 0;
|
||||||
enumeration_whitelist_top++;
|
enumeration_whitelist_top++;
|
||||||
new_item = malloc(strlen(device_address) + 1);
|
new_item = calloc(1, strlen(device_address) + 1);
|
||||||
if (new_item == NULL)
|
if (new_item == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
strcpy(new_item, device_address);
|
strcpy(new_item, device_address);
|
||||||
@ -2217,7 +2218,7 @@ int burn_speed_descriptor_new(struct burn_speed_descriptor **s,
|
|||||||
{
|
{
|
||||||
struct burn_speed_descriptor *o;
|
struct burn_speed_descriptor *o;
|
||||||
|
|
||||||
(*s) = o = malloc(sizeof(struct burn_speed_descriptor));
|
(*s) = o = calloc(1, sizeof(struct burn_speed_descriptor));
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
o->source = 0;
|
o->source = 0;
|
||||||
@ -2388,7 +2389,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
if(s == BURN_DISC_UNGRABBED)
|
if(s == BURN_DISC_UNGRABBED)
|
||||||
return -1;
|
return -1;
|
||||||
*caps = o = (struct burn_multi_caps *)
|
*caps = o = (struct burn_multi_caps *)
|
||||||
malloc(sizeof(struct burn_multi_caps));
|
calloc(1, sizeof(struct burn_multi_caps));
|
||||||
if(*caps == NULL)
|
if(*caps == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
/* Default says nothing is available */
|
/* Default says nothing is available */
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
/* -*- 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
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -125,7 +129,7 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs = malloc(sizeof(struct burn_source_file));
|
fs = calloc(1, sizeof(struct burn_source_file));
|
||||||
|
|
||||||
/* ts A70825 */
|
/* ts A70825 */
|
||||||
if (fs == NULL) {
|
if (fs == NULL) {
|
||||||
@ -171,7 +175,7 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
|||||||
|
|
||||||
if (datafd == -1)
|
if (datafd == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs = malloc(sizeof(struct burn_source_file));
|
fs = calloc(1, sizeof(struct burn_source_file));
|
||||||
if (fs == NULL) /* ts A70825 */
|
if (fs == NULL) /* ts A70825 */
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->datafd = datafd;
|
fs->datafd = datafd;
|
||||||
@ -399,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);
|
||||||
@ -500,7 +508,7 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
|||||||
"Desired fifo buffer too small", 0, 0);
|
"Desired fifo buffer too small", 0, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fs = malloc(sizeof(struct burn_source_fifo));
|
fs = calloc(1, sizeof(struct burn_source_fifo));
|
||||||
if (fs == NULL)
|
if (fs == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->is_started = 0;
|
fs->is_started = 0;
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -338,7 +342,7 @@ char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
|||||||
{
|
{
|
||||||
int i, l;
|
int i, l;
|
||||||
|
|
||||||
sprintf(text, "[%d,", getpid());
|
sprintf(text, "[%lu,", (unsigned long int) getpid());
|
||||||
l= strlen(text);
|
l= strlen(text);
|
||||||
for(i= 0; i < sizeof(pthread_t) && 2 * i < 80 - l - 3; i++)
|
for(i= 0; i < sizeof(pthread_t) && 2 * i < 80 - l - 3; i++)
|
||||||
sprintf(text + l + 2 * i,
|
sprintf(text + l + 2 * i,
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
This is the official API definition of libburn.
|
This is the official API definition of libburn.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
/* Important: If you add a public API function then add its name to file
|
||||||
|
libburn/libburn.ver
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef LIBBURN_H
|
#ifndef LIBBURN_H
|
||||||
@ -825,7 +828,7 @@ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
|
|||||||
/* ts A70223 */
|
/* ts A70223 */
|
||||||
/** Allows the use of media types which are implemented in libburn but not yet
|
/** Allows the use of media types which are implemented in libburn but not yet
|
||||||
tested. The list of those untested profiles is subject to change.
|
tested. The list of those untested profiles is subject to change.
|
||||||
Currently it contains: 0x15 "DVD-R/DL sequential recording",
|
- Currently no media types are under test reservation -
|
||||||
If you really test such media, then please report the outcome on
|
If you really test such media, then please report the outcome on
|
||||||
libburn-hackers@pykix.org
|
libburn-hackers@pykix.org
|
||||||
If ever then this call should be done soon after burn_initialize() before
|
If ever then this call should be done soon after burn_initialize() before
|
||||||
@ -1293,16 +1296,20 @@ off_t burn_disc_available_space(struct burn_drive *d,
|
|||||||
/** Tells the MMC Profile identifier of the loaded media. The drive must be
|
/** Tells the MMC Profile identifier of the loaded media. The drive must be
|
||||||
grabbed in order to get a non-zero result.
|
grabbed in order to get a non-zero result.
|
||||||
libburn currently writes only to profiles
|
libburn currently writes only to profiles
|
||||||
0x09 "CD-R", 0x0a "CD-RW",
|
0x09 "CD-R"
|
||||||
0x11 "DVD-R sequential recording", 0x12 "DVD-RAM",
|
0x0a "CD-RW"
|
||||||
0x13 "DVD-RW restricted overwrite", 0x14 "DVD-RW sequential recording",
|
0x11 "DVD-R sequential recording"
|
||||||
0x1a "DVD+RW", 0x1b "DVD+R",
|
0x12 "DVD-RAM"
|
||||||
|
0x13 "DVD-RW restricted overwrite"
|
||||||
|
0x14 "DVD-RW sequential recording",
|
||||||
|
0x15 "DVD-R/DL sequential recording",
|
||||||
|
0x1a "DVD+RW"
|
||||||
|
0x1b "DVD+R",
|
||||||
0x2b "DVD+R/DL",
|
0x2b "DVD+R/DL",
|
||||||
0x41 "BD-R sequential recording", 0x43 "BD-RE",
|
0x41 "BD-R sequential recording",
|
||||||
|
0x43 "BD-RE",
|
||||||
0xffff "stdio file"
|
0xffff "stdio file"
|
||||||
Note: 0xffff is not a MMC profile but a libburn invention.
|
Note: 0xffff is not a MMC profile but a libburn invention.
|
||||||
If enabled by burn_allow_untested_profiles() it also writes to profiles
|
|
||||||
0x15 "DVD-R/DL sequential recording",
|
|
||||||
Read-only are the profiles
|
Read-only are the profiles
|
||||||
0x08 "CD-ROM", 0x10 "DVD-ROM",
|
0x08 "CD-ROM", 0x10 "DVD-ROM",
|
||||||
0x40 "BD-ROM",
|
0x40 "BD-ROM",
|
||||||
@ -2191,6 +2198,10 @@ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned cha
|
|||||||
/* ts A61106 */
|
/* ts A61106 */
|
||||||
/** Sets the multi flag which eventually marks the emerging session as not
|
/** Sets the multi flag which eventually marks the emerging session as not
|
||||||
being the last one and thus creating a BURN_DISC_APPENDABLE media.
|
being the last one and thus creating a BURN_DISC_APPENDABLE media.
|
||||||
|
Note: DVD-R[W] in write mode BURN_WRITE_SAO are not capable of this.
|
||||||
|
DVD-R DL are not capable of this at all.
|
||||||
|
libburn will refuse to write if burn_write_opts_set_multi() is
|
||||||
|
enabled under such conditions.
|
||||||
@param opts The option object to be manipulated
|
@param opts The option object to be manipulated
|
||||||
@param multi 1=media will be appendable, 0=media will be closed (default)
|
@param multi 1=media will be appendable, 0=media will be closed (default)
|
||||||
@since 0.2.6
|
@since 0.2.6
|
||||||
@ -2627,8 +2638,8 @@ void burn_version(int *major, int *minor, int *micro);
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#define burn_header_version_major 0
|
#define burn_header_version_major 0
|
||||||
#define burn_header_version_minor 7
|
#define burn_header_version_minor 8
|
||||||
#define burn_header_version_micro 7
|
#define burn_header_version_micro 6
|
||||||
/** 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.
|
||||||
@ -2682,7 +2693,7 @@ These two advises are mutually exclusive.
|
|||||||
/** Obtain the id string of the SCSI transport interface.
|
/** Obtain the id string of the SCSI transport interface.
|
||||||
This interface may be a system specific adapter module of libburn or
|
This interface may be a system specific adapter module of libburn or
|
||||||
an adapter to a supporting library like libcdio.
|
an adapter to a supporting library like libcdio.
|
||||||
@flag Bitfield for control puposes, submit 0 for now
|
@param flag Bitfield for control puposes, submit 0 for now
|
||||||
@return A pointer to the id string. Do not alter the string content.
|
@return A pointer to the id string. Do not alter the string content.
|
||||||
@since 0.7.6
|
@since 0.7.6
|
||||||
*/
|
*/
|
||||||
@ -2716,7 +2727,7 @@ int burn_msgs_set_severities(char *queue_severity,
|
|||||||
"DEBUG", "ALL".
|
"DEBUG", "ALL".
|
||||||
To call with minimum_severity "NEVER" will discard the
|
To call with minimum_severity "NEVER" will discard the
|
||||||
whole queue.
|
whole queue.
|
||||||
@param error_code Will become a unique error code as liste in
|
@param error_code Will become a unique error code as listed in
|
||||||
libburn/libdax_msgs.h
|
libburn/libdax_msgs.h
|
||||||
@param msg_text Must provide at least BURN_MSGS_MESSAGE_LEN bytes.
|
@param msg_text Must provide at least BURN_MSGS_MESSAGE_LEN bytes.
|
||||||
@param os_errno Will become the eventual errno related to the message
|
@param os_errno Will become the eventual errno related to the message
|
||||||
@ -2811,7 +2822,7 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
|
|||||||
But during burn_disc_write() onto real CD or DVD, FreeBSD 8.0 pauses the
|
But during burn_disc_write() onto real CD or DVD, FreeBSD 8.0 pauses the
|
||||||
other threads until the signal handler returns.
|
other threads until the signal handler returns.
|
||||||
The new actions try to avoid this deadlock. It is advised to use action 3
|
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():
|
at least during burn_disc_write(), burn_disc_erase(), burn_disc_format():
|
||||||
burn_set_signal_handling(text, NULL, 0x30);
|
burn_set_signal_handling(text, NULL, 0x30);
|
||||||
and to call burn_is_aborting(0) when the drive is BURN_DRIVE_IDLE.
|
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).
|
If burn_is_aborting(0) returns 1, then call burn_abort() and exit(1).
|
||||||
@ -2980,6 +2991,110 @@ int burn_drive_get_drive_role(struct burn_drive *d);
|
|||||||
int burn_drive_equals_adr(struct burn_drive *d1, char *adr2, int drive_role2);
|
int burn_drive_equals_adr(struct burn_drive *d1, char *adr2, int drive_role2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Audio track data extraction facility.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Maximum size for address paths and fmt_info strings */
|
||||||
|
#define LIBDAX_AUDIOXTR_STRLEN 4096
|
||||||
|
|
||||||
|
|
||||||
|
/** Extractor object encapsulating intermediate states of extraction.
|
||||||
|
The clients of libdax_audioxtr shall only allocate pointers to this
|
||||||
|
struct and get a storage object via libdax_audioxtr_new().
|
||||||
|
Appropriate initial value for the pointer is NULL.
|
||||||
|
*/
|
||||||
|
struct libdax_audioxtr;
|
||||||
|
|
||||||
|
|
||||||
|
/** Open an audio file, check wether suitable, create extractor object.
|
||||||
|
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
||||||
|
@param path Address of the audio file to extract. "-" is stdin (but might
|
||||||
|
be not suitable for all futurely supported formats).
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success
|
||||||
|
0 unsuitable format
|
||||||
|
-1 severe error
|
||||||
|
-2 path not found
|
||||||
|
@since 0.2.4
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain identification parameters of opened audio source.
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param fmt Gets pointed to the audio file format id text: ".wav" , ".au"
|
||||||
|
@param fmt_info Gets pointed to a format info text telling parameters
|
||||||
|
@param num_channels e.g. 1=mono, 2=stereo, etc
|
||||||
|
@param sample_rate e.g. 11025, 44100
|
||||||
|
@param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ...
|
||||||
|
@param msb_first Byte order of samples: 0=Intel 1=Motorola
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success, <=0 failure
|
||||||
|
@since 0.2.4
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr,
|
||||||
|
char **fmt, char **fmt_info,
|
||||||
|
int *num_channels, int *sample_rate,
|
||||||
|
int *bits_per_sample, int *msb_first, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain a prediction about the extracted size based on internal information
|
||||||
|
of the formatted file.
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param size Gets filled with the predicted size
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 prediction was possible , 0 no prediction could be made
|
||||||
|
@since 0.2.4
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain next buffer full of extracted data in desired format (only raw audio
|
||||||
|
for now).
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param buffer Gets filled with extracted data
|
||||||
|
@param buffer_size Maximum number of bytes to be filled into buffer
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= do not stop at predicted end of data
|
||||||
|
@return >0 number of valid buffer bytes,
|
||||||
|
0 End of file
|
||||||
|
-1 operating system reports error
|
||||||
|
-2 usage error by application
|
||||||
|
@since 0.2.4
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
|
||||||
|
char buffer[], int buffer_size, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Try to obtain a file descriptor which will deliver extracted data
|
||||||
|
to normal calls of read(2). This may fail because the format is
|
||||||
|
unsuitable for that, but ".wav" is ok. If this call succeeds the xtr
|
||||||
|
object will have forgotten its file descriptor and libdax_audioxtr_read()
|
||||||
|
will return a usage error. One may use *fd after libdax_audioxtr_destroy()
|
||||||
|
and will have to close it via close(2) when done with it.
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param fd Eventually returns the file descriptor number
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= do not dup(2) and close(2) but hand out original fd
|
||||||
|
@return 1 success, 0 cannot hand out fd , -1 severe error
|
||||||
|
@since 0.2.4
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Clean up after extraction and destroy extractor object.
|
||||||
|
@param xtr Opaque handle to extractor, *xtr is allowed to be NULL,
|
||||||
|
*xtr is set to NULL by this function
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 = destroyed object, 0 = was already destroyed
|
||||||
|
@since 0.2.4
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DOXYGEN
|
#ifndef DOXYGEN
|
||||||
|
|
||||||
BURN_END_DECLS
|
BURN_END_DECLS
|
||||||
|
165
libburn/libburn.ver
Normal file
165
libburn/libburn.ver
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
LIBBURN4 {
|
||||||
|
global:
|
||||||
|
burn_abort;
|
||||||
|
burn_abort_pacifier;
|
||||||
|
burn_allow_untested_profiles;
|
||||||
|
burn_disc_add_session;
|
||||||
|
burn_disc_available_space;
|
||||||
|
burn_disc_create;
|
||||||
|
burn_disc_erasable;
|
||||||
|
burn_disc_erase;
|
||||||
|
burn_disc_format;
|
||||||
|
burn_disc_free;
|
||||||
|
burn_disc_free_multi_caps;
|
||||||
|
burn_disc_get_cd_info;
|
||||||
|
burn_disc_get_format_descr;
|
||||||
|
burn_disc_get_formats;
|
||||||
|
burn_disc_get_media_id;
|
||||||
|
burn_disc_get_msc1;
|
||||||
|
burn_disc_get_multi_caps;
|
||||||
|
burn_disc_get_profile;
|
||||||
|
burn_disc_get_sectors;
|
||||||
|
burn_disc_get_sessions;
|
||||||
|
burn_disc_get_status;
|
||||||
|
burn_disc_pretend_blank;
|
||||||
|
burn_disc_pretend_full;
|
||||||
|
burn_disc_read;
|
||||||
|
burn_disc_read_atip;
|
||||||
|
burn_disc_remove_session;
|
||||||
|
burn_disc_track_lba_nwa;
|
||||||
|
burn_disc_write;
|
||||||
|
burn_drive_add_whitelist;
|
||||||
|
burn_drive_cancel;
|
||||||
|
burn_drive_clear_whitelist;
|
||||||
|
burn_drive_convert_fs_adr;
|
||||||
|
burn_drive_convert_scsi_adr;
|
||||||
|
burn_drive_d_get_adr;
|
||||||
|
burn_drive_equals_adr;
|
||||||
|
burn_drive_free_speedlist;
|
||||||
|
burn_drive_get_adr;
|
||||||
|
burn_drive_get_all_profiles;
|
||||||
|
burn_drive_get_best_speed;
|
||||||
|
burn_drive_get_disc;
|
||||||
|
burn_drive_get_drive_role;
|
||||||
|
burn_drive_get_min_write_speed;
|
||||||
|
burn_drive_get_read_speed;
|
||||||
|
burn_drive_get_speedlist;
|
||||||
|
burn_drive_get_start_end_lba;
|
||||||
|
burn_drive_get_status;
|
||||||
|
burn_drive_get_write_speed;
|
||||||
|
burn_drive_grab;
|
||||||
|
burn_drive_info_forget;
|
||||||
|
burn_drive_info_free;
|
||||||
|
burn_drive_is_enumerable_adr;
|
||||||
|
burn_drive_leave_locked;
|
||||||
|
burn_drive_obtain_scsi_adr;
|
||||||
|
burn_drive_probe_cd_write_modes;
|
||||||
|
burn_drive_release;
|
||||||
|
burn_drive_scan;
|
||||||
|
burn_drive_scan_and_grab;
|
||||||
|
burn_drive_set_buffer_waiting;
|
||||||
|
burn_drive_set_speed;
|
||||||
|
burn_drive_set_stream_recording;
|
||||||
|
burn_drive_snooze;
|
||||||
|
burn_drive_wrote_well;
|
||||||
|
burn_fd_source_new;
|
||||||
|
burn_fifo_fill;
|
||||||
|
burn_fifo_get_statistics;
|
||||||
|
burn_fifo_inquire_status;
|
||||||
|
burn_fifo_next_interval;
|
||||||
|
burn_fifo_peek_data;
|
||||||
|
burn_fifo_source_new;
|
||||||
|
burn_file_source_new;
|
||||||
|
burn_finish;
|
||||||
|
burn_get_read_capacity;
|
||||||
|
burn_guess_cd_manufacturer;
|
||||||
|
burn_guess_manufacturer;
|
||||||
|
burn_initialize;
|
||||||
|
burn_is_aborting;
|
||||||
|
burn_lba_to_msf;
|
||||||
|
burn_msf_to_lba;
|
||||||
|
burn_msf_to_sectors;
|
||||||
|
burn_msgs_obtain;
|
||||||
|
burn_msgs_set_severities;
|
||||||
|
burn_msgs_submit;
|
||||||
|
burn_obtain_profile_name;
|
||||||
|
burn_os_alloc_buffer;
|
||||||
|
burn_os_free_buffer;
|
||||||
|
burn_os_open_track_src;
|
||||||
|
burn_precheck_write;
|
||||||
|
burn_preset_device_open;
|
||||||
|
burn_random_access_write;
|
||||||
|
burn_read_data;
|
||||||
|
burn_read_opts_free;
|
||||||
|
burn_read_opts_new;
|
||||||
|
burn_read_opts_read_subcodes_audio;
|
||||||
|
burn_read_opts_read_subcodes_data;
|
||||||
|
burn_read_opts_report_recovered_errors;
|
||||||
|
burn_read_opts_set_c2errors;
|
||||||
|
burn_read_opts_set_hardware_error_recovery;
|
||||||
|
burn_read_opts_set_hardware_error_retries;
|
||||||
|
burn_read_opts_set_raw;
|
||||||
|
burn_read_opts_transfer_damaged_blocks;
|
||||||
|
burn_scsi_transport_id;
|
||||||
|
burn_sectors_to_msf;
|
||||||
|
burn_session_add_track;
|
||||||
|
burn_session_create;
|
||||||
|
burn_session_free;
|
||||||
|
burn_session_get_hidefirst;
|
||||||
|
burn_session_get_leadout_entry;
|
||||||
|
burn_session_get_sectors;
|
||||||
|
burn_session_get_tracks;
|
||||||
|
burn_session_hide_first_track;
|
||||||
|
burn_session_remove_track;
|
||||||
|
burn_set_messenger;
|
||||||
|
burn_set_scsi_logging;
|
||||||
|
burn_set_signal_handling;
|
||||||
|
burn_set_verbosity;
|
||||||
|
burn_sev_to_text;
|
||||||
|
burn_source_free;
|
||||||
|
burn_structure_print_disc;
|
||||||
|
burn_structure_print_session;
|
||||||
|
burn_structure_print_track;
|
||||||
|
burn_text_to_sev;
|
||||||
|
burn_track_clear_isrc;
|
||||||
|
burn_track_create;
|
||||||
|
burn_track_define_data;
|
||||||
|
burn_track_free;
|
||||||
|
burn_track_get_counters;
|
||||||
|
burn_track_get_entry;
|
||||||
|
burn_track_get_mode;
|
||||||
|
burn_track_get_sectors;
|
||||||
|
burn_track_set_byte_swap;
|
||||||
|
burn_track_set_cdxa_conv;
|
||||||
|
burn_track_set_default_size;
|
||||||
|
burn_track_set_isrc;
|
||||||
|
burn_track_set_size;
|
||||||
|
burn_track_set_source;
|
||||||
|
burn_version;
|
||||||
|
burn_write_opts_auto_write_type;
|
||||||
|
burn_write_opts_free;
|
||||||
|
burn_write_opts_get_drive;
|
||||||
|
burn_write_opts_new;
|
||||||
|
burn_write_opts_set_dvd_obs;
|
||||||
|
burn_write_opts_set_fillup;
|
||||||
|
burn_write_opts_set_force;
|
||||||
|
burn_write_opts_set_format;
|
||||||
|
burn_write_opts_set_has_mediacatalog;
|
||||||
|
burn_write_opts_set_mediacatalog;
|
||||||
|
burn_write_opts_set_multi;
|
||||||
|
burn_write_opts_set_perform_opc;
|
||||||
|
burn_write_opts_set_simulate;
|
||||||
|
burn_write_opts_set_start_byte;
|
||||||
|
burn_write_opts_set_stdio_fsync;
|
||||||
|
burn_write_opts_set_stream_recording;
|
||||||
|
burn_write_opts_set_toc_entries;
|
||||||
|
burn_write_opts_set_underrun_proof;
|
||||||
|
burn_write_opts_set_write_type;
|
||||||
|
libdax_audioxtr_destroy;
|
||||||
|
libdax_audioxtr_detach_fd;
|
||||||
|
libdax_audioxtr_get_id;
|
||||||
|
libdax_audioxtr_get_size;
|
||||||
|
libdax_audioxtr_new;
|
||||||
|
libdax_audioxtr_read;
|
||||||
|
local: *;
|
||||||
|
};
|
@ -4,6 +4,10 @@
|
|||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
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>
|
||||||
@ -21,7 +25,8 @@ extern struct libdax_msgs *libdax_messenger;
|
|||||||
/* Only this single source module is entitled to do this */
|
/* Only this single source module is entitled to do this */
|
||||||
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
|
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
|
||||||
|
|
||||||
/* All clients of the extraction facility must do this */
|
/* All clients of the extraction facility must do this or include libburn.h */
|
||||||
|
#define LIBDAX_AUDIOXTR_H_PUBLIC 1
|
||||||
#include "libdax_audioxtr.h"
|
#include "libdax_audioxtr.h"
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +35,7 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
|||||||
int ret= -1;
|
int ret= -1;
|
||||||
struct libdax_audioxtr *o;
|
struct libdax_audioxtr *o;
|
||||||
|
|
||||||
o= *xtr= (struct libdax_audioxtr *) malloc(sizeof(struct libdax_audioxtr));
|
o= *xtr= (struct libdax_audioxtr *) calloc(1, sizeof(struct libdax_audioxtr));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
||||||
|
@ -7,6 +7,13 @@
|
|||||||
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
||||||
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
|
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Normally this public API is defined in <libburn/libburn.h>
|
||||||
|
Macro LIBDAX_AUDIOXTR_H_PUBLIC enables the definition for programs
|
||||||
|
which only include this file.
|
||||||
|
*/
|
||||||
|
#ifdef LIBDAX_AUDIOXTR_H_PUBLIC
|
||||||
|
|
||||||
/* Public Macros */
|
/* Public Macros */
|
||||||
|
|
||||||
/* Maximum size for address paths and fmt_info strings */
|
/* Maximum size for address paths and fmt_info strings */
|
||||||
@ -110,15 +117,16 @@ int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag);
|
|||||||
*/
|
*/
|
||||||
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
||||||
|
|
||||||
|
#endif /* LIBDAX_AUDIOXTR_H_PUBLIC */
|
||||||
|
|
||||||
|
|
||||||
#ifdef LIDBAX_AUDIOXTR________________
|
#ifdef LIBDAX_AUDIOXTR________________
|
||||||
|
|
||||||
|
|
||||||
-- place documentation text here ---
|
-- place documentation text here ---
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIDBAX_AUDIOXTR_________________ */
|
#endif /* LIBDAX_AUDIOXTR_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
provided under GPL version 2 or later.
|
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>
|
||||||
@ -33,7 +37,7 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
|
|||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
|
|
||||||
(*item)= o=
|
(*item)= o=
|
||||||
(struct libdax_msgs_item *) malloc(sizeof(struct libdax_msgs_item));
|
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->timestamp= 0.0;
|
o->timestamp= 0.0;
|
||||||
@ -136,7 +140,7 @@ int libdax_msgs_new(struct libdax_msgs **m, int flag)
|
|||||||
{
|
{
|
||||||
struct libdax_msgs *o;
|
struct libdax_msgs *o;
|
||||||
|
|
||||||
(*m)= o= (struct libdax_msgs *) malloc(sizeof(struct libdax_msgs));
|
(*m)= o= (struct libdax_msgs *) calloc(1, sizeof(struct libdax_msgs));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->refcount= 1;
|
o->refcount= 1;
|
||||||
@ -366,7 +370,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
|||||||
item->severity= severity;
|
item->severity= severity;
|
||||||
item->priority= priority;
|
item->priority= priority;
|
||||||
if(msg_text!=NULL) {
|
if(msg_text!=NULL) {
|
||||||
item->msg_text= malloc(strlen(msg_text)+1);
|
item->msg_text= calloc(1, strlen(msg_text)+1);
|
||||||
if(item->msg_text==NULL)
|
if(item->msg_text==NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
strcpy(item->msg_text,msg_text);
|
strcpy(item->msg_text,msg_text);
|
||||||
|
@ -395,7 +395,7 @@ int libdax_msgs_item_get_rank(struct libdax_msgs_item *item,
|
|||||||
int *severity, int *priority, int flag);
|
int *severity, int *priority, int flag);
|
||||||
|
|
||||||
|
|
||||||
#ifdef LIDBAX_MSGS_________________
|
#ifdef LIBDAX_MSGS_________________
|
||||||
|
|
||||||
|
|
||||||
/* Registered Error Codes */
|
/* Registered Error Codes */
|
||||||
@ -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:
|
||||||
|
|
||||||
@ -677,7 +679,7 @@ Range "libisoburn" : 0x00060000 to 0x00006ffff
|
|||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif /* LIDBAX_MSGS_________________ */
|
#endif /* LIBDAX_MSGS_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
106
libburn/mmc.c
106
libburn/mmc.c
@ -5,6 +5,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
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> */
|
||||||
@ -425,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;
|
||||||
@ -805,7 +813,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
{
|
{
|
||||||
int cancelled;
|
int cancelled;
|
||||||
struct command c;
|
struct command c;
|
||||||
int len;
|
int len, key, asc, ascq;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* <<< ts A61031 */
|
||||||
@ -884,33 +892,20 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
d->pbf_altered = 1;
|
d->pbf_altered = 1;
|
||||||
|
|
||||||
/* ts A61112 : react on eventual error condition */
|
/* ts A61112 : react on eventual error condition */
|
||||||
if (c.error && c.sense[2]!=0) {
|
spc_decode_sense(c.sense, 0, &key, &asc, &ascq);
|
||||||
|
if (c.error && key != 0) {
|
||||||
|
|
||||||
/* >>> make this scsi_notify_error() when liberated */
|
/* >>> make this scsi_notify_error() when liberated */
|
||||||
if (c.sense[2]!=0) {
|
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
char msg[160];
|
|
||||||
sprintf(msg,
|
|
||||||
"SCSI error on write(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
|
||||||
start, len,
|
|
||||||
c.sense[2],c.sense[12],c.sense[13]);
|
|
||||||
#else /* NIX */
|
|
||||||
char msg[256];
|
char msg[256];
|
||||||
int key, asc, ascq;
|
int key, asc, ascq;
|
||||||
|
|
||||||
sprintf(msg, "SCSI error on write(%d,%d): ",
|
sprintf(msg, "SCSI error on write(%d,%d): ", start, len);
|
||||||
start, len);
|
|
||||||
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
&key, &asc, &ascq);
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
#endif /* !NIX */
|
|
||||||
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002011d,
|
0x0002011d,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
}
|
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
return BE_CANCELLED;
|
return BE_CANCELLED;
|
||||||
}
|
}
|
||||||
@ -1157,7 +1152,7 @@ int mmc_fake_toc(struct burn_drive *d)
|
|||||||
if (d->disc == NULL)
|
if (d->disc == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
d->toc_entries = d->last_track_no + d->complete_sessions;
|
d->toc_entries = d->last_track_no + d->complete_sessions;
|
||||||
d->toc_entry = malloc(d->toc_entries * sizeof(struct burn_toc_entry));
|
d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
|
||||||
if (d->toc_entry == NULL)
|
if (d->toc_entry == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry));
|
memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry));
|
||||||
@ -1396,6 +1391,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;
|
||||||
@ -1404,9 +1404,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) {
|
||||||
@ -1743,12 +1744,6 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->erasable = 0; /* never erasable */
|
d->erasable = 0; /* never erasable */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A80207 : DVD - R DL can normally be read but not be written */
|
|
||||||
if(d->current_profile == 0x15 && !burn_support_untested_profiles) {
|
|
||||||
disc_status = 2; /* always full and finalized */
|
|
||||||
d->erasable = 0; /* never erasable */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Libburn_support_bd_r_readonlY
|
#ifdef Libburn_support_bd_r_readonlY
|
||||||
/* <<< For now: declaring BD-R read-only
|
/* <<< For now: declaring BD-R read-only
|
||||||
*/
|
*/
|
||||||
@ -1964,8 +1959,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;
|
||||||
@ -2315,7 +2315,8 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||||||
|
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
if (c.sense[2]!=0 && !d->silent_on_scsi_error) {
|
spc_decode_sense(c.sense, 0, &key, &asc, &ascq);
|
||||||
|
if (key != 0 && !d->silent_on_scsi_error) {
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"SCSI error on set_streaming(%d): ", w_speed);
|
"SCSI error on set_streaming(%d): ", w_speed);
|
||||||
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
@ -2395,7 +2396,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
{
|
{
|
||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1;
|
int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1;
|
||||||
int old_alloc_len, only_current_profile = 0;
|
int old_alloc_len, only_current_profile = 0, key, asc, ascq;
|
||||||
unsigned char *descr, *prf, *up_to, *prf_end;
|
unsigned char *descr, *prf, *up_to, *prf_end;
|
||||||
struct command c;
|
struct command c;
|
||||||
int phys_if_std = 0;
|
int phys_if_std = 0;
|
||||||
@ -2430,6 +2431,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
|
|
||||||
#ifdef Libisofs_simulate_old_mmc1_drivE
|
#ifdef Libisofs_simulate_old_mmc1_drivE
|
||||||
c.error = 1;
|
c.error = 1;
|
||||||
|
c.sense[0] = 0x70; /* Fixed format sense data */
|
||||||
c.sense[2] = 0x5;
|
c.sense[2] = 0x5;
|
||||||
c.sense[12] = 0x20;
|
c.sense[12] = 0x20;
|
||||||
c.sense[13] = 0x0;
|
c.sense[13] = 0x0;
|
||||||
@ -2437,8 +2439,8 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
|
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
/* ts A90603 : MMC-1 drive do not know 46h GET CONFIGURATION */
|
/* ts A90603 : MMC-1 drive do not know 46h GET CONFIGURATION */
|
||||||
if (c.sense[2] == 0x5 && c.sense[12] == 0x20 &&
|
spc_decode_sense(c.sense, 0, &key, &asc, &ascq);
|
||||||
c.sense[13] == 0x0) {
|
if (key == 0x5 && asc == 0x20 && ascq == 0x0) {
|
||||||
d->current_is_guessed_profile = 1;
|
d->current_is_guessed_profile = 1;
|
||||||
/* Will yield a non-zero profile only after
|
/* Will yield a non-zero profile only after
|
||||||
mmc_read_disc_info_al() was called */
|
mmc_read_disc_info_al() was called */
|
||||||
@ -2509,8 +2511,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
#ifdef Libburn_support_dvd_r_seQ
|
#ifdef Libburn_support_dvd_r_seQ
|
||||||
if (cp == 0x11 || cp == 0x14) /* DVD-R, DVD-RW */
|
if (cp == 0x11 || cp == 0x14) /* DVD-R, DVD-RW */
|
||||||
d->current_is_supported_profile = 1;
|
d->current_is_supported_profile = 1;
|
||||||
if (cp == 0x15) /* DVD-R/DL . */
|
if (cp == 0x15) /* DVD-R/DL */
|
||||||
/* Writeable only if burn_support_untested_profiles */
|
|
||||||
d->current_is_supported_profile = 1;
|
d->current_is_supported_profile = 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef Libburn_support_dvd_plus_R
|
#ifdef Libburn_support_dvd_plus_R
|
||||||
@ -3589,24 +3590,11 @@ unsuitable_media:;
|
|||||||
|
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error && !tolerate_failure) {
|
if (c.error && !tolerate_failure) {
|
||||||
if (c.sense[2]!=0) {
|
spc_decode_sense(c.sense, 0, &key, &asc, &ascq);
|
||||||
|
if (key != 0) {
|
||||||
#ifdef NIX
|
|
||||||
sprintf(msg,
|
|
||||||
"SCSI error on format_unit(%s): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
|
||||||
descr,
|
|
||||||
c.sense[2],c.sense[12],c.sense[13]);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020122,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg, 0, 0);
|
|
||||||
#else /* NIX */
|
|
||||||
sprintf(msg, "SCSI error on format_unit(%s): ", descr);
|
sprintf(msg, "SCSI error on format_unit(%s): ", descr);
|
||||||
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
&key, &asc, &ascq);
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
#endif /* !NIX */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((!c.error) && (format_type == 0x13 || format_type == 0x15))
|
} else if ((!c.error) && (format_type == 0x13 || format_type == 0x15))
|
||||||
@ -3676,6 +3664,7 @@ static int mmc_get_write_performance_al(struct burn_drive *d,
|
|||||||
|
|
||||||
#ifdef Libisofs_simulate_old_mmc1_drivE
|
#ifdef Libisofs_simulate_old_mmc1_drivE
|
||||||
c.error = 1;
|
c.error = 1;
|
||||||
|
c.sense[0] = 0x70; /* Fixed format sense data */
|
||||||
c.sense[2] = 0x5;
|
c.sense[2] = 0x5;
|
||||||
c.sense[12] = 0x20;
|
c.sense[12] = 0x20;
|
||||||
c.sense[13] = 0x0;
|
c.sense[13] = 0x0;
|
||||||
@ -3907,11 +3896,13 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||||||
int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
|
int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command c;
|
||||||
|
char msg[256];
|
||||||
|
int key, asc, ascq;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 0);
|
mmc_start_if_needed(d, 0);
|
||||||
if (mmc_function_spy(d, "mmc_read_10") <= 0)
|
if (mmc_function_spy(d, "mmc_read_10") <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
;
|
|
||||||
if (amount > BUFFER_SIZE / 2048)
|
if (amount > BUFFER_SIZE / 2048)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -3927,24 +3918,9 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
|
|||||||
c.dir = FROM_DRIVE;
|
c.dir = FROM_DRIVE;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
char msg[160];
|
|
||||||
|
|
||||||
sprintf(msg,
|
|
||||||
"SCSI error on read_10(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
|
||||||
start, amount,
|
|
||||||
c.sense[2],c.sense[12],c.sense[13]);
|
|
||||||
#else /* NIX */
|
|
||||||
char msg[256];
|
|
||||||
int key, asc, ascq;
|
|
||||||
|
|
||||||
sprintf(msg, "SCSI error on read_10(%d,%d): ", start, amount);
|
sprintf(msg, "SCSI error on read_10(%d,%d): ", start, amount);
|
||||||
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||||
&key, &asc, &ascq);
|
&key, &asc, &ascq);
|
||||||
|
|
||||||
#endif /* !NIX */
|
|
||||||
|
|
||||||
if(!d->silent_on_scsi_error)
|
if(!d->silent_on_scsi_error)
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020144,
|
0x00020144,
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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>
|
||||||
@ -20,7 +24,7 @@ struct burn_source *burn_null_source_new(void)
|
|||||||
{
|
{
|
||||||
struct burn_source *src;
|
struct burn_source *src;
|
||||||
|
|
||||||
src = malloc(sizeof(struct burn_source));
|
src = calloc(1, sizeof(struct burn_source));
|
||||||
src->refcount = 1;
|
src->refcount = 1;
|
||||||
src->read = null_read;
|
src->read = null_read;
|
||||||
src->read_sub = NULL;
|
src->read_sub = NULL;
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
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"
|
||||||
@ -23,7 +27,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
|||||||
{
|
{
|
||||||
struct burn_write_opts *opts;
|
struct burn_write_opts *opts;
|
||||||
|
|
||||||
opts = malloc(sizeof(struct burn_write_opts));
|
opts = calloc(1, sizeof(struct burn_write_opts));
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -64,7 +68,7 @@ struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
|||||||
{
|
{
|
||||||
struct burn_read_opts *opts;
|
struct burn_read_opts *opts;
|
||||||
|
|
||||||
opts = malloc(sizeof(struct burn_read_opts));
|
opts = calloc(1, sizeof(struct burn_read_opts));
|
||||||
opts->drive = drive;
|
opts->drive = drive;
|
||||||
opts->refcount = 1;
|
opts->refcount = 1;
|
||||||
opts->raw = 0;
|
opts->raw = 0;
|
||||||
@ -121,7 +125,7 @@ void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count,
|
|||||||
struct burn_toc_entry *toc_entries)
|
struct burn_toc_entry *toc_entries)
|
||||||
{
|
{
|
||||||
opts->toc_entries = count;
|
opts->toc_entries = count;
|
||||||
opts->toc_entry = malloc(count * sizeof(struct burn_toc_entry));
|
opts->toc_entry = calloc(count, sizeof(struct burn_toc_entry));
|
||||||
memcpy(opts->toc_entry, &toc_entries,
|
memcpy(opts->toc_entry, &toc_entries,
|
||||||
sizeof(struct burn_toc_entry) * count);
|
sizeof(struct burn_toc_entry) * count);
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,37 @@
|
|||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_SIGNAL_COUNT 16
|
#define BURN_OS_SIGNAL_COUNT 16
|
||||||
|
|
||||||
/** To list all signals which shall surely not be caught */
|
/** The list of all signals which shall surely not be caught.
|
||||||
|
It depends on the particular signal whether it can be ignored or whether
|
||||||
|
it will lead to sudden death of the process.
|
||||||
|
Some signals are not POSIX,
|
||||||
|
but nevertheless ought to be ignored if they are defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH ,SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_WINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIGURG
|
||||||
|
#define BURN_OS_SIG_URG ,SIGURG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_URG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The combined list of all signals which shall not be caught.
|
||||||
|
*/
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP
|
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT 3
|
#define BURN_OS_NON_SIGNAL_COUNT \
|
||||||
|
( 3 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
|
||||||
|
|
||||||
|
|
||||||
/* The maximum size for a (SCSI) i/o transaction */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
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 GPLv2+
|
Copyright (C) 2006 - 2010 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
|
||||||
@ -41,7 +42,11 @@ SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
|||||||
|
|
||||||
/* The maximum size for a (SCSI) i/o transaction */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
/* Important : MUST be at least 32768 ! */
|
/* Important : MUST be at least 32768 ! */
|
||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
/* Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
|
||||||
|
on 8-STABLE. It is by default only used with BD in streaming mode.
|
||||||
|
So older systems should still be quite safe with this buffer max size.
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
/** To hold all state information of BSD device enumeration
|
/** To hold all state information of BSD device enumeration
|
||||||
@ -59,5 +64,6 @@ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
|
|||||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
struct cam_device* cam; \
|
struct cam_device* cam; \
|
||||||
int lock_fd; \
|
int lock_fd; \
|
||||||
|
int is_ahci; \
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,26 +29,49 @@
|
|||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_SIGNAL_COUNT 16
|
#define BURN_OS_SIGNAL_COUNT 16
|
||||||
|
|
||||||
/** To list all signals which shall surely not be caught */
|
|
||||||
|
/** The list of all signals which shall surely not be caught.
|
||||||
|
It depends on the particular signal whether it can be ignored or whether
|
||||||
|
it will lead to sudden death of the process.
|
||||||
|
Some signals are not POSIX,
|
||||||
|
but nevertheless ought to be ignored if they are defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH ,SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_WINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIGURG
|
||||||
|
#define BURN_OS_SIG_URG ,SIGURG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_URG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The combined list of all signals which shall not be caught.
|
||||||
|
*/
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP
|
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT 3
|
#define BURN_OS_NON_SIGNAL_COUNT \
|
||||||
|
( 3 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
|
||||||
|
|
||||||
|
|
||||||
/* The maximum size for a (SCSI) i/o transaction */
|
/* 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
|
/* 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.
|
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.
|
Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
|
||||||
|
on 8-STABLE. It is by default only used with BD in streaming mode.
|
||||||
|
So older systems should still be quite safe with this buffer max size.
|
||||||
*/
|
*/
|
||||||
#ifdef __linux
|
/* Important : MUST be at least 32768 ! */
|
||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
#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
|
/* To hold the position of the most recently delivered address from
|
||||||
|
66
libburn/os-solaris.h
Normal file
66
libburn/os-solaris.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#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;
|
||||||
|
|
18
libburn/os.h
18
libburn/os.h
@ -14,6 +14,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_dummY
|
||||||
|
|
||||||
|
|
||||||
|
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
|
||||||
|
#include "os-dummy.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
#ifdef Libburn_use_libcdiO
|
#ifdef Libburn_use_libcdiO
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +53,14 @@
|
|||||||
#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
|
||||||
|
|
||||||
|
|
||||||
@ -52,10 +68,12 @@
|
|||||||
#include "os-dummy.h"
|
#include "os-dummy.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! __sun*/
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
#endif /* ! __FreeBSD__kernel__ */
|
#endif /* ! __FreeBSD__kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
#endif /* ! Libburn_use_libcdiO */
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! BURN_OS_H_INCLUDED */
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
/* #include <m alloc.h> ts A61013 : not in GNU/Linux man 3 malloc */
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
Provided under GPL version 2 or later.
|
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>
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -95,6 +95,10 @@ 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 ------ */
|
||||||
|
|
||||||
@ -165,9 +169,10 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
|||||||
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
||||||
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
idx->ccb.cdm.matches = (struct dev_match_result *)
|
||||||
|
calloc(1, idx->bufsize);
|
||||||
if (idx->ccb.cdm.matches == NULL) {
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
warnx("can't malloc memory for matches");
|
warnx("cannot allocate memory for matches");
|
||||||
close(idx->fd);
|
close(idx->fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
Provided under GPL version 2 or later.
|
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>
|
||||||
@ -30,6 +33,18 @@
|
|||||||
#include <sys/disk.h> /* DIOCGMEDIASIZE */
|
#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"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
@ -145,15 +160,15 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
|
|||||||
struct burn_drive_enumeration_state *idx;
|
struct burn_drive_enumeration_state *idx;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
|
|
||||||
idx = malloc(sizeof(*idx));
|
idx = calloc(1, sizeof(*idx));
|
||||||
if (idx == NULL) {
|
if (idx == NULL) {
|
||||||
warnx("can't malloc memory for enumerator");
|
warnx("cannot allocate memory for enumerator");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
idx->skip_device = 0;
|
idx->skip_device = 0;
|
||||||
|
|
||||||
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||||
warn("couldn't open %s", XPT_DEVICE);
|
warn("could not open %s", XPT_DEVICE);
|
||||||
free(idx);
|
free(idx);
|
||||||
idx = NULL;
|
idx = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
@ -168,9 +183,9 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
|
|||||||
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
bufsize = sizeof(struct dev_match_result) * 100;
|
bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
idx->ccb.cdm.match_buf_len = bufsize;
|
idx->ccb.cdm.match_buf_len = bufsize;
|
||||||
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
|
idx->ccb.cdm.matches = (struct dev_match_result *) calloc(1, bufsize);
|
||||||
if (idx->ccb.cdm.matches == NULL) {
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
warnx("can't malloc memory for matches");
|
warnx("cannot allocate memory for matches");
|
||||||
close(idx->fd);
|
close(idx->fd);
|
||||||
free(idx);
|
free(idx);
|
||||||
return -1;
|
return -1;
|
||||||
@ -435,6 +450,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
out.lock_fd = -1;
|
out.lock_fd = -1;
|
||||||
|
out.is_ahci = 0;
|
||||||
|
|
||||||
out.start_lba= -2000000000;
|
out.start_lba= -2000000000;
|
||||||
out.end_lba= -2000000000;
|
out.end_lba= -2000000000;
|
||||||
@ -471,9 +487,9 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
out.close_session = mmc_close_session;
|
out.close_session = mmc_close_session;
|
||||||
out.close_track_session = mmc_close;
|
out.close_track_session = mmc_close;
|
||||||
out.read_buffer_capacity = mmc_read_buffer_capacity;
|
out.read_buffer_capacity = mmc_read_buffer_capacity;
|
||||||
out.idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
out.idata = calloc(1, sizeof(struct burn_scsi_inquiry_data));
|
||||||
out.idata->valid = 0;
|
out.idata->valid = 0;
|
||||||
out.mdata = malloc(sizeof(struct scsi_mode_data));
|
out.mdata = calloc(1, sizeof(struct scsi_mode_data));
|
||||||
out.mdata->valid = 0;
|
out.mdata->valid = 0;
|
||||||
if (out.idata == NULL || out.mdata == NULL) {
|
if (out.idata == NULL || out.mdata == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||||
@ -527,6 +543,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* Adapter specific handles and data */
|
/* Adapter specific handles and data */
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
out.lock_fd = -1;
|
out.lock_fd = -1;
|
||||||
|
out.is_ahci = 0;
|
||||||
|
|
||||||
/* Adapter specific functions */
|
/* Adapter specific functions */
|
||||||
out.grab = sg_grab;
|
out.grab = sg_grab;
|
||||||
@ -678,6 +695,7 @@ static int sg_lock(struct burn_drive *d, int flag)
|
|||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
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;
|
||||||
@ -700,6 +718,18 @@ int sg_grab(struct burn_drive *d)
|
|||||||
if (sg_lock(d, 0) <= 0)
|
if (sg_lock(d, 0) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
fcntl(cam->fd, F_SETOWN, getpid());
|
fcntl(cam->fd, F_SETOWN, getpid());
|
||||||
|
|
||||||
|
cam_path_string(d->cam, path_string, sizeof(path_string));
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: CAM path = %s\n", path_string);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (strstr(path_string, ":ahcich") != NULL)
|
||||||
|
d->is_ahci = 1;
|
||||||
|
else
|
||||||
|
d->is_ahci = -1;
|
||||||
|
|
||||||
d->released = 0;
|
d->released = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -729,12 +759,17 @@ 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, err, sense_len, ret;
|
int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0, i;
|
||||||
|
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
|
||||||
union ccb *ccb;
|
union ccb *ccb;
|
||||||
char buf[161];
|
char buf[161];
|
||||||
static FILE *fp = NULL;
|
static FILE *fp = NULL;
|
||||||
|
time_t start_time;
|
||||||
|
|
||||||
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
@ -777,6 +812,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);
|
||||||
|
|
||||||
@ -806,9 +858,81 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
start_time = time(NULL);
|
||||||
|
timeout_ms = 200000;
|
||||||
|
for (i = 0; !done; i++) {
|
||||||
|
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);
|
||||||
|
spc_decode_sense(c->sense, sense_len,
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
if (sense_len >= 14 && cam_pass_err_recover && key)
|
||||||
|
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[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
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[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
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[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
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,
|
||||||
@ -822,38 +946,81 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
}
|
}
|
||||||
/* XXX */
|
/* XXX */
|
||||||
|
|
||||||
/* 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, 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[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
c->sense[2] = 0x02;
|
||||||
|
c->sense[12] = 0x04;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
no_retry = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
|
||||||
|
sense_len, 0, start_time,
|
||||||
|
timeout_ms, i,
|
||||||
|
2 | !!ignore_error);
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
|
if (no_retry || ignore_error || !c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
{ret = 1; goto ex;}
|
{ret = 1; goto ex;}
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
sense_len > 0 ? sense_len : 18,
|
||||||
|
0, 1 | 2);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FAIL:
|
case FAIL:
|
||||||
done = 1;
|
done = 1;
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
break;
|
break;
|
||||||
|
case GO_ON:
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
/* >>> Need own duration time
|
||||||
|
measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense,
|
||||||
|
sense_len > 0 ? sense_len : 18,
|
||||||
|
0, 1 | 2);
|
||||||
|
{ret = 1; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
if (c->error)
|
if (c->error)
|
||||||
scsi_notify_error(d, c, c->sense, 18, 0);
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
/* >>> Need own duration time measurement. Then remove bit1 */
|
/* >>> Need own duration time measurement. Then remove bit1 */
|
||||||
scsi_log_err(c, fp, c->sense, 0, (c->error != 0) | 2);
|
scsi_log_err(c, fp, c->sense, sense_len > 0 ? sense_len : 18,
|
||||||
|
0, (c->error != 0) | 2);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return ret;
|
return ret;
|
||||||
@ -869,6 +1036,10 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
|||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
char *spt;
|
char *spt;
|
||||||
int i, e;
|
int i, e;
|
||||||
|
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
||||||
|
int fd;
|
||||||
|
off_t add_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (stat(path, &stbuf) == -1)
|
if (stat(path, &stbuf) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
@ -876,6 +1047,22 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
if (!S_ISCHR(stbuf.st_mode))
|
if (!S_ISCHR(stbuf.st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
||||||
|
|
||||||
|
/* If it throws no error with DIOCGMEDIASIZE then it is a
|
||||||
|
'block device'
|
||||||
|
*/
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return 0;
|
||||||
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#else /* Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
|
|
||||||
spt = strrchr(path, '/');
|
spt = strrchr(path, '/');
|
||||||
if (spt == NULL)
|
if (spt == NULL)
|
||||||
spt = path;
|
spt = path;
|
||||||
@ -898,6 +1085,9 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
|||||||
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,6 +94,10 @@ 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 ------ */
|
||||||
|
|
||||||
@ -131,6 +135,13 @@ Send feedback to libburn-hackers@pykix.org .
|
|||||||
|
|
||||||
#define Libburn_guess_freebsd_atapi_devicE 1
|
#define Libburn_guess_freebsd_atapi_devicE 1
|
||||||
|
|
||||||
|
#ifdef sun
|
||||||
|
#define Libburn_is_on_solariS 1
|
||||||
|
#endif
|
||||||
|
#ifdef __sun
|
||||||
|
#define Libburn_is_on_solariS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/logging.h>
|
#include <cdio/logging.h>
|
||||||
#include <cdio/mmc.h>
|
#include <cdio/mmc.h>
|
||||||
@ -225,6 +236,7 @@ static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (initialize == -1) {
|
} else if (initialize == -1) {
|
||||||
|
if (idx->ppsz_cd_drives != NULL)
|
||||||
if (*(idx->ppsz_cd_drives) != NULL)
|
if (*(idx->ppsz_cd_drives) != NULL)
|
||||||
cdio_free_device_list(idx->ppsz_cd_drives);
|
cdio_free_device_list(idx->ppsz_cd_drives);
|
||||||
idx->ppsz_cd_drives = NULL;
|
idx->ppsz_cd_drives = NULL;
|
||||||
@ -419,14 +431,28 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
{
|
{
|
||||||
int ret, recursion_count = 0;
|
int ret, recursion_count = 0;
|
||||||
char path[4096];
|
char path[4096];
|
||||||
|
#ifdef Libburn_is_on_solariS
|
||||||
|
int l;
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (strlen(adr) >= sizeof(path))
|
if (strlen(adr) >= sizeof(path))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
#ifdef Libburn_is_on_solariS
|
||||||
|
/* >>> provisory : preserve Solaris /dev/rdsk/cXtYdZs2 addresses */
|
||||||
|
l = strlen(adr);
|
||||||
|
if (l >= 18)
|
||||||
|
if (strncmp(adr, "/dev/rdsk/c", 11) == 0 && adr[11] >= '0' &&
|
||||||
|
adr[11] <= '9' && strcmp(adr + (l - 2), "s2") == 0)
|
||||||
|
return 1;
|
||||||
|
#endif /* Libburn_is_on_solariS */
|
||||||
|
|
||||||
|
ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
|
||||||
|
if(ret > 0 && strlen(path) < adr_size)
|
||||||
strcpy(path, adr);
|
strcpy(path, adr);
|
||||||
ret = burn_drive_resolve_link(path, adr, &recursion_count, 2);
|
|
||||||
return (ret >= 0);
|
return (ret >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,13 +466,31 @@ int scsi_enumerate_drives(void)
|
|||||||
int initialize = 1, ret, i_bus_no = -1, recursion_count = 0;
|
int initialize = 1, ret, i_bus_no = -1, recursion_count = 0;
|
||||||
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
||||||
char buf[4096], target[4096];
|
char buf[4096], target[4096];
|
||||||
|
#ifdef Libburn_is_on_solariS
|
||||||
|
int l;
|
||||||
|
#endif
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
ret = sg_give_next_adr_raw(&idx, buf, sizeof(buf), initialize);
|
ret = sg_give_next_adr_raw(&idx, buf, sizeof(buf), initialize);
|
||||||
initialize = 0;
|
initialize = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
break;
|
break;
|
||||||
ret = burn_drive_resolve_link(buf, target, &recursion_count,2);
|
ret = 1;
|
||||||
|
|
||||||
|
#ifdef Libburn_is_on_solariS
|
||||||
|
/* >>> provisory : preserve Solaris /dev/rdsk/cXtYdZs2 */
|
||||||
|
l = strlen(buf);
|
||||||
|
if (l >= 18)
|
||||||
|
if (strncmp(buf, "/dev/rdsk/c", 11) == 0 &&
|
||||||
|
buf[11] >= '0' && buf[11] <= '9' &&
|
||||||
|
strcmp(buf + (l - 2), "s2") == 0)
|
||||||
|
ret = 0;
|
||||||
|
#endif /* Libburn_is_on_solariS */
|
||||||
|
|
||||||
|
if (ret == 1) {
|
||||||
|
ret = burn_drive_resolve_link(buf, target,
|
||||||
|
&recursion_count,2);
|
||||||
|
}
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
strcpy(target, buf);
|
strcpy(target, buf);
|
||||||
if (burn_drive_is_banned(target))
|
if (burn_drive_is_banned(target))
|
||||||
@ -542,6 +586,9 @@ int sg_release(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
@ -553,7 +600,8 @@ 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 sense_valid = 0, i, usleep_time, timeout_ms;
|
int sense_valid = 0, i, timeout_ms, no_retry = 0;
|
||||||
|
int key = 0, asc = 0, ascq = 0, done = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
driver_return_code_t i_status;
|
driver_return_code_t i_status;
|
||||||
unsigned int dxfer_len;
|
unsigned int dxfer_len;
|
||||||
@ -563,6 +611,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
CdIo_t *p_cdio;
|
CdIo_t *p_cdio;
|
||||||
unsigned char *sense_pt = NULL;
|
unsigned char *sense_pt = NULL;
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
int usleep_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
if (d->p_cdio == NULL) {
|
if (d->p_cdio == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -598,15 +650,18 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
/* retry-loop */
|
/* retry-loop */
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
timeout_ms = 200000;
|
timeout_ms = 200000;
|
||||||
for(i = 0; ; i++) {
|
for(i = 0; !done; i++) {
|
||||||
|
|
||||||
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
|
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
|
||||||
dxfer_len, c->page->data);
|
dxfer_len, c->page->data);
|
||||||
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
||||||
if (sense_valid >= 18)
|
if (sense_valid >= 18) {
|
||||||
memcpy(c->sense, sense_pt,
|
memcpy(c->sense, sense_pt,
|
||||||
sense_valid >= sizeof(c->sense) ?
|
sense_valid >= sizeof(c->sense) ?
|
||||||
sizeof(c->sense) : sense_valid );
|
sizeof(c->sense) : sense_valid );
|
||||||
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
|
} else
|
||||||
|
key = asc = ascq = 0;
|
||||||
if (sense_pt != NULL)
|
if (sense_pt != NULL)
|
||||||
free(sense_pt);
|
free(sense_pt);
|
||||||
|
|
||||||
@ -628,28 +683,50 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!sense_valid) {
|
if ((!sense_valid) || (key == 0 && asc == 0 && ascq == 0)) {
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
if (i_status != 0) { /* set dummy sense */
|
if (i_status != 0) { /* set dummy sense */
|
||||||
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
|
/*LOGICAL UNIT NOT READY,
|
||||||
|
CAUSE NOT REPORTABLE*/
|
||||||
|
c->sense[0] = 0x70; /*Fixed format sense data*/
|
||||||
c->sense[2] = 0x02;
|
c->sense[2] = 0x02;
|
||||||
c->sense[12] = 0x04;
|
c->sense[12] = 0x04;
|
||||||
|
no_retry = 1;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
c->sense[2] &= 15;
|
if (i_status != 0 || (key || asc || ascq)) {
|
||||||
|
|
||||||
if (i_status != 0 ||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
(c->sense[2] || c->sense[12] || c->sense[13])) {
|
|
||||||
if (!c->retry) {
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18,
|
||||||
|
0, start_time, timeout_ms, i, 2);
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
|
if (no_retry || !c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
switch (scsi_error(d, c->sense, 18)) {
|
switch (scsi_error(d, c->sense, 18)) {
|
||||||
case RETRY:
|
case RETRY:
|
||||||
|
if (burn_sg_log_scsi & 3) {
|
||||||
|
/* >>> Need own duration time
|
||||||
|
measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 18, 0,
|
||||||
|
1 | 2);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FAIL:
|
case FAIL:
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
goto ex;
|
goto ex;
|
||||||
|
case GO_ON:
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
/* >>> Need own duration time
|
||||||
|
measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 18, 0,
|
||||||
|
1 | 2);
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Calming down retries and breaking up endless cycle
|
Calming down retries and breaking up endless cycle
|
||||||
@ -662,17 +739,24 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
usleep(usleep_time);
|
usleep(usleep_time);
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
} else
|
} else
|
||||||
break; /* retry-loop */
|
done = 1;
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
if (c->error)
|
if (c->error)
|
||||||
scsi_notify_error(d, c, c->sense, 18, 0);
|
scsi_notify_error(d, c, c->sense, 18, 0);
|
||||||
|
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
/* >>> Need own duration time measurement. Then remove bit1 */
|
/* >>> Need own duration time measurement. Then remove bit1 */
|
||||||
scsi_log_err(c, fp, c->sense, 0, (c->error != 0) | 2);
|
scsi_log_err(c, fp, c->sense, 18, 0, (c->error != 0) | 2);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,7 +953,24 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size;
|
*bytes = add_size;
|
||||||
|
|
||||||
#endif/* Libburn_is_on_freebsD */
|
#endif /* Libburn_is_on_freebsD */
|
||||||
|
|
||||||
|
#ifdef Libburn_is_on_solariS
|
||||||
|
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_is_on_solariS */
|
||||||
|
|
||||||
} 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;
|
||||||
|
@ -104,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 ------ */
|
||||||
|
|
||||||
@ -1769,36 +1773,6 @@ int sg_release(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
/* <<< now in spc.c as scsi_log_err */
|
|
||||||
|
|
||||||
/** logs outcome of a sg command. flag&1 causes an error message */
|
|
||||||
static int sg_log_err(struct command *c, FILE *fp,
|
|
||||||
sg_io_hdr_t *s,
|
|
||||||
int flag)
|
|
||||||
{
|
|
||||||
if(fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
|
||||||
if(flag & 1) {
|
|
||||||
fprintf(fp,
|
|
||||||
"+++ key=%X asc=%2.2Xh ascq=%2.2Xh (%6d ms)\n",
|
|
||||||
s->sbp[2], s->sbp[12], s->sbp[13],s->duration);
|
|
||||||
} else {
|
|
||||||
scsi_show_cmd_reply(c, fp, 0);
|
|
||||||
fprintf(fp,"%6d ms\n", s->duration);
|
|
||||||
}
|
|
||||||
if (burn_sg_log_scsi & 4)
|
|
||||||
fflush(fp);
|
|
||||||
}
|
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
sg_log_err(c, stderr, s, flag);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NIX */
|
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
@ -1808,13 +1782,19 @@ static int sg_log_err(struct command *c, FILE *fp,
|
|||||||
*/
|
*/
|
||||||
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, no_c_page = 0, usleep_time, i;
|
int done = 0, no_c_page = 0, i;
|
||||||
int err;
|
int err;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
sg_io_hdr_t s;
|
sg_io_hdr_t s;
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
static FILE *fp= NULL;
|
static FILE *fp= NULL;
|
||||||
|
|
||||||
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
int usleep_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* <<< ts A60821
|
/* <<< ts A60821
|
||||||
debug: for tracing calls which might use open drive fds */
|
debug: for tracing calls which might use open drive fds */
|
||||||
char buf[161];
|
char buf[161];
|
||||||
@ -1918,6 +1898,32 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
|
/* <<< */
|
||||||
|
if(0){
|
||||||
|
static int erst= 1;
|
||||||
|
static unsigned char b00_sense[22]= {
|
||||||
|
0x72, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
|
||||||
|
0x09, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
if (erst > 0) {
|
||||||
|
s.sb_len_wr= 22;
|
||||||
|
memcpy(s.sbp, b00_sense, s.sb_len_wr);
|
||||||
|
erst--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* <<< */
|
||||||
|
#endif /* NIX */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr,
|
||||||
|
s.duration, start_time, s.timeout, i, 0);
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
if (s.sb_len_wr) {
|
if (s.sb_len_wr) {
|
||||||
if (!c->retry) {
|
if (!c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
@ -1928,11 +1934,21 @@ 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.sb_len_wr,
|
||||||
|
s.duration, 1);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FAIL:
|
case FAIL:
|
||||||
done = 1;
|
done = 1;
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
break;
|
break;
|
||||||
|
case GO_ON:
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_err(c, fp, s.sbp, s.sb_len_wr,
|
||||||
|
s.duration, 1);
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A90921 :
|
/* ts A90921 :
|
||||||
@ -1949,14 +1965,28 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61106 */
|
/* ts A61106 */
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
if (s.host_status != Libburn_sg_host_oK ||
|
||||||
|
(s.driver_status != Libburn_sg_driver_oK && !c->error)) {
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
if (c->error) {
|
if (c->error) {
|
||||||
scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0);
|
scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0);
|
||||||
} else if (s.host_status != Libburn_sg_host_oK ||
|
} else if (s.host_status != Libburn_sg_host_oK ||
|
||||||
s.driver_status != Libburn_sg_driver_oK) {
|
s.driver_status != Libburn_sg_driver_oK) {
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
char msg[161];
|
char msg[161];
|
||||||
|
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
@ -1971,9 +2001,13 @@ ex:;
|
|||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
/* <<< sg_log_err(c, fp, &s, c->error != 0); */
|
scsi_log_err(c, fp, s.sbp, s.sb_len_wr,
|
||||||
scsi_log_err(c, fp, s.sbp, s.duration, c->error != 0);
|
s.duration, c->error != 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
930
libburn/sg-solaris.c
Normal file
930
libburn/sg-solaris.c
Normal file
@ -0,0 +1,930 @@
|
|||||||
|
/* -*- 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, timeout_ms, ret, key, asc, ascq, done = 0;
|
||||||
|
time_t start_time;
|
||||||
|
struct uscsi_cmd cgc;
|
||||||
|
char msg[80];
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
|
||||||
|
#define Libburn_use_scsi_eval_cmd_outcomE yes
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
int usleep_time, no_retry = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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; !done; 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> Should replace "18" by realistic sense length.
|
||||||
|
What's about following older remark ?
|
||||||
|
*/
|
||||||
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
|
if (key || asc || ascq) {
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18, 0,
|
||||||
|
start_time, timeout_ms, i, 2);
|
||||||
|
} else
|
||||||
|
done = 1;
|
||||||
|
|
||||||
|
|
||||||
|
#else /* Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
|
if (key || asc || ascq) {
|
||||||
|
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, 18, 0,
|
||||||
|
1 | 2);
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FAIL:
|
||||||
|
c->error = 1;
|
||||||
|
goto ex;
|
||||||
|
case GO_ON:
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
/* >>> Need own duration time
|
||||||
|
measurement. Then remove bit1 */
|
||||||
|
scsi_log_err(c, fp, c->sense, 18, 0,
|
||||||
|
1 | 2);
|
||||||
|
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 */
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
#ifndef Libburn_use_scsi_eval_cmd_outcomE
|
||||||
|
|
||||||
|
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, 18, 0, (c->error != 0) | 2);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_use_scsi_eval_cmd_outcomE */
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NIX
|
||||||
|
|
||||||
|
int sg_is_enumerable_adr(char* path)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int bus_no, target_no, lun_no;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (strncmp("/dev/rdsk/", path, 10) != 0)
|
||||||
|
return 0;
|
||||||
|
ret = decode_btl_solaris(path + 10, &bus_no, &target_no, &lun_no, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ! NIX */
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#endif /* NIX */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
20
libburn/sg.c
20
libburn/sg.c
@ -1,10 +1,21 @@
|
|||||||
|
|
||||||
/* 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 GPLv2+
|
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
|
#ifdef Libburn_use_libcdiO
|
||||||
|
|
||||||
#include "sg-libcdio.c"
|
#include "sg-libcdio.c"
|
||||||
@ -24,6 +35,11 @@
|
|||||||
|
|
||||||
#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
|
||||||
@ -46,8 +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_kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
#endif /* ! Libburn_use_libcdiO */
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
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>
|
||||||
|
191
libburn/spc.c
191
libburn/spc.c
@ -5,9 +5,12 @@
|
|||||||
Provided under GPL version 2 or later.
|
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>
|
||||||
@ -72,6 +75,30 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00728 */
|
||||||
|
int spc_decode_sense(unsigned char *sense, int senselen,
|
||||||
|
int *key, int *asc, int *ascq)
|
||||||
|
{
|
||||||
|
*key = *asc = *ascq = 0;
|
||||||
|
if ((sense[0] & 0x7f) == 0x72 || (sense[0] & 0x7f) == 0x73) {
|
||||||
|
if (senselen <= 0 || senselen > 1)
|
||||||
|
*key = sense[1] & 0x0f;
|
||||||
|
if (senselen <= 0 || senselen > 2)
|
||||||
|
*asc = sense[2];
|
||||||
|
if (senselen <= 0 || senselen > 3)
|
||||||
|
*ascq = sense[3];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (senselen <= 0 || senselen > 2)
|
||||||
|
*key = sense[2] & 0x0f;
|
||||||
|
if (senselen <= 0 || senselen > 12)
|
||||||
|
*asc = sense[12];
|
||||||
|
if (senselen <= 0 || senselen > 13)
|
||||||
|
*ascq = sense[13];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
|
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command c;
|
||||||
@ -80,23 +107,23 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scsi_init_command(&c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY));
|
scsi_init_command(&c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY));
|
||||||
/*
|
|
||||||
c.oplen = sizeof(SPC_TEST_UNIT_READY);
|
|
||||||
memcpy(c.opcode, SPC_TEST_UNIT_READY, sizeof(SPC_TEST_UNIT_READY));
|
|
||||||
c.page = NULL;
|
|
||||||
*/
|
|
||||||
c.retry = 0;
|
c.retry = 0;
|
||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
*key= c.sense[2];
|
|
||||||
*asc= c.sense[12];
|
/*
|
||||||
*ascq= c.sense[13];
|
fprintf(stderr, "sense[0 - 2] = %2.2X %2.2X %2.2X",
|
||||||
return (c.sense[2] & 0xF) == 0;
|
c.sense[0], c.sense[1], c.sense[2]);
|
||||||
|
*/
|
||||||
|
|
||||||
|
spc_decode_sense(c.sense, 0, key, asc, ascq);
|
||||||
|
return (key == 0);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int spc_test_unit_ready(struct burn_drive *d)
|
int spc_test_unit_ready(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int key,asc,ascq;
|
int key,asc,ascq;
|
||||||
@ -113,7 +140,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;
|
||||||
@ -143,9 +171,11 @@ 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);
|
||||||
|
sense[0] = 0x70; /* Fixed format sense data */
|
||||||
sense[2] = key;
|
sense[2] = key;
|
||||||
sense[12] = asc;
|
sense[12] = asc;
|
||||||
sense[13] = ascq;
|
sense[13] = ascq;
|
||||||
@ -156,8 +186,24 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
|||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (ascq == 0x02 || ascq == 0x03)
|
||||||
|
goto handle_error;
|
||||||
|
|
||||||
slumber:;
|
slumber:;
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
@ -228,7 +274,7 @@ void spc_inquiry(struct burn_drive *d)
|
|||||||
memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY));
|
memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY));
|
||||||
c.oplen = sizeof(SPC_INQUIRY);
|
c.oplen = sizeof(SPC_INQUIRY);
|
||||||
*/
|
*/
|
||||||
c.dxfer_len= (c.opcode[3] << 8) | c.opcode[4];
|
c.dxfer_len = (c.opcode[3] << 8) | c.opcode[4];
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
c.page = &buf;
|
c.page = &buf;
|
||||||
c.page->bytes = 0;
|
c.page->bytes = 0;
|
||||||
@ -782,9 +828,7 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
if (last_try)
|
if (last_try)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
key = c.sense[2];
|
spc_decode_sense(c.sense, 0, &key, &asc, &ascq);
|
||||||
asc = c.sense[12];
|
|
||||||
ascq = c.sense[13];
|
|
||||||
if (key)
|
if (key)
|
||||||
burn_print(7, "%d not supported\n", try_block_type);
|
burn_print(7, "%d not supported\n", try_block_type);
|
||||||
else {
|
else {
|
||||||
@ -937,6 +981,7 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
int senselen, char msg_data[161],
|
int senselen, char msg_data[161],
|
||||||
int *key, int *asc, int *ascq)
|
int *key, int *asc, int *ascq)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
char *msg;
|
char *msg;
|
||||||
static char key_def[16][40] = {
|
static char key_def[16][40] = {
|
||||||
"(no specific error)",
|
"(no specific error)",
|
||||||
@ -960,14 +1005,11 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
msg= msg_data;
|
msg= msg_data;
|
||||||
*key= *asc= *ascq= -1;
|
*key= *asc= *ascq= -1;
|
||||||
|
|
||||||
if (senselen<=0 || senselen>2)
|
ret = spc_decode_sense(sense, senselen, key, asc, ascq);
|
||||||
*key = sense[2];
|
if (ret <= 0)
|
||||||
if (senselen<=0 || senselen>12)
|
*key= *asc= *ascq= -1;
|
||||||
*asc = sense[12];
|
|
||||||
if (senselen<=0 || senselen>13)
|
|
||||||
*ascq = sense[13];
|
|
||||||
|
|
||||||
sprintf(msg, "[%X %2.2X %2.2X] ", (*key) & 0xf, *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",
|
||||||
@ -975,15 +1017,20 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
|
|
||||||
switch (*asc) {
|
switch (*asc) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
if (*key > 0 || *ascq > 0)
|
||||||
|
break; /* Fall through to unknown error */
|
||||||
sprintf(msg, "(No error reported by SCSI transaction)");
|
sprintf(msg, "(No error reported by SCSI transaction)");
|
||||||
return RETRY;
|
return GO_ON;
|
||||||
|
|
||||||
case 0x02:
|
case 0x02:
|
||||||
sprintf(msg, "Not ready");
|
sprintf(msg, "Not ready");
|
||||||
return RETRY;
|
return RETRY;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
|
if (*ascq == 1)
|
||||||
sprintf(msg,
|
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)
|
||||||
@ -1179,6 +1226,12 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
sprintf(msg, "Medium not present");
|
sprintf(msg, "Medium not present");
|
||||||
d->status = BURN_DISC_EMPTY;
|
d->status = BURN_DISC_EMPTY;
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
case 0x3E:
|
||||||
|
if (*ascq == 1)
|
||||||
|
sprintf(msg, "Logical unit failure");
|
||||||
|
else if (*ascq == 2)
|
||||||
|
sprintf(msg, "Timeout on logical unit");
|
||||||
|
return FAIL;
|
||||||
case 0x57:
|
case 0x57:
|
||||||
if (*key != 3 || *ascq != 0)
|
if (*key != 3 || *ascq != 0)
|
||||||
break;
|
break;
|
||||||
@ -1355,28 +1408,10 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
|||||||
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
|
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
|
||||||
c->opcode[0],
|
c->opcode[0],
|
||||||
scsi_command_name((unsigned int) c->opcode[0], 0));
|
scsi_command_name((unsigned int) c->opcode[0], 0));
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
if (key>=0)
|
|
||||||
sprintf(msg+strlen(msg), " key=%Xh", key);
|
|
||||||
if (asc>=0)
|
|
||||||
sprintf(msg+strlen(msg), " asc=%2.2Xh", asc);
|
|
||||||
if (ascq>=0)
|
|
||||||
sprintf(msg+strlen(msg), " ascq=%2.2Xh", ascq);
|
|
||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
scsi_msg,0,0);
|
|
||||||
#else
|
|
||||||
strcat(msg, scsi_msg);
|
strcat(msg, scsi_msg);
|
||||||
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
||||||
|
|
||||||
#endif /* NIX */
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1469,19 +1504,31 @@ int scsi_log_cmd(struct command *c, void *fp_in, int flag)
|
|||||||
bit1 do not print duration
|
bit1 do not print duration
|
||||||
*/
|
*/
|
||||||
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
||||||
int duration, int flag)
|
int sense_len, int duration, int flag)
|
||||||
{
|
{
|
||||||
char durtxt[20];
|
char durtxt[20];
|
||||||
FILE *fp = fp_in;
|
FILE *fp = fp_in;
|
||||||
|
int key, asc, ascq, i, l;
|
||||||
|
|
||||||
if(fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||||
if(flag & 1) {
|
if (flag & 1) {
|
||||||
|
l = 18;
|
||||||
|
if ((sense[0] & 0x7f) == 0x72 ||
|
||||||
|
(sense[0] & 0x7f) == 0x73)
|
||||||
|
l = sense[7] + 7 + 1; /* SPC-5 4.5.2. */
|
||||||
|
if (l > sense_len)
|
||||||
|
l = sense_len;
|
||||||
|
fprintf(fp, "+++ sense data =");
|
||||||
|
for (i = 0 ; i < l; i++)
|
||||||
|
fprintf(fp, " %2.2X", sense[i]);
|
||||||
|
fprintf(fp, "\n");
|
||||||
durtxt[0] = 0;
|
durtxt[0] = 0;
|
||||||
if (!(flag & 2))
|
if (!(flag & 2))
|
||||||
sprintf(durtxt, " (%6d ms)\n",duration);
|
sprintf(durtxt, " (%6d ms)", duration);
|
||||||
|
spc_decode_sense(sense, 0, &key, &asc, &ascq);
|
||||||
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
|
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
|
||||||
sense[2], sense[12], sense[13], durtxt);
|
(unsigned int) key, (unsigned int) asc,
|
||||||
|
(unsigned int) ascq, durtxt);
|
||||||
} else {
|
} else {
|
||||||
scsi_show_cmd_reply(c, fp, 0);
|
scsi_show_cmd_reply(c, fp, 0);
|
||||||
if (!(flag & 2))
|
if (!(flag & 2))
|
||||||
@ -1492,7 +1539,55 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|||||||
}
|
}
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||||
return 1;
|
return 1;
|
||||||
scsi_log_err(c, stderr, sense, duration, flag);
|
scsi_log_err(c, stderr, sense, sense_len, duration, flag);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00808 */
|
||||||
|
/*
|
||||||
|
@param flag bit0 = do not retry
|
||||||
|
bit1 = do not print duration
|
||||||
|
@return 0 = not yet done , 1 = done , -1 = error
|
||||||
|
*/
|
||||||
|
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
|
||||||
|
unsigned char *sense, int sense_len,
|
||||||
|
int duration, time_t start_time, int timeout_ms,
|
||||||
|
int loop_count, int flag)
|
||||||
|
{
|
||||||
|
enum response outcome;
|
||||||
|
int done = -1, usleep_time;
|
||||||
|
|
||||||
|
if (sense_len <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_err(c, fp, sense, sense_len, duration,
|
||||||
|
1 | (flag & 2));
|
||||||
|
outcome = scsi_error(d, sense, sense_len);
|
||||||
|
if (outcome == RETRY && c->retry && !(flag & 1)) {
|
||||||
|
/* Calming down retries and breaking up endless cycle
|
||||||
|
*/
|
||||||
|
usleep_time = Libburn_scsi_retry_usleeP +
|
||||||
|
loop_count * Libburn_scsi_retry_incR;
|
||||||
|
if (time(NULL) + usleep_time / 1000000 - start_time >
|
||||||
|
timeout_ms / 1000 + 1) {
|
||||||
|
done = 1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
usleep(usleep_time);
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_cmd(c, fp, 0);
|
||||||
|
return 0;
|
||||||
|
} else if (outcome == RETRY) {
|
||||||
|
done = 1;
|
||||||
|
} else if (outcome == GO_ON) {
|
||||||
|
return 1;
|
||||||
|
} else if (outcome == FAIL) {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
ex:;
|
||||||
|
c->error = 1;
|
||||||
|
scsi_notify_error(d, c, sense, sense_len, 0);
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
@ -49,7 +49,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
|||||||
int channel_no, int target_no, int lun_no, int flag);
|
int channel_no, int target_no, int lun_no, int flag);
|
||||||
|
|
||||||
/* ts A61115 moved from sg-*.h */
|
/* ts A61115 moved from sg-*.h */
|
||||||
enum response { RETRY, FAIL };
|
enum response { RETRY, FAIL, GO_ON };
|
||||||
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
||||||
|
|
||||||
/* ts A61122 */
|
/* ts A61122 */
|
||||||
@ -78,7 +78,29 @@ int scsi_log_cmd(struct command *c, void *fp, int flag);
|
|||||||
/* ts A91221 (former sg_log_err ts A91108) */
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
/** Logs outcome of a sg command. */
|
/** Logs outcome of a sg command. */
|
||||||
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
||||||
int duration, int flag);
|
int sense_len, int duration, int flag);
|
||||||
|
|
||||||
|
/* ts B00728 */
|
||||||
|
int spc_decode_sense(unsigned char *sense, int senselen,
|
||||||
|
int *key, int *asc, int *ascq);
|
||||||
|
|
||||||
|
/* ts B00808 */
|
||||||
|
/** Evaluates outcome of a single SCSI command, eventually logs sense data,
|
||||||
|
and issues DEBUG error message in case the command is evaluated as done.
|
||||||
|
@param flag bit1 = do not print duration
|
||||||
|
@return 0 = not yet done , 1 = done , -1 = error
|
||||||
|
*/
|
||||||
|
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
|
||||||
|
unsigned char *sense, int sense_len,
|
||||||
|
int duration, time_t start_time, int timeout_ms,
|
||||||
|
int loop_count, int flag);
|
||||||
|
|
||||||
|
/* The waiting time before eventually retrying a failed SCSI command.
|
||||||
|
Before each retry wait Libburn_scsi_retry_incR longer than with
|
||||||
|
the previous one.
|
||||||
|
*/
|
||||||
|
#define Libburn_scsi_retry_usleeP 100000
|
||||||
|
#define Libburn_scsi_retry_incR 100000
|
||||||
|
|
||||||
|
|
||||||
#endif /*__SPC*/
|
#endif /*__SPC*/
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
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> */
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
Provided under GPL version 2 or later.
|
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 */
|
||||||
@ -30,7 +34,7 @@ char *burn_strdup(char *s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
l = strlen(s) + 1;
|
l = strlen(s) + 1;
|
||||||
ret = malloc(l);
|
ret = calloc(1, l);
|
||||||
memcpy(ret, s, l);
|
memcpy(ret, s, l);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -48,7 +52,7 @@ char *burn_strndup(char *s, int n)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
l = strlen(s);
|
l = strlen(s);
|
||||||
ret = malloc(l < n ? l : n);
|
ret = calloc(1, l < n ? l : n);
|
||||||
|
|
||||||
memcpy(ret, s, l < n - 1 ? l : n - 1);
|
memcpy(ret, s, l < n - 1 ? l : n - 1);
|
||||||
ret[n - 1] = '\0';
|
ret[n - 1] = '\0';
|
||||||
@ -138,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 &&
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
@ -25,18 +25,19 @@
|
|||||||
#include "../libburn/libdax_msgs.h"
|
#include "../libburn/libdax_msgs.h"
|
||||||
struct libdax_msgs *libdax_messenger= NULL;
|
struct libdax_msgs *libdax_messenger= NULL;
|
||||||
|
|
||||||
|
/* The API for .wav extraction */
|
||||||
|
#define LIBDAX_AUDIOXTR_H_PUBLIC 1
|
||||||
|
#include "../libburn/libdax_audioxtr.h"
|
||||||
|
|
||||||
#else /* Dewav_without_libburN */
|
#else /* Dewav_without_libburN */
|
||||||
|
|
||||||
/* This build environment uses libdax_msgs via libburn */
|
/* This build environment uses libdax_msgs and libdax_audioxtr via libburn */
|
||||||
/* Thus the API header of libburn */
|
/* Thus the API header of libburn */
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
#endif /* ! Dewav_without_libburN */
|
#endif /* ! Dewav_without_libburN */
|
||||||
|
|
||||||
|
|
||||||
/* The API for .wav extraction */
|
|
||||||
#include "../libburn/libdax_audioxtr.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -20,31 +20,37 @@
|
|||||||
Before you can do anything, you have to initialize libburn by
|
Before you can do anything, you have to initialize libburn by
|
||||||
burn_initialize()
|
burn_initialize()
|
||||||
and provide some signal and abort handling, e.g. by the builtin handler, by
|
and provide some signal and abort handling, e.g. by the builtin handler, by
|
||||||
burn_set_signal_handling()
|
burn_set_signal_handling("libburner : ", NULL, 0x0)
|
||||||
as it is done in main() at the end of this file. Then you aquire a
|
as it is done in main() at the end of this file.
|
||||||
drive in an appropriate way conforming to the API. The two main
|
Then you aquire a drive in an appropriate way conforming to the API. The twoi
|
||||||
approaches are shown here in application functions:
|
main 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 or DVD-RW
|
|
||||||
|
With that aquired drive you can blank a CD-RW or DVD-RW as shown in
|
||||||
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
|
||||||
libburner_format()
|
libburner_format()
|
||||||
With the aquired drive you can burn to CD, DVD, BD
|
With the aquired drive you can burn to CD, DVD, BD. See
|
||||||
libburner_payload()
|
libburner_payload()
|
||||||
|
|
||||||
|
These three functions switch temporarily to a non-fatal signal handler
|
||||||
|
while they are waiting for the drive to become idle again:
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x30)
|
||||||
|
After the waiting loop ended, they check for eventual abort events by
|
||||||
|
burn_is_aborting(0)
|
||||||
|
The 0x30 handler will eventually execute
|
||||||
|
burn_abort()
|
||||||
|
but not wait for the drive to become idle and not call exit().
|
||||||
|
This is needed because the worker threads might block as long as the signal
|
||||||
|
handler has not returned. The 0x0 handler would wait for them to finish.
|
||||||
|
Take this into respect when implementing own signal handlers.
|
||||||
|
|
||||||
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
|
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
|
||||||
@ -60,7 +66,7 @@
|
|||||||
/* This program insists in the own headerfile. */
|
/* This program insists in the own headerfile. */
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
/* libburn is intended for Linux systems with kernel 2.4 or 2.6 for now */
|
/* libburn works on Linux systems with kernel 2.4 or 2.6, FreeBSD, Solaris */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -333,7 +339,7 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
if (burn_is_aborting(0) > 0)
|
if (burn_is_aborting(0) > 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* Back to synchronous handling */
|
/* Back to synchronous handling */
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0);
|
burn_set_signal_handling("libburner : ", NULL, 0x0);
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -401,7 +407,7 @@ int libburner_format(struct burn_drive *drive)
|
|||||||
}
|
}
|
||||||
if (burn_is_aborting(0) > 0)
|
if (burn_is_aborting(0) > 0)
|
||||||
return -1;
|
return -1;
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0);
|
burn_set_signal_handling("libburner : ", NULL, 0x0);
|
||||||
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)
|
||||||
@ -732,6 +738,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);
|
||||||
@ -750,7 +763,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Activate the synchronous 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, 0x0);
|
||||||
|
|
||||||
/** Note: driveno might change its value in this call */
|
/** Note: driveno might change its value in this call */
|
||||||
ret = libburner_aquire_drive(drive_adr, &driveno);
|
ret = libburner_aquire_drive(drive_adr, &driveno);
|
||||||
|
Reference in New Issue
Block a user